feat: add interfaces for secondary menu items with various types and functionalities

This commit is contained in:
2026-01-03 01:24:36 +00:00
parent c41268cd4e
commit 57b323b53c
23 changed files with 1069 additions and 240 deletions

View File

@@ -98,10 +98,10 @@ export class DeesAppui extends DeesElement {
accessor secondarymenuHeading: string = '';
@property({ type: Array })
accessor secondarymenuGroups: interfaces.IMenuGroup[] = [];
accessor secondarymenuGroups: interfaces.ISecondaryMenuGroup[] = [];
@property({ type: Object })
accessor secondarymenuSelectedItem: interfaces.IMenuItem | undefined = undefined;
accessor secondarymenuSelectedItem: interfaces.ISecondaryMenuItemTab | undefined = undefined;
// Collapse states
@property({ type: Boolean })
@@ -126,6 +126,13 @@ export class DeesAppui extends DeesElement {
@property({ type: Number })
accessor contentTabsAutoHideThreshold: number = 0;
// Activity log visibility and count
@state()
accessor activityLogVisible: boolean = false;
@state()
accessor activityLogCount: number = 0;
// Properties for maincontent
@property({ type: Array })
accessor maincontentTabs: interfaces.IMenuItem[] = [];
@@ -175,8 +182,9 @@ export class DeesAppui extends DeesElement {
height: calc(100% - 40px);
width: 100%;
display: grid;
grid-template-columns: auto auto 1fr 240px;
/* grid-template-columns set dynamically in template */
grid-template-rows: 1fr;
transition: grid-template-columns 0.3s ease;
}
/* Z-index layering for proper stacking */
@@ -198,6 +206,19 @@ export class DeesAppui extends DeesElement {
.maingrid > dees-appui-activitylog {
position: relative;
z-index: 1;
overflow: hidden;
transition: opacity 0.3s ease, transform 0.3s ease;
}
.maingrid > dees-appui-activitylog.hidden {
opacity: 0;
transform: translateX(20px);
pointer-events: none;
}
.maingrid > dees-appui-activitylog.visible {
opacity: 1;
transform: translateX(0);
}
/* View container for dynamically loaded views */
@@ -221,14 +242,18 @@ export class DeesAppui extends DeesElement {
.user=${this.appbarUser}
.profileMenuItems=${this.appbarProfileMenuItems}
.showSearch=${this.appbarShowSearch}
.showActivityLogToggle=${true}
.activityLogCount=${this.activityLogCount}
.activityLogActive=${this.activityLogVisible}
@menu-select=${(e: CustomEvent) => this.handleAppbarMenuSelect(e)}
@breadcrumb-navigate=${(e: CustomEvent) => this.handleAppbarBreadcrumbNavigate(e)}
@search-click=${() => this.handleAppbarSearchClick()}
@search-query=${(e: CustomEvent) => this.handleAppbarSearchQuery(e)}
@user-menu-open=${() => this.handleAppbarUserMenuOpen()}
@profile-menu-select=${(e: CustomEvent) => this.handleAppbarProfileMenuSelect(e)}
@activity-toggle=${() => this.toggleActivityLog()}
></dees-appui-appbar>
<div class="maingrid">
<div class="maingrid" style="grid-template-columns: auto auto 1fr ${this.activityLogVisible ? '280px' : '0px'};">
${this.mainmenuVisible ? html`
<dees-appui-mainmenu
.logoIcon=${this.mainmenuLogoIcon}
@@ -264,7 +289,9 @@ export class DeesAppui extends DeesElement {
<div class="view-container"></div>
<slot name="maincontent"></slot>
</dees-appui-maincontent>
<dees-appui-activitylog></dees-appui-activitylog>
<dees-appui-activitylog
class="${this.activityLogVisible ? 'visible' : 'hidden'}"
></dees-appui-activitylog>
</div>
`;
}
@@ -277,6 +304,13 @@ export class DeesAppui extends DeesElement {
this.maincontent = this.shadowRoot!.querySelector('dees-appui-maincontent') as DeesAppuiMaincontent;
this.activitylogElement = this.shadowRoot!.querySelector('dees-appui-activitylog') as DeesAppuiActivitylog;
// Subscribe to activity log entry changes for badge count
if (this.activitylogElement) {
this.activitylogElement.entries$.subscribe((entries) => {
this.activityLogCount = entries.length;
});
}
// Set appui reference in view registry for lifecycle context
this.viewRegistry.setAppuiRef(this as unknown as interfaces.TDeesAppui);
}
@@ -534,7 +568,7 @@ export class DeesAppui extends DeesElement {
/**
* Set the secondary menu configuration
*/
public setSecondaryMenu(config: { heading?: string; groups: interfaces.IMenuGroup[] }): void {
public setSecondaryMenu(config: { heading?: string; groups: interfaces.ISecondaryMenuGroup[] }): void {
if (config.heading !== undefined) {
this.secondarymenuHeading = config.heading;
}
@@ -544,7 +578,7 @@ export class DeesAppui extends DeesElement {
/**
* Update a specific secondary menu group
*/
public updateSecondaryMenuGroup(groupName: string, update: Partial<interfaces.IMenuGroup>): void {
public updateSecondaryMenuGroup(groupName: string, update: Partial<interfaces.ISecondaryMenuGroup>): void {
this.secondarymenuGroups = this.secondarymenuGroups.map(group =>
group.name === groupName ? { ...group, ...update } : group
);
@@ -555,7 +589,7 @@ export class DeesAppui extends DeesElement {
*/
public addSecondaryMenuItem(
groupName: string,
item: interfaces.IMenuGroup['items'][0]
item: interfaces.ISecondaryMenuItem
): void {
this.secondarymenuGroups = this.secondarymenuGroups.map(group => {
if (group.name === groupName) {
@@ -569,13 +603,13 @@ export class DeesAppui extends DeesElement {
}
/**
* Set the selected secondary menu item by key
* Set the selected secondary menu item by key (for tab items only)
*/
public setSecondaryMenuSelection(itemKey: string): void {
for (const group of this.secondarymenuGroups) {
const item = group.items.find(i => i.key === itemKey);
if (item) {
this.secondarymenuSelectedItem = item;
const item = group.items.find(i => 'key' in i && i.key === itemKey);
if (item && (!('type' in item) || item.type === 'tab' || item.type === undefined)) {
this.secondarymenuSelectedItem = item as interfaces.ISecondaryMenuItemTab;
return;
}
}
@@ -673,6 +707,27 @@ export class DeesAppui extends DeesElement {
};
}
/**
* Set activity log visibility
*/
public setActivityLogVisible(visible: boolean): void {
this.activityLogVisible = visible;
}
/**
* Toggle activity log visibility
*/
public toggleActivityLog(): void {
this.activityLogVisible = !this.activityLogVisible;
}
/**
* Get activity log visibility state
*/
public getActivityLogVisible(): boolean {
return this.activityLogVisible;
}
// ==========================================
// PROGRAMMATIC API: NAVIGATION
// ==========================================