diff --git a/.scripts/configure.ts b/.scripts/configure.ts index 3604eb520a..d9df0da12b 100644 --- a/.scripts/configure.ts +++ b/.scripts/configure.ts @@ -222,7 +222,7 @@ if (!isDocker) { API_BASE_URL: API_BASE_URL, CLIENT_BASE_URL: CLIENT_BASE_URL, - COOKIE_DOMAIN: '${env.COOKIE_DOMAIN}', + COOKIE_DOMAIN: 'DOCKER_COOKIE_DOMAIN', PLATFORM_WEBSITE_URL: 'DOCKER_PLATFORM_WEBSITE_URL', PLATFORM_WEBSITE_DOWNLOAD_URL: 'DOCKER_PLATFORM_WEBSITE_DOWNLOAD_URL', diff --git a/apps/gauzy/src/app/pages/pages.component.ts b/apps/gauzy/src/app/pages/pages.component.ts index cc12f8a93c..b8c2facdba 100644 --- a/apps/gauzy/src/app/pages/pages.component.ts +++ b/apps/gauzy/src/app/pages/pages.component.ts @@ -2,12 +2,10 @@ import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, Data, Router } from '@angular/router'; import { NbMenuItem } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; -import { merge, pairwise } from 'rxjs'; -import { filter, map, take, tap } from 'rxjs/operators'; +import { filter, map, merge, pairwise, take, tap } from 'rxjs'; import { NgxPermissionsService } from 'ngx-permissions'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { chain } from 'underscore'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { FeatureEnum, IOrganization, IRolePermission, IUser, IntegrationEnum, PermissionsEnum } from '@gauzy/contracts'; import { AuthStrategy, IJobMatchingEntity, @@ -19,8 +17,8 @@ import { Store, UsersService } from '@gauzy/ui-core/core'; -import { FeatureEnum, IOrganization, IRolePermission, IUser, IntegrationEnum, PermissionsEnum } from '@gauzy/contracts'; import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ReportService } from './reports/all-report/report.service'; @UntilDestroy({ checkProperties: true }) @@ -80,15 +78,9 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie filter((organization: IOrganization) => !!organization), distinctUntilChange(), pairwise(), // Pair each emitted value with the previous one - tap(([organization]: [IOrganization, IOrganization]) => { - const { id: organizationId, tenantId } = organization; - + tap(([previousOrganization]: [IOrganization, IOrganization]) => { // Remove the specified menu items for previous selected organization - this._navMenuBuilderService.removeNavMenuItems( - // Define the base item IDs - this.getReportMenuBaseItemIds().map((itemId) => `${itemId}-${organizationId}-${tenantId}`), - 'reports' - ); + this.removeOrganizationReportsMenuItems(previousOrganization); }), untilDestroyed(this) ) @@ -118,25 +110,21 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie .subscribe(); this.reportService.menuItems$.pipe(distinctUntilChange(), untilDestroyed(this)).subscribe((menuItems) => { - if (menuItems) { - this.reportMenuItems = chain(menuItems) - .values() - .map((item) => { - return { - id: item.slug + `-${this.organization?.id}`, - title: item.name, - link: `/pages/reports/${item.slug}`, - icon: item.iconClass, - data: { - translationKey: `${item.name}` - } - }; - }) - .value(); - } else { - this.reportMenuItems = []; - } - this.addOrganizationReportsMenuItems(); + // Convert the menuItems object to an array + const reportItems = menuItems ? Object.values(menuItems) : []; + + this.reportMenuItems = reportItems.map((item) => ({ + id: item.slug, + title: item.name, + link: `/pages/reports/${item.slug}`, + icon: item.iconClass, + data: { + translationKey: item.name + } + })); + + // Add the report menu items to the navigation menu + this.addOrRemoveOrganizationReportsMenuItems(); }); } @@ -176,49 +164,62 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie } /** - * Adds report menu items to the organization's navigation menu. + * Removes the report menu items associated with the current organization. + * + * This function checks if the organization is defined. If not, it logs a warning and exits early. + * If the organization is defined, it constructs item IDs based on the organization and tenant ID + * and removes these items from the navigation menu. + * + * @returns {void} This function does not return a value. */ - private addOrganizationReportsMenuItems() { - if (!this.organization) { - // Handle the case where this.organization is not defined - console.warn('Organization not defined. Unable to add/remove menu items.'); + private removeOrganizationReportsMenuItems(organization: IOrganization): void { + // Return early if the organization is not defined, logging a warning + if (!organization) { + console.warn(`Organization not defined. Unable to remove menu items.`); return; } - const { id: organizationId, tenantId } = this.organization; - // Remove the specified menu items for current selected organization - // Note: We need to remove old menus before constructing new menus for the organization. - this._navMenuBuilderService.removeNavMenuItems( - // Define the base item IDs - this.getReportMenuBaseItemIds().map((itemId) => `${itemId}-${organizationId}-${tenantId}`), - 'reports' + // Destructure organization properties + const { id: organizationId, tenantId } = organization; + + // Generate the item IDs to remove and call the service method + const itemIdsToRemove = this.getReportMenuBaseItemIds().map( + (itemId) => `${itemId}-${organizationId}-${tenantId}` ); - // Validate if reportMenuItems is an array and has elements - if (!Array.isArray(this.reportMenuItems) || this.reportMenuItems.length === 0) { + this._navMenuBuilderService.removeNavMenuItems(itemIdsToRemove, 'reports'); + } + + /** + * Adds report menu items to the organization's navigation menu. + */ + private addOrRemoveOrganizationReportsMenuItems() { + if (!this.organization) { + console.warn('Organization not defined. Unable to add/remove menu items.'); return; } + const { id: organizationId, tenantId } = this.organization; + + // Remove old menu items before constructing new ones for the organization + this.removeOrganizationReportsMenuItems(this.organization); + // Iterate over each report and add it to the navigation menu - try { - this.reportMenuItems.forEach((report: NavMenuSectionItem) => { - // Validate the structure of each report item - if (report && report.id && report.title) { - this._navMenuBuilderService.addNavMenuItem( - { - id: report.id, // Unique identifier for the menu item - title: report.title, // The title of the menu item - icon: report.icon, // The icon class for the menu item, using FontAwesome in this case - link: report.link, // The link where the menu item directs - data: report.data - }, - 'reports' - ); // The id of the section where this item should be added - } - }); - } catch (error) { - console.error('Error adding report menu items', error); - } + this.reportMenuItems.forEach((report: NavMenuSectionItem) => { + // Validate the structure of each report item + if (report?.id && report?.title) { + this._navMenuBuilderService.addNavMenuItem( + { + id: `${report.id}-${organizationId}-${tenantId}`, // Unique identifier for the menu item + title: report.title, // The title of the menu item + icon: report.icon, // The icon class for the menu item + link: report.link, // The link where the menu item directs + data: report.data // The data associated with the menu item + }, + 'reports' // The id of the section where this item should be added + ); + } + }); } /** @@ -402,5 +403,8 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie this.store.featureTenant = tenant.featureOrganizations.filter((item) => !item.organizationId); } - ngOnDestroy() {} + ngOnDestroy() { + // Remove the report menu items associated with the current organization before destroying the component + this.removeOrganizationReportsMenuItems(this.organization); + } } diff --git a/packages/ui-core/core/src/index.ts b/packages/ui-core/core/src/index.ts index b6be039673..38d20e147f 100644 --- a/packages/ui-core/core/src/index.ts +++ b/packages/ui-core/core/src/index.ts @@ -5,6 +5,7 @@ export * from './lib/auth'; export * from './lib/common/component-registry.types'; export * from './lib/components'; export * from './lib/core.module'; +export * from './lib/extension'; export * from './lib/guards'; export * from './lib/interceptors'; export * from './lib/module-import-guard'; diff --git a/packages/ui-core/core/src/lib/extension/index.ts b/packages/ui-core/core/src/lib/extension/index.ts new file mode 100644 index 0000000000..91ade2b9f0 --- /dev/null +++ b/packages/ui-core/core/src/lib/extension/index.ts @@ -0,0 +1 @@ +export * from './add-nav-menu-item'; diff --git a/packages/ui-core/core/src/lib/services/nav-builder/nav-menu-builder.service.ts b/packages/ui-core/core/src/lib/services/nav-builder/nav-menu-builder.service.ts index fb97a0df9f..fdee036657 100644 --- a/packages/ui-core/core/src/lib/services/nav-builder/nav-menu-builder.service.ts +++ b/packages/ui-core/core/src/lib/services/nav-builder/nav-menu-builder.service.ts @@ -229,9 +229,7 @@ export class NavMenuBuilderService { } } } else { - console.error( - `Could not add menu item "${item.config.id}", section "${item.sectionId}" does not exist` - ); + this.logMenuWarning(item.config.id, item.sectionId); } }); @@ -239,4 +237,26 @@ export class NavMenuBuilderService { }) ); } + + /** + * Logs a warning message about an inability to add a menu item. + * + * @param itemId - The ID of the menu item that could not be added. + * @param sectionId - The ID of the section where the item was to be added. + * @param level - Optional logging level; defaults to 'warn'. + */ + logMenuWarning(itemId: string, sectionId: string, level: 'warn' | 'info' | 'error' = 'warn') { + const message = `Warning: Unable to add menu item "${itemId}" because the specified section "${sectionId}" does not exist.`; + + switch (level) { + case 'info': + console.info(message); + break; + case 'error': + console.error(message); + break; + default: + console.warn(message); + } + } }