-
Notifications
You must be signed in to change notification settings - Fork 16
Update: JSDoc documentation for drawer system (fixes #812) #813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,61 @@ | ||
| /** | ||
| * @file Drawer Service - Sidebar navigation system with menu items and custom views | ||
| * @module core/js/drawer | ||
| * @description Singleton service managing the drawer sidebar navigation system. Provides API | ||
| * for registering menu items and displaying custom views. Handles drawer lifecycle, state management, | ||
| * and integration with navigation toolbar. | ||
| * | ||
| * **Architecture:** | ||
| * - Singleton controller (exported as instance) | ||
| * - Manages {@link DrawerCollection} of menu items (sorted by drawerOrder) | ||
| * - Creates/destroys {@link DrawerView} on language change | ||
| * - Two operational modes: menu list or custom view | ||
| * | ||
| * **Public Events Triggered:** | ||
| * - `drawer:opened` - Drawer opened (any mode) | ||
| * - `drawer:openedItemView` - Menu mode shown | ||
| * - `drawer:openedCustomView` - Custom view shown | ||
| * - `drawer:closed` - Drawer closed | ||
| * - `drawer:empty` - Drawer content cleared | ||
| * - `drawer:noItems` - No menu items registered | ||
| * | ||
| * **Usage Pattern:** | ||
| * ```javascript | ||
| * // Register menu item | ||
| * drawer.addItem({ | ||
| * title: 'Resources', | ||
| * description: 'View course resources', | ||
| * className: 'resources-drawer-item', | ||
| * drawerOrder: 10 | ||
| * }, 'resources:showDrawer'); | ||
| * | ||
| * // Listen for callback | ||
| * Adapt.on('resources:showDrawer', () => { | ||
| * drawer.openCustomView(new ResourcesView()); | ||
| * }); | ||
| * ``` | ||
| * | ||
| * **Known Issues & Improvements:** | ||
| * - **Issue:** DrawerCollection is module-scoped but not accessible via API | ||
| * - **Issue:** No way to update existing item without remove/add | ||
| * - **Issue:** No validation of drawerObject structure | ||
| * - **Enhancement:** Add `updateItem(eventCallback, drawerObject)` method | ||
| * - **Enhancement:** Add `getItem(eventCallback)` to retrieve item data | ||
| * - **Enhancement:** Add `getAllItems()` to get current menu items | ||
| */ | ||
|
|
||
| import Backbone from 'backbone'; | ||
| import Adapt from 'core/js/adapt'; | ||
| import DrawerView from 'core/js/views/drawerView'; | ||
| import tooltips from './tooltips'; | ||
|
|
||
| const DrawerCollection = new Backbone.Collection(null, { comparator: 'drawerOrder' }); | ||
|
|
||
| /** | ||
| * @class Drawer | ||
| * @classdesc Singleton service for drawer navigation system. Only one instance exists per course. | ||
| * @extends {Backbone.Controller} | ||
| */ | ||
| class Drawer extends Backbone.Controller { | ||
|
|
||
| initialize() { | ||
|
|
@@ -29,22 +80,85 @@ class Drawer extends Backbone.Controller { | |
| this.remove(); | ||
| } | ||
|
|
||
| /** | ||
| * Toggles drawer open/closed based on current state. | ||
| * Convenience method for open/close logic. | ||
| * @example | ||
| * Adapt.trigger('navigation:toggleDrawer'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider as deprecated. As a general principle for Adapt, any event triggered on a subject as if it were a function call that is not a triggered by the subject as notification of a state change should be replaced with a function API. Where a function alternative to an event trigger already exists, consider the event trigger to be deprecated. |
||
| * | ||
| * drawer.toggle(); | ||
| */ | ||
| toggle() { | ||
| (this.isOpen) ? this.close() : this.open(); | ||
| } | ||
|
|
||
| /** | ||
| * Checks if drawer is currently open in menu mode. | ||
| * Returns false if drawer is showing custom view or closed. | ||
| * @returns {boolean} True if drawer is visible in menu mode | ||
| * @example | ||
| * if (drawer.isOpen) { | ||
| * console.log('Menu is showing'); | ||
| * } | ||
| */ | ||
| get isOpen() { | ||
| return this._drawerView?.isOpen ?? false; | ||
| } | ||
|
|
||
| /** | ||
| * Opens drawer in menu mode showing list of registered items. | ||
| * If only one item registered, automatically triggers its callback. | ||
| * @fires drawer:opened | ||
| * @fires drawer:openedItemView | ||
| * @example | ||
| * drawer.open(); | ||
| */ | ||
| open() { | ||
| this._drawerView?.showDrawer(true); | ||
| } | ||
|
|
||
| /** | ||
| * Opens drawer with custom view content. | ||
| * Called by plugins in response to menu item click. | ||
| * @param {Backbone.View|jQuery|HTMLElement|string} view - View instance or HTML content to display | ||
| * @param {boolean} [hasBackButton=true] - Show back button to return to menu | ||
| * @param {string} [position] - Override drawer position ('left'|'right', null uses global config) | ||
| * @fires drawer:opened | ||
| * @fires drawer:openedCustomView | ||
| * @fires drawer:empty | ||
| * @example | ||
| * Adapt.on('resources:showDrawer', () => { | ||
| * const resourcesView = new ResourcesView(); | ||
| * drawer.openCustomView(resourcesView, true, 'right'); | ||
| * }); | ||
| * | ||
| * drawer.openCustomView('<div>Simple HTML</div>', false); | ||
| */ | ||
| openCustomView(view, hasBackButton, position) { | ||
| this._drawerView?.openCustomView(view, hasBackButton, position); | ||
| } | ||
|
|
||
| /** | ||
| * Registers a menu item in the drawer. | ||
| * Replaces existing item with same eventCallback. | ||
| * @param {Object} drawerObject - Menu item configuration | ||
| * @param {string} drawerObject.title - Display title | ||
| * @param {string} drawerObject.description - Description text | ||
| * @param {string} [drawerObject.className] - CSS class for styling | ||
| * @param {number} [drawerObject.drawerOrder=0] - Sort order (lower numbers first) | ||
| * @param {string} eventCallback - Event name to trigger when clicked | ||
| * @example | ||
| * drawer.addItem({ | ||
| * title: 'Resources', | ||
| * description: 'View downloadable resources', | ||
| * className: 'resources-item', | ||
| * drawerOrder: 20 | ||
| * }, 'resources:showDrawer'); | ||
| * | ||
| * Adapt.on('resources:showDrawer', () => { | ||
| * drawer.openCustomView(new ResourcesView()); | ||
| * }); | ||
| */ | ||
| addItem(drawerObject, eventCallback) { | ||
| if (this.hasItem(eventCallback)) { | ||
| DrawerCollection.remove(DrawerCollection.find(item => item.eventCallback === eventCallback)); | ||
|
|
@@ -53,14 +167,40 @@ class Drawer extends Backbone.Controller { | |
| DrawerCollection.add(drawerObject); | ||
| } | ||
|
|
||
| /** | ||
| * Checks if menu item is registered. | ||
| * @param {string} eventCallback - Event callback to check | ||
| * @returns {boolean} True if item exists | ||
| * @example | ||
| * if (!drawer.hasItem('resources:showDrawer')) { | ||
| * drawer.addItem({ title: 'Resources' }, 'resources:showDrawer'); | ||
| * } | ||
| */ | ||
| hasItem(eventCallback) { | ||
| return Boolean(DrawerCollection.find(item => item.eventCallback === eventCallback)); | ||
| } | ||
|
|
||
| /** | ||
| * Closes the drawer immediately. | ||
| * Called automatically on navigation. | ||
| * @param {jQuery} [$toElement=null] - Element to focus after closing | ||
| * @fires drawer:closed | ||
| * @example | ||
| * drawer.close(); | ||
| * | ||
| * drawer.close($('.js-nav-home-btn')); | ||
| */ | ||
| close($toElement = null) { | ||
| this._drawerView?.hideDrawer($toElement, { force: true }); | ||
| } | ||
|
|
||
| /** | ||
| * Destroys the drawer view and cleans up. | ||
| * Called automatically on language change. | ||
| * @fires drawer:empty | ||
| * @example | ||
| * drawer.remove(); | ||
| */ | ||
| remove() { | ||
| this._drawerView?.remove(); | ||
| this._drawerView = null; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description and terminology aren't quite right throughout.
Replace 'menu items' with 'drawer items' and the word 'menu' for 'sidebar/drawer' as the word menu is used for menu plugins.
Remove 'navigation system' as the word navigation is used for a core module called 'navigation' which is the horizontal navigation bar, not the vertical sidebar.