diff --git a/.cspell.json b/.cspell.json index db57332ab4e..f09cfdc0ae4 100644 --- a/.cspell.json +++ b/.cspell.json @@ -507,7 +507,15 @@ "COMMONPROGRAMFILES", "serverapi", "serializables", - "drppicker" + "drppicker", + "titlebar", + "raleway", + "browserslist", + "flexbox", + "nbinput", + "nbbutton", + "xaxis", + "wdth" ], "useGitignore": true, "ignorePaths": [ diff --git a/.deploy/api/Dockerfile b/.deploy/api/Dockerfile index 55f608294dc..8bbb537afee 100644 --- a/.deploy/api/Dockerfile +++ b/.deploy/api/Dockerfile @@ -165,6 +165,10 @@ COPY --chown=node:node packages/plugins/job-employee-ui/package.json ./packages/ COPY --chown=node:node packages/plugins/job-matching-ui/package.json ./packages/plugins/job-matching-ui/ COPY --chown=node:node packages/plugins/job-proposal-ui/package.json ./packages/plugins/job-proposal-ui/ COPY --chown=node:node packages/plugins/job-search-ui/package.json ./packages/plugins/job-search-ui/ +COPY --chown=node:node packages/plugins/legal-ui/package.json ./packages/plugins/legal-ui/ +COPY --chown=node:node packages/plugins/maintenance-ui/package.json ./packages/plugins/maintenance-ui/ +COPY --chown=node:node packages/plugins/onboarding-ui/package.json ./packages/plugins/onboarding-ui/ +COPY --chown=node:node packages/plugins/public-layout-ui/package.json ./packages/plugins/public-layout-ui/ COPY --chown=node:node packages/ui-core/package.json ./packages/ui-core/ COPY --chown=node:node packages/ui-config/package.json ./packages/ui-config/ COPY --chown=node:node packages/ui-auth/package.json ./packages/ui-auth/ @@ -230,6 +234,10 @@ COPY --chown=node:node packages/plugins/job-employee-ui/package.json ./packages/ COPY --chown=node:node packages/plugins/job-matching-ui/package.json ./packages/plugins/job-matching-ui/ COPY --chown=node:node packages/plugins/job-proposal-ui/package.json ./packages/plugins/job-proposal-ui/ COPY --chown=node:node packages/plugins/job-search-ui/package.json ./packages/plugins/job-search-ui/ +COPY --chown=node:node packages/plugins/public-layout-ui/package.json ./packages/plugins/public-layout-ui/ +COPY --chown=node:node packages/plugins/legal-ui/package.json ./packages/plugins/legal-ui/ +COPY --chown=node:node packages/plugins/maintenance-ui/package.json ./packages/plugins/maintenance-ui/ +COPY --chown=node:node packages/plugins/onboarding-ui/package.json ./packages/plugins/onboarding-ui/ COPY --chown=node:node packages/ui-core/package.json ./packages/ui-core/ COPY --chown=node:node packages/ui-config/package.json ./packages/ui-config/ COPY --chown=node:node packages/ui-auth/package.json ./packages/ui-auth/ diff --git a/.deploy/webapp/Dockerfile b/.deploy/webapp/Dockerfile index 48d1a6f7241..2e198cc546b 100644 --- a/.deploy/webapp/Dockerfile +++ b/.deploy/webapp/Dockerfile @@ -105,6 +105,10 @@ COPY --chown=node:node packages/plugins/job-employee-ui/package.json ./packages/ COPY --chown=node:node packages/plugins/job-matching-ui/package.json ./packages/plugins/job-matching-ui/ COPY --chown=node:node packages/plugins/job-proposal-ui/package.json ./packages/plugins/job-proposal-ui/ COPY --chown=node:node packages/plugins/job-search-ui/package.json ./packages/plugins/job-search-ui/ +COPY --chown=node:node packages/plugins/legal-ui/package.json ./packages/plugins/legal-ui/ +COPY --chown=node:node packages/plugins/maintenance-ui/package.json ./packages/plugins/maintenance-ui/ +COPY --chown=node:node packages/plugins/onboarding-ui/package.json ./packages/plugins/onboarding-ui/ +COPY --chown=node:node packages/plugins/public-layout-ui/package.json ./packages/plugins/public-layout-ui/ COPY --chown=node:node packages/ui-core/package.json ./packages/ui-core/ COPY --chown=node:node packages/ui-config/package.json ./packages/ui-config/ COPY --chown=node:node packages/ui-auth/package.json ./packages/ui-auth/ diff --git a/angular.json b/angular.json index bb9c75d7e97..5ac048b5c40 100644 --- a/angular.json +++ b/angular.json @@ -433,6 +433,150 @@ } } }, + "plugin-legal-ui": { + "projectType": "library", + "root": "packages/plugins/legal-ui", + "sourceRoot": "packages/plugins/legal-ui", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "packages/plugins/legal-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/legal-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/legal-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "tsConfig": "packages/plugins/legal-ui/tsconfig.spec.json", + "polyfills": ["zone.js", "zone.js/testing"] + } + } + }, + "schematics": { + "@nrwl/angular:component": { + "prefix": "ngx", + "style": "scss" + } + } + }, + "plugin-maintenance-ui": { + "projectType": "library", + "root": "packages/plugins/maintenance-ui", + "sourceRoot": "packages/plugins/maintenance-ui", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "packages/plugins/maintenance-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/maintenance-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/maintenance-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@nrwl/jest:jest", + "options": { + "jestConfig": "packages/plugins/maintenance-ui/jest.config.js", + "passWithNoTests": true + } + } + }, + "schematics": { + "@nrwl/angular:component": { + "prefix": "ngx", + "style": "scss" + } + } + }, + "plugin-onboarding-ui": { + "projectType": "library", + "root": "packages/plugins/onboarding-ui", + "sourceRoot": "packages/plugins/onboarding-ui", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "packages/plugins/onboarding-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/onboarding-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/onboarding-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "tsConfig": "packages/plugins/onboarding-ui/tsconfig.spec.json", + "polyfills": ["zone.js", "zone.js/testing"] + } + } + }, + "schematics": { + "@nrwl/angular:component": { + "prefix": "ngx", + "style": "scss" + } + } + }, + "plugin-public-layout-ui": { + "projectType": "library", + "root": "packages/plugins/public-layout-ui", + "sourceRoot": "packages/plugins/public-layout-ui/src", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "packages/plugins/public-layout-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/public-layout-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/public-layout-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "tsConfig": "packages/plugins/public-layout-ui/tsconfig.spec.json", + "polyfills": ["zone.js", "zone.js/testing"] + } + } + }, + "schematics": { + "@nrwl/angular:component": { + "prefix": "gz", + "style": "scss" + } + } + }, "gauzy-e2e": { "root": "apps/gauzy-e2e", "sourceRoot": "apps/gauzy-e2e/src", diff --git a/apps/desktop-timer/src/app/app.module.ts b/apps/desktop-timer/src/app/app.module.ts index 56d8af8f628..a6a9d67a73c 100644 --- a/apps/desktop-timer/src/app/app.module.ts +++ b/apps/desktop-timer/src/app/app.module.ts @@ -40,7 +40,8 @@ import { TokenInterceptor, UnauthorizedInterceptor, UpdaterModule, - serverConnectionFactory + serverConnectionFactory, + NgxDesktopThemeModule } from '@gauzy/desktop-ui-lib'; import { environment as gauzyEnvironment } from '@gauzy/ui-config'; import { @@ -90,7 +91,8 @@ if (environment.SENTRY_DSN) { BrowserModule, BrowserAnimationsModule, AppRoutingModule, - NbThemeModule.forRoot({ name: 'gauzy-light' }), + NbThemeModule, + NgxDesktopThemeModule, NgxLoginModule, SetupModule, TimeTrackerModule, @@ -196,7 +198,7 @@ if (environment.SENTRY_DSN) { }, { provide: APP_INITIALIZER, - useFactory: () => () => {}, + useFactory: () => () => { }, deps: [Sentry.TraceService], multi: true }, @@ -212,4 +214,4 @@ if (environment.SENTRY_DSN) { bootstrap: [AppComponent], exports: [] }) -export class AppModule {} +export class AppModule { } diff --git a/apps/desktop-timer/src/assets/styles/styles.scss b/apps/desktop-timer/src/assets/styles/styles.scss index 5e1e02bf5e1..9b7d74e32b1 100644 --- a/apps/desktop-timer/src/assets/styles/styles.scss +++ b/apps/desktop-timer/src/assets/styles/styles.scss @@ -92,3 +92,7 @@ .toast-top-custom-title-bar { margin-top: 35px !important; } + +::-webkit-scrollbar { + display: none; +} diff --git a/apps/desktop-timer/src/index.ts b/apps/desktop-timer/src/index.ts index b3c73bd717f..d80f501c260 100644 --- a/apps/desktop-timer/src/index.ts +++ b/apps/desktop-timer/src/index.ts @@ -6,7 +6,7 @@ console.log = log.log; Object.assign(console, log.functions); import * as path from 'path'; -import { app, BrowserWindow, ipcMain, shell, Menu, MenuItemConstructorOptions } from 'electron'; +import { app, BrowserWindow, ipcMain, shell, Menu, MenuItemConstructorOptions, nativeTheme } from 'electron'; import { environment } from './environments/environment'; import * as Url from 'url'; import * as Sentry from '@sentry/electron'; @@ -44,7 +44,8 @@ import { ErrorEventManager, DialogErrorHandler, AppError, - UIError + UIError, + DesktopThemeListener } from '@gauzy/desktop-libs'; import { createSetupWindow, @@ -91,6 +92,18 @@ const report = new ErrorReport(new ErrorReportRepository(process.env.REPO_OWNER, const eventErrorManager = ErrorEventManager.instance; args.some((val) => val === '--serve'); +ipcMain.handle('PREFERRED_THEME', () => { + const applicationSetting = LocalStore.getStore('appSetting'); + let theme: string; + if (!applicationSetting || !applicationSetting.theme) { + theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light'; + LocalStore.updateApplicationSetting({ theme }); + } else { + theme = applicationSetting.theme; + } + return theme; +}); + let notificationWindow = null; let gauzyWindow: BrowserWindow = null; let setupWindow: BrowserWindow = null; @@ -236,12 +249,12 @@ async function startServer(value, restart = false) { project: projectConfig ? projectConfig : { - projectId: null, - taskId: null, - note: null, - aw, - organizationContactId: null - } + projectId: null, + taskId: null, + note: null, + aw, + organizationContactId: null + } }); } catch (error) { throw new AppError('MAINSTRSERVER', error); @@ -425,6 +438,15 @@ app.on('ready', async () => { } removeMainListener(); ipcMainHandler(store, startServer, knex, { ...environment }, timeTrackerWindow); + new DesktopThemeListener({ + timeTrackerWindow, + settingsWindow, + updaterWindow, + imageViewerWindow: imageView, + gauzyWindow, + splashScreenWindow: splashScreen.browserWindow, + alwaysOnWindow: alwaysOn.browserWindow + }).listen(); }); app.on('window-all-closed', () => { diff --git a/apps/desktop/src/app/app.module.ts b/apps/desktop/src/app/app.module.ts index 0249ac04897..ca3004660b4 100644 --- a/apps/desktop/src/app/app.module.ts +++ b/apps/desktop/src/app/app.module.ts @@ -31,7 +31,8 @@ import { TimeoutInterceptor, TimeTrackerModule, TokenInterceptor, - UpdaterModule + UpdaterModule, + NgxDesktopThemeModule } from '@gauzy/desktop-ui-lib'; import { environment as gauzyEnvironment } from '@gauzy/ui-config'; import { @@ -78,7 +79,8 @@ if (environment.SENTRY_DSN) { BrowserAnimationsModule, RouterModule, AppRoutingModule, - NbThemeModule.forRoot({ name: 'gauzy-light' }), + NbThemeModule, + NgxDesktopThemeModule, SetupModule, TimeTrackerModule, HttpClientModule, @@ -90,7 +92,7 @@ if (environment.SENTRY_DSN) { LanguageModule.forRoot(), AboutModule, AlwaysOnModule, - RecapModule + RecapModule, ], providers: [ AppService, @@ -129,7 +131,7 @@ if (environment.SENTRY_DSN) { }, { provide: APP_INITIALIZER, - useFactory: () => () => {}, + useFactory: () => () => { }, deps: [Sentry.TraceService], multi: true }, @@ -174,5 +176,5 @@ if (environment.SENTRY_DSN) { bootstrap: [AppComponent] }) export class AppModule { - constructor() {} + constructor() { } } diff --git a/apps/desktop/src/assets/styles/styles.scss b/apps/desktop/src/assets/styles/styles.scss index a0d29d27871..6eb2029e072 100644 --- a/apps/desktop/src/assets/styles/styles.scss +++ b/apps/desktop/src/assets/styles/styles.scss @@ -44,14 +44,18 @@ @include angular-material(); // framework global styles - @include nb-theme-global(); - @include nb-auth-global(); + @include nb-theme-global(); + @include nb-auth-global(); @include ngx-layout(); - // loading progress bar - @include ngx-pace-theme(); + // loading progress bar + @include ngx-pace-theme(); @include nb-overrides(); - @include material-overrides(); - @include gauzy-overrides(); + @include material-overrides(); + @include gauzy-overrides(); +} + +::-webkit-scrollbar { + display: none; } diff --git a/apps/desktop/src/index.ts b/apps/desktop/src/index.ts index b831c1637f3..5a4b90ece56 100644 --- a/apps/desktop/src/index.ts +++ b/apps/desktop/src/index.ts @@ -6,7 +6,7 @@ console.log = log.log; Object.assign(console, log.functions); import * as path from 'path'; -import { app, BrowserWindow, ipcMain, Menu, shell, MenuItemConstructorOptions, dialog } from 'electron'; +import { app, BrowserWindow, ipcMain, Menu, shell, MenuItemConstructorOptions, dialog, nativeTheme } from 'electron'; import * as remoteMain from '@electron/remote/main'; import { setupTitlebar } from 'custom-electron-titlebar/main'; @@ -43,7 +43,8 @@ import { ipcMainHandler, ipcTimer, removeMainListener, - removeTimerListener + removeTimerListener, + DesktopThemeListener } from '@gauzy/desktop-libs'; import { AlwaysOn, @@ -146,6 +147,18 @@ ipcMain.setMaxListeners(0); /* Remove handler if exist */ ipcMain.removeHandler('PREFERRED_LANGUAGE'); +ipcMain.handle('PREFERRED_THEME', () => { + const applicationSetting = LocalStore.getStore('appSetting'); + let theme: string; + if (!applicationSetting || !applicationSetting.theme) { + theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light'; + LocalStore.updateApplicationSetting({ theme }); + } else { + theme = applicationSetting.theme; + } + return theme; +}); + // setup logger to catch all unhandled errors and submit as bug reports to our repo log.catchErrors({ showDialog: false, @@ -517,6 +530,16 @@ app.on('ready', async () => { throw new UIError('400', error, 'MAINWININIT'); } } + + new DesktopThemeListener({ + timeTrackerWindow, + settingsWindow, + updaterWindow, + imageViewWindow: imageView, + gauzyWindow, + splashScreenWindow: splashScreen.browserWindow, + alwaysOnWindow: alwaysOn.browserWindow + }).listen() }); app.on('window-all-closed', () => { diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index dffd3e7ded8..525acd156ee 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -45,7 +45,11 @@ "../../../packages/plugins/job-employee-ui", "../../../packages/plugins/job-matching-ui", "../../../packages/plugins/job-proposal-ui", - "../../../packages/plugins/job-search-ui" + "../../../packages/plugins/job-search-ui", + "../../../packages/plugins/legal-ui", + "../../../packages/plugins/maintenance-ui", + "../../../packages/plugins/onboarding-ui", + "../../../packages/plugins/public-layout-ui" ] }, "build": { diff --git a/apps/desktop/src/preload.ts b/apps/desktop/src/preload.ts index 9145e77621e..0be7b6031b7 100644 --- a/apps/desktop/src/preload.ts +++ b/apps/desktop/src/preload.ts @@ -1,8 +1,8 @@ import { CustomTitlebar, TitlebarColor } from "custom-electron-titlebar"; import { nativeImage, ipcRenderer } from 'electron'; import * as path from 'path'; -let contentInteval; -const getElementByXpath = (path) => { +let contentInterval; +const getElementByXpath = (path) => { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } window.addEventListener('DOMContentLoaded', async () => { @@ -20,20 +20,21 @@ window.addEventListener('DOMContentLoaded', async () => { ipcRenderer.on('refresh_menu', () => { titleBar.refreshMenu(); }); + ipcRenderer.on('adjust_view', () => { - clearInterval(contentInteval); + clearInterval(contentInterval); const headerIcon = '/html/body/div[2]/ga-app/ngx-pages/ngx-one-column-layout/nb-layout/div[1]/div/div/nb-sidebar[1]/div/div/div'; const headerCompany = '/html/body/div[2]/ga-app/ngx-pages/ngx-one-column-layout/nb-layout/div[1]/div/div/nb-sidebar[2]/div/div/div/div[1]/div'; - contentInteval = setInterval(() => { - const elHeaderIcon:any = getElementByXpath(headerIcon); - const elHeaderCompany:any = getElementByXpath(headerCompany); + contentInterval = setInterval(() => { + const elHeaderIcon: any = getElementByXpath(headerIcon); + const elHeaderCompany: any = getElementByXpath(headerCompany); if (elHeaderIcon) { elHeaderIcon.style.marginTop = '30px'; - clearInterval(contentInteval); + clearInterval(contentInterval); } if (elHeaderCompany) { elHeaderCompany.style.marginTop = '30px'; - clearInterval(contentInteval); + clearInterval(contentInterval); } }, 1000) }); diff --git a/apps/gauzy-e2e/src/support/Base/pageobjects/AppointmentsPageObject.ts b/apps/gauzy-e2e/src/support/Base/pageobjects/AppointmentsPageObject.ts index f58ff7aaa9e..e3b6b23960d 100644 --- a/apps/gauzy-e2e/src/support/Base/pageobjects/AppointmentsPageObject.ts +++ b/apps/gauzy-e2e/src/support/Base/pageobjects/AppointmentsPageObject.ts @@ -1,28 +1,22 @@ export const AppointmentsPage = { - bookPublicAppointmentButtonCss: - 'div.main-header > div > button[status="success"]', + bookPublicAppointmentButtonCss: 'div.main-header > div > button[status="success"]', employeeDropdownCss: 'ga-employee-selector > ng-select', - employeeDropdownOptionsCss: - 'ng-dropdown-panel > div.ng-dropdown-panel-items div.ng-option', + employeeDropdownOptionsCss: 'ng-dropdown-panel > div.ng-dropdown-panel-items div.ng-option', bookAppointmentButtonCss: 'div.center-div > button[status="success"]', headerCss: 'div.main-header > h4', employeeNameCss: 'div.employee-details > span.employee-name', - appointmentButtonsCss: 'ga-appointment-calendar button[status="success"]', + appointmentButtonsCss: 'ngx-appointment-calendar button[status="success"]', dateSpecificAvailabilityTabCss: 'nb-route-tabset > ul.route-tabset > li', eventTypeButtonsCss: 'button[status="success"]', calendarTableCss: 'table.fc-scrollgrid', - calendarTableRowCss: - '.fc-timegrid-slots > table > tbody > tr:nth-child(3) > td:nth-child(2)', - availableTimeCalendarTableRowsCss: - '.fc-timegrid-event[style="background-color: green;"]', + calendarTableRowCss: '.fc-timegrid-slots > table > tbody > tr:nth-child(3) > td:nth-child(2)', + availableTimeCalendarTableRowsCss: '.fc-timegrid-event[style="background-color: green;"]', agendaInputFieldCss: 'input[placeholder="Agenda"]', bufferTimeCheckboxCss: 'nb-checkbox[formcontrolname="bufferTime"]', bufferMinutesInputFieldCss: '#bufferTimeInMins', breakTimeCheckboxCss: 'nb-checkbox[formcontrolname="breakTime"]', - breakTimeDateDropdownCss: - 'ga-timer-picker[formcontrolname="breakStartTime"] ng-select', - breakTimeDateDropdownOptionsCss: - 'ng-dropdown-panel > div.ng-dropdown-panel-items div.ng-option', + breakTimeDateDropdownCss: 'ga-timer-picker[formcontrolname="breakStartTime"] ng-select', + breakTimeDateDropdownOptionsCss: 'ng-dropdown-panel > div.ng-dropdown-panel-items div.ng-option', breakTimeMinutesInputCss: '#breakTimeInMins', locationInputCss: 'input#location', descriptionFieldCss: 'input#description', @@ -31,5 +25,4 @@ export const AppointmentsPage = { appointmentConfirmedCss: 'nb-card h4.ng-star-inserted', appointmentDetails: '.p-2 span', selectEmployeeDropdownOptionCss: 'nb-option-list > ul.option-list > nb-option' - }; diff --git a/apps/gauzy/package.json b/apps/gauzy/package.json index 6864ac4a245..5d41c85beb5 100644 --- a/apps/gauzy/package.json +++ b/apps/gauzy/package.json @@ -60,6 +60,13 @@ "@fullcalendar/moment-timezone": "~6.1.10", "@fullcalendar/timegrid": "~6.1.10", "@gauzy/contracts": "^0.1.0", + "@gauzy/plugin-job-employee-ui": "^0.1.0", + "@gauzy/plugin-job-proposal-ui": "^0.1.0", + "@gauzy/plugin-job-search-ui": "^0.1.0", + "@gauzy/plugin-legal-ui": "^0.1.0", + "@gauzy/plugin-maintenance-ui": "^0.1.0", + "@gauzy/plugin-onboarding-ui": "^0.1.0", + "@gauzy/plugin-public-layout-ui": "^0.1.0", "@gauzy/ui-config": "^0.1.0", "@gauzy/ui-core": "^0.1.0", "@jitsu/js": "^1.8.2", diff --git a/apps/gauzy/src/app/app.component.ts b/apps/gauzy/src/app/app.component.ts index d919718ab07..3f688a1c5c1 100644 --- a/apps/gauzy/src/app/app.component.ts +++ b/apps/gauzy/src/app/app.component.ts @@ -9,6 +9,9 @@ import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, map, mergeMap, take, tap } from 'rxjs'; import { pluck, union } from 'underscore'; +import { IDateRangePicker, ILanguage, LanguagesEnum } from '@gauzy/contracts'; +import { environment } from '@gauzy/ui-config'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { AnalyticsService, DEFAULT_DATE_PICKER_CONFIG, @@ -19,12 +22,10 @@ import { JitsuService, LanguagesService, SelectorBuilderService, - SeoService + SeoService, + Store } from '@gauzy/ui-core/core'; -import { IDateRangePicker, ILanguage, LanguagesEnum } from '@gauzy/contracts'; -import { distinctUntilChange, isNotEmpty, Store } from '@gauzy/ui-core/common'; import { I18nService } from '@gauzy/ui-core/i18n'; -import { environment } from '@gauzy/ui-config'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/app.module.guard.ts b/apps/gauzy/src/app/app.module.guard.ts index c1058647fbf..915c37794ac 100644 --- a/apps/gauzy/src/app/app.module.guard.ts +++ b/apps/gauzy/src/app/app.module.guard.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router'; import { environment } from '@gauzy/ui-config'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Injectable() export class AppModuleGuard implements CanActivate { diff --git a/apps/gauzy/src/app/app.module.ts b/apps/gauzy/src/app/app.module.ts index f7abf5ff33f..91c761b1d0e 100644 --- a/apps/gauzy/src/app/app.module.ts +++ b/apps/gauzy/src/app/app.module.ts @@ -42,10 +42,11 @@ import { LanguageInterceptor, SentryErrorHandler, ServerConnectionService, + Store, TenantInterceptor, TokenInterceptor } from '@gauzy/ui-core/core'; -import { CommonModule, Store } from '@gauzy/ui-core/common'; +import { CommonModule } from '@gauzy/ui-core/common'; import { HttpLoaderFactory, I18nModule, I18nService } from '@gauzy/ui-core/i18n'; import { SharedModule, TimeTrackerModule, dayOfWeekAsString } from '@gauzy/ui-core/shared'; import { ThemeModule } from '@gauzy/ui-core/theme'; diff --git a/apps/gauzy/src/app/app.routes.ts b/apps/gauzy/src/app/app.routes.ts index 5d4e400a664..fdf16544d9c 100644 --- a/apps/gauzy/src/app/app.routes.ts +++ b/apps/gauzy/src/app/app.routes.ts @@ -11,9 +11,13 @@ export const appRoutes: Routes = [ loadChildren: () => import('@gauzy/ui-auth').then((m) => m.NgxAuthModule), canActivate: [] }, + { + path: 'sign-in', + loadChildren: () => import('@gauzy/ui-auth').then((m) => m.SignInSuccessModule) + }, { path: 'onboarding', - loadChildren: () => import('./onboarding/onboarding.module').then((m) => m.OnboardingModule), + loadChildren: () => import('@gauzy/plugin-onboarding-ui').then((m) => m.OnboardingModule), canActivate: [AuthGuard, AppModuleGuard] }, { @@ -23,20 +27,16 @@ export const appRoutes: Routes = [ }, { path: 'share', - loadChildren: () => import('./share/share.module').then((m) => m.ShareModule), + loadChildren: () => import('@gauzy/plugin-public-layout-ui').then((m) => m.PublicLayoutModule), canActivate: [] }, - { - path: 'server-down', - loadChildren: () => import('./server-down/server-down.module').then((m) => m.ServerDownModule) - }, { path: 'legal', - loadChildren: () => import('./legal/legal.module').then((m) => m.LegalModule) + loadChildren: () => import('@gauzy/plugin-legal-ui').then((m) => m.LegalModule) }, { - path: 'sign-in', - loadChildren: () => import('@gauzy/ui-auth').then((m) => m.SignInSuccessModule) + path: 'server-down', + loadChildren: () => import('@gauzy/plugin-maintenance-ui').then((m) => m.MaintenanceModeModule) }, { path: '', diff --git a/apps/gauzy/src/app/legal/legal-routing.module.ts b/apps/gauzy/src/app/legal/legal-routing.module.ts deleted file mode 100644 index 0ef34c67a79..00000000000 --- a/apps/gauzy/src/app/legal/legal-routing.module.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { NbAuthComponent } from '@nebular/auth'; -import { PrivacyPolicyComponent, TermsAndConditionsComponent } from '@gauzy/ui-core/shared'; - -export const routes: Routes = [ - { - path: 'legal', - component: NbAuthComponent, - children: [ - { - path: 'terms', - component: TermsAndConditionsComponent - }, - { - path: 'privacy', - component: PrivacyPolicyComponent - } - ] - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class LegalRoutingModule {} diff --git a/apps/gauzy/src/app/legal/legal.module.ts b/apps/gauzy/src/app/legal/legal.module.ts deleted file mode 100644 index 7891739ca3a..00000000000 --- a/apps/gauzy/src/app/legal/legal.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NgModule } from '@angular/core'; -import { MainLegalModule } from '@gauzy/ui-core/shared'; -import { LegalRoutingModule } from './legal-routing.module'; - -@NgModule({ - imports: [LegalRoutingModule, MainLegalModule], - declarations: [] -}) -export class LegalModule {} diff --git a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete-routing.module.ts b/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete-routing.module.ts deleted file mode 100644 index 837ff3e3303..00000000000 --- a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete-routing.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { OrganizationsStepFormModule } from '@gauzy/ui-core/shared'; -import { OnboardingCompleteComponent } from './onboarding-complete.component'; - -const routes: Routes = [ - { - path: '', - component: OnboardingCompleteComponent - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes), OrganizationsStepFormModule], - exports: [RouterModule] -}) -export class OnboardingCompleteRoutingModule {} diff --git a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.ts b/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.ts deleted file mode 100644 index c45cc93264e..00000000000 --- a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { Observable } from 'rxjs'; -import { TranslateService } from '@ngx-translate/core'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { NgxPermissionsService } from 'ngx-permissions'; -import { IFeature, IUser } from '@gauzy/contracts'; -import { FeatureStoreService, UsersService } from '@gauzy/ui-core/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'ga-onboarding-complete', - templateUrl: './onboarding-complete.component.html', - styleUrls: ['./onboarding-complete.component.scss'] -}) -export class OnboardingCompleteComponent extends TranslationBaseComponent implements OnInit { - constructor( - private router: Router, - public readonly translationService: TranslateService, - private readonly store: Store, - private usersService: UsersService, - private ngxPermissionsService: NgxPermissionsService, - private readonly _featureStoreService: FeatureStoreService - ) { - super(translationService); - } - - blocks$: Observable = this._featureStoreService.blocks$; - features$: Observable = this._featureStoreService.features$; - - ngOnInit() { - const id = this.store.userId; - if (!id) return; - - this.usersService - .getMe(['role', 'role.rolePermissions', 'tenant']) - .then((user: IUser) => { - //only enabled permissions assign to logged in user - const permissions = user.role.rolePermissions - .filter(({ enabled }) => enabled) - .map(({ permission }) => permission); - this.ngxPermissionsService.loadPermissions(permissions); - }) - .catch() - .finally(() => this.getFeatures()); - } - - getFeatures() { - this._featureStoreService.loadFeatures(['children']).pipe(untilDestroyed(this)).subscribe(); - } - - navigateTo(link: string) { - const url = `pages/${link}`; - this.router.navigate([url]); - } -} diff --git a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.module.ts b/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.module.ts deleted file mode 100644 index e691b11b95d..00000000000 --- a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbButtonModule, NbCardModule, NbIconModule } from '@nebular/theme'; -import { TenantService } from '@gauzy/ui-core/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { FeatureToggleModule } from '@gauzy/ui-core/shared'; -import { ThemeModule, ThemeSelectorModule } from '@gauzy/ui-core/theme'; -import { OnboardingCompleteRoutingModule } from './onboarding-complete-routing.module'; -import { OnboardingCompleteComponent } from './onboarding-complete.component'; - -@NgModule({ - imports: [ - CommonModule, - NbButtonModule, - NbCardModule, - NbIconModule, - TranslateModule.forChild(), - ThemeModule, - OnboardingCompleteRoutingModule, - FeatureToggleModule, - ThemeSelectorModule - ], - providers: [TenantService], - declarations: [OnboardingCompleteComponent] -}) -export class OnboardingCompleteModule {} diff --git a/apps/gauzy/src/app/onboarding/onboarding-routing.module.ts b/apps/gauzy/src/app/onboarding/onboarding-routing.module.ts deleted file mode 100644 index fd6c30b9aab..00000000000 --- a/apps/gauzy/src/app/onboarding/onboarding-routing.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { RouterModule, Routes } from '@angular/router'; -import { NgModule } from '@angular/core'; -import { OnboardingComponent } from './onboarding.component'; - -const routes: Routes = [ - { - path: '', - component: OnboardingComponent, - children: [ - { - path: 'tenant', - loadChildren: () => - import('./tenant-onboarding/tenant-onboarding.module').then((m) => m.TenantOnboardingModule) - }, - { - path: 'complete', - loadChildren: () => - import('./onboarding-complete/onboarding-complete.module').then((m) => m.OnboardingCompleteModule) - } - ] - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class OnboardingRoutingModule {} diff --git a/apps/gauzy/src/app/onboarding/onboarding.module.ts b/apps/gauzy/src/app/onboarding/onboarding.module.ts deleted file mode 100644 index 6feecb3f31e..00000000000 --- a/apps/gauzy/src/app/onboarding/onboarding.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbLayoutModule, NbSpinnerModule } from '@nebular/theme'; -import { AuthService, RoleGuard } from '@gauzy/ui-core/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { ThemeModule, ThemeSettingsModule } from '@gauzy/ui-core/theme'; -import { OnboardingRoutingModule } from './onboarding-routing.module'; -import { OnboardingComponent } from './onboarding.component'; - -@NgModule({ - imports: [ - CommonModule, - NbLayoutModule, - NbSpinnerModule, - ThemeModule, - TranslateModule.forChild(), - OnboardingRoutingModule, - ThemeSettingsModule - ], - declarations: [OnboardingComponent], - providers: [AuthService, RoleGuard] -}) -export class OnboardingModule {} diff --git a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding-routing.module.ts b/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding-routing.module.ts deleted file mode 100644 index efcd2575280..00000000000 --- a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding-routing.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { OrganizationsStepFormModule } from '@gauzy/ui-core/shared'; -import { OnboardingResolver } from '@gauzy/ui-core/core'; -import { TenantOnboardingComponent } from './tenant-onboarding.component'; - -const routes: Routes = [ - { - path: '', - component: TenantOnboardingComponent, - resolve: { - user: OnboardingResolver - } - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes), OrganizationsStepFormModule], - exports: [RouterModule] -}) -export class TenantDetailsRoutingModule {} diff --git a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.module.ts b/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.module.ts deleted file mode 100644 index 5a8164e16f6..00000000000 --- a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbSpinnerModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { TagsService, TenantService } from '@gauzy/ui-core/core'; -import { OrganizationsStepFormModule } from '@gauzy/ui-core/shared'; -import { ThemeModule, ThemeSelectorModule } from '@gauzy/ui-core/theme'; -import { TenantDetailsRoutingModule } from './tenant-onboarding-routing.module'; -import { TenantOnboardingComponent } from './tenant-onboarding.component'; - -@NgModule({ - imports: [ - CommonModule, - NbSpinnerModule, - TranslateModule.forChild(), - ThemeModule, - TenantDetailsRoutingModule, - OrganizationsStepFormModule, - ThemeSelectorModule - ], - providers: [TenantService, TagsService], - declarations: [TenantOnboardingComponent] -}) -export class TenantOnboardingModule {} diff --git a/apps/gauzy/src/app/pages/about/about.component.ts b/apps/gauzy/src/app/pages/about/about.component.ts index 01404437761..df8c93d91c4 100644 --- a/apps/gauzy/src/app/pages/about/about.component.ts +++ b/apps/gauzy/src/app/pages/about/about.component.ts @@ -1,12 +1,11 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Store } from '@gauzy/ui-core/common'; @Component({ selector: 'ngx-about', templateUrl: './about.component.html' }) export class AboutComponent implements OnInit, OnDestroy { - constructor(private readonly store: Store) {} + constructor() {} ngOnInit() {} diff --git a/apps/gauzy/src/app/pages/accounting-templates/accounting-templates.component.ts b/apps/gauzy/src/app/pages/accounting-templates/accounting-templates.component.ts index 6eac52d05eb..25f8f9ff232 100644 --- a/apps/gauzy/src/app/pages/accounting-templates/accounting-templates.component.ts +++ b/apps/gauzy/src/app/pages/accounting-templates/accounting-templates.component.ts @@ -7,8 +7,8 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { AceEditorComponent } from 'ngx-ace-editor-wrapper'; import { NbThemeService } from '@nebular/theme'; import { AccountingTemplateTypeEnum, IOrganization, LanguagesEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { AccountingTemplateService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { AccountingTemplateService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/approval-policy/approval-policy.component.ts b/apps/gauzy/src/app/pages/approval-policy/approval-policy.component.ts index 36595483aa0..d29784cf017 100644 --- a/apps/gauzy/src/app/pages/approval-policy/approval-policy.component.ts +++ b/apps/gauzy/src/app/pages/approval-policy/approval-policy.component.ts @@ -5,9 +5,9 @@ import { Subject, firstValueFrom } from 'rxjs'; import { NbDialogService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { ApprovalPolicyService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { ApprovalPolicyService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { IApprovalPolicy, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { ApprovalPolicyMutationComponent, DeleteConfirmationComponent, diff --git a/apps/gauzy/src/app/pages/approvals/approvals.component.ts b/apps/gauzy/src/app/pages/approvals/approvals.component.ts index 7912981d348..76f96cf91cf 100644 --- a/apps/gauzy/src/app/pages/approvals/approvals.component.ts +++ b/apps/gauzy/src/app/pages/approvals/approvals.component.ts @@ -15,8 +15,8 @@ import { IRequestApproval, RequestApprovalStatusTypesEnum } from '@gauzy/contracts'; -import { RequestApprovalService, ToastrService } from '@gauzy/ui-core/core'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { RequestApprovalService, Store, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { PaginationFilterBaseComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/approvals/table-components/request-approval-action/request-approval-action.component.ts b/apps/gauzy/src/app/pages/approvals/table-components/request-approval-action/request-approval-action.component.ts index e151bcde699..0e949262166 100644 --- a/apps/gauzy/src/app/pages/approvals/table-components/request-approval-action/request-approval-action.component.ts +++ b/apps/gauzy/src/app/pages/approvals/table-components/request-approval-action/request-approval-action.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'; import { RequestApprovalStatusTypesEnum, ComponentLayoutStyleEnum, RolesEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ngx-request-approval-action', diff --git a/apps/gauzy/src/app/pages/candidates/candidate-statistic/candidate-statistic.component.ts b/apps/gauzy/src/app/pages/candidates/candidate-statistic/candidate-statistic.component.ts index 75aa47f6b05..6449d5d535a 100644 --- a/apps/gauzy/src/app/pages/candidates/candidate-statistic/candidate-statistic.component.ts +++ b/apps/gauzy/src/app/pages/candidates/candidate-statistic/candidate-statistic.component.ts @@ -7,9 +7,10 @@ import { CandidateInterviewService, CandidatesService, EmployeesService, - ErrorHandlingService + ErrorHandlingService, + Store } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/candidates/candidates.component.ts b/apps/gauzy/src/app/pages/candidates/candidates.component.ts index adce7a3fd68..5ada1adcc46 100644 --- a/apps/gauzy/src/app/pages/candidates/candidates.component.ts +++ b/apps/gauzy/src/app/pages/candidates/candidates.component.ts @@ -15,8 +15,8 @@ import { firstValueFrom, Subject } from 'rxjs'; import { NbDialogService } from '@nebular/theme'; import { Router, ActivatedRoute } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { CandidatesService, ErrorHandlingService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { CandidatesService, ErrorHandlingService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { PaginationFilterBaseComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-documents/edit-candidate-documents.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-documents/edit-candidate-documents.component.ts index 3b92e80ca2c..e02e543aefa 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-documents/edit-candidate-documents.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-documents/edit-candidate-documents.component.ts @@ -5,8 +5,8 @@ import { tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { LocalDataSource } from 'angular2-smart-table'; import { ICandidateDocument, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { CandidateDocumentsService, CandidateStore, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { CandidateDocumentsService, CandidateStore, Store, ToastrService } from '@gauzy/ui-core/core'; import { CandidateCvComponent, DocumentDateTableComponent, diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-employment/edit-candidate-employment.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-employment/edit-candidate-employment.component.ts index 0aa21efb5bb..993352931f8 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-employment/edit-candidate-employment.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-employment/edit-candidate-employment.component.ts @@ -19,7 +19,7 @@ import { OrganizationPositionsService } from '@gauzy/ui-core/core'; import { ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-education/edit-candidate-education.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-education/edit-candidate-education.component.ts index cd7f6016049..2acb7960033 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-education/edit-candidate-education.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-education/edit-candidate-education.component.ts @@ -4,8 +4,8 @@ import { UntypedFormGroup, UntypedFormBuilder, FormArray, Validators } from '@an import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ICandidateEducation, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; import { LocalDataSource, Cell } from 'angular2-smart-table'; -import { ComponentEnum, Store } from '@gauzy/ui-core/common'; -import { CandidateEducationsService, CandidateStore, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum } from '@gauzy/ui-core/common'; +import { CandidateEducationsService, CandidateStore, Store, ToastrService } from '@gauzy/ui-core/core'; import { tap } from 'rxjs/operators'; import { DateViewComponent, PaginationFilterBaseComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-experience/edit-candidate-experience-form.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-experience/edit-candidate-experience-form.component.ts index fedad36120b..ff57b7d36a7 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-experience/edit-candidate-experience-form.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-experience/edit-candidate-experience-form.component.ts @@ -4,10 +4,10 @@ import { UntypedFormGroup, UntypedFormBuilder, FormArray, Validators } from '@an import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { ICandidateExperience, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; -import { ComponentEnum, Store } from '@gauzy/ui-core/common'; +import { ComponentEnum } from '@gauzy/ui-core/common'; import { LocalDataSource } from 'angular2-smart-table'; import { PaginationFilterBaseComponent } from '@gauzy/ui-core/shared'; -import { CandidateExperienceService, CandidateStore, ToastrService } from '@gauzy/ui-core/core'; +import { CandidateExperienceService, CandidateStore, Store, ToastrService } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-edit-candidate-experience-form', diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-skills/edit-candidate-skills.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-skills/edit-candidate-skills.component.ts index 0fb75ab0624..5b5abfd6bac 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-skills/edit-candidate-skills.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-experience/edit-candidate-skills/edit-candidate-skills.component.ts @@ -5,9 +5,9 @@ import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { takeUntil } from 'rxjs/operators'; import { UntypedFormGroup, UntypedFormBuilder, FormArray, Validators } from '@angular/forms'; import { ISkill, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; -import { ComponentEnum, Store } from '@gauzy/ui-core/common'; +import { ComponentEnum } from '@gauzy/ui-core/common'; import { LocalDataSource } from 'angular2-smart-table'; -import { CandidateSkillsService, CandidateStore, ToastrService } from '@gauzy/ui-core/core'; +import { CandidateSkillsService, CandidateStore, Store, ToastrService } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-edit-candidate-skills', diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-feedbacks/edit-candidate-feedbacks.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-feedbacks/edit-candidate-feedbacks.component.ts index 881602ba8dd..f1cbde34c12 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-feedbacks/edit-candidate-feedbacks.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-feedbacks/edit-candidate-feedbacks.component.ts @@ -16,7 +16,7 @@ import { IOrganization } from '@gauzy/contracts'; import { LocalDataSource, Cell } from 'angular2-smart-table'; -import { ComponentEnum, Store } from '@gauzy/ui-core/common'; +import { ComponentEnum } from '@gauzy/ui-core/common'; import { CandidateCriterionsRatingService, CandidateFeedbacksService, @@ -24,6 +24,7 @@ import { CandidatesService, CandidateStore, EmployeesService, + Store, ToastrService } from '@gauzy/ui-core/core'; import { DeleteFeedbackComponent, PaginationFilterBaseComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-interview/edit-candidate-interview.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-interview/edit-candidate-interview.component.ts index d443e987cb4..894a04dd002 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-interview/edit-candidate-interview.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-interview/edit-candidate-interview.component.ts @@ -21,9 +21,10 @@ import { CandidatesService, CandidateStore, EmployeesService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { ComponentEnum, Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { ComponentEnum, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { CandidateInterviewFeedbackComponent, CandidateInterviewMutationComponent, diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-main/edit-candidate-main.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-main/edit-candidate-main.component.ts index afb3eb94ff0..e76fa0ff9af 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-main/edit-candidate-main.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-main/edit-candidate-main.component.ts @@ -4,8 +4,8 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { combineLatest } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { IOrganization, ICandidate, IImageAsset } from '@gauzy/contracts'; -import { CandidateStore, ToastrService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { CandidateStore, Store, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; /** * This component contains the properties stored within the User Entity of an candidate. diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-profile.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-profile.component.ts index 0b01a88f923..4dda3fb02da 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-profile.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate-profile/edit-candidate-profile.component.ts @@ -19,7 +19,7 @@ import { UsersService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { CandidateInterviewInfoComponent } from '@gauzy/ui-core/shared'; import { firstValueFrom } from 'rxjs'; diff --git a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate.component.ts b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate.component.ts index 73f6042b2fd..c75d7067372 100644 --- a/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate.component.ts +++ b/apps/gauzy/src/app/pages/candidates/edit-candidate/edit-candidate.component.ts @@ -3,7 +3,7 @@ import { Router, ActivatedRoute } from '@angular/router'; import { PermissionsEnum, ICandidate, ICandidateInterview } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; import { Subject, firstValueFrom } from 'rxjs'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { takeUntil } from 'rxjs/operators'; import { CandidateInterviewService, CandidatesService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-calendar/interview-calendar.component.ts b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-calendar/interview-calendar.component.ts index 3f21b96577d..8068ae4c314 100644 --- a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-calendar/interview-calendar.component.ts +++ b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-calendar/interview-calendar.component.ts @@ -15,8 +15,14 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IEmployee, IDateRange, ICandidateInterview, IOrganization, IPagination } from '@gauzy/contracts'; import * as moment from 'moment'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { CandidateInterviewService, EmployeesService, ErrorHandlingService, ToastrService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { + CandidateInterviewService, + EmployeesService, + ErrorHandlingService, + Store, + ToastrService +} from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { CandidateInterviewInfoComponent, CandidateInterviewMutationComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-personal-qualities/candidate-personal-qualities.component.ts b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-personal-qualities/candidate-personal-qualities.component.ts index acc90142969..b69fa25c9a4 100644 --- a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-personal-qualities/candidate-personal-qualities.component.ts +++ b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-personal-qualities/candidate-personal-qualities.component.ts @@ -6,7 +6,7 @@ import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ICandidatePersonalQualities, IOrganization } from '@gauzy/contracts'; import { takeUntil } from 'rxjs/operators'; import { CandidatePersonalQualitiesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-candidate-personal-qualities', diff --git a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-technologies/candidate-technologies.component.ts b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-technologies/candidate-technologies.component.ts index 77c54a6908a..77de60a96cd 100644 --- a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-technologies/candidate-technologies.component.ts +++ b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-criterions/candidate-technologies/candidate-technologies.component.ts @@ -6,7 +6,7 @@ import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ICandidateTechnologies, IOrganization } from '@gauzy/contracts'; import { takeUntil } from 'rxjs/operators'; import { CandidateTechnologiesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-candidate-technologies', diff --git a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-panel/interview-panel.component.ts b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-panel/interview-panel.component.ts index 3ca2ead5524..a35b6ceb060 100644 --- a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-panel/interview-panel.component.ts +++ b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/interview-panel/interview-panel.component.ts @@ -15,7 +15,7 @@ import { Router } from '@angular/router'; import { NbDialogService } from '@nebular/theme'; import { Cell, LocalDataSource } from 'angular2-smart-table'; import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { InterviewStarRatingComponent } from './table-components/rating/rating.component'; import { ComponentEnum } from '@gauzy/ui-core/common'; import { @@ -25,6 +25,7 @@ import { CandidateStore, EmployeesService, ErrorHandlingService, + Store, ToastrService } from '@gauzy/ui-core/core'; import { diff --git a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/manage-candidate-interviews.component.ts b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/manage-candidate-interviews.component.ts index 0ed5cd1b6d6..0eb94d65063 100644 --- a/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/manage-candidate-interviews.component.ts +++ b/apps/gauzy/src/app/pages/candidates/manage-candidate-interviews/manage-candidate-interviews.component.ts @@ -7,7 +7,7 @@ import { NbDialogService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ActivatedRoute } from '@angular/router'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidateInterviewService, ToastrService } from '@gauzy/ui-core/core'; import { CandidateInterviewMutationComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/contacts/contact-mutation/contact-mutation.component.ts b/apps/gauzy/src/app/pages/contacts/contact-mutation/contact-mutation.component.ts index 15c42b57086..12bbb2f1cc5 100644 --- a/apps/gauzy/src/app/pages/contacts/contact-mutation/contact-mutation.component.ts +++ b/apps/gauzy/src/app/pages/contacts/contact-mutation/contact-mutation.component.ts @@ -15,10 +15,10 @@ import { debounceTime, filter, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { LatLng } from 'leaflet'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FilterArrayPipe, FormHelpers, LeafletMapComponent, LocationFormComponent } from '@gauzy/ui-core/shared'; -import { ErrorHandlingService, OrganizationProjectsService, ToastrService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, OrganizationProjectsService, Store, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/contacts/contact-view/contact-view.component.ts b/apps/gauzy/src/app/pages/contacts/contact-view/contact-view.component.ts index ff6507c62da..4ef76cbb73d 100644 --- a/apps/gauzy/src/app/pages/contacts/contact-view/contact-view.component.ts +++ b/apps/gauzy/src/app/pages/contacts/contact-view/contact-view.component.ts @@ -7,7 +7,7 @@ import { LatLng } from 'leaflet'; import { firstValueFrom } from 'rxjs'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FilterArrayPipe, LeafletMapComponent } from '@gauzy/ui-core/shared'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeesService, OrganizationContactService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @@ -99,9 +99,10 @@ export class ContactViewComponent extends TranslationBaseComponent implements On name: this.selectedContact.name, organizationId: this.selectedContact.organizationId, id: this.selectedContact.id, - members: this.selectedMembers + members: this.selectedMembers, + contactType: this.selectedContact.contactType }; - await this.organizationContactService.create(organizationContactData); + await this.organizationContactService.update(this.selectedContact.id, organizationContactData); } } diff --git a/apps/gauzy/src/app/pages/contacts/contacts.component.ts b/apps/gauzy/src/app/pages/contacts/contacts.component.ts index b55b99268e5..8ff6e356177 100644 --- a/apps/gauzy/src/app/pages/contacts/contacts.component.ts +++ b/apps/gauzy/src/app/pages/contacts/contacts.component.ts @@ -24,9 +24,10 @@ import { OrganizationContactService, OrganizationProjectsService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { InviteContactComponent } from './invite-contact/invite-contact.component'; import { ContactWithTagsComponent, diff --git a/apps/gauzy/src/app/pages/dashboard/accounting/accounting.component.ts b/apps/gauzy/src/app/pages/dashboard/accounting/accounting.component.ts index 7fa295109ff..ae513bd0f1b 100644 --- a/apps/gauzy/src/app/pages/dashboard/accounting/accounting.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/accounting/accounting.component.ts @@ -12,10 +12,11 @@ import { DateRangePickerBuilderService, EmployeeStatisticsService, EmployeesService, + Store, ToastrService } from '@gauzy/ui-core/core'; import { IAggregatedEmployeeStatistic, IDateRangePicker, IOrganization, ISelectedEmployee } from '@gauzy/contracts'; -import { distinctUntilChange, isEmpty, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { ALL_EMPLOYEES_SELECTED, ChartUtil, IChartData } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/dashboard/dashboard-routing.module.ts b/apps/gauzy/src/app/pages/dashboard/dashboard-routing.module.ts index e3e8bb91abb..f0cb4df902b 100644 --- a/apps/gauzy/src/app/pages/dashboard/dashboard-routing.module.ts +++ b/apps/gauzy/src/app/pages/dashboard/dashboard-routing.module.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { PermissionsGuard } from '@gauzy/ui-core/core'; +import { PermissionsGuard, TabsetRegistryIdEnum } from '@gauzy/ui-core/core'; import { PermissionsEnum } from '@gauzy/contracts'; import { DateRangePickerResolver } from '@gauzy/ui-core/shared'; import { DashboardComponent } from './dashboard.component'; @@ -14,6 +14,7 @@ const routes: Routes = [ { path: '', component: DashboardComponent, + data: { tabsetId: TabsetRegistryIdEnum.Dashboard }, children: [ { path: '', diff --git a/apps/gauzy/src/app/pages/dashboard/dashboard.component.html b/apps/gauzy/src/app/pages/dashboard/dashboard.component.html index 0c5f7087aad..1db15796d0c 100644 --- a/apps/gauzy/src/app/pages/dashboard/dashboard.component.html +++ b/apps/gauzy/src/app/pages/dashboard/dashboard.component.html @@ -1,4 +1,3 @@ -
- - +
+
diff --git a/apps/gauzy/src/app/pages/dashboard/dashboard.component.scss b/apps/gauzy/src/app/pages/dashboard/dashboard.component.scss index 2bc8076d628..94ef632fb0a 100644 --- a/apps/gauzy/src/app/pages/dashboard/dashboard.component.scss +++ b/apps/gauzy/src/app/pages/dashboard/dashboard.component.scss @@ -1,157 +1,157 @@ @import 'var'; .header { - padding: 30px; - - .header-container { - display: flex; - justify-content: space-between; - - .employee-info, - .org-info { - display: flex; - - .employee-image, - .org-image { - max-width: 70px; - max-height: 70px; - border-radius: 13px; - margin-right: 24px; - margin-left: 24px; - } - } - - .employee-details, - .org-details { - display: flex; - flex-direction: column; - justify-content: center; - - .employee-name, - .org-name { - font-weight: bold; - font-size: 18px; - } - - .employee-position, - .org-position { - font-size: 14px; - } - } - } + padding: 30px; + + .header-container { + display: flex; + justify-content: space-between; + + .employee-info, + .org-info { + display: flex; + + .employee-image, + .org-image { + max-width: 70px; + max-height: 70px; + border-radius: 13px; + margin-right: 24px; + margin-left: 24px; + } + } + + .employee-details, + .org-details { + display: flex; + flex-direction: column; + justify-content: center; + + .employee-name, + .org-name { + font-weight: bold; + font-size: 18px; + } + + .employee-position, + .org-position { + font-size: 14px; + } + } + } } .open { - cursor: pointer; + cursor: pointer; } .body { - padding: 36px; - display: flex; - justify-content: space-between; - - .half-content { - width: 49%; - } - - .info-block { - &:hover { - box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.26); - transform: translateY(-1px); - } - - display: flex; - justify-content: space-between; - margin-bottom: 20px; - width: 100%; - height: 84px; - border-radius: 4px; - padding: 29px; - background-color: #f6f9fc; - cursor: pointer; - .info-text, - .info-value { - display: flex; - font-size: 18px; - color: #333333; - - .profit-positive-color { - color: #66de0b; - } - - .profit-negative-color { - color: #ff7b00; - } - - .expense-color { - color: #dbc300; - } - - .income-color { - color: #089c17; - } - } - - .info-text { - flex-direction: column; - justify-content: center; - } - - .info-value { - flex-direction: row; - align-items: center; - - span { - font-size: 24px; - margin-right: 12px; - } - } - } - - .bonus { - display: flex; - flex-direction: column; - align-items: flex-end; - width: 100%; - - .bonus-value { - margin-right: 39px; - - :first-child { - text-align: right; - font-size: 16px; - margin-bottom: 15px; - margin-right: 3px; - } - - :last-child { - font-size: 46px; - font-weight: bold; - color: #0091ff; - } - - .negative-bonus-color { - color: red; - } - } - - .bonus-disclaimer { - margin-top: 15px; - margin-right: 39px; - font-size: 0.7rem; - width: 215px; - } - } + padding: 36px; + display: flex; + justify-content: space-between; + + .half-content { + width: 49%; + } + + .info-block { + &:hover { + box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.26); + transform: translateY(-1px); + } + + display: flex; + justify-content: space-between; + margin-bottom: 20px; + width: 100%; + height: 84px; + border-radius: 4px; + padding: 29px; + background-color: #f6f9fc; + cursor: pointer; + .info-text, + .info-value { + display: flex; + font-size: 18px; + color: #333333; + + .profit-positive-color { + color: #66de0b; + } + + .profit-negative-color { + color: #ff7b00; + } + + .expense-color { + color: #dbc300; + } + + .income-color { + color: #089c17; + } + } + + .info-text { + flex-direction: column; + justify-content: center; + } + + .info-value { + flex-direction: row; + align-items: center; + + span { + font-size: 24px; + margin-right: 12px; + } + } + } + + .bonus { + display: flex; + flex-direction: column; + align-items: flex-end; + width: 100%; + + .bonus-value { + margin-right: 39px; + + :first-child { + text-align: right; + font-size: 16px; + margin-bottom: 15px; + margin-right: 3px; + } + + :last-child { + font-size: 46px; + font-weight: bold; + color: #0091ff; + } + + .negative-bonus-color { + color: red; + } + } + + .bonus-disclaimer { + margin-top: 15px; + margin-right: 39px; + font-size: 0.7rem; + width: 215px; + } + } } ::ng-deep nb-route-tabset .route-tab .tab-link { border-radius: 0.5rem 0.5rem 0 0; - svg{ + svg { fill: nb-theme(text-primary-color); } - span{ + span { display: inline-block; - text-transform: lowercase; - &:first-letter{ + text-transform: initial; + &:first-letter { text-transform: uppercase; } } diff --git a/apps/gauzy/src/app/pages/dashboard/dashboard.component.ts b/apps/gauzy/src/app/pages/dashboard/dashboard.component.ts index d2a9b91ffe2..84fc0a22dd3 100644 --- a/apps/gauzy/src/app/pages/dashboard/dashboard.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/dashboard.component.ts @@ -1,143 +1,188 @@ -import { AfterContentChecked, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { AfterContentChecked, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { filter, tap } from 'rxjs/operators'; import { NbRouteTab } from '@nebular/theme'; -import { tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; import { ISelectedEmployee, PermissionsEnum } from '@gauzy/contracts'; +import { PageTabRegistryService, Store, TabsetRegistryId, TabsetRegistryIdEnum } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { DynamicTabsComponent } from '@gauzy/ui-core/shared'; -@UntilDestroy({ checkProperties: true }) +@UntilDestroy() @Component({ templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.scss'] }) export class DashboardComponent extends TranslationBaseComponent implements AfterContentChecked, OnInit, OnDestroy { public tabs: NbRouteTab[] = []; - public loading = true; + public tabsetId: TabsetRegistryId = this._route.snapshot.data.tabsetId; // The identifier for the tabset public selectedEmployee: ISelectedEmployee; + @ViewChild('dynamicTabs') dynamicTabsComponent!: DynamicTabsComponent; + constructor( - private readonly cdr: ChangeDetectorRef, - private readonly store: Store, - public readonly translateService: TranslateService + public readonly translateService: TranslateService, + private readonly _cdr: ChangeDetectorRef, + private readonly _route: ActivatedRoute, + private readonly _store: Store, + private readonly _pageTabRegistryService: PageTabRegistryService ) { super(translateService); } ngOnInit(): void { - this._applyTranslationOnTabs(); - this.store.selectedEmployee$ + // Register the page tabs + this.registerPageTabs(); + } + + ngAfterViewInit(): void { + this._store.selectedEmployee$ .pipe( + filter((employee: ISelectedEmployee) => !!employee), tap((employee: ISelectedEmployee) => (this.selectedEmployee = employee)), - tap(() => this.loadTabs()), + tap(() => this.registerAccountingTabs()), untilDestroyed(this) ) .subscribe(); } ngAfterContentChecked(): void { - this.cdr.detectChanges(); + this._cdr.detectChanges(); } /** - * Returns the route path for the specified route name within the dashboard page. - * @param name The name of the route. - * @returns The route path. + * Returns the full route path for the specified route name within the dashboard page. + * + * @param path The name of the route (e.g., 'settings', 'profile'). + * @returns The full route path (e.g., '/pages/dashboard/settings'). */ - getRoute(name: string): string { - return `/pages/dashboard/${name}`; + getRoute(path: string): string { + return `/pages/dashboard/${path}`; } /** - * Populates the tabs array based on user permissions and selected employee. + * Registers page tabs for the dashboard module. + * Ensures that tabs are registered only once. + * + * @returns {void} */ - loadTabs(): void { - this.tabs = [ - ...(this.store.hasAllPermissions(PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.TEAM_DASHBOARD) - ? [ - { - title: this.getTranslation('ORGANIZATIONS_PAGE.TEAMS'), - icon: 'people-outline', - responsive: true, - route: this.getRoute('teams'), - activeLinkOptions: { exact: false } - } as NbRouteTab - ] - : []), - ...(this.store.hasAllPermissions( + registerPageTabs(): void { + // Check if the user has permission to view teams + if (this._store.hasAnyPermission(PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.TEAM_DASHBOARD)) { + // Register the teams tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Dashboard, // The identifier for the tabset + tabId: 'teams', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: this.getRoute('teams'), // The route for the tab + tabTitle: () => this.getTranslation('ORGANIZATIONS_PAGE.TEAMS'), // The title for the tab + tabIcon: 'people-outline', // The icon for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 1 // The order of the tab + }); + } + + // Check if the user has permission to view project management + if ( + this._store.hasAnyPermission( PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.PROJECT_MANAGEMENT_DASHBOARD ) - ? [ - { - title: this.getTranslation('DASHBOARD_PAGE.PROJECT_MANAGEMENT'), - icon: 'browser-outline', - responsive: true, - route: this.getRoute('project-management'), - activeLinkOptions: { exact: false } - } as NbRouteTab - ] - : []), - ...(this.store.hasAllPermissions( - PermissionsEnum.ADMIN_DASHBOARD_VIEW, - PermissionsEnum.TIME_TRACKING_DASHBOARD - ) - ? [ - { - title: this.getTranslation('DASHBOARD_PAGE.TIME_TRACKING'), - icon: 'clock-outline', - responsive: true, - route: this.getRoute('time-tracking'), - activeLinkOptions: { exact: false } - } as NbRouteTab - ] - : []), - ...(this.store.hasAllPermissions(PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.ACCOUNTING_DASHBOARD) - ? [ - ...(!this.selectedEmployee || !this.selectedEmployee.id - ? [ - { - title: this.getTranslation('DASHBOARD_PAGE.ACCOUNTING'), - icon: 'credit-card-outline', - responsive: true, - route: this.getRoute('accounting'), - activeLinkOptions: { exact: false } - } as NbRouteTab - ] - : []) - ] - : []), - ...(this.store.hasAllPermissions( + ) { + // Register the project management tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Dashboard, // The identifier for the tabset + tabId: 'project-management', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: this.getRoute('project-management'), // The route for the tab + tabTitle: () => this.getTranslation('DASHBOARD_PAGE.PROJECT_MANAGEMENT'), // The title for the tab + tabIcon: 'browser-outline', // The icon for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 2 // The order of the tab + }); + } + + // Check if the user has permission to view time tracking + if ( + this._store.hasAnyPermission(PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.TIME_TRACKING_DASHBOARD) + ) { + // Register the time tracking tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Dashboard, // The identifier for the tabset + tabId: 'time-tracking', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: this.getRoute('time-tracking'), // The route for the tab + tabTitle: () => this.getTranslation('TIMESHEET.TIME_TRACKING'), // The title for the tab + tabIcon: 'clock-outline', // The icon for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 3 // The order of the tab + }); + } + } + + /** + * Registers accounting tabs for the dashboard module. + * Ensures that tabs are registered only once. + */ + registerAccountingTabs(): void { + // Remove the specified page tabs for the current tenant + this._pageTabRegistryService.removePageTab(TabsetRegistryIdEnum.Dashboard, 'accounting'); + this._pageTabRegistryService.removePageTab(TabsetRegistryIdEnum.Dashboard, 'hr'); + + // Check if the user has permission to view accounting + if (this._store.hasAnyPermission(PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.ACCOUNTING_DASHBOARD)) { + if (!this.selectedEmployee || !this.selectedEmployee.id) { + // Register the accounting tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Dashboard, // The identifier for the tabset + tabId: 'accounting', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: this.getRoute('accounting'), // The route for the tab + tabTitle: () => this.getTranslation('DASHBOARD_PAGE.ACCOUNTING'), // The title for the tab + tabIcon: 'credit-card-outline', // The icon for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 4 // The order of the tab + }); + } + } + + // Check if the user has permission to view human resources + if ( + this._store.hasAllPermissions( PermissionsEnum.ADMIN_DASHBOARD_VIEW, PermissionsEnum.HUMAN_RESOURCE_DASHBOARD ) - ? [ - ...(this.selectedEmployee && this.selectedEmployee.id - ? [ - { - title: this.getTranslation('DASHBOARD_PAGE.HUMAN_RESOURCES'), - icon: 'person-outline', - responsive: true, - route: this.getRoute('hr'), - activeLinkOptions: { exact: false } - } as NbRouteTab - ] - : []) - ] - : []) - ]; - this.loading = false; - } + ) { + if (this.selectedEmployee && this.selectedEmployee.id) { + // Register the human resources tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Dashboard, // The identifier for the tabset + tabId: 'hr', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: this.getRoute('hr'), // The route for the tab + tabTitle: () => this.getTranslation('DASHBOARD_PAGE.HUMAN_RESOURCES'), // The title for the tab + tabIcon: 'person-outline', // The icon for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 5 // The order of the tab + }); + } + } - private _applyTranslationOnTabs() { - this.translateService.onLangChange - .pipe( - tap(() => this.loadTabs()), - untilDestroyed(this) - ) - .subscribe(); + // Reload the dynamic tabs component + this.dynamicTabsComponent.reload$.next(true); } - ngOnDestroy() {} + /** + * Clears the registry when the component is destroyed. + */ + ngOnDestroy() { + // Delete the dashboard tabset from the registry + this._pageTabRegistryService.deleteTabset(TabsetRegistryIdEnum.Dashboard); + } } diff --git a/apps/gauzy/src/app/pages/dashboard/dashboard.module.ts b/apps/gauzy/src/app/pages/dashboard/dashboard.module.ts index 9ff910b9316..081f2109e83 100644 --- a/apps/gauzy/src/app/pages/dashboard/dashboard.module.ts +++ b/apps/gauzy/src/app/pages/dashboard/dashboard.module.ts @@ -6,17 +6,18 @@ import { NbDialogModule, NbIconModule, NbInputModule, + NbRouteTabsetModule, + NbSelectModule, NbSpinnerModule, NbTooltipModule, - NbTreeGridModule, - NbSelectModule, - NbRouteTabsetModule + NbTreeGridModule } from '@nebular/theme'; import { NgSelectModule } from '@ng-select/ng-select'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { NgxPermissionsModule } from 'ngx-permissions'; import { TranslateModule } from '@ngx-translate/core'; import { + DynamicTabsModule, InfoBlockModule, LineChartModule, NoDataMessageModule, @@ -38,37 +39,50 @@ import { TimeTrackingModule } from './time-tracking/time-tracking.module'; import { ProjectManagementDetailsComponent } from './project-management/project-management-details/project-management-details.component'; import { TeamModule } from './team/team.module'; +// NB Modules +const NB_MODULES = [ + NbAlertModule, + NbButtonModule, + NbCardModule, + NbDialogModule.forChild(), + NbIconModule, + NbInputModule, + NbRouteTabsetModule, + NbSelectModule, + NbSpinnerModule, + NbTooltipModule, + NbTreeGridModule +]; + +// Third Party Modules +const THIRD_PARTY_MODULES = [ + InfiniteScrollModule, + LineChartModule, + NgSelectModule, + NgxPermissionsModule.forChild(), + TranslateModule.forChild() +]; + @NgModule({ imports: [ DashboardRoutingModule, - NbCardModule, - NgSelectModule, - NbButtonModule, - NbInputModule, + ...NB_MODULES, + ...THIRD_PARTY_MODULES, + // Feature Modules RecordsHistoryModule, - NbDialogModule.forChild(), - NbTreeGridModule, - NbIconModule, - NbTooltipModule, - NbSpinnerModule, - NbSelectModule, - NbAlertModule, - NgxPermissionsModule.forChild(), ProfitHistoryModule, - TranslateModule.forChild(), EmployeeChartsModule, - NbSpinnerModule, SingleStatisticModule, InfoBlockModule, - NbRouteTabsetModule, TimeTrackingModule, + TeamModule, + // Shared Modules SharedModule, - LineChartModule, - InfiniteScrollModule, TableComponentsModule, NoDataMessageModule, WorkInProgressModule, - TeamModule + // Custom Modules + DynamicTabsModule ], declarations: [ DashboardComponent, diff --git a/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.html b/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.html index ed6cd510fd4..aabb03f23c2 100644 --- a/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.html +++ b/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.html @@ -3,11 +3,7 @@
- + {{ 'MENU.INCOME' | translate }} @@ -22,11 +18,7 @@
- + {{ 'MENU.EXPENSES' | translate }} @@ -41,11 +33,7 @@
- + {{ 'DASHBOARD_PAGE.RECURRING_EXPENSES' | translate }} @@ -53,21 +41,14 @@
- {{ - 'DASHBOARD_PAGE.ADD_ORGANIZATION_RECURRING_EXPENSE' - | translate - }} + {{ 'DASHBOARD_PAGE.ADD_ORGANIZATION_RECURRING_EXPENSE' | translate }}
- + {{ 'DASHBOARD_PAGE.RECURRING_EXPENSES' | translate }} @@ -75,10 +56,7 @@
- {{ - 'DASHBOARD_PAGE.ADD_EMPLOYEE_RECURRING_EXPENSE' - | translate - }} + {{ 'DASHBOARD_PAGE.ADD_EMPLOYEE_RECURRING_EXPENSE' | translate }}
diff --git a/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.ts b/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.ts index f5cddc6da8b..ba81e5ff4fa 100644 --- a/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/data-entry-shortcuts/data-entry-shortcuts.component.ts @@ -1,27 +1,25 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subject } from 'rxjs'; import { Router } from '@angular/router'; -import { Store } from '@gauzy/ui-core/common'; -import { takeUntil } from 'rxjs/operators'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { Store } from '@gauzy/ui-core/core'; import { PermissionsEnum } from '@gauzy/contracts'; +@UntilDestroy() @Component({ selector: 'ga-data-entry-shortcuts', templateUrl: './data-entry-shortcuts.component.html', styleUrls: ['./data-entry-shortcuts.component.scss'] }) export class DataEntryShortcutsComponent implements OnInit, OnDestroy { - private _ngDestroy$ = new Subject(); - - constructor(private readonly router: Router, private readonly store: Store) {} + constructor(readonly router: Router, readonly store: Store) {} hasPermissionE = false; hasPermissionI = false; hasPermissionIEdit = false; hasPermissionEEdit = false; - async ngOnInit() { - this.store.userRolePermissions$.pipe(takeUntil(this._ngDestroy$)).subscribe(() => { + ngOnInit() { + this.store.userRolePermissions$.pipe(untilDestroyed(this)).subscribe(() => { this.hasPermissionE = this.store.hasPermission(PermissionsEnum.ORG_EXPENSES_VIEW); this.hasPermissionI = this.store.hasPermission(PermissionsEnum.ORG_INCOMES_VIEW); this.hasPermissionEEdit = this.store.hasPermission(PermissionsEnum.ORG_EXPENSES_EDIT); @@ -29,24 +27,33 @@ export class DataEntryShortcutsComponent implements OnInit, OnDestroy { }); } - async addIncome() { - this.router.navigateByUrl('pages/accounting/income?openAddDialog=true'); + /** + * Navigate to the income page and open the add dialog. + */ + async addIncome(): Promise { + await this.router.navigateByUrl('pages/accounting/income?openAddDialog=true'); } - async addExpense() { - this.router.navigateByUrl('pages/accounting/expenses?openAddDialog=true'); + /** + * Navigate to the expenses page and open the add dialog. + */ + async addExpense(): Promise { + await this.router.navigateByUrl('pages/accounting/expenses?openAddDialog=true'); } - async addOrganizationRecurringExpense() { - this.router.navigateByUrl('pages/organizations'); + /** + * Navigate to the organizations page. + */ + async addOrganizationRecurringExpense(): Promise { + await this.router.navigateByUrl('pages/organizations'); } - async addEmployeeRecurringExpense() { - this.router.navigateByUrl('pages/employees'); + /** + * Navigate to the employees page. + */ + async addEmployeeRecurringExpense(): Promise { + await this.router.navigateByUrl('pages/employees'); } - ngOnDestroy() { - this._ngDestroy$.next(); - this._ngDestroy$.complete(); - } + ngOnDestroy() {} } diff --git a/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-doughnut-chart/employee-doughnut-chart.component.ts b/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-doughnut-chart/employee-doughnut-chart.component.ts index dcf2bc55b11..e691bb0e981 100644 --- a/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-doughnut-chart/employee-doughnut-chart.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-doughnut-chart/employee-doughnut-chart.component.ts @@ -9,8 +9,9 @@ import { ChartConfiguration, ChartType, TooltipItem } from 'chart.js'; import { environment } from '@gauzy/ui-config'; import { CurrencyPosition, IMonthAggregatedEmployeeStatistics, IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { CurrencyPositionPipe } from '@gauzy/ui-core/shared'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-horizontal-bar-chart/employee-horizontal-bar-chart.component.ts b/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-horizontal-bar-chart/employee-horizontal-bar-chart.component.ts index b471cc0453e..4af862bbf2d 100644 --- a/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-horizontal-bar-chart/employee-horizontal-bar-chart.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/human-resources/employee-charts/employee-horizontal-bar-chart/employee-horizontal-bar-chart.component.ts @@ -9,9 +9,9 @@ import { ChartConfiguration, ChartType } from 'chart.js'; import { environment } from '@gauzy/ui-config'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { CurrencyPosition, IMonthAggregatedEmployeeStatistics, IOrganization } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { CurrencyPositionPipe } from '@gauzy/ui-core/shared'; -import { months } from '@gauzy/ui-core/core'; +import { Store, months } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -94,8 +94,8 @@ export class EmployeeHorizontalBarChartComponent @ViewChild(BaseChartDirective, { static: false }) baseChartDirective: BaseChartDirective; constructor( - private readonly _themeService: NbThemeService, public readonly translateService: TranslateService, + private readonly _themeService: NbThemeService, private readonly _currencyPipe: CurrencyPipe, private readonly _currencyPositionPipe: CurrencyPositionPipe, private readonly _store: Store diff --git a/apps/gauzy/src/app/pages/dashboard/human-resources/human-resources.component.ts b/apps/gauzy/src/app/pages/dashboard/human-resources/human-resources.component.ts index ad22c20a77a..fae800f8711 100644 --- a/apps/gauzy/src/app/pages/dashboard/human-resources/human-resources.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/human-resources/human-resources.component.ts @@ -13,8 +13,8 @@ import { combineLatest } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { Subject } from 'rxjs/internal/Subject'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, EmployeeStatisticsService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, EmployeeStatisticsService, Store } from '@gauzy/ui-core/core'; import { ProfitHistoryComponent, RecordsHistoryComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/dashboard/project-management/project-management-details/project-management-details.component.ts b/apps/gauzy/src/app/pages/dashboard/project-management/project-management-details/project-management-details.component.ts index d7b3220a29e..30d1181641a 100644 --- a/apps/gauzy/src/app/pages/dashboard/project-management/project-management-details/project-management-details.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/project-management/project-management-details/project-management-details.component.ts @@ -7,7 +7,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { pluck } from 'underscore'; import { NbDialogService } from '@nebular/theme'; -import { ErrorHandlingService, ServerDataSource, TasksService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, ServerDataSource, Store, TasksService } from '@gauzy/ui-core/core'; import { IOrganization, IOrganizationProject, @@ -16,7 +16,7 @@ import { PermissionsEnum, TaskStatusEnum } from '@gauzy/contracts'; -import { API_PREFIX, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, distinctUntilChange } from '@gauzy/ui-core/common'; import { AddTaskDialogComponent, PaginationFilterBaseComponent } from '@gauzy/ui-core/shared'; import { MyTaskDialogComponent } from '../../../tasks/components/my-task-dialog/my-task-dialog.component'; diff --git a/apps/gauzy/src/app/pages/dashboard/project-management/project-management.component.ts b/apps/gauzy/src/app/pages/dashboard/project-management/project-management.component.ts index febd2305b06..20ddb9eb0c3 100644 --- a/apps/gauzy/src/app/pages/dashboard/project-management/project-management.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/project-management/project-management.component.ts @@ -5,7 +5,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { distinctUntilChange } from '@gauzy/ui-core/common'; import { IDateRangePicker, IOrganization } from '@gauzy/contracts'; import { DateRangePickerBuilderService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/dashboard/team/all-team/all-team.component.ts b/apps/gauzy/src/app/pages/dashboard/team/all-team/all-team.component.ts index f84bb6c9ae5..2288f17a312 100644 --- a/apps/gauzy/src/app/pages/dashboard/team/all-team/all-team.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/team/all-team/all-team.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { UntilDestroy } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { OrganizationProjectsService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/dashboard/team/team-member/team-member.component.ts b/apps/gauzy/src/app/pages/dashboard/team/team-member/team-member.component.ts index 3c6794ee5a6..f92f22c24a8 100644 --- a/apps/gauzy/src/app/pages/dashboard/team/team-member/team-member.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/team/team-member/team-member.component.ts @@ -1,7 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { IOrganizationTeamEmployee } from '@gauzy/contracts'; import { progressStatus } from '@gauzy/ui-core/common'; -import moment from 'moment'; +import * as moment from 'moment'; @Component({ selector: 'gauzy-team-member', diff --git a/apps/gauzy/src/app/pages/dashboard/team/team.component.ts b/apps/gauzy/src/app/pages/dashboard/team/team.component.ts index e90b0f0a01d..6789b255b49 100644 --- a/apps/gauzy/src/app/pages/dashboard/team/team.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/team/team.component.ts @@ -18,7 +18,7 @@ import { ITimeLog, ReportGroupFilterEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, TimeZoneService } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/dashboard/time-tracking/time-tracking.component.ts b/apps/gauzy/src/app/pages/dashboard/time-tracking/time-tracking.component.ts index 41d8204e571..2a921b94695 100644 --- a/apps/gauzy/src/app/pages/dashboard/time-tracking/time-tracking.component.ts +++ b/apps/gauzy/src/app/pages/dashboard/time-tracking/time-tracking.component.ts @@ -14,7 +14,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { BehaviorSubject, combineLatest, firstValueFrom, of, Subject, Subscription, switchMap, timer } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { indexBy, range, reduce } from 'underscore'; -import moment from 'moment'; +import * as moment from 'moment'; import { NgxPermissionsService } from 'ngx-permissions'; import { TranslateService } from '@ngx-translate/core'; import { SwiperComponent } from 'swiper/angular'; @@ -45,11 +45,12 @@ import { ITimeLogTodayFilters, TimeFormatEnum } from '@gauzy/contracts'; -import { GuiDrag, Store, distinctUntilChange, isNotEmpty, progressStatus, toUtcOffset } from '@gauzy/ui-core/common'; +import { GuiDrag, distinctUntilChange, isNotEmpty, progressStatus, toUtcOffset } from '@gauzy/ui-core/common'; import { DateRangePickerBuilderService, EmployeesService, OrganizationProjectsService, + Store, TimesheetStatisticsService, ToastrService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/departments/departments-mutation/departments-mutation.component.ts b/apps/gauzy/src/app/pages/departments/departments-mutation/departments-mutation.component.ts index c4207db732f..2a50ca7373e 100644 --- a/apps/gauzy/src/app/pages/departments/departments-mutation/departments-mutation.component.ts +++ b/apps/gauzy/src/app/pages/departments/departments-mutation/departments-mutation.component.ts @@ -3,7 +3,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms import { IEmployee, IOrganization, IOrganizationDepartment, ITag } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { debounceTime, filter, tap } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/departments/departments.component.ts b/apps/gauzy/src/app/pages/departments/departments.component.ts index 41628ab8294..d745beb6097 100644 --- a/apps/gauzy/src/app/pages/departments/departments.component.ts +++ b/apps/gauzy/src/app/pages/departments/departments.component.ts @@ -15,8 +15,8 @@ import { IOrganization, ITag } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { OrganizationDepartmentsService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { OrganizationDepartmentsService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent, EmployeeWithLinksComponent, diff --git a/apps/gauzy/src/app/pages/documents/documents.component.ts b/apps/gauzy/src/app/pages/documents/documents.component.ts index f28e28ac3d3..e291566230e 100644 --- a/apps/gauzy/src/app/pages/documents/documents.component.ts +++ b/apps/gauzy/src/app/pages/documents/documents.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, ViewChild, OnDestroy, TemplateRef } from '@angular/core'; import { UntypedFormGroup, UntypedFormBuilder, FormArray, Validators } from '@angular/forms'; import { IOrganizationDocument, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { debounceTime, filter, first, tap } from 'rxjs/operators'; import { NbDialogRef, NbDialogService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; @@ -9,7 +9,7 @@ import { LocalDataSource } from 'angular2-smart-table'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { UploadDocumentComponent } from './upload-document/upload-document.component'; import { ComponentEnum } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, OrganizationDocumentsService, ToastrService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, OrganizationDocumentsService, Store, ToastrService } from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent, DocumentDateTableComponent, diff --git a/apps/gauzy/src/app/pages/email-templates/email-templates.component.ts b/apps/gauzy/src/app/pages/email-templates/email-templates.component.ts index 3ca4911cc1d..0299415e931 100644 --- a/apps/gauzy/src/app/pages/email-templates/email-templates.component.ts +++ b/apps/gauzy/src/app/pages/email-templates/email-templates.component.ts @@ -14,7 +14,7 @@ import { distinctUntilChange } from '@gauzy/ui-core/common'; import { combineLatest, Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { AceEditorComponent } from 'ngx-ace-editor-wrapper'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmailTemplateService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ToastrService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/employee-levels/employee-level.component.ts b/apps/gauzy/src/app/pages/employee-levels/employee-level.component.ts index 1aed87982c6..1d98a8234db 100644 --- a/apps/gauzy/src/app/pages/employee-levels/employee-level.component.ts +++ b/apps/gauzy/src/app/pages/employee-levels/employee-level.component.ts @@ -6,14 +6,14 @@ import { debounceTime, firstValueFrom, Subject } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { LocalDataSource } from 'angular2-smart-table'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { PaginationFilterBaseComponent, IPaginationBase, NotesWithTagsComponent, DeleteConfirmationComponent } from '@gauzy/ui-core/shared'; -import { EmployeeLevelService, ToastrService } from '@gauzy/ui-core/core'; +import { EmployeeLevelService, Store, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/employees/activity/app-url-activity/app-url-activity/app-url-activity.component.ts b/apps/gauzy/src/app/pages/employees/activity/app-url-activity/app-url-activity/app-url-activity.component.ts index 215583f81e8..148438079d1 100644 --- a/apps/gauzy/src/app/pages/employees/activity/app-url-activity/app-url-activity/app-url-activity.component.ts +++ b/apps/gauzy/src/app/pages/employees/activity/app-url-activity/app-url-activity/app-url-activity.component.ts @@ -5,7 +5,7 @@ import { BehaviorSubject, filter } from 'rxjs'; import { tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { chain, reduce } from 'underscore'; -import moment from 'moment'; +import * as moment from 'moment'; import { TranslateService } from '@ngx-translate/core'; import { ITimeLogFilters, @@ -15,8 +15,8 @@ import { IActivity, IURLMetaData } from '@gauzy/contracts'; -import { ActivityService, DateRangePickerBuilderService, TimesheetFilterService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange, isEmpty, isJsObject, toLocal, toUTC } from '@gauzy/ui-core/common'; +import { ActivityService, DateRangePickerBuilderService, Store, TimesheetFilterService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty, isJsObject, toLocal, toUTC } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/employees/activity/layout/layout.component.ts b/apps/gauzy/src/app/pages/employees/activity/layout/layout.component.ts index a18f69f56a2..832c51ded30 100644 --- a/apps/gauzy/src/app/pages/employees/activity/layout/layout.component.ts +++ b/apps/gauzy/src/app/pages/employees/activity/layout/layout.component.ts @@ -6,7 +6,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { PermissionsEnum } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { RouteUtil } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/employees/activity/screenshot/screenshot/screenshot.component.ts b/apps/gauzy/src/app/pages/employees/activity/screenshot/screenshot/screenshot.component.ts index e6f27dae150..34a2985d02f 100644 --- a/apps/gauzy/src/app/pages/employees/activity/screenshot/screenshot/screenshot.component.ts +++ b/apps/gauzy/src/app/pages/employees/activity/screenshot/screenshot/screenshot.component.ts @@ -10,7 +10,7 @@ import moment from 'moment-timezone'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { NbDialogService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; import { ITimeLogFilters, ITimeSlot, @@ -19,7 +19,7 @@ import { IScreenshot, PermissionsEnum } from '@gauzy/contracts'; -import { isEmpty, distinctUntilChange, isNotEmpty, toTimezone, Store } from '@gauzy/ui-core/common'; +import { isEmpty, distinctUntilChange, isNotEmpty, toTimezone } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, DeleteConfirmationComponent, diff --git a/apps/gauzy/src/app/pages/employees/appointment/appointment-routing.module.ts b/apps/gauzy/src/app/pages/employees/appointment/appointment-routing.module.ts index e94ba0a285f..30bd8e37e42 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/appointment-routing.module.ts +++ b/apps/gauzy/src/app/pages/employees/appointment/appointment-routing.module.ts @@ -1,11 +1,11 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { AppointmentComponent } from './appointment.component'; -import { ManageAppointmentComponent } from './manage-appointment/manage-appointment.component'; +import { AppointmentCalendarComponent, ManageAppointmentComponent } from '@gauzy/ui-core/shared'; + const routes: Routes = [ { path: '', - component: AppointmentComponent, + component: AppointmentCalendarComponent }, { path: 'manage/:employeeId', diff --git a/apps/gauzy/src/app/pages/employees/appointment/appointment.component.html b/apps/gauzy/src/app/pages/employees/appointment/appointment.component.html deleted file mode 100644 index 54d60c46a6d..00000000000 --- a/apps/gauzy/src/app/pages/employees/appointment/appointment.component.html +++ /dev/null @@ -1,60 +0,0 @@ - - -
-

- - {{ 'MENU.APPOINTMENTS' | translate }} - -

-
- - - - - -
-
-
- {{ 'PUBLIC_APPOINTMENTS.TIMEZONE' | translate }} - - {{ selectedTimeZoneName }} {{ selectedTimeZoneOffset }} - - {{ - 'PUBLIC_APPOINTMENTS.CHANGE' | translate - }} -
-
- -
- -
-
-
diff --git a/apps/gauzy/src/app/pages/employees/appointment/appointment.module.ts b/apps/gauzy/src/app/pages/employees/appointment/appointment.module.ts index 3dedb9c8ae4..6784de16bbf 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/appointment.module.ts +++ b/apps/gauzy/src/app/pages/employees/appointment/appointment.module.ts @@ -1,34 +1,10 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { NbButtonModule, NbCardModule, NbIconModule, NbSpinnerModule } from '@nebular/theme'; -import { FullCalendarModule } from '@fullcalendar/angular'; -import { TranslateModule } from '@ngx-translate/core'; -import { - AppointmentEmployeesService, - AvailabilitySlotsService, - EmployeeAppointmentService, - TimeOffService -} from '@gauzy/ui-core/core'; -import { SharedModule } from '@gauzy/ui-core/shared'; +import { AppointmentCalendarModule } from '@gauzy/ui-core/shared'; import { AppointmentRoutingModule } from './appointment-routing.module'; -import { AppointmentComponent } from './appointment.component'; -import { TimezoneSelectorModule } from './timezone-selector/timezone-selector.module'; @NgModule({ - imports: [ - CommonModule, - NbButtonModule, - NbCardModule, - NbIconModule, - NbSpinnerModule, - FullCalendarModule, - TranslateModule.forChild(), - SharedModule, - TimezoneSelectorModule, - AppointmentRoutingModule - ], - exports: [AppointmentComponent], - declarations: [AppointmentComponent], - providers: [EmployeeAppointmentService, AppointmentEmployeesService, AvailabilitySlotsService, TimeOffService] + imports: [CommonModule, AppointmentCalendarModule, AppointmentRoutingModule], + providers: [] }) export class AppointmentModule {} diff --git a/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.component.html b/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.component.html deleted file mode 100644 index 952ba15cce0..00000000000 --- a/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.component.html +++ /dev/null @@ -1,49 +0,0 @@ - - - {{ 'EMPLOYEE_SCHEDULES_MODAL.EMPLOYEE' | translate }}: - {{ employeeSchedule.employeeName }} - - - {{ - (!employeeSchedule.slots.length - ? 'EMPLOYEE_SCHEDULES_MODAL.SLOTS_UNAVAILABLE' - : 'EMPLOYEE_SCHEDULES_MODAL.SLOTS_AVAILABLE' - ) | translate - }} -
- - - - {{ item.startTime }} to {{ item.endTime }}
-
-
-
-
- - - - - -
diff --git a/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.component.ts b/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.component.ts deleted file mode 100644 index fcee809c3d8..00000000000 --- a/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { NbDialogRef } from '@nebular/theme'; -import { TranslateService } from '@ngx-translate/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import * as timezone from 'moment-timezone'; - -export interface EmployeeSchedule { - employeeName: string; - slots: any; - timezone: string; -} - -@Component({ - templateUrl: './employee-schedules.component.html' -}) -export class EmployeeSchedulesComponent extends TranslationBaseComponent implements OnInit { - employeeSchedule: EmployeeSchedule; - constructor(public dialogRef: NbDialogRef, private translate: TranslateService) { - super(translate); - } - - ngOnInit() { - this.employeeSchedule.slots.forEach((s) => { - s.startTime = timezone(s.startTime).tz(this.employeeSchedule.timezone).format('LLLL'); - s.endTime = timezone(s.endTime).tz(this.employeeSchedule.timezone).format('LLLL'); - }); - } - - closeDialog(val) { - this.dialogRef.close(val); - } -} diff --git a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment-routing.module.ts b/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment-routing.module.ts deleted file mode 100644 index ac3233b1309..00000000000 --- a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment-routing.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { ManageAppointmentComponent } from './manage-appointment.component'; - -const routes: Routes = [ - { - path: '', - component: ManageAppointmentComponent - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class ManageAppointmentRoutingModule {} diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts index 8f18340fcd0..6314fc5a13e 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts @@ -4,7 +4,7 @@ import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { EmployeeStore, OrganizationContactService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy() @Component({ diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.ts index 2c4813866d7..7da3f6cecaa 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.ts @@ -11,7 +11,7 @@ import { IEmployeeLevel } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { combineLatest } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { CKEditor4 } from 'ckeditor4-angular/ckeditor'; @@ -21,7 +21,8 @@ import { EmployeeStore, OrganizationDepartmentsService, OrganizationEmploymentTypesService, - OrganizationPositionsService + OrganizationPositionsService, + Store } from '@gauzy/ui-core/core'; import { ToastrService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-hiring/edit-employee-hiring.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-hiring/edit-employee-hiring.component.ts index 871807f3007..b47a48aa54f 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-hiring/edit-employee-hiring.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-hiring/edit-employee-hiring.component.ts @@ -4,7 +4,7 @@ import { IEmployee } from '@gauzy/contracts'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { CompareDateValidator } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeeStore } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.ts index 1a8fa6fe9fc..da9099681ba 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.ts @@ -4,7 +4,7 @@ import { IEmployee, IImageAsset, IOrganization } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { combineLatest } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeeStore, ErrorHandlingService } from '@gauzy/ui-core/core'; /** diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-networks/edit-employee-networks.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-networks/edit-employee-networks.component.ts index 235989f4ec4..b68b574c72b 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-networks/edit-employee-networks.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-networks/edit-employee-networks.component.ts @@ -6,7 +6,7 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { UrlPatternValidator } from '@gauzy/ui-core/core'; import { distinctUntilChange } from '@gauzy/ui-core/common'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeeStore } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts index 075f101e99b..3a7653f4d68 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts @@ -7,7 +7,7 @@ import { NbRouteTab } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IEmployee, IEmployeeUpdateInput, IUserUpdateInput, PermissionsEnum } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeesService, EmployeeStore, diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts index ee470c4b83e..b72163f9c20 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts @@ -1,4 +1,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { TranslateService } from '@ngx-translate/core'; +import { combineLatest, Subject } from 'rxjs'; +import { filter, tap } from 'rxjs/operators'; import { IEditEntityByMemberInput, IEmployee, @@ -6,15 +10,9 @@ import { IOrganizationProject, PermissionsEnum } from '@gauzy/contracts'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslateService } from '@ngx-translate/core'; import { distinctUntilChange } from '@gauzy/ui-core/common'; -import { combineLatest, Subject } from 'rxjs'; -import { filter, tap } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; -import { EmployeeStore, OrganizationProjectsService } from '@gauzy/ui-core/core'; +import { EmployeeStore, OrganizationProjectsService, Store, ToastrService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.ts index 6f8084bd1ad..aa3913dc2d8 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.ts @@ -6,10 +6,10 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { IEmployee, IImageAsset, IOrganization, ISelectedEmployee, IUser, PermissionsEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ALL_EMPLOYEES_SELECTED } from '@gauzy/ui-core/shared'; -import { ErrorHandlingService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -118,7 +118,7 @@ export class EditEmployeeComponent extends TranslationBaseComponent implements O } /** - * Edit public employee page redirection + * Create URL tree for edit public employee page * * @returns */ @@ -126,15 +126,14 @@ export class EditEmployeeComponent extends TranslationBaseComponent implements O if (!this.organization || !this.selectedEmployee) { return; } + const { id, profile_link } = this.organization; + const { id: employeeId, profile_link: employeeProfileLink } = this.selectedEmployee; + // The call to Location.prepareExternalUrl is the key thing here. let tree = this.router.createUrlTree([ - `/share/organization/ - ${this.organization.profile_link}/ - ${this.organization.id}/ - ${this.selectedEmployee.profile_link}/ - ${this.selectedEmployee.id} - ` + `/share/organization/${profile_link}/${id}/${employeeProfileLink}/${employeeId}` ]); + // As far as I can tell you don't really need the UrlSerializer. const externalUrl = this._location.prepareExternalUrl(this._urlSerializer.serialize(tree)); window.open(externalUrl, '_blank'); diff --git a/apps/gauzy/src/app/pages/employees/employees.component.ts b/apps/gauzy/src/app/pages/employees/employees.component.ts index 626248e40ec..428c7ad1ae2 100644 --- a/apps/gauzy/src/app/pages/employees/employees.component.ts +++ b/apps/gauzy/src/app/pages/employees/employees.component.ts @@ -12,6 +12,7 @@ import { EmployeesService, ErrorHandlingService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { @@ -24,7 +25,7 @@ import { ITag, PermissionsEnum } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { AllowScreenshotCaptureComponent, CardGridComponent, @@ -906,5 +907,5 @@ export class EmployeesComponent extends PaginationFilterBaseComponent implements } } - ngOnDestroy(): void { } + ngOnDestroy(): void {} } diff --git a/apps/gauzy/src/app/pages/employees/event-types/event-type-mutation/event-type-mutation.component.ts b/apps/gauzy/src/app/pages/employees/event-types/event-type-mutation/event-type-mutation.component.ts index 77ab1cfe2ef..b02e10f7948 100644 --- a/apps/gauzy/src/app/pages/employees/event-types/event-type-mutation/event-type-mutation.component.ts +++ b/apps/gauzy/src/app/pages/employees/event-types/event-type-mutation/event-type-mutation.component.ts @@ -6,7 +6,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, tap } from 'rxjs/operators'; import { IEventTypeViewModel, IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/employees/event-types/event-type.component.ts b/apps/gauzy/src/app/pages/employees/event-types/event-type.component.ts index 306ebbb37e1..3758f784c22 100644 --- a/apps/gauzy/src/app/pages/employees/event-types/event-type.component.ts +++ b/apps/gauzy/src/app/pages/employees/event-types/event-type.component.ts @@ -14,8 +14,8 @@ import { IEventTypeViewModel, PermissionsEnum } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, EventTypeService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, EventTypeService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { PaginationFilterBaseComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/employees/schedules/availability-slots/availability-slots.component.ts b/apps/gauzy/src/app/pages/employees/schedules/availability-slots/availability-slots.component.ts index edfd16a7778..7c81a8f9ca3 100644 --- a/apps/gauzy/src/app/pages/employees/schedules/availability-slots/availability-slots.component.ts +++ b/apps/gauzy/src/app/pages/employees/schedules/availability-slots/availability-slots.component.ts @@ -23,9 +23,9 @@ import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { NgxPermissionsService } from 'ngx-permissions'; -import { Store, distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ErrorHandlingService, ToastrService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, Store, ToastrService } from '@gauzy/ui-core/core'; import { AvailabilitySlotsService, TimeOffService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @@ -447,10 +447,10 @@ export class AvailabilitySlotsComponent extends TranslationBaseComponent impleme start: eventStartTime, end: eventEndTime, allDay: slot.allDay, - color: isDayOff ? 'red' : 'seablue', + color: isDayOff ? '#FF0000' : '#4682B4', extendedProps: { id: slot.id, - isDayOff: isDayOff ? true : false + isDayOff: !!isDayOff // Simplified boolean assignment } }); this.calendar.getApi().refetchEvents(); diff --git a/apps/gauzy/src/app/pages/employees/timesheet/approvals/approvals/approvals.component.ts b/apps/gauzy/src/app/pages/employees/timesheet/approvals/approvals/approvals.component.ts index 5bac5f366a0..3bac206e207 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/approvals/approvals/approvals.component.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/approvals/approvals/approvals.component.ts @@ -12,8 +12,8 @@ import { debounceTime, filter, map, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; -import { Store, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; +import { isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar.module.ts b/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar.module.ts index 385b6f3d597..b0ff9c4da8f 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar.module.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar.module.ts @@ -5,15 +5,14 @@ import { NbDialogModule, NbCardModule, NbButtonModule, NbIconModule, NbSpinnerMo import { FullCalendarModule } from '@fullcalendar/angular'; import { NgxPermissionsModule } from 'ngx-permissions'; import { TranslateModule } from '@ngx-translate/core'; -import { CalendarRoutingModule } from './calendar-routing.module'; -import { CalendarComponent } from './calendar/calendar.component'; -import { ShareModule } from './../../../../share/share.module'; import { EditTimeLogModalModule, GauzyFiltersModule, SharedModule, ViewTimeLogModalModule } from '@gauzy/ui-core/shared'; +import { CalendarRoutingModule } from './calendar-routing.module'; +import { CalendarComponent } from './calendar/calendar.component'; @NgModule({ declarations: [CalendarComponent], @@ -28,7 +27,6 @@ import { NbIconModule, NbSpinnerModule, CalendarRoutingModule, - ShareModule, SharedModule, EditTimeLogModalModule, ViewTimeLogModalModule, diff --git a/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts b/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts index 47eda613fba..87c5597a951 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts @@ -17,12 +17,12 @@ import bootstrapPlugin from '@fullcalendar/bootstrap'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { NgxPermissionsService } from 'ngx-permissions'; import { TranslateService } from '@ngx-translate/core'; -import moment from 'moment'; +import * as moment from 'moment'; import { pick } from 'underscore'; import { Observable } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; -import { Store, isEmpty, toTimezone } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { isEmpty, toTimezone } from '@gauzy/ui-core/common'; import { IGetTimeLogInput, ITimeLog, ITimeLogFilters, PermissionsEnum, TimeFormatEnum } from '@gauzy/contracts'; import { BaseSelectorFilterComponent, diff --git a/apps/gauzy/src/app/pages/employees/timesheet/daily/daily/daily.component.ts b/apps/gauzy/src/app/pages/employees/timesheet/daily/daily/daily.component.ts index 3a05696b7ca..4283f666520 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/daily/daily/daily.component.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/daily/daily/daily.component.ts @@ -1,23 +1,24 @@ // tslint:disable: nx-enforce-module-boundaries import { Component, OnInit, OnDestroy, AfterViewInit, ViewChild } from '@angular/core'; import { ActivatedRoute, ParamMap } from '@angular/router'; -import { TimeTrackerService, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { NbDialogService, NbMenuItem, NbMenuService } from '@nebular/theme'; import { filter, map, debounceTime, tap } from 'rxjs/operators'; import { BehaviorSubject, Observable, catchError, finalize, firstValueFrom, from, of, switchMap } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { pick } from 'underscore'; -import moment from 'moment'; +import * as moment from 'moment'; import { IGetTimeLogInput, ITimeLog, PermissionsEnum, ITimeLogFilters, TimeLogSourceEnum } from '@gauzy/contracts'; import { DateRangePickerBuilderService, ErrorHandlingService, + Store, + TimeTrackerService, TimesheetFilterService, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, ConfirmComponent, diff --git a/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.html b/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.html index 14ba49fe44f..da4e5a46ba3 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.html +++ b/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.html @@ -7,6 +7,6 @@

- +
diff --git a/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.ts b/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.ts index ca05e286344..841dd087dbc 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/layout/layout.component.ts @@ -1,93 +1,105 @@ -import { Component, OnInit, OnDestroy, ChangeDetectorRef, AfterContentChecked } from '@angular/core'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { NbRouteTab } from '@nebular/theme'; -import { tap } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; import { PermissionsEnum } from '@gauzy/contracts'; +import { PageTabRegistryService, Store, TabsetRegistryId, TabsetRegistryIdEnum } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -@UntilDestroy({ checkProperties: true }) @Component({ selector: 'ngx-timesheet-layout', templateUrl: './layout.component.html', styleUrls: ['./layout.component.scss'] }) -export class TimesheetLayoutComponent - extends TranslationBaseComponent - implements AfterContentChecked, OnInit, OnDestroy -{ +export class TimesheetLayoutComponent extends TranslationBaseComponent implements OnInit, OnDestroy { public tabs: NbRouteTab[] = []; + public tabsetId: TabsetRegistryId = this._route.snapshot.data.tabsetId; // The identifier for the tabset constructor( - private readonly cdr: ChangeDetectorRef, public readonly translateService: TranslateService, - private readonly store: Store + private readonly _route: ActivatedRoute, + private readonly _store: Store, + private readonly _pageTabRegistryService: PageTabRegistryService ) { super(translateService); } ngOnInit(): void { - this._loadTabs(); - this._applyTranslationOnTabs(); - } - - ngAfterContentChecked(): void { - this.cdr.detectChanges(); - } - - private _loadTabs() { - this.tabs = [ - ...(this.store.hasAnyPermission( - PermissionsEnum.TIME_TRACKER, - PermissionsEnum.ALL_ORG_EDIT, - PermissionsEnum.TIME_TRACKING_DASHBOARD - ) - ? [ - { - title: this.getTranslation('TIMESHEET.DAILY'), - responsive: true, - route: '/pages/employees/timesheets/daily', - activeLinkOptions: { exact: false } - }, - { - title: this.getTranslation('TIMESHEET.WEEKLY'), - responsive: true, - route: '/pages/employees/timesheets/weekly', - activeLinkOptions: { exact: false } - }, - { - title: this.getTranslation('TIMESHEET.CALENDAR'), - responsive: true, - route: '/pages/employees/timesheets/calendar', - activeLinkOptions: { exact: false } - } - ] - : []), - ...(this.store.hasAnyPermission(PermissionsEnum.CAN_APPROVE_TIMESHEET) - ? [ - { - title: this.getTranslation('TIMESHEET.APPROVALS'), - responsive: true, - route: '/pages/employees/timesheets/approvals', - activeLinkOptions: { exact: false } - } - ] - : []) - ]; + // Register the page tabs + this.registerPageTabs(); } /** - * Translate context menus + * Registers page tabs for the timesheet module. + * Ensures that tabs are registered only once. + * + * @returns {void} */ - private _applyTranslationOnTabs() { - this.translateService.onLangChange - .pipe( - tap(() => this._loadTabs()), - untilDestroyed(this) - ) - .subscribe(); + registerPageTabs(): void { + // Define the permissions required to view daily, weekly, or calendar timesheets + const permissions = [ + PermissionsEnum.TIME_TRACKER, + PermissionsEnum.ALL_ORG_EDIT, + PermissionsEnum.TIME_TRACKING_DASHBOARD + ]; + + // Check if the user has permission to view daily, weekly, or calendar timesheets + if (this._store.hasAnyPermission(...permissions)) { + // Register the daily timesheet tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Timesheet, // The identifier for the tabset + tabId: 'daily', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: '/pages/employees/timesheets/daily', // The route for the tab + tabTitle: () => this.getTranslation('TIMESHEET.DAILY'), // The title for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 1 // The order of the tab + }); + + // Register the weekly timesheet tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Timesheet, // The identifier for the tabset + tabId: 'weekly', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: '/pages/employees/timesheets/weekly', // The route for the tab + tabTitle: () => this.getTranslation('TIMESHEET.WEEKLY'), // The title for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 2 // The order of the tab + }); + + // Register the calendar timesheet tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Timesheet, // The identifier for the tabset + tabId: 'calendar', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: '/pages/employees/timesheets/calendar', // The route for the tab + tabTitle: () => this.getTranslation('TIMESHEET.CALENDAR'), // The title for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 3 // The order of the tab + }); + } + + // Check if the user has permission to approve timesheets + if (this._store.hasPermission(PermissionsEnum.CAN_APPROVE_TIMESHEET)) { + // Register the approvals tab + this._pageTabRegistryService.registerPageTab({ + tabsetId: TabsetRegistryIdEnum.Timesheet, // The identifier for the tabset + tabId: 'approvals', // The identifier for the tab + tabsetType: 'route', // The type of tabset to use + route: '/pages/employees/timesheets/approvals', // The route for the tab + tabTitle: () => this.getTranslation('TIMESHEET.APPROVALS'), // The title for the tab + responsive: true, // Whether the tab is responsive + activeLinkOptions: { exact: false }, // The options for the active link + order: 4 // The order of the tab + }); + } } - ngOnDestroy(): void {} + ngOnDestroy(): void { + // Delete the timesheet tabset from the registry + this._pageTabRegistryService.deleteTabset(TabsetRegistryIdEnum.Timesheet); + } } diff --git a/apps/gauzy/src/app/pages/employees/timesheet/timesheet-routing.module.ts b/apps/gauzy/src/app/pages/employees/timesheet/timesheet-routing.module.ts index 962e11be639..698e3c3fe52 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/timesheet-routing.module.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/timesheet-routing.module.ts @@ -1,48 +1,40 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; +import { TabsetRegistryIdEnum } from '@gauzy/ui-core/core'; import { TimesheetLayoutComponent } from './layout/layout.component'; const routes: Routes = [ - { - path: '', - redirectTo: 'daily', - pathMatch: 'full' - }, { path: '', component: TimesheetLayoutComponent, + data: { tabsetId: TabsetRegistryIdEnum.Timesheet }, children: [ + { + path: '', + redirectTo: 'daily', + pathMatch: 'full' + }, { path: 'daily', - loadChildren: () => import('./daily/daily.module').then( - (m) => m.DailyModule - ) + loadChildren: () => import('./daily/daily.module').then((m) => m.DailyModule) }, { path: 'weekly', - loadChildren: () => import('./weekly/weekly.module').then( - (m) => m.WeeklyModule - ) + loadChildren: () => import('./weekly/weekly.module').then((m) => m.WeeklyModule) }, { path: 'calendar', - loadChildren: () => import('./calendar/calendar.module').then( - (m) => m.CalendarModule - ) + loadChildren: () => import('./calendar/calendar.module').then((m) => m.CalendarModule) }, { path: 'approvals', - loadChildren: () => import('./approvals/approvals.module').then( - (m) => m.ApprovalsModule - ) + loadChildren: () => import('./approvals/approvals.module').then((m) => m.ApprovalsModule) } ] }, { path: ':id', - loadChildren: () => import('./view/view.module').then( - (m) => m.ViewModule - ) + loadChildren: () => import('./view/view.module').then((m) => m.ViewModule) } ]; diff --git a/apps/gauzy/src/app/pages/employees/timesheet/timesheet.module.ts b/apps/gauzy/src/app/pages/employees/timesheet/timesheet.module.ts index 1b0076311a9..7480bae72f4 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/timesheet.module.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/timesheet.module.ts @@ -1,22 +1,21 @@ -// tslint:disable: nx-enforce-module-boundaries import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { NbCardModule } from '@nebular/theme'; import { TranslateModule } from '@ngx-translate/core'; -import { NbRouteTabsetModule, NbCardModule } from '@nebular/theme'; -import { SharedModule } from '@gauzy/ui-core/shared'; +import { DynamicTabsModule, SharedModule } from '@gauzy/ui-core/shared'; import { TimesheetRoutingModule } from './timesheet-routing.module'; import { TimesheetLayoutComponent } from './layout/layout.component'; @NgModule({ - declarations: [TimesheetLayoutComponent], - exports: [], imports: [ CommonModule, + NbCardModule, + TranslateModule.forChild(), TimesheetRoutingModule, SharedModule, - NbRouteTabsetModule, - NbCardModule, - TranslateModule.forChild() - ] + DynamicTabsModule + ], + declarations: [TimesheetLayoutComponent], + exports: [] }) export class TimesheetModule {} diff --git a/apps/gauzy/src/app/pages/employees/timesheet/weekly/weekly/weekly.component.ts b/apps/gauzy/src/app/pages/employees/timesheet/weekly/weekly/weekly.component.ts index 245955a3389..72630b73d11 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/weekly/weekly/weekly.component.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/weekly/weekly/weekly.component.ts @@ -5,9 +5,15 @@ import { filter, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { chain, pick } from 'underscore'; -import { DateRangePickerBuilderService, moment, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { + DateRangePickerBuilderService, + moment, + Store, + TimesheetFilterService, + TimesheetService +} from '@gauzy/ui-core/core'; import { IGetTimeLogInput, ITimeLog, IOrganizationProject, ITimeLogFilters, PermissionsEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { TranslateService } from '@ngx-translate/core'; import { BaseSelectorFilterComponent, diff --git a/apps/gauzy/src/app/pages/employment-types/employment-types.component.ts b/apps/gauzy/src/app/pages/employment-types/employment-types.component.ts index 3716e96c1ad..a51fa6be5d4 100644 --- a/apps/gauzy/src/app/pages/employment-types/employment-types.component.ts +++ b/apps/gauzy/src/app/pages/employment-types/employment-types.component.ts @@ -13,8 +13,8 @@ import { } from '@gauzy/contracts'; import { takeUntil } from 'rxjs/operators'; import { NbDialogService } from '@nebular/theme'; -import { OrganizationEmploymentTypesService } from '@gauzy/ui-core/core'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { OrganizationEmploymentTypesService, Store } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { Subject, firstValueFrom, filter, debounceTime, tap } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { diff --git a/apps/gauzy/src/app/pages/equipment-sharing-policy/equipment-sharing-policy.component.ts b/apps/gauzy/src/app/pages/equipment-sharing-policy/equipment-sharing-policy.component.ts index 36079382327..bd9a0afe40f 100644 --- a/apps/gauzy/src/app/pages/equipment-sharing-policy/equipment-sharing-policy.component.ts +++ b/apps/gauzy/src/app/pages/equipment-sharing-policy/equipment-sharing-policy.component.ts @@ -7,8 +7,8 @@ import { filter, tap } from 'rxjs/operators'; import { firstValueFrom, Subject, debounceTime } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IEquipmentSharing, ComponentLayoutStyleEnum, IEquipmentSharingPolicy, IOrganization } from '@gauzy/contracts'; -import { EquipmentSharingPolicyService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { EquipmentSharingPolicyService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { DeleteConfirmationComponent, EquipmentSharingPolicyMutationComponent, diff --git a/apps/gauzy/src/app/pages/equipment-sharing/equipment-sharing.component.ts b/apps/gauzy/src/app/pages/equipment-sharing/equipment-sharing.component.ts index 49f1e2368cf..bbe7331ac74 100644 --- a/apps/gauzy/src/app/pages/equipment-sharing/equipment-sharing.component.ts +++ b/apps/gauzy/src/app/pages/equipment-sharing/equipment-sharing.component.ts @@ -15,8 +15,14 @@ import { NbDialogService } from '@nebular/theme'; import { combineLatest, Subject, firstValueFrom } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { EquipmentSharingService, ErrorHandlingService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { + EquipmentSharingService, + ErrorHandlingService, + ServerDataSource, + Store, + ToastrService +} from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { DateViewComponent, DeleteConfirmationComponent, diff --git a/apps/gauzy/src/app/pages/equipment/equipment.component.ts b/apps/gauzy/src/app/pages/equipment/equipment.component.ts index b002749bbb1..e2e9aa8a375 100644 --- a/apps/gauzy/src/app/pages/equipment/equipment.component.ts +++ b/apps/gauzy/src/app/pages/equipment/equipment.component.ts @@ -8,8 +8,8 @@ import { NbDialogService } from '@nebular/theme'; import { debounceTime, firstValueFrom, Subject } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { EquipmentService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { EquipmentService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { DeleteConfirmationComponent, EquipmentMutationComponent, diff --git a/apps/gauzy/src/app/pages/expense-recurring/expense-recurring.component.ts b/apps/gauzy/src/app/pages/expense-recurring/expense-recurring.component.ts index 91a90126ac7..d2c1139e0d4 100644 --- a/apps/gauzy/src/app/pages/expense-recurring/expense-recurring.component.ts +++ b/apps/gauzy/src/app/pages/expense-recurring/expense-recurring.component.ts @@ -16,10 +16,11 @@ import { import { DateRangePickerBuilderService, OrganizationRecurringExpenseService, + Store, ToastrService, monthNames } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { RecurringExpenseDeleteConfirmationComponent, RecurringExpenseMutationComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/expenses/expense-categories/expense-categories.component.ts b/apps/gauzy/src/app/pages/expenses/expense-categories/expense-categories.component.ts index 0b13af2b1d5..4953330330a 100644 --- a/apps/gauzy/src/app/pages/expenses/expense-categories/expense-categories.component.ts +++ b/apps/gauzy/src/app/pages/expenses/expense-categories/expense-categories.component.ts @@ -12,11 +12,12 @@ import { IExpenseCategory } from '@gauzy/contracts'; import { IPaginationBase, NotesWithTagsComponent, PaginationFilterBaseComponent } from '@gauzy/ui-core/shared'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { ErrorHandlingService, OrganizationExpenseCategoriesService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/expenses/expense-categories/expense-category-mutation/expense-category-mutation.component.ts b/apps/gauzy/src/app/pages/expenses/expense-categories/expense-category-mutation/expense-category-mutation.component.ts index 45508e1f627..f2eb7a3a2a1 100644 --- a/apps/gauzy/src/app/pages/expenses/expense-categories/expense-category-mutation/expense-category-mutation.component.ts +++ b/apps/gauzy/src/app/pages/expenses/expense-categories/expense-category-mutation/expense-category-mutation.component.ts @@ -5,7 +5,7 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { ITag, IOrganization, IExpenseCategory } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FormHelpers } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/expenses/expenses.component.ts b/apps/gauzy/src/app/pages/expenses/expenses.component.ts index 609831351a1..aacb563e20d 100644 --- a/apps/gauzy/src/app/pages/expenses/expenses.component.ts +++ b/apps/gauzy/src/app/pages/expenses/expenses.component.ts @@ -16,15 +16,16 @@ import { combineLatest, Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { NbDialogService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import moment from 'moment'; +import * as moment from 'moment'; import { Cell } from 'angular2-smart-table'; import { TranslateService } from '@ngx-translate/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange, employeeMapper, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange, employeeMapper, toUTC } from '@gauzy/ui-core/common'; import { DateRangePickerBuilderService, ErrorHandlingService, ExpensesService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { diff --git a/apps/gauzy/src/app/pages/goal-settings/edit-kpi/edit-kpi.component.ts b/apps/gauzy/src/app/pages/goal-settings/edit-kpi/edit-kpi.component.ts index d9aee8059e2..cfe6c537bad 100644 --- a/apps/gauzy/src/app/pages/goal-settings/edit-kpi/edit-kpi.component.ts +++ b/apps/gauzy/src/app/pages/goal-settings/edit-kpi/edit-kpi.component.ts @@ -1,9 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TranslateService } from '@ngx-translate/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { NbDialogRef } from '@nebular/theme'; -import { EmployeesService } from '@gauzy/ui-core/core'; import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { @@ -14,9 +12,8 @@ import { KeyResultNumberUnitsEnum, IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { GoalSettingsService } from '@gauzy/ui-core/core'; -import { ToastrService } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { EmployeesService, GoalSettingsService, Store, ToastrService } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-edit-kpi', diff --git a/apps/gauzy/src/app/pages/goal-settings/edit-time-frame/edit-time-frame.component.ts b/apps/gauzy/src/app/pages/goal-settings/edit-time-frame/edit-time-frame.component.ts index 80d4d25c35b..09057f5fc88 100644 --- a/apps/gauzy/src/app/pages/goal-settings/edit-time-frame/edit-time-frame.component.ts +++ b/apps/gauzy/src/app/pages/goal-settings/edit-time-frame/edit-time-frame.component.ts @@ -17,7 +17,7 @@ import { } from 'date-fns'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { GoalSettingsService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/goal-settings/goal-settings.component.ts b/apps/gauzy/src/app/pages/goal-settings/goal-settings.component.ts index c0b6b30d0c5..73de2e23eae 100644 --- a/apps/gauzy/src/app/pages/goal-settings/goal-settings.component.ts +++ b/apps/gauzy/src/app/pages/goal-settings/goal-settings.component.ts @@ -6,8 +6,8 @@ import { TranslateService } from '@ngx-translate/core'; import { Cell, LocalDataSource } from 'angular2-smart-table'; import { NbDialogService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { GoalSettingsService, ToastrService } from '@gauzy/ui-core/core'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { GoalSettingsService, Store, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { AlertModalComponent, DateViewComponent, diff --git a/apps/gauzy/src/app/pages/goals/edit-keyresults/edit-keyresults.component.ts b/apps/gauzy/src/app/pages/goals/edit-keyresults/edit-keyresults.component.ts index 5a5fbe5f865..433b321af1e 100644 --- a/apps/gauzy/src/app/pages/goals/edit-keyresults/edit-keyresults.component.ts +++ b/apps/gauzy/src/app/pages/goals/edit-keyresults/edit-keyresults.component.ts @@ -26,7 +26,7 @@ import { KeyResultNumberUnitsEnum, IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { endOfTomorrow } from 'date-fns'; @Component({ diff --git a/apps/gauzy/src/app/pages/goals/edit-objective/edit-objective.component.ts b/apps/gauzy/src/app/pages/goals/edit-objective/edit-objective.component.ts index bf497cfaeeb..6a20f7d5f1f 100644 --- a/apps/gauzy/src/app/pages/goals/edit-objective/edit-objective.component.ts +++ b/apps/gauzy/src/app/pages/goals/edit-objective/edit-objective.component.ts @@ -14,8 +14,7 @@ import { IOrganization, IUser } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { GoalSettingsService, OrganizationTeamsService } from '@gauzy/ui-core/core'; +import { GoalSettingsService, OrganizationTeamsService, Store } from '@gauzy/ui-core/core'; import { debounceTime, filter, firstValueFrom, tap } from 'rxjs'; import { EditTimeFrameComponent } from '../../goal-settings/edit-time-frame/edit-time-frame.component'; import { isFuture } from 'date-fns'; diff --git a/apps/gauzy/src/app/pages/goals/goal-template-select/goal-template-select.component.ts b/apps/gauzy/src/app/pages/goals/goal-template-select/goal-template-select.component.ts index 82136cdf725..9dc31e2c364 100644 --- a/apps/gauzy/src/app/pages/goals/goal-template-select/goal-template-select.component.ts +++ b/apps/gauzy/src/app/pages/goals/goal-template-select/goal-template-select.component.ts @@ -21,9 +21,9 @@ import { GoalSettingsService, GoalTemplatesService, KeyResultService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; import { TranslateService } from '@ngx-translate/core'; import { EditTimeFrameComponent } from '../../../pages/goal-settings/edit-time-frame/edit-time-frame.component'; diff --git a/apps/gauzy/src/app/pages/goals/goals.component.ts b/apps/gauzy/src/app/pages/goals/goals.component.ts index a3296a44e03..28ef266eb36 100644 --- a/apps/gauzy/src/app/pages/goals/goals.component.ts +++ b/apps/gauzy/src/app/pages/goals/goals.component.ts @@ -14,7 +14,7 @@ import { GoalLevelEnum } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ErrorHandlingService, GoalService, diff --git a/apps/gauzy/src/app/pages/goals/key-result-parameters/key-result-parameters.component.ts b/apps/gauzy/src/app/pages/goals/key-result-parameters/key-result-parameters.component.ts index 2d2d78fe043..e067b1e3fae 100644 --- a/apps/gauzy/src/app/pages/goals/key-result-parameters/key-result-parameters.component.ts +++ b/apps/gauzy/src/app/pages/goals/key-result-parameters/key-result-parameters.component.ts @@ -11,8 +11,7 @@ import { IOrganization } from '@gauzy/contracts'; import { NbDialogRef } from '@nebular/theme'; -import { GoalSettingsService, KeyResultService, TasksService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { GoalSettingsService, KeyResultService, Store, TasksService } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; @UntilDestroy() diff --git a/apps/gauzy/src/app/pages/goals/keyresult-details/keyresult-details.component.ts b/apps/gauzy/src/app/pages/goals/keyresult-details/keyresult-details.component.ts index 14a092bd814..dedb71c6655 100644 --- a/apps/gauzy/src/app/pages/goals/keyresult-details/keyresult-details.component.ts +++ b/apps/gauzy/src/app/pages/goals/keyresult-details/keyresult-details.component.ts @@ -9,6 +9,7 @@ import { KeyResultService, KeyResultUpdateService, OrganizationProjectsService, + Store, TasksService, TasksStoreService } from '@gauzy/ui-core/core'; @@ -24,7 +25,6 @@ import { IKPI, IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TranslateService } from '@ngx-translate/core'; import { AddTaskDialogComponent, AlertModalComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/goals/keyresult-progress-chart/keyresult-progress-chart.component.ts b/apps/gauzy/src/app/pages/goals/keyresult-progress-chart/keyresult-progress-chart.component.ts index bcf4d4da3f4..2339ff87868 100644 --- a/apps/gauzy/src/app/pages/goals/keyresult-progress-chart/keyresult-progress-chart.component.ts +++ b/apps/gauzy/src/app/pages/goals/keyresult-progress-chart/keyresult-progress-chart.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit, Input } from '@angular/core'; import { IKeyResult, KeyResultDeadlineEnum, IKPI, IOrganization } from '@gauzy/contracts'; import { GoalSettingsService } from '@gauzy/ui-core/core'; import { differenceInCalendarDays, addMonths, compareDesc, addDays, addWeeks, addQuarters, isAfter } from 'date-fns'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TranslateService } from '@ngx-translate/core'; diff --git a/apps/gauzy/src/app/pages/goals/keyresult-update/keyresult-update.component.ts b/apps/gauzy/src/app/pages/goals/keyresult-update/keyresult-update.component.ts index 5f9f957a0e4..ee80d7d2395 100644 --- a/apps/gauzy/src/app/pages/goals/keyresult-update/keyresult-update.component.ts +++ b/apps/gauzy/src/app/pages/goals/keyresult-update/keyresult-update.component.ts @@ -12,7 +12,7 @@ import { import { TranslateService } from '@ngx-translate/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { GoalSettingsService, KeyResultUpdateService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-keyresult-update', diff --git a/apps/gauzy/src/app/pages/help-center/add-article/add-article.component.ts b/apps/gauzy/src/app/pages/help-center/add-article/add-article.component.ts index 7a26223b607..3003d955464 100644 --- a/apps/gauzy/src/app/pages/help-center/add-article/add-article.component.ts +++ b/apps/gauzy/src/app/pages/help-center/add-article/add-article.component.ts @@ -1,18 +1,21 @@ -import { IHelpCenterArticle, IEmployee, IHelpCenterAuthor, IOrganization } from '@gauzy/contracts'; import { Component, OnDestroy, OnInit, Input } from '@angular/core'; +import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { NbDialogRef } from '@nebular/theme'; -import { Subject } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { CKEditor4 } from 'ckeditor4-angular/ckeditor'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { IHelpCenterArticle, IEmployee, IHelpCenterAuthor, IOrganization } from '@gauzy/contracts'; import { ckEditorConfig } from '@gauzy/ui-core/shared'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ErrorHandlingService, HelpCenterAuthorService } from '@gauzy/ui-core/core'; -import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; -import { HelpCenterArticleService } from '@gauzy/ui-core/core'; -import { EmployeesService } from '@gauzy/ui-core/core'; -import { takeUntil } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; +import { + EmployeesService, + ErrorHandlingService, + HelpCenterArticleService, + HelpCenterAuthorService, + Store +} from '@gauzy/ui-core/core'; +@UntilDestroy() @Component({ selector: 'ga-add-article', templateUrl: 'add-article.component.html', @@ -23,7 +26,7 @@ export class AddArticleComponent extends TranslationBaseComponent implements OnI @Input() editType: string; @Input() length: number; @Input() id: string; - private _ngDestroy$ = new Subject(); + constructor( protected dialogRef: NbDialogRef, readonly translateService: TranslateService, @@ -67,7 +70,7 @@ export class AddArticleComponent extends TranslationBaseComponent implements OnI const { id: organizationId, tenantId } = this.organization; this.employeeService .getAll(['user'], { organizationId, tenantId }) - .pipe(takeUntil(this._ngDestroy$)) + .pipe(untilDestroyed(this)) .subscribe((employees) => { this.employees = employees.items; }); @@ -179,10 +182,7 @@ export class AddArticleComponent extends TranslationBaseComponent implements OnI this.dialogRef.close(); } - ngOnDestroy() { - this._ngDestroy$.next(); - this._ngDestroy$.complete(); - } + ngOnDestroy() {} public get name(): AbstractControl { return this.form.get('name'); diff --git a/apps/gauzy/src/app/pages/help-center/help-center.component.ts b/apps/gauzy/src/app/pages/help-center/help-center.component.ts index 9a1035fed80..b7e41fc4ecc 100644 --- a/apps/gauzy/src/app/pages/help-center/help-center.component.ts +++ b/apps/gauzy/src/app/pages/help-center/help-center.component.ts @@ -10,7 +10,7 @@ import { HelpCenterArticleService, HelpCenterAuthorService, ToastrService } from import { filter } from 'rxjs/operators'; import { EmployeesService } from '@gauzy/ui-core/core'; import { FormControl } from '@angular/forms'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { firstValueFrom } from 'rxjs'; diff --git a/apps/gauzy/src/app/pages/help/help.component.ts b/apps/gauzy/src/app/pages/help/help.component.ts index f9becbc0daa..54cba9a2138 100644 --- a/apps/gauzy/src/app/pages/help/help.component.ts +++ b/apps/gauzy/src/app/pages/help/help.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ngx-help', diff --git a/apps/gauzy/src/app/pages/hubstaff/components/hubstaff-authorize/hubstaff-authorize.component.ts b/apps/gauzy/src/app/pages/hubstaff/components/hubstaff-authorize/hubstaff-authorize.component.ts index dc5575d27b4..db6b32f956b 100644 --- a/apps/gauzy/src/app/pages/hubstaff/components/hubstaff-authorize/hubstaff-authorize.component.ts +++ b/apps/gauzy/src/app/pages/hubstaff/components/hubstaff-authorize/hubstaff-authorize.component.ts @@ -4,8 +4,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { filter, tap } from 'rxjs/operators'; import { IIntegration, IIntegrationTenant, IOrganization, IntegrationEnum } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; -import { HubstaffService } from '@gauzy/ui-core/core'; +import { HubstaffService, Store } from '@gauzy/ui-core/core'; import { IntegrationsService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/hubstaff/components/hubstaff/hubstaff.component.ts b/apps/gauzy/src/app/pages/hubstaff/components/hubstaff/hubstaff.component.ts index 1a4294ab944..3629e2c9f1c 100644 --- a/apps/gauzy/src/app/pages/hubstaff/components/hubstaff/hubstaff.component.ts +++ b/apps/gauzy/src/app/pages/hubstaff/components/hubstaff/hubstaff.component.ts @@ -9,8 +9,7 @@ import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ID, IHubstaffOrganization, IHubstaffProject, IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ErrorHandlingService, HubstaffService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, HubstaffService, Store, ToastrService } from '@gauzy/ui-core/core'; import { SettingsDialogComponent } from '../settings-dialog/settings-dialog.component'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/hubstaff/components/settings-dialog/settings-dialog.component.ts b/apps/gauzy/src/app/pages/hubstaff/components/settings-dialog/settings-dialog.component.ts index d5a87010f58..b1a89b6c95c 100644 --- a/apps/gauzy/src/app/pages/hubstaff/components/settings-dialog/settings-dialog.component.ts +++ b/apps/gauzy/src/app/pages/hubstaff/components/settings-dialog/settings-dialog.component.ts @@ -1,7 +1,7 @@ import { AfterViewInit, ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { NbDialogRef } from '@nebular/theme'; import { Observable } from 'rxjs'; -import moment from 'moment'; +import * as moment from 'moment'; import { tap } from 'rxjs/operators'; import { IDateRangeActivityFilter, IntegrationEntity } from '@gauzy/contracts'; import { HubstaffService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/import-export/import-export.component.ts b/apps/gauzy/src/app/pages/import-export/import-export.component.ts index d25cf800cd9..0957661725b 100644 --- a/apps/gauzy/src/app/pages/import-export/import-export.component.ts +++ b/apps/gauzy/src/app/pages/import-export/import-export.component.ts @@ -21,8 +21,7 @@ import { } from '@gauzy/contracts'; import { Environment, environment } from '@gauzy/ui-config'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ErrorHandlingService, ToastrService, UsersOrganizationsService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, Store, ToastrService, UsersOrganizationsService } from '@gauzy/ui-core/core'; import { ExportAllService, GauzyCloudService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/import-export/import/import.component.ts b/apps/gauzy/src/app/pages/import-export/import/import.component.ts index 4be0484b84a..fff6e0ad4d3 100644 --- a/apps/gauzy/src/app/pages/import-export/import/import.component.ts +++ b/apps/gauzy/src/app/pages/import-export/import/import.component.ts @@ -12,8 +12,7 @@ import { saveAs } from 'file-saver'; import { environment } from '@gauzy/ui-config'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { API_PREFIX } from '@gauzy/ui-core/common'; -import { Store } from '@gauzy/ui-core/common'; -import { ImportService } from '@gauzy/ui-core/core'; +import { ImportService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/income/income.component.ts b/apps/gauzy/src/app/pages/income/income.component.ts index 95cc55f3b8c..f6d498454ff 100644 --- a/apps/gauzy/src/app/pages/income/income.component.ts +++ b/apps/gauzy/src/app/pages/income/income.component.ts @@ -7,7 +7,7 @@ import { TranslateService } from '@ngx-translate/core'; import { Cell } from 'angular2-smart-table'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import moment from 'moment'; +import * as moment from 'moment'; import { IIncome, ComponentLayoutStyleEnum, @@ -18,12 +18,13 @@ import { IDateRangePicker, PermissionsEnum } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange, employeeMapper, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange, employeeMapper, toUTC } from '@gauzy/ui-core/common'; import { DateRangePickerBuilderService, ErrorHandlingService, IncomeService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { diff --git a/apps/gauzy/src/app/pages/integrations/components/integration-list/list.component.ts b/apps/gauzy/src/app/pages/integrations/components/integration-list/list.component.ts index 27edcfce028..eb50709d543 100644 --- a/apps/gauzy/src/app/pages/integrations/components/integration-list/list.component.ts +++ b/apps/gauzy/src/app/pages/integrations/components/integration-list/list.component.ts @@ -6,7 +6,7 @@ import { Observable } from 'rxjs/internal/Observable'; import { NbDialogService, NbToastrService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { HttpStatus, IIntegration, @@ -19,7 +19,8 @@ import { ErrorHandlingService, IntegrationEntitySettingServiceStoreService, IntegrationTenantService, - IntegrationsService + IntegrationsService, + Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { DeleteConfirmationComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/authorization/authorization.component.ts b/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/authorization/authorization.component.ts index 0ef64fbca2c..78501017568 100644 --- a/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/authorization/authorization.component.ts +++ b/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/authorization/authorization.component.ts @@ -5,8 +5,7 @@ import { EMPTY } from 'rxjs'; import { catchError, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IIntegrationTenant, IOrganization } from '@gauzy/contracts'; -import { ErrorHandlingService, GauzyAIService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, GauzyAIService, Store, ToastrService } from '@gauzy/ui-core/core'; import { ReplacePipe } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/view/view.component.ts b/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/view/view.component.ts index 67f68d6d2e0..995b77b4300 100644 --- a/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/view/view.component.ts +++ b/apps/gauzy/src/app/pages/integrations/gauzy-ai/components/view/view.component.ts @@ -15,12 +15,13 @@ import { } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ReplacePipe } from '@gauzy/ui-core/shared'; -import { ErrorHandlingService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; import { + ErrorHandlingService, GauzyAIService, IntegrationEntitySettingService, - IntegrationEntitySettingServiceStoreService + IntegrationEntitySettingServiceStoreService, + Store, + ToastrService } from '@gauzy/ui-core/core'; import { SettingTitlesEnum } from '../integration-setting-card/integration-setting-card.component'; diff --git a/apps/gauzy/src/app/pages/integrations/github/components/installation/installation.component.ts b/apps/gauzy/src/app/pages/integrations/github/components/installation/installation.component.ts index e74df3bfdd3..50a025edf8b 100644 --- a/apps/gauzy/src/app/pages/integrations/github/components/installation/installation.component.ts +++ b/apps/gauzy/src/app/pages/integrations/github/components/installation/installation.component.ts @@ -3,8 +3,7 @@ import { ActivatedRoute } from '@angular/router'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IGithubAppInstallInput, IIntegrationTenant, IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { GithubService } from '@gauzy/ui-core/core'; +import { GithubService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/integrations/github/components/view/view.component.ts b/apps/gauzy/src/app/pages/integrations/github/components/view/view.component.ts index e521acc8a6b..248088f6213 100644 --- a/apps/gauzy/src/app/pages/integrations/github/components/view/view.component.ts +++ b/apps/gauzy/src/app/pages/integrations/github/components/view/view.component.ts @@ -22,8 +22,14 @@ import { SYNC_TAG_GAUZY, TaskStatusEnum } from '@gauzy/contracts'; -import { ErrorHandlingService, GithubService, OrganizationProjectsService, ToastrService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { + ErrorHandlingService, + GithubService, + OrganizationProjectsService, + Store, + ToastrService +} from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { ClickableLinkComponent, ProjectComponent, diff --git a/apps/gauzy/src/app/pages/integrations/github/components/wizard/wizard.component.ts b/apps/gauzy/src/app/pages/integrations/github/components/wizard/wizard.component.ts index 97dd599b67a..47659f57a38 100644 --- a/apps/gauzy/src/app/pages/integrations/github/components/wizard/wizard.component.ts +++ b/apps/gauzy/src/app/pages/integrations/github/components/wizard/wizard.component.ts @@ -5,7 +5,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { environment } from '@gauzy/ui-config'; import { IOrganization } from '@gauzy/contracts'; import { distinctUntilChange, toParams } from '@gauzy/ui-core/common'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { GITHUB_AUTHORIZATION_URL } from '../../github.config'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item-variant/variant-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item-variant/variant-form.component.ts index 32325fe3cb7..51da063ffc5 100644 --- a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item-variant/variant-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item-variant/variant-form.component.ts @@ -13,9 +13,9 @@ import { ProductVariantPriceService, ProductVariantService, ProductVariantSettingService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; import { SelectAssetComponent } from '@gauzy/ui-core/shared'; export interface IOptionCreateInput { diff --git a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.html b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.html index 85ae4d3c70b..d8ee009174a 100644 --- a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.html +++ b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.html @@ -6,12 +6,7 @@
-
@@ -20,14 +15,9 @@
- + @@ -42,10 +32,7 @@ >
- + - +
@@ -93,9 +74,7 @@ fullWidth type="text" nbInput - [placeholder]=" - 'INVENTORY_PAGE.NAME' | translate - " + [placeholder]="'INVENTORY_PAGE.NAME' | translate" formControlName="activeOptionName" />
@@ -104,9 +83,7 @@ fullWidth type="text" nbInput - [placeholder]=" - 'INVENTORY_PAGE.CODE' | translate - " + [placeholder]="'INVENTORY_PAGE.CODE' | translate" formControlName="activeOptionCode" />
@@ -117,19 +94,11 @@ status="success" outline size="small" - (click)=" - onTranslateOptionClick(optionGroupData) - " + (click)="onTranslateOptionClick(optionGroupData)" > - @@ -147,15 +114,8 @@
- - + +
@@ -171,15 +131,8 @@
- - + +
diff --git a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.ts index ba70aece439..c40359a6757 100644 --- a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/options-form/options-form.component.ts @@ -6,13 +6,12 @@ import { IProductOptionTranslatable } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { InventoryStore } from '@gauzy/ui-core/core'; +import { InventoryStore, Store } from '@gauzy/ui-core/core'; import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; import { firstValueFrom } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { NbDialogService } from '@nebular/theme'; -import { Store } from '@gauzy/ui-core/common'; import { ProductOptionGroupTranslationsComponent } from '@gauzy/ui-core/shared'; export interface OptionCreateInput { @@ -64,7 +63,7 @@ export class OptionsFormComponent implements OnInit { optionGroups: any[] = []; @HostListener('document:click', ['$event']) - clickout(event) { + onClick(event: MouseEvent) { if (!this.eRef.nativeElement.contains(event.target)) { this.activeOptionGroup = this.getEmptyOptionGroup(); this.activeOption = this.getEmptyOption(); @@ -158,13 +157,13 @@ export class OptionsFormComponent implements OnInit { this.optionGroups.splice(0, 0, newOptionGroup); } - onDeleteOptinGroupClick(optionGroupDeleted: IProductOptionGroupUI) { + onDeleteOptionGroupClick(optionGroupDeleted: IProductOptionGroupUI) { optionGroupDeleted.options.forEach((option) => { this.onDeleteOption(option); }); this.optionGroups = this.optionGroups.filter( - (optinGroup) => optinGroup.formOptionGroupId !== optionGroupDeleted.formOptionGroupId + (optionGroup) => optionGroup.formOptionGroupId !== optionGroupDeleted.formOptionGroupId ); this.inventoryStore.addDeletedOptionGroup(optionGroupDeleted); @@ -206,7 +205,7 @@ export class OptionsFormComponent implements OnInit { updateActiveOptionGroupName(value: string) { if (this.optionGroups.find((optionGroup) => optionGroup.name == value)) { this.form.controls['activeOptionGroupName'].setErrors({ - error: 'alredy group' + error: 'already group' }); return; @@ -220,11 +219,11 @@ export class OptionsFormComponent implements OnInit { } updateActiveOptionName(value: string) { - let checkDublicateOption = this.activeOptionGroup.options.find((option) => option.name == value); + let checkDuplicateOption = this.activeOptionGroup.options.find((option) => option.name == value); - if (checkDublicateOption) { + if (checkDuplicateOption) { this.form.controls['activeOptionName'].setErrors({ - error: 'dublicate option' + error: 'duplicate option' }); } else { this.form.controls['activeOptionName'].setErrors(null); @@ -235,11 +234,11 @@ export class OptionsFormComponent implements OnInit { } updateActiveOptionCode(value: string) { - let checkDublicateCode = this.activeOptionGroup.options.find((option) => option.code == value); + let checkDuplicateCode = this.activeOptionGroup.options.find((option) => option.code == value); - if (checkDublicateCode) { + if (checkDuplicateCode) { this.form.controls['activeOptionCode'].setErrors({ - error: 'dublicate code' + error: 'duplicate code' }); } else { this.form.controls['activeOptionCode'].setErrors(null); diff --git a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-form.component.ts index 8e1c889000b..850d8777571 100644 --- a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-form.component.ts @@ -15,8 +15,7 @@ import { } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { InventoryStore, ProductService, ProductVariantService, ToastrService } from '@gauzy/ui-core/core'; +import { InventoryStore, ProductService, ProductVariantService, Store, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-gallery/product-gallery.component.ts b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-gallery/product-gallery.component.ts index 87b59c9306f..14b4678724c 100644 --- a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-gallery/product-gallery.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/product-gallery/product-gallery.component.ts @@ -6,8 +6,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { IImageAsset, IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ImageAssetService, InventoryStore, ProductService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { ImageAssetService, InventoryStore, ProductService, Store, ToastrService } from '@gauzy/ui-core/core'; import { GalleryComponent, GalleryService, ImageAssetComponent, SelectAssetComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) @@ -100,10 +99,10 @@ export class ProductGalleryComponent extends TranslationBaseComponent implements if (!selectedImages) return; selectedImages = selectedImages.length ? selectedImages.filter((image) => { - return !this.inventoryStore.gallery.find((galleryImg) => { - return galleryImg.id == image.id || galleryImg.name == image.name; - }); - }) + return !this.inventoryStore.gallery.find((galleryImg) => { + return galleryImg.id == image.id || galleryImg.name == image.name; + }); + }) : []; try { @@ -231,5 +230,5 @@ export class ProductGalleryComponent extends TranslationBaseComponent implements }); } - ngOnDestroy(): void { } + ngOnDestroy(): void {} } diff --git a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/variant-form/variant-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/variant-form/variant-form.component.ts index b864fa67a5d..ac040aea5ee 100644 --- a/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/variant-form/variant-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/edit-inventory-item/variant-form/variant-form.component.ts @@ -3,7 +3,7 @@ import { IProductOptionTranslatable, LanguagesEnum, VariantCreateInput } from '@ import { Router } from '@angular/router'; import { InventoryStore, TranslatableService } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy() @Component({ diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-form/merchant-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-form/merchant-form.component.ts index f986033d0a7..df4b23e1080 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-form/merchant-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-form/merchant-form.component.ts @@ -8,8 +8,8 @@ import { Subject, firstValueFrom } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { LatLng } from 'leaflet'; import { ITag, IMerchant, IWarehouse, IImageAsset, IOrganization } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { WarehouseService, ImageAssetService, MerchantService, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { WarehouseService, ImageAssetService, MerchantService, ToastrService, Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FormHelpers, LocationFormComponent, LeafletMapComponent, SelectAssetComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-table/merchant-table.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-table/merchant-table.component.ts index 991977027e8..584cc97314f 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-table/merchant-table.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-merchants/merchant-table/merchant-table.component.ts @@ -8,8 +8,8 @@ import { Subject, firstValueFrom } from 'rxjs'; import { Cell } from 'angular2-smart-table'; import { NbDialogService } from '@nebular/theme'; import { IMerchant, IOrganization, ComponentLayoutStyleEnum, IWarehouse } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { MerchantService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { MerchantService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-product-categories/product-categories.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-product-categories/product-categories.component.ts index 7631357a39d..f023fced4c9 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-product-categories/product-categories.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-product-categories/product-categories.component.ts @@ -7,8 +7,8 @@ import { debounceTime, filter, tap } from 'rxjs/operators'; import { combineLatest, Subject, firstValueFrom } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IProductCategoryTranslated, IOrganization, ComponentLayoutStyleEnum } from '@gauzy/contracts'; -import { ProductCategoryService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ProductCategoryService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { ImageRowComponent } from '../inventory-table-components'; import { DeleteConfirmationComponent, diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-product-types/product-types.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-product-types/product-types.component.ts index 84846b04be9..56a55b6b91f 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-product-types/product-types.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-product-types/product-types.component.ts @@ -7,9 +7,8 @@ import { Subject, combineLatest, firstValueFrom } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization, IProductTypeTranslated, ComponentLayoutStyleEnum } from '@gauzy/contracts'; -import { ErrorHandlingService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ProductTypeService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, ProductTypeService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { DeleteConfirmationComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/select-product-form/select-product-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/select-product-form/select-product-form.component.ts index 2d87d4d6258..9ee2014d7d5 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/select-product-form/select-product-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/select-product-form/select-product-form.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; import { IOrganization, IProductTranslated, LanguagesEnum } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { API_PREFIX } from '@gauzy/ui-core/common'; @@ -8,11 +9,10 @@ import { distinctUntilChange } from '@gauzy/ui-core/common'; import { ImageRowComponent } from '../../inventory-table-components/image-row.component'; import { NbDialogRef } from '@nebular/theme'; import { SelectedRowComponent } from '../../inventory-table-components/selected-row.component'; -import { HttpClient } from '@angular/common/http'; import { tap } from 'rxjs/operators'; import { debounceTime } from 'rxjs'; import { IPaginationBase, PaginationFilterBaseComponent } from '@gauzy/ui-core/shared'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; export interface SelectedRowEvent { data: IProductTranslated; diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-form/warehouse-form.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-form/warehouse-form.component.ts index 8e853d17c84..c10a8b71999 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-form/warehouse-form.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-form/warehouse-form.component.ts @@ -2,7 +2,7 @@ import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular import { ActivatedRoute, Router } from '@angular/router'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { ITag, IWarehouse, IImageAsset, IOrganization } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { LatLng } from 'leaflet'; @@ -10,7 +10,7 @@ import { NbDialogService, NbStepperComponent } from '@nebular/theme'; import { Subject, firstValueFrom, debounceTime } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ImageAssetService, ToastrService, WarehouseService } from '@gauzy/ui-core/core'; +import { ImageAssetService, Store, ToastrService, WarehouseService } from '@gauzy/ui-core/core'; import { FormHelpers, LocationFormComponent, LeafletMapComponent, SelectAssetComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-products-table/warehouse-products-table.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-products-table/warehouse-products-table.component.ts index 947c82ff373..a24cd9fff62 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-products-table/warehouse-products-table.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouse-products-table/warehouse-products-table.component.ts @@ -1,13 +1,13 @@ import { AfterViewInit, Component, Input, OnInit } from '@angular/core'; import { IWarehouse, IOrganization } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Cell, LocalDataSource } from 'angular2-smart-table'; import { NbDialogService } from '@nebular/theme'; import { filter, firstValueFrom, Subject } from 'rxjs'; import { debounceTime, tap } from 'rxjs/operators'; -import { InventoryStore, WarehouseService } from '@gauzy/ui-core/core'; +import { InventoryStore, Store, WarehouseService } from '@gauzy/ui-core/core'; import { SelectProductComponent } from '../select-product-form/select-product-form.component'; import { ImageRowComponent } from '../../inventory-table-components/image-row.component'; import { ManageQuantityComponent } from '../manage-quantity/manage-quantity.component'; diff --git a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouses-table/warehouses-table.component.ts b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouses-table/warehouses-table.component.ts index ae6fc759683..72b461c7502 100644 --- a/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouses-table/warehouses-table.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/manage-warehouses/warehouses-table/warehouses-table.component.ts @@ -8,8 +8,8 @@ import { Subject, firstValueFrom } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ComponentLayoutStyleEnum, IOrganization, IWarehouse, PermissionsEnum } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ServerDataSource, ToastrService, WarehouseService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ServerDataSource, Store, ToastrService, WarehouseService } from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/inventory/components/table-inventory-items/table-inventory.component.ts b/apps/gauzy/src/app/pages/inventory/components/table-inventory-items/table-inventory.component.ts index 7257fdccbb0..2747134431a 100644 --- a/apps/gauzy/src/app/pages/inventory/components/table-inventory-items/table-inventory.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/table-inventory-items/table-inventory.component.ts @@ -21,8 +21,8 @@ import { PaginationFilterBaseComponent, TagsOnlyComponent } from '@gauzy/ui-core/shared'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ProductService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ProductService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { ImageRowComponent, NameWithDescriptionComponent } from '../inventory-table-components'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/inventory/components/view-inventory-item/view-inventory-item.component.ts b/apps/gauzy/src/app/pages/inventory/components/view-inventory-item/view-inventory-item.component.ts index 86fd5d27f13..c940bc09ae2 100644 --- a/apps/gauzy/src/app/pages/inventory/components/view-inventory-item/view-inventory-item.component.ts +++ b/apps/gauzy/src/app/pages/inventory/components/view-inventory-item/view-inventory-item.component.ts @@ -8,9 +8,9 @@ import { combineLatest } from 'rxjs'; import { IImageAsset, IProductOptionTranslatable, IProductTranslatable, LanguagesEnum } from '@gauzy/contracts'; import { ProductService, TranslatableService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { EnabledStatusComponent, ImageRowComponent } from '../inventory-table-components'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { GalleryComponent, GalleryService } from '@gauzy/ui-core/shared'; +import { EnabledStatusComponent, ImageRowComponent } from '../inventory-table-components'; @UntilDestroy() @Component({ diff --git a/apps/gauzy/src/app/pages/invoices/invoice-add/invoice-add.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-add/invoice-add.component.ts index 375d7288867..f335f514389 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-add/invoice-add.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-add/invoice-add.component.ts @@ -19,14 +19,14 @@ import { ExpenseStatusesEnum } from '@gauzy/contracts'; import { filter, tap } from 'rxjs/operators'; -import { Store, compareDate, distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; +import { compareDate, distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; import { LocalDataSource } from 'angular2-smart-table'; import { Observable, firstValueFrom } from 'rxjs'; import { Router } from '@angular/router'; import { NbDialogService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import * as moment from 'moment'; -import { ToastrService } from '@gauzy/ui-core/core'; +import { Store, ToastrService } from '@gauzy/ui-core/core'; import { ExpensesService, InvoiceEstimateHistoryService, @@ -328,7 +328,7 @@ export class InvoiceAddComponent extends PaginationFilterBaseComponent implement type: 'text', isFilterable: false, width: '13%', - valuePrepareFunction: (cell, row) => { + valuePrepareFunction: (cell) => { return `${this.currency.value} ${cell}`; } }; @@ -351,8 +351,8 @@ export class InvoiceAddComponent extends PaginationFilterBaseComponent implement type: 'text', addable: false, editable: false, - valuePrepareFunction: (cell, row) => { - return `${this.currency.value} ${row.quantity * row.price}`; + valuePrepareFunction: (cell) => { + return `${this.currency.value} ${cell}`; }, isFilterable: false, width: '13%' diff --git a/apps/gauzy/src/app/pages/invoices/invoice-download/invoice-download-mutation.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-download/invoice-download-mutation.component.ts index 6b7daaa50e4..2457d7ea086 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-download/invoice-download-mutation.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-download/invoice-download-mutation.component.ts @@ -4,8 +4,7 @@ import { TranslateService } from '@ngx-translate/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { IInvoice } from '@gauzy/contracts'; import { saveAs } from 'file-saver'; -import { Store } from '@gauzy/ui-core/common'; -import { InvoiceEstimateHistoryService, InvoicesService, ToastrService } from '@gauzy/ui-core/core'; +import { InvoiceEstimateHistoryService, InvoicesService, Store, ToastrService } from '@gauzy/ui-core/core'; import { tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; diff --git a/apps/gauzy/src/app/pages/invoices/invoice-edit/invoice-edit.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-edit/invoice-edit.component.ts index 36ffa2ca607..89b26be56de 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-edit/invoice-edit.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-edit/invoice-edit.component.ts @@ -22,8 +22,8 @@ import { IProduct, IExpense } from '@gauzy/contracts'; -import { Store, compareDate, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ToastrService } from '@gauzy/ui-core/core'; +import { compareDate, distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store, ToastrService } from '@gauzy/ui-core/core'; import * as moment from 'moment'; import { InvoiceEmailMutationComponent } from '../invoice-email/invoice-email-mutation.component'; import { diff --git a/apps/gauzy/src/app/pages/invoices/invoice-email/invoice-email-mutation.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-email/invoice-email-mutation.component.ts index 0bdb20b2d9b..711ae196281 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-email/invoice-email-mutation.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-email/invoice-email-mutation.component.ts @@ -5,8 +5,7 @@ import { IInvoice, InvoiceStatusTypesEnum, IInvoiceItem } from '@gauzy/contracts import { TranslateService } from '@ngx-translate/core'; import { UntypedFormGroup, UntypedFormBuilder, Validators } from '@angular/forms'; import { NbDialogRef } from '@nebular/theme'; -import { InvoiceEstimateHistoryService, InvoicesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { InvoiceEstimateHistoryService, InvoicesService, Store, ToastrService } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-invoice-email', diff --git a/apps/gauzy/src/app/pages/invoices/invoice-payments/payment-mutation/payment-mutation.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-payments/payment-mutation/payment-mutation.component.ts index 2b412bf35b4..c748e9d80e0 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-payments/payment-mutation/payment-mutation.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-payments/payment-mutation/payment-mutation.component.ts @@ -14,11 +14,11 @@ import { } from '@gauzy/contracts'; import { UntypedFormGroup, UntypedFormBuilder, Validators } from '@angular/forms'; import { NbDialogRef } from '@nebular/theme'; -import moment from 'moment'; +import * as moment from 'moment'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { environment } from '@gauzy/ui-config'; -import { Store, compareDate, isNotEmpty } from '@gauzy/ui-core/common'; -import { InvoicesService, OrganizationSettingService } from '@gauzy/ui-core/core'; +import { compareDate, isNotEmpty } from '@gauzy/ui-core/common'; +import { InvoicesService, OrganizationSettingService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/invoices/invoice-payments/payments.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-payments/payments.component.ts index 8d4ab2d804a..2b320dec7f8 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-payments/payments.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-payments/payments.component.ts @@ -10,8 +10,13 @@ import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { saveAs } from 'file-saver'; import { IInvoice, IPayment, InvoiceStatusTypesEnum, IOrganization, IUser } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { InvoiceEstimateHistoryService, InvoicesService, PaymentService, ToastrService } from '@gauzy/ui-core/core'; +import { + InvoiceEstimateHistoryService, + InvoicesService, + PaymentService, + Store, + ToastrService +} from '@gauzy/ui-core/core'; import { DateViewComponent, DeleteConfirmationComponent, diff --git a/apps/gauzy/src/app/pages/invoices/invoice-send/invoice-send-mutation.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-send/invoice-send-mutation.component.ts index df3eb77239b..dbc2c5f54e2 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-send/invoice-send-mutation.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoice-send/invoice-send-mutation.component.ts @@ -3,8 +3,7 @@ import { NbDialogRef } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { IInvoice, ITag, InvoiceStatusTypesEnum } from '@gauzy/contracts'; -import { InvoiceEstimateHistoryService, InvoicesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { InvoiceEstimateHistoryService, InvoicesService, Store, ToastrService } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-invoice-send', diff --git a/apps/gauzy/src/app/pages/invoices/invoice-view/index.ts b/apps/gauzy/src/app/pages/invoices/invoice-view/index.ts deleted file mode 100644 index a6a69c2eedb..00000000000 --- a/apps/gauzy/src/app/pages/invoices/invoice-view/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './inner-component/invoice-view-inner.component'; -export * from './invoice-view.component'; \ No newline at end of file diff --git a/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.html b/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.html deleted file mode 100644 index 6fefb58c10a..00000000000 --- a/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.html +++ /dev/null @@ -1,161 +0,0 @@ - -
-
-
-
-
-

- {{ - (!isEstimate ? 'INVOICES_PAGE.INVOICE_NUMBER' : 'INVOICES_PAGE.ESTIMATE_NUMBER') - | translate - }} -

-

{{ invoice?.invoiceNumber }}

-
-
- - - -
-
-
-
-
-
-
- {{ - (!isEstimate ? 'INVOICES_PAGE.INVOICE_DATE' : 'INVOICES_PAGE.ESTIMATE_DATE') - | translate - }} -
-
- {{ 'INVOICES_PAGE.DUE_DATE' | translate }}: -
-
-
-
{{ invoiceDate | dateFormat }}
-
{{ dueDate | dateFormat }}
-
-
-
-
-
-
- {{ 'INVOICES_PAGE.VIEW.FROM' | translate | titlecase }}: -
-
{{ invoice?.fromOrganization?.name }}
-
-
-
- {{ 'INVOICES_PAGE.VIEW.TO' | translate | titlecase }}: -
-
{{ invoice?.toContact?.name }}
-
-
-
-
-
- -
- -
- -
-
-
-
{{ 'INVOICES_PAGE.TAX' | translate }}:
-
{{ 'INVOICES_PAGE.TAX_2' | translate }}:
-
{{ 'INVOICES_PAGE.INVOICES_SELECT_DISCOUNT_VALUE' | translate }}:
-
{{ 'INVOICES_PAGE.TOTAL_VALUE' | translate }}:
-
- {{ 'INVOICES_PAGE.ALREADY_PAID' | translate }}: -
-
- {{ 'INVOICES_PAGE.AMOUNT_DUE' | translate }}: -
-
-
-
- - {{ - invoice?.tax || 0 - | currency : invoice?.currency - | position : invoice?.fromOrganization.currencyPosition - }} - - {{ invoice?.tax || 0 }} % -
-
- - {{ - invoice?.tax2 || 0 - | currency : invoice?.currency - | position : invoice?.fromOrganization.currencyPosition - }} - - - {{ invoice?.tax2 || 0 }} - % - -
-
- - {{ - invoice.discountValue || 0 - | currency : invoice?.currency - | position : invoice?.fromOrganization.currencyPosition - }} - - - {{ invoice?.discountValue || 0 }} - % - -
-
- - {{ - invoice?.totalValue || 0 - | currency : invoice?.currency - | position : invoice?.fromOrganization.currencyPosition - }} - -
-
- - {{ - invoice?.alreadyPaid || 0 - | currency : invoice?.currency - | position : invoice?.fromOrganization.currencyPosition - }} - -
-
- - {{ - invoice?.amountDue || 0 - | currency : invoice?.currency - | position : invoice?.fromOrganization.currencyPosition - }} - -
-
-
-
-
{{ 'INVOICES_PAGE.INTERNAL_NOTE.INTERNAL_NOTE' | translate }}:
- {{ invoice.internalNote }} -
-
-
-
diff --git a/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.ts b/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.ts deleted file mode 100644 index 9797270d98e..00000000000 --- a/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { Component, OnInit, OnDestroy, Input, TemplateRef, ViewChild } from '@angular/core'; -import { CurrencyPipe } from '@angular/common'; -import { TranslateService } from '@ngx-translate/core'; -import { DiscountTaxTypeEnum, IInvoice, InvoiceTypeEnum } from '@gauzy/contracts'; -import { tap } from 'rxjs/operators'; -import { LocalDataSource, Angular2SmartTableComponent, Cell } from 'angular2-smart-table'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { CurrencyPositionPipe } from '@gauzy/ui-core/shared'; -import { Store } from '@gauzy/ui-core/common'; -import { TranslatableService, UsersOrganizationsService } from '@gauzy/ui-core/core'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'ga-invoice-view-inner', - templateUrl: './invoice-view-inner.component.html', - styleUrls: ['./invoice-view-inner.component.scss'] -}) -export class InvoiceViewInnerComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - invoiceDate: string; - dueDate: string; - settingsSmartTable: object; - isTableLoaded = false; - smartTableSource = new LocalDataSource(); - loading: boolean; - showInternalNote: boolean; - isTaxFlatValue: boolean; - isTax2FlatValue: boolean; - isDiscountFlatValue: boolean; - discountTaxTypes = DiscountTaxTypeEnum; - - invoiceViewInnerTable: Angular2SmartTableComponent; - @ViewChild('invoiceViewInnerTable') set content(content: Angular2SmartTableComponent) { - if (content) { - this.invoiceViewInnerTable = content; - this._onChangedSource(); - } - } - - @Input() invoice: IInvoice; - @Input() isEstimate: boolean; - @Input() buttonsOutlet: TemplateRef; - - constructor( - readonly translateService: TranslateService, - private readonly store: Store, - private readonly userOrganizationService: UsersOrganizationsService, - private readonly translatableService: TranslatableService, - private readonly currencyPipe: CurrencyPipe, - private readonly currencyPipePosition: CurrencyPositionPipe - ) { - super(translateService); - } - - ngOnInit() { - this.checkUser(); - this.loadSmartTable(); - this._applyTranslationOnSmartTable(); - this.invoiceDate = this.invoice.invoiceDate.toString().slice(0, 10); - this.dueDate = this.invoice.dueDate.toString().slice(0, 10); - this.loadTableData(); - this._deselectAll(); - } - - loadSmartTable() { - this.settingsSmartTable = { - actions: false, - hideSubHeader: true, - pager: { - display: false - }, - columns: { - name: { - title: this.getTranslation('INVOICES_PAGE.ITEM'), - type: 'text', - isFilterable: false - }, - description: { - title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.DESCRIPTION'), - type: 'text', - isFilterable: false - }, - quantity: { - title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.QUANTITY'), - type: 'text', - isFilterable: false - }, - price: { - title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.PRICE'), - type: 'text', - isFilterable: false, - valuePrepareFunction: (value: number, cell: Cell) => { - const row = cell.getRow().getData(); - const priceTransformed = this.getPipesTransform( - row.price * row.quantity, - row.currency, - this.invoice.fromOrganization.currencyPosition - ); - return `${priceTransformed}`; - } - }, - totalValue: { - title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.TOTAL_VALUE'), - type: 'text', - isFilterable: false, - valuePrepareFunction: (value: number, cell: Cell) => { - const row = cell.getRow().getData(); - const priceTransformed = this.getPipesTransform( - row.price * row.quantity, - row.currency, - this.invoice.fromOrganization.currencyPosition - ); - return `${priceTransformed}`; - } - } - } - }; - } - - async loadTableData() { - this.loading = true; - const items = []; - let data; - for (const item of this.invoice.invoiceItems) { - data = { - description: item.description, - quantity: item.quantity, - price: item.price, - totalValue: +item.totalValue, - currency: this.invoice.currency - }; - switch (this.invoice.invoiceType) { - case InvoiceTypeEnum.BY_EMPLOYEE_HOURS: - if (item.employeeId) { - const { employee } = item; - data['name'] = `${employee.user.firstName} ${employee.user.lastName}`; - } - break; - case InvoiceTypeEnum.BY_PROJECT_HOURS: - if (item.projectId) { - const { project } = item; - data['name'] = project.name; - } - break; - case InvoiceTypeEnum.BY_TASK_HOURS: - if (item.taskId) { - const { task } = item; - data['name'] = task.title; - } - break; - case InvoiceTypeEnum.BY_PRODUCTS: - if (item.productId) { - const { product } = item; - data['name'] = this.translatableService.getTranslatedProperty(product, 'name'); - } - break; - case InvoiceTypeEnum.BY_EXPENSES: - if (item.expenseId) { - const { expense } = item; - data['name'] = expense.purpose; - } - break; - default: - delete this.settingsSmartTable['columns']['name']; - data = { - description: item.description, - quantity: item.quantity, - price: item.price, - totalValue: +item.totalValue, - id: item.id, - currency: this.invoice.currency - }; - break; - } - items.push(data); - } - this.smartTableSource.load(items); - this.isTableLoaded = true; - this.loading = false; - } - - async checkUser() { - if (this.store.user && this.store.user.id) { - const userOrg = await this.userOrganizationService.getAll([], { - userId: this.store.user.id, - organizationId: this.invoice.organizationId - }); - - if (userOrg.items.length !== 0) { - this.showInternalNote = true; - } - } - } - - _applyTranslationOnSmartTable() { - this.translateService.onLangChange.pipe(untilDestroyed(this)).subscribe(() => { - this.loadSmartTable(); - }); - } - /** - * This function transform simple number to currency format. - * @param value should be the number to transform - * @param currencyCode should be the currency code of invoice - * @param position should be the position of currency organization - * @returns should be a string - */ - getPipesTransform(value: number, currencyCode: string, position: string): string { - const transform = this.currencyPipe.transform(value, currencyCode); - return this.currencyPipePosition.transform(transform, position); - } - - /* - * Table on changed source event - */ - private _onChangedSource() { - this.invoiceViewInnerTable.source.onChangedSource - .pipe( - untilDestroyed(this), - tap(() => this._deselectAll()) - ) - .subscribe(); - } - - private _deselectAll() { - if (this.invoiceViewInnerTable && this.invoiceViewInnerTable.grid) { - this.invoiceViewInnerTable.grid.dataSet['willSelect'] = 'indexed'; - this.invoiceViewInnerTable.grid.dataSet.deselectAll(); - } - } - - ngOnDestroy() {} -} diff --git a/apps/gauzy/src/app/pages/invoices/invoice-view/invoice-view.component.html b/apps/gauzy/src/app/pages/invoices/invoice-view/invoice-view.component.html index 9eefadbb536..c657eec337e 100644 --- a/apps/gauzy/src/app/pages/invoices/invoice-view/invoice-view.component.html +++ b/apps/gauzy/src/app/pages/invoices/invoice-view/invoice-view.component.html @@ -1,63 +1,40 @@ -

- {{ 'INVOICES_PAGE.VIEW_INVOICE' | translate }} -

-

- {{ 'INVOICES_PAGE.VIEW_ESTIMATE' | translate }} +

+ {{ (isEstimate ? 'INVOICES_PAGE.VIEW_ESTIMATE' : 'INVOICES_PAGE.VIEW_INVOICE') | translate }}

- - + + +
+
- - - diff --git a/apps/gauzy/src/app/pages/invoices/public-link/public-link.component.ts b/apps/gauzy/src/app/pages/invoices/public-link/public-link.component.ts index 34f45b8b6d8..ad40ce6d212 100644 --- a/apps/gauzy/src/app/pages/invoices/public-link/public-link.component.ts +++ b/apps/gauzy/src/app/pages/invoices/public-link/public-link.component.ts @@ -13,20 +13,21 @@ import { InvoicesService } from '@gauzy/ui-core/core'; styleUrls: ['./public-link.component.scss'] }) export class PublicLinkComponent implements OnInit { + public publicLink: string; + public isCopied: boolean = false; // Track if link has been copied + /* * Getter & Setter for dynamic invoice property */ - _invoice: IInvoice; - get invoice(): IInvoice { + private _invoice: IInvoice; + public get invoice(): IInvoice { return this._invoice; } - @Input() set invoice(value: IInvoice) { + @Input() public set invoice(value: IInvoice) { this._invoice = value; this.createPublicLink(); } - publicLink: IInvoice['token']; - constructor( private readonly _router: Router, private readonly _location: Location, @@ -47,6 +48,9 @@ export class PublicLinkComponent implements OnInit { } } + /** + * Generate public invoice link + */ async generatePublicInvoiceLink() { this.invoice = await this._invoicesService.generateLink(this.invoice.id); } @@ -55,19 +59,66 @@ export class PublicLinkComponent implements OnInit { * Create invoice public link */ createPublicLink() { - if (this.invoice) { - const { id, token } = this.invoice; - // The call to Location.prepareExternalUrl is the key thing here. - let tree = this._router.createUrlTree([`/share/invoices/${id}/${token}`]); + if (!this.invoice) { + return; + } + const { id, token, isEstimate } = this.invoice; + // Define the base URL based on whether it's an estimate or an invoice + const basePath = isEstimate ? 'estimates' : 'invoices'; + // Create the URL tree with the appropriate path + const urlTree = this._router.createUrlTree([`/share/${basePath}/${id}/${token}`]); + // Serialize the URL tree and prepare the external URL + const serializedUrl = this._urlSerializer.serialize(urlTree); + // As far as I can tell you don't really need the UrlSerializer. + this.publicLink = __prepareExternalUrlLocation(this._location.prepareExternalUrl(serializedUrl)); + } - // As far as I can tell you don't really need the UrlSerializer. - this.publicLink = __prepareExternalUrlLocation( - this._location.prepareExternalUrl(this._urlSerializer.serialize(tree)) - ); + /** + * Copy to clipboard + */ + copyLink() { + try { + this._clipboardService.copyFromContent(this.publicLink); // Copy the link to clipboard + this.isCopied = true; // Show "Copied" status + + // Hide "Copied" status after 2 seconds + setTimeout(() => { + this.isCopied = false; + }, 2000); + } catch (error) { + // Fallback for older browsers + this.fallbackCopyToClipboard(this.publicLink); } } - cancel() { + /** + * Fallback copy to clipboard + * + * @param text + */ + private fallbackCopyToClipboard(text: string) { + // Create a temporary element to copy the link + const textArea = document.createElement('textarea'); + textArea.value = text; + + // Append the element to the body + document.body.appendChild(textArea); + textArea.select(); + + try { + document.execCommand('copy'); + console.log('Link copied to clipboard'); + } catch (error) { + console.error('Failed to copy: ', error); + } + + document.body.removeChild(textArea); + } + + /** + * Close the dialog + */ + close() { this._dialogRef.close(); } } diff --git a/apps/gauzy/src/app/pages/invoices/table-components/invoice-employees-selector.component.ts b/apps/gauzy/src/app/pages/invoices/table-components/invoice-employees-selector.component.ts index 650a7c548c2..cf5800d61ed 100644 --- a/apps/gauzy/src/app/pages/invoices/table-components/invoice-employees-selector.component.ts +++ b/apps/gauzy/src/app/pages/invoices/table-components/invoice-employees-selector.component.ts @@ -3,8 +3,8 @@ import { DefaultEditor } from 'angular2-smart-table'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IEmployee, IOrganization } from '@gauzy/contracts'; -import { Store, isNotEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, EmployeesService } from '@gauzy/ui-core/core'; +import { isNotEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, EmployeesService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/invoices/table-components/invoice-expense-selector.component.ts b/apps/gauzy/src/app/pages/invoices/table-components/invoice-expense-selector.component.ts index b9d7c62a38a..8a92b7d8497 100644 --- a/apps/gauzy/src/app/pages/invoices/table-components/invoice-expense-selector.component.ts +++ b/apps/gauzy/src/app/pages/invoices/table-components/invoice-expense-selector.component.ts @@ -3,8 +3,7 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { DefaultEditor } from 'angular2-smart-table'; import { ExpenseTypesEnum, IExpense, IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { ExpensesService } from '@gauzy/ui-core/core'; +import { ExpensesService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/invoices/table-components/invoice-product-selector.component.ts b/apps/gauzy/src/app/pages/invoices/table-components/invoice-product-selector.component.ts index 430a74e00c4..01dfbc06000 100644 --- a/apps/gauzy/src/app/pages/invoices/table-components/invoice-product-selector.component.ts +++ b/apps/gauzy/src/app/pages/invoices/table-components/invoice-product-selector.component.ts @@ -4,8 +4,7 @@ import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { DefaultEditor } from 'angular2-smart-table'; import { IOrganization, IProduct, IProductTranslatable } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { ProductService, TranslatableService } from '@gauzy/ui-core/core'; +import { ProductService, Store, TranslatableService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/invoices/table-components/invoice-project-selector.component.ts b/apps/gauzy/src/app/pages/invoices/table-components/invoice-project-selector.component.ts index 66c5299d107..1a43718e147 100644 --- a/apps/gauzy/src/app/pages/invoices/table-components/invoice-project-selector.component.ts +++ b/apps/gauzy/src/app/pages/invoices/table-components/invoice-project-selector.component.ts @@ -3,8 +3,7 @@ import { IOrganization, IOrganizationProject } from '@gauzy/contracts'; import { filter, tap } from 'rxjs/operators'; import { DefaultEditor } from 'angular2-smart-table'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; -import { OrganizationProjectsService } from '@gauzy/ui-core/core'; +import { OrganizationProjectsService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/invoices/table-components/invoice-tasks-selector.component.ts b/apps/gauzy/src/app/pages/invoices/table-components/invoice-tasks-selector.component.ts index f87176d0461..ea629f837df 100644 --- a/apps/gauzy/src/app/pages/invoices/table-components/invoice-tasks-selector.component.ts +++ b/apps/gauzy/src/app/pages/invoices/table-components/invoice-tasks-selector.component.ts @@ -4,8 +4,7 @@ import { Observable } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { DefaultEditor } from 'angular2-smart-table'; -import { Store } from '@gauzy/ui-core/common'; -import { TasksStoreService } from '@gauzy/ui-core/core'; +import { Store, TasksStoreService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/jobs/job.routes.ts b/apps/gauzy/src/app/pages/jobs/job.routes.ts index 77755ff7377..1b5cc9c598d 100644 --- a/apps/gauzy/src/app/pages/jobs/job.routes.ts +++ b/apps/gauzy/src/app/pages/jobs/job.routes.ts @@ -1,14 +1,14 @@ import { Route } from '@angular/router'; -import { PageRouteService } from '@gauzy/ui-core/core'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; import { JobLayoutComponent } from './job-layout/job-layout.component'; /** * Creates jobs routes for the application * - * @param _pageRouteService An instance of PageRouteService + * @param _pageRouteRegistryService An instance of PageRouteRegistryService * @returns An array of Route objects */ -export const createRoutes = (_pageRouteService: PageRouteService): Route[] => [ +export const createJobsRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ { path: '', component: JobLayoutComponent, @@ -18,7 +18,7 @@ export const createRoutes = (_pageRouteService: PageRouteService): Route[] => [ redirectTo: 'employee', pathMatch: 'full' }, - ..._pageRouteService.getPageLocationRoutes('jobs') + ..._pageRouteRegistryService.getPageLocationRoutes('jobs') ] } ]; diff --git a/apps/gauzy/src/app/pages/jobs/jobs.module.ts b/apps/gauzy/src/app/pages/jobs/jobs.module.ts index 9009f3491bb..691c7036bb5 100644 --- a/apps/gauzy/src/app/pages/jobs/jobs.module.ts +++ b/apps/gauzy/src/app/pages/jobs/jobs.module.ts @@ -1,10 +1,10 @@ import { NgModule } from '@angular/core'; import { RouterModule, ROUTES } from '@angular/router'; import { SharedModule } from '@gauzy/ui-core/shared'; -import { PageRouteService } from '@gauzy/ui-core/core'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; import { PLUGINS } from './plugins'; import { JobLayoutComponent } from './job-layout/job-layout.component'; -import { createRoutes } from './job.routes'; +import { createJobsRoutes } from './job.routes'; @NgModule({ declarations: [JobLayoutComponent], @@ -13,8 +13,8 @@ import { createRoutes } from './job.routes'; providers: [ { provide: ROUTES, - useFactory: (pageRouteService: PageRouteService) => createRoutes(pageRouteService), - deps: [PageRouteService], + useFactory: (service: PageRouteRegistryService) => createJobsRoutes(service), + deps: [PageRouteRegistryService], multi: true } ] diff --git a/apps/gauzy/src/app/pages/jobs/plugins.ts b/apps/gauzy/src/app/pages/jobs/plugins.ts index beec0084b72..45aceee220c 100644 --- a/apps/gauzy/src/app/pages/jobs/plugins.ts +++ b/apps/gauzy/src/app/pages/jobs/plugins.ts @@ -1,7 +1,7 @@ -import { JobEmployeeModule } from '@gauzy/plugins/job-employee-ui'; -import { JobMatchingModule } from '@gauzy/plugins/job-matching-ui'; -import { JobSearchModule } from '@gauzy/plugins/job-search-ui'; -import { JobProposalTemplateModule } from '@gauzy/plugins/job-proposal-ui'; +import { JobEmployeeModule } from '@gauzy/plugin-job-employee-ui'; +import { JobMatchingModule } from '@gauzy/plugin-job-matching-ui'; +import { JobSearchModule } from '@gauzy/plugin-job-search-ui'; +import { JobProposalTemplateModule } from '@gauzy/plugin-job-proposal-ui'; /** * An array of plugins to be included or used in the codebase. diff --git a/apps/gauzy/src/app/pages/legal/legal-routing.module.ts b/apps/gauzy/src/app/pages/legal/legal-routing.module.ts deleted file mode 100644 index 27c45ca0a10..00000000000 --- a/apps/gauzy/src/app/pages/legal/legal-routing.module.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { ISelectorVisibility } from '@gauzy/ui-core/core'; -import { PrivacyPolicyComponent, TermsAndConditionsComponent } from '@gauzy/ui-core/shared'; - -/** - * Disabled header selectors for privacy/terms pages - */ -const selectors: ISelectorVisibility = { - organization: false, - date: false, - employee: false, - project: false, - team: false -}; - -export const routes: Routes = [ - { - path: '', - children: [ - { - path: 'terms', - component: TermsAndConditionsComponent, - data: { - selectors // Disables header selectors for terms page - } - }, - { - path: 'privacy', - component: PrivacyPolicyComponent, - data: { - selectors // Disables header selectors for privacy page - } - } - ] - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class PageLegalRoutingModule {} diff --git a/apps/gauzy/src/app/pages/legal/legal.module.ts b/apps/gauzy/src/app/pages/legal/legal.module.ts deleted file mode 100644 index 4dfac000a08..00000000000 --- a/apps/gauzy/src/app/pages/legal/legal.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NgModule } from '@angular/core'; -import { MainLegalModule } from '@gauzy/ui-core/shared'; -import { PageLegalRoutingModule } from './legal-routing.module'; - -@NgModule({ - imports: [PageLegalRoutingModule, MainLegalModule], - declarations: [] -}) -export class PageLegalModule {} diff --git a/apps/gauzy/src/app/pages/miscellaneous/miscellaneous-routing.module.ts b/apps/gauzy/src/app/pages/miscellaneous/miscellaneous-routing.module.ts deleted file mode 100644 index b9323ac4eaf..00000000000 --- a/apps/gauzy/src/app/pages/miscellaneous/miscellaneous-routing.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; - -import { MiscellaneousComponent } from './miscellaneous.component'; -import { NotFoundComponent } from './not-found/not-found.component'; - -const routes: Routes = [ - { - path: '', - component: MiscellaneousComponent, - children: [ - { - path: '404', - component: NotFoundComponent - } - ] - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class MiscellaneousRoutingModule {} diff --git a/apps/gauzy/src/app/pages/miscellaneous/miscellaneous.module.ts b/apps/gauzy/src/app/pages/miscellaneous/miscellaneous.module.ts deleted file mode 100644 index cec2b727c86..00000000000 --- a/apps/gauzy/src/app/pages/miscellaneous/miscellaneous.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbCardModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { MiscellaneousRoutingModule } from './miscellaneous-routing.module'; -import { MiscellaneousComponent } from './miscellaneous.component'; -import { NotFoundComponent } from './not-found/not-found.component'; - -@NgModule({ - imports: [CommonModule, NbCardModule, TranslateModule.forChild(), MiscellaneousRoutingModule], - declarations: [MiscellaneousComponent, NotFoundComponent] -}) -export class MiscellaneousModule {} diff --git a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-location/edit-organization-location.component.ts b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-location/edit-organization-location.component.ts index 8ae9de2a328..12f55b779bb 100644 --- a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-location/edit-organization-location.component.ts +++ b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-location/edit-organization-location.component.ts @@ -7,8 +7,8 @@ import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization, CrudActionEnum } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store, isNotEmpty } from '@gauzy/ui-core/common'; -import { OrganizationEditStore, OrganizationsService, ToastrService } from '@gauzy/ui-core/core'; +import { isNotEmpty } from '@gauzy/ui-core/common'; +import { OrganizationEditStore, OrganizationsService, Store, ToastrService } from '@gauzy/ui-core/core'; import { LeafletMapComponent, LocationFormComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-main/edit-organization-main.component.ts b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-main/edit-organization-main.component.ts index 99bf863fa7c..52deea0bee7 100644 --- a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-main/edit-organization-main.component.ts +++ b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-main/edit-organization-main.component.ts @@ -7,8 +7,14 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { debounceTime } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { DUMMY_PROFILE_IMAGE, Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, OrganizationEditStore, OrganizationsService, ToastrService } from '@gauzy/ui-core/core'; +import { DUMMY_PROFILE_IMAGE, distinctUntilChange } from '@gauzy/ui-core/common'; +import { + ErrorHandlingService, + OrganizationEditStore, + OrganizationsService, + Store, + ToastrService +} from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-other-settings/edit-organization-other-settings.component.ts b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-other-settings/edit-organization-other-settings.component.ts index 3ca06df3b60..c498eee024e 100644 --- a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-other-settings/edit-organization-other-settings.component.ts +++ b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-settings/edit-organization-other-settings/edit-organization-other-settings.component.ts @@ -2,7 +2,7 @@ import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChi import { UntypedFormBuilder, FormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { formatDate } from '@angular/common'; -import moment from 'moment'; +import * as moment from 'moment'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, tap, debounceTime, map } from 'rxjs/operators'; @@ -35,8 +35,13 @@ import { DEFAULT_AUTO_ARCHIVE_ISSUE_PERIOD, DEFAULT_SCREENSHOT_FREQUENCY_OPTIONS } from '@gauzy/contracts'; -import { Store, isEmpty } from '@gauzy/ui-core/common'; -import { AccountingTemplateService, OrganizationEditStore, OrganizationTaskSettingService } from '@gauzy/ui-core/core'; +import { isEmpty } from '@gauzy/ui-core/common'; +import { + AccountingTemplateService, + OrganizationEditStore, + OrganizationTaskSettingService, + Store +} from '@gauzy/ui-core/core'; import { OrganizationsService, ToastrService } from '@gauzy/ui-core/core'; import { NotesWithTagsComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-task-setting.resolver.ts b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-task-setting.resolver.ts index 6ba4aa4f3c8..4bd3357998a 100644 --- a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-task-setting.resolver.ts +++ b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization-task-setting.resolver.ts @@ -3,8 +3,8 @@ import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; import { EMPTY, Observable, of as observableOf } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { IOrganizationTaskSetting } from '@gauzy/contracts'; -import { Store, isEmpty } from '@gauzy/ui-core/common'; -import { OrganizationTaskSettingService } from '@gauzy/ui-core/core'; +import { isEmpty } from '@gauzy/ui-core/common'; +import { OrganizationTaskSettingService, Store } from '@gauzy/ui-core/core'; @Injectable({ providedIn: 'root' diff --git a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.component.ts b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.component.ts index 2778eebe081..cc5149de608 100644 --- a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.component.ts +++ b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.component.ts @@ -6,8 +6,9 @@ import { debounceTime } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -86,5 +87,5 @@ export class EditOrganizationComponent extends TranslationBaseComponent implemen window.open(externalUrl, '_blank'); } - ngOnDestroy(): void { } + ngOnDestroy(): void {} } diff --git a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.resolver.ts b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.resolver.ts index 0c9f21f2626..9f522711d3f 100644 --- a/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.resolver.ts +++ b/apps/gauzy/src/app/pages/organizations/edit-organization/edit-organization.resolver.ts @@ -3,8 +3,8 @@ import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; import { debounceTime, EMPTY, Observable, of as observableOf } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; import { IOrganization } from '@gauzy/contracts'; -import { Store, isEmpty } from '@gauzy/ui-core/common'; -import { OrganizationsService } from '@gauzy/ui-core/core'; +import { isEmpty } from '@gauzy/ui-core/common'; +import { OrganizationsService, Store } from '@gauzy/ui-core/core'; @Injectable({ providedIn: 'root' diff --git a/apps/gauzy/src/app/pages/organizations/organizations.component.ts b/apps/gauzy/src/app/pages/organizations/organizations.component.ts index f96dc2fb32d..b1c6b0923c4 100644 --- a/apps/gauzy/src/app/pages/organizations/organizations.component.ts +++ b/apps/gauzy/src/app/pages/organizations/organizations.component.ts @@ -7,11 +7,12 @@ import { LocalDataSource, Cell } from 'angular2-smart-table'; import { debounceTime, firstValueFrom, Subject } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { ErrorHandlingService, OrganizationEditStore, OrganizationsService, + Store, ToastrService, UsersOrganizationsService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/pages-routing.module.ts b/apps/gauzy/src/app/pages/pages-routing.module.ts index 9cc5590c142..6ff0a99eab9 100644 --- a/apps/gauzy/src/app/pages/pages-routing.module.ts +++ b/apps/gauzy/src/app/pages/pages-routing.module.ts @@ -2,9 +2,8 @@ import { RouterModule, Routes } from '@angular/router'; import { NgModule } from '@angular/core'; import { PermissionsGuard, UserResolver } from '@gauzy/ui-core/core'; import { PermissionsEnum } from '@gauzy/contracts'; -import { DateRangePickerResolver } from '@gauzy/ui-core/shared'; +import { DateRangePickerResolver, NotFoundComponent } from '@gauzy/ui-core/shared'; import { PagesComponent } from './pages.component'; -import { NotFoundComponent } from './miscellaneous/not-found/not-found.component'; const routes: Routes = [ { @@ -110,7 +109,7 @@ const routes: Routes = [ children: [ { path: 'proposals', - loadChildren: () => import('./proposals/proposals.module').then((m) => m.ProposalsModule) + loadChildren: () => import('@gauzy/plugin-job-proposal-ui').then((m) => m.JobProposalModule) }, { path: 'estimates', @@ -632,11 +631,14 @@ const routes: Routes = [ }, { path: 'legal', - loadChildren: () => import('./legal/legal.module').then((m) => m.PageLegalModule) + loadChildren: () => import('@gauzy/plugin-legal-ui').then((m) => m.PageLegalModule) }, { path: '**', - component: NotFoundComponent + component: NotFoundComponent, + data: { + selectors: false + } } ] } diff --git a/apps/gauzy/src/app/pages/pages.component.ts b/apps/gauzy/src/app/pages/pages.component.ts index 4e420b7e4dd..eb52cd5ec23 100644 --- a/apps/gauzy/src/app/pages/pages.component.ts +++ b/apps/gauzy/src/app/pages/pages.component.ts @@ -16,10 +16,11 @@ import { NavMenuBuilderService, NavMenuSectionItem, PermissionsService, + Store, UsersService } from '@gauzy/ui-core/core'; import { FeatureEnum, IOrganization, IRolePermission, IUser, IntegrationEnum, PermissionsEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { ReportService } from './reports/all-report/report.service'; @UntilDestroy({ checkProperties: true }) @@ -143,7 +144,8 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie * Executes after the view initialization. */ ngAfterViewInit(): void { - merge( + // Merge observables to handle changes in job matching entity settings + const merge$ = merge( this._integrationEntitySettingServiceStoreService.jobMatchingEntity$.pipe( distinctUntilChange(), // Ensure that only distinct changes are considered filter(({ currentValue }: IJobMatchingEntity) => !!currentValue), // Filter out falsy values @@ -151,11 +153,10 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie // Update component properties based on the current job matching entity settings const isEmployeeJobMatchingEntity = !!currentValue.sync && !!currentValue.isActive; - if (isEmployeeJobMatchingEntity) { - this.addJobsNavigationMenuItems(); - } else { - this.removeJobsNavigationMenuItems(); - } + // Add or remove the jobs navigation menu items based on the current job matching entity + isEmployeeJobMatchingEntity + ? this.addJobsNavigationMenuItems() + : this.removeJobsNavigationMenuItems(); }) ), this.store.user$.pipe( @@ -169,9 +170,9 @@ export class PagesComponent extends TranslationBaseComponent implements AfterVie filter((organization: IOrganization) => !!organization), tap((organization: IOrganization) => this.addOrganizationManageMenuItem(organization)) ) - ) - .pipe(untilDestroyed(this)) - .subscribe(); + ); + // Subscribe to the merge$ observable + merge$.pipe(untilDestroyed(this)).subscribe(); } /** diff --git a/apps/gauzy/src/app/pages/pages.module.ts b/apps/gauzy/src/app/pages/pages.module.ts index 890a457dfe4..6ddde33101d 100644 --- a/apps/gauzy/src/app/pages/pages.module.ts +++ b/apps/gauzy/src/app/pages/pages.module.ts @@ -3,18 +3,17 @@ import { CommonModule } from '@angular/common'; import { NbMenuModule, NbToastrModule, NbSpinnerModule, NbIconModule } from '@nebular/theme'; import { FeatureToggleModule as NgxFeatureToggleModule } from 'ngx-feature-toggle'; import { AuthService, CommonNavModule, RoleGuard } from '@gauzy/ui-core/core'; +import { MiscellaneousModule } from '@gauzy/ui-core/shared'; import { ThemeModule } from '@gauzy/ui-core/theme'; -import { MiscellaneousModule } from './miscellaneous/miscellaneous.module'; import { PagesComponent } from './pages.component'; import { PagesRoutingModule } from './pages-routing.module'; +const NB_MODULES = [NbMenuModule, NbToastrModule.forRoot(), NbSpinnerModule, NbIconModule]; + @NgModule({ imports: [ CommonModule, - NbIconModule, - NbMenuModule, - NbSpinnerModule, - NbToastrModule.forRoot(), + ...NB_MODULES, NgxFeatureToggleModule, ThemeModule, PagesRoutingModule, diff --git a/apps/gauzy/src/app/pages/payments/payments.component.ts b/apps/gauzy/src/app/pages/payments/payments.component.ts index 2ea14b49f3e..56124bfa78d 100644 --- a/apps/gauzy/src/app/pages/payments/payments.component.ts +++ b/apps/gauzy/src/app/pages/payments/payments.component.ts @@ -12,9 +12,10 @@ import { DateRangePickerBuilderService, ErrorHandlingService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; import { environment as ENV } from '@gauzy/ui-config'; import { IPayment, diff --git a/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deal-form/pipeline-deal-form.component.ts b/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deal-form/pipeline-deal-form.component.ts index b3daa54972b..d97269df9f5 100644 --- a/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deal-form/pipeline-deal-form.component.ts +++ b/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deal-form/pipeline-deal-form.component.ts @@ -6,9 +6,15 @@ import { filter } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { IPipeline, IContact, IOrganization, IDeal, IPagination } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { DealsService, ErrorHandlingService, OrganizationContactService, ToastrService } from '@gauzy/ui-core/core'; +import { + DealsService, + ErrorHandlingService, + OrganizationContactService, + Store, + ToastrService +} from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deals.component.ts b/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deals.component.ts index edfbdcf94c4..ff7ae93da02 100644 --- a/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deals.component.ts +++ b/apps/gauzy/src/app/pages/pipelines/pipeline-deals/pipeline-deals.component.ts @@ -5,8 +5,8 @@ import { LocalDataSource, Cell } from 'angular2-smart-table'; import { TranslateService } from '@ngx-translate/core'; import { NbDialogService } from '@nebular/theme'; import { IDeal, IPipeline, ComponentLayoutStyleEnum, IOrganization, ID, IPagination } from '@gauzy/contracts'; -import { ComponentEnum, distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { DealsService, ErrorHandlingService, PipelinesService, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; +import { DealsService, ErrorHandlingService, PipelinesService, Store, ToastrService } from '@gauzy/ui-core/core'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { catchError, combineLatest, firstValueFrom, map, Observable, of, Subject, switchMap } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; diff --git a/apps/gauzy/src/app/pages/pipelines/pipeline-form/pipeline-form.component.ts b/apps/gauzy/src/app/pages/pipelines/pipeline-form/pipeline-form.component.ts index 2d6210349d6..62cb232e6d5 100644 --- a/apps/gauzy/src/app/pages/pipelines/pipeline-form/pipeline-form.component.ts +++ b/apps/gauzy/src/app/pages/pipelines/pipeline-form/pipeline-form.component.ts @@ -4,8 +4,8 @@ import { filter, tap } from 'rxjs/operators'; import { NbDialogRef } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization, IPipeline } from '@gauzy/contracts'; -import { ErrorHandlingService, PipelinesService } from '@gauzy/ui-core/core'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, PipelinesService, Store } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/pipelines/pipelines.component.ts b/apps/gauzy/src/app/pages/pipelines/pipelines.component.ts index 8add79c0301..db71f8ade2f 100644 --- a/apps/gauzy/src/app/pages/pipelines/pipelines.component.ts +++ b/apps/gauzy/src/app/pages/pipelines/pipelines.component.ts @@ -1,24 +1,25 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { HttpClient } from '@angular/common/http'; -import { IPipeline, ComponentLayoutStyleEnum, IOrganization, PipelineTabsEnum } from '@gauzy/contracts'; import { Cell } from 'angular2-smart-table'; import { TranslateService } from '@ngx-translate/core'; import { NbDialogService, NbTabComponent } from '@nebular/theme'; import { Subject, firstValueFrom, BehaviorSubject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { IPipeline, ComponentLayoutStyleEnum, IOrganization, PipelineTabsEnum } from '@gauzy/contracts'; import { AtLeastOneFieldValidator, ErrorHandlingService, PipelinesService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { API_PREFIX, ComponentEnum, - Store, distinctUntilChange, isNotEmpty, isNotNullOrUndefined @@ -30,7 +31,6 @@ import { PaginationFilterBaseComponent, StatusBadgeComponent } from '@gauzy/ui-core/shared'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { PipelineFormComponent } from './pipeline-form/pipeline-form.component'; import { StageComponent } from './stage/stage.component'; diff --git a/apps/gauzy/src/app/pages/pipelines/routes/deal.resolver.ts b/apps/gauzy/src/app/pages/pipelines/routes/deal.resolver.ts index 1c715630108..5bac89ad5b7 100644 --- a/apps/gauzy/src/app/pages/pipelines/routes/deal.resolver.ts +++ b/apps/gauzy/src/app/pages/pipelines/routes/deal.resolver.ts @@ -3,8 +3,7 @@ import { ActivatedRouteSnapshot, Resolve } from '@angular/router'; import { catchError, from, of } from 'rxjs'; import { Observable } from 'rxjs/internal/Observable'; import { IDeal } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { DealsService, ErrorHandlingService } from '@gauzy/ui-core/core'; +import { DealsService, ErrorHandlingService, Store } from '@gauzy/ui-core/core'; @Injectable() export class DealResolver implements Resolve>> { diff --git a/apps/gauzy/src/app/pages/pipelines/routes/pipeline.resolver.ts b/apps/gauzy/src/app/pages/pipelines/routes/pipeline.resolver.ts index c0def4d0450..e7584621a9f 100644 --- a/apps/gauzy/src/app/pages/pipelines/routes/pipeline.resolver.ts +++ b/apps/gauzy/src/app/pages/pipelines/routes/pipeline.resolver.ts @@ -4,8 +4,7 @@ import { of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { IPipeline } from '@gauzy/contracts'; -import { ErrorHandlingService, PipelinesService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, PipelinesService, Store } from '@gauzy/ui-core/core'; @Injectable() export class PipelineResolver implements Resolve>> { diff --git a/apps/gauzy/src/app/pages/pipelines/stage-form/stage-form.component.ts b/apps/gauzy/src/app/pages/pipelines/stage-form/stage-form.component.ts index b5a47941a7e..bff51e6e4cf 100644 --- a/apps/gauzy/src/app/pages/pipelines/stage-form/stage-form.component.ts +++ b/apps/gauzy/src/app/pages/pipelines/stage-form/stage-form.component.ts @@ -4,8 +4,8 @@ import { IPipelineStageUpdateInput } from '@gauzy/contracts'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { NbDialogService } from '@nebular/theme'; import { first } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; import { DeleteConfirmationComponent } from '@gauzy/ui-core/shared'; +import { Store } from '@gauzy/ui-core/core'; @Component({ templateUrl: './stage-form.component.html', diff --git a/apps/gauzy/src/app/pages/positions/positions.component.ts b/apps/gauzy/src/app/pages/positions/positions.component.ts index 30ac43bd0e9..77d9eae8df8 100644 --- a/apps/gauzy/src/app/pages/positions/positions.component.ts +++ b/apps/gauzy/src/app/pages/positions/positions.component.ts @@ -5,8 +5,8 @@ import { TranslateService } from '@ngx-translate/core'; import { LocalDataSource } from 'angular2-smart-table'; import { firstValueFrom, filter, tap, Subject, debounceTime } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { OrganizationPositionsService, ToastrService } from '@gauzy/ui-core/core'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { OrganizationPositionsService, Store, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { PaginationFilterBaseComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/projects/components/project-create/create.component.ts b/apps/gauzy/src/app/pages/projects/components/project-create/create.component.ts index bf05ee32bf0..ec1cbbcc493 100644 --- a/apps/gauzy/src/app/pages/projects/components/project-create/create.component.ts +++ b/apps/gauzy/src/app/pages/projects/components/project-create/create.component.ts @@ -4,8 +4,7 @@ import { UntilDestroy } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { IOrganization, IOrganizationProject, IOrganizationProjectCreateInput } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ErrorHandlingService, OrganizationProjectsService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, OrganizationProjectsService, Store, ToastrService } from '@gauzy/ui-core/core'; import { ProjectMutationComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/projects/components/project-edit/edit.component.ts b/apps/gauzy/src/app/pages/projects/components/project-edit/edit.component.ts index 9cd3a82ae24..771da1cf439 100644 --- a/apps/gauzy/src/app/pages/projects/components/project-edit/edit.component.ts +++ b/apps/gauzy/src/app/pages/projects/components/project-edit/edit.component.ts @@ -11,8 +11,7 @@ import { IOrganizationProjectUpdateInput } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, OrganizationProjectsService, ToastrService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, OrganizationProjectsService, Store, ToastrService } from '@gauzy/ui-core/core'; import { ProjectMutationComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) @@ -84,6 +83,7 @@ export class ProjectEditMutationComponent extends TranslationBaseComponent imple } /** Make loading true */ this.loading = true; + try { const { id: organizationId, tenantId } = this.organization; const { id } = this.project; diff --git a/apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts b/apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts index 043b8689356..0deb2ab702c 100644 --- a/apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts +++ b/apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts @@ -16,12 +16,13 @@ import { ITag, IOrganizationProject } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { ErrorHandlingService, OrganizationProjectsService, OrganizationProjectStore, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { diff --git a/apps/gauzy/src/app/pages/proposals/proposal-edit-or-details.resolver.ts b/apps/gauzy/src/app/pages/proposals/proposal-edit-or-details.resolver.ts deleted file mode 100644 index 2a6edcc817f..00000000000 --- a/apps/gauzy/src/app/pages/proposals/proposal-edit-or-details.resolver.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; -import { catchError, from, Observable, of as observableOf } from 'rxjs'; -import { IProposal } from '@gauzy/contracts'; -import { ProposalsService } from '@gauzy/ui-core/core'; - -@Injectable({ - providedIn: 'root' -}) -export class ProposalEditOrDetailsResolver implements Resolve> { - constructor(private readonly proposalsService: ProposalsService, private readonly router: Router) {} - - resolve(route: ActivatedRouteSnapshot): Observable { - try { - const proposalId = route.params.id; - return from( - this.proposalsService - .getById(proposalId, ['employee', 'employee.user', 'tags', 'organizationContact']) - .pipe( - catchError((error) => { - return observableOf(error); - }) - ) - ); - } catch (error) { - this.router.navigate(['/pages/employees']); - } - } -} diff --git a/apps/gauzy/src/app/pages/proposals/proposals-pie-chart/proposals-pie-chart.component.ts b/apps/gauzy/src/app/pages/proposals/proposals-pie-chart/proposals-pie-chart.component.ts deleted file mode 100644 index 03435c5a558..00000000000 --- a/apps/gauzy/src/app/pages/proposals/proposals-pie-chart/proposals-pie-chart.component.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core'; -import { NbThemeService } from '@nebular/theme'; -import { TranslateService } from '@ngx-translate/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; - -@Component({ - selector: 'ngx-proposals-pie-chart', - template: ``, - styleUrls: ['./proposals-pie-chart.component.scss'] -}) -export class ProposalsPieChartComponent extends TranslationBaseComponent implements AfterViewInit, OnDestroy { - @Input() values: { name: string; value: number }[]; - - options: any = {}; - themeSubscription: any; - - constructor(private theme: NbThemeService, readonly translateService: TranslateService) { - super(translateService); - } - - // TODO translate - ngAfterViewInit() { - this.themeSubscription = this.theme.getJsTheme().subscribe((config) => { - const colors = config.variables; - const echarts: any = config.variables.echarts; - this.options = { - backgroundColor: echarts.bg, - color: [ - colors.warningLight, - colors.infoLight, - colors.dangerLight, - colors.successLight, - colors.primaryLight - ], - tooltip: { - trigger: 'item', - formatter: '{a}
{b} : {c} ({d}%)' - }, - legend: { - orient: 'vertical', - left: 'left', - data: [ - this.getTranslation('PROPOSALS_PAGE.ACCEPTED_PROPOSALS'), - this.getTranslation('PROPOSALS_PAGE.TOTAL_PROPOSALS') - ], - textStyle: { - color: echarts.textColor - } - }, - series: [ - { - name: this.getTranslation('PROPOSALS_PAGE.PROPOSALS'), - type: 'pie', - radius: '80%', - center: ['50%', '50%'], - data: this.values, - itemStyle: { - emphasis: { - shadowBlur: 10, - shadowOffsetX: 0, - shadowColor: echarts.itemHoverShadowColor - } - }, - label: { - normal: { - textStyle: { - color: echarts.textColor - } - } - }, - labelLine: { - normal: { - lineStyle: { - color: echarts.axisLineColor - } - } - } - } - ] - }; - }); - } - - ngOnDestroy(): void { - this.themeSubscription.unsubscribe(); - } -} diff --git a/apps/gauzy/src/app/pages/proposals/proposals-routing.module.ts b/apps/gauzy/src/app/pages/proposals/proposals-routing.module.ts deleted file mode 100644 index b1ac7d69897..00000000000 --- a/apps/gauzy/src/app/pages/proposals/proposals-routing.module.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { PermissionsGuard } from '@gauzy/ui-core/core'; -import { PermissionsEnum } from '@gauzy/contracts'; -import { DateRangePickerResolver } from '@gauzy/ui-core/shared'; -import { ProposalsComponent } from './proposals.component'; -import { ProposalRegisterComponent } from './proposal-register/proposal-register.component'; -import { ProposalDetailsComponent } from './proposal-details/proposal-details.component'; -import { ProposalEditComponent } from './proposal-edit/proposal-edit.component'; -import { ProposalEditOrDetailsResolver } from './proposal-edit-or-details.resolver'; - -export function redirectTo() { - return '/pages/dashboard'; -} - -const routes: Routes = [ - { - path: '', - component: ProposalsComponent, - canActivate: [PermissionsGuard], - data: { - permissions: { - only: [PermissionsEnum.ORG_PROPOSALS_VIEW], - redirectTo - }, - selectors: { - project: false - }, - datePicker: { - unitOfTime: 'month' - } - }, - resolve: { dates: DateRangePickerResolver } - }, - { - path: 'register', - component: ProposalRegisterComponent, - canActivate: [PermissionsGuard], - data: { - permissions: { - only: [PermissionsEnum.ORG_PROPOSALS_EDIT], - redirectTo - }, - selectors: { - project: false, - employee: false - }, - datePicker: { - unitOfTime: 'month' - } - }, - resolve: { - dates: DateRangePickerResolver - } - }, - { - path: 'details/:id', - component: ProposalDetailsComponent, - canActivate: [PermissionsGuard], - data: { - permissions: { - only: [PermissionsEnum.ORG_PROPOSALS_VIEW], - redirectTo - }, - selectors: { - organization: false, - date: false, - employee: false, - project: false - } - }, - resolve: { - proposal: ProposalEditOrDetailsResolver - } - }, - { - path: 'edit/:id', - component: ProposalEditComponent, - canActivate: [PermissionsGuard], - data: { - permissions: { - only: [PermissionsEnum.ORG_PROPOSALS_EDIT], - redirectTo - }, - selectors: { - organization: false, - date: false, - employee: false, - project: false - } - }, - resolve: { - proposal: ProposalEditOrDetailsResolver - } - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class ProposalsRoutingModule {} diff --git a/apps/gauzy/src/app/pages/proposals/proposals.module.ts b/apps/gauzy/src/app/pages/proposals/proposals.module.ts deleted file mode 100644 index 1420723c8d5..00000000000 --- a/apps/gauzy/src/app/pages/proposals/proposals.module.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { NgModule } from '@angular/core'; -import { - NbBadgeModule, - NbButtonModule, - NbCardModule, - NbDatepickerModule, - NbDialogModule, - NbIconModule, - NbInputModule, - NbSpinnerModule, - NbTooltipModule -} from '@nebular/theme'; -import { NgChartsModule } from 'ng2-charts'; -import { NgxPermissionsModule } from 'ngx-permissions'; -import { CKEditorModule } from 'ckeditor4-angular'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { TranslateModule } from '@ngx-translate/core'; -import { ProposalsService } from '@gauzy/ui-core/core'; -import { - SmartDataViewLayoutModule, - CardGridModule, - ContactSelectModule, - ProposalTemplateSelectModule, - SelectorsModule, - SharedModule, - TableComponentsModule, - TableFiltersModule, - TagsColorInputModule, - UserFormsModule -} from '@gauzy/ui-core/shared'; -import { ProposalsComponent } from './proposals.component'; -import { ProposalsRoutingModule } from './proposals-routing.module'; -import { ProposalRegisterComponent } from './proposal-register/proposal-register.component'; -import { ProposalStatusComponent } from './table-components/proposal-status/proposal-status.component'; -import { ProposalDetailsComponent } from './proposal-details/proposal-details.component'; -import { ProposalEditComponent } from './proposal-edit/proposal-edit.component'; -import { ProposalsPieChartComponent } from './proposals-pie-chart/proposals-pie-chart.component'; -import { JobTitleComponent } from './table-components/job-title/job-title.component'; - -@NgModule({ - imports: [ - ProposalsRoutingModule, - CKEditorModule, - NbBadgeModule, - NbButtonModule, - NbCardModule, - NbDatepickerModule, - NbDialogModule.forChild(), - NbIconModule, - NbInputModule, - NbSpinnerModule, - NbTooltipModule, - NgSelectModule, - NgChartsModule, - NgxPermissionsModule.forChild(), - TranslateModule.forChild(), - SharedModule, - TagsColorInputModule, - TableComponentsModule, - UserFormsModule, - CardGridModule, - ProposalTemplateSelectModule, - SmartDataViewLayoutModule, - ContactSelectModule, - TableFiltersModule, - SelectorsModule - ], - declarations: [ - ProposalsComponent, - ProposalRegisterComponent, - ProposalStatusComponent, - ProposalDetailsComponent, - ProposalEditComponent, - JobTitleComponent, - ProposalsPieChartComponent - ], - providers: [ProposalsService] -}) -export class ProposalsModule {} diff --git a/apps/gauzy/src/app/pages/proposals/table-components/job-title/job-title.component.ts b/apps/gauzy/src/app/pages/proposals/table-components/job-title/job-title.component.ts deleted file mode 100644 index bdf6b6152d0..00000000000 --- a/apps/gauzy/src/app/pages/proposals/table-components/job-title/job-title.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - template: ` - {{ rowData.jobTitle }} - ` -}) -export class JobTitleComponent { - @Input() - rowData: any; - - value: string | number; -} diff --git a/apps/gauzy/src/app/pages/recurring-expense-employee/recurring-expense-employee.component.ts b/apps/gauzy/src/app/pages/recurring-expense-employee/recurring-expense-employee.component.ts index cfe763b9680..a3a11eec011 100644 --- a/apps/gauzy/src/app/pages/recurring-expense-employee/recurring-expense-employee.component.ts +++ b/apps/gauzy/src/app/pages/recurring-expense-employee/recurring-expense-employee.component.ts @@ -9,6 +9,7 @@ import { DateRangePickerBuilderService, EmployeeRecurringExpenseService, EmployeesService, + Store, ToastrService, monthNames } from '@gauzy/ui-core/core'; @@ -21,7 +22,7 @@ import { IDateRangePicker, ComponentType } from '@gauzy/contracts'; -import { Store, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; +import { distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { RecurringExpenseMutationComponent, RecurringExpenseDeleteConfirmationComponent } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/reports/all-report/all-report/all-report.component.ts b/apps/gauzy/src/app/pages/reports/all-report/all-report/all-report.component.ts index 319d865b89a..2024318af00 100644 --- a/apps/gauzy/src/app/pages/reports/all-report/all-report/all-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/all-report/all-report/all-report.component.ts @@ -3,7 +3,7 @@ import { IGetReportCategory, IOrganization, IReport, IReportCategory, Permission import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, tap } from 'rxjs/operators'; import { chain } from 'underscore'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ReportService } from '../report.service'; @UntilDestroy() diff --git a/apps/gauzy/src/app/pages/reports/amounts-owed-report/amounts-owed-report/amounts-owed-report.component.ts b/apps/gauzy/src/app/pages/reports/amounts-owed-report/amounts-owed-report/amounts-owed-report.component.ts index 677a27145c2..3a50380d8e4 100644 --- a/apps/gauzy/src/app/pages/reports/amounts-owed-report/amounts-owed-report/amounts-owed-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/amounts-owed-report/amounts-owed-report/amounts-owed-report.component.ts @@ -5,7 +5,7 @@ import { filter, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { pluck } from 'underscore'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; import { IGetExpenseInput, ReportGroupFilterEnum, @@ -13,7 +13,7 @@ import { ITimeLogFilters, IGetTimeLogReportInput } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, ChartUtil, diff --git a/apps/gauzy/src/app/pages/reports/apps-urls-report/apps-urls-report/apps-urls-report.component.ts b/apps/gauzy/src/app/pages/reports/apps-urls-report/apps-urls-report/apps-urls-report.component.ts index da448fed120..a96a7d28f2f 100644 --- a/apps/gauzy/src/app/pages/reports/apps-urls-report/apps-urls-report/apps-urls-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/apps-urls-report/apps-urls-report/apps-urls-report.component.ts @@ -3,8 +3,7 @@ import { Observable } from 'rxjs/internal/Observable'; import { IGetActivitiesInput, ITimeLogFilters } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy } from '@ngneat/until-destroy'; -import { DateRangePickerBuilderService, TimesheetFilterService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/reports/client-budgets-report/client-budgets-report/client-budgets-report.component.ts b/apps/gauzy/src/app/pages/reports/client-budgets-report/client-budgets-report/client-budgets-report.component.ts index a287cb73667..a048429dda5 100644 --- a/apps/gauzy/src/app/pages/reports/client-budgets-report/client-budgets-report/client-budgets-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/client-budgets-report/client-budgets-report/client-budgets-report.component.ts @@ -12,8 +12,8 @@ import { OrganizationContactBudgetTypeEnum, ITimeLogFilters } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.ts b/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.ts index d52174c7cdb..0692dbff81f 100644 --- a/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.ts @@ -6,8 +6,8 @@ import { filter, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { pluck } from 'underscore'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, ExpensesService, TimesheetFilterService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, ExpensesService, Store, TimesheetFilterService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, ChartUtil, diff --git a/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.ts b/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.ts index cb09825a5f4..d911763e493 100644 --- a/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.ts +++ b/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.ts @@ -8,11 +8,12 @@ import { distinctUntilChanged, filter, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { chain } from 'underscore'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; import { DateRangePickerBuilderService, ErrorHandlingService, + Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/reports/payment-report/payment-report/payment-report.component.ts b/apps/gauzy/src/app/pages/reports/payment-report/payment-report/payment-report.component.ts index 2147f1d559b..c1f5493fbe8 100644 --- a/apps/gauzy/src/app/pages/reports/payment-report/payment-report/payment-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/payment-report/payment-report/payment-report.component.ts @@ -14,7 +14,7 @@ import { filter, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { pluck } from 'underscore'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, ChartUtil, @@ -22,7 +22,7 @@ import { IChartData, TimeZoneService } from '@gauzy/ui-core/shared'; -import { DateRangePickerBuilderService, PaymentService, TimesheetFilterService } from '@gauzy/ui-core/core'; +import { DateRangePickerBuilderService, PaymentService, Store, TimesheetFilterService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/reports/project-budgets-report/project-budgets-report/project-budgets-report.component.ts b/apps/gauzy/src/app/pages/reports/project-budgets-report/project-budgets-report/project-budgets-report.component.ts index fa9d1e615f0..7a09b734395 100644 --- a/apps/gauzy/src/app/pages/reports/project-budgets-report/project-budgets-report/project-budgets-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/project-budgets-report/project-budgets-report/project-budgets-report.component.ts @@ -12,8 +12,8 @@ import { ReportGroupByFilter, ReportGroupFilterEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/reports/time-limit-report/time-limit-report/time-limit-report.component.ts b/apps/gauzy/src/app/pages/reports/time-limit-report/time-limit-report/time-limit-report.component.ts index ef0bd4f47b2..6244dd7651f 100644 --- a/apps/gauzy/src/app/pages/reports/time-limit-report/time-limit-report/time-limit-report.component.ts +++ b/apps/gauzy/src/app/pages/reports/time-limit-report/time-limit-report/time-limit-report.component.ts @@ -5,8 +5,8 @@ import { filter, tap } from 'rxjs/operators'; import { Observable } from 'rxjs/internal/Observable'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { TranslateService } from '@ngx-translate/core'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; import { IGetTimeLimitReportInput, ITimeLogFilters } from '@gauzy/contracts'; import { BaseSelectorFilterComponent, GauzyFiltersComponent, TimeZoneService } from '@gauzy/ui-core/shared'; diff --git a/apps/gauzy/src/app/pages/reports/time-reports/time-reports/time-reports.component.ts b/apps/gauzy/src/app/pages/reports/time-reports/time-reports/time-reports.component.ts index 7bbfca351a8..30a325babe3 100644 --- a/apps/gauzy/src/app/pages/reports/time-reports/time-reports/time-reports.component.ts +++ b/apps/gauzy/src/app/pages/reports/time-reports/time-reports/time-reports.component.ts @@ -4,7 +4,7 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { pick, pluck } from 'underscore'; -import { DateRangePickerBuilderService, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { DateRangePickerBuilderService, Store, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; import { IGetTimeLogReportInput, ITimeLogFilters, @@ -12,7 +12,7 @@ import { ReportGroupFilterEnum, TimeLogType } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, ChartUtil, diff --git a/apps/gauzy/src/app/pages/reports/weekly-time-reports/weekly-time-reports/weekly-time-reports.component.ts b/apps/gauzy/src/app/pages/reports/weekly-time-reports/weekly-time-reports/weekly-time-reports.component.ts index d6d6a750661..174bf420446 100644 --- a/apps/gauzy/src/app/pages/reports/weekly-time-reports/weekly-time-reports/weekly-time-reports.component.ts +++ b/apps/gauzy/src/app/pages/reports/weekly-time-reports/weekly-time-reports/weekly-time-reports.component.ts @@ -5,9 +5,15 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { pluck, pick } from 'underscore'; import * as randomColor from 'randomcolor'; -import { DateRangePickerBuilderService, moment, TimesheetFilterService, TimesheetService } from '@gauzy/ui-core/core'; +import { + DateRangePickerBuilderService, + moment, + Store, + TimesheetFilterService, + TimesheetService +} from '@gauzy/ui-core/core'; import { IGetTimeLogReportInput, ITimeLogFilters, ReportDayData } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty, progressStatus } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty, progressStatus } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, ChartUtil, diff --git a/apps/gauzy/src/app/pages/settings/danger-zone/danger-zone.component.ts b/apps/gauzy/src/app/pages/settings/danger-zone/danger-zone.component.ts index f2d96695f96..9e95d2fab37 100644 --- a/apps/gauzy/src/app/pages/settings/danger-zone/danger-zone.component.ts +++ b/apps/gauzy/src/app/pages/settings/danger-zone/danger-zone.component.ts @@ -7,8 +7,7 @@ import { filter, tap } from 'rxjs/operators'; import { IUser } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { Environment, environment } from '@gauzy/ui-config'; -import { ToastrService, UsersService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store, ToastrService, UsersService } from '@gauzy/ui-core/core'; import { DangerZoneMutationComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/settings/email-history/email-filters/email-filters.component.ts b/apps/gauzy/src/app/pages/settings/email-history/email-filters/email-filters.component.ts index 50a467e28cc..bc123e4f2bd 100644 --- a/apps/gauzy/src/app/pages/settings/email-history/email-filters/email-filters.component.ts +++ b/apps/gauzy/src/app/pages/settings/email-history/email-filters/email-filters.component.ts @@ -3,8 +3,8 @@ import { NbDialogRef } from '@nebular/theme'; import { IEmailTemplate, IEmailHistory, IOrganization, LanguagesEnum } from '@gauzy/contracts'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { EmailService, EmailTemplateService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { EmailService, EmailTemplateService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/settings/email-history/email-history.component.ts b/apps/gauzy/src/app/pages/settings/email-history/email-history.component.ts index c62ca43829e..7402589118b 100644 --- a/apps/gauzy/src/app/pages/settings/email-history/email-history.component.ts +++ b/apps/gauzy/src/app/pages/settings/email-history/email-history.component.ts @@ -12,10 +12,10 @@ import { filter, tap, debounceTime } from 'rxjs/operators'; import { Subject, firstValueFrom } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { EmailFiltersComponent } from './email-filters/email-filters.component'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { EmailService, EmployeesService, OrganizationContactService, ToastrService } from '@gauzy/ui-core/core'; +import { EmailService, EmployeesService, OrganizationContactService, Store, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/settings/file-storage/file-storage.component.ts b/apps/gauzy/src/app/pages/settings/file-storage/file-storage.component.ts index 01f2e069fd3..6e582057221 100644 --- a/apps/gauzy/src/app/pages/settings/file-storage/file-storage.component.ts +++ b/apps/gauzy/src/app/pages/settings/file-storage/file-storage.component.ts @@ -14,9 +14,9 @@ import { PermissionsEnum, SMTPSecureEnum } from '@gauzy/contracts'; -import { isNotEmpty, Store } from '@gauzy/ui-core/common'; +import { isNotEmpty } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ErrorHandlingService, ToastrService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, Store, ToastrService } from '@gauzy/ui-core/core'; import { FileStorageService, TenantService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/settings/roles-permissions/roles-permissions.component.ts b/apps/gauzy/src/app/pages/settings/roles-permissions/roles-permissions.component.ts index 77891c9fb29..1336d9b36f9 100644 --- a/apps/gauzy/src/app/pages/settings/roles-permissions/roles-permissions.component.ts +++ b/apps/gauzy/src/app/pages/settings/roles-permissions/roles-permissions.component.ts @@ -8,8 +8,7 @@ import { Observable, Subject, of as observableOf, startWith, catchError } from ' import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { environment } from '@gauzy/ui-config'; -import { RolePermissionsService, RoleService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { RolePermissionsService, RoleService, Store, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -154,7 +153,7 @@ export class RolesPermissionsComponent extends TranslationBaseComponent implemen async permissionChanged(permission: string, enabled: boolean, allowChange: boolean) { /** - * If anyone trying to update another users permissions without enough permisison + * If anyone trying to update another users permissions without enough permission */ if (!allowChange) { this.toastrService.danger( diff --git a/apps/gauzy/src/app/pages/tags/tags.component.ts b/apps/gauzy/src/app/pages/tags/tags.component.ts index bb4886a3f98..25d69384171 100644 --- a/apps/gauzy/src/app/pages/tags/tags.component.ts +++ b/apps/gauzy/src/app/pages/tags/tags.component.ts @@ -7,8 +7,8 @@ import { Subject, firstValueFrom } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ITag, IOrganization, ComponentLayoutStyleEnum } from '@gauzy/contracts'; -import { ComponentEnum, Store, distinctUntilChange, splitCamelCase } from '@gauzy/ui-core/common'; -import { TagsService, ToastrService } from '@gauzy/ui-core/core'; +import { ComponentEnum, distinctUntilChange, splitCamelCase } from '@gauzy/ui-core/common'; +import { Store, TagsService, ToastrService } from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/tasks/components/my-task-dialog/my-task-dialog.component.ts b/apps/gauzy/src/app/pages/tasks/components/my-task-dialog/my-task-dialog.component.ts index 20f76b7879d..b671e0e4254 100644 --- a/apps/gauzy/src/app/pages/tasks/components/my-task-dialog/my-task-dialog.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/my-task-dialog/my-task-dialog.component.ts @@ -12,9 +12,9 @@ import { EmployeesService, ErrorHandlingService, OrganizationProjectsService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; const initialTaskValue = { title: '', diff --git a/apps/gauzy/src/app/pages/tasks/components/task/task-settings/project-view/project-view.component.ts b/apps/gauzy/src/app/pages/tasks/components/task/task-settings/project-view/project-view.component.ts index 824e1f1998e..e2eb76f07be 100644 --- a/apps/gauzy/src/app/pages/tasks/components/task/task-settings/project-view/project-view.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/task/task-settings/project-view/project-view.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; import { CrudActionEnum, IOrganizationProject, TaskListTypeEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { OrganizationProjectsService, OrganizationProjectStore } from '@gauzy/ui-core/core'; +import { OrganizationProjectsService, OrganizationProjectStore, Store } from '@gauzy/ui-core/core'; export interface TaskViewMode { type: TaskListTypeEnum; diff --git a/apps/gauzy/src/app/pages/tasks/components/task/task-settings/task-settings.component.ts b/apps/gauzy/src/app/pages/tasks/components/task/task-settings/task-settings.component.ts index 5edeb44e574..0373dbaca54 100644 --- a/apps/gauzy/src/app/pages/tasks/components/task/task-settings/task-settings.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/task/task-settings/task-settings.component.ts @@ -4,8 +4,7 @@ import { IOrganizationProject, TaskListTypeEnum, PermissionsEnum, IPagination, I import { Observable } from 'rxjs'; import { map, tap, switchMap, take } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; -import { TasksService, TasksStoreService } from '@gauzy/ui-core/core'; +import { Store, TasksService, TasksStoreService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/tasks/components/task/task.component.ts b/apps/gauzy/src/app/pages/tasks/components/task/task.component.ts index d77f48cdd16..5e0e1a16c1f 100644 --- a/apps/gauzy/src/app/pages/tasks/components/task/task.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/task/task.component.ts @@ -11,6 +11,7 @@ import { ErrorHandlingService, MyTasksStoreService, ServerDataSource, + Store, TasksStoreService, TeamTasksStoreService } from '@gauzy/ui-core/core'; @@ -43,7 +44,7 @@ import { PermissionsEnum, TaskListTypeEnum } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { MyTaskDialogComponent } from './../my-task-dialog/my-task-dialog.component'; import { TeamTaskDialogComponent } from '../team-task-dialog/team-task-dialog.component'; diff --git a/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/task/task.component.ts b/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/task/task.component.ts index 0a9f3a8f315..f87aa432df0 100644 --- a/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/task/task.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/task/task.component.ts @@ -15,8 +15,8 @@ import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { TaskStatusesService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store, TaskStatusesService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/tasks-sprint-view.component.ts b/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/tasks-sprint-view.component.ts index 4dca38aa527..bca2b6363dd 100644 --- a/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/tasks-sprint-view.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/task/tasks-layouts/tasks-sprint-view/tasks-sprint-view.component.ts @@ -6,8 +6,7 @@ import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/dr import { NbDialogService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { SprintStoreService, TasksStoreService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { SprintStoreService, Store, TasksStoreService } from '@gauzy/ui-core/core'; import { GauzyEditableGridComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/tasks/components/team-task-dialog/team-task-dialog.component.ts b/apps/gauzy/src/app/pages/tasks/components/team-task-dialog/team-task-dialog.component.ts index dbefd5a2240..bef3d768937 100644 --- a/apps/gauzy/src/app/pages/tasks/components/team-task-dialog/team-task-dialog.component.ts +++ b/apps/gauzy/src/app/pages/tasks/components/team-task-dialog/team-task-dialog.component.ts @@ -3,15 +3,15 @@ import { IEmployee, IOrganizationProject, IOrganizationTeam, ITag, ITask, TaskSt import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { NbDialogRef } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; -import moment from 'moment'; +import * as moment from 'moment'; import { CKEditor4 } from 'ckeditor4-angular/ckeditor'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { richTextCKEditorConfig } from '@gauzy/ui-core/shared'; -import { Store } from '@gauzy/ui-core/common'; import { ErrorHandlingService, OrganizationProjectsService, OrganizationTeamsService, + Store, ToastrService } from '@gauzy/ui-core/core'; diff --git a/apps/gauzy/src/app/pages/teams/teams-mutation/teams-mutation.component.ts b/apps/gauzy/src/app/pages/teams/teams-mutation/teams-mutation.component.ts index 86b11467406..518a18fc9bc 100644 --- a/apps/gauzy/src/app/pages/teams/teams-mutation/teams-mutation.component.ts +++ b/apps/gauzy/src/app/pages/teams/teams-mutation/teams-mutation.component.ts @@ -3,8 +3,8 @@ import { UntypedFormBuilder, FormControl, UntypedFormGroup, Validators } from '@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IEmployee, IOrganization, IImageAsset, IOrganizationProject, IOrganizationTeam, ITag } from '@gauzy/contracts'; -import { DUMMY_PROFILE_IMAGE, Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; -import { ToastrService } from '@gauzy/ui-core/core'; +import { DUMMY_PROFILE_IMAGE, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { Store, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/teams/teams.component.ts b/apps/gauzy/src/app/pages/teams/teams.component.ts index 48a65060309..5cfa0d169c5 100644 --- a/apps/gauzy/src/app/pages/teams/teams.component.ts +++ b/apps/gauzy/src/app/pages/teams/teams.component.ts @@ -24,9 +24,10 @@ import { OrganizationProjectsService, OrganizationTeamsService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { PaginationFilterBaseComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/time-off/time-off-settings/time-off-settings.component.ts b/apps/gauzy/src/app/pages/time-off/time-off-settings/time-off-settings.component.ts index b06d5d536fa..b39f6b2d480 100644 --- a/apps/gauzy/src/app/pages/time-off/time-off-settings/time-off-settings.component.ts +++ b/apps/gauzy/src/app/pages/time-off/time-off-settings/time-off-settings.component.ts @@ -7,8 +7,8 @@ import { Cell } from 'angular2-smart-table'; import { NbDialogService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { ServerDataSource, TimeOffService, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ServerDataSource, Store, TimeOffService, ToastrService } from '@gauzy/ui-core/core'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { DeleteConfirmationComponent, EmployeeWithLinksComponent, diff --git a/apps/gauzy/src/app/pages/time-off/time-off.component.ts b/apps/gauzy/src/app/pages/time-off/time-off.component.ts index 3e294eaa258..86f574cfbc6 100644 --- a/apps/gauzy/src/app/pages/time-off/time-off.component.ts +++ b/apps/gauzy/src/app/pages/time-off/time-off.component.ts @@ -7,10 +7,16 @@ import { combineLatest, Subject } from 'rxjs'; import { Cell } from 'angular2-smart-table'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import moment from 'moment'; -import { DateRangePickerBuilderService, ServerDataSource, TimeOffService, ToastrService } from '@gauzy/ui-core/core'; +import * as moment from 'moment'; +import { + DateRangePickerBuilderService, + ServerDataSource, + Store, + TimeOffService, + ToastrService +} from '@gauzy/ui-core/core'; import { StatusTypesEnum, ITimeOff, ComponentLayoutStyleEnum, IOrganization, IDateRangePicker } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; import { PaginationFilterBaseComponent, IPaginationBase, diff --git a/apps/gauzy/src/app/pages/upwork/components/reports/reports.component.ts b/apps/gauzy/src/app/pages/upwork/components/reports/reports.component.ts index f95c68690b3..8fc4c755ba6 100644 --- a/apps/gauzy/src/app/pages/upwork/components/reports/reports.component.ts +++ b/apps/gauzy/src/app/pages/upwork/components/reports/reports.component.ts @@ -4,12 +4,11 @@ import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/internal/operators/tap'; import { debounceTime, filter } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import moment from 'moment'; +import * as moment from 'moment'; import { Cell } from 'angular2-smart-table'; import { IncomeTypeEnum, IOrganization, IUpworkDateRange } from '@gauzy/contracts'; -import { UpworkStoreService } from '@gauzy/ui-core/core'; +import { Store, UpworkStoreService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; import { DateViewComponent, IncomeExpenseAmountComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/upwork/components/transactions/transactions.component.ts b/apps/gauzy/src/app/pages/upwork/components/transactions/transactions.component.ts index c5ea558ee20..f2134e95d46 100644 --- a/apps/gauzy/src/app/pages/upwork/components/transactions/transactions.component.ts +++ b/apps/gauzy/src/app/pages/upwork/components/transactions/transactions.component.ts @@ -1,11 +1,10 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { filter, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { IOrganization } from '@gauzy/contracts'; -import { ErrorHandlingService, ToastrService, UpworkService } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, Store, ToastrService, UpworkService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/upwork/components/upwork-authorize/upwork-authorize.component.ts b/apps/gauzy/src/app/pages/upwork/components/upwork-authorize/upwork-authorize.component.ts index a143870f056..2dc7bde746b 100644 --- a/apps/gauzy/src/app/pages/upwork/components/upwork-authorize/upwork-authorize.component.ts +++ b/apps/gauzy/src/app/pages/upwork/components/upwork-authorize/upwork-authorize.component.ts @@ -11,8 +11,7 @@ import { IUpworkClientSecretPair, IntegrationEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { IntegrationsService, UpworkService } from '@gauzy/ui-core/core'; +import { IntegrationsService, Store, UpworkService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/upwork/components/upwork/upwork.component.ts b/apps/gauzy/src/app/pages/upwork/components/upwork/upwork.component.ts index 5ab667a5646..0349a9ba7b9 100644 --- a/apps/gauzy/src/app/pages/upwork/components/upwork/upwork.component.ts +++ b/apps/gauzy/src/app/pages/upwork/components/upwork/upwork.component.ts @@ -1,14 +1,13 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { NbMenuItem, NbRouteTab } from '@nebular/theme'; import { filter } from 'rxjs/operators'; import { tap } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import { ID, IOrganization } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { ID, IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { UpworkStoreService } from '@gauzy/ui-core/core'; +import { Store, UpworkStoreService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/apps/gauzy/src/app/pages/users/edit-user-mutation/edit-user-mutation.component.ts b/apps/gauzy/src/app/pages/users/edit-user-mutation/edit-user-mutation.component.ts index a59405613a2..8ba3119e371 100644 --- a/apps/gauzy/src/app/pages/users/edit-user-mutation/edit-user-mutation.component.ts +++ b/apps/gauzy/src/app/pages/users/edit-user-mutation/edit-user-mutation.component.ts @@ -3,8 +3,7 @@ import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { IOrganization, IUserOrganization, RolesEnum } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { UsersOrganizationsService } from '@gauzy/ui-core/core'; +import { Store, UsersOrganizationsService } from '@gauzy/ui-core/core'; import { BasicInfoFormComponent } from '@gauzy/ui-core/shared'; @Component({ diff --git a/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations-mutation/edit-user-organizations-mutation.component.ts b/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations-mutation/edit-user-organizations-mutation.component.ts index f1f112629d2..ad4c02f61fd 100644 --- a/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations-mutation/edit-user-organizations-mutation.component.ts +++ b/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations-mutation/edit-user-organizations-mutation.component.ts @@ -3,8 +3,7 @@ import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; import { IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { OrganizationsService, UserIdService, UsersOrganizationsService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { OrganizationsService, Store, UserIdService, UsersOrganizationsService } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-edit-user-organizations-mutation', diff --git a/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations.component.ts b/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations.component.ts index d50c7b73167..cf7dd512b3c 100644 --- a/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations.component.ts +++ b/apps/gauzy/src/app/pages/users/edit-user-profile/edit-user-organizations/edit-user-organizations.component.ts @@ -7,8 +7,13 @@ import { ActivatedRoute, Router } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { NbDialogService } from '@nebular/theme'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { OrganizationsService, ToastrService, UsersOrganizationsService, UsersService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { + OrganizationsService, + Store, + ToastrService, + UsersOrganizationsService, + UsersService +} from '@gauzy/ui-core/core'; import { DeleteConfirmationComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/apps/gauzy/src/app/pages/users/users.component.ts b/apps/gauzy/src/app/pages/users/users.component.ts index be575df52b8..c4a372b4e78 100644 --- a/apps/gauzy/src/app/pages/users/users.component.ts +++ b/apps/gauzy/src/app/pages/users/users.component.ts @@ -6,7 +6,7 @@ import { Cell, LocalDataSource } from 'angular2-smart-table'; import { filter, tap } from 'rxjs/operators'; import { debounceTime, firstValueFrom, Subject } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { ErrorHandlingService, ToastrService, UsersOrganizationsService, monthNames } from '@gauzy/ui-core/core'; +import { ErrorHandlingService, Store, ToastrService, UsersOrganizationsService, monthNames } from '@gauzy/ui-core/core'; import { InvitationTypeEnum, PermissionsEnum, @@ -21,7 +21,7 @@ import { ITag, IEmployee } from '@gauzy/contracts'; -import { ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { DeleteConfirmationComponent, EmailComponent, diff --git a/apps/gauzy/src/app/pages/vendors/vendors.component.ts b/apps/gauzy/src/app/pages/vendors/vendors.component.ts index f086066e9a6..ca3bfa90096 100644 --- a/apps/gauzy/src/app/pages/vendors/vendors.component.ts +++ b/apps/gauzy/src/app/pages/vendors/vendors.component.ts @@ -8,9 +8,15 @@ import { debounceTime, firstValueFrom, Subject } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Cell } from 'angular2-smart-table'; -import { ErrorHandlingService, OrganizationVendorsService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { + ErrorHandlingService, + OrganizationVendorsService, + ServerDataSource, + Store, + ToastrService +} from '@gauzy/ui-core/core'; import { IOrganizationVendor, ITag, ComponentLayoutStyleEnum, IOrganization } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { CompanyLogoComponent, DeleteConfirmationComponent, diff --git a/apps/gauzy/src/app/server-down/server-down.component.html b/apps/gauzy/src/app/server-down/server-down.component.html deleted file mode 100644 index 9ec7ea8329d..00000000000 --- a/apps/gauzy/src/app/server-down/server-down.component.html +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/apps/gauzy/src/app/server-down/server-down.component.scss b/apps/gauzy/src/app/server-down/server-down.component.scss deleted file mode 100644 index 006b0abf418..00000000000 --- a/apps/gauzy/src/app/server-down/server-down.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -.info-page { - padding: 0 !important; - .server-down-content { - color: white; - - display: flex; - align-items: center; - justify-content: center; - text-align: center; - height: 100%; - flex-direction: column; - } - - .info-massage h3 { - color: red; - width: 100%; - } -} - -img { - max-height: 96px; - max-width: 300px; - width: auto; -} diff --git a/apps/gauzy/src/app/server-down/server-down.component.ts b/apps/gauzy/src/app/server-down/server-down.component.ts deleted file mode 100644 index de8bd34f92a..00000000000 --- a/apps/gauzy/src/app/server-down/server-down.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; -import { Location } from '@angular/common'; -import { Environment, GAUZY_ENV } from '@gauzy/ui-config'; -import { Store } from '@gauzy/ui-core/common'; -import { ServerConnectionService } from '@gauzy/ui-core/core'; - -@Component({ - selector: 'ga-server-down-page', - styleUrls: ['./server-down.component.scss'], - templateUrl: './server-down.component.html' -}) -export class ServerDownComponent implements OnInit, OnDestroy { - noInternetLogo: string; - interval: any; - - constructor( - private readonly store: Store, - private readonly location: Location, - private readonly serverConnectionService: ServerConnectionService, - @Inject(GAUZY_ENV) private environment: Environment - ) { - this.noInternetLogo = environment['NO_INTERNET_LOGO']; - } - - ngOnInit(): void { - this.checkConnection(); - } - - /** - * Checks the server connection every 5 seconds. - */ - private async checkConnection() { - const url = this.environment.API_BASE_URL; - console.log('Checking server connection to URL: ', url); - - this.interval = setInterval(async () => { - console.log('Checking server connection...'); - - await this.serverConnectionService.checkServerConnection(url); - - if (Number(this.store.serverConnection) === 200) { - console.log('Server is online'); - clearInterval(this.interval); - this.location.back(); - } else { - console.log('Server is offline'); - } - }, 5000); - } - - /** - * Checks if the company site is defined in the environment. - * - * @return {string} The company site name. - */ - public get companySite(): string { - return this.environment.COMPANY_SITE_NAME; - } - - ngOnDestroy(): void {} -} diff --git a/apps/gauzy/src/app/server-down/server-down.module.ts b/apps/gauzy/src/app/server-down/server-down.module.ts deleted file mode 100644 index f7ecd33aa2b..00000000000 --- a/apps/gauzy/src/app/server-down/server-down.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { RouterModule, ROUTES } from '@angular/router'; -import { NbLayoutModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { PageRouteService } from '@gauzy/ui-core/core'; -import { createRoutes } from './server-down.routes'; -import { ServerDownComponent } from './server-down.component'; - -@NgModule({ - imports: [CommonModule, FormsModule, RouterModule.forChild([]), NbLayoutModule, TranslateModule.forChild()], - declarations: [ServerDownComponent], - providers: [ - { - provide: ROUTES, - useFactory: (pageRouteService: PageRouteService) => createRoutes(pageRouteService), - deps: [PageRouteService], - multi: true - } - ] -}) -export class ServerDownModule {} diff --git a/apps/gauzy/src/app/server-down/server-down.routes.ts b/apps/gauzy/src/app/server-down/server-down.routes.ts deleted file mode 100644 index d5c3154014b..00000000000 --- a/apps/gauzy/src/app/server-down/server-down.routes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Route } from '@angular/router'; -import { PageRouteService } from '@gauzy/ui-core/core'; -import { ServerDownComponent } from './server-down.component'; - -/** - * Creates routes for the server down page. - * - * @param _pageRouteService An instance of PageRouteService - * @returns An array of Route objects - */ -export const createRoutes = (_pageRouteService: PageRouteService): Route[] => [ - { - path: '', - component: ServerDownComponent - } -]; diff --git a/apps/gauzy/src/app/share/employee/employee-routing.module.ts b/apps/gauzy/src/app/share/employee/employee-routing.module.ts deleted file mode 100644 index 75f7916f944..00000000000 --- a/apps/gauzy/src/app/share/employee/employee-routing.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { PublicOrganizationResolver } from '../organization/public-organization.resolver'; -import { PublicEmployeeResolver } from './public-employee.resolver'; -import { EmployeeComponent } from './employee.component'; - -const routes: Routes = [ - { - path: '', - component: EmployeeComponent, - runGuardsAndResolvers: 'always', - resolve: { - organization: PublicOrganizationResolver, - employee: PublicEmployeeResolver - } - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class EmployeeRoutingModule {} diff --git a/apps/gauzy/src/app/share/employee/employee.component.ts b/apps/gauzy/src/app/share/employee/employee.component.ts deleted file mode 100644 index 7baf9abaf21..00000000000 --- a/apps/gauzy/src/app/share/employee/employee.component.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; -import { map, tap } from 'rxjs/operators'; -import { NbDialogService } from '@nebular/theme'; -import { PermissionsEnum, IEmployee, IEmployeeAward, IOrganization } from '@gauzy/contracts'; -import moment from 'moment'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { EmployeesService, ErrorHandlingService, ToastrService, UsersService } from '@gauzy/ui-core/core'; -import { PublicPageEmployeeMutationComponent } from '@gauzy/ui-core/shared'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'ngx-employee-share', - templateUrl: './employee.component.html', - styleUrls: ['./employee.component.scss'] -}) -export class EmployeeComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - hasEditPermission$: Observable; - imageUrl: string; - imageUpdateButton: boolean; - public organization$: Observable; - public organization: IOrganization; - public employee$: Observable; - hoverState: boolean; - employeeAwards: IEmployeeAward[] = []; - - constructor( - private readonly employeeService: EmployeesService, - private readonly userService: UsersService, - private readonly route: ActivatedRoute, - readonly translateService: TranslateService, - private readonly dialogService: NbDialogService, - private readonly toastrService: ToastrService, - private readonly store: Store, - private readonly errorHandlingService: ErrorHandlingService - ) { - super(translateService); - } - - ngOnInit(): void { - this.organization$ = this.route.data.pipe( - map(({ organization }) => organization), - tap((organization: IOrganization) => (this.organization = organization)) - ); - this.employee$ = this.route.data.pipe( - map(({ employee }) => ({ - ...employee, - startedWorkOn: employee.startedWorkOn ? moment(employee.startedWorkOn).toDate() : undefined - })), - tap((employee: IEmployee) => (this.imageUrl = employee.user.imageUrl)), - tap((employee: IEmployee) => (this.employeeAwards = employee.awards)) - ); - this.hasEditPermission$ = this.store.userRolePermissions$.pipe( - map(() => this.store.hasPermission(PermissionsEnum.PUBLIC_PAGE_EDIT)) - ); - } - - ngAfterViewInit() {} - - updateImageUrl(url: string) { - this.imageUrl = url; - this.imageUpdateButton = true; - } - - async saveImage({ userId, imageUrl }) { - try { - await this.userService.update(userId, { - imageUrl - }); - this.toastrService.success('PUBLIC_PAGE.IMAGE_UPDATED'); - } catch (e) { - this.errorHandlingService.handleError(e); - } - - this.imageUpdateButton = false; - } - - /** - * Opens a dialog to edit an employee. - * - * @param {IEmployee} employee - The employee to be edited. - * @return {void} This function does not return a value. - */ - openEditEmployeeDialog(employee: IEmployee): void { - if (!this.store.hasPermission(PermissionsEnum.PUBLIC_PAGE_EDIT)) { - return; - } - this.dialogService - .open(PublicPageEmployeeMutationComponent, { - context: { - employee, - employeeAwards: this.employeeAwards - } - }) - .onClose.pipe( - tap(async (empFormValue) => { - if (empFormValue) { - await this.handleEmployeeUpdate(employee, empFormValue); - } - }), - untilDestroyed(this) - ) - .subscribe(); - } - - async handleEmployeeUpdate(employee, { username, email, firstName, lastName, preferredLanguage, ...empFormValue }) { - try { - if (!this.organization) { - return; - } - const { id: organizationId, tenantId } = this.organization; - const updatedUser: any = await this.userService.update(employee.user.id, { - username, - email, - firstName, - lastName, - preferredLanguage - }); - const employeeUpdatedRes = await this.employeeService.update(employee.id, { - organizationId, - tenantId, - ...empFormValue - }); - const updatedEmployee = { - ...employee, - ...employeeUpdatedRes, - isActive: employee.isActive, - billRateCurrency: employee.billRateCurrency, - user: { - ...employee.user, - ...updatedUser, - imageUrl: updatedUser.imageUrl ? updatedUser.imageUrl : employee.user.imageUrl - }, - startedWorkOn: employeeUpdatedRes.startedWorkOn - ? moment(new Date(employeeUpdatedRes.startedWorkOn)).format('MM-DD-YYYY') - : employee.startedWorkOn - }; - this.employee$ = of(updatedEmployee); - this.toastrService.success('PUBLIC_PAGE.EMPLOYEE_UPDATED'); - } catch (e) { - this.errorHandlingService.handleError(e); - } - } - - handleImageUploadError(error: any) { - this.toastrService.danger(error, 'Error'); - } - - ngOnDestroy(): void {} -} diff --git a/apps/gauzy/src/app/share/employee/employee.module.ts b/apps/gauzy/src/app/share/employee/employee.module.ts deleted file mode 100644 index 2c209e56283..00000000000 --- a/apps/gauzy/src/app/share/employee/employee.module.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { - NbButtonModule, - NbCardModule, - NbIconModule, - NbInputModule, - NbListModule, - NbTabsetModule, - NbTagModule, - NbUserModule -} from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { - ImageUploaderModule, - PublicPageEmployeeMutationModule, - SharedModule, - TableComponentsModule, - WorkInProgressModule -} from '@gauzy/ui-core/shared'; -import { EmployeeRoutingModule } from './employee-routing.module'; -import { EmployeeComponent } from './employee.component'; - -@NgModule({ - imports: [ - CommonModule, - NbButtonModule, - NbCardModule, - NbIconModule, - NbInputModule, - NbListModule, - NbTabsetModule, - NbTagModule, - NbUserModule, - SharedModule, - EmployeeRoutingModule, - ImageUploaderModule, - PublicPageEmployeeMutationModule, - TranslateModule.forChild(), - WorkInProgressModule, - TableComponentsModule - ], - declarations: [EmployeeComponent] -}) -export class EmployeeModule {} diff --git a/apps/gauzy/src/app/share/employee/index.ts b/apps/gauzy/src/app/share/employee/index.ts deleted file mode 100644 index 832c975e769..00000000000 --- a/apps/gauzy/src/app/share/employee/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './employee.module'; -export * from './employee.component'; -export * from './employee-routing.module'; -export * from './public-employee.resolver'; \ No newline at end of file diff --git a/apps/gauzy/src/app/share/employee/public-employee.resolver.ts b/apps/gauzy/src/app/share/employee/public-employee.resolver.ts deleted file mode 100644 index cd1c1694fd6..00000000000 --- a/apps/gauzy/src/app/share/employee/public-employee.resolver.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Resolve, Router, ActivatedRouteSnapshot } from '@angular/router'; -import { EmployeesService } from '@gauzy/ui-core/core'; -import { catchError } from 'rxjs/operators'; -import { EMPTY, Observable } from 'rxjs'; -import { IEmployee } from '@gauzy/contracts'; -import { ErrorHandlingService } from '@gauzy/ui-core/core'; - -@Injectable({ - providedIn: 'root' -}) -export class PublicEmployeeResolver implements Resolve { - constructor( - private readonly employeesService: EmployeesService, - private readonly router: Router, - private readonly errorHandlingService: ErrorHandlingService - ) {} - - resolve(route: ActivatedRouteSnapshot): Observable { - const slug = route.params.slug; - const employeeId = route.params.employeeId; - try { - return this.employeesService - .getPublicById(slug, employeeId, ['user', 'organizationEmploymentTypes', 'skills', 'awards']) - .pipe( - catchError((e) => { - this.errorHandlingService.handleError(e); - this.router.navigateByUrl('/'); - return EMPTY; - }) - ); - } catch (error) { - this.router.navigateByUrl('/'); - } - } -} diff --git a/apps/gauzy/src/app/share/invoices-estimates/index.ts b/apps/gauzy/src/app/share/invoices-estimates/index.ts deleted file mode 100644 index de18bdc42ad..00000000000 --- a/apps/gauzy/src/app/share/invoices-estimates/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './invoice-estimate.module'; -export * from './invoice-estimate.component'; -export * from './invoice-estimate.routing.module'; diff --git a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.html b/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.html deleted file mode 100644 index 75f53bcd28a..00000000000 --- a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.html +++ /dev/null @@ -1,18 +0,0 @@ - - -

- {{ 'INVOICES_PAGE.VIEW_INVOICE' | translate }} -

-

- {{ 'INVOICES_PAGE.VIEW_ESTIMATE' | translate }} -

-
- - - - -
diff --git a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.scss b/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.scss deleted file mode 100644 index f4d57e3f6a7..00000000000 --- a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.invoice-body { - padding: 40px 100px; -} diff --git a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.ts b/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.ts deleted file mode 100644 index 370ecfff4a1..00000000000 --- a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { IInvoice } from '@gauzy/contracts'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslateService } from '@ngx-translate/core'; -import { InvoicesService } from '@gauzy/ui-core/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'ga-invoice-estimate', - templateUrl: './invoice-estimate.component.html', - styleUrls: ['./invoice-estimate.component.scss'] -}) -export class InvoiceEstimateComponent extends TranslationBaseComponent implements OnInit { - invoiceId: string; - token: string; - invoice: IInvoice; - - constructor( - private readonly route: ActivatedRoute, - private readonly invoicesService: InvoicesService, - public readonly translateService: TranslateService - ) { - super(translateService); - } - - ngOnInit() { - this.route.params.pipe(untilDestroyed(this)).subscribe(async (params) => { - this.invoiceId = params.id; - this.token = params.token; - await this.getInvoiceEstimate(); - }); - } - - async getInvoiceEstimate() { - try { - this.invoice = await this.invoicesService.getPublicInvoice(this.invoiceId, this.token, [ - 'invoiceItems', - 'invoiceItems.employee', - 'invoiceItems.employee.user', - 'invoiceItems.project', - 'invoiceItems.product', - 'invoiceItems.expense', - 'invoiceItems.task', - 'fromOrganization', - 'toContact' - ]); - } catch (error) { - console.error('Error while getting public invoice', error); - } - } -} diff --git a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.module.ts b/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.module.ts deleted file mode 100644 index 3146af4d669..00000000000 --- a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbCardModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { InvoicesService } from '@gauzy/ui-core/core'; -import { InvoiceEstimateRoutingModule } from './invoice-estimate.routing.module'; -import { InvoiceEstimateComponent } from './invoice-estimate.component'; -import { InvoicesModule } from '../../pages/invoices/invoices.module'; - -@NgModule({ - imports: [InvoiceEstimateRoutingModule, InvoicesModule, CommonModule, NbCardModule, TranslateModule.forChild()], - declarations: [InvoiceEstimateComponent], - exports: [InvoiceEstimateComponent], - providers: [InvoicesService] -}) -export class InvoiceEstimateModule {} diff --git a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.routing.module.ts b/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.routing.module.ts deleted file mode 100644 index 3e2be401ae8..00000000000 --- a/apps/gauzy/src/app/share/invoices-estimates/invoice-estimate.routing.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { InvoiceEstimateComponent } from './invoice-estimate.component'; - -const routes: Routes = [ - { - path: '', - component: InvoiceEstimateComponent - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class InvoiceEstimateRoutingModule {} diff --git a/apps/gauzy/src/app/share/organization/index.ts b/apps/gauzy/src/app/share/organization/index.ts deleted file mode 100644 index d1536e569d1..00000000000 --- a/apps/gauzy/src/app/share/organization/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './organization.module'; -export * from './organization.component'; -export * from './organization-routing.module'; diff --git a/apps/gauzy/src/app/share/organization/organization-routing.module.ts b/apps/gauzy/src/app/share/organization/organization-routing.module.ts deleted file mode 100644 index 84c318558ff..00000000000 --- a/apps/gauzy/src/app/share/organization/organization-routing.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { OrganizationComponent } from './organization.component'; -import { PublicOrganizationResolver } from './public-organization.resolver'; - -const routes: Routes = [ - { - path: '', - component: OrganizationComponent, - data: { - relations: ['skills', 'awards', 'languages', 'languages.language'] - }, - resolve: { - organization: PublicOrganizationResolver - }, - runGuardsAndResolvers: 'always' - }, - { - path: ':slug/:employeeId', - loadChildren: () => import('../employee/employee.module').then((m) => m.EmployeeModule) - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class OrganizationRoutingModule {} diff --git a/apps/gauzy/src/app/share/organization/organization.module.ts b/apps/gauzy/src/app/share/organization/organization.module.ts deleted file mode 100644 index d53bbe901e3..00000000000 --- a/apps/gauzy/src/app/share/organization/organization.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { - NbCardModule, - NbButtonModule, - NbInputModule, - NbIconModule, - NbDialogModule, - NbListModule, - NbTabsetModule, - NbUserModule, - NbTagModule -} from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { - ImageUploaderModule, - PublicPageMutationModule, - SharedModule, - TableComponentsModule, - WorkInProgressModule -} from '@gauzy/ui-core/shared'; -import { OrganizationComponent } from './organization.component'; -import { OrganizationRoutingModule } from './organization-routing.module'; - -@NgModule({ - imports: [ - CommonModule, - OrganizationRoutingModule, - NbCardModule, - NbDialogModule.forChild(), - FormsModule, - ReactiveFormsModule, - ImageUploaderModule, - NbButtonModule, - NbIconModule, - NbInputModule, - PublicPageMutationModule, - TranslateModule.forChild(), - NbListModule, - NbUserModule, - NbTabsetModule, - NbTagModule, - SharedModule, - TableComponentsModule, - WorkInProgressModule - ], - declarations: [OrganizationComponent], - providers: [] -}) -export class OrganizationModule {} diff --git a/apps/gauzy/src/app/share/organization/public-organization.resolver.ts b/apps/gauzy/src/app/share/organization/public-organization.resolver.ts deleted file mode 100644 index 13ea198e7dd..00000000000 --- a/apps/gauzy/src/app/share/organization/public-organization.resolver.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, Router } from '@angular/router'; -import { EMPTY, Observable } from 'rxjs'; -import { catchError } from 'rxjs/operators'; -import { IOrganization } from '@gauzy/contracts'; -import { ErrorHandlingService, OrganizationsService } from '@gauzy/ui-core/core'; - -@Injectable({ - providedIn: 'root' -}) -export class PublicOrganizationResolver implements Resolve { - constructor( - private readonly organizationsService: OrganizationsService, - private readonly router: Router, - private readonly errorHandlingService: ErrorHandlingService - ) {} - - /** - * - * @param route - * @returns - */ - resolve(route: ActivatedRouteSnapshot): Observable { - try { - const profileLink = route.params.profileLink; - const organizationId = route.params.organizationId; - const relations = route.data.relations || []; - - return this.organizationsService.getByProfileLink(profileLink, organizationId, [...relations]).pipe( - catchError((error) => { - this.errorHandlingService.handleError(error); - this.router.navigateByUrl('/'); - return EMPTY; - }) - ); - } catch (error) { - this.router.navigateByUrl('/'); - } - } -} diff --git a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.component.html b/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.component.html deleted file mode 100644 index 500fae32dc7..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.component.html +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.component.ts b/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.component.ts deleted file mode 100644 index 25caf2670e5..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.component.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { firstValueFrom, Subject } from 'rxjs'; -import { Router, ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { IEventType, IEmployee } from '@gauzy/contracts'; -import { takeUntil } from 'rxjs/operators'; -import { EmployeesService } from '@gauzy/ui-core/core'; - -@Component({ - templateUrl: './appointment-form.component.html' -}) -export class AppointmentFormComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - private _ngDestroy$ = new Subject(); - loading: boolean = true; - selectedRange: { start: Date; end: Date }; - selectedEventType: IEventType; - allowedDuration: Number; - employee: IEmployee; - - constructor( - private route: ActivatedRoute, - private router: Router, - private employeeService: EmployeesService, - readonly translateService: TranslateService - ) { - super(translateService); - } - - ngOnInit(): void { - this.selectedRange = { - start: history.state.dateStart, - end: history.state.dateEnd - }; - - this.route.params.pipe(takeUntil(this._ngDestroy$)).subscribe(async (params) => { - try { - if (!params.employeeId) { - return; - } - this.employee = await firstValueFrom(this.employeeService.getEmployeeById(params.employeeId, ['user'])); - - this.selectedEventType = history.state.selectedEventType; - - if (this.selectedEventType) { - this.allowedDuration = - this.selectedEventType.durationUnit === 'Day(s)' - ? this.selectedEventType.duration * 24 * 60 - : this.selectedEventType.durationUnit === 'Hour(s)' - ? this.selectedEventType.duration * 60 - : this.selectedEventType.duration * 1; - - this.loading = false; - } else { - history.go(-1); - } - } catch (error) { - await this.router.navigate(['/share/404']); - } - }); - } - - ngOnDestroy() { - this._ngDestroy$.next(); - this._ngDestroy$.complete(); - } -} diff --git a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.module.ts b/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.module.ts deleted file mode 100644 index fde14b4f3d5..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.module.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbButtonModule, NbCardModule, NbSpinnerModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { AppointmentModule } from '../../../pages/employees/appointment/appointment.module'; -import { ManageAppointmentModule } from '../../../pages/employees/appointment/manage-appointment/manage-appointment.module'; -import { AppointmentFormRoutingModule } from './appointment-form.routing.module'; -import { AppointmentFormComponent } from './appointment-form.component'; - -@NgModule({ - imports: [ - CommonModule, - NbButtonModule, - NbCardModule, - NbSpinnerModule, - TranslateModule.forChild(), - AppointmentFormRoutingModule, - AppointmentModule, - ManageAppointmentModule - ], - declarations: [AppointmentFormComponent], - exports: [AppointmentFormComponent], - providers: [] -}) -export class AppointmentFormModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.routing.module.ts b/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.routing.module.ts deleted file mode 100644 index f1d68ced1f8..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/appointment-form/appointment-form.routing.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { AppointmentFormComponent } from './appointment-form.component'; -const routes: Routes = [ - { - path: '', - component: AppointmentFormComponent, - }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class AppointmentFormRoutingModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/appointment-form/index.ts b/apps/gauzy/src/app/share/public-appointments/appointment-form/index.ts deleted file mode 100644 index 55da2655d62..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/appointment-form/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './appointment-form.module'; -export * from './appointment-form.component'; -export * from './appointment-form.routing.module'; diff --git a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.component.html b/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.component.html deleted file mode 100644 index 15a6d104114..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.component.html +++ /dev/null @@ -1,96 +0,0 @@ - - -
-

- {{ 'PUBLIC_APPOINTMENTS.CONFIRM_APPOINTMENT' | translate }} - -

-

- {{ 'PUBLIC_APPOINTMENTS.APPOINTMENT_INFO' | translate }} -

-
-
- - -
- {{ 'PUBLIC_APPOINTMENTS.DETAILS' | translate }} - -
-
- {{ 'PUBLIC_APPOINTMENTS.HOST' | translate }}: {{ employee.user.name }} ({{ employee.user.email }}) -
-
- {{ 'FORM.LABELS.MEETING_AGENDA' | translate }}: {{ appointment.agenda }} -
-
- {{ 'FORM.LABELS.MEETING_DESCRIPTION' | translate }}: - - {{ appointment.description }} -
-
- {{ 'PUBLIC_APPOINTMENTS.PARTICIPANTS' | translate }}: - - {{ appointment.emails }} -
-
- {{ 'FORM.LABELS.MEETING_LOCATION' | translate }}: - - {{ appointment.location || 'N/A' }} -
-
- {{ 'FORM.LABELS.DURATION' | translate }}: - {{ duration }} -
-
- -
- {{ 'PUBLIC_APPOINTMENTS.EMAIL_SENT' | translate }} -
-
- -
- {{ 'PUBLIC_APPOINTMENTS.RESCHEDULE' | translate }}: - - {{ editLink }} -
-
- -
- {{ - 'PUBLIC_APPOINTMENTS.EXPIRED_OR_CANCELLED' | translate - }} - -
-
-
- -
-
-
diff --git a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.component.ts b/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.component.ts deleted file mode 100644 index 3c1b6bc86e9..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.component.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; -import { firstValueFrom } from 'rxjs'; -import { TranslateService } from '@ngx-translate/core'; -import { NbDialogService } from '@nebular/theme'; -import * as moment from 'moment'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { IEmployee, IEmployeeAppointment } from '@gauzy/contracts'; -import { EmployeeAppointmentService, EmployeesService } from '@gauzy/ui-core/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { AlertModalComponent } from '@gauzy/ui-core/shared'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - templateUrl: './confirm-appointment.component.html' -}) -export class ConfirmAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - loading: boolean = true; - employee: IEmployee; - appointment: IEmployeeAppointment; - participants: string; - duration: string; - editLink: string; - - constructor( - private readonly route: ActivatedRoute, - private readonly router: Router, - private readonly dialogService: NbDialogService, - private readonly employeeService: EmployeesService, - private readonly employeeAppointmentService: EmployeeAppointmentService, - public readonly translateService: TranslateService - ) { - super(translateService); - } - - ngOnInit(): void { - this.route.params.pipe(untilDestroyed(this)).subscribe(async (params) => { - const appointmentId = params.appointmentId; - const employeeId = params.id; - if (employeeId && appointmentId) { - this.loadAppointment(appointmentId, employeeId); - const token = await this.employeeAppointmentService.signAppointmentId(appointmentId); - this.editLink = `/share/employee/edit-appointment?token=${token}`; - this.loading = false; - } else { - this.router.navigate(['/share/404']); - } - }); - } - - async loadAppointment(appointmentId: string, employeeId: string = '') { - this.appointment = await firstValueFrom(this.employeeAppointmentService.getById(appointmentId)); - - if (employeeId) { - this.employee = await firstValueFrom(this.employeeService.getEmployeeById(employeeId, ['user'])); - } - - this.duration = `${moment(this.appointment.startDateTime).format('llll')} - ${moment( - this.appointment.endDateTime - ).format('llll')}`; - } - - async cancelAppointment(appointmentId: string) { - const dialog = this.dialogService.open(AlertModalComponent, { - context: { - data: { - title: this.getTranslation('APPOINTMENTS_PAGE.CANCEL_APPOINTMENT'), - message: this.getTranslation('APPOINTMENTS_PAGE.ARE_YOU_SURE'), - status: 'danger' - } - } - }); - const response = await firstValueFrom(dialog.onClose); - if (!!response) { - if (response === 'yes') { - await this.employeeAppointmentService.update(appointmentId, { - status: 'Cancelled' - }); - this.loadAppointment(appointmentId); - } - } - } - - ngOnDestroy() {} -} diff --git a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.module.ts b/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.module.ts deleted file mode 100644 index 795522ad968..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NgModule } from '@angular/core'; -import { NbCardModule, NbSpinnerModule, NbButtonModule, NbIconModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { EmployeeAppointmentService, EmployeesService } from '@gauzy/ui-core/core'; -import { ConfirmAppointmentRoutingModule } from './confirm-appointment.routing.module'; -import { ConfirmAppointmentComponent } from './confirm-appointment.component'; -import { ManageAppointmentModule } from '../../../pages/employees/appointment/manage-appointment/manage-appointment.module'; -import { SharedModule } from '@gauzy/ui-core/shared'; - -@NgModule({ - imports: [ - NbButtonModule, - NbCardModule, - NbIconModule, - NbSpinnerModule, - TranslateModule.forChild(), - SharedModule, - ConfirmAppointmentRoutingModule, - ManageAppointmentModule - ], - declarations: [ConfirmAppointmentComponent], - providers: [EmployeesService, EmployeeAppointmentService] -}) -export class ConfirmAppointmentModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.routing.module.ts b/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.routing.module.ts deleted file mode 100644 index 9102ae4701d..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/confirm-appointment.routing.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { ConfirmAppointmentComponent } from './confirm-appointment.component'; -const routes: Routes = [ - { - path: '', - component: ConfirmAppointmentComponent - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class ConfirmAppointmentRoutingModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/index.ts b/apps/gauzy/src/app/share/public-appointments/confirm-appointment/index.ts deleted file mode 100644 index 6586df40260..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/confirm-appointment/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './confirm-appointment.module'; -export * from './confirm-appointment.component'; -export * from './confirm-appointment.routing.module'; diff --git a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.component.html b/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.component.html deleted file mode 100644 index cfc4b9c1daa..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.component.html +++ /dev/null @@ -1,56 +0,0 @@ - - -
-

{{ 'PUBLIC_APPOINTMENTS.PICK_DATETIME' | translate }}

-
-
- -
-
- Employee Avatar -
- - {{ employee.user.firstName }} - {{ employee.user.lastName }} -
- {{ employee.organizationPosition?.name }} -
-
- {{ employee.user.email }} -
-
-
-
-
-
- {{ 'PUBLIC_APPOINTMENTS.EVENT_TYPE' | translate }} - {{ eventType.title }} -
-
-
- {{ 'PUBLIC_APPOINTMENTS.DURATION' | translate }} - - {{ eventType.duration }} {{ eventType.durationUnit }} - -
-
- {{ eventType.description }} -
-
-
-
- -
-
-
diff --git a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.component.ts b/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.component.ts deleted file mode 100644 index fffed4612f9..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { firstValueFrom } from 'rxjs'; -import { IEmployee, IEventType } from '@gauzy/contracts'; -import { TranslateService } from '@ngx-translate/core'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { AppointmentComponent } from '../../../pages/employees/appointment/appointment.component'; -import { EmployeesService, EventTypeService } from '@gauzy/ui-core/core'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - templateUrl: './create-appointment.component.html', - styleUrls: ['../public-appointments.component.scss'] -}) -export class CreateAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - employee: IEmployee; - eventType: IEventType; - loading: boolean = true; - public appointmentFormURL: string; - - @ViewChild('appointmentCalendar') - appointmentCalendar: AppointmentComponent; - - constructor( - private readonly route: ActivatedRoute, - private readonly router: Router, - private readonly employeeService: EmployeesService, - private readonly eventTypeService: EventTypeService, - readonly translateService: TranslateService - ) { - super(translateService); - } - - ngOnInit(): void { - this.route.params.pipe(untilDestroyed(this)).subscribe(async (params) => { - try { - if (!params.id) { - return; - } - - this.employee = await firstValueFrom(this.employeeService.getEmployeeById(params.id, ['user'])); - this.eventType = await this.eventTypeService.getEventTypeById(params.eventId); - this.loading = false; - this.appointmentFormURL = `/share/employee/${params.id}/create-appointment`; - } catch (error) { - await this.router.navigate(['/share/404']); - } - }); - } - - ngOnDestroy() {} -} diff --git a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.module.ts b/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.module.ts deleted file mode 100644 index 34adefe99c3..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbButtonModule, NbCardModule, NbSpinnerModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { AvailabilitySlotsService, EventTypeService } from '@gauzy/ui-core/core'; -import { CreateAppointmentComponent } from './create-appointment.component'; -import { CreateAppointmentRoutingModule } from './create-appointment.routing.module'; -import { AppointmentModule } from '../../../pages/employees/appointment/appointment.module'; - -@NgModule({ - imports: [ - CommonModule, - NbButtonModule, - NbCardModule, - NbSpinnerModule, - TranslateModule.forChild(), - CreateAppointmentRoutingModule, - AppointmentModule - ], - declarations: [CreateAppointmentComponent], - exports: [CreateAppointmentComponent], - providers: [EventTypeService, AvailabilitySlotsService] -}) -export class CreateAppointmentModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.routing.module.ts b/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.routing.module.ts deleted file mode 100644 index 4bbf6d9e2fa..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/create-appointment/create-appointment.routing.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { CreateAppointmentComponent } from './create-appointment.component'; -const routes: Routes = [ - { - path: '', - component: CreateAppointmentComponent, - }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class CreateAppointmentRoutingModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/create-appointment/index.ts b/apps/gauzy/src/app/share/public-appointments/create-appointment/index.ts deleted file mode 100644 index a6a371eb2c7..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/create-appointment/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './create-appointment.module'; -export * from './create-appointment.component'; -export * from './create-appointment.routing.module'; diff --git a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.component.html b/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.component.html deleted file mode 100644 index 74cfdff31ff..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.component.html +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.component.ts b/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.component.ts deleted file mode 100644 index 9376bf65a4f..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Subject } from 'rxjs'; -import { Router, ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { EmployeeAppointmentService } from '@gauzy/ui-core/core'; - -@Component({ - templateUrl: './edit-appointment.component.html' -}) -export class EditAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - private _ngDestroy$ = new Subject(); - loading: boolean; - appointmentID: string; - - constructor( - private route: ActivatedRoute, - private router: Router, - private employeeAppointmentService: EmployeeAppointmentService, - readonly translateService: TranslateService - ) { - super(translateService); - } - - ngOnInit(): void { - this.route.queryParams.subscribe(async ({ token }) => { - try { - if (!token) throw new Error('token missing'); - this.appointmentID = await this.employeeAppointmentService.decodeToken(token); - } catch (error) { - await this.router.navigate(['/share/404']); - } - }); - } - - ngOnDestroy() { - this._ngDestroy$.next(); - this._ngDestroy$.complete(); - } -} diff --git a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.module.ts b/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.module.ts deleted file mode 100644 index b6c3426077f..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbCardModule, NbSpinnerModule, NbButtonModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { EmployeeAppointmentService } from '@gauzy/ui-core/core'; -import { EditAppointmentComponent } from './edit-appointment.component'; -import { EditAppointmentRoutingModule } from './edit-appointment.routing.module'; -import { ManageAppointmentModule } from '../../../pages/employees/appointment/manage-appointment/manage-appointment.module'; - -@NgModule({ - imports: [ - CommonModule, - NbButtonModule, - NbCardModule, - NbSpinnerModule, - TranslateModule.forChild(), - EditAppointmentRoutingModule, - ManageAppointmentModule - ], - declarations: [EditAppointmentComponent], - providers: [EmployeeAppointmentService] -}) -export class EditAppointmentModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.routing.module.ts b/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.routing.module.ts deleted file mode 100644 index cfce841bcff..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/edit-appointment/edit-appointment.routing.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { EditAppointmentComponent } from './edit-appointment.component'; -const routes: Routes = [ - { - path: '', - component: EditAppointmentComponent - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class EditAppointmentRoutingModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/index.ts b/apps/gauzy/src/app/share/public-appointments/index.ts deleted file mode 100644 index caf6689eb2e..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './appointment-form'; -export * from './confirm-appointment'; -export * from './create-appointment'; -export * from './edit-appointment'; -export * from './pick-employee'; -export * from './public-appointment.routing.module'; -export * from './public-appointments.component'; -export * from './public-appointments.module'; diff --git a/apps/gauzy/src/app/share/public-appointments/pick-employee/index.ts b/apps/gauzy/src/app/share/public-appointments/pick-employee/index.ts deleted file mode 100644 index c88fc724921..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/pick-employee/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './pick-employee.module'; -export * from './pick-employee.component'; -export * from './pick-employee.routing.module'; diff --git a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.html b/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.html deleted file mode 100644 index cb06cdf0514..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.html +++ /dev/null @@ -1,38 +0,0 @@ - - -
- -

- {{ 'APPOINTMENTS_PAGE.SELECT_EMPLOYEE' | translate }} -

-
-
- -
-
- -
- - - -
-
-
-
-
diff --git a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.ts b/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.ts deleted file mode 100644 index fe1d5c76f94..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; -import { Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { filter } from 'rxjs/operators'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { EventTypeService, ToastrService } from '@gauzy/ui-core/core'; -import { EmployeeSelectorComponent } from '@gauzy/ui-core/shared'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: '', - templateUrl: './pick-employee.component.html', - styleUrls: ['pick-employee.component.scss'] -}) -export class PickEmployeeComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - public loading: boolean; - public _selectedOrganizationId: string; - - @ViewChild('employeeSelector') employeeSelector: EmployeeSelectorComponent; - - constructor( - public readonly translateService: TranslateService, - private readonly router: Router, - private readonly toastrService: ToastrService, - private readonly eventTypeService: EventTypeService, - private readonly store: Store - ) { - super(translateService); - } - - ngOnInit(): void { - this.loading = true; - this.store.selectedOrganization$ - .pipe( - filter((organization) => !!organization), - untilDestroyed(this) - ) - .subscribe((org) => { - this._selectedOrganizationId = org.id; - this.loading = false; - }); - } - - async bookAppointment() { - const selectedEmployee = this.employeeSelector.selectedEmployee.id; - if (selectedEmployee) { - let { items } = await this.eventTypeService.getAll(['employee', 'employee.user', 'tags'], { - employee: { - id: selectedEmployee - }, - isActive: true - }); - - if (items.length === 0) { - const { tenantId } = this.store.user; - items = ( - await this.eventTypeService.getAll(['tags'], { - organizationId: this._selectedOrganizationId, - tenantId, - isActive: true - }) - ).items; - } - - if (items.length === 1) { - this.router.navigate([`/share/employee/${selectedEmployee}/${items[0].id}`]); - } else { - this.router.navigate([`/share/employee/${selectedEmployee}`]); - } - } else { - this.toastrService.danger(this.getTranslation('PUBLIC_APPOINTMENTS.SELECT_EMPLOYEE_ERROR')); - } - } - - ngOnDestroy() {} -} diff --git a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.module.ts b/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.module.ts deleted file mode 100644 index 743f929bb35..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { NbCardModule, NbButtonModule, NbToastrModule, NbSpinnerModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { EventTypeService } from '@gauzy/ui-core/core'; -import { SelectorsModule, SharedModule } from '@gauzy/ui-core/shared'; -import { PickEmployeeComponent } from './pick-employee.component'; -import { PickEmployeeRoutingModule } from './pick-employee.routing.module'; - -@NgModule({ - imports: [ - NbToastrModule, - NbSpinnerModule, - NbButtonModule, - NbCardModule, - TranslateModule.forChild(), - PickEmployeeRoutingModule, - SharedModule, - SelectorsModule - ], - declarations: [PickEmployeeComponent], - providers: [EventTypeService] -}) -export class PickEmployeeModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.routing.module.ts b/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.routing.module.ts deleted file mode 100644 index c7192028085..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.routing.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { PickEmployeeComponent } from './pick-employee.component'; -const routes: Routes = [ - { - path: '', - component: PickEmployeeComponent - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class PickEmployeeRoutingModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/public-appointment.routing.module.ts b/apps/gauzy/src/app/share/public-appointments/public-appointment.routing.module.ts deleted file mode 100644 index e72278fedda..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/public-appointment.routing.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { PublicAppointmentsComponent } from './public-appointments.component'; - -const routes: Routes = [ - { - path: '', - component: PublicAppointmentsComponent, - }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class PublicAppointmentRoutingModule {} diff --git a/apps/gauzy/src/app/share/public-appointments/public-appointments.component.html b/apps/gauzy/src/app/share/public-appointments/public-appointments.component.html deleted file mode 100644 index 2478852634f..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/public-appointments.component.html +++ /dev/null @@ -1,63 +0,0 @@ - - -
-

{{ 'PUBLIC_APPOINTMENTS.BOOK_APPOINTMENTS' | translate }}

-
-
- -
- Employee Avatar -
- {{ employee.user.firstName }} - {{ employee.user.lastName }} -
- {{ employee.organizationPosition?.name }} -
-
- {{ employee.user.email }} -
-
-
- -
-
{{ 'PUBLIC_APPOINTMENTS.SELECT_EVENT_TYPES' | translate }}
-
-
-
- {{ 'PUBLIC_APPOINTMENTS.NO_ACTIVE_EVENT_TYpES' | translate }} -
-
-
-
-
-
- - {{ eventType.title }} - -
-
-
- {{ 'PUBLIC_APPOINTMENTS.DURATION' | translate }} - - {{ eventType.duration }} {{ eventType.durationUnit }} - -
-
- -
-
-
-
-
diff --git a/apps/gauzy/src/app/share/public-appointments/public-appointments.component.ts b/apps/gauzy/src/app/share/public-appointments/public-appointments.component.ts deleted file mode 100644 index a9b4d49de8e..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/public-appointments.component.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; -import { IEmployee, IEventType } from '@gauzy/contracts'; -import { TranslateService } from '@ngx-translate/core'; -import { firstValueFrom } from 'rxjs'; -import { filter } from 'rxjs/operators'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; -import { EmployeesService, EventTypeService } from '@gauzy/ui-core/core'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'ga-public-appointments', - templateUrl: './public-appointments.component.html', - styleUrls: ['./public-appointments.component.scss'] -}) -export class PublicAppointmentsComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - employee: IEmployee; - eventTypes: IEventType[]; - loading = true; - _selectedOrganizationId: string; - eventTypesExist: boolean; - - constructor( - private readonly router: Router, - private readonly route: ActivatedRoute, - private readonly store: Store, - private readonly employeeService: EmployeesService, - private readonly eventTypeService: EventTypeService, - readonly translateService: TranslateService - ) { - super(translateService); - } - - ngOnInit(): void { - this.route.params.pipe(untilDestroyed(this)).subscribe(async (params) => { - try { - this.employee = await firstValueFrom(this.employeeService.getEmployeeById(params.id, ['user'])); - await this._getEventTypes(); - } catch (error) { - await this.router.navigate(['/share/404']); - } - }); - this.store.selectedOrganization$ - .pipe( - filter((organization) => !!organization), - untilDestroyed(this) - ) - .subscribe((org) => { - if (org) { - this._selectedOrganizationId = org.id; - } - }); - } - - async _getEventTypes() { - let { items } = await this.eventTypeService.getAll(['employee', 'employee.user', 'tags'], { - employee: { - id: this.employee.id - }, - isActive: true - }); - - if (items.length === 0) { - const { tenantId } = this.store.user; - items = ( - await this.eventTypeService.getAll(['tags'], { - organizationId: this._selectedOrganizationId, - tenantId, - isActive: true - }) - ).items; - } - - if (items.length === 1) { - this.router.navigate([`/share/employee/${this.employee.id}/${items[0].id}`]); - } - - if (items.length !== 0) { - this.eventTypesExist = true; - } - - const eventTypesOrder = ['Minute(s)', 'Hour(s)', 'Day(s)']; - this.eventTypes = [...items].sort((a, b) => { - if (a.duration > b.duration && a.durationUnit === b.durationUnit) { - return 1; - } else if (a.durationUnit !== b.durationUnit) { - return eventTypesOrder.indexOf(a.durationUnit) - eventTypesOrder.indexOf(b.durationUnit); - } - - return -1; - }); - this.loading = false; - } - - selectEventType(id) { - this.router.navigate([`${this.router.url}/${id}`]); - } - - ngOnDestroy() {} -} diff --git a/apps/gauzy/src/app/share/public-appointments/public-appointments.module.ts b/apps/gauzy/src/app/share/public-appointments/public-appointments.module.ts deleted file mode 100644 index d1e078a4304..00000000000 --- a/apps/gauzy/src/app/share/public-appointments/public-appointments.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbButtonModule, NbCardModule, NbSpinnerModule } from '@nebular/theme'; -import { EventTypeService } from '@gauzy/ui-core/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { PublicAppointmentsComponent } from './public-appointments.component'; -import { PublicAppointmentRoutingModule } from './public-appointment.routing.module'; -import { CreateAppointmentModule } from './create-appointment/create-appointment.module'; -import { AppointmentModule } from '../../pages/employees/appointment/appointment.module'; - -@NgModule({ - imports: [ - CommonModule, - PublicAppointmentRoutingModule, - NbButtonModule, - NbCardModule, - NbSpinnerModule, - TranslateModule.forChild(), - AppointmentModule, - CreateAppointmentModule - ], - declarations: [PublicAppointmentsComponent], - exports: [PublicAppointmentsComponent], - providers: [EventTypeService] -}) -export class PublicAppointmentsModule {} diff --git a/apps/gauzy/src/app/share/share-routing.module.ts b/apps/gauzy/src/app/share/share-routing.module.ts deleted file mode 100644 index 6a7c7bb9d1e..00000000000 --- a/apps/gauzy/src/app/share/share-routing.module.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { RouterModule, Routes } from '@angular/router'; -import { NgModule } from '@angular/core'; - -import { ShareComponent } from './share.component'; -import { NotFoundComponent } from '../pages/miscellaneous/not-found/not-found.component'; - -const routes: Routes = [ - { - path: '', - component: ShareComponent, - children: [ - { - path: '', - redirectTo: 'organization', - pathMatch: 'full' - }, - { - path: 'organization/:profileLink/:organizationId', - loadChildren: () => import('./organization/organization.module').then( - (m) => m.OrganizationModule - ) - }, - { - path: 'employee/edit-appointment', - loadChildren: () => - import( - './public-appointments/edit-appointment/edit-appointment.module' - ).then((m) => m.EditAppointmentModule) - }, - { - path: 'employee', - loadChildren: () => - import( - './public-appointments/pick-employee/pick-employee.module' - ).then((m) => m.PickEmployeeModule) - }, - { - path: 'employee/:id', - loadChildren: () => - import( - './public-appointments/public-appointments.module' - ).then((m) => m.PublicAppointmentsModule) - }, - { - path: 'employee/:id/confirm/:appointmentId', - loadChildren: () => - import( - './public-appointments/confirm-appointment/confirm-appointment.module' - ).then((m) => m.ConfirmAppointmentModule) - }, - { - path: 'employee/:employeeId/create-appointment', - loadChildren: () => - import( - './public-appointments/appointment-form/appointment-form.module' - ).then((m) => m.AppointmentFormModule) - }, - { - path: 'employee/:id/:eventId', - loadChildren: () => - import( - './public-appointments/create-appointment/create-appointment.module' - ).then((m) => m.CreateAppointmentModule) - }, - { - path: 'invoices/:id/:token', - loadChildren: () => - import('./invoices-estimates/invoice-estimate.module').then( - (m) => m.InvoiceEstimateModule - ) - }, - { - path: 'estimates/:id/:token', - loadChildren: () => - import('./invoices-estimates/invoice-estimate.module').then( - (m) => m.InvoiceEstimateModule - ) - }, - { - path: '**', - component: NotFoundComponent - } - ] - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class ShareRoutingModule { } diff --git a/apps/gauzy/src/app/share/share.component.ts b/apps/gauzy/src/app/share/share.component.ts deleted file mode 100644 index 4252d595ed7..00000000000 --- a/apps/gauzy/src/app/share/share.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslateService } from '@ngx-translate/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; - -@UntilDestroy({ checkProperties: true }) -@Component({ - selector: 'ngx-share', - template: ` - - - - ` -}) -export class ShareComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - constructor(public translate: TranslateService) { - super(translate); - } - - ngOnInit() { - this._applyTranslationOnSmartTable(); - } - - private _applyTranslationOnSmartTable() { - this.translate.onLangChange.pipe(untilDestroyed(this)).subscribe(); - } - - ngOnDestroy() {} -} diff --git a/apps/gauzy/src/app/share/share.module.ts b/apps/gauzy/src/app/share/share.module.ts deleted file mode 100644 index 32034aff704..00000000000 --- a/apps/gauzy/src/app/share/share.module.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NbMenuModule, NbSpinnerModule, NbToastrModule } from '@nebular/theme'; -import { TranslateModule } from '@ngx-translate/core'; -import { AuthService, RoleGuard } from '@gauzy/ui-core/core'; -import { ThemeModule } from '@gauzy/ui-core/theme'; -import { ShareComponent } from './share.component'; -import { ShareRoutingModule } from './share-routing.module'; -import { MiscellaneousModule } from '../pages/miscellaneous/miscellaneous.module'; - -@NgModule({ - imports: [ - CommonModule, - NbMenuModule, - NbSpinnerModule, - NbToastrModule.forRoot(), - TranslateModule.forChild(), - ShareRoutingModule, - MiscellaneousModule, - ThemeModule - ], - declarations: [ShareComponent], - providers: [AuthService, RoleGuard] -}) -export class ShareModule {} diff --git a/apps/server-api/package.json b/apps/server-api/package.json index 77597c61192..96f790cfe21 100644 --- a/apps/server-api/package.json +++ b/apps/server-api/package.json @@ -42,7 +42,6 @@ "@electron/remote": "^2.0.8", "@gauzy/desktop-ui-lib": "^0.1.0", "@gauzy/ui-config": "^0.1.0", - "@gauzy/ui-core": "^0.1.0", "@grpc/grpc-js": "^1.6.7", "@nebular/auth": "^12.0.0", "@nebular/bootstrap": "^9.1.0-rc.6", diff --git a/apps/server-api/src/app/app.module.ts b/apps/server-api/src/app/app.module.ts index b2482d55da6..11d298c4d03 100644 --- a/apps/server-api/src/app/app.module.ts +++ b/apps/server-api/src/app/app.module.ts @@ -12,7 +12,8 @@ import { ServerDashboardModule, SettingsModule, SetupModule, - UpdaterModule + UpdaterModule, + NgxDesktopThemeModule } from '@gauzy/desktop-ui-lib'; import { environment as gauzyEnvironment } from '@gauzy/ui-config'; import { @@ -54,7 +55,8 @@ if (environment.SENTRY_DSN) { BrowserAnimationsModule, RouterModule, AppRoutingModule, - NbThemeModule.forRoot({ name: 'gauzy-light' }), + NbThemeModule, + NgxDesktopThemeModule, NbMenuModule.forRoot(), NbSidebarModule.forRoot(), SetupModule, @@ -83,7 +85,7 @@ if (environment.SENTRY_DSN) { }, { provide: APP_INITIALIZER, - useFactory: () => () => {}, + useFactory: () => () => { }, deps: [Sentry.TraceService], multi: true }, @@ -98,5 +100,5 @@ if (environment.SENTRY_DSN) { bootstrap: [AppComponent] }) export class AppModule { - constructor() {} + constructor() { } } diff --git a/apps/server-api/src/assets/styles/styles.scss b/apps/server-api/src/assets/styles/styles.scss index 597268f5f6c..6905349095e 100644 --- a/apps/server-api/src/assets/styles/styles.scss +++ b/apps/server-api/src/assets/styles/styles.scss @@ -55,3 +55,7 @@ @include material-overrides(); @include gauzy-overrides(); } + +::-webkit-scrollbar { + display: none; +} diff --git a/apps/server-api/src/index.ts b/apps/server-api/src/index.ts index 3dc53c01ea9..f2ee9436946 100644 --- a/apps/server-api/src/index.ts +++ b/apps/server-api/src/index.ts @@ -15,7 +15,8 @@ import { Menu, shell, MenuItemConstructorOptions, - screen + screen, + nativeTheme } from 'electron'; import { environment } from './environments/environment'; @@ -50,7 +51,8 @@ import { DialogErrorHandler, AppError, DialogOpenFile, - ReverseUiProxy + ReverseUiProxy, + DesktopThemeListener } from '@gauzy/desktop-libs'; import { createSetupWindow, @@ -150,6 +152,18 @@ ipcMain.setMaxListeners(0); /* Remove handler if exist */ ipcMain.removeHandler('PREFERRED_LANGUAGE'); +ipcMain.handle('PREFERRED_THEME', () => { + const applicationSetting = LocalStore.getStore('appSetting'); + let theme: string; + if (!applicationSetting || !applicationSetting.theme) { + theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light'; + LocalStore.updateApplicationSetting({ theme }); + } else { + theme = applicationSetting.theme; + } + return theme; +}); + // setup logger to catch all unhandled errors and submit as bug reports to our repo log.catchErrors({ showDialog: false, @@ -263,6 +277,12 @@ const runMainWindow = async () => { serverWindow.webContents.send('dashboard_ready', { setting: serverConfig.setting }); + + new DesktopThemeListener({ + settingsWindow, + splashScreenWindow: splashScreen.browserWindow, + serverWindow + }).listen(); }; const initializeConfig = async (val) => { diff --git a/apps/server/src/app/app.module.ts b/apps/server/src/app/app.module.ts index b2482d55da6..11d298c4d03 100644 --- a/apps/server/src/app/app.module.ts +++ b/apps/server/src/app/app.module.ts @@ -12,7 +12,8 @@ import { ServerDashboardModule, SettingsModule, SetupModule, - UpdaterModule + UpdaterModule, + NgxDesktopThemeModule } from '@gauzy/desktop-ui-lib'; import { environment as gauzyEnvironment } from '@gauzy/ui-config'; import { @@ -54,7 +55,8 @@ if (environment.SENTRY_DSN) { BrowserAnimationsModule, RouterModule, AppRoutingModule, - NbThemeModule.forRoot({ name: 'gauzy-light' }), + NbThemeModule, + NgxDesktopThemeModule, NbMenuModule.forRoot(), NbSidebarModule.forRoot(), SetupModule, @@ -83,7 +85,7 @@ if (environment.SENTRY_DSN) { }, { provide: APP_INITIALIZER, - useFactory: () => () => {}, + useFactory: () => () => { }, deps: [Sentry.TraceService], multi: true }, @@ -98,5 +100,5 @@ if (environment.SENTRY_DSN) { bootstrap: [AppComponent] }) export class AppModule { - constructor() {} + constructor() { } } diff --git a/apps/server/src/assets/styles/styles.scss b/apps/server/src/assets/styles/styles.scss index 597268f5f6c..6905349095e 100644 --- a/apps/server/src/assets/styles/styles.scss +++ b/apps/server/src/assets/styles/styles.scss @@ -55,3 +55,7 @@ @include material-overrides(); @include gauzy-overrides(); } + +::-webkit-scrollbar { + display: none; +} diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index fa93a0323b5..e4bca782af5 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -15,7 +15,8 @@ import { Menu, shell, MenuItemConstructorOptions, - screen + screen, + nativeTheme } from 'electron'; import { environment } from './environments/environment'; @@ -51,7 +52,8 @@ import { DialogErrorHandler, AppError, DialogOpenFile, - ReverseUiProxy + ReverseUiProxy, + DesktopThemeListener } from '@gauzy/desktop-libs'; import { createSetupWindow, @@ -156,6 +158,18 @@ ipcMain.setMaxListeners(0); /* Remove handler if exist */ ipcMain.removeHandler('PREFERRED_LANGUAGE'); +ipcMain.handle('PREFERRED_THEME', () => { + const applicationSetting = LocalStore.getStore('appSetting'); + let theme: string; + if (!applicationSetting || !applicationSetting.theme) { + theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light'; + LocalStore.updateApplicationSetting({ theme }); + } else { + theme = applicationSetting.theme; + } + return theme; +}); + // setup logger to catch all unhandled errors and submit as bug reports to our repo log.catchErrors({ showDialog: false, @@ -269,6 +283,12 @@ const runMainWindow = async () => { serverWindow.webContents.send('dashboard_ready', { setting: serverConfig.setting }); + + new DesktopThemeListener({ + settingsWindow, + splashScreenWindow: splashScreen.browserWindow, + serverWindow + }).listen(); }; const initializeConfig = async (val) => { diff --git a/apps/server/src/package.json b/apps/server/src/package.json index a052bd7bd04..33b18c7e3ff 100755 --- a/apps/server/src/package.json +++ b/apps/server/src/package.json @@ -46,7 +46,11 @@ "../../../packages/plugins/job-employee-ui", "../../../packages/plugins/job-matching-ui", "../../../packages/plugins/job-proposal-ui", - "../../../packages/plugins/job-search-ui" + "../../../packages/plugins/job-search-ui", + "../../../packages/plugins/legal-ui", + "../../../packages/plugins/maintenance-ui", + "../../../packages/plugins/onboarding-ui", + "../../../packages/plugins/public-layout-ui" ] }, "build": { diff --git a/package.json b/package.json index 1bc87b8f4e6..e0c97b57109 100644 --- a/package.json +++ b/package.json @@ -137,8 +137,8 @@ "build:package:config:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/config build:prod", "build:package:plugin": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugin build", "build:package:plugin:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugin build", - "build:package:plugins:pre": "yarn run build:package:ui-config && yarn run build:package:ui-core && yarn run build:package:ui-auth && yarn run build:package:plugin:job-search-ui && yarn run build:package:plugin:job-matching-ui && yarn run build:package:plugin:job-employee-ui && yarn run build:package:plugin:job-proposal-ui", - "build:package:plugins:pre:prod": "yarn run build:package:ui-config:prod && yarn run build:package:ui-core:prod && yarn run build:package:ui-auth && yarn run build:package:plugin:job-search-ui:prod && yarn run build:package:plugin:job-matching-ui:prod && yarn run build:package:plugin:job-employee-ui:prod && yarn run build:package:plugin:job-proposal-ui:prod", + "build:package:plugins:pre": "yarn run build:package:ui-config && yarn run build:package:ui-core && yarn run build:package:ui-auth && yarn run build:package:plugin:onboarding-ui && yarn run build:package:plugin:legal-ui && yarn run build:package:plugin:job-search-ui && yarn run build:package:plugin:job-matching-ui && yarn run build:package:plugin:job-employee-ui && yarn run build:package:plugin:job-proposal-ui && yarn run build:package:plugin:public-layout-ui && yarn run build:package:plugin:maintenance-ui", + "build:package:plugins:pre:prod": "yarn run build:package:ui-config:prod && yarn run build:package:ui-core:prod && yarn run build:package:ui-auth && yarn run build:package:plugin:onboarding-ui:prod && yarn run build:package:plugin:legal-ui:prod && yarn run build:package:plugin:job-search-ui:prod && yarn run build:package:plugin:job-matching-ui:prod && yarn run build:package:plugin:job-employee-ui:prod && yarn run build:package:plugin:job-proposal-ui:prod && yarn run build:package:plugin:public-layout-ui:prod && yarn run build:package:plugin:maintenance-ui:prod", "build:package:plugins:post": "yarn run build:package:plugin:integration-jira && yarn run build:package:plugin:integration-ai && yarn run build:package:plugin:sentry && yarn run build:package:plugin:jitsu-analytic && yarn run build:package:plugin:product-reviews && yarn run build:package:plugin:job-search && yarn run build:package:plugin:job-proposal && yarn run build:package:plugin:integration-github && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog && yarn run build:package:plugin:integration-hubstaff && yarn run build:package:plugin:integration-upwork", "build:package:plugins:post:prod": "yarn run build:package:plugin:integration-jira:prod && yarn run build:package:plugin:integration-ai:prod && yarn run build:package:plugin:sentry:prod && yarn run build:package:plugin:jitsu-analytic:prod && yarn run build:package:plugin:product-reviews:prod && yarn run build:package:plugin:job-search:prod && yarn run build:package:plugin:job-proposal:prod && yarn run build:package:plugin:integration-github:prod && yarn run build:package:plugin:knowledge-base:prod && yarn run build:package:plugin:changelog:prod && yarn run build:package:plugin:integration-hubstaff:prod && yarn run build:package:plugin:integration-upwork:prod", "build:package:plugin:integration-ai": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/integration-ai build", @@ -167,6 +167,14 @@ "build:package:plugin:job-proposal-ui:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/job-proposal-ui lib:build:prod", "build:package:plugin:job-search-ui": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/job-search-ui lib:build", "build:package:plugin:job-search-ui:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/job-search-ui lib:build:prod", + "build:package:plugin:legal-ui": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/legal-ui lib:build", + "build:package:plugin:legal-ui:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/legal-ui lib:build:prod", + "build:package:plugin:maintenance-ui": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/maintenance-ui lib:build", + "build:package:plugin:maintenance-ui:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/maintenance-ui lib:build:prod", + "build:package:plugin:onboarding-ui": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/onboarding-ui lib:build", + "build:package:plugin:onboarding-ui:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/onboarding-ui lib:build:prod", + "build:package:plugin:public-layout-ui": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/public-layout-ui lib:build", + "build:package:plugin:public-layout-ui:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/public-layout-ui lib:build:prod", "build:package:plugin:job-proposal": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/job-proposal build", "build:package:plugin:job-proposal:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/job-proposal build:prod", "build:package:plugin:knowledge-base": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/plugins/knowledge-base build", @@ -182,7 +190,7 @@ "build:package:api:prod": "yarn run build:package:contracts:prod && yarn run build:package:common:prod && yarn run build:package:config:prod && yarn run build:package:plugin:prod && yarn run build:package:auth:prod && yarn run build:package:plugins:pre:prod && yarn run build:package:core:prod && yarn run build:package:plugins:post:prod", "build:package:gauzy": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:common-angular && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:auth && yarn run build:package:plugins:pre && yarn run build:package:core && yarn run build:package:plugins:post", "build:package:desktop-ui-lib": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn --cwd ./packages/desktop-ui-lib build", - "copy-files-desktop": "copyfiles -f packages/core/src/**/*.gql dist/apps/desktop/data/", + "copy-files-desktop": "copyfiles -f packages/core/src/**/*.gql dist/apps/desktop/data/", "build:desktop-timer": "cross-env NODE_ENV=production yarn copy-files-i18n-desktop-timer && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:desktop-timer:prod && yarn run pack:desktop-timer && yarn run generate:icons:desktop-timer --environment=prod && yarn ng:prod build desktop-timer --prod --base-href ./ && yarn run prepare:desktop-timer && yarn ng:prod build api-desktop --prod --output-path=dist/apps/desktop-timer/desktop-api && yarn run copy-assets-gauzy-timer", "prepare:desktop-timer": "yarn run postinstall.electron && tsc -p apps/desktop-timer/tsconfig.json", "build:desktop-timer:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/desktop-timer", @@ -193,15 +201,15 @@ "build:desktop-timer:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer", "build:desktop-timer:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer", "build:desktop-timer:mac:release": "yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/desktop-timer", - "copy-assets-gauzy": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop/data/sound/", - "copy-assets-gauzy-timer": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop-timer/data/sound/", + "copy-assets-gauzy": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop/data/sound/", + "copy-assets-gauzy-timer": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop-timer/data/sound/", "config:electron": "yarn ts-node ./.scripts/electron.env.ts", "config:server:prod": "yarn run config:electron -- --environment=prod --desktop=server", "config:desktop:prod": "yarn run config:electron -- --environment=prod --desktop=desktop", "config:desktop-timer:prod": "yarn run config:electron -- --environment=prod --desktop=desktop-timer", "prepare:gauzy-server": "yarn run postinstall.electron && tsc -p apps/server/tsconfig.json", "build:gauzy-server": "cross-env NODE_ENV=production yarn run copy-files-i18n-server && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:server:prod && yarn run pack:server && yarn run generate:icons:server --environment=prod && yarn ng:prod build gauzy-server --prod --base-href ./ && yarn run prepare:gauzy-server && yarn ng:prod build gauzy-server-ui --prod --base-href ./ && yarn ng:prod build gauzy-server-api --prod && yarn run copy-files-gauzy-server", - "copy-files-gauzy-server": "copyfiles -f packages/core/src/**/*.gql dist/apps/gauzy-server/data/", + "copy-files-gauzy-server": "copyfiles -f packages/core/src/**/*.gql dist/apps/gauzy-server/data/", "build:gauzy-server:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/gauzy-server", "build:gauzy-server:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/gauzy-server", "build:gauzy-server:mac": "yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/gauzy-server", @@ -226,7 +234,7 @@ "config:api-server:prod": "yarn run config:electron -- --environment=prod --desktop=server-api", "prepare:gauzy-api-server": "yarn run postinstall.electron && tsc -p apps/server-api/tsconfig.json", "build:gauzy-api-server": "cross-env NODE_ENV=production yarn run copy-files-i18n-api-server && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:api-server:prod && yarn run pack:api-server && yarn run generate:icons:server-api --environment=prod && yarn ng:prod build gauzy-api-server --prod --base-href ./ && yarn run prepare:gauzy-api-server && yarn ng:prod build server-api --prod && yarn run copy-files-gauzy-api-server", - "copy-files-gauzy-api-server": "copyfiles -f packages/core/src/**/*.gql dist/apps/gauzy-api-server/data/", + "copy-files-gauzy-api-server": "copyfiles -f packages/core/src/**/*.gql dist/apps/gauzy-api-server/data/", "build:gauzy-api-server:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run config:prod && yarn run build:gauzy-api-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/gauzy-api-server", "build:gauzy-api-server:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run config:prod && yarn run build:gauzy-api-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/gauzy-api-server", "build:gauzy-api-server:mac": "yarn run build:gauzy-api-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/gauzy-api-server", diff --git a/packages/auth/package.json b/packages/auth/package.json index 4acb5ad92e8..11edb56b088 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,7 +1,7 @@ { "name": "@gauzy/auth", "version": "0.1.0", - "description": "Ever Gauzy Platform Auth module", + "description": "Authentication module for the Ever Gauzy Platform, providing various authentication strategies and integrations.", "author": { "name": "Ever Co. LTD", "email": "ever@ever.co", @@ -25,7 +25,16 @@ "build:prod": "rimraf dist && yarn run compile", "compile": "tsc -p tsconfig.build.json" }, - "keywords": [], + "keywords": [ + "auth", + "authentication", + "authorization", + "gauzy", + "nestjs", + "oauth", + "jwt", + "passport" + ], "dependencies": { "@gauzy/common": "^0.1.0", "@gauzy/config": "^0.1.0", diff --git a/packages/contracts/src/daily-plan.model.ts b/packages/contracts/src/daily-plan.model.ts index 1eba808d810..64b1275583e 100644 --- a/packages/contracts/src/daily-plan.model.ts +++ b/packages/contracts/src/daily-plan.model.ts @@ -1,4 +1,5 @@ -import { IBasePerTenantAndOrganizationEntityModel } from './base-entity.model'; +import { IRelationalOrganizationTeam } from './organization-team.model'; +import { IBasePerTenantAndOrganizationEntityModel, IBaseRelationsEntityModel, ID } from './base-entity.model'; import { IRelationalEmployee } from './employee.model'; import { ITask } from './task.model'; @@ -14,15 +15,22 @@ export interface IDailyPlanBase extends IBasePerTenantAndOrganizationEntityModel status: DailyPlanStatusEnum; } -export interface IDailyPlan extends IDailyPlanBase, IRelationalEmployee { +export interface IDailyPlan extends IDailyPlanBase, IRelationalEmployee, IRelationalOrganizationTeam { tasks?: ITask[]; } -export interface IDailyPlanCreateInput extends IDailyPlanBase, IRelationalEmployee { - taskId?: ITask['id']; +export interface IDailyPlanCreateInput extends IDailyPlanBase, IRelationalEmployee, IRelationalOrganizationTeam { + taskId?: ID; } -export interface IDailyPlanUpdateInput extends Partial, Pick {} +export interface IDailyPlanUpdateInput + extends Partial, + Pick, + Partial> {} + +export interface IGetDailyPlansByTeamInput extends IBaseRelationsEntityModel, IBasePerTenantAndOrganizationEntityModel { + teamIds?: ID[]; +} export interface IDailyPlanTasksUpdateInput extends Pick, @@ -32,5 +40,5 @@ export interface IDailyPlanTasksUpdateInput export interface IDailyPlansTasksUpdateInput extends Pick, IBasePerTenantAndOrganizationEntityModel { - plansIds: IDailyPlan['id'][]; + plansIds: ID[]; } diff --git a/packages/contracts/src/employee-appointment.model.ts b/packages/contracts/src/employee-appointment.model.ts index 7c9be8647cb..3a5aa623e95 100644 --- a/packages/contracts/src/employee-appointment.model.ts +++ b/packages/contracts/src/employee-appointment.model.ts @@ -3,8 +3,16 @@ import { IAppointmentEmployee } from './appointment-employees.model'; import { IEmployee, IEmployeeFindInput } from './employee.model'; import { IOrganizationFindInput } from './organization.model'; -export interface IEmployeeAppointment - extends IBasePerTenantAndOrganizationEntityModel { +/** + * Employee appointment status. + */ +export enum EmployeeAppointmentStatus { + SCHEDULED = 'Scheduled', + CANCELLED = 'Cancelled', + COMPLETED = 'Completed' +} + +export interface IEmployeeAppointment extends IBasePerTenantAndOrganizationEntityModel { employee?: IEmployee; employeeId?: string; description?: string; @@ -19,18 +27,17 @@ export interface IEmployeeAppointment breakStartTime?: Date; invitees?: IAppointmentEmployee[]; emails?: string; - status?: string; + status?: EmployeeAppointmentStatus; } export interface IEmployeeAppointmentFindInput { employee?: IEmployeeFindInput; employeeId?: string; - status?: string; + status?: EmployeeAppointmentStatus; organization?: IOrganizationFindInput; } -export interface IEmployeeAppointmentCreateInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface IEmployeeAppointmentCreateInput extends IBasePerTenantAndOrganizationEntityModel { employeeId?: string; description?: string; location?: string; @@ -46,8 +53,7 @@ export interface IEmployeeAppointmentCreateInput invitees?: IAppointmentEmployee[]; } -export interface IEmployeeAppointmentUpdateInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface IEmployeeAppointmentUpdateInput extends IBasePerTenantAndOrganizationEntityModel { employeeId?: string; description?: string; location?: string; @@ -59,6 +65,6 @@ export interface IEmployeeAppointmentUpdateInput bufferTimeInMins?: Number; breakTimeInMins?: Number; breakStartTime?: Date; - status?: string; + status?: EmployeeAppointmentStatus; invitees?: IAppointmentEmployee[]; } diff --git a/packages/contracts/src/employee.model.ts b/packages/contracts/src/employee.model.ts index 75577d50a65..671bf33ebe0 100644 --- a/packages/contracts/src/employee.model.ts +++ b/packages/contracts/src/employee.model.ts @@ -29,13 +29,13 @@ export interface IFindMembersInput extends IBasePerTenantAndOrganizationEntityMo } export interface IEmployeeEntityMutationInput { - employeeId?: IEmployee['id']; + employeeId?: ID; employee?: Pick; } export interface IRelationalEmployee { readonly employee?: IEmployee; - readonly employeeId?: IEmployee['id']; + readonly employeeId?: ID; } export interface IEmployee extends IBasePerTenantAndOrganizationEntityModel { diff --git a/packages/contracts/src/organization-contact.model.ts b/packages/contracts/src/organization-contact.model.ts index a8f5a058496..7abc59ee1bf 100644 --- a/packages/contracts/src/organization-contact.model.ts +++ b/packages/contracts/src/organization-contact.model.ts @@ -5,18 +5,22 @@ import { IOrganizationCreateInput } from './organization.model'; import { IUser, LanguagesEnum } from './user.model'; import { ITag } from './tag.model'; import { IContact, IContactCreateInput } from './contact.model'; -import { IBasePerTenantAndOrganizationEntityModel, IBasePerTenantAndOrganizationEntityMutationInput } from './base-entity.model'; +import { + IBasePerTenantAndOrganizationEntityModel, + IBasePerTenantAndOrganizationEntityMutationInput, + ID +} from './base-entity.model'; import { ITimeLog } from './timesheet.model'; import { IRelationalImageAsset } from './image-asset.model'; export interface IOrganizationContactEntityMutationInput { - organizationContactId?: IOrganizationContact['id']; + organizationContactId?: ID; organizationContact?: Pick; } export interface IRelationalOrganizationContact { organizationContact?: IOrganizationContact; - organizationContactId?: IOrganizationContact['id']; + organizationContactId?: ID; } export interface IOrganizationContact extends IBaseEntityWithMembers, IRelationalImageAsset { @@ -43,8 +47,7 @@ export enum OrganizationContactBudgetTypeEnum { COST = 'cost' } -export interface IOrganizationContactFindInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface IOrganizationContactFindInput extends IBasePerTenantAndOrganizationEntityModel { name?: string; primaryEmail?: string; primaryPhone?: string; @@ -54,7 +57,10 @@ export interface IOrganizationContactFindInput createdBy?: string; } -export interface IOrganizationContactCreateInput extends IContactCreateInput, IBasePerTenantAndOrganizationEntityMutationInput, IRelationalImageAsset { +export interface IOrganizationContactCreateInput + extends IContactCreateInput, + IBasePerTenantAndOrganizationEntityMutationInput, + IRelationalImageAsset { name: string; primaryEmail?: string; primaryPhone?: string; diff --git a/packages/contracts/src/proposal.model.ts b/packages/contracts/src/proposal.model.ts index ea3f4821db5..39424a43de5 100644 --- a/packages/contracts/src/proposal.model.ts +++ b/packages/contracts/src/proposal.model.ts @@ -1,53 +1,53 @@ import { IOrganizationContactEntityMutationInput, IRelationalOrganizationContact } from './organization-contact.model'; import { IBasePerTenantAndOrganizationEntityModel } from './base-entity.model'; -import { IEmployee, IEmployeeEntityMutationInput, IEmployeeFindInput } from './employee.model'; -import { ITag } from './tag.model'; +import { IEmployee, IEmployeeEntityMutationInput, IRelationalEmployee } from './employee.model'; +import { ITaggable } from './tag.model'; -export interface IProposal extends IBasePerTenantAndOrganizationEntityModel, IRelationalOrganizationContact { - employeeId?: string; - employee?: IEmployee; - jobPostUrl: string; - valueDate?: Date; - jobPostContent?: string; - proposalContent?: string; - status?: ProposalStatusEnum; - tags?: ITag[]; +/** + * Proposal Status Enum + */ +export enum ProposalStatusEnum { + SENT = 'SENT', + ACCEPTED = 'ACCEPTED' } -export interface IProposalCreateInput extends IBasePerTenantAndOrganizationEntityModel, IEmployeeEntityMutationInput, IOrganizationContactEntityMutationInput { - jobPostUrl?: string; +// Base interface for common proposal fields +export interface IProposalBase extends IBasePerTenantAndOrganizationEntityModel, ITaggable { + jobPostUrl: string; valueDate?: Date; jobPostContent?: string; proposalContent?: string; status?: ProposalStatusEnum; - tags?: ITag[]; } -export interface IProposalFindInput extends IBasePerTenantAndOrganizationEntityModel { - employeeId?: string; - employee?: IEmployeeFindInput; - jobPostUrl?: string; - valueDate?: Date; - jobPostContent?: string; - proposalContent?: string; - status?: ProposalStatusEnum; - tags?: ITag[]; +export interface IProposal extends IProposalBase, IRelationalEmployee, IRelationalOrganizationContact { + author?: IEmployee; } -export enum ProposalStatusEnum { - SENT = 'SENT', - ACCEPTED = 'ACCEPTED' -} -export interface IProposalViewModel extends IBasePerTenantAndOrganizationEntityModel, IRelationalOrganizationContact { - tags?: ITag[]; +/** + * Proposal Base Create Input + */ +export interface IProposalBaseCreateInput extends IEmployeeEntityMutationInput, Partial {} + +/** + * Proposal Create Input + */ +export interface IProposalCreateInput extends IProposalBaseCreateInput, IOrganizationContactEntityMutationInput {} + +/** + * Proposal Find Input + */ +export interface IProposalFindInput + extends Omit {} + +/** + * Proposal View Model + */ +export interface IProposalViewModel extends IRelationalOrganizationContact, Partial { valueDate: Date; id: string; employeeId?: string; employee?: IEmployee; - jobPostUrl?: string; jobPostLink?: string; - jobPostContent?: string; - proposalContent?: string; - status?: ProposalStatusEnum; - author?: string; + author?: IEmployee; } diff --git a/packages/contracts/src/tag.model.ts b/packages/contracts/src/tag.model.ts index b2c8069190d..ae8d55dba64 100644 --- a/packages/contracts/src/tag.model.ts +++ b/packages/contracts/src/tag.model.ts @@ -1,6 +1,10 @@ import { IRelationalOrganizationTeam } from './organization-team.model'; import { IBasePerTenantAndOrganizationEntityModel } from './base-entity.model'; +export interface ITaggable { + tags?: ITag[]; +} + export interface ITag extends IBasePerTenantAndOrganizationEntityModel, IRelationalOrganizationTeam { name: string; color: string; @@ -18,7 +22,7 @@ export interface ITagFindInput extends IBasePerTenantAndOrganizationEntityModel, isSystem?: boolean; } -export interface ITagCreateInput extends ITag { } +export interface ITagCreateInput extends ITag {} export interface ITagUpdateInput extends Partial { id?: string; diff --git a/packages/contracts/src/task-status.model.ts b/packages/contracts/src/task-status.model.ts index 9dc0279a9fe..0c59e71b0d8 100644 --- a/packages/contracts/src/task-status.model.ts +++ b/packages/contracts/src/task-status.model.ts @@ -1,8 +1,12 @@ -import { IBasePerTenantAndOrganizationEntityModel } from './base-entity.model'; -import { IOrganizationProject } from './organization-projects.model'; +import { IBasePerTenantAndOrganizationEntityModel, ID } from './base-entity.model'; +import { IRelationalOrganizationProject } from './organization-projects.model'; import { IRelationalOrganizationTeam } from './organization-team.model'; -export interface ITaskStatus extends IBasePerTenantAndOrganizationEntityModel, IRelationalOrganizationTeam { +export interface ITaskStatus + extends IBasePerTenantAndOrganizationEntityModel, + IRelationalOrganizationTeam, + IRelationalOrganizationProject, + TaskStatusWorkFlow { name: string; value: string; description?: string; @@ -12,37 +16,45 @@ export interface ITaskStatus extends IBasePerTenantAndOrganizationEntityModel, I isSystem?: boolean; isCollapsed?: boolean; fullIconUrl?: string; - project?: IOrganizationProject; - projectId?: IOrganizationProject['id']; + template?: TaskStatusEnum; +} + +export interface TaskStatusWorkFlow { + isTodo?: boolean; + isInProgress?: boolean; + isDone?: boolean; } -export interface ITaskStatusCreateInput extends Omit, Omit { } +export interface ITaskStatusCreateInput extends Omit, Omit {} export interface ITaskStatusUpdateInput extends Partial { - id?: string; + id?: ID; } export interface ITaskStatusFindInput extends IBasePerTenantAndOrganizationEntityModel, - Pick { } + Pick {} /** * Default task statuses */ export enum TaskStatusEnum { + BACKLOG = 'backlog', OPEN = 'open', IN_PROGRESS = 'in-progress', READY_FOR_REVIEW = 'ready-for-review', IN_REVIEW = 'in-review', BLOCKED = 'blocked', - COMPLETED = 'completed' + DONE = 'done', + COMPLETED = 'completed', + CUSTOM = 'custom' } /** * Interface for individual reorder request item. */ export interface IReorderDTO extends IBasePerTenantAndOrganizationEntityModel { - id: string; // Either a UUID type or a string that follows UUID pattern + id: ID; // Either a UUID type or a string that follows UUID pattern order: number; // New order for the record. } diff --git a/packages/core/src/core/dto/tenant-base.dto.ts b/packages/core/src/core/dto/tenant-base.dto.ts index 13f8bf8adc2..d9bfbb8c47b 100644 --- a/packages/core/src/core/dto/tenant-base.dto.ts +++ b/packages/core/src/core/dto/tenant-base.dto.ts @@ -1,10 +1,9 @@ import { ApiPropertyOptional } from '@nestjs/swagger'; import { IsObject, IsOptional, IsUUID } from 'class-validator'; -import { IBasePerTenantEntityModel, ITenant } from '@gauzy/contracts'; +import { IBasePerTenantEntityModel, ID, ITenant } from '@gauzy/contracts'; import { IsTenantBelongsToUser } from './../../shared/validators'; export class TenantBaseDTO implements IBasePerTenantEntityModel { - @ApiPropertyOptional({ type: () => Object }) @IsOptional() @IsObject() @@ -15,5 +14,5 @@ export class TenantBaseDTO implements IBasePerTenantEntityModel { @IsOptional() @IsUUID() @IsTenantBelongsToUser() - readonly tenantId: ITenant['id']; + readonly tenantId: ID; } diff --git a/packages/core/src/core/dto/tenant-organization-base.dto.ts b/packages/core/src/core/dto/tenant-organization-base.dto.ts index 5dc5e4cd78d..ad7f5080bd6 100644 --- a/packages/core/src/core/dto/tenant-organization-base.dto.ts +++ b/packages/core/src/core/dto/tenant-organization-base.dto.ts @@ -1,21 +1,10 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { - IsObject, - IsOptional, - IsString, - IsUUID, - ValidateIf, -} from 'class-validator'; -import { - IOrganization, - IBasePerTenantAndOrganizationEntityModel, -} from '@gauzy/contracts'; +import { IsObject, IsOptional, IsString, IsUUID, ValidateIf } from 'class-validator'; +import { IOrganization, IBasePerTenantAndOrganizationEntityModel, ID } from '@gauzy/contracts'; import { TenantBaseDTO } from './tenant-base.dto'; import { IsOrganizationBelongsToUser } from './../../shared/validators'; -export class TenantOrganizationBaseDTO extends TenantBaseDTO - implements IBasePerTenantAndOrganizationEntityModel { - +export class TenantOrganizationBaseDTO extends TenantBaseDTO implements IBasePerTenantAndOrganizationEntityModel { @ApiProperty({ type: () => Object }) @ValidateIf((it) => !it.organizationId && !it.sentTo) @IsObject() @@ -26,11 +15,11 @@ export class TenantOrganizationBaseDTO extends TenantBaseDTO @ValidateIf((it) => !it.organization && !it.sentTo) @IsUUID() @IsOrganizationBelongsToUser() - readonly organizationId: IOrganization['id']; + readonly organizationId: ID; @ApiPropertyOptional({ type: () => String }) @ValidateIf((it) => !it.organization && !it.organizationId) @IsOptional() @IsString() - readonly sentTo?: IOrganization['id']; + readonly sentTo?: ID; } diff --git a/packages/core/src/database/migrations/1723645947040-AlterTaskStatusesAddWorkFlowFields.ts b/packages/core/src/database/migrations/1723645947040-AlterTaskStatusesAddWorkFlowFields.ts new file mode 100644 index 00000000000..1c17933c968 --- /dev/null +++ b/packages/core/src/database/migrations/1723645947040-AlterTaskStatusesAddWorkFlowFields.ts @@ -0,0 +1,165 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; +import { yellow } from 'chalk'; +import { DatabaseTypeEnum } from '@gauzy/config'; + +export class AlterTaskStatusesAddWorkFlowFields1723645947040 implements MigrationInterface { + name = 'AlterTaskStatusesAddWorkFlowFields1723645947040'; + + /** + * Up Migration + * + * @param queryRunner + */ + public async up(queryRunner: QueryRunner): Promise { + console.log(yellow(this.name + ' start running!')); + + switch (queryRunner.connection.options.type) { + case DatabaseTypeEnum.sqlite: + case DatabaseTypeEnum.betterSqlite3: + await this.sqliteUpQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.postgres: + await this.postgresUpQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.mysql: + await this.mysqlUpQueryRunner(queryRunner); + break; + default: + throw Error(`Unsupported database: ${queryRunner.connection.options.type}`); + } + } + + /** + * Down Migration + * + * @param queryRunner + */ + public async down(queryRunner: QueryRunner): Promise { + switch (queryRunner.connection.options.type) { + case DatabaseTypeEnum.sqlite: + case DatabaseTypeEnum.betterSqlite3: + await this.sqliteDownQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.postgres: + await this.postgresDownQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.mysql: + await this.mysqlDownQueryRunner(queryRunner); + break; + default: + throw Error(`Unsupported database: ${queryRunner.connection.options.type}`); + } + } + + /** + * PostgresDB Up Migration + * + * @param queryRunner + */ + public async postgresUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "task_status" ADD "isTodo" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "task_status" ADD "isInProgress" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "task_status" ADD "isDone" boolean NOT NULL DEFAULT false`); + } + + /** + * PostgresDB Down Migration + * + * @param queryRunner + */ + public async postgresDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "task_status" DROP COLUMN "isDone"`); + await queryRunner.query(`ALTER TABLE "task_status" DROP COLUMN "isInProgress"`); + await queryRunner.query(`ALTER TABLE "task_status" DROP COLUMN "isTodo"`); + } + + /** + * SqliteDB and BetterSQlite3DB Up Migration + * + * @param queryRunner + */ + public async sqliteUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_a19e8975e5c296640d457dfc11"`); + await queryRunner.query(`DROP INDEX "IDX_68eaba689ed6d3e27ec93d3e88"`); + await queryRunner.query(`DROP INDEX "IDX_b0c955f276679dd2b2735c3936"`); + await queryRunner.query(`DROP INDEX "IDX_9b9a828a49f4bd6383a4073fe2"`); + await queryRunner.query(`DROP INDEX "IDX_efbaf00a743316b394cc31e4a2"`); + await queryRunner.query(`DROP INDEX "IDX_0330b4a942b536d8d1f264abe3"`); + await queryRunner.query(`DROP INDEX "IDX_25d9737ee153411871b4d20c67"`); + await queryRunner.query(`DROP INDEX "IDX_79c525a8c2209e90186bfcbea9"`); + await queryRunner.query( + `CREATE TABLE "temporary_task_status" ("id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "tenantId" varchar, "organizationId" varchar, "name" varchar NOT NULL, "value" varchar NOT NULL, "description" varchar, "icon" varchar, "color" varchar, "isSystem" boolean NOT NULL DEFAULT (0), "projectId" varchar, "organizationTeamId" varchar, "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "deletedAt" datetime, "isCollapsed" boolean NOT NULL DEFAULT (0), "order" integer, "isTodo" boolean NOT NULL DEFAULT (0), "isInProgress" boolean NOT NULL DEFAULT (0), "isDone" boolean NOT NULL DEFAULT (0), CONSTRAINT "FK_0330b4a942b536d8d1f264abe32" FOREIGN KEY ("organizationTeamId") REFERENCES "organization_team" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_a19e8975e5c296640d457dfc11f" FOREIGN KEY ("projectId") REFERENCES "organization_project" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_efbaf00a743316b394cc31e4a20" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9b9a828a49f4bd6383a4073fe23" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE)` + ); + await queryRunner.query( + `INSERT INTO "temporary_task_status"("id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt", "isCollapsed", "order") SELECT "id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt", "isCollapsed", "order" FROM "task_status"` + ); + await queryRunner.query(`DROP TABLE "task_status"`); + await queryRunner.query(`ALTER TABLE "temporary_task_status" RENAME TO "task_status"`); + await queryRunner.query(`CREATE INDEX "IDX_a19e8975e5c296640d457dfc11" ON "task_status" ("projectId") `); + await queryRunner.query(`CREATE INDEX "IDX_68eaba689ed6d3e27ec93d3e88" ON "task_status" ("value") `); + await queryRunner.query(`CREATE INDEX "IDX_b0c955f276679dd2b2735c3936" ON "task_status" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_9b9a828a49f4bd6383a4073fe2" ON "task_status" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_efbaf00a743316b394cc31e4a2" ON "task_status" ("tenantId") `); + await queryRunner.query( + `CREATE INDEX "IDX_0330b4a942b536d8d1f264abe3" ON "task_status" ("organizationTeamId") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_25d9737ee153411871b4d20c67" ON "task_status" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_79c525a8c2209e90186bfcbea9" ON "task_status" ("isArchived") `); + } + + /** + * SqliteDB and BetterSQlite3DB Down Migration + * + * @param queryRunner + */ + public async sqliteDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_79c525a8c2209e90186bfcbea9"`); + await queryRunner.query(`DROP INDEX "IDX_25d9737ee153411871b4d20c67"`); + await queryRunner.query(`DROP INDEX "IDX_0330b4a942b536d8d1f264abe3"`); + await queryRunner.query(`DROP INDEX "IDX_efbaf00a743316b394cc31e4a2"`); + await queryRunner.query(`DROP INDEX "IDX_9b9a828a49f4bd6383a4073fe2"`); + await queryRunner.query(`DROP INDEX "IDX_b0c955f276679dd2b2735c3936"`); + await queryRunner.query(`DROP INDEX "IDX_68eaba689ed6d3e27ec93d3e88"`); + await queryRunner.query(`DROP INDEX "IDX_a19e8975e5c296640d457dfc11"`); + await queryRunner.query(`ALTER TABLE "task_status" RENAME TO "temporary_task_status"`); + await queryRunner.query( + `CREATE TABLE "task_status" ("id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "tenantId" varchar, "organizationId" varchar, "name" varchar NOT NULL, "value" varchar NOT NULL, "description" varchar, "icon" varchar, "color" varchar, "isSystem" boolean NOT NULL DEFAULT (0), "projectId" varchar, "organizationTeamId" varchar, "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "deletedAt" datetime, "isCollapsed" boolean NOT NULL DEFAULT (0), "order" integer, CONSTRAINT "FK_0330b4a942b536d8d1f264abe32" FOREIGN KEY ("organizationTeamId") REFERENCES "organization_team" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_a19e8975e5c296640d457dfc11f" FOREIGN KEY ("projectId") REFERENCES "organization_project" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_efbaf00a743316b394cc31e4a20" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9b9a828a49f4bd6383a4073fe23" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE)` + ); + await queryRunner.query( + `INSERT INTO "task_status"("id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt", "isCollapsed", "order") SELECT "id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt", "isCollapsed", "order" FROM "temporary_task_status"` + ); + await queryRunner.query(`DROP TABLE "temporary_task_status"`); + await queryRunner.query(`CREATE INDEX "IDX_79c525a8c2209e90186bfcbea9" ON "task_status" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_25d9737ee153411871b4d20c67" ON "task_status" ("isActive") `); + await queryRunner.query( + `CREATE INDEX "IDX_0330b4a942b536d8d1f264abe3" ON "task_status" ("organizationTeamId") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_efbaf00a743316b394cc31e4a2" ON "task_status" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_9b9a828a49f4bd6383a4073fe2" ON "task_status" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_b0c955f276679dd2b2735c3936" ON "task_status" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_68eaba689ed6d3e27ec93d3e88" ON "task_status" ("value") `); + await queryRunner.query(`CREATE INDEX "IDX_a19e8975e5c296640d457dfc11" ON "task_status" ("projectId") `); + } + + /** + * MySQL Up Migration + * + * @param queryRunner + */ + public async mysqlUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`task_status\` ADD \`isTodo\` tinyint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`task_status\` ADD \`isInProgress\` tinyint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`task_status\` ADD \`isDone\` tinyint NOT NULL DEFAULT 0`); + } + + /** + * MySQL Down Migration + * + * @param queryRunner + */ + public async mysqlDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`task_status\` DROP COLUMN \`isDone\``); + await queryRunner.query(`ALTER TABLE \`task_status\` DROP COLUMN \`isInProgress\``); + await queryRunner.query(`ALTER TABLE \`task_status\` DROP COLUMN \`isTodo\``); + } +} diff --git a/packages/core/src/database/migrations/1724062299873-AlterDailyPlanAddTeamRelation.ts b/packages/core/src/database/migrations/1724062299873-AlterDailyPlanAddTeamRelation.ts new file mode 100644 index 00000000000..5dd891c5fc4 --- /dev/null +++ b/packages/core/src/database/migrations/1724062299873-AlterDailyPlanAddTeamRelation.ts @@ -0,0 +1,205 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; +import { yellow } from 'chalk'; +import { DatabaseTypeEnum } from '@gauzy/config'; + +export class AlterDailyPlanAddTeamRelation1724062299873 implements MigrationInterface { + name = 'AlterDailyPlanAddTeamRelation1724062299873'; + + /** + * Up Migration + * + * @param queryRunner + */ + public async up(queryRunner: QueryRunner): Promise { + console.log(yellow(this.name + ' start running!')); + + switch (queryRunner.connection.options.type) { + case DatabaseTypeEnum.sqlite: + case DatabaseTypeEnum.betterSqlite3: + await this.sqliteUpQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.postgres: + await this.postgresUpQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.mysql: + await this.mysqlUpQueryRunner(queryRunner); + break; + default: + throw Error(`Unsupported database: ${queryRunner.connection.options.type}`); + } + } + + /** + * Down Migration + * + * @param queryRunner + */ + public async down(queryRunner: QueryRunner): Promise { + switch (queryRunner.connection.options.type) { + case DatabaseTypeEnum.sqlite: + case DatabaseTypeEnum.betterSqlite3: + await this.sqliteDownQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.postgres: + await this.postgresDownQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.mysql: + await this.mysqlDownQueryRunner(queryRunner); + break; + default: + throw Error(`Unsupported database: ${queryRunner.connection.options.type}`); + } + } + + /** + * PostgresDB Up Migration + * + * @param queryRunner + */ + public async postgresUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "daily_plan" ADD "organizationTeamId" uuid`); + await queryRunner.query( + `CREATE INDEX "IDX_b022c2b684c35dcc63c22850f1" ON "daily_plan" ("organizationTeamId") ` + ); + await queryRunner.query( + `ALTER TABLE "daily_plan" ADD CONSTRAINT "FK_b022c2b684c35dcc63c22850f13" FOREIGN KEY ("organizationTeamId") REFERENCES "organization_team"("id") ON DELETE CASCADE ON UPDATE NO ACTION` + ); + } + + /** + * PostgresDB Down Migration + * + * @param queryRunner + */ + public async postgresDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "daily_plan" DROP CONSTRAINT "FK_b022c2b684c35dcc63c22850f13"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b022c2b684c35dcc63c22850f1"`); + await queryRunner.query(`ALTER TABLE "daily_plan" DROP COLUMN "organizationTeamId"`); + } + + /** + * SqliteDB and BetterSQlite3DB Up Migration + * + * @param queryRunner + */ + public async sqliteUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_f2cf366f3f08e31784b056df88"`); + await queryRunner.query(`DROP INDEX "IDX_9779a35ef1338bafb7b90714f1"`); + await queryRunner.query(`DROP INDEX "IDX_ecb357a3764a7344c633a257d7"`); + await queryRunner.query(`DROP INDEX "IDX_ce5e588780497b05cd6267e20e"`); + await queryRunner.query(`DROP INDEX "IDX_903b08cd4c8025e73316342452"`); + await queryRunner.query( + `CREATE TABLE "temporary_daily_plan" ("deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "tenantId" varchar, "organizationId" varchar, "date" datetime NOT NULL, "workTimePlanned" decimal NOT NULL, "status" varchar NOT NULL, "employeeId" varchar, "organizationTeamId" varchar, CONSTRAINT "FK_f2cf366f3f08e31784b056df880" FOREIGN KEY ("employeeId") REFERENCES "employee" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9779a35ef1338bafb7b90714f16" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT "FK_ecb357a3764a7344c633a257d76" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "temporary_daily_plan"("deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId") SELECT "deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId" FROM "daily_plan"` + ); + await queryRunner.query(`DROP TABLE "daily_plan"`); + await queryRunner.query(`ALTER TABLE "temporary_daily_plan" RENAME TO "daily_plan"`); + await queryRunner.query(`CREATE INDEX "IDX_f2cf366f3f08e31784b056df88" ON "daily_plan" ("employeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_9779a35ef1338bafb7b90714f1" ON "daily_plan" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_ecb357a3764a7344c633a257d7" ON "daily_plan" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_ce5e588780497b05cd6267e20e" ON "daily_plan" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_903b08cd4c8025e73316342452" ON "daily_plan" ("isActive") `); + await queryRunner.query( + `CREATE INDEX "IDX_b022c2b684c35dcc63c22850f1" ON "daily_plan" ("organizationTeamId") ` + ); + await queryRunner.query(`DROP INDEX "IDX_f2cf366f3f08e31784b056df88"`); + await queryRunner.query(`DROP INDEX "IDX_9779a35ef1338bafb7b90714f1"`); + await queryRunner.query(`DROP INDEX "IDX_ecb357a3764a7344c633a257d7"`); + await queryRunner.query(`DROP INDEX "IDX_ce5e588780497b05cd6267e20e"`); + await queryRunner.query(`DROP INDEX "IDX_903b08cd4c8025e73316342452"`); + await queryRunner.query(`DROP INDEX "IDX_b022c2b684c35dcc63c22850f1"`); + await queryRunner.query( + `CREATE TABLE "temporary_daily_plan" ("deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "tenantId" varchar, "organizationId" varchar, "date" datetime NOT NULL, "workTimePlanned" decimal NOT NULL, "status" varchar NOT NULL, "employeeId" varchar, "organizationTeamId" varchar, CONSTRAINT "FK_f2cf366f3f08e31784b056df880" FOREIGN KEY ("employeeId") REFERENCES "employee" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9779a35ef1338bafb7b90714f16" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT "FK_ecb357a3764a7344c633a257d76" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_b022c2b684c35dcc63c22850f13" FOREIGN KEY ("organizationTeamId") REFERENCES "organization_team" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "temporary_daily_plan"("deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId", "organizationTeamId") SELECT "deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId", "organizationTeamId" FROM "daily_plan"` + ); + await queryRunner.query(`DROP TABLE "daily_plan"`); + await queryRunner.query(`ALTER TABLE "temporary_daily_plan" RENAME TO "daily_plan"`); + await queryRunner.query(`CREATE INDEX "IDX_f2cf366f3f08e31784b056df88" ON "daily_plan" ("employeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_9779a35ef1338bafb7b90714f1" ON "daily_plan" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_ecb357a3764a7344c633a257d7" ON "daily_plan" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_ce5e588780497b05cd6267e20e" ON "daily_plan" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_903b08cd4c8025e73316342452" ON "daily_plan" ("isActive") `); + await queryRunner.query( + `CREATE INDEX "IDX_b022c2b684c35dcc63c22850f1" ON "daily_plan" ("organizationTeamId") ` + ); + } + + /** + * SqliteDB and BetterSQlite3DB Down Migration + * + * @param queryRunner + */ + public async sqliteDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_b022c2b684c35dcc63c22850f1"`); + await queryRunner.query(`DROP INDEX "IDX_903b08cd4c8025e73316342452"`); + await queryRunner.query(`DROP INDEX "IDX_ce5e588780497b05cd6267e20e"`); + await queryRunner.query(`DROP INDEX "IDX_ecb357a3764a7344c633a257d7"`); + await queryRunner.query(`DROP INDEX "IDX_9779a35ef1338bafb7b90714f1"`); + await queryRunner.query(`DROP INDEX "IDX_f2cf366f3f08e31784b056df88"`); + await queryRunner.query(`ALTER TABLE "daily_plan" RENAME TO "temporary_daily_plan"`); + await queryRunner.query( + `CREATE TABLE "daily_plan" ("deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "tenantId" varchar, "organizationId" varchar, "date" datetime NOT NULL, "workTimePlanned" decimal NOT NULL, "status" varchar NOT NULL, "employeeId" varchar, "organizationTeamId" varchar, CONSTRAINT "FK_f2cf366f3f08e31784b056df880" FOREIGN KEY ("employeeId") REFERENCES "employee" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9779a35ef1338bafb7b90714f16" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT "FK_ecb357a3764a7344c633a257d76" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "daily_plan"("deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId", "organizationTeamId") SELECT "deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId", "organizationTeamId" FROM "temporary_daily_plan"` + ); + await queryRunner.query(`DROP TABLE "temporary_daily_plan"`); + await queryRunner.query( + `CREATE INDEX "IDX_b022c2b684c35dcc63c22850f1" ON "daily_plan" ("organizationTeamId") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_903b08cd4c8025e73316342452" ON "daily_plan" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_ce5e588780497b05cd6267e20e" ON "daily_plan" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_ecb357a3764a7344c633a257d7" ON "daily_plan" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_9779a35ef1338bafb7b90714f1" ON "daily_plan" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_f2cf366f3f08e31784b056df88" ON "daily_plan" ("employeeId") `); + await queryRunner.query(`DROP INDEX "IDX_b022c2b684c35dcc63c22850f1"`); + await queryRunner.query(`DROP INDEX "IDX_903b08cd4c8025e73316342452"`); + await queryRunner.query(`DROP INDEX "IDX_ce5e588780497b05cd6267e20e"`); + await queryRunner.query(`DROP INDEX "IDX_ecb357a3764a7344c633a257d7"`); + await queryRunner.query(`DROP INDEX "IDX_9779a35ef1338bafb7b90714f1"`); + await queryRunner.query(`DROP INDEX "IDX_f2cf366f3f08e31784b056df88"`); + await queryRunner.query(`ALTER TABLE "daily_plan" RENAME TO "temporary_daily_plan"`); + await queryRunner.query( + `CREATE TABLE "daily_plan" ("deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "tenantId" varchar, "organizationId" varchar, "date" datetime NOT NULL, "workTimePlanned" decimal NOT NULL, "status" varchar NOT NULL, "employeeId" varchar, CONSTRAINT "FK_f2cf366f3f08e31784b056df880" FOREIGN KEY ("employeeId") REFERENCES "employee" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9779a35ef1338bafb7b90714f16" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT "FK_ecb357a3764a7344c633a257d76" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "daily_plan"("deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId") SELECT "deletedAt", "id", "createdAt", "updatedAt", "isActive", "isArchived", "tenantId", "organizationId", "date", "workTimePlanned", "status", "employeeId" FROM "temporary_daily_plan"` + ); + await queryRunner.query(`DROP TABLE "temporary_daily_plan"`); + await queryRunner.query(`CREATE INDEX "IDX_903b08cd4c8025e73316342452" ON "daily_plan" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_ce5e588780497b05cd6267e20e" ON "daily_plan" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_ecb357a3764a7344c633a257d7" ON "daily_plan" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_9779a35ef1338bafb7b90714f1" ON "daily_plan" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_f2cf366f3f08e31784b056df88" ON "daily_plan" ("employeeId") `); + } + + /** + * MySQL Up Migration + * + * @param queryRunner + */ + public async mysqlUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`daily_plan\` ADD \`organizationTeamId\` varchar(255) NULL`); + await queryRunner.query( + `CREATE INDEX \`IDX_b022c2b684c35dcc63c22850f1\` ON \`daily_plan\` (\`organizationTeamId\`)` + ); + await queryRunner.query( + `ALTER TABLE \`daily_plan\` ADD CONSTRAINT \`FK_b022c2b684c35dcc63c22850f13\` FOREIGN KEY (\`organizationTeamId\`) REFERENCES \`organization_team\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION` + ); + } + + /** + * MySQL Down Migration + * + * @param queryRunner + */ + public async mysqlDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`daily_plan\` DROP FOREIGN KEY \`FK_b022c2b684c35dcc63c22850f13\``); + await queryRunner.query(`DROP INDEX \`IDX_b022c2b684c35dcc63c22850f1\` ON \`daily_plan\``); + await queryRunner.query(`ALTER TABLE \`daily_plan\` DROP COLUMN \`organizationTeamId\``); + } +} diff --git a/packages/core/src/employee-appointment/employee-appointment.controller.ts b/packages/core/src/employee-appointment/employee-appointment.controller.ts index 51841e13679..a1d66858ee6 100644 --- a/packages/core/src/employee-appointment/employee-appointment.controller.ts +++ b/packages/core/src/employee-appointment/employee-appointment.controller.ts @@ -1,37 +1,26 @@ -import { - Controller, - UseGuards, - HttpStatus, - Body, - Param, - Get, - Post, - Put, - HttpCode, - Query, - ValidationPipe, - UsePipes -} from '@nestjs/common'; +import { Controller, UseGuards, HttpStatus, Body, Param, Get, Post, Put, HttpCode, Query } from '@nestjs/common'; import { CommandBus } from '@nestjs/cqrs'; import { I18nLang } from 'nestjs-i18n'; import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'; import { + ID, LanguagesEnum, IEmployeeAppointmentCreateInput, IEmployeeAppointmentUpdateInput, IEmployeeAppointment, IPagination } from '@gauzy/contracts'; +import { CrudController, PaginationParams } from './../core/crud'; +import { RelationsQueryDTO } from '../shared/dto'; +import { TenantPermissionGuard } from './../shared/guards'; +import { ParseJsonPipe, UUIDValidationPipe, UseValidationPipe } from './../shared/pipes'; import { EmployeeAppointmentService } from './employee-appointment.service'; import { EmployeeAppointmentCreateCommand, EmployeeAppointmentUpdateCommand } from './commands'; import { EmployeeAppointment } from './employee-appointment.entity'; -import { ParseJsonPipe, UUIDValidationPipe, UseValidationPipe } from './../shared/pipes'; -import { TenantPermissionGuard } from './../shared/guards'; -import { CrudController, PaginationParams } from './../core/crud'; @ApiTags('EmployeeAppointment') @UseGuards(TenantPermissionGuard) -@Controller() +@Controller('/employee-appointment') export class EmployeeAppointmentController extends CrudController { constructor( private readonly employeeAppointmentService: EmployeeAppointmentService, @@ -56,8 +45,8 @@ export class EmployeeAppointmentController extends CrudController { + @Get('/sign/:id') + async signAppointment(@Param('id', UUIDValidationPipe) id: ID): Promise { return this.employeeAppointmentService.signAppointmentId(id); } @@ -77,9 +66,9 @@ export class EmployeeAppointmentController extends CrudController { - const decoded = this.employeeAppointmentService.decode(token); + const decoded = this.employeeAppointmentService.decodeSignToken(token); return decoded['appointmentId']; } @@ -89,7 +78,7 @@ export class EmployeeAppointmentController extends CrudController @@ -115,7 +104,7 @@ export class EmployeeAppointmentController extends CrudController> { const { relations, findInput } = data; return this.employeeAppointmentService.findAll({ @@ -140,9 +129,12 @@ export class EmployeeAppointmentController extends CrudController { - return this.employeeAppointmentService.findOneByIdString(id); + @Get('/:id') + async findById( + @Param('id', UUIDValidationPipe) id: ID, + @Query() query: RelationsQueryDTO + ): Promise { + return await this.employeeAppointmentService.findById(id, query.relations); } /** @@ -161,7 +153,7 @@ export class EmployeeAppointmentController extends CrudController { return await this.commandBus.execute(new EmployeeAppointmentUpdateCommand(id, entity)); diff --git a/packages/core/src/employee-appointment/employee-appointment.entity.ts b/packages/core/src/employee-appointment/employee-appointment.entity.ts index d154dee8ccb..ef69ae78660 100644 --- a/packages/core/src/employee-appointment/employee-appointment.entity.ts +++ b/packages/core/src/employee-appointment/employee-appointment.entity.ts @@ -1,27 +1,13 @@ import { ApiProperty } from '@nestjs/swagger'; -import { - IsNotEmpty, - IsString, - IsDate, - IsBoolean, - IsNumber -} from 'class-validator'; -import { - JoinColumn, - RelationId -} from 'typeorm'; -import { IEmployee, IEmployeeAppointment } from '@gauzy/contracts'; -import { - AppointmentEmployee, - Employee, - TenantOrganizationBaseEntity -} from '../core/entities/internal'; +import { IsNotEmpty, IsString, IsDate, IsBoolean, IsNumber } from 'class-validator'; +import { JoinColumn, RelationId } from 'typeorm'; +import { EmployeeAppointmentStatus, ID, IEmployee, IEmployeeAppointment } from '@gauzy/contracts'; +import { AppointmentEmployee, Employee, TenantOrganizationBaseEntity } from '../core/entities/internal'; import { MultiORMColumn, MultiORMEntity, MultiORMManyToOne, MultiORMOneToMany } from './../core/decorators/entity'; import { MikroOrmEmployeeAppointmentRepository } from './repository/mikro-orm-employee-appointment.repository'; @MultiORMEntity('employee_appointment', { mikroOrmRepository: () => MikroOrmEmployeeAppointmentRepository }) export class EmployeeAppointment extends TenantOrganizationBaseEntity implements IEmployeeAppointment { - @ApiProperty({ type: () => String }) @IsString() @IsNotEmpty() @@ -83,24 +69,31 @@ export class EmployeeAppointment extends TenantOrganizationBaseEntity implements @ApiProperty({ type: () => String }) @IsString() @MultiORMColumn({ nullable: true }) - status?: string; + status?: EmployeeAppointmentStatus; /* |-------------------------------------------------------------------------- | @ManyToOne |-------------------------------------------------------------------------- */ + /** - * + * Appointment Employee */ - @MultiORMManyToOne(() => Employee, { nullable: true, onDelete: 'CASCADE' }) + @MultiORMManyToOne(() => Employee, { + /** Indicates if relation column value can be nullable or not. */ + nullable: true, + + /** Database cascade action on delete. */ + onDelete: 'CASCADE' + }) @JoinColumn() employee?: IEmployee; @ApiProperty({ type: () => String }) @RelationId((it: EmployeeAppointment) => it.employee) @MultiORMColumn({ nullable: true, relationId: true }) - employeeId?: IEmployee['id']; + employeeId?: ID; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/employee-appointment/employee-appointment.module.ts b/packages/core/src/employee-appointment/employee-appointment.module.ts index 5925a5d5935..8335d0730a7 100644 --- a/packages/core/src/employee-appointment/employee-appointment.module.ts +++ b/packages/core/src/employee-appointment/employee-appointment.module.ts @@ -1,6 +1,5 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { Module } from '@nestjs/common'; -import { RouterModule } from '@nestjs/core'; import { CqrsModule } from '@nestjs/cqrs'; import { MikroOrmModule } from '@mikro-orm/nestjs'; import { EmployeeAppointment } from './employee-appointment.entity'; @@ -11,10 +10,10 @@ import { EmailSendModule } from '../email-send/email-send.module'; import { EmployeeModule } from '../employee/employee.module'; import { OrganizationModule } from '../organization/organization.module'; import { RolePermissionModule } from '../role-permission/role-permission.module'; +import { TypeOrmEmployeeAppointmentRepository } from './repository/type-orm-employee-appointment.repository'; @Module({ imports: [ - RouterModule.register([{ path: '/employee-appointment', module: EmployeeAppointmentModule }]), TypeOrmModule.forFeature([EmployeeAppointment]), MikroOrmModule.forFeature([EmployeeAppointment]), EmailSendModule, @@ -24,7 +23,7 @@ import { RolePermissionModule } from '../role-permission/role-permission.module' CqrsModule ], controllers: [EmployeeAppointmentController], - providers: [EmployeeAppointmentService, ...CommandHandlers], - exports: [EmployeeAppointmentService] + providers: [EmployeeAppointmentService, TypeOrmEmployeeAppointmentRepository, ...CommandHandlers], + exports: [EmployeeAppointmentService, TypeOrmEmployeeAppointmentRepository] }) export class EmployeeAppointmentModule {} diff --git a/packages/core/src/employee-appointment/employee-appointment.service.ts b/packages/core/src/employee-appointment/employee-appointment.service.ts index 8e07fd10f60..9a76f81e598 100644 --- a/packages/core/src/employee-appointment/employee-appointment.service.ts +++ b/packages/core/src/employee-appointment/employee-appointment.service.ts @@ -1,7 +1,6 @@ -import { InjectRepository } from '@nestjs/typeorm'; import { Injectable } from '@nestjs/common'; -import { sign, decode } from 'jsonwebtoken'; -import { IEmployeeAppointmentCreateInput } from '@gauzy/contracts'; +import { sign, decode, JwtPayload } from 'jsonwebtoken'; +import { ID, IEmployeeAppointment, IEmployeeAppointmentCreateInput } from '@gauzy/contracts'; import { environment as env } from '@gauzy/config'; import { TenantAwareCrudService } from './../core/crud'; import { TypeOrmEmployeeAppointmentRepository } from './repository/type-orm-employee-appointment.repository'; @@ -11,44 +10,50 @@ import { EmployeeAppointment } from './employee-appointment.entity'; @Injectable() export class EmployeeAppointmentService extends TenantAwareCrudService { constructor( - @InjectRepository(EmployeeAppointment) typeOrmEmployeeAppointmentRepository: TypeOrmEmployeeAppointmentRepository, - mikroOrmEmployeeAppointmentRepository: MikroOrmEmployeeAppointmentRepository ) { super(typeOrmEmployeeAppointmentRepository, mikroOrmEmployeeAppointmentRepository); } /** + * Finds an employee appointment by its ID. * - * @param employeeAppointmentRequest - * @returns + * @param id - The unique identifier of the employee appointment. + * @param relations - An optional array of related entities to include in the query result. Defaults to an empty array. + * @returns A promise that resolves to the employee appointment entity, including any specified relations. */ - async saveAppointment(employeeAppointmentRequest: IEmployeeAppointmentCreateInput): Promise { - return await this.typeOrmRepository.save(employeeAppointmentRequest); + async findById(id: ID, relations: string[] = []): Promise { + return await super.findOneByIdString(id, { relations }); } /** + * Saves a new employee appointment to the database. * - * @param id - * @returns + * @param input - The data required to create a new employee appointment, encapsulated in an `IEmployeeAppointmentCreateInput` object. + * @returns A promise that resolves to the saved `EmployeeAppointment` entity. + */ + async saveAppointment(input: IEmployeeAppointmentCreateInput): Promise { + return await this.typeOrmRepository.save(input); + } + + /** + * Signs an appointment ID using a JSON Web Token (JWT). + * + * @param id - The ID of the appointment to be signed. + * @returns A signed JWT token containing the appointment ID. */ - signAppointmentId(id: string) { - return sign( - { - appointmentId: id - }, - env.JWT_SECRET, - {} - ); + signAppointmentId(id: ID): string { + return sign({ appointmentId: id }, env.JWT_SECRET, {}); } /** + * Decodes a signed appointment ID from a JSON Web Token (JWT). * * @param token * @returns */ - decode(token: string) { + decodeSignToken(token: string): JwtPayload | string { return decode(token); } } diff --git a/packages/core/src/employee/dto/employee-feature.dto.ts b/packages/core/src/employee/dto/employee-feature.dto.ts index da940ba67d6..25849161f14 100644 --- a/packages/core/src/employee/dto/employee-feature.dto.ts +++ b/packages/core/src/employee/dto/employee-feature.dto.ts @@ -1,20 +1,19 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsObject, IsString, ValidateIf } from "class-validator"; -import { IEmployee, IRelationalEmployee } from "@gauzy/contracts"; -import { Employee } from "./../employee.entity"; -import { IsEmployeeBelongsToOrganization } from "./../../shared/validators"; +import { ApiPropertyOptional } from '@nestjs/swagger'; +import { IsObject, IsString, ValidateIf } from 'class-validator'; +import { ID, IEmployee, IRelationalEmployee } from '@gauzy/contracts'; +import { Employee } from './../employee.entity'; +import { IsEmployeeBelongsToOrganization } from './../../shared/validators'; export class EmployeeFeatureDTO implements IRelationalEmployee { + @ApiPropertyOptional({ type: () => Employee }) + @ValidateIf((it) => !it.employeeId || it.employee) + @IsObject() + @IsEmployeeBelongsToOrganization() + readonly employee: IEmployee; - @ApiPropertyOptional({ type: () => Employee }) - @ValidateIf((it) => !it.employeeId || it.employee) - @IsObject() - @IsEmployeeBelongsToOrganization() - readonly employee: IEmployee; - - @ApiPropertyOptional({ type: () => String }) - @ValidateIf((it) => !it.employee || it.employeeId) - @IsString() - @IsEmployeeBelongsToOrganization() - readonly employeeId: IEmployee['id']; + @ApiPropertyOptional({ type: () => String }) + @ValidateIf((it) => !it.employee || it.employeeId) + @IsString() + @IsEmployeeBelongsToOrganization() + readonly employeeId: ID; } diff --git a/packages/core/src/organization-team/dto/index.ts b/packages/core/src/organization-team/dto/index.ts index 48ffe5cfc63..487bbbdf58b 100644 --- a/packages/core/src/organization-team/dto/index.ts +++ b/packages/core/src/organization-team/dto/index.ts @@ -1,4 +1,4 @@ - -export * from "./create-organization-team.dto"; -export * from "./update-organization-team.dto"; -export * from "./organization-team-statistic.dto"; +export * from './create-organization-team.dto'; +export * from './update-organization-team.dto'; +export * from './organization-team-statistic.dto'; +export * from './organization-team-feature.dto'; diff --git a/packages/core/src/organization-team/dto/organization-team-feature.dto.ts b/packages/core/src/organization-team/dto/organization-team-feature.dto.ts new file mode 100644 index 00000000000..cf543072c8f --- /dev/null +++ b/packages/core/src/organization-team/dto/organization-team-feature.dto.ts @@ -0,0 +1,16 @@ +import { ApiPropertyOptional } from '@nestjs/swagger'; +import { IsObject, IsUUID, ValidateIf } from 'class-validator'; +import { ID, IOrganizationTeam, IRelationalOrganizationTeam } from '@gauzy/contracts'; +import { OrganizationTeam } from '../organization-team.entity'; + +export class OrganizationTeamFeatureDTO implements IRelationalOrganizationTeam { + @ApiPropertyOptional({ type: () => OrganizationTeam }) + @ValidateIf((it) => !it.organizationTeamId || it.organizationTeam) + @IsObject() + readonly organizationTeam: IOrganizationTeam; + + @ApiPropertyOptional({ type: () => String }) + @ValidateIf((it) => !it.organizationTeam || it.organizationTeamId) + @IsUUID() + readonly organizationTeamId: ID; +} diff --git a/packages/core/src/organization-team/organization-team.entity.ts b/packages/core/src/organization-team/organization-team.entity.ts index 35ad489ba20..689fab8134e 100644 --- a/packages/core/src/organization-team/organization-team.entity.ts +++ b/packages/core/src/organization-team/organization-team.entity.ts @@ -1,5 +1,7 @@ import { JoinTable, JoinColumn, RelationId } from 'typeorm'; import { + ID, + IDailyPlan, IEquipmentSharing, IGoal, IImageAsset, @@ -20,6 +22,7 @@ import { import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; import { + DailyPlan, EquipmentSharing, Goal, ImageAsset, @@ -166,7 +169,7 @@ export class OrganizationTeam extends TenantOrganizationBaseEntity implements IO @RelationId((it: OrganizationTeam) => it.createdBy) @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) - createdById?: IUser['id']; + createdById?: ID; /** * ImageAsset @@ -190,7 +193,7 @@ export class OrganizationTeam extends TenantOrganizationBaseEntity implements IO @RelationId((it: OrganizationTeam) => it.image) @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) - imageId?: IImageAsset['id']; + imageId?: ID; /* |-------------------------------------------------------------------------- @@ -261,6 +264,14 @@ export class OrganizationTeam extends TenantOrganizationBaseEntity implements IO @MultiORMOneToMany(() => IssueType, (it) => it.organizationTeam) issueTypes?: IIssueType[]; + /** + * Team daily plans + */ + @MultiORMOneToMany(() => DailyPlan, (dailyPlan) => dailyPlan.organizationTeam, { + cascade: true + }) + dailyPlans?: IDailyPlan[]; + /* |-------------------------------------------------------------------------- | @ManyToMany diff --git a/packages/core/src/public-share/invoice/public-invoice.module.ts b/packages/core/src/public-share/invoice/public-invoice.module.ts index 2f67f7c8df2..6ee2d357b86 100644 --- a/packages/core/src/public-share/invoice/public-invoice.module.ts +++ b/packages/core/src/public-share/invoice/public-invoice.module.ts @@ -1,27 +1,17 @@ import { Module } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { MikroOrmModule } from '@mikro-orm/nestjs'; import { QueryHandlers } from './queries/handlers'; import { CommandHandlers } from './commands/handlers'; import { Invoice } from './../../core/entities/internal'; import { PublicInvoiceController } from './public-invoice.controller'; import { PublicInvoiceService } from './public-invoice.service'; -import { MikroOrmModule } from '@mikro-orm/nestjs'; @Module({ - imports: [ - CqrsModule, - TypeOrmModule.forFeature([Invoice]), - MikroOrmModule.forFeature([Invoice]), - ], - controllers: [ - PublicInvoiceController - ], - providers: [ - PublicInvoiceService, - ...QueryHandlers, - ...CommandHandlers - ], + imports: [CqrsModule, TypeOrmModule.forFeature([Invoice]), MikroOrmModule.forFeature([Invoice])], + controllers: [PublicInvoiceController], + providers: [PublicInvoiceService, ...QueryHandlers, ...CommandHandlers], exports: [] }) -export class PublicInvoiceModule { } +export class PublicInvoiceModule {} diff --git a/packages/core/src/public-share/invoice/public-invoice.service.ts b/packages/core/src/public-share/invoice/public-invoice.service.ts index 37f4bebcc82..56e4548f3b6 100644 --- a/packages/core/src/public-share/invoice/public-invoice.service.ts +++ b/packages/core/src/public-share/invoice/public-invoice.service.ts @@ -9,11 +9,10 @@ import { TypeOrmInvoiceRepository } from '../../invoice/repository/type-orm-invo @Injectable() export class PublicInvoiceService { - constructor( @InjectRepository(Invoice) - private typeOrmInvoiceRepository: TypeOrmInvoiceRepository, - ) { } + private readonly typeOrmInvoiceRepository: TypeOrmInvoiceRepository + ) {} /** * Find public invoice by token @@ -22,18 +21,16 @@ export class PublicInvoiceService { * @param relations * @returns */ - async findOneByConditions( - params: FindOptionsWhere, - relations: string[] = [] - ): Promise { + async findOneByConditions(params: FindOptionsWhere, relations: string[] = []): Promise { + if (!params.id || !params.token) { + throw new ForbiddenException(); + } + try { - if (!params.id || !params.token) { - throw new ForbiddenException(); - } + // verify token const { id, organizationId, tenantId } = verify(params.token as string, environment.JWT_SECRET) as IInvoice; - if (id !== params.id) { - throw new ForbiddenException(); - } + + // Get invoice return await this.typeOrmInvoiceRepository.findOneOrFail({ select: { tenant: { @@ -59,13 +56,17 @@ export class PublicInvoiceService { applyDiscount: true, employeeId: true, employee: { + id: true, + userId: true, user: { + id: true, firstName: true, - lastName: true, + lastName: true } }, projectId: true, project: { + id: true, imageUrl: true, name: true, description: true @@ -73,18 +74,21 @@ export class PublicInvoiceService { productId: true, expenseId: true, expense: { + id: true, purpose: true }, taskId: true, task: { + id: true, title: true, - description: true, + description: true } }, toContact: { + id: true, contactType: true, imageUrl: true, - name: true, + name: true } }, where: { @@ -92,11 +96,7 @@ export class PublicInvoiceService { organizationId, tenantId }, - ...( - (relations) ? { - relations: relations - } : {} - ), + ...(relations ? { relations: relations } : {}) }); } catch (error) { throw new ForbiddenException(); @@ -110,16 +110,13 @@ export class PublicInvoiceService { * @param entity * @returns */ - async updateInvoice( - params: IInvoice, - entity: IInvoiceUpdateInput - ): Promise { + async updateInvoice(params: IInvoice, entity: IInvoiceUpdateInput): Promise { try { const decoded = verify(params.token as string, environment.JWT_SECRET) as any; const invoice = await this.typeOrmInvoiceRepository.findOneByOrFail({ id: decoded.invoiceId, organizationId: decoded.organizationId, - tenantId: decoded.tenantId, + tenantId: decoded.tenantId }); return await this.typeOrmInvoiceRepository.update(invoice.id, entity); } catch (error) { diff --git a/packages/core/src/shared/dto/count-query.dto.ts b/packages/core/src/shared/dto/count-query.dto.ts index 70e7b4341e7..7f26cd5c8f7 100644 --- a/packages/core/src/shared/dto/count-query.dto.ts +++ b/packages/core/src/shared/dto/count-query.dto.ts @@ -1,18 +1,20 @@ -import { ApiProperty, PickType } from "@nestjs/swagger"; -import { IsNotEmpty, IsUUID } from "class-validator"; -import { IBasePerTenantAndOrganizationEntityModel, IOrganization } from "@gauzy/contracts"; -import { TenantBaseDTO } from "./../../core/dto"; -import { IsOrganizationBelongsToUser } from "./../../shared/validators"; +import { ApiProperty, PickType } from '@nestjs/swagger'; +import { IsNotEmpty, IsUUID } from 'class-validator'; +import { IBasePerTenantAndOrganizationEntityModel, ID } from '@gauzy/contracts'; +import { TenantBaseDTO } from './../../core/dto'; +import { IsOrganizationBelongsToUser } from './../../shared/validators'; /** * Entity Count DTO * */ -export class CountQueryDTO extends PickType(TenantBaseDTO, ['tenantId']) implements IBasePerTenantAndOrganizationEntityModel { - +export class CountQueryDTO + extends PickType(TenantBaseDTO, ['tenantId']) + implements IBasePerTenantAndOrganizationEntityModel +{ @ApiProperty({ type: () => String }) @IsNotEmpty() @IsUUID() @IsOrganizationBelongsToUser() - readonly organizationId: IOrganization['id']; + readonly organizationId: ID; } diff --git a/packages/core/src/tasks/daily-plan/daily-plan.controller.ts b/packages/core/src/tasks/daily-plan/daily-plan.controller.ts index 0e66ee23d44..86abd69bd4f 100644 --- a/packages/core/src/tasks/daily-plan/daily-plan.controller.ts +++ b/packages/core/src/tasks/daily-plan/daily-plan.controller.ts @@ -13,21 +13,14 @@ import { } from '@nestjs/common'; import { UpdateResult } from 'typeorm'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { - IDailyPlan, - IDailyPlanTasksUpdateInput, - IEmployee, - IPagination, - ITask, - PermissionsEnum -} from '@gauzy/contracts'; +import { ID, IDailyPlan, IDailyPlanTasksUpdateInput, IPagination, PermissionsEnum } from '@gauzy/contracts'; import { CrudController, PaginationParams } from '../../core/crud'; import { UseValidationPipe } from '../../shared/pipes'; -import { DailyPlan } from './daily-plan.entity'; -import { DailyPlanService } from './daily-plan.service'; import { CreateDailyPlanDTO, RemoveTaskFromManyPlansDTO, UpdateDailyPlanDTO } from './dto'; import { PermissionGuard, TenantPermissionGuard } from '../../shared/guards'; import { Permissions } from '../../shared/decorators'; +import { DailyPlan } from './daily-plan.entity'; +import { DailyPlanService } from './daily-plan.service'; @ApiTags('Daily Plan') @UseGuards(TenantPermissionGuard, PermissionGuard) @@ -63,6 +56,32 @@ export class DailyPlanController extends CrudController { return await this.dailyPlanService.getMyPlans(params); } + /** + * GET daily plans for a given team + * + * @param options + * @param employeeId + * @returns + */ + @ApiOperation({ + summary: 'Find team daily plans.' + }) + @ApiResponse({ + status: HttpStatus.OK, + description: 'Found plans', + type: DailyPlan + }) + @ApiResponse({ + status: HttpStatus.NOT_FOUND, + description: 'No Record found' + }) + @Get('team') + @Permissions(PermissionsEnum.ALL_ORG_VIEW, PermissionsEnum.DAILY_PLAN_READ) + @UseValidationPipe() + async getTeamDailyPlans(@Query() params: PaginationParams): Promise> { + return await this.dailyPlanService.getTeamDailyPlans(params); + } + /** * GET daily plans for a given employee * @@ -85,7 +104,7 @@ export class DailyPlanController extends CrudController { @Permissions(PermissionsEnum.ALL_ORG_VIEW, PermissionsEnum.DAILY_PLAN_READ) @Get('employee/:id') async getEmployeeDailyPlans( - @Param('id') employeeId: IEmployee['id'], + @Param('id') employeeId: ID, @Query() params: PaginationParams ): Promise> { return await this.dailyPlanService.getDailyPlansByEmployee(params, employeeId); @@ -113,7 +132,7 @@ export class DailyPlanController extends CrudController { @Permissions(PermissionsEnum.ALL_ORG_VIEW, PermissionsEnum.DAILY_PLAN_READ) @Get('task/:id') async getDailyPlansForTaskId( - @Param('id') taskId: ITask['id'], + @Param('id') taskId: ID, @Query() params: PaginationParams ): Promise> { return await this.dailyPlanService.getDailyPlansByTask(params, taskId); @@ -141,7 +160,7 @@ export class DailyPlanController extends CrudController { @Permissions(PermissionsEnum.ALL_ORG_EDIT, PermissionsEnum.DAILY_PLAN_CREATE, PermissionsEnum.DAILY_PLAN_UPDATE) @Post(':id/task') // Route for adding a task to a daily plan async addTaskToDailyPlan( - @Param('id') planId: IDailyPlan['id'], // Extract the plan ID from the URL parameter + @Param('id') planId: ID, // Extract the plan ID from the URL parameter @Body() input: IDailyPlanTasksUpdateInput // Data for updating the daily plan ): Promise { // Call the service method to add a task to the daily plan @@ -171,7 +190,7 @@ export class DailyPlanController extends CrudController { @Permissions(PermissionsEnum.ALL_ORG_EDIT, PermissionsEnum.DAILY_PLAN_CREATE, PermissionsEnum.DAILY_PLAN_UPDATE) @Put(':id/task') // Endpoint for removing a task from a daily plan async removeTaskFromDailyPlan( - @Param('id') planId: IDailyPlan['id'], // Extract the daily plan ID from the URL parameter + @Param('id') planId: ID, // Extract the daily plan ID from the URL parameter @Body() input: IDailyPlanTasksUpdateInput // Data for updating the daily plan ): Promise { // Call the service to remove the task from the daily plan @@ -200,7 +219,7 @@ export class DailyPlanController extends CrudController { }) @Put(':taskId/remove') // Endpoint for removing a task from many daily plans async removeTaskFromManyPlans( - @Param('taskId') taskId: ITask['id'], + @Param('taskId') taskId: ID, @Body() input: RemoveTaskFromManyPlansDTO ): Promise { return this.dailyPlanService.removeTaskFromManyPlans(taskId, input); @@ -275,10 +294,7 @@ export class DailyPlanController extends CrudController { @Permissions(PermissionsEnum.ALL_ORG_EDIT, PermissionsEnum.DAILY_PLAN_UPDATE) @Put(':id') @UseValidationPipe({ transform: true, whitelist: true }) - async update( - @Query('id') id: IDailyPlan['id'], - @Body() entity: UpdateDailyPlanDTO - ): Promise { + async update(@Query('id') id: ID, @Body() entity: UpdateDailyPlanDTO): Promise { return await this.dailyPlanService.updateDailyPlan(id, entity); } @@ -303,7 +319,7 @@ export class DailyPlanController extends CrudController { }) @Permissions(PermissionsEnum.ALL_ORG_EDIT, PermissionsEnum.DAILY_PLAN_DELETE) @Delete(':id') - async delete(@Param('id') planId: IDailyPlan['id']) { - return await this.dailyPlanService.deletePlan(planId); + async delete(@Param('id') planId: ID) { + return await this.dailyPlanService.delete(planId); } } diff --git a/packages/core/src/tasks/daily-plan/daily-plan.entity.ts b/packages/core/src/tasks/daily-plan/daily-plan.entity.ts index 8c65e8729fa..d14d575c6b1 100644 --- a/packages/core/src/tasks/daily-plan/daily-plan.entity.ts +++ b/packages/core/src/tasks/daily-plan/daily-plan.entity.ts @@ -3,7 +3,7 @@ import { JoinColumn, JoinTable, RelationId } from 'typeorm'; import { EntityRepositoryType } from '@mikro-orm/knex'; import { IsDate, IsNotEmpty, IsNumber, IsOptional, IsString, IsUUID } from 'class-validator'; import { Type } from 'class-transformer'; -import { DailyPlanStatusEnum, IDailyPlan, IEmployee, ITask } from '@gauzy/contracts'; +import { DailyPlanStatusEnum, ID, IDailyPlan, IEmployee, IOrganizationTeam, ITask } from '@gauzy/contracts'; import { ColumnIndex, MultiORMColumn, @@ -11,7 +11,7 @@ import { MultiORMManyToMany, MultiORMManyToOne } from '../../core/decorators/entity'; -import { Employee, Task, TenantOrganizationBaseEntity } from '../../core/entities/internal'; +import { Employee, OrganizationTeam, Task, TenantOrganizationBaseEntity } from '../../core/entities/internal'; import { MikroOrmDailyPlanRepository } from './repository'; @MultiORMEntity('daily_plan', { mikroOrmRepository: () => MikroOrmDailyPlanRepository }) @@ -61,7 +61,28 @@ export class DailyPlan extends TenantOrganizationBaseEntity implements IDailyPla @RelationId((it: DailyPlan) => it.employee) @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) - employeeId?: IEmployee['id']; + employeeId?: ID; + + /** + * OrganizationTeam + */ + @MultiORMManyToOne(() => OrganizationTeam, { + /** Indicates if relation column value can be nullable or not. */ + nullable: true, + + /** Database cascade action on delete. */ + onDelete: 'CASCADE' + }) + @JoinColumn() + organizationTeam?: IOrganizationTeam; + + @ApiPropertyOptional({ type: () => String }) + @IsOptional() + @IsUUID() + @RelationId((it: DailyPlan) => it.organizationTeam) + @ColumnIndex() + @MultiORMColumn({ nullable: true, relationId: true }) + organizationTeamId?: ID; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/tasks/daily-plan/daily-plan.service.ts b/packages/core/src/tasks/daily-plan/daily-plan.service.ts index 6626953d31d..5fabc553623 100644 --- a/packages/core/src/tasks/daily-plan/daily-plan.service.ts +++ b/packages/core/src/tasks/daily-plan/daily-plan.service.ts @@ -1,15 +1,15 @@ -import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; +import { BadRequestException, HttpException, HttpStatus, Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { SelectQueryBuilder, UpdateResult } from 'typeorm'; import { + ID, IDailyPlan, IDailyPlanCreateInput, IDailyPlansTasksUpdateInput, IDailyPlanTasksUpdateInput, IDailyPlanUpdateInput, IEmployee, - IPagination, - ITask + IPagination } from '@gauzy/contracts'; import { isNotEmpty } from '@gauzy/common'; import { prepareSQLQuery as p } from '../../database/database.helper'; @@ -146,10 +146,7 @@ export class DailyPlanService extends TenantAwareCrudService { * @returns A promise that resolves to an object containing the list of daily plans and the total count. * @throws BadRequestException - If there's an error during the query. */ - async getDailyPlansByEmployee( - options: PaginationParams, - employeeId?: IEmployee['id'] - ): Promise> { + async getDailyPlansByEmployee(options: PaginationParams, employeeId?: ID): Promise> { try { // Fetch all daily plans for specific employee return await this.getAllPlans(options, employeeId); @@ -158,6 +155,54 @@ export class DailyPlanService extends TenantAwareCrudService { } } + /** + * Retrieves daily plans for all employees of a specific team with pagination and additional query options. + * + * @param teamId - The ID of the team for whom to retrieve daily plans. + * @param options - Pagination and additional query options for filtering and retrieving daily plans. + * @returns A promise that resolves to an object containing the list of daily plans and the total count. + * @throws BadRequestException - If there's an error during the query. + */ + async getTeamDailyPlans(options: PaginationParams): Promise> { + try { + // Apply optional find options if provided + const { where, relations = [] } = options || {}; + const { organizationId, organizationTeamId } = where; + const tenantId = RequestContext.currentTenantId(); + + // Create the initial query + const query = this.typeOrmRepository.createQueryBuilder(this.tableName); + + // Join related entities + query.leftJoinAndSelect(`${query.alias}.employee`, 'employee'); + query.leftJoinAndSelect(`${query.alias}.tasks`, 'tasks'); + + query.setFindOptions({ + where: isNotEmpty(where) && where, + relations: isNotEmpty(relations) && relations + }); + + // Filter conditions + query.where(p(`"${query.alias}"."tenantId" = :tenantId`), { tenantId }); + query.andWhere(p(`"${query.alias}"."organizationId" = :organizationId`), { organizationId }); + + if (organizationTeamId) { + query.andWhere(p(`"${query.alias}"."organizationTeamId" = :organizationTeamId`), { + organizationTeamId + }); + } + + // Retrieve results and total count + const [items, total] = await query.getManyAndCount(); + + // Return the pagination result + return { items, total }; + } catch (error) { + console.log('Error while fetching daily plans for team'); + throw new HttpException(`Failed to fetch daily plans for team: ${error.message}`, HttpStatus.BAD_REQUEST); + } + } + /** * Retrieves daily plans for the current employee based on given pagination options. * @@ -183,7 +228,7 @@ export class DailyPlanService extends TenantAwareCrudService { * @param input - An object containing details about the task to add, including task ID, employee ID, and organization ID. * @returns The updated daily plan with the newly added task. */ - async addTaskToPlan(planId: IDailyPlan['id'], input: IDailyPlanTasksUpdateInput): Promise { + async addTaskToPlan(planId: ID, input: IDailyPlanTasksUpdateInput): Promise { try { const tenantId = RequestContext.currentTenantId(); const { employeeId, taskId, organizationId } = input; @@ -224,7 +269,7 @@ export class DailyPlanService extends TenantAwareCrudService { * @param input - An object containing details about the task to remove, including task ID, employee ID, and organization ID. * @returns The updated daily plan without the deleted task. */ - async removeTaskFromPlan(planId: IDailyPlan['id'], input: IDailyPlanTasksUpdateInput): Promise { + async removeTaskFromPlan(planId: ID, input: IDailyPlanTasksUpdateInput): Promise { try { const tenantId = RequestContext.currentTenantId(); const { employeeId, taskId, organizationId } = input; @@ -269,7 +314,7 @@ export class DailyPlanService extends TenantAwareCrudService { * @returns The updated daily plans without the deleted task. */ - async removeTaskFromManyPlans(taskId: ITask['id'], input: IDailyPlansTasksUpdateInput): Promise { + async removeTaskFromManyPlans(taskId: ID, input: IDailyPlansTasksUpdateInput): Promise { try { const tenantId = RequestContext.currentTenantId(); const { employeeId, plansIds, organizationId } = input; @@ -343,10 +388,7 @@ export class DailyPlanService extends TenantAwareCrudService { * @returns The updated daily plan including related tasks. * @memberof DailyPlanService */ - async updateDailyPlan( - id: IDailyPlan['id'], - partialEntity: IDailyPlanUpdateInput - ): Promise { + async updateDailyPlan(id: ID, partialEntity: IDailyPlanUpdateInput): Promise { try { const { employeeId, organizationId } = partialEntity; @@ -378,24 +420,13 @@ export class DailyPlanService extends TenantAwareCrudService { } } - /** - * DELETE daily plan - * - * @param {IDailyPlan['id']} planId - * @returns - * @memberof DailyPlanService - */ - async deletePlan(planId: IDailyPlan['id']) { - return await super.delete(planId); - } - /** * Retrieves daily plans for a specific task including employee * @param options pagination and additional query options * @param taskId - The ID of the task for whom to retrieve daily plans. * @returns A promise that resolves to an object containing the list of plans and total count */ - async getDailyPlansByTask(options: PaginationParams, taskId: ITask['id']): Promise> { + async getDailyPlansByTask(options: PaginationParams, taskId: ID): Promise> { try { const { where } = options; const { organizationId } = where; diff --git a/packages/core/src/tasks/daily-plan/dto/create-daily-plan.dto.ts b/packages/core/src/tasks/daily-plan/dto/create-daily-plan.dto.ts index 4ea9fb927fa..55104387f12 100644 --- a/packages/core/src/tasks/daily-plan/dto/create-daily-plan.dto.ts +++ b/packages/core/src/tasks/daily-plan/dto/create-daily-plan.dto.ts @@ -1,18 +1,18 @@ import { ApiProperty, ApiPropertyOptional, IntersectionType } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { IsDate, IsEnum, IsNotEmpty, IsNumber, IsOptional, IsUUID } from 'class-validator'; -import { DailyPlanStatusEnum, IDailyPlanCreateInput, ITask } from '@gauzy/contracts'; +import { DailyPlanStatusEnum, ID, IDailyPlanCreateInput } from '@gauzy/contracts'; import { TenantOrganizationBaseDTO } from '../../../core/dto'; import { EmployeeFeatureDTO } from '../../../employee/dto'; +import { OrganizationTeamFeatureDTO } from '../../../organization-team/dto'; /** * Create Daily Plan DTO validation */ -export class CreateDailyPlanDTO extends IntersectionType( - TenantOrganizationBaseDTO, - EmployeeFeatureDTO -) implements IDailyPlanCreateInput { - +export class CreateDailyPlanDTO + extends IntersectionType(TenantOrganizationBaseDTO, EmployeeFeatureDTO, OrganizationTeamFeatureDTO) + implements IDailyPlanCreateInput +{ @ApiProperty({ type: () => Date }) @Type(() => Date) @IsNotEmpty() @@ -32,5 +32,5 @@ export class CreateDailyPlanDTO extends IntersectionType( @ApiPropertyOptional({ type: () => String }) @IsOptional() @IsUUID() - readonly taskId?: ITask['id']; + readonly taskId?: ID; } diff --git a/packages/core/src/tasks/daily-plan/dto/update-daily-plan.dto.ts b/packages/core/src/tasks/daily-plan/dto/update-daily-plan.dto.ts index c8460b014b4..1a04eac7e9f 100644 --- a/packages/core/src/tasks/daily-plan/dto/update-daily-plan.dto.ts +++ b/packages/core/src/tasks/daily-plan/dto/update-daily-plan.dto.ts @@ -10,6 +10,8 @@ import { CreateDailyPlanDTO } from './create-daily-plan.dto'; export class UpdateDailyPlanDTO extends IntersectionType( TenantOrganizationBaseDTO, - PartialType(PickType(CreateDailyPlanDTO, ['date', 'workTimePlanned', 'status', 'employeeId'])) + PartialType( + PickType(CreateDailyPlanDTO, ['date', 'workTimePlanned', 'status', 'employeeId', 'organizationTeamId']) + ) ) implements IDailyPlanUpdateInput {} diff --git a/packages/core/src/tasks/statuses/default-global-statuses.ts b/packages/core/src/tasks/statuses/default-global-statuses.ts index f1b1b97e0eb..60e3870fe42 100644 --- a/packages/core/src/tasks/statuses/default-global-statuses.ts +++ b/packages/core/src/tasks/statuses/default-global-statuses.ts @@ -1,64 +1,121 @@ import { ITaskStatus, TaskStatusEnum } from '@gauzy/contracts'; export const DEFAULT_GLOBAL_STATUSES: ITaskStatus[] = [ + { + name: TaskStatusEnum.BACKLOG, + value: TaskStatusEnum.BACKLOG, + description: 'The issue/task has been reported and is waiting for the team to action it.', + icon: 'task-statuses/backlog.svg', + order: 0, + color: '#FFCC00', + isSystem: true, + isCollapsed: false, + isTodo: true, + isInProgress: false, + isDone: false + }, { name: TaskStatusEnum.OPEN, value: TaskStatusEnum.OPEN, - description: 'The issue/task has been reported and is waiting for the team to action it.', + description: 'The issue/task has being processed or ready to start', icon: 'task-statuses/open.svg', - order: 0, + order: 1, color: '#D6E4F9', isSystem: true, - isCollapsed: false + isCollapsed: false, + isTodo: true, + isInProgress: false, + isDone: false }, { name: TaskStatusEnum.IN_PROGRESS, value: TaskStatusEnum.IN_PROGRESS, description: 'This issue/task is being actively worked on at the moment by the assignee.', icon: 'task-statuses/in-progress.svg', - order: 1, + order: 2, color: '#ECE8FC', isSystem: true, - isCollapsed: false + isCollapsed: false, + isTodo: false, + isInProgress: true, + isDone: false }, { name: TaskStatusEnum.READY_FOR_REVIEW, value: TaskStatusEnum.READY_FOR_REVIEW, description: 'At this point the merge request / pull request is ready to be reviewed for issue/task.', icon: 'task-statuses/ready.svg', - order: 2, + order: 3, color: '#F5F1CB', isSystem: true, - isCollapsed: false + isCollapsed: false, + isTodo: false, + isInProgress: true, + isDone: false }, { name: TaskStatusEnum.IN_REVIEW, value: TaskStatusEnum.IN_REVIEW, description: 'It needs peer review issue/task before being considered done.', icon: 'task-statuses/in-review.svg', - order: 3, + order: 4, color: '#F3D8B0', isSystem: true, - isCollapsed: false + isCollapsed: false, + isTodo: false, + isInProgress: true, + isDone: false }, { name: TaskStatusEnum.BLOCKED, value: TaskStatusEnum.BLOCKED, description: 'The issue/task is missing information, wait for customer decision, etc.', icon: 'task-statuses/blocked.svg', - order: 4, + order: 5, color: '#F5B8B8', isSystem: true, - isCollapsed: false + isCollapsed: false, + isTodo: false, + isInProgress: true, + isDone: false + }, + { + name: TaskStatusEnum.DONE, + value: TaskStatusEnum.DONE, + description: 'The issue/task has been carried out and delivered according to specifications.', + icon: 'task-statuses/done.svg', + order: 6, + color: '#4CAF50', + isSystem: true, + isCollapsed: false, + isTodo: false, + isInProgress: false, + isDone: true }, { name: TaskStatusEnum.COMPLETED, value: TaskStatusEnum.COMPLETED, description: 'The issue/task is considered finished. The resolution is correct.', icon: 'task-statuses/completed.svg', - order: 5, + order: 7, color: '#D4EFDF', isSystem: true, - isCollapsed: false + isCollapsed: false, + isTodo: false, + isInProgress: false, + isDone: true }, + { + name: TaskStatusEnum.CUSTOM, + value: TaskStatusEnum.CUSTOM, + description: 'Custom issue type', + icon: 'task-statuses/custom.svg', + order: 8, + color: '#D4EFDF', + isSystem: true, + isCollapsed: false, + isTodo: false, + isInProgress: false, + isDone: false + } ]; diff --git a/packages/core/src/tasks/statuses/dto/create-status.dto.ts b/packages/core/src/tasks/statuses/dto/create-status.dto.ts index 452948194b0..fead457cbdd 100644 --- a/packages/core/src/tasks/statuses/dto/create-status.dto.ts +++ b/packages/core/src/tasks/statuses/dto/create-status.dto.ts @@ -1,9 +1,8 @@ -import { ITaskStatusCreateInput } from '@gauzy/contracts'; import { IntersectionType, PartialType } from '@nestjs/swagger'; +import { ITaskStatusCreateInput } from '@gauzy/contracts'; import { TaskStatus } from '../status.entity'; import { TenantOrganizationBaseDTO } from './../../../core/dto'; -export class CreateStatusDTO extends IntersectionType( - PartialType(TenantOrganizationBaseDTO), - TaskStatus -) implements ITaskStatusCreateInput { } +export class CreateStatusDTO + extends IntersectionType(PartialType(TenantOrganizationBaseDTO), TaskStatus) + implements ITaskStatusCreateInput {} diff --git a/packages/core/src/tasks/statuses/dto/status-query.dto.ts b/packages/core/src/tasks/statuses/dto/status-query.dto.ts index e747cdadf62..f48c3cb5ba7 100644 --- a/packages/core/src/tasks/statuses/dto/status-query.dto.ts +++ b/packages/core/src/tasks/statuses/dto/status-query.dto.ts @@ -1,9 +1,11 @@ -import { ITaskStatusFindInput } from '@gauzy/contracts'; import { IntersectionType, PartialType, PickType } from '@nestjs/swagger'; +import { ITaskStatusFindInput } from '@gauzy/contracts'; import { TenantOrganizationBaseDTO } from './../../../core/dto'; import { TaskStatus } from './../status.entity'; -export class StatusQueryDTO extends IntersectionType( - PartialType(TenantOrganizationBaseDTO), - PickType(TaskStatus, ['projectId', 'organizationTeamId']) -) implements ITaskStatusFindInput { } +export class StatusQueryDTO + extends IntersectionType( + PartialType(TenantOrganizationBaseDTO), + PickType(TaskStatus, ['projectId', 'organizationTeamId']) + ) + implements ITaskStatusFindInput {} diff --git a/packages/core/src/tasks/statuses/dto/update-status.dto.ts b/packages/core/src/tasks/statuses/dto/update-status.dto.ts index f0677d1d2aa..62cbef6e54a 100644 --- a/packages/core/src/tasks/statuses/dto/update-status.dto.ts +++ b/packages/core/src/tasks/statuses/dto/update-status.dto.ts @@ -1,9 +1,8 @@ -import { ITaskStatusUpdateInput } from '@gauzy/contracts'; import { IntersectionType, PartialType } from '@nestjs/swagger'; +import { ITaskStatusUpdateInput } from '@gauzy/contracts'; import { TenantOrganizationBaseDTO } from './../../../core/dto'; import { TaskStatus } from '../status.entity'; -export class UpdatesStatusDTO extends IntersectionType( - PartialType(TenantOrganizationBaseDTO), - PartialType(TaskStatus) -) implements ITaskStatusUpdateInput { } +export class UpdatesStatusDTO + extends IntersectionType(PartialType(TenantOrganizationBaseDTO), PartialType(TaskStatus)) + implements ITaskStatusUpdateInput {} diff --git a/packages/core/src/tasks/statuses/standard-statuses-template.ts b/packages/core/src/tasks/statuses/standard-statuses-template.ts new file mode 100644 index 00000000000..0160d45ec89 --- /dev/null +++ b/packages/core/src/tasks/statuses/standard-statuses-template.ts @@ -0,0 +1,16 @@ +import { TaskStatusEnum, TaskStatusWorkFlow } from '@gauzy/contracts'; + +/** + * Default task statuses + */ +export const TASK_STATUSES_TEMPLATES: { [key in TaskStatusEnum]: TaskStatusWorkFlow } = { + [TaskStatusEnum.BACKLOG]: { isTodo: true, isInProgress: false, isDone: false }, + [TaskStatusEnum.OPEN]: { isTodo: true, isInProgress: false, isDone: false }, + [TaskStatusEnum.IN_PROGRESS]: { isTodo: false, isInProgress: true, isDone: false }, + [TaskStatusEnum.READY_FOR_REVIEW]: { isTodo: false, isInProgress: true, isDone: false }, + [TaskStatusEnum.IN_REVIEW]: { isTodo: false, isInProgress: true, isDone: false }, + [TaskStatusEnum.BLOCKED]: { isTodo: false, isInProgress: true, isDone: false }, + [TaskStatusEnum.DONE]: { isTodo: false, isInProgress: false, isDone: true }, + [TaskStatusEnum.COMPLETED]: { isTodo: false, isInProgress: false, isDone: true }, + [TaskStatusEnum.CUSTOM]: { isTodo: false, isInProgress: false, isDone: false } +}; diff --git a/packages/core/src/tasks/statuses/status.entity.ts b/packages/core/src/tasks/statuses/status.entity.ts index b19381d8742..39dea26a901 100644 --- a/packages/core/src/tasks/statuses/status.entity.ts +++ b/packages/core/src/tasks/statuses/status.entity.ts @@ -1,15 +1,20 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { RelationId } from 'typeorm'; import { EntityRepositoryType } from '@mikro-orm/knex'; -import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; -import { IOrganizationProject, IOrganizationTeam, ITaskStatus } from '@gauzy/contracts'; +import { IsBoolean, IsEnum, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; +import { ID, IOrganizationProject, IOrganizationTeam, ITaskStatus, TaskStatusEnum } from '@gauzy/contracts'; import { OrganizationProject, OrganizationTeam, TenantOrganizationBaseEntity } from '../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from '../../core/decorators/entity'; +import { + ColumnIndex, + MultiORMColumn, + MultiORMEntity, + MultiORMManyToOne, + VirtualMultiOrmColumn +} from '../../core/decorators/entity'; import { MikroOrmTaskStatusRepository } from './repository'; @MultiORMEntity('task_status', { mikroOrmRepository: () => MikroOrmTaskStatusRepository }) export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskStatus { - [EntityRepositoryType]?: MikroOrmTaskStatusRepository; @ApiProperty({ type: () => String }) @@ -54,7 +59,31 @@ export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskSta @MultiORMColumn({ default: false }) isCollapsed?: boolean; + @ApiPropertyOptional({ type: () => Boolean, default: false }) + @IsOptional() + @IsBoolean() + @MultiORMColumn({ default: false }) + isTodo?: boolean; + + @ApiPropertyOptional({ type: () => Boolean, default: false }) + @IsOptional() + @IsBoolean() + @MultiORMColumn({ default: false }) + isInProgress?: boolean; + + @ApiPropertyOptional({ type: () => Boolean, default: false }) + @IsOptional() + @IsBoolean() + @MultiORMColumn({ default: false }) + isDone?: boolean; + /** Additional virtual columns */ + @ApiPropertyOptional({ type: () => String, enum: TaskStatusEnum }) + @IsOptional() + @IsEnum(TaskStatusEnum) + @VirtualMultiOrmColumn() + template?: TaskStatusEnum; + @VirtualMultiOrmColumn() fullIconUrl?: string; /* @@ -84,7 +113,7 @@ export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskSta @RelationId((it: TaskStatus) => it.project) @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) - projectId?: IOrganizationProject['id']; + projectId?: ID; /** * Organization Team @@ -104,5 +133,5 @@ export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskSta @RelationId((it: TaskStatus) => it.organizationTeam) @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) - organizationTeamId?: IOrganizationTeam['id']; + organizationTeamId?: ID; } diff --git a/packages/core/src/tasks/statuses/status.service.ts b/packages/core/src/tasks/statuses/status.service.ts index 588dfa79acd..7c4d7bb08db 100644 --- a/packages/core/src/tasks/statuses/status.service.ts +++ b/packages/core/src/tasks/statuses/status.service.ts @@ -1,4 +1,4 @@ -import { BadRequestException, Injectable, Logger } from '@nestjs/common'; +import { BadRequestException, HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { DeleteResult } from 'typeorm'; import { Knex as KnexConnection } from 'knex'; @@ -15,11 +15,13 @@ import { ITenant } from '@gauzy/contracts'; import { isPostgres } from '@gauzy/config'; -import { TaskStatusPrioritySizeService } from '../task-status-priority-size.service'; import { RequestContext } from '../../core/context'; import { MultiORMEnum } from '../../core/utils'; +import { IPartialEntity } from '../../core/crud/icrud.service'; +import { TaskStatusPrioritySizeService } from '../task-status-priority-size.service'; import { TaskStatus } from './status.entity'; import { DEFAULT_GLOBAL_STATUSES } from './default-global-statuses'; +import { TASK_STATUSES_TEMPLATES } from './standard-statuses-template'; import { MikroOrmTaskStatusRepository, TypeOrmTaskStatusRepository } from './repository'; @Injectable() @@ -30,16 +32,35 @@ export class TaskStatusService extends TaskStatusPrioritySizeService constructor( @InjectRepository(TaskStatus) readonly typeOrmTaskStatusRepository: TypeOrmTaskStatusRepository, - readonly mikroOrmTaskStatusRepository: MikroOrmTaskStatusRepository, - - @InjectConnection() - readonly knexConnection: KnexConnection + @InjectConnection() readonly knexConnection: KnexConnection ) { console.log(`TaskStatusService initialized. Unique Service ID: ${uuidv4()} `); super(typeOrmTaskStatusRepository, mikroOrmTaskStatusRepository, knexConnection); } + /** + * Create task status + * + * @param entity - object that contains the input values and template to be used + * @returns - a promise that resolves after task status created + */ + public async create(entity: IPartialEntity): Promise { + try { + // Extract the template from the entity + const { template, ...partialEntity } = entity; + + // Get the work flow for the template + const workFlow = TASK_STATUSES_TEMPLATES[template]; + + // Save the entity with the work flow + return await this.save({ ...partialEntity, ...workFlow }); + } catch (error) { + // Handle errors and return an appropriate error response + throw new HttpException(`Failed to add task status: ${error.message}`, HttpStatus.BAD_REQUEST); + } + } + /** * GET statuses by filters * If parameters not match, retrieve global statuses diff --git a/packages/desktop-libs/src/index.ts b/packages/desktop-libs/src/index.ts index 645221ed9a6..294dfa43de8 100644 --- a/packages/desktop-libs/src/index.ts +++ b/packages/desktop-libs/src/index.ts @@ -23,3 +23,4 @@ export * from './lib/states'; export * from './lib/strategies'; export * from './lib/translation'; export * from './lib/update-server/desktop-local-update-server'; +export * from './lib/desktop-theme-listener'; diff --git a/packages/desktop-libs/src/lib/desktop-ipc.ts b/packages/desktop-libs/src/lib/desktop-ipc.ts index 4d90d0838d2..1af87397a92 100644 --- a/packages/desktop-libs/src/lib/desktop-ipc.ts +++ b/packages/desktop-libs/src/lib/desktop-ipc.ts @@ -357,6 +357,10 @@ export function ipcMainHandler(store, startServer, knex, config, timeTrackerWind } }); + ipcMain.handle('SAVED_THEME', () => { + return LocalStore.getStore('appSetting').theme; + }) + pluginListeners(); } diff --git a/packages/desktop-libs/src/lib/desktop-menu.ts b/packages/desktop-libs/src/lib/desktop-menu.ts index 65617c97b26..9870254cf28 100644 --- a/packages/desktop-libs/src/lib/desktop-menu.ts +++ b/packages/desktop-libs/src/lib/desktop-menu.ts @@ -1,11 +1,16 @@ +import { createAboutWindow, createSettingsWindow } from '@gauzy/desktop-window'; import { BrowserWindow, Menu, MenuItemConstructorOptions, shell } from 'electron'; import { LocalStore } from './desktop-store'; -import { createSettingsWindow, createAboutWindow } from '@gauzy/desktop-window'; -import { TranslateService } from './translation'; import { TimerService } from './offline'; +import { PluginManager } from './plugin-system/data-access/plugin-manager'; +import { PluginEventManager } from './plugin-system/events/plugin-event.manager'; +import { TranslateService } from './translation'; export class AppMenu { public menu: MenuItemConstructorOptions[] = []; + private readonly pluginManager = PluginManager.getInstance(); + private readonly pluginEventManager = PluginEventManager.getInstance(); + constructor(timeTrackerWindow, settingsWindow, updaterWindow, knex, windowPath, serverWindow?, isZoomVisible?) { const isZoomEnabled = isZoomVisible; this.menu = [ @@ -63,7 +68,11 @@ export class AppMenu { enabled: true, async click() { if (!settingsWindow) { - settingsWindow = await createSettingsWindow(settingsWindow, windowPath.timeTrackerUi, windowPath.preloadPath); + settingsWindow = await createSettingsWindow( + settingsWindow, + windowPath.timeTrackerUi, + windowPath.preloadPath + ); } settingsWindow.show(); settingsWindow.webContents.send('app_setting', LocalStore.getApplicationConfig()); @@ -108,6 +117,7 @@ export class AppMenu { } ] }, + this.pluginMenu, { label: TranslateService.instant('TIMER_TRACKER.MENU.HELP'), submenu: [ @@ -159,9 +169,37 @@ export class AppMenu { if (updaterWindow) { updaterWindow.webContents.send('refresh_menu'); } + + this.pluginEventManager.listen(() => { + // Determine if the updated menu + const updatedMenu = this.menu.map((menu) => (menu.id === 'plugin-menu' ? this.pluginMenu : menu)); + // Only rebuild the menu if there was an actual change + if (!this.deepArrayEqual(this.menu, updatedMenu)) { + this.menu = updatedMenu; + this.build(); + console.log('Menu rebuilt after plugin update.'); + } else { + console.log('Plugin update detected, but no changes were made to the menu.'); + } + }); } public build(): void { Menu.setApplicationMenu(Menu.buildFromTemplate([...this.menu])); } + + public get pluginMenu(): MenuItemConstructorOptions { + const submenu = this.pluginManager.getMenuPlugins(); + + return { + id: 'plugin-menu', + label: TranslateService.instant('TIMER_TRACKER.SETTINGS.PLUGIN'), + visible: submenu.length > 0, + submenu + } as MenuItemConstructorOptions; + } + + private deepArrayEqual(arr1: T, arr2: T) { + return JSON.stringify(arr1) === JSON.stringify(arr2); + } } diff --git a/packages/desktop-libs/src/lib/desktop-theme-listener.ts b/packages/desktop-libs/src/lib/desktop-theme-listener.ts new file mode 100644 index 00000000000..d2d69c26892 --- /dev/null +++ b/packages/desktop-libs/src/lib/desktop-theme-listener.ts @@ -0,0 +1,69 @@ +import { + ipcMain, + BrowserWindow, +} from 'electron'; +import { LocalStore } from './desktop-store'; +export class DesktopThemeListener { + private desktopWindow: { + gauzyWindow?: BrowserWindow; + timeTrackerWindow?: BrowserWindow; + imageViewerWindow?: BrowserWindow; + splashScreenWindow?: BrowserWindow; + settingsWindow?: BrowserWindow; + setupWindow?: BrowserWindow; + updaterWindow?: BrowserWindow; + popupWindow?: BrowserWindow; + alwaysOnWindow?: BrowserWindow; + serverWindow?: BrowserWindow; + } = {} + constructor( + desktopWindow: { + gauzyWindow?: BrowserWindow; + timeTrackerWindow?: BrowserWindow; + imageViewerWindow?: BrowserWindow; + splashScreenWindow?: BrowserWindow; + settingsWindow?: BrowserWindow; + setupWindow?: BrowserWindow; + updaterWindow?: BrowserWindow; + popupWindow?: BrowserWindow; + alwaysOnWindow?: BrowserWindow; + serverWindow?: BrowserWindow; + } + ) { + this.desktopWindow = desktopWindow; + } + + public listen() { + ipcMain.removeAllListeners('THEME_CHANGE'); + ipcMain.on('THEME_CHANGE', async (_, theme) => { + LocalStore.updateApplicationSetting({ theme }); + if (this.desktopWindow.gauzyWindow) { + this.desktopWindow.gauzyWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.timeTrackerWindow) { + this.desktopWindow.timeTrackerWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.imageViewerWindow) { + this.desktopWindow.imageViewerWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.splashScreenWindow) { + this.desktopWindow.splashScreenWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.settingsWindow) { + this.desktopWindow.settingsWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.setupWindow) { + this.desktopWindow.setupWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.updaterWindow) { + this.desktopWindow.updaterWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.alwaysOnWindow) { + this.desktopWindow.alwaysOnWindow.webContents.send('THEME_CHANGE', theme); + } + if (this.desktopWindow.serverWindow) { + this.desktopWindow.serverWindow.webContents.send('THEME_CHANGE', theme); + } + }); + } +} diff --git a/packages/desktop-libs/src/lib/plugin-system/data-access/plugin-manager.ts b/packages/desktop-libs/src/lib/plugin-system/data-access/plugin-manager.ts index 4ba3825e68f..451b025bb03 100644 --- a/packages/desktop-libs/src/lib/plugin-system/data-access/plugin-manager.ts +++ b/packages/desktop-libs/src/lib/plugin-system/data-access/plugin-manager.ts @@ -1,18 +1,30 @@ -import { app } from 'electron'; +import { app, MenuItemConstructorOptions } from 'electron'; import * as logger from 'electron-log'; import * as fs from 'fs'; import * as path from 'path'; import { PluginMetadataService } from '../database/plugin-metadata.service'; +import { PluginEventManager } from '../events/plugin-event.manager'; import { IPlugin, IPluginManager, IPluginMetadata, PluginDownloadContextType } from '../shared'; import { lazyLoader } from '../shared/lazy-loader'; import { DownloadContextFactory } from './download-context.factory'; export class PluginManager implements IPluginManager { private plugins: Map = new Map(); - private activePlugins: Set = new Set(); + private activePlugins: Set = new Set(); private pluginMetadataService = new PluginMetadataService(); private pluginPath = path.join(app.getPath('userData'), 'plugins'); private factory = DownloadContextFactory; + private eventManager = PluginEventManager.getInstance(); + private static instance: IPluginManager; + + private constructor() {} + + public static getInstance(): IPluginManager { + if (!this.instance) { + this.instance = new PluginManager(); + } + return this.instance; + } public async downloadPlugin(config: U, contextType?: PluginDownloadContextType): Promise { logger.info(`Downloading plugin...`); @@ -25,7 +37,7 @@ export class PluginManager implements IPluginManager { } else { await this.installPlugin(metadata, pathDirname); } - fs.rmSync(pathDirname, { recursive: true, force: true }); + fs.rmSync(pathDirname, { recursive: true, force: true, retryDelay: 1000, maxRetries: 3 }); process.noAsar = false; } @@ -86,19 +98,19 @@ export class PluginManager implements IPluginManager { public async activatePlugin(name: string): Promise { const plugin = this.plugins.get(name); if (plugin) { - plugin.activate(); - this.activePlugins.add(name); + await plugin.activate(); + this.activePlugins.add(plugin); await this.pluginMetadataService.update({ name, isActivate: true }); - plugin.initialize(); + await plugin.initialize(); } } public async deactivatePlugin(name: string): Promise { const plugin = this.plugins.get(name); if (plugin) { - plugin.dispose(); - plugin.deactivate(); - this.activePlugins.delete(name); + await plugin.dispose(); + await plugin.deactivate(); + this.activePlugins.delete(plugin); await this.pluginMetadataService.update({ name, isActivate: false }); } } @@ -110,7 +122,7 @@ export class PluginManager implements IPluginManager { await this.deactivatePlugin(name); this.plugins.delete(name); await this.pluginMetadataService.delete({ name }); - fs.rmSync(metadata.pathname, { recursive: true, force: true }); + fs.rmSync(metadata.pathname, { recursive: true, force: true, retryDelay: 1000, maxRetries: 3 }); logger.info(`Uninstalling plugin ${name}`); } } @@ -127,6 +139,7 @@ export class PluginManager implements IPluginManager { await this.activatePlugin(metadata.name); } } + this.eventManager.notify(); } public getAllPlugins(): Promise { @@ -138,10 +151,21 @@ export class PluginManager implements IPluginManager { } public initializePlugins(): void { - this.plugins.forEach((plugin) => plugin.initialize()); + this.activePlugins.forEach(async (plugin) => await plugin.initialize()); } public disposePlugins(): void { - this.plugins.forEach((plugin) => plugin.dispose()); + this.activePlugins.forEach(async (plugin) => await plugin.dispose()); + } + + public getMenuPlugins(): MenuItemConstructorOptions[] { + try { + const plugins = Array.from(this.activePlugins); + logger.info('Active Plugins:', plugins); + return plugins.map((plugin) => plugin?.menu).filter((menu): menu is MenuItemConstructorOptions => !!menu); + } catch (error) { + logger.error('Error retrieving plugin submenu:', error); + return []; + } } } diff --git a/packages/desktop-libs/src/lib/plugin-system/events/plugin-event.manager.ts b/packages/desktop-libs/src/lib/plugin-system/events/plugin-event.manager.ts new file mode 100644 index 00000000000..ff1ea2c08c1 --- /dev/null +++ b/packages/desktop-libs/src/lib/plugin-system/events/plugin-event.manager.ts @@ -0,0 +1,29 @@ +import EventEmitter from 'events'; + +export enum PluginEvent { + NOTIFY = 'on::plugin::notify' +} + +export class PluginEventManager extends EventEmitter { + private static _instance: PluginEventManager; + + private constructor() { + super(); + this.removeAllListeners(PluginEvent.NOTIFY); + } + + public static getInstance(): PluginEventManager { + if (!this._instance) { + this._instance = new PluginEventManager(); + } + return PluginEventManager._instance; + } + + public notify(message?: string): void { + this.emit(PluginEvent.NOTIFY, message); + } + + public listen(listener: (message?: string) => T) { + this.on(PluginEvent.NOTIFY, listener.bind(this)); + } +} diff --git a/packages/desktop-libs/src/lib/plugin-system/events/plugin.event.ts b/packages/desktop-libs/src/lib/plugin-system/events/plugin.event.ts index 583ee0ef2db..08975c4857a 100644 --- a/packages/desktop-libs/src/lib/plugin-system/events/plugin.event.ts +++ b/packages/desktop-libs/src/lib/plugin-system/events/plugin.event.ts @@ -2,9 +2,11 @@ import { ipcMain, IpcMainEvent } from 'electron'; import * as logger from 'electron-log'; import { PluginManager } from '../data-access/plugin-manager'; import { IPluginManager, PluginChannel, PluginHandlerChannel } from '../shared'; +import { PluginEventManager } from './plugin-event.manager'; class ElectronPluginListener { private pluginManager: IPluginManager; + private eventManager = PluginEventManager.getInstance(); constructor(pluginManager: IPluginManager) { this.pluginManager = pluginManager; @@ -61,7 +63,7 @@ class ElectronPluginListener { return async (event: IpcMainEvent, ...args: any[]) => { try { await handler.call(this, event, ...args); - event.reply(PluginChannel.STATUS, { status: 'success' }); + this.eventManager.notify(); } catch (error: any) { logger.error('Error handling event:', error); event.reply(PluginChannel.STATUS, { status: 'error', message: error?.message ?? String(error) }); @@ -70,36 +72,50 @@ class ElectronPluginListener { } private async loadPlugins(event: IpcMainEvent): Promise { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugins loading...' }); await this.pluginManager.loadPlugins(); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugins loaded' }); } private initializePlugins(event: IpcMainEvent): void { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugins initializing' }); this.pluginManager.initializePlugins(); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugins initialized' }); } private disposePlugins(event: IpcMainEvent): void { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugins Disposing...' }); this.pluginManager.disposePlugins(); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugins Disposed' }); } private async downloadPlugin(event: IpcMainEvent, config: any): Promise { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugin Downloading...' }); await this.pluginManager.downloadPlugin(config); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugin Downloaded' }); } private async activatePlugin(event: IpcMainEvent, name: string): Promise { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugin Activating...' }); await this.pluginManager.activatePlugin(name); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugin Activated' }); } private async deactivatePlugin(event: IpcMainEvent, name: string): Promise { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugin Deactivating...' }); await this.pluginManager.deactivatePlugin(name); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugin Deactivated' }); } private async uninstallPlugin(event: IpcMainEvent, name: string): Promise { + event.reply(PluginChannel.STATUS, { status: 'inProgress', message: 'Plugin Uninstalling...' }); await this.pluginManager.uninstallPlugin(name); + event.reply(PluginChannel.STATUS, { status: 'success', message: 'Plugin Uninstalled' }); } } export async function pluginListeners(): Promise { - const pluginManager: IPluginManager = new PluginManager(); + const pluginManager: IPluginManager = PluginManager.getInstance(); const listener = new ElectronPluginListener(pluginManager); listener.registerListeners(); listener.registerHandlers(); diff --git a/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin-manager.interface.ts b/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin-manager.interface.ts index a416f1abc23..ee15a60d77e 100644 --- a/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin-manager.interface.ts +++ b/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin-manager.interface.ts @@ -1,3 +1,4 @@ +import { MenuItemConstructorOptions } from 'electron'; import { IPluginMetadata } from './plugin-metadata.interface'; export interface IPluginManager { @@ -10,4 +11,5 @@ export interface IPluginManager { uninstallPlugin(name: string): Promise; getAllPlugins(): Promise; getOnePlugin(name: string): Promise; + getMenuPlugins(): MenuItemConstructorOptions[]; } diff --git a/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin.interface.ts b/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin.interface.ts index 381bde9fab0..34bdfeef7b4 100644 --- a/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin.interface.ts +++ b/packages/desktop-libs/src/lib/plugin-system/shared/interfaces/plugin.interface.ts @@ -1,9 +1,10 @@ export interface IPlugin { name: string; version: string; - initialize(): void; - dispose(): void; - activate(): void; - deactivate(): void; + initialize(): Promise | void; + dispose(): Promise | void; + activate(): Promise | void; + deactivate(): Promise | void; component?(): void; + menu?: Electron.MenuItemConstructorOptions; } diff --git a/packages/desktop-ui-lib/src/index.ts b/packages/desktop-ui-lib/src/index.ts index e378b5ed433..b13d8ba14cb 100644 --- a/packages/desktop-ui-lib/src/index.ts +++ b/packages/desktop-ui-lib/src/index.ts @@ -37,7 +37,7 @@ export * from './lib/time-tracker/time-tracker.module'; export * from './lib/time-tracker/time-tracker.service'; export * from './lib/updater/updater.component'; export * from './lib/updater/updater.module'; - +export * from './lib/theme'; /** * Auth Module */ diff --git a/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.html b/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.html index 9ab9ad1da4e..c8381f4f55b 100644 --- a/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.html +++ b/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.html @@ -5,8 +5,8 @@
- +
diff --git a/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.ts b/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.ts index 274a2977f5e..4a7e9baf1cd 100644 --- a/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.ts +++ b/packages/desktop-ui-lib/src/lib/recap/features/recap/recap.component.ts @@ -2,6 +2,8 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { UntilDestroy } from '@ngneat/until-destroy'; import { Observable } from 'rxjs'; import { RecapQuery } from '../../+state/recap.query'; +import { RecapStore } from '../../+state/recap.store'; +import { IDateRangePicker } from '../../shared/features/date-range-picker/date-picker.interface'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -13,12 +15,16 @@ import { RecapQuery } from '../../+state/recap.query'; export class RecapComponent { private readonly basePath = ['/', 'time-tracker', 'daily']; - constructor(private readonly recapQuery: RecapQuery) {} + constructor(private readonly recapQuery: RecapQuery, private readonly recapStore: RecapStore) {} public get isLoading$(): Observable { return this.recapQuery.isLoading$; } + public onRangeChange(range: IDateRangePicker) { + this.recapStore.update({ range }); + } + public get segments() { return [ { diff --git a/packages/desktop-ui-lib/src/lib/recap/features/time-tracking-charts/time-tracking-charts.component.html b/packages/desktop-ui-lib/src/lib/recap/features/time-tracking-charts/time-tracking-charts.component.html index 21338713c02..d9e8247aaf5 100644 --- a/packages/desktop-ui-lib/src/lib/recap/features/time-tracking-charts/time-tracking-charts.component.html +++ b/packages/desktop-ui-lib/src/lib/recap/features/time-tracking-charts/time-tracking-charts.component.html @@ -3,7 +3,7 @@ m[m]': {trim: 'both'} }} · - {{dailyActivities$ | async}}% + {{dailyActivities$ | async | percent:'1.0-2' }} state.count.weekDuration)); } - public get dailyActivities$(): Observable { - return this.recapQuery.state$.pipe(map((state) => (state.count.weekActivities || 0).toFixed(2))); + public get dailyActivities$(): Observable { + return this.recapQuery.state$.pipe(map((state) => state.count.weekActivities / 100)); } public get chartData$(): Observable { diff --git a/packages/desktop-ui-lib/src/lib/recap/recap.module.ts b/packages/desktop-ui-lib/src/lib/recap/recap.module.ts index 07532ca784a..55baa500efc 100644 --- a/packages/desktop-ui-lib/src/lib/recap/recap.module.ts +++ b/packages/desktop-ui-lib/src/lib/recap/recap.module.ts @@ -43,6 +43,10 @@ import { AutoRefreshComponent } from './shared/ui/auto-refresh/auto-refresh.comp import { ProgressStatusModule } from './shared/ui/progress-status/progress-status.module'; import { ProjectColumnViewModule } from './shared/ui/project-column-view/project-column-view.module'; import { StatisticComponent } from './shared/ui/statistic/statistic.component'; +import { WeeklyCalendarComponent } from './weekly/features/weekly-calendar/weekly-calendar.component'; +import { WeeklyProgressComponent } from './weekly/features/weekly-progress/weekly-progress.component'; +import { WeeklyRecapComponent } from './weekly/features/weekly-recap/weekly-recap.component'; +import { WeeklyStatisticComponent } from './weekly/features/weekly-statistic/weekly-statistic.component'; @NgModule({ declarations: [ @@ -55,7 +59,11 @@ import { StatisticComponent } from './shared/ui/statistic/statistic.component'; StatisticComponent, AutoRefreshComponent, ActivityReportComponent, - SegmentedControlComponent + SegmentedControlComponent, + WeeklyRecapComponent, + WeeklyCalendarComponent, + WeeklyProgressComponent, + WeeklyStatisticComponent ], imports: [ CommonModule, @@ -95,6 +103,6 @@ import { StatisticComponent } from './shared/ui/statistic/statistic.component'; RequestQuery, RequestStore ], - exports: [RecapComponent] + exports: [RecapComponent, WeeklyRecapComponent] }) export class RecapModule {} diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/features/activity-report/activity-report.component.scss b/packages/desktop-ui-lib/src/lib/recap/shared/features/activity-report/activity-report.component.scss index 22294101eab..b8dfd836e41 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/features/activity-report/activity-report.component.scss +++ b/packages/desktop-ui-lib/src/lib/recap/shared/features/activity-report/activity-report.component.scss @@ -92,7 +92,7 @@ } .main-report-wrapper { - height: calc(100vh - 8.5rem); + height: calc(100vh - 8rem); margin-bottom: 0 !important; .main-report-body { diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-picker.utils.ts b/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-picker.utils.ts index 71e75907b09..d2a0110cb7c 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-picker.utils.ts +++ b/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-picker.utils.ts @@ -1,7 +1,9 @@ -import { IDateRangePicker, ISelectedDateRange, ITimeLogFilters, WeekDaysEnum } from '@gauzy/contracts'; -import * as moment from 'moment'; -import { TimePeriod } from './date-picker.interface'; +import { ISelectedDateRange, ITimeLogFilters, WeekDaysEnum } from '@gauzy/contracts'; +import * as momentDefault from 'moment'; +import { extendMoment } from 'moment-range'; +import { IDateRangePicker, TimePeriod } from './date-picker.interface'; +export const moment = extendMoment(momentDefault); /** * We are having issue, when organization not allowed future date * When someone run timer for today, all statistic not displaying correctly @@ -66,3 +68,18 @@ export function dayOfWeekAsString(weekDay: WeekDaysEnum): number { WeekDaysEnum.SATURDAY ].indexOf(weekDay); } + +/** + * Updates the week days based on the specified start and end dates. + * If no dates are provided in the request, it defaults to the current week. + */ +export function updateWeekDays(input: IDateRangePicker) { + const { startDate = moment().startOf('week'), endDate = moment().endOf('week') } = input; + + const start = moment(moment(startDate).format('YYYY-MM-DD')); + const end = moment(moment(endDate).format('YYYY-MM-DD')); + const range = Array.from(moment.range(start, end).by('day')); + const weekDays = range.map((date: moment.Moment) => date.format('YYYY-MM-DD')); + + return { range, weekDays }; +} diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.component.html b/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.component.html index d91dbe25433..523e39cf726 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.component.html +++ b/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.component.html @@ -12,7 +12,7 @@ (); + + @Input() + public set dates(range: IDateRangePicker) { + this.dates$.next({ + ...range, + isCustomDate: false + }); + } ngOnInit(): void { this.range$ @@ -188,48 +208,64 @@ export class DateRangePickerComponent implements OnInit, OnDestroy { distinctUntilChange(), debounceTime(500), tap((range: IDateRangePicker) => { - this.recapStore.update({ - range: { - startDate: moment(range.startDate).toISOString(), - endDate: moment(range.endDate).toISOString() - } + this.rangeChanges.emit({ + startDate: moment(range.startDate).toISOString(), + endDate: moment(range.endDate).toISOString() }); }), untilDestroyed(this) ) .subscribe(); - this.selectedDateRange = this.getSelectorDates(); - this.createDateRangeMenus(); - this.setPastStrategy(); - this.setFutureStrategy(); + this.store.selectedOrganization$ + .pipe( + filter((organization: IOrganization) => !!organization), + tap((organization: IOrganization) => { + this.futureDateAllowed = organization.futureDateAllowed; + this.selectedDateRange = this.getSelectorDates(); + this.createDateRangeMenus(); + this.setPastStrategy(); + this.setFutureStrategy(); + }), + untilDestroyed(this) + ) + .subscribe(); } /** * Create Date Range Translated Menus */ - createDateRangeMenus() { - this.ranges = { - [DateRangeKeyEnum.TODAY]: [moment(), moment()], - [DateRangeKeyEnum.YESTERDAY]: [moment().subtract(1, 'days'), moment().subtract(1, 'days')] + private createDateRangeMenus() { + const ranges = { + day: { + [DateRangeKeyEnum.TODAY]: [moment().startOf('day'), moment().endOf('day')], + [DateRangeKeyEnum.YESTERDAY]: [ + moment().subtract(1, 'days').startOf('day'), + moment().subtract(1, 'days').endOf('day') + ] + }, + week: { + [DateRangeKeyEnum.CURRENT_WEEK]: [moment().startOf('isoWeek'), moment().endOf('isoWeek')], + [DateRangeKeyEnum.LAST_WEEK]: [ + moment().subtract(1, 'week').startOf('isoWeek'), + moment().subtract(1, 'week').endOf('isoWeek') + ] + }, + month: { + [DateRangeKeyEnum.CURRENT_MONTH]: [moment().startOf('month'), moment().endOf('month')], + [DateRangeKeyEnum.LAST_MONTH]: [ + moment().subtract(1, 'month').startOf('month'), + moment().subtract(1, 'month').endOf('month') + ] + } }; - // Define the units of time to remove based on conditions - const unitsToRemove = []; - - if (this.isLockDatePicker && this.unitOfTime !== 'day') { - unitsToRemove.push(DateRangeKeyEnum.TODAY, DateRangeKeyEnum.YESTERDAY); - } - if (this.isLockDatePicker && this.unitOfTime !== 'week') { - unitsToRemove.push(DateRangeKeyEnum.CURRENT_WEEK, DateRangeKeyEnum.LAST_WEEK); - } - if (this.isLockDatePicker && this.unitOfTime !== 'month') { - unitsToRemove.push(DateRangeKeyEnum.CURRENT_MONTH, DateRangeKeyEnum.LAST_MONTH); - } - - // Remove date ranges based on unitsToRemove - unitsToRemove.forEach((unit) => { - delete this.ranges[unit]; - }); + this.ranges = this.isLockDatePicker + ? ranges[this.unitOfTime] + : ({ + ...ranges.day, + ...ranges.week, + ...ranges.month + } as any as DateRanges); } /** diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.module.ts b/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.module.ts index f39f85de76a..3954373be38 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.module.ts +++ b/packages/desktop-ui-lib/src/lib/recap/shared/features/date-range-picker/date-range-picker.module.ts @@ -8,6 +8,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { NgxDaterangepickerMd as NgxDateRangePickerMd } from 'ngx-daterangepicker-material'; import { RecapQuery } from '../../../+state/recap.query'; import { RecapStore } from '../../../+state/recap.store'; +import { PipeModule } from '../../../../time-tracker/pipes/pipe.module'; import { dayOfWeekAsString } from './date-picker.utils'; import { DateRangePickerComponent } from './date-range-picker.component'; @@ -22,6 +23,7 @@ import { DateRangePickerComponent } from './date-range-picker.component'; NbInputModule, NgSelectModule, TranslateModule, + PipeModule, NgxDateRangePickerMd.forRoot({ firstDay: dayOfWeekAsString(WeekDaysEnum.MONDAY) }) diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/features/segmented-control/segmented-control.component.scss b/packages/desktop-ui-lib/src/lib/recap/shared/features/segmented-control/segmented-control.component.scss index 715e0a9807a..fada4e0627f 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/features/segmented-control/segmented-control.component.scss +++ b/packages/desktop-ui-lib/src/lib/recap/shared/features/segmented-control/segmented-control.component.scss @@ -36,7 +36,7 @@ $text-color: var(--gauzy-text-color-2); // Segment component styles .segment { @include flex-center($gap-small); - padding: $padding-small; + padding: 0 $padding-small; span { display: none; diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.html b/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.html index 5c45b8b68f2..e68e5494e79 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.html +++ b/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.html @@ -1,8 +1,8 @@
-
{{ percentage }}%
+
{{ (percentage / 100) | percent:'1.0-2' }}
- +
diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.scss b/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.scss index aaa78629d3c..368fed70bbf 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.scss +++ b/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.scss @@ -3,6 +3,7 @@ .wrapper { display: flex; align-items: center; + gap: 0.5rem } :host { @@ -20,12 +21,6 @@ .progress-container { height: 5px !important; } - - .progress-value { - span { - display: none; - } - } } } } @@ -34,12 +29,11 @@ width: 100%; .percentage-col { - margin-right: 10px; width: 60px; } .progress-col { - width: 75%; + width: 100%; display: flex; align-items: flex-end; } diff --git a/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.ts b/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.ts index 530a8070bd2..59798278df7 100644 --- a/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.ts +++ b/packages/desktop-ui-lib/src/lib/recap/shared/ui/progress-status/progress-status.component.ts @@ -2,6 +2,11 @@ import { Component, Input } from '@angular/core'; import { progressStatus } from '@gauzy/ui-core/common'; import { NbComponentOrCustomStatus } from '@nebular/theme'; +export interface IProgressStatusDisplayValue { + in?: boolean; + out?: boolean; +} + @Component({ selector: 'ngx-progress-status', templateUrl: './progress-status.component.html', @@ -11,7 +16,7 @@ export class ProgressStatusComponent { /* * Getter & Setter for Percentage */ - private _percentage: any; + private _percentage: number = 0; get percentage(): number { return this._percentage; } @@ -19,10 +24,24 @@ export class ProgressStatusComponent { this._percentage = value; } + /* + * Getter & Setter for Percentage + */ + private _displayValue: IProgressStatusDisplayValue = { + in: false, + out: true + }; + get displayValue(): IProgressStatusDisplayValue { + return this._displayValue; + } + @Input() set displayValue(value: IProgressStatusDisplayValue) { + this._displayValue = value; + } + /* * Getter & Setter for NbComponentOrCustomStatus */ - private _defaultStatus: NbComponentOrCustomStatus; + private _defaultStatus: NbComponentOrCustomStatus = 'success'; get defaultStatus(): NbComponentOrCustomStatus { return this._defaultStatus; } diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.query.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.query.ts new file mode 100644 index 00000000000..98bd3f58449 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.query.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { Query } from '@datorama/akita'; +import { Observable } from 'rxjs'; +import { IDateRangePicker } from '../../shared/features/date-range-picker/date-picker.interface'; +import { IWeeklyRecapState, WeeklyRecapStore } from './weekly.store'; + +@Injectable({ providedIn: 'root' }) +export class WeeklyRecapQuery extends Query { + public readonly range$: Observable = this.select((state) => state.range); + public readonly state$: Observable = this.select(); + public readonly isLoading$: Observable = this.selectLoading(); + + constructor(protected store: WeeklyRecapStore) { + super(store); + } +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.service.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.service.ts new file mode 100644 index 00000000000..c5008270f21 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.service.ts @@ -0,0 +1,98 @@ +import { Injectable } from '@angular/core'; +import { ICountsStatistics, IGetCountsStatistics, IGetTimeLogInput, ReportDayData } from '@gauzy/contracts'; +import { Observable } from 'rxjs'; +import { RequestQuery } from '../../+state/request/request.query'; +import { Store, ToastrNotificationService } from '../../../services'; +import { TimesheetService, TimesheetStatisticsService } from '../../services/timesheet'; +import { IDateRangePicker } from '../../shared/features/date-range-picker/date-picker.interface'; +import { WeeklyRecapQuery } from './weekly.query'; +import { IWeeklyRecapState, WeeklyRecapStore } from './weekly.store'; + +@Injectable({ + providedIn: 'root' +}) +export class WeeklyRecapService { + constructor( + private readonly timesheetStatisticsService: TimesheetStatisticsService, + private readonly timesheetService: TimesheetService, + private readonly notificationService: ToastrNotificationService, + private readonly weeklyQuery: WeeklyRecapQuery, + private readonly weeklyStore: WeeklyRecapStore, + private readonly requestQuery: RequestQuery, + private readonly store: Store + ) {} + + public update(state: Partial) { + this.weeklyStore.update(state); + } + + public get state$(): Observable { + return this.weeklyQuery.state$; + } + + public get range$(): Observable { + return this.weeklyQuery.range$; + } + + public get range(): IDateRangePicker { + return this.weeklyQuery.getValue().range; + } + + public get count(): ICountsStatistics { + return this.weeklyQuery.getValue().count; + } + + public get weeklyActivities(): ReportDayData[] { + return this.weeklyQuery.getValue().weeklyActivities; + } + + public async getWeeklyActivities(): Promise { + try { + this.weeklyStore.setLoading(true); + const { organizationId, tenantId, user } = this.store; + const employeeIds = [user.employee.id]; + const timeZone = user.timeZone; + const timeFormat = user.timeFormat; + const request: IGetTimeLogInput = { + ...this.requestQuery.request, + ...this.range, + organizationId, + employeeIds, + tenantId, + timeFormat, + timeZone, + unitOfTime: 'week' + }; + const weeklyActivities = await this.timesheetService.getWeeklyReportChart(request); + this.weeklyStore.update({ weeklyActivities }); + } catch (error) { + this.notificationService.error(error.message || 'An error occurred while fetching tasks.'); + this.weeklyStore.setError(error); + } finally { + this.weeklyStore.setLoading(false); + } + } + + public async getCounts(): Promise { + try { + this.weeklyStore.setLoading(true); + const { organizationId, tenantId, user } = this.store; + const employeeIds = [user.employee.id]; + const request: IGetCountsStatistics = { + ...this.requestQuery.request, + ...this.range, + organizationId, + employeeIds, + onlyMe: true, + tenantId + }; + const count = await this.timesheetStatisticsService.getCounts(request); + this.weeklyStore.update({ count: { ...count, reWeeklyLimit: user.employee.reWeeklyLimit } }); + } catch (error) { + this.notificationService.error(error.message || 'An error occurred while fetching tasks.'); + this.weeklyStore.setError(error); + } finally { + this.weeklyStore.setLoading(false); + } + } +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.store.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.store.ts new file mode 100644 index 00000000000..7cc915dbfd3 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/+state/weekly.store.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { Store, StoreConfig } from '@datorama/akita'; +import { ICountsStatistics, ReportDayData } from '@gauzy/contracts'; +import { TimeTrackerDateManager } from '../../../services'; +import { IDateRangePicker } from '../../shared/features/date-range-picker/date-picker.interface'; + +export interface IWeeklyRecapState { + count: ICountsStatistics & { reWeeklyLimit: number }; + range: IDateRangePicker; + weeklyActivities: ReportDayData[]; +} + +export function createInitialState(): IWeeklyRecapState { + return { + weeklyActivities: [], + range: { + startDate: TimeTrackerDateManager.startCurrentWeek, + endDate: TimeTrackerDateManager.endCurrentWeek + }, + count: { + reWeeklyLimit: 0, + projectsCount: 0, + employeesCount: 0, + weekActivities: 0, + weekDuration: 0, + todayActivities: 0, + todayDuration: 0 + } + }; +} + +@StoreConfig({ name: '_weeklyRecap' }) +@Injectable({ providedIn: 'root' }) +export class WeeklyRecapStore extends Store { + constructor() { + super(createInitialState()); + } +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.html b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.html new file mode 100644 index 00000000000..ab9810097b7 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.html @@ -0,0 +1,2 @@ + diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.scss b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.ts new file mode 100644 index 00000000000..ee77f83dc2c --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-calendar/weekly-calendar.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { map } from 'rxjs'; +import { WeeklyRecapService } from '../../+state/weekly.service'; +import { IDateRangePicker } from '../../../shared/features/date-range-picker/date-picker.interface'; + +@Component({ + selector: 'ngx-weekly-calendar', + templateUrl: './weekly-calendar.component.html', + styleUrls: ['./weekly-calendar.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class WeeklyCalendarComponent { + constructor(private readonly weeklyRecapService: WeeklyRecapService) {} + + public get selectedDateRange$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.range)); + } + + public onRangeChange(range: IDateRangePicker) { + this.weeklyRecapService.update({ range }); + } +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.html b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.html new file mode 100644 index 00000000000..494472e4838 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.html @@ -0,0 +1,20 @@ +
+
+
+ {{(range$ | async).startDate | dateTime : 'll'}} - {{(range$ | async).endDate | dateTime : 'll'}} +
+
+ +
+
{{ day | dateTime : 'D dddd' }}
+ +
{{ (weeklyActivities$ | async)?.dates[day]?.sum | durationFormat : 'h[h] m[m] s[s]':{trim:'both'} }} +
+
+
+
+ + + + diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.scss b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.scss new file mode 100644 index 00000000000..1007ce1db87 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.scss @@ -0,0 +1,35 @@ +@import 'report'; + +.activity { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; +} + +.week-days { + display: flex; + align-items: center; + justify-content: space-between; + border-top: 0.5px solid var(--select-filled-control-disabled-text-color); + padding-top: 1rem; + + .day, + .hours { + text-wrap: nowrap; + } +} + +.week-range { + font-weight: 500; +} + +.week-wrapper { + display: flex; + flex-direction: column; + gap: 1rem; + padding: 1rem; + border-radius: var(--border-radius); + background-color: var(--gauzy-card-3); + height: 100%; +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.ts new file mode 100644 index 00000000000..91441e0a8bc --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-progress/weekly-progress.component.ts @@ -0,0 +1,30 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { map, tap } from 'rxjs'; +import { WeeklyRecapService } from '../../+state/weekly.service'; +import { updateWeekDays } from '../../../shared/features/date-range-picker'; + +@Component({ + selector: 'ngx-weekly-progress', + templateUrl: './weekly-progress.component.html', + styleUrls: ['./weekly-progress.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class WeeklyProgressComponent { + public weekDays: string[] = []; + + constructor(private readonly weeklyRecapService: WeeklyRecapService) {} + + public get weeklyActivities$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.weeklyActivities[0])); + } + + public get range$() { + return this.weeklyRecapService.state$.pipe( + tap((state) => { + const { weekDays } = updateWeekDays(state.range); + this.weekDays = weekDays; + }), + map((state) => state.range) + ); + } +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.html b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.html new file mode 100644 index 00000000000..d8674ef95b5 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.html @@ -0,0 +1,15 @@ + + + + + +
+ + +
+
+ + + + +
diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.scss b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.scss new file mode 100644 index 00000000000..2d05816ca92 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.scss @@ -0,0 +1,11 @@ +@import '../../../features/recap/recap.component.scss'; + +.recap-weekly { + display: flex; + flex-direction: column; + gap: 1rem; + background-color: var(--gauzy-card-2); + padding: 1rem; + border-radius: var(--border-radius); + height: 100%; +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.ts new file mode 100644 index 00000000000..4306520d33d --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-recap/weekly-recap.component.ts @@ -0,0 +1,44 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BehaviorSubject, combineLatest, concatMap } from 'rxjs'; +import { WeeklyRecapService } from '../../+state/weekly.service'; +import { AutoRefreshService } from '../../../+state/auto-refresh/auto-refresh.service'; +import { RequestQuery } from '../../../+state/request/request.query'; +import { LoggerService } from '../../../../electron/services'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ngx-weekly-recap', + templateUrl: './weekly-recap.component.html', + styleUrls: ['./weekly-recap.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class WeeklyRecapComponent implements OnInit { + public isLoading$ = new BehaviorSubject(false); + constructor( + private readonly weeklyRecapService: WeeklyRecapService, + private readonly requestQuery: RequestQuery, + private readonly autoRefreshService: AutoRefreshService, + private readonly logger: LoggerService + ) {} + + ngOnInit(): void { + combineLatest([this.weeklyRecapService.range$, this.requestQuery.request$, this.autoRefreshService.refresh$]) + .pipe( + concatMap(() => this.load()), + untilDestroyed(this) + ) + .subscribe(); + } + + public async load(): Promise { + try { + this.isLoading$.next(true); + await Promise.allSettled([this.weeklyRecapService.getCounts(), this.weeklyRecapService.getWeeklyActivities()]); + } catch (error) { + this.logger.error(error) + }finally { + this.isLoading$.next(false) + } + } +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.html b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.html new file mode 100644 index 00000000000..c834dae87cc --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.html @@ -0,0 +1,38 @@ + + + + +
{{ 'TIMESHEET.WORKED_TODAY' | translate }}
+
+ +
{{ todayDuration$ | async | durationFormat : 'h[h] m[m] s[s]':{trim: 'both'} }}
+
+
+ + +
{{ 'TIMESHEET.TODAY_ACTIVITY' | translate }}
+
+ +
{{ todayActivity$ | async | percent:'1.0-2' }}
+
+
+ + +
{{ 'TIMESHEET.WORKED_FOR_WEEK' | translate }}
+
+ +
{{ weeklyDuration$ | async | durationFormat : 'h[h] m[m] s[s]':{trim: 'both'} }}
+
of {{ weeklyLimit$ | async | durationFormat : 'h[h]':{trim: 'both'} }} +
+
+
+ + +
{{ 'TIMESHEET.ACTIVITY_FOR_WEEK' | translate }}
+
+ +
{{ weeklyActivity$ | async | percent:'1.0-2' }}
+
+
+
+
diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.scss b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.scss new file mode 100644 index 00000000000..7f65afa2f18 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.scss @@ -0,0 +1,36 @@ +nb-card { + margin: 0 !important; + + nb-card-body, + nb-card-header { + padding: 0 !important; + } + + .card-wrapper { + display: flex; + flex-direction: row; + gap: 1rem; + + nb-card { + padding: 1rem; + width: 100%; + } + } +} + +.h1 { + color: var(--gauzy-text-color-1); + font-size: 32px; + font-weight: 400; + line-height: 44px; + letter-spacing: 0; + text-wrap: nowrap; +} + +.h2 { + font-size: 16px; + font-weight: 400; + line-height: 16px; + letter-spacing: -0.009em; + color: var(--gauzy-text-color-2); +} diff --git a/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.ts b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.ts new file mode 100644 index 00000000000..cf1e2103b9e --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/recap/weekly/features/weekly-statistic/weekly-statistic.component.ts @@ -0,0 +1,33 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { map } from 'rxjs'; +import { WeeklyRecapService } from '../../+state/weekly.service'; + +@Component({ + selector: 'ngx-weekly-statistic', + templateUrl: './weekly-statistic.component.html', + styleUrls: ['./weekly-statistic.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class WeeklyStatisticComponent { + constructor(private readonly weeklyRecapService: WeeklyRecapService) {} + + public get todayDuration$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.count.todayDuration)); + } + + public get weeklyDuration$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.count.weekDuration)); + } + + public get todayActivity$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.count.todayActivities / 100)); + } + + public get weeklyActivity$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.count.weekActivities / 100)); + } + + public get weeklyLimit$() { + return this.weeklyRecapService.state$.pipe(map((state) => state.count.reWeeklyLimit)); + } +} diff --git a/packages/desktop-ui-lib/src/lib/services/time-tracker-date.manager.ts b/packages/desktop-ui-lib/src/lib/services/time-tracker-date.manager.ts index b8571b17cc9..1672b455e0e 100644 --- a/packages/desktop-ui-lib/src/lib/services/time-tracker-date.manager.ts +++ b/packages/desktop-ui-lib/src/lib/services/time-tracker-date.manager.ts @@ -1,5 +1,5 @@ -import * as moment from 'moment'; import { IOrganization, LanguagesEnum } from '@gauzy/contracts'; +import * as moment from 'moment'; export class TimeTrackerDateManager { private static _instance: TimeTrackerDateManager; @@ -26,31 +26,19 @@ export class TimeTrackerDateManager { } public static get startWeek(): string { - return moment() - .startOf('week') - .subtract(this.utcOffset, 'minutes') - .format('YYYY-MM-DD HH:mm:ss'); + return moment().startOf('week').subtract(this.utcOffset, 'minutes').format('YYYY-MM-DD HH:mm:ss'); } public static get endWeek(): string { - return moment() - .endOf('week') - .subtract(this.utcOffset, 'minutes') - .format('YYYY-MM-DD HH:mm:ss'); + return moment().endOf('week').subtract(this.utcOffset, 'minutes').format('YYYY-MM-DD HH:mm:ss'); } public static get startToday(): string { - return moment() - .startOf('day') - .subtract(this.utcOffset, 'minutes') - .format('YYYY-MM-DD HH:mm:ss'); + return moment().startOf('day').subtract(this.utcOffset, 'minutes').format('YYYY-MM-DD HH:mm:ss'); } public static get endToday(): string { - return moment() - .endOf('day') - .subtract(this.utcOffset, 'minutes') - .format('YYYY-MM-DD HH:mm:ss'); + return moment().endOf('day').subtract(this.utcOffset, 'minutes').format('YYYY-MM-DD HH:mm:ss'); } public static get utcOffset(): number { @@ -77,17 +65,15 @@ export class TimeTrackerDateManager { public static get isMidnight(): boolean { const now = moment(); const endOfDay = now.clone().endOf('day'); - return moment(now.format('YYYY-MM-DD HH:mm:ss')).isSame( - endOfDay.format('YYYY-MM-DD HH:mm:ss') - ); + return moment(now.format('YYYY-MM-DD HH:mm:ss')).isSame(endOfDay.format('YYYY-MM-DD HH:mm:ss')); } // Set the start of the week private startWeekDay() { moment.updateLocale(this._language, { week: { - dow: TimeTrackerDateManager._startWeekDayNumber, - }, + dow: TimeTrackerDateManager._startWeekDayNumber + } }); } @@ -103,4 +89,12 @@ export class TimeTrackerDateManager { public static get endCurrentDay(): string { return moment().endOf('day').format('YYYY-MM-DD HH:mm:ss'); } + + public static get startCurrentWeek(): string { + return moment().startOf('week').format('YYYY-MM-DD HH:mm:ss'); + } + + public static get endCurrentWeek(): string { + return moment().endOf('week').format('YYYY-MM-DD HH:mm:ss'); + } } diff --git a/packages/desktop-ui-lib/src/lib/services/toastr-notification.service.ts b/packages/desktop-ui-lib/src/lib/services/toastr-notification.service.ts index d7ed5bf456e..48a6183ae35 100644 --- a/packages/desktop-ui-lib/src/lib/services/toastr-notification.service.ts +++ b/packages/desktop-ui-lib/src/lib/services/toastr-notification.service.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@angular/core'; import { NbToastrService } from '@nebular/theme'; -import { NotificationService } from './notification.service'; import { GAUZY_ENV } from '../constants'; +import { NotificationService } from './notification.service'; @Injectable({ providedIn: 'root', @@ -31,4 +31,8 @@ export class ToastrNotificationService extends NotificationService { public warn(message: string): void { this._toastrService.warning(message, this._notification.title); } + + public info(message: string): void { + this._toastrService.info(message, this._notification.title); + } } diff --git a/packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.ts b/packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.ts index 794727099a6..f12e359d3a4 100644 --- a/packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.ts +++ b/packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.ts @@ -1,4 +1,5 @@ import { Component, inject, NgZone, OnInit } from '@angular/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { NbDialogRef } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { tap } from 'rxjs'; @@ -20,15 +21,10 @@ export class AddPluginComponent implements OnInit { ngOnInit(): void { this.pluginElectronService.status .pipe( + distinctUntilChange(), tap(({ status, message }) => this.ngZone.run(() => { - this.installing = false; - if (status === 'success') { - this.close(); - } else { - console.error(message); - this.error = message; - } + this.handleStatus({ status, message }); }) ), untilDestroyed(this) @@ -36,6 +32,25 @@ export class AddPluginComponent implements OnInit { .subscribe(); } + private handleStatus(notification: { status: string; message?: string }) { + switch (notification.status) { + case 'success': + this.installing = false; + this.close(); + break; + case 'error': + this.installing = false; + this.error = notification.message; + break; + case 'inProgress': + this.installing = true; + break; + default: + this.installing = false; + break; + } + } + public installPlugin(value: string) { if (!value) { this.error = "The server URL mustn't be empty."; diff --git a/packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.ts b/packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.ts index ee57b7ccc30..dd4ebcac936 100644 --- a/packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.ts +++ b/packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.ts @@ -5,6 +5,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { Angular2SmartTableComponent, Cell, LocalDataSource } from 'angular2-smart-table'; import { BehaviorSubject, concatMap, filter, from, Observable, switchMap, tap } from 'rxjs'; +import { ToastrNotificationService } from '../../../../services'; import { PluginElectronService } from '../../services/plugin-electron.service'; import { IPlugin } from '../../services/plugin-loader.service'; import { AddPluginComponent } from '../add-plugin/add-plugin.component'; @@ -20,6 +21,7 @@ import { PluginUpdateComponent } from './plugin-update/plugin-update.component'; export class PluginListComponent implements OnInit { private readonly translateService = inject(TranslateService); private readonly pluginElectronService = inject(PluginElectronService); + private readonly toastrNotificationService = inject(ToastrNotificationService); private readonly dialog = inject(NbDialogService); private readonly router = inject(Router); private readonly ngZone = inject(NgZone); @@ -93,7 +95,7 @@ export class PluginListComponent implements OnInit { private observePlugins(): void { this.pluginElectronService.status .pipe( - tap(() => (this.processing = false)), + tap((response) => this.ngZone.run(() => this.handleStatus(response))), filter((response) => response.status === 'success'), switchMap(() => from(this.pluginElectronService.plugins)), tap((plugins) => this.ngZone.run(() => (this.plugins = plugins))), @@ -110,6 +112,27 @@ export class PluginListComponent implements OnInit { .subscribe(); } + private handleStatus(notification: { status: string; message?: string }) { + switch (notification.status) { + case 'success': + this.processing = false; + this.toastrNotificationService.success(notification.message); + break; + case 'error': + this.processing = false; + this.toastrNotificationService.error(notification.message); + break; + case 'inProgress': + this.processing = true; + this.toastrNotificationService.info(notification.message); + break; + default: + this.processing = false; + this.toastrNotificationService.warn('Unexpected Status'); + break; + } + } + private loadPlugins(): void { from(this.pluginElectronService.plugins) .pipe( @@ -119,9 +142,8 @@ export class PluginListComponent implements OnInit { .subscribe(); } - public handleRowSelection(event) { - const selected = event.selected[0]; - this.plugin = selected && selected.id === this.plugin?.id ? this.plugin : selected; + public handleRowSelection({ isSelected, data }) { + this.plugin = isSelected ? data : null; } public changeStatus() { diff --git a/packages/desktop-ui-lib/src/lib/settings/settings.component.html b/packages/desktop-ui-lib/src/lib/settings/settings.component.html index 0521d013106..b2e179a922f 100644 --- a/packages/desktop-ui-lib/src/lib/settings/settings.component.html +++ b/packages/desktop-ui-lib/src/lib/settings/settings.component.html @@ -1,38 +1,26 @@ - + - + ">
{{ menu | translate }}
- + +
- + ">

{{ 'TIMER_TRACKER.SETTINGS.MONITOR' | translate }}

@@ -42,67 +30,44 @@

{{ 'TIMER_TRACKER.SETTINGS.MONITOR' | translate }}

{{ - 'TIMER_TRACKER.SETTINGS.AUTOMATIC_SCREEN_CAPTURE' - | translate + 'TIMER_TRACKER.SETTINGS.AUTOMATIC_SCREEN_CAPTURE' + | translate }}
-
-
- - + }" class="row monitors mb-3"> +
+ +
- + - +
- + "> {{ item?.title | translate }}
- + "> {{ item?.subtitle | translate }}
@@ -117,8 +82,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.NOTIFICATION_SETTINGS' - | translate + 'TIMER_TRACKER.SETTINGS.NOTIFICATION_SETTINGS' + | translate }}

@@ -127,8 +92,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.DESKTOP_NOTIFICATIONS' - | translate + 'TIMER_TRACKER.SETTINGS.DESKTOP_NOTIFICATIONS' + | translate }}
@@ -137,8 +102,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.SHOW_DESKTOP_NOTIF_SCREEN_CAPTURE' - | translate + 'TIMER_TRACKER.SETTINGS.SHOW_DESKTOP_NOTIF_SCREEN_CAPTURE' + | translate }}

@@ -151,75 +116,59 @@
- + " status="basic"> {{ - 'TIMER_TRACKER.SETTINGS.DETAILED_NOTIF' - | translate + 'TIMER_TRACKER.SETTINGS.DETAILED_NOTIF' + | translate }}
{{ 'TIMER_TRACKER.SETTINGS.SHOW_NOTIF_CAPTURED_IMG' - | translate - }} + | translate + }}
- +
- + " status="basic"> {{ - 'TIMER_TRACKER.SETTINGS.SIMPLE_NOTIF' - | translate + 'TIMER_TRACKER.SETTINGS.SIMPLE_NOTIF' + | translate }}
{{ 'TIMER_TRACKER.SETTINGS.SHOW_NATIVE_OS_NOTIF' - | translate - }} + | translate + }}
- +
@@ -246,19 +195,14 @@
- + " status="basic"> {{ - (muted - ? 'TIMER_TRACKER.SETTINGS.SOUND_DISABLED' - : 'TIMER_TRACKER.SETTINGS.SOUND_ENABLED' - ) | translate + (muted + ? 'TIMER_TRACKER.SETTINGS.SOUND_DISABLED' + : 'TIMER_TRACKER.SETTINGS.SOUND_ENABLED' + ) | translate }} @@ -276,8 +220,8 @@

{{ 'TIMER_TRACKER.TIMER' | translate }}

{{ - 'TIMER_TRACKER.SETTINGS.UPDATE_ACTIVITIES' - | translate + 'TIMER_TRACKER.SETTINGS.UPDATE_ACTIVITIES' + | translate }}
@@ -286,37 +230,25 @@
- - {{ humanize(item / 60) | titlecase }} + [disabled]="appSetting?.timerStarted || appSetting?.enforced"> + {{ humanize(item / 60) | + titlecase }} - {{ - 'TIMER_TRACKER.SETTINGS.RANDOM_SCREENSHOT_TIME' - | translate + {{ + 'TIMER_TRACKER.SETTINGS.RANDOM_SCREENSHOT_TIME' + | translate }} - {{ - 'TIMER_TRACKER.SETTINGS.TRACK_TIME_PC_LOCKED' - | translate + [disabled]="appSetting?.timerStarted || appSetting?.enforced" status="basic">{{ + 'TIMER_TRACKER.SETTINGS.TRACK_TIME_PC_LOCKED' + | translate }} @@ -327,8 +259,8 @@
{{ - 'TIMER_TRACKER.SETTINGS.KEEP_SYSTEM_ACTIVE' - | translate + 'TIMER_TRACKER.SETTINGS.KEEP_SYSTEM_ACTIVE' + | translate }}
@@ -337,8 +269,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.PREVENT_DISPLAY_GOING_SLEEP' - | translate + 'TIMER_TRACKER.SETTINGS.PREVENT_DISPLAY_GOING_SLEEP' + | translate }}

@@ -347,16 +279,11 @@
- {{ - 'TIMER_TRACKER.SETTINGS.PREVENT_DISPLAY_SLEEP' - | translate + " status="basic" [disabled]="appSetting?.timerStarted">{{ + 'TIMER_TRACKER.SETTINGS.PREVENT_DISPLAY_SLEEP' + | translate }} @@ -367,8 +294,8 @@
{{ - 'TIMER_TRACKER.SETTINGS.TIMEZONE' - | translate + 'TIMER_TRACKER.SETTINGS.TIMEZONE' + | translate }}
@@ -377,8 +304,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.TIMEZONE_LABEL' - | translate + 'TIMER_TRACKER.SETTINGS.TIMEZONE_LABEL' + | translate }}

@@ -387,16 +314,11 @@
- - {{ zone.translation | translate }} + + {{ zone.translation | + translate }} @@ -407,8 +329,8 @@
{{ - 'TIMER_TRACKER.SETTINGS.WIDGET' - | translate + 'TIMER_TRACKER.SETTINGS.WIDGET' + | translate }}
@@ -417,8 +339,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.WIDGET_LABEL' - | translate + 'TIMER_TRACKER.SETTINGS.WIDGET_LABEL' + | translate }}

@@ -427,16 +349,11 @@
- {{ - 'TIMER_TRACKER.SETTINGS.WIDGET' - | translate + " status="basic" [disabled]="appSetting?.timerStarted">{{ + 'TIMER_TRACKER.SETTINGS.WIDGET' + | translate }} @@ -444,10 +361,7 @@
-
+
@@ -460,8 +374,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.AUTOMATIC_UPDATE_CHECK' - | translate + 'TIMER_TRACKER.SETTINGS.AUTOMATIC_UPDATE_CHECK' + | translate }}
@@ -470,73 +384,53 @@

{{ - 'TIMER_TRACKER.SETTINGS.ENABLE_AUTOMATIC_UPDATE_LABEL' - | translate + 'TIMER_TRACKER.SETTINGS.ENABLE_AUTOMATIC_UPDATE_LABEL' + | translate }}

-
+
- {{ - 'TIMER_TRACKER.SETTINGS.ENABLE_AUTOMATIC_UPDATE' - | translate + ">{{ + 'TIMER_TRACKER.SETTINGS.ENABLE_AUTOMATIC_UPDATE' + | translate }}
-
+
{{ - 'TIMER_TRACKER.SETTINGS.SET_UPDATE_INTERVAL_DURATION' - | translate + 'TIMER_TRACKER.SETTINGS.SET_UPDATE_INTERVAL_DURATION' + | translate }}
- - + + " [value]="delay"> {{ humanize(delay) | titlecase - }} + }}
@@ -549,8 +443,8 @@
{{ - 'TIMER_TRACKER.SETTINGS.UPDATE_SERVER' - | translate + 'TIMER_TRACKER.SETTINGS.UPDATE_SERVER' + | translate }}
@@ -559,8 +453,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.SELECT_DEFAULT_CDN' - | translate + 'TIMER_TRACKER.SETTINGS.SELECT_DEFAULT_CDN' + | translate }}

@@ -571,85 +465,57 @@
- - Github - + "> + Github +
- - Digital Ocean - + "> + Digital Ocean +
- + "> {{ - 'TIMER_TRACKER.SETTINGS.LOCAL_SERVER' - | translate + 'TIMER_TRACKER.SETTINGS.LOCAL_SERVER' + | translate }}
-
+
-

+ ">

-
- -
+
{{ (file$ | async)?.uri }}
@@ -665,8 +531,8 @@

{{ - 'TIMER_TRACKER.SETTINGS.OTHER_SETTINGS' - | translate + 'TIMER_TRACKER.SETTINGS.OTHER_SETTINGS' + | translate }}

@@ -675,17 +541,13 @@
- {{ - 'TIMER_TRACKER.SETTINGS.ALLOW_PRERELEASE_VERSIONS' - | translate + ">{{ + 'TIMER_TRACKER.SETTINGS.ALLOW_PRERELEASE_VERSIONS' + | translate }} @@ -697,8 +559,8 @@
{{ - 'TIMER_TRACKER.SETTINGS.CHECK_UPDATE_APP_VERSION' - | translate + 'TIMER_TRACKER.SETTINGS.CHECK_UPDATE_APP_VERSION' + | translate }}
@@ -707,118 +569,72 @@

{{ - ((available$ | async) - ? downloadFinish - ? 'TIMER_TRACKER.SETTINGS.UPDATE_DOWNLOADED_NOTE' - : 'TIMER_TRACKER.SETTINGS.UPDATE_AVAILABLE_NOTE' - : 'TIMER_TRACKER.SETTINGS.CHECK_UPDATE_NOTE' - ) | translate + ((available$ | async) + ? downloadFinish + ? 'TIMER_TRACKER.SETTINGS.UPDATE_DOWNLOADED_NOTE' + : 'TIMER_TRACKER.SETTINGS.UPDATE_AVAILABLE_NOTE' + : 'TIMER_TRACKER.SETTINGS.CHECK_UPDATE_NOTE' + ) | translate }}

- -
-
-
- +
-
+
- + {{ - 'TIMER_TRACKER.SETTINGS.UPDATE_LOGS' - | translate + 'TIMER_TRACKER.SETTINGS.UPDATE_LOGS' + | translate }}
-

+ "> {{ content }}

@@ -829,13 +645,10 @@
-
+ ">

{{ 'TIMER_TRACKER.SETTINGS.ADVANCED_SETTINGS' | translate }} @@ -844,286 +657,188 @@

{{ 'TIMER_TRACKER.SETTINGS.WARNING_STOP_TIMER' | translate - }} + }}
- + ">
-

+

{{ - 'TIMER_TRACKER.SETTINGS.SERVER_ACCESS_CONFIG' - | translate + 'TIMER_TRACKER.SETTINGS.SERVER_ACCESS_CONFIG' + | translate }}

-
+

{{ - 'TIMER_TRACKER.SETTINGS.SERVER_TYPE' - | translate + 'TIMER_TRACKER.SETTINGS.SERVER_TYPE' + | translate }}

-
- + - + + " [value]="item"> {{ item }}
-
+

{{ - 'TIMER_TRACKER.SETTINGS.SERVER_HOSTNAME' - | translate + 'TIMER_TRACKER.SETTINGS.SERVER_HOSTNAME' + | translate }}

-
- + + " status="basic" />
-
+ ">

{{ - 'TIMER_TRACKER.SETTINGS.API_SERVER_PORT' - | translate + 'TIMER_TRACKER.SETTINGS.API_SERVER_PORT' + | translate }}

-
- + + " />
-
+

{{ - 'TIMER_TRACKER.SETTINGS.UI_SERVER_PORT' - | translate + 'TIMER_TRACKER.SETTINGS.UI_SERVER_PORT' + | translate }}

-
- + + " status="basic" />
-
+ ">

{{ - 'TIMER_TRACKER.SETTINGS.SERVER_URL' - | translate + 'TIMER_TRACKER.SETTINGS.SERVER_URL' + | translate }}

-
- + + " status="basic" />
-
-
-
- -
+
{{ - ( - isCheckHost$ - | async - )?.message - | translate - : { - url: config.serverUrl - } + ( + isCheckHost$ + | async + )?.message + | translate + : { + url: config.serverUrl + } }}
@@ -1136,129 +851,91 @@

-

+

{{ - 'TIMER_TRACKER.SETTINGS.DB_CONFIG' - | translate + 'TIMER_TRACKER.SETTINGS.DB_CONFIG' + | translate }}

-
+

{{ - 'TIMER_TRACKER.SETTINGS.DB_DRIVER' - | translate + 'TIMER_TRACKER.SETTINGS.DB_DRIVER' + | translate }}

-
- + - + + " [value]="item"> {{ item | replace: '-' : ' ' | titlecase }}
- + ">
-
-
- -
+
{{ - ( - isConnectedDatabase$ - | async - )?.message + ( + isConnectedDatabase$ + | async + )?.message }}
@@ -1266,72 +943,55 @@

-
+
-

+

{{ - 'TIMER_TRACKER.SETTINGS.STARTUP_CONFIG' - | translate + 'TIMER_TRACKER.SETTINGS.STARTUP_CONFIG' + | translate }}

- {{ - 'TIMER_TRACKER.SETTINGS.AUTOMATIC_LAUNCH' - | translate + " status="basic">{{ + 'TIMER_TRACKER.SETTINGS.AUTOMATIC_LAUNCH' + | translate }}
- {{ + " status="basic">{{ 'TIMER_TRACKER.SETTINGS.AUTO_START_STARTUP' - | translate + | translate }}
- {{ - 'TIMER_TRACKER.SETTINGS.MIN_ON_STARTUP' - | translate + ">{{ + 'TIMER_TRACKER.SETTINGS.MIN_ON_STARTUP' + | translate }}
@@ -1341,99 +1001,70 @@

+ (update)="updateSslSetting($event)">
- -
+ "> +
-

+

{{ - 'TIMER_TRACKER.SETTINGS.3RD_PARTY_CONFIG' - | translate + 'TIMER_TRACKER.SETTINGS.3RD_PARTY_CONFIG' + | translate }}

-
+

{{ - 'TIMER_TRACKER.SETTINGS.AW_PORT' - | translate + 'TIMER_TRACKER.SETTINGS.AW_PORT' + | translate }}

-
- + + " type="text" nbInput fullWidth status="basic" [disabled]="true" />
- + " status="basic"> {{ - 'TIMER_TRACKER.SETTINGS.VISIBLE_AW' - | translate + 'TIMER_TRACKER.SETTINGS.VISIBLE_AW' + | translate }}
- {{ - 'TIMER_TRACKER.SETTINGS.VISIBLE_WAKATIME' - | translate + " status="basic">{{ + 'TIMER_TRACKER.SETTINGS.VISIBLE_WAKATIME' + | translate }}
@@ -1444,61 +1075,40 @@

- + ">
-

- + {{ item?.title }} + ">{{ item?.title }}

-
+ ">
-
+

{{ - field?.name.replaceAll( - '_', - ' ' - ) + field?.name.replaceAll( + '_', + ' ' + ) }}

-
- + + " status="basic" />
@@ -1513,22 +1123,17 @@

- +

- + - +
@@ -1537,15 +1142,13 @@

{{ 'TIMER_TRACKER.VERSION' | translate : { version } - }} + }}
- +

{{ 'TIMER_TRACKER.SETTINGS.DB_USERNAME' | translate }}

- +

{{ 'TIMER_TRACKER.SETTINGS.DB_PASSWORD' | translate }}

- +

{{ 'TIMER_TRACKER.SETUP.DB_PORT' | translate }}

- +
-
-
diff --git a/packages/desktop-ui-lib/src/lib/settings/settings.component.scss b/packages/desktop-ui-lib/src/lib/settings/settings.component.scss index 892fa839aa1..6b8a3c8aefd 100644 --- a/packages/desktop-ui-lib/src/lib/settings/settings.component.scss +++ b/packages/desktop-ui-lib/src/lib/settings/settings.component.scss @@ -52,22 +52,22 @@ } :host .warning-config { - @include nb-rtl(text-align, left); - @include nb-ltr(text-align, right); - margin-bottom: 10px; - font-size: 12px; - font-weight: 600; - color: var(--color-warning-default); - position: absolute; - @include nb-rtl(left, var(--sidebar-width)); - @include nb-ltr(right, 10px); - top: 30px; - - span { - background-color: var(--color-warning-transparent-300); - padding: 8px 12px; - border-radius: 8px; - } + @include nb-rtl(text-align, left); + @include nb-ltr(text-align, right); + margin-bottom: 10px; + font-size: 12px; + font-weight: 600; + color: var(--color-warning-default); + position: absolute; + @include nb-rtl(left, var(--sidebar-width)); + @include nb-ltr(right, 10px); + top: 30px; + + span { + background-color: var(--color-warning-transparent-300); + padding: 8px 12px; + border-radius: 8px; + } } ::ng-deep body { @@ -322,11 +322,11 @@ warn-container { } :host .close-warn { - position: absolute; - top: calc(-15px / 2); - box-shadow: var(--gauzy-shadow); - @include nb-rtl(left, calc(15px / 2)); - @include nb-ltr(right, calc(15px / 2)); + position: absolute; + top: calc(-15px / 2); + box-shadow: var(--gauzy-shadow); + @include nb-rtl(left, calc(15px / 2)); + @include nb-ltr(right, calc(15px / 2)); } .restart-btn-container { @@ -335,9 +335,9 @@ warn-container { .nb-tab-card, .nb-tab-body { - background-color: unset; - padding: 0; - margin: 0; + background-color: unset; + padding: 0; + margin: 0; } .nb-tab-footer { @@ -345,7 +345,13 @@ warn-container { } .language { - position: absolute; - left: 1rem; - bottom: 5.5rem; + position: absolute; + left: 1rem; + bottom: 5.5rem; +} + +.switch-theme-toggle { + position: absolute; + right: 1rem; + bottom: 6.2rem; } diff --git a/packages/desktop-ui-lib/src/lib/settings/settings.module.ts b/packages/desktop-ui-lib/src/lib/settings/settings.module.ts index 7b1527d04d5..05d51251c25 100644 --- a/packages/desktop-ui-lib/src/lib/settings/settings.module.ts +++ b/packages/desktop-ui-lib/src/lib/settings/settings.module.ts @@ -30,6 +30,7 @@ import { TimeTrackerService } from '../time-tracker/time-tracker.service'; import { PluginsModule } from './plugins/plugins.module'; import { SettingsComponent } from './settings.component'; import { SslModule } from './ssl'; +import { SwitchThemeModule } from '../theme-selector/switch-theme/switch-theme.module'; @NgModule({ declarations: [SettingsComponent], @@ -57,9 +58,10 @@ import { SslModule } from './ssl'; TaskRenderModule, SslModule, PluginsModule, - PipeModule + PipeModule, + SwitchThemeModule ], providers: [NbToastrService, TimeTrackerService, NbDialogService, Store], exports: [SettingsComponent] }) -export class SettingsModule {} +export class SettingsModule { } diff --git a/packages/desktop-ui-lib/src/lib/theme-selector/index.ts b/packages/desktop-ui-lib/src/lib/theme-selector/index.ts new file mode 100644 index 00000000000..03e967f0914 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme-selector/index.ts @@ -0,0 +1 @@ +export * from './switch-theme/switch-theme.component'; diff --git a/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.html b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.html new file mode 100644 index 00000000000..ee310c5cb21 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.html @@ -0,0 +1,7 @@ +
+ {{ 'SETTINGS_MENU.LIGHT' | translate }}/{{ + 'SETTINGS_MENU.DARK' | translate + }} + +
diff --git a/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.scss b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.scss new file mode 100644 index 00000000000..8792a97ac2a --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.scss @@ -0,0 +1,74 @@ +@import 'var'; + +:host .switch-container { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + + nb-toggle.switch ::ng-deep .toggle { + height: 1.5rem; + width: 3.375rem; + font-family: 'Font Awesome 6 Free' !important; + font-size: .625rem; + display: flex; + align-items: center; + background-color: rgba(126, 126, 143, 0.5); + border-width: 0; + .toggle-switcher{ + height: 1rem; + width: 1rem; + } + span { + display: flex; + justify-content: center; + align-items: center; + justify-self: flex-end; + } + + nb-icon{ + display: none; + } + } + nb-toggle.light ::ng-deep .toggle { + justify-content: end; + &:before { + content: '\f186'; + @include nb-rtl(margin-left, .275rem); + @include nb-ltr(margin-right, .275rem); + color: rgba(255, 255, 255, 0.25); + } + span { + &:before { + content: '\f185'; + } + } + .toggle-switcher{ + @include nb-ltr(margin-left, .25rem); + @include nb-rtl(margin-right, .25rem); + } + } + + nb-toggle.dark ::ng-deep .toggle { + justify-content: flex-start; + &:before { + content: '\f185'; + @include nb-ltr(margin-left, .325rem); + @include nb-rtl(margin-right, .325rem); + color: rgba(255, 255, 255, 0.25); + } + span { + &:before { + content: '\f186'; + } + } + } +} + +::ng-deep [dir=ltr] nb-toggle.switch .toggle.checked .toggle-switcher { + left: calc(100% - 1.375rem); +} + +::ng-deep [dir=rtl] nb-toggle.switch .toggle.checked .toggle-switcher { + right: calc(100% - 1.375rem); +} diff --git a/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.ts b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.ts new file mode 100644 index 00000000000..b0a33c89a2e --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.component.ts @@ -0,0 +1,30 @@ +import { Component, OnInit } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { ElectronService } from '../../electron/services'; + +@Component({ + selector: 'gauzy-switch-theme', + templateUrl: './switch-theme.component.html', + styleUrls: ['./switch-theme.component.scss'] +}) +export class SwitchThemeComponent implements OnInit { + switch = true; // Default theme can be light + hasText = false; + + constructor( + private translate: TranslateService, + private electronService: ElectronService + ) { } + + ngOnInit(): void { + this.electronService.ipcRenderer.invoke('SAVED_THEME').then((theme) => { + this.switch = theme === 'dark'; + }); + } + + switchTheme(): void { + const currentTheme = this.switch; + this.switch = !currentTheme; + this.electronService.ipcRenderer.send('THEME_CHANGE', this.switch ? 'dark' : 'light'); + } +} diff --git a/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.module.ts b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.module.ts new file mode 100644 index 00000000000..5f8316bf795 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NbToggleModule } from '@nebular/theme'; // Import Nebular Toggle Module +import { TranslateModule } from '@ngx-translate/core'; // Import ngx-translate Module + +import { SwitchThemeComponent } from './switch-theme.component'; + +@NgModule({ + declarations: [SwitchThemeComponent], + imports: [ + CommonModule, + NbToggleModule, + TranslateModule + ], + exports: [SwitchThemeComponent] +}) +export class SwitchThemeModule { } diff --git a/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.service.ts b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.service.ts new file mode 100644 index 00000000000..6b4f271bc5c --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme-selector/switch-theme/switch-theme.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class SwitchThemeService { + private _isAlreadyLoaded: boolean = false; + private _hasAlreadyPreferredTheme: boolean = false; + + constructor() { + this._hasAlreadyPreferredTheme = null; + } + + public get isAlreadyLoaded() { + return this._isAlreadyLoaded; + } + + public set isAlreadyLoaded(value: boolean) { + this._isAlreadyLoaded = value; + } + + public get hasAlreadyPreferredTheme() { + return this._hasAlreadyPreferredTheme; + } +} diff --git a/packages/desktop-ui-lib/src/lib/theme/index.ts b/packages/desktop-ui-lib/src/lib/theme/index.ts new file mode 100644 index 00000000000..4dcafbd6553 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme/index.ts @@ -0,0 +1,34 @@ +import { CommonModule } from '@angular/common'; +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { ElectronService } from '../electron/services'; +import { + NbThemeModule, + NbThemeService +} from '@nebular/theme'; +import { ThemeInitializerFactory } from './theme-initializer.factory'; +import { + GAUZY_DARK, + GAUZY_LIGHT +} from './styles'; + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + NbThemeModule.forRoot({ name: GAUZY_LIGHT.name }, [ + GAUZY_LIGHT, + GAUZY_DARK + ]) + ], + providers: [ + NbThemeService, + { + provide: APP_INITIALIZER, + useFactory: ThemeInitializerFactory, + deps: [NbThemeService, ElectronService], + multi: true + } + ], + exports: [NbThemeModule] +}) +export class NgxDesktopThemeModule { } diff --git a/packages/desktop-ui-lib/src/lib/theme/styles/index.ts b/packages/desktop-ui-lib/src/lib/theme/styles/index.ts new file mode 100644 index 00000000000..8f92c5f0b35 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme/styles/index.ts @@ -0,0 +1,2 @@ +export * from './theme.gauzy-light'; +export * from './theme.gauzy-dark'; diff --git a/packages/desktop-ui-lib/src/lib/theme/styles/theme.gauzy-dark.ts b/packages/desktop-ui-lib/src/lib/theme/styles/theme.gauzy-dark.ts new file mode 100644 index 00000000000..4ec88895401 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme/styles/theme.gauzy-dark.ts @@ -0,0 +1,357 @@ +import { NbJSThemeOptions } from '@nebular/theme'; + +const palette = { + primary: '#6E49E8', + success: '#25B869', + info: '#0095ff', + warning: '#ffaa00', + danger: '#ff3d71' +}; + +const theme = { + fontMain: 'Open Sans, sans-serif', + fontSecondary: 'Raleway, sans-serif', + + bg: '#000000', + bg2: '#1a2138', + bg3: '#151a30', + bg4: '#101426', + + border: '#222b45', + border2: '#1a2138', + border3: '#151a30', + border4: '#101426', + border5: '#101426', + + fg: '#8f9bb3', + fgHeading: '#ffffff', + fgText: '#ffffff', + fgHighlight: palette.primary, + layoutBg: '#1b1b38', + separator: '#1b1b38', + + primary: palette.primary, + success: palette.success, + info: palette.info, + warning: palette.warning, + danger: palette.danger, + + primaryLight: '#598bff', + successLight: '#2ce69b', + infoLight: '#42aaff', + warningLight: '#ffc94d', + dangerLight: '#ff708d' +}; + +export const GAUZY_DARK = { + name: 'gauzy-dark', + base: 'dark', + variables: { + ...theme, + + temperature: { + arcFill: [ + theme.primary, + theme.primary, + theme.primary, + theme.primary, + theme.primary + ], + arcEmpty: theme.bg2, + thumbBg: theme.bg2, + thumbBorder: theme.primary + }, + + solar: { + gradientLeft: theme.primary, + gradientRight: theme.primary, + shadowColor: 'rgba(0, 0, 0, 0)', + secondSeriesFill: theme.bg2, + radius: ['80%', '90%'] + }, + + traffic: { + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + + yAxisSplitLine: theme.separator, + + lineBg: theme.border4, + lineShadowBlur: '1', + itemColor: theme.border4, + itemBorderColor: theme.border4, + itemEmphasisBorderColor: theme.primary, + shadowLineDarkBg: 'rgba(0, 0, 0, 0)', + shadowLineShadow: 'rgba(0, 0, 0, 0)', + gradFrom: theme.bg2, + gradTo: theme.bg2 + }, + + electricity: { + tooltipBg: theme.bg, + tooltipLineColor: theme.fgText, + tooltipLineWidth: '0', + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + + axisLineColor: theme.border3, + xAxisTextColor: theme.fg, + yAxisSplitLine: theme.separator, + + itemBorderColor: theme.primary, + lineStyle: 'solid', + lineWidth: '4', + lineGradFrom: theme.primary, + lineGradTo: theme.primary, + lineShadow: 'rgba(0, 0, 0, 0)', + + areaGradFrom: theme.bg2, + areaGradTo: theme.bg2, + shadowLineDarkBg: 'rgba(0, 0, 0, 0)' + }, + + bubbleMap: { + titleColor: theme.fgText, + areaColor: theme.bg4, + areaHoverColor: theme.fgHighlight, + areaBorderColor: theme.border5 + }, + + profitBarAnimationEchart: { + textColor: theme.fgText, + + firstAnimationBarColor: theme.primary, + secondAnimationBarColor: theme.success, + + splitLineStyleOpacity: '1', + splitLineStyleWidth: '1', + splitLineStyleColor: theme.separator, + + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '16', + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipBorderWidth: '1', + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;' + }, + + trafficBarEchart: { + gradientFrom: theme.warningLight, + gradientTo: theme.warning, + shadow: theme.warningLight, + shadowBlur: '0', + + axisTextColor: theme.fgText, + axisFontSize: '12', + + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal' + }, + + countryOrders: { + countryBorderColor: theme.border4, + countryFillColor: theme.bg3, + countryBorderWidth: '1', + hoveredCountryBorderColor: theme.primary, + hoveredCountryFillColor: theme.primaryLight, + hoveredCountryBorderWidth: '1', + + chartAxisLineColor: theme.border4, + chartAxisTextColor: theme.fg, + chartAxisFontSize: '16', + chartGradientTo: theme.primary, + chartGradientFrom: theme.primaryLight, + chartAxisSplitLine: theme.separator, + chartShadowLineColor: theme.primaryLight, + + chartLineBottomShadowColor: theme.primary, + + chartInnerLineColor: theme.bg2 + }, + + echarts: { + bg: theme.bg, + textColor: theme.fgText, + axisLineColor: theme.fgText, + splitLineColor: theme.separator, + itemHoverShadowColor: 'rgba(0, 0, 0, 0.5)', + tooltipBackgroundColor: theme.primary, + areaOpacity: '0.7' + }, + + chartjs: { + axisLineColor: theme.separator, + textColor: theme.fgText + }, + + orders: { + tooltipBg: theme.bg, + tooltipLineColor: 'rgba(0, 0, 0, 0)', + tooltipLineWidth: '0', + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '20', + + axisLineColor: theme.border4, + axisFontSize: '16', + axisTextColor: theme.fg, + yAxisSplitLine: theme.separator, + + itemBorderColor: theme.primary, + lineStyle: 'solid', + lineWidth: '4', + + // first line + firstAreaGradFrom: theme.bg3, + firstAreaGradTo: theme.bg3, + firstShadowLineDarkBg: 'rgba(0, 0, 0, 0)', + + // second line + secondLineGradFrom: theme.primary, + secondLineGradTo: theme.primary, + + secondAreaGradFrom: 'rgba(51, 102, 255, 0.2)', + secondAreaGradTo: 'rgba(51, 102, 255, 0)', + secondShadowLineDarkBg: 'rgba(0, 0, 0, 0)', + + // third line + thirdLineGradFrom: theme.success, + thirdLineGradTo: theme.successLight, + + thirdAreaGradFrom: 'rgba(0, 214, 143, 0.2)', + thirdAreaGradTo: 'rgba(0, 214, 143, 0)', + thirdShadowLineDarkBg: 'rgba(0, 0, 0, 0)' + }, + + profit: { + bg: theme.bg, + textColor: theme.fgText, + axisLineColor: theme.border4, + splitLineColor: theme.separator, + areaOpacity: '1', + + axisFontSize: '16', + axisTextColor: theme.fg, + + // first bar + firstLineGradFrom: theme.bg3, + firstLineGradTo: theme.bg3, + firstLineShadow: 'rgba(0, 0, 0, 0)', + + // second bar + secondLineGradFrom: theme.primary, + secondLineGradTo: theme.primary, + secondLineShadow: 'rgba(0, 0, 0, 0)', + + // third bar + thirdLineGradFrom: theme.success, + thirdLineGradTo: theme.successLight, + thirdLineShadow: 'rgba(0, 0, 0, 0)' + }, + + orderProfitLegend: { + firstItem: theme.success, + secondItem: theme.primary, + thirdItem: theme.bg3 + }, + + visitors: { + tooltipBg: theme.bg, + tooltipLineColor: 'rgba(0, 0, 0, 0)', + tooltipLineWidth: '0', + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '20', + + axisLineColor: theme.border4, + axisFontSize: '16', + axisTextColor: theme.fg, + yAxisSplitLine: theme.separator, + + itemBorderColor: theme.primary, + lineStyle: 'dotted', + lineWidth: '6', + lineGradFrom: '#ffffff', + lineGradTo: '#ffffff', + lineShadow: 'rgba(0, 0, 0, 0)', + + areaGradFrom: theme.primary, + areaGradTo: theme.primaryLight, + + innerLineStyle: 'solid', + innerLineWidth: '1', + + innerAreaGradFrom: theme.success, + innerAreaGradTo: theme.success + }, + + visitorsLegend: { + firstIcon: theme.success, + secondIcon: theme.primary + }, + + visitorsPie: { + firstPieGradientLeft: theme.success, + firstPieGradientRight: theme.success, + firstPieShadowColor: 'rgba(0, 0, 0, 0)', + firstPieRadius: ['70%', '90%'], + + secondPieGradientLeft: theme.warning, + secondPieGradientRight: theme.warningLight, + secondPieShadowColor: 'rgba(0, 0, 0, 0)', + secondPieRadius: ['60%', '97%'], + shadowOffsetX: '0', + shadowOffsetY: '0' + }, + + visitorsPieLegend: { + firstSection: theme.warning, + secondSection: theme.success + }, + + earningPie: { + radius: ['65%', '100%'], + center: ['50%', '50%'], + + fontSize: '22', + + firstPieGradientLeft: theme.success, + firstPieGradientRight: theme.success, + firstPieShadowColor: 'rgba(0, 0, 0, 0)', + + secondPieGradientLeft: theme.primary, + secondPieGradientRight: theme.primary, + secondPieShadowColor: 'rgba(0, 0, 0, 0)', + + thirdPieGradientLeft: theme.warning, + thirdPieGradientRight: theme.warning, + thirdPieShadowColor: 'rgba(0, 0, 0, 0)' + }, + + earningLine: { + gradFrom: theme.primary, + gradTo: theme.primary, + + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '16', + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipBorderWidth: '1', + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;' + } + } +} as NbJSThemeOptions; diff --git a/packages/desktop-ui-lib/src/lib/theme/styles/theme.gauzy-light.ts b/packages/desktop-ui-lib/src/lib/theme/styles/theme.gauzy-light.ts new file mode 100644 index 00000000000..3cb1bc23f8d --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme/styles/theme.gauzy-light.ts @@ -0,0 +1,351 @@ +import { NbJSThemeOptions } from '@nebular/theme'; + +const palette = { + primary: '#6E49E8', + success: '#25B869', + info: '#0095ff', + warning: '#ffaa00', + danger: '#ff3d71', +}; + +const theme = { + fontMain: 'Open Sans, sans-serif', + fontSecondary: 'Raleway, sans-serif', + + bg: '#ffffff', + bg2: '#f7f9fc', + bg3: '#edf1f7', + bg4: '#e4e9f2', + + border: '#ffffff', + border2: '#f7f9fc', + border3: '#edf1f7', + border4: '#e4e9f2', + border5: '#c5cee0', + + fg: '#8f9bb3', + fgHeading: '#1a2138', + fgText: '#1a2138', + fgHighlight: palette.primary, + layoutBg: '#f7f9fc', + separator: '#edf1f7', + + primary: palette.primary, + success: palette.success, + info: palette.info, + warning: palette.warning, + danger: palette.danger, + + primaryLight: '#598bff', + successLight: '#2ce69b', + infoLight: '#42aaff', + warningLight: '#ffc94d', + dangerLight: '#ff708d', +}; + +export const GAUZY_LIGHT = { + name: 'gauzy-light', + base: 'default', + variables: { + ...theme, + + temperature: { + arcFill: [ theme.primary, theme.primary, theme.primary, theme.primary, theme.primary ], + arcEmpty: theme.bg2, + thumbBg: theme.bg2, + thumbBorder: theme.primary, + }, + + solar: { + gradientLeft: theme.primary, + gradientRight: theme.primary, + shadowColor: 'rgba(0, 0, 0, 0)', + secondSeriesFill: theme.bg2, + radius: ['80%', '90%'], + }, + + traffic: { + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + + yAxisSplitLine: theme.separator, + + lineBg: theme.border4, + lineShadowBlur: '1', + itemColor: theme.border4, + itemBorderColor: theme.border4, + itemEmphasisBorderColor: theme.primary, + shadowLineDarkBg: 'rgba(0, 0, 0, 0)', + shadowLineShadow: 'rgba(0, 0, 0, 0)', + gradFrom: theme.bg2, + gradTo: theme.bg2, + }, + + electricity: { + tooltipBg: theme.bg, + tooltipLineColor: theme.fgText, + tooltipLineWidth: '0', + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + + axisLineColor: theme.border3, + xAxisTextColor: theme.fg, + yAxisSplitLine: theme.separator, + + itemBorderColor: theme.primary, + lineStyle: 'solid', + lineWidth: '4', + lineGradFrom: theme.primary, + lineGradTo: theme.primary, + lineShadow: 'rgba(0, 0, 0, 0)', + + areaGradFrom: theme.bg2, + areaGradTo: theme.bg2, + shadowLineDarkBg: 'rgba(0, 0, 0, 0)', + }, + + bubbleMap: { + titleColor: theme.fgText, + areaColor: theme.bg4, + areaHoverColor: theme.fgHighlight, + areaBorderColor: theme.border5, + }, + + profitBarAnimationEchart: { + textColor: theme.fgText, + + firstAnimationBarColor: theme.primary, + secondAnimationBarColor: theme.success, + + splitLineStyleOpacity: '1', + splitLineStyleWidth: '1', + splitLineStyleColor: theme.separator, + + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '16', + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipBorderWidth: '1', + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;', + }, + + trafficBarEchart: { + gradientFrom: theme.warningLight, + gradientTo: theme.warning, + shadow: theme.warningLight, + shadowBlur: '0', + + axisTextColor: theme.fgText, + axisFontSize: '12', + + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + }, + + countryOrders: { + countryBorderColor: theme.border4, + countryFillColor: theme.bg3, + countryBorderWidth: '1', + hoveredCountryBorderColor: theme.primary, + hoveredCountryFillColor: theme.primaryLight, + hoveredCountryBorderWidth: '1', + + chartAxisLineColor: theme.border4, + chartAxisTextColor: theme.fg, + chartAxisFontSize: '16', + chartGradientTo: theme.primary, + chartGradientFrom: theme.primaryLight, + chartAxisSplitLine: theme.separator, + chartShadowLineColor: theme.primaryLight, + + chartLineBottomShadowColor: theme.primary, + + chartInnerLineColor: theme.bg2, + }, + + echarts: { + bg: theme.bg, + textColor: theme.fgText, + axisLineColor: theme.fgText, + splitLineColor: theme.separator, + itemHoverShadowColor: 'rgba(0, 0, 0, 0.5)', + tooltipBackgroundColor: theme.primary, + areaOpacity: '0.7', + }, + + chartjs: { + axisLineColor: theme.separator, + textColor: theme.fgText, + }, + + orders: { + tooltipBg: theme.bg, + tooltipLineColor: 'rgba(0, 0, 0, 0)', + tooltipLineWidth: '0', + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '20', + + axisLineColor: theme.border4, + axisFontSize: '16', + axisTextColor: theme.fg, + yAxisSplitLine: theme.separator, + + itemBorderColor: theme.primary, + lineStyle: 'solid', + lineWidth: '4', + + // first line + firstAreaGradFrom: theme.bg3, + firstAreaGradTo: theme.bg3, + firstShadowLineDarkBg: 'rgba(0, 0, 0, 0)', + + // second line + secondLineGradFrom: theme.primary, + secondLineGradTo: theme.primary, + + secondAreaGradFrom: 'rgba(51, 102, 255, 0.2)', + secondAreaGradTo: 'rgba(51, 102, 255, 0)', + secondShadowLineDarkBg: 'rgba(0, 0, 0, 0)', + + // third line + thirdLineGradFrom: theme.success, + thirdLineGradTo: theme.successLight, + + thirdAreaGradFrom: 'rgba(0, 214, 143, 0.2)', + thirdAreaGradTo: 'rgba(0, 214, 143, 0)', + thirdShadowLineDarkBg: 'rgba(0, 0, 0, 0)', + }, + + profit: { + bg: theme.bg, + textColor: theme.fgText, + axisLineColor: theme.border4, + splitLineColor: theme.separator, + areaOpacity: '1', + + axisFontSize: '16', + axisTextColor: theme.fg, + + // first bar + firstLineGradFrom: theme.bg3, + firstLineGradTo: theme.bg3, + firstLineShadow: 'rgba(0, 0, 0, 0)', + + // second bar + secondLineGradFrom: theme.primary, + secondLineGradTo: theme.primary, + secondLineShadow: 'rgba(0, 0, 0, 0)', + + // third bar + thirdLineGradFrom: theme.success, + thirdLineGradTo: theme.successLight, + thirdLineShadow: 'rgba(0, 0, 0, 0)', + }, + + orderProfitLegend: { + firstItem: theme.success, + secondItem: theme.primary, + thirdItem: theme.bg3, + }, + + visitors: { + tooltipBg: theme.bg, + tooltipLineColor: 'rgba(0, 0, 0, 0)', + tooltipLineWidth: '1', + tooltipBorderColor: theme.border2, + tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;', + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '20', + + axisLineColor: theme.border4, + axisFontSize: '16', + axisTextColor: theme.fg, + yAxisSplitLine: theme.separator, + + itemBorderColor: theme.primary, + lineStyle: 'dotted', + lineWidth: '6', + lineGradFrom: '#ffffff', + lineGradTo: '#ffffff', + lineShadow: 'rgba(0, 0, 0, 0)', + + areaGradFrom: theme.primary, + areaGradTo: theme.primaryLight, + + innerLineStyle: 'solid', + innerLineWidth: '1', + + innerAreaGradFrom: theme.success, + innerAreaGradTo: theme.success, + }, + + visitorsLegend: { + firstIcon: theme.success, + secondIcon: theme.primary, + }, + + visitorsPie: { + firstPieGradientLeft: theme.success, + firstPieGradientRight: theme.success, + firstPieShadowColor: 'rgba(0, 0, 0, 0)', + firstPieRadius: ['70%', '90%'], + + secondPieGradientLeft: theme.warning, + secondPieGradientRight: theme.warningLight, + secondPieShadowColor: 'rgba(0, 0, 0, 0)', + secondPieRadius: ['60%', '97%'], + shadowOffsetX: '0', + shadowOffsetY: '0', + }, + + visitorsPieLegend: { + firstSection: theme.warning, + secondSection: theme.success, + }, + + earningPie: { + radius: ['65%', '100%'], + center: ['50%', '50%'], + + fontSize: '22', + + firstPieGradientLeft: theme.success, + firstPieGradientRight: theme.success, + firstPieShadowColor: 'rgba(0, 0, 0, 0)', + + secondPieGradientLeft: theme.primary, + secondPieGradientRight: theme.primary, + secondPieShadowColor: 'rgba(0, 0, 0, 0)', + + thirdPieGradientLeft: theme.warning, + thirdPieGradientRight: theme.warning, + thirdPieShadowColor: 'rgba(0, 0, 0, 0)', + }, + + earningLine: { + gradFrom: theme.primary, + gradTo: theme.primary, + + tooltipTextColor: theme.fgText, + tooltipFontWeight: 'normal', + tooltipFontSize: '16', + tooltipBg: theme.bg, + tooltipBorderColor: theme.border2, + tooltipBorderWidth: '1', + tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;', + }, + }, +} as NbJSThemeOptions; diff --git a/packages/desktop-ui-lib/src/lib/theme/theme-initializer.factory.ts b/packages/desktop-ui-lib/src/lib/theme/theme-initializer.factory.ts new file mode 100644 index 00000000000..b1e36fa278c --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/theme/theme-initializer.factory.ts @@ -0,0 +1,26 @@ +import { NbThemeService } from '@nebular/theme'; +import { ElectronService } from '../electron/services'; + +const themes = { + light: 'gauzy-light', + dark: 'gauzy-dark' +} +export function ThemeInitializerFactory( + themeService: NbThemeService, + electronService: ElectronService +) { + return async () => { + const theme = await electronService.ipcRenderer.invoke( + 'PREFERRED_THEME' + ); + themeService.changeTheme(themes[theme]); + try { + electronService.ipcRenderer.removeAllListeners('THEME_CHANGE'); + electronService.ipcRenderer.on('THEME_CHANGE', (_, theme) => { + themeService.changeTheme(themes[theme]); + }) + } catch (error) { + console.log('error in theme change', error); + } + }; +} diff --git a/packages/desktop-ui-lib/src/lib/time-tracker/organization-selector/organization-selector.component.ts b/packages/desktop-ui-lib/src/lib/time-tracker/organization-selector/organization-selector.component.ts index ae11953e59a..97c3b664910 100644 --- a/packages/desktop-ui-lib/src/lib/time-tracker/organization-selector/organization-selector.component.ts +++ b/packages/desktop-ui-lib/src/lib/time-tracker/organization-selector/organization-selector.component.ts @@ -1,24 +1,16 @@ -import { - Component, - OnInit, - Output, - EventEmitter, - AfterViewInit, - NgZone, - Input, -} from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, Input, NgZone, OnInit, Output } from '@angular/core'; import { IOrganization, IUser } from '@gauzy/contracts'; import { uniq } from 'underscore'; -import { UserOrganizationService } from './user-organization.service'; import { ElectronService } from '../../electron/services'; +import { Store } from '../../services'; +import { UserOrganizationService } from './user-organization.service'; @Component({ selector: 'ngx-desktop-timer-organization-selector', templateUrl: './organization-selector.component.html', - styleUrls: ['./organization-selector.component.scss'], + styleUrls: ['./organization-selector.component.scss'] }) export class OrganizationSelectorComponent implements OnInit, AfterViewInit { - public organizations: IOrganization[] = []; public selectedOrganization: IOrganization; @@ -47,13 +39,14 @@ export class OrganizationSelectorComponent implements OnInit, AfterViewInit { constructor( private readonly _userOrganizationService: UserOrganizationService, private readonly _electronService: ElectronService, + private readonly _store: Store, private readonly _ngZone: NgZone ) { this.organizationChange = new EventEmitter(); this._isDisabled = false; } - ngOnInit() { } + ngOnInit() {} /** * Component lifecycle hook for operations after the view initializes. @@ -91,6 +84,7 @@ export class OrganizationSelectorComponent implements OnInit, AfterViewInit { // Emit an event indicating the organization has changed if (this.organizationChange) { + this._store.selectedOrganization = this.selectedOrganization; this.organizationChange.emit(organization); } } @@ -125,9 +119,7 @@ export class OrganizationSelectorComponent implements OnInit, AfterViewInit { if (this.organizations.length > 0) { // Find the default organization - const defaultOrganization = this.organizations.find( - (organization) => organization.isDefault - ); + const defaultOrganization = this.organizations.find((organization) => organization.isDefault); // Select the first organization from the list const [firstOrganization] = this.organizations; @@ -144,6 +136,8 @@ export class OrganizationSelectorComponent implements OnInit, AfterViewInit { // If no specific ID, use default or first organization this.selectedOrganization = defaultOrganization || firstOrganization; } + + this._store.selectedOrganization = this.selectedOrganization; } } catch (error) { console.error('Error loading organizations:', error); // Error handling diff --git a/packages/desktop-ui-lib/src/lib/time-tracker/pipes/dayjs.pipe.ts b/packages/desktop-ui-lib/src/lib/time-tracker/pipes/dayjs.pipe.ts new file mode 100644 index 00000000000..db42da38877 --- /dev/null +++ b/packages/desktop-ui-lib/src/lib/time-tracker/pipes/dayjs.pipe.ts @@ -0,0 +1,11 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import * as dayjs from 'dayjs'; + +@Pipe({ + name: 'dayjs' +}) +export class DayjsPipe implements PipeTransform { + transform(value: Date): dayjs.Dayjs { + return dayjs(value); + } +} diff --git a/packages/desktop-ui-lib/src/lib/time-tracker/pipes/pipe.module.ts b/packages/desktop-ui-lib/src/lib/time-tracker/pipes/pipe.module.ts index 09b4bb419fa..4ca0e903832 100644 --- a/packages/desktop-ui-lib/src/lib/time-tracker/pipes/pipe.module.ts +++ b/packages/desktop-ui-lib/src/lib/time-tracker/pipes/pipe.module.ts @@ -1,11 +1,12 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { DateTimePipe } from './date-time.pipe'; +import { DayjsPipe } from './dayjs.pipe'; import { DurationFormatPipe } from './duration-format.pipe'; import { HumanizePipe } from './humanize.pipe'; import { ReplacePipe } from './replace.pipe'; -const pipes = [DateTimePipe, DurationFormatPipe, HumanizePipe, ReplacePipe]; +const pipes = [DateTimePipe, DurationFormatPipe, HumanizePipe, ReplacePipe, DayjsPipe]; @NgModule({ declarations: [...pipes], imports: [CommonModule], diff --git a/packages/desktop-ui-lib/src/lib/time-tracker/time-tracker.component.html b/packages/desktop-ui-lib/src/lib/time-tracker/time-tracker.component.html index c3c158d9d91..3e557967a4c 100644 --- a/packages/desktop-ui-lib/src/lib/time-tracker/time-tracker.component.html +++ b/packages/desktop-ui-lib/src/lib/time-tracker/time-tracker.component.html @@ -4,31 +4,24 @@
-
+ }" class="no-padding full-width timer">
+ [disabled]="start$ | async">
-
+ }" class="timer-container"> {{ timeRun$ | async }}
@@ -40,25 +33,21 @@ {{ 'TIMER_TRACKER.TODAY' | translate }}
-
+ [ngClass]="{ over: (isOver$ | async) }" class="work-duration-container" + nbTooltipIcon="alert-triangle-outline" nbTooltipStatus="danger">
{{ weeklyDuration$ | async }}
{{ 'TIMER_TRACKER.OF_HRS' - | translate - : { - limit: (weeklyLimit$ | async) - } - }} + | translate + : { + limit: (weeklyLimit$ | async) + } + }}
{{ 'TIMESHEET.WEEK' | translate }} @@ -69,37 +58,18 @@
- -
@@ -108,23 +78,16 @@
- + [placeholder]="'TIMER_TRACKER.SELECT_CLIENT' | translate" bindLabel="name" + bindValue="id" nbTooltipStatus="warning"> @@ -133,12 +96,8 @@
- + {{ item?.name }} @@ -150,23 +109,16 @@
- + [placeholder]="'TIMER_TRACKER.SELECT_PROJECT' | translate" bindLabel="name" + bindValue="id" nbTooltipStatus="warning"> @@ -175,12 +127,8 @@
- + {{ item?.name }} @@ -192,21 +140,13 @@
- + [placeholder]="'FORM.LABELS.SELECT_TEAM' | translate | titlecase" bindLabel="name" + bindValue="id" nbTooltipStatus="warning"> @@ -227,32 +167,22 @@
- + [placeholder]="'TIMER_TRACKER.SELECT_TASK' | translate" bindLabel="title" + bindValue="id" nbTooltipStatus="warning"> - + #{{ - item?.taskNumber || item?.prefix.concat('-').concat(item?.number) - | uppercase + item?.taskNumber || item?.prefix.concat('-').concat(item?.number) + | uppercase }} @@ -263,13 +193,11 @@
- + #{{ - item?.taskNumber || - item?.prefix.concat('-').concat(item?.number) | uppercase + item?.taskNumber || + item?.prefix.concat('-').concat(item?.number) | uppercase }} @@ -282,36 +210,26 @@
-
+ class="col-12 form-group" nbTooltipStatus="warning"> - +
-
+
- {{ 'TIMER_TRACKER.WAKATIME_INTEGRATION' | translate }} + {{ 'TIMER_TRACKER.WAKATIME_INTEGRATION' | translate + }}
@@ -320,26 +238,18 @@
-
+
{{ 'TIMER_TRACKER.LAST_CAPTURE_TAKEN' | translate }} {{ (lastScreenCapture$ | async)?.recordedAt | humanize }}
- - + [src]="(lastScreenCapture$ | async)?.thumbUrl" class="screen-capture-img" /> +
@@ -351,15 +261,11 @@
-
@@ -382,8 +288,7 @@
- + [settings]="smartTableSettings" [source]="sourceData$ | async" + style="cursor: pointer">
@@ -450,73 +341,42 @@ + + +
-

- +
@@ -81,33 +60,34 @@
{{ 'PROPOSALS_PAGE.STATISTICS' | translate }}
- + + +
- + {{ 'PROPOSALS_PAGE.STATISTICS' | translate }}

}" > + @@ -131,43 +124,63 @@
{{ 'PROPOSALS_PAGE.STATISTICS' | translate }}
- - + + + + + + + + + + +
+
{{ 'PROPOSALS_PAGE.STATISTICS' | translate }}
+
+
+ {{ 'PROPOSALS_PAGE.ACCEPTED_PROPOSALS' | translate }}: + {{ countAccepted }} +
+
+ {{ 'PROPOSALS_PAGE.TOTAL_PROPOSALS' | translate }}: + {{ totalProposals }} +
+
+ {{ 'PROPOSALS_PAGE.SUCCESS_RATE' | translate }}: + {{ successRate }} +
+
+
+
diff --git a/apps/gauzy/src/app/pages/proposals/proposals.component.scss b/packages/plugins/job-proposal-ui/src/lib/proposal/components/proposal/proposal.component.scss similarity index 91% rename from apps/gauzy/src/app/pages/proposals/proposals.component.scss rename to packages/plugins/job-proposal-ui/src/lib/proposal/components/proposal/proposal.component.scss index 05528bd4ecb..0e685b65c29 100644 --- a/apps/gauzy/src/app/pages/proposals/proposals.component.scss +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/components/proposal/proposal.component.scss @@ -1,4 +1,4 @@ -@import '../payments/payments.component.scss'; +@import '@shared/_payments'; .statistics { display: flex; @@ -25,4 +25,4 @@ nb-card-body { height: calc(100vh - 21.5rem) !important; } -} \ No newline at end of file +} diff --git a/apps/gauzy/src/app/pages/proposals/proposals.component.ts b/packages/plugins/job-proposal-ui/src/lib/proposal/components/proposal/proposal.component.ts similarity index 86% rename from apps/gauzy/src/app/pages/proposals/proposals.component.ts rename to packages/plugins/job-proposal-ui/src/lib/proposal/components/proposal/proposal.component.ts index 3ac128a8ef2..b83d942ee8b 100644 --- a/apps/gauzy/src/app/pages/proposals/proposals.component.ts +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/components/proposal/proposal.component.ts @@ -6,6 +6,7 @@ import { debounceTime, filter, tap } from 'rxjs/operators'; import { Cell } from 'angular2-smart-table'; import { NbDialogService } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IProposal, ComponentLayoutStyleEnum, @@ -16,17 +17,18 @@ import { IDateRangePicker, ITag, PermissionsEnum, - IEmployee + IEmployee, + ID } from '@gauzy/contracts'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { DateRangePickerBuilderService, ErrorHandlingService, ProposalsService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange, toUTC } from '@gauzy/ui-core/common'; import { ActionConfirmationComponent, ClickableLinkComponent, @@ -47,15 +49,15 @@ import { @UntilDestroy({ checkProperties: true }) @Component({ - selector: 'ga-proposals', - templateUrl: './proposals.component.html', - styleUrls: ['./proposals.component.scss'] + selector: 'ga-proposal-list', + templateUrl: './proposal.component.html', + styleUrls: ['./proposal.component.scss'] }) -export class ProposalsComponent extends PaginationFilterBaseComponent implements AfterViewInit, OnInit, OnDestroy { - public smartTableSettings: object; - public selectedEmployeeId: IEmployee['id'] | null; +export class ProposalComponent extends PaginationFilterBaseComponent implements AfterViewInit, OnInit, OnDestroy { + public smartTableSettings: any; + public selectedEmployeeId: ID | null; public selectedDateRange: IDateRangePicker; - public proposals: IProposalViewModel[]; + public proposals: IProposal[] = []; public smartTableSource: ServerDataSource; public dataLayoutStyle = ComponentLayoutStyleEnum.TABLE; public componentLayoutStyleEnum = ComponentLayoutStyleEnum; @@ -72,15 +74,15 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements private _refresh$: Subject = new Subject(); constructor( - private readonly store: Store, - private readonly dateRangePickerBuilderService: DateRangePickerBuilderService, - private readonly router: Router, - private readonly proposalsService: ProposalsService, - private readonly toastrService: ToastrService, - private readonly dialogService: NbDialogService, - private readonly errorHandler: ErrorHandlingService, readonly translateService: TranslateService, - private readonly httpClient: HttpClient + private readonly _store: Store, + private readonly _dateRangePickerBuilderService: DateRangePickerBuilderService, + private readonly _router: Router, + private readonly _proposalsService: ProposalsService, + private readonly _toastrService: ToastrService, + private readonly _dialogService: NbDialogService, + private readonly _errorHandlingService: ErrorHandlingService, + private readonly _httpClient: HttpClient ) { super(translateService); this.setView(); @@ -89,7 +91,6 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements ngOnInit() { this._loadSmartTableSettings(); this._applyTranslationOnSmartTable(); - // Subscribe to changes in the proposals$ observable stream this.proposals$ .pipe( @@ -117,9 +118,9 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements ) .subscribe(); // Combine observable streams to react to changes in organization, date range, and employee - const storeOrganization$ = this.store.selectedOrganization$; - const storeDateRange$ = this.dateRangePickerBuilderService.selectedDateRange$; - const storeEmployee$ = this.store.selectedEmployee$; + const storeOrganization$ = this._store.selectedOrganization$; + const storeDateRange$ = this._dateRangePickerBuilderService.selectedDateRange$; + const storeEmployee$ = this._store.selectedEmployee$; combineLatest([storeOrganization$, storeDateRange$, storeEmployee$]) .pipe( // Wait for 500 milliseconds to debounce rapid changes @@ -158,7 +159,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements ngAfterViewInit() { // Check if a user exists in the store and the user lacks a specific permission - if (this.store.user && !this.store.hasPermission(PermissionsEnum.CHANGE_SELECTED_EMPLOYEE)) { + if (this._store.user && !this._store.hasPermission(PermissionsEnum.CHANGE_SELECTED_EMPLOYEE)) { // Delete the 'author' column from the smartTableSettings.columns object delete this.smartTableSettings['columns']['author']; @@ -171,7 +172,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements * Sets the view based on the component layout. */ setView(): void { - this.store + this._store .componentLayout$(this.viewComponentName) .pipe( distinctUntilChange(), @@ -187,6 +188,25 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements .subscribe(); } + /** + * Navigates to the edit page of a proposal. + * @param selectedItem - The proposal item for which edit page is to be displayed. + */ + edit(selectedItem?: IProposal): void { + // If a proposal item is selected, mark it as selected + if (selectedItem) { + this.selectProposal({ + isSelected: true, + data: selectedItem + }); + } + + // If a proposal is selected, navigate to its edit page + if (this.selectedProposal) { + this._router.navigate([`/pages/sales/proposals/edit`, this.selectedProposal.id]); + } + } + /** * Navigates to the details page of a proposal. * @param selectedItem - The proposal item for which details are to be displayed. @@ -202,7 +222,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements // If a proposal is selected, navigate to its details page if (this.selectedProposal) { - this.router.navigate([`/pages/sales/proposals/details`, this.selectedProposal.id]); + this._router.navigate([`/pages/sales/proposals/details`, this.selectedProposal.id]); } } @@ -220,7 +240,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements } // Open the dialog for user confirmation - const dialogRef = this.dialogService.open(DeleteConfirmationComponent, { + const dialogRef = this._dialogService.open(DeleteConfirmationComponent, { context: { recordType: 'Proposal' } @@ -238,14 +258,14 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements const { id: proposalId } = this.selectedProposal; // Delete the proposal - await this.proposalsService.delete(proposalId); + await this._proposalsService.delete(proposalId); // Display a success message - this.toastrService.success('NOTES.PROPOSALS.DELETE_PROPOSAL'); + this._toastrService.success('NOTES.PROPOSALS.DELETE_PROPOSAL'); } } catch (error) { // Handle errors during the process - this.errorHandler.handleError(error); + this._errorHandlingService.handleError(error); } finally { // Trigger refresh actions this._refresh$.next(true); @@ -268,7 +288,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements } // Open the dialog for user confirmation - const dialogRef = this.dialogService.open(ActionConfirmationComponent, { + const dialogRef = this._dialogService.open(ActionConfirmationComponent, { context: { recordType: 'status' } @@ -287,18 +307,18 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements const { id: proposalId } = this.selectedProposal; // Update the proposal status to "ACCEPTED" - await this.proposalsService.update(proposalId, { + await this._proposalsService.update(proposalId, { status: ProposalStatusEnum.ACCEPTED, organizationId, tenantId }); // TODO: Translate the success message - this.toastrService.success('NOTES.PROPOSALS.PROPOSAL_ACCEPTED'); + this._toastrService.success('NOTES.PROPOSALS.PROPOSAL_ACCEPTED'); } } catch (error) { // Handle errors during the process - this.errorHandler.handleError(error); + this._errorHandlingService.handleError(error); } finally { // Trigger refresh actions this._refresh$.next(true); @@ -321,7 +341,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements } // Open the dialog for user confirmation - const dialogRef = this.dialogService.open(ActionConfirmationComponent, { + const dialogRef = this._dialogService.open(ActionConfirmationComponent, { context: { recordType: 'status' } @@ -340,17 +360,17 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements const { id: proposalId } = this.selectedProposal; // Update the proposal status to "SENT" - await this.proposalsService.update(proposalId, { + await this._proposalsService.update(proposalId, { status: ProposalStatusEnum.SENT, organizationId, tenantId }); - this.toastrService.success('NOTES.PROPOSALS.PROPOSAL_SENT'); + this._toastrService.success('NOTES.PROPOSALS.PROPOSAL_SENT'); } } catch (error) { // Handle errors during the process - this.errorHandler.handleError(error); + this._errorHandlingService.handleError(error); } finally { this._refresh$.next(true); this.proposals$.next(true); @@ -381,6 +401,9 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements }; }; + /** + * Load Smart Table settings to configure the component. + */ private _loadSmartTableSettings() { const pagination: IPaginationBase = this.getPagination(); this.smartTableSettings = { @@ -537,7 +560,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements const { id: organizationId, tenantId } = this.organization; const { startDate, endDate } = getAdjustDateRangeFutureAllowed(this.selectedDateRange); - this.smartTableSource = new ServerDataSource(this.httpClient, { + this.smartTableSource = new ServerDataSource(this._httpClient, { endPoint: `${API_PREFIX}/proposal/pagination`, relations: ['organization', 'employee', 'employee.user', 'tags', 'organizationContact'], join: { @@ -555,9 +578,9 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements }, resultMap: (proposal: IProposal) => this.proposalMapper(proposal), finalize: () => { - // + // Calculate the statistics this.calculateStatistics(); - // + // Set pagination this.setPagination({ ...this.getPagination(), totalItems: this.smartTableSource.count() @@ -594,6 +617,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements /** * Maps properties of an IProposal object to a new object with a modified structure. + * * @param item - The IProposal object to be mapped. * @returns {object} - The mapped object. */ @@ -635,6 +659,8 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements // Set paging and sorting for the smart table source this.smartTableSource.setPaging(activePage, itemsPerPage, false); + + // Set sort for the smart table source this.smartTableSource.setSort( [ { @@ -645,6 +671,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements false ); + // If the layout style is GRID, initiate GRID view pagination if (this.dataLayoutStyle === ComponentLayoutStyleEnum.CARDS_GRID) { // If the layout style is GRID, initiate GRID view pagination await this.smartTableSource.getElements(); @@ -660,7 +687,7 @@ export class ProposalsComponent extends PaginationFilterBaseComponent implements } } catch (error) { // Handle errors by displaying a danger toastr message - this.toastrService.danger(error); + this._errorHandlingService.handleError(error); } } diff --git a/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/job-title/job-title.component.ts b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/job-title/job-title.component.ts new file mode 100644 index 00000000000..4135750a9af --- /dev/null +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/job-title/job-title.component.ts @@ -0,0 +1,9 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + template: `{{ rowData.jobTitle }}` +}) +export class JobTitleComponent { + @Input() rowData: any; + @Input() value: string | number; +} diff --git a/apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.html b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.html similarity index 73% rename from apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.html rename to packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.html index c8a67127716..e768dc8758e 100644 --- a/apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.html +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.html @@ -1,7 +1,4 @@ -
+
{{ 'BUTTONS.SENT' | translate }}
diff --git a/apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.scss b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.scss similarity index 100% rename from apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.scss rename to packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.scss diff --git a/apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.ts b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.ts similarity index 80% rename from apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.ts rename to packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.ts index 343909314f7..9da7af6b1ef 100644 --- a/apps/gauzy/src/app/pages/proposals/table-components/proposal-status/proposal-status.component.ts +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/components/table-components/proposal-status/proposal-status.component.ts @@ -6,7 +6,6 @@ import { Component, Input } from '@angular/core'; styleUrls: ['./proposal-status.component.scss'] }) export class ProposalStatusComponent { - @Input() - rowData: any; - value: string | number; + @Input() rowData: any; + @Input() value: string | number; } diff --git a/packages/plugins/job-proposal-ui/src/lib/proposal/job-proposal.module.ts b/packages/plugins/job-proposal-ui/src/lib/proposal/job-proposal.module.ts new file mode 100644 index 00000000000..dcc52b0b8c7 --- /dev/null +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/job-proposal.module.ts @@ -0,0 +1,223 @@ +import { Inject, NgModule } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { ROUTES, RouterModule } from '@angular/router'; +import { + NbBadgeModule, + NbButtonModule, + NbCardModule, + NbDatepickerModule, + NbDialogModule, + NbIconModule, + NbInputModule, + NbSpinnerModule, + NbTooltipModule +} from '@nebular/theme'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { NgChartsModule } from 'ng2-charts'; +import { NgxPermissionsModule } from 'ngx-permissions'; +import { CKEditorModule } from 'ckeditor4-angular'; +import { PermissionsEnum } from '@gauzy/contracts'; +import { PageRouteRegistryService, PermissionsGuard } from '@gauzy/ui-core/core'; +import { HttpLoaderFactory } from '@gauzy/ui-core/i18n'; +import { + SmartDataViewLayoutModule, + SharedModule, + SelectorsModule, + TableFiltersModule, + ContactSelectModule, + ProposalTemplateSelectModule, + CardGridModule, + UserFormsModule, + TableComponentsModule, + TagsColorInputModule, + DateRangePickerResolver +} from '@gauzy/ui-core/shared'; +import { createProposalsRoutes } from './job-proposal.routes'; +import { COMPONENTS, ProposalDetailsComponent, ProposalEditComponent, ProposalRegisterComponent } from './components'; +import { ProposalComponent } from './components/proposal/proposal.component'; +import { ProposalDetailsResolver } from './resolvers/proposal-details.resolver'; + +/** + * Redirects to the dashboard page + * + * @returns + */ +function redirectTo() { + return '/pages/dashboard'; +} + +/** + * NB Modules + */ +const NB_MODULES = [ + NbBadgeModule, + NbButtonModule, + NbCardModule, + NbDatepickerModule, + NbDialogModule, + NbIconModule, + NbInputModule, + NbSpinnerModule, + NbTooltipModule +]; + +/** + * Third Party Modules + */ +const THIRD_PARTY_MODULES = [ + CKEditorModule, + NgChartsModule, + NgSelectModule, + NgxPermissionsModule.forRoot(), + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient] + } + }) +]; + +@NgModule({ + imports: [ + RouterModule.forChild([]), + ...NB_MODULES, + ...THIRD_PARTY_MODULES, + SharedModule, + TagsColorInputModule, + TableComponentsModule, + UserFormsModule, + CardGridModule, + ProposalTemplateSelectModule, + SmartDataViewLayoutModule, + ContactSelectModule, + TableFiltersModule, + SelectorsModule + ], + declarations: [...COMPONENTS], + exports: [RouterModule], + providers: [ + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createProposalsRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class JobProposalModule { + private static hasRegisteredPageRoutes = false; // Flag to check if routes have been registered + + constructor( + @Inject(PageRouteRegistryService) + readonly _pageRouteRegistryService: PageRouteRegistryService + ) { + // Register the routes + this.registerPageRoutes(); + } + + /** + * Registers routes for the Jobs proposal template module. + * Ensures that routes are registered only once. + * + * @returns {void} + */ + async registerPageRoutes(): Promise { + if (JobProposalModule.hasRegisteredPageRoutes) { + return; + } + + // Register Job Proposal Page Routes + this._pageRouteRegistryService.registerPageRoute({ + // Register the location 'jobs' + location: 'proposals', + // Register the path 'proposal-template' + path: '', + // Register the component + component: ProposalComponent, + // Register the canActivate guard + canActivate: [PermissionsGuard], + // Register the data object + data: { + selectors: { + project: false, + team: false + }, + datePicker: { unitOfTime: 'month' } + }, + resolve: { dates: DateRangePickerResolver } + }); + + // Register Job Proposal Register Page Routes + this._pageRouteRegistryService.registerPageRoute({ + // Register the location 'jobs' + location: 'proposals', + // Register the path 'proposal-template' + path: 'register', + // Register the component + component: ProposalRegisterComponent, + // Register the canActivate guard + canActivate: [PermissionsGuard], + // Register the data object + data: { + permissions: { + only: [PermissionsEnum.ORG_PROPOSALS_EDIT], + redirectTo + }, + selectors: { + employee: false, + project: false, + team: false + }, + datePicker: { unitOfTime: 'month' } + }, + resolve: { dates: DateRangePickerResolver } + }); + + // Register Job Proposal Details Page Routes + this._pageRouteRegistryService.registerPageRoute({ + // Register the location 'jobs' + location: 'proposals', + // Register the path 'proposal-template' + path: 'details/:id', + // Register the component + component: ProposalDetailsComponent, + // Register the canActivate guard + canActivate: [PermissionsGuard], + // Register the data object + data: { + permissions: { + only: [PermissionsEnum.ORG_PROPOSALS_VIEW], + redirectTo + }, + selectors: false + }, + resolve: { proposal: ProposalDetailsResolver } + }); + + // Register Job Proposal Edit Page Routes + this._pageRouteRegistryService.registerPageRoute({ + // Register the location 'jobs' + location: 'proposals', + // Register the path 'proposal-template' + path: 'edit/:id', + // Register the component + component: ProposalEditComponent, + // Register the canActivate guard + canActivate: [PermissionsGuard], + // Register the data object + data: { + permissions: { + only: [PermissionsEnum.ORG_PROPOSALS_EDIT], + redirectTo + }, + selectors: false + }, + resolve: { proposal: ProposalDetailsResolver } + }); + + // Set hasRegisteredRoutes to true + JobProposalModule.hasRegisteredPageRoutes = true; + } +} diff --git a/packages/plugins/job-proposal-ui/src/lib/proposal/job-proposal.routes.ts b/packages/plugins/job-proposal-ui/src/lib/proposal/job-proposal.routes.ts new file mode 100644 index 00000000000..09c04636469 --- /dev/null +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/job-proposal.routes.ts @@ -0,0 +1,17 @@ +import { Route } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { ProposalLayoutComponent } from './components/proposal-layout.component'; + +/** + * Creates proposal routes for the application + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createProposalsRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + component: ProposalLayoutComponent, + children: _pageRouteRegistryService.getPageLocationRoutes('proposals') + } +]; diff --git a/packages/plugins/job-proposal-ui/src/lib/proposal/resolvers/proposal-details.resolver.ts b/packages/plugins/job-proposal-ui/src/lib/proposal/resolvers/proposal-details.resolver.ts new file mode 100644 index 00000000000..ffaab8ec39f --- /dev/null +++ b/packages/plugins/job-proposal-ui/src/lib/proposal/resolvers/proposal-details.resolver.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; +import { catchError, Observable, of } from 'rxjs'; +import { IProposal } from '@gauzy/contracts'; +import { ProposalsService } from '@gauzy/ui-core/core'; + +@Injectable({ + providedIn: 'root' +}) +export class ProposalDetailsResolver implements Resolve> { + constructor(readonly proposalsService: ProposalsService, readonly router: Router) {} + + /** + * Resolves a proposal by its ID from the route parameters. + * If an error occurs during retrieval, the user is redirected to the employees page. + * + * @param route - The activated route snapshot containing the route parameters. + * @returns An observable that emits the resolved proposal or `null` in case of an error. + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const proposalId = route.params.id; + + return this.proposalsService + .getById(proposalId, ['employee', 'employee.user', 'tags', 'organizationContact']) + .pipe( + catchError((error) => { + // Redirect to the employees page if an error occurs + this.router.navigate(['/pages/employees']); + // Return an observable emitting null to indicate the failure + return of(null); + }) + ); + } +} diff --git a/packages/plugins/job-proposal-ui/src/lib/public-api.ts b/packages/plugins/job-proposal-ui/src/lib/public-api.ts index 07d1712237d..f713091e263 100644 --- a/packages/plugins/job-proposal-ui/src/lib/public-api.ts +++ b/packages/plugins/job-proposal-ui/src/lib/public-api.ts @@ -1,7 +1,28 @@ /** - * Public API Surface of job-proposal-ui + * Public API Surface of @gauzy/plugin-job-proposal-ui */ -export * from './job-proposal-template.module'; -export * from './job-proposal-template.routes'; -export * from './components/proposal-template/proposal-template.component'; -export * from './components/add-edit-proposal-template/add-edit-proposal-template.component'; +// Proposal Templates Module and Routes +export * from './proposal-template/job-proposal-template.module'; +export * from './proposal-template/job-proposal-template.routes'; + +// Proposal Template Components +export * from './proposal-template/components/add-edit-proposal-template/add-edit-proposal-template.component'; +export * from './proposal-template/components/proposal-template/proposal-template.component'; + +// Proposals Module and Routes +export * from './proposal/job-proposal.module'; +export * from './proposal/job-proposal.routes'; + +// Proposal Components +export * from './proposal/components/proposal-layout.component'; +export * from './proposal/components/proposal-register/proposal-register.component'; +export * from './proposal/components/proposal-details/proposal-details.component'; +export * from './proposal/components/proposal-edit/proposal-edit.component'; +export * from './proposal/components/proposal-pie-chart/proposal-pie-chart.component'; + +// Table Components +export * from './proposal/components/table-components/job-title/job-title.component'; +export * from './proposal/components/table-components/proposal-status/proposal-status.component'; + +// Proposal Resolvers +export * from './proposal/resolvers/proposal-details.resolver'; diff --git a/packages/plugins/job-proposal-ui/tsconfig.json b/packages/plugins/job-proposal-ui/tsconfig.json index 339a416fe07..86320afd3cd 100644 --- a/packages/plugins/job-proposal-ui/tsconfig.json +++ b/packages/plugins/job-proposal-ui/tsconfig.json @@ -10,14 +10,10 @@ "noFallthroughCasesInSwitch": false, "baseUrl": ".", "paths": { - "@gauzy/ui-core": ["./../../../dist/packages/ui-core"], - "@gauzy/ui-core/common": ["./../../../dist/packages/ui-core/common"], - "@gauzy/ui-core/core": ["./../../../dist/packages/ui-core/core"], - "@gauzy/ui-core/i18n": ["./../../../dist/packages/ui-core/i18n"], - "@gauzy/ui-core/shared": ["./../../../dist/packages/ui-core/shared"], - "@gauzy/ui-core/theme": ["./../../../dist/packages/ui-core/theme"], + "@gauzy/ui-core/*": ["./../../../dist/packages/ui-core/*/index.d.ts"], "@ngx-translate/*": ["./node_modules/@ngx-translate/*"], - "ngx-permissions": ["./node_modules/ngx-permissions"] + "ngx-permissions": ["./node_modules/ngx-permissions"], + "ngx-infinite-scroll": ["./node_modules/ngx-infinite-scroll"] } }, "files": [], diff --git a/packages/plugins/job-proposal/src/lib/proposal/proposal.entity.ts b/packages/plugins/job-proposal/src/lib/proposal/proposal.entity.ts index e6e4805bcb8..f5a781f0367 100644 --- a/packages/plugins/job-proposal/src/lib/proposal/proposal.entity.ts +++ b/packages/plugins/job-proposal/src/lib/proposal/proposal.entity.ts @@ -1,16 +1,7 @@ -import { - JoinColumn, - RelationId, - JoinTable -} from 'typeorm'; +import { JoinColumn, RelationId, JoinTable } from 'typeorm'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsOptional, IsUUID } from 'class-validator'; -import { - IProposal, - IEmployee, - IOrganizationContact, - ProposalStatusEnum -} from '@gauzy/contracts'; +import { IsEnum, IsNotEmpty, IsOptional, IsUUID } from 'class-validator'; +import { IProposal, IEmployee, IOrganizationContact, ProposalStatusEnum, ID } from '@gauzy/contracts'; import { ColumnIndex, Employee, @@ -27,24 +18,29 @@ import { MikroOrmProposalRepository } from './repository/mikro-orm-proposal.repo @MultiORMEntity('proposal', { mikroOrmRepository: () => MikroOrmProposalRepository }) export class Proposal extends TenantOrganizationBaseEntity implements IProposal, Taggable { - @ApiProperty({ type: () => String }) + @ApiPropertyOptional({ type: () => String }) + @IsOptional() @ColumnIndex() @MultiORMColumn({ nullable: true }) jobPostUrl: string; @ApiPropertyOptional({ type: () => Date }) + @IsOptional() @MultiORMColumn({ nullable: true }) valueDate?: Date; - @ApiPropertyOptional({ type: () => String }) + @ApiProperty({ type: () => String }) + @IsNotEmpty() @MultiORMColumn() jobPostContent?: string; - @ApiPropertyOptional({ type: () => String }) + @ApiProperty({ type: () => String }) + @IsNotEmpty() @MultiORMColumn() proposalContent?: string; @ApiProperty({ type: () => String, enum: ProposalStatusEnum }) + @IsEnum(ProposalStatusEnum) @MultiORMColumn() status?: ProposalStatusEnum; @@ -70,7 +66,7 @@ export class Proposal extends TenantOrganizationBaseEntity implements IProposal, @IsUUID() @RelationId((it: Proposal) => it.employee) @MultiORMColumn({ nullable: true, relationId: true }) - employeeId?: string; + employeeId?: ID; /** * @@ -90,7 +86,7 @@ export class Proposal extends TenantOrganizationBaseEntity implements IProposal, @IsUUID() @RelationId((it: Proposal) => it.organizationContact) @MultiORMColumn({ nullable: true, relationId: true }) - organizationContactId?: string; + organizationContactId?: ID; /* |-------------------------------------------------------------------------- diff --git a/packages/plugins/job-search-ui/package.json b/packages/plugins/job-search-ui/package.json index d69f015cf3f..6cd4434065e 100644 --- a/packages/plugins/job-search-ui/package.json +++ b/packages/plugins/job-search-ui/package.json @@ -41,6 +41,7 @@ "@angular/forms": "^16.2.12", "@angular/router": "^16.2.12", "@gauzy/contracts": "^0.1.0", + "@gauzy/ui-core": "^0.1.0", "@nebular/theme": "^12.0.0", "@ngneat/until-destroy": "^9.2.0", "@ngx-translate/core": "^15.0.0", diff --git a/packages/plugins/job-search-ui/src/lib/components/apply-job-manually/apply-job-manually.component.ts b/packages/plugins/job-search-ui/src/lib/components/apply-job-manually/apply-job-manually.component.ts index a0963ca9e4a..d2752b7a26d 100644 --- a/packages/plugins/job-search-ui/src/lib/components/apply-job-manually/apply-job-manually.component.ts +++ b/packages/plugins/job-search-ui/src/lib/components/apply-job-manually/apply-job-manually.component.ts @@ -20,8 +20,8 @@ import { JobPostSourceEnum } from '@gauzy/contracts'; import { environment } from '@gauzy/ui-config'; -import { API_PREFIX, Store, distinctUntilChange, isNotEmpty, sleep } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, JobService } from '@gauzy/ui-core/core'; +import { API_PREFIX, distinctUntilChange, isNotEmpty, sleep } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, JobService, Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { EmployeeSelectorComponent, FormHelpers, ckEditorConfig } from '@gauzy/ui-core/shared'; diff --git a/packages/plugins/job-search-ui/src/lib/components/job-search/job-search.component.ts b/packages/plugins/job-search-ui/src/lib/components/job-search/job-search.component.ts index 081829be8e2..0e3c761f144 100644 --- a/packages/plugins/job-search-ui/src/lib/components/job-search/job-search.component.ts +++ b/packages/plugins/job-search-ui/src/lib/components/job-search/job-search.component.ts @@ -15,6 +15,7 @@ import { ErrorHandlingService, ProposalTemplateService, ServerDataSource, + Store, ToastrService } from '@gauzy/ui-core/core'; import { @@ -44,7 +45,7 @@ import { PaginationFilterBaseComponent, getAdjustDateRangeFutureAllowed } from '@gauzy/ui-core/shared'; -import { API_PREFIX, Store, distinctUntilChange, isNotEmpty, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, distinctUntilChange, isNotEmpty, toUTC } from '@gauzy/ui-core/common'; import { ApplyJobManuallyComponent } from '../apply-job-manually/apply-job-manually.component'; import { JobTitleDescriptionDetailsComponent } from '../job-title-description-details/job-title-description-details.component'; diff --git a/packages/plugins/job-search-ui/src/lib/job-search.module.ts b/packages/plugins/job-search-ui/src/lib/job-search.module.ts index 36f3aee8467..9f7af3a17f0 100644 --- a/packages/plugins/job-search-ui/src/lib/job-search.module.ts +++ b/packages/plugins/job-search-ui/src/lib/job-search.module.ts @@ -21,7 +21,7 @@ import { MomentModule } from 'ngx-moment'; import { NgxPermissionsModule } from 'ngx-permissions'; import { FileUploadModule } from 'ng2-file-upload'; import { LanguagesEnum } from '@gauzy/contracts'; -import { PageRouteService } from '@gauzy/ui-core/core'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; import { HttpLoaderFactory } from '@gauzy/ui-core/i18n'; import { SmartDataViewLayoutModule, @@ -31,7 +31,7 @@ import { SharedModule, StatusBadgeModule } from '@gauzy/ui-core/shared'; -import { createRoutes } from './job-search.routes'; +import { createJobSearchRoutes } from './job-search.routes'; import { JobSearchComponent } from './components/job-search/job-search.component'; import { COMPONENTS } from './components'; @@ -88,8 +88,8 @@ const THIRD_PARTY_MODULES = [ providers: [ { provide: ROUTES, - useFactory: (pageRouteService: PageRouteService) => createRoutes(pageRouteService), - deps: [PageRouteService], + useFactory: (service: PageRouteRegistryService) => createJobSearchRoutes(service), + deps: [PageRouteRegistryService], multi: true } ] @@ -97,7 +97,7 @@ const THIRD_PARTY_MODULES = [ export class JobSearchModule { private static hasRegisteredPageRoutes = false; // Flag to check if routes have been registered - constructor(@Inject(PageRouteService) readonly _pageRouteService: PageRouteService) { + constructor(@Inject(PageRouteRegistryService) readonly _pageRouteRegistryService: PageRouteRegistryService) { // Register the routes this.registerPageRoutes(); } @@ -114,7 +114,7 @@ export class JobSearchModule { } // Register Job Browser Page Routes - this._pageRouteService.registerPageRoute({ + this._pageRouteRegistryService.registerPageRoute({ // Register the location 'jobs' location: 'jobs', // Register the path 'search' diff --git a/packages/plugins/job-search-ui/src/lib/job-search.routes.ts b/packages/plugins/job-search-ui/src/lib/job-search.routes.ts index 234301316dd..9a91b28c4f9 100644 --- a/packages/plugins/job-search-ui/src/lib/job-search.routes.ts +++ b/packages/plugins/job-search-ui/src/lib/job-search.routes.ts @@ -1,15 +1,15 @@ import { Route } from '@angular/router'; import { IntegrationEnum, PermissionsEnum } from '@gauzy/contracts'; -import { IntegrationResolver, PageRouteService, PermissionsGuard } from '@gauzy/ui-core/core'; +import { IntegrationResolver, PageRouteRegistryService, PermissionsGuard } from '@gauzy/ui-core/core'; import { JobSearchComponent } from './components/job-search/job-search.component'; /** * Creates jobs browse routes for the application * - * @param _pageRouteService An instance of PageRouteService + * @param _pageRouteRegistryService An instance of PageRouteRegistryService * @returns An array of Route objects */ -export const createRoutes = (_pageRouteService: PageRouteService): Route[] => [ +export const createJobSearchRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ { path: '', component: JobSearchComponent, diff --git a/packages/plugins/job-search-ui/tsconfig.json b/packages/plugins/job-search-ui/tsconfig.json index 339a416fe07..8a309f45a75 100644 --- a/packages/plugins/job-search-ui/tsconfig.json +++ b/packages/plugins/job-search-ui/tsconfig.json @@ -10,12 +10,7 @@ "noFallthroughCasesInSwitch": false, "baseUrl": ".", "paths": { - "@gauzy/ui-core": ["./../../../dist/packages/ui-core"], - "@gauzy/ui-core/common": ["./../../../dist/packages/ui-core/common"], - "@gauzy/ui-core/core": ["./../../../dist/packages/ui-core/core"], - "@gauzy/ui-core/i18n": ["./../../../dist/packages/ui-core/i18n"], - "@gauzy/ui-core/shared": ["./../../../dist/packages/ui-core/shared"], - "@gauzy/ui-core/theme": ["./../../../dist/packages/ui-core/theme"], + "@gauzy/ui-core/*": ["./../../../dist/packages/ui-core/*/index.d.ts"], "@ngx-translate/*": ["./node_modules/@ngx-translate/*"], "ngx-permissions": ["./node_modules/ngx-permissions"] } diff --git a/packages/plugins/knowledge-base/jest.config.ts b/packages/plugins/knowledge-base/jest.config.ts index 5764e5a052a..db722b387d2 100644 --- a/packages/plugins/knowledge-base/jest.config.ts +++ b/packages/plugins/knowledge-base/jest.config.ts @@ -1,6 +1,6 @@ /* eslint-disable */ export default { - displayName: 'plugins-knowledge-base', + displayName: 'plugin-knowledge-base', preset: '../../../jest.preset.js', testEnvironment: 'node', transform: { diff --git a/packages/plugins/legal-ui/.dockerignore b/packages/plugins/legal-ui/.dockerignore new file mode 100644 index 00000000000..6edd0523636 --- /dev/null +++ b/packages/plugins/legal-ui/.dockerignore @@ -0,0 +1,20 @@ +docker +tmp +README.md +.env + +# git + +.git +.gitignore +.gitmodules + +# dependencies + +node_modules + +# misc + +npm-debug.log +dist +build diff --git a/packages/plugins/legal-ui/.eslintrc.json b/packages/plugins/legal-ui/.eslintrc.json new file mode 100644 index 00000000000..83c0ab9447f --- /dev/null +++ b/packages/plugins/legal-ui/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "extends": ["../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "ga", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "ga", + "style": "kebab-case" + } + ] + }, + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"] + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/packages/plugins/legal-ui/.gitignore b/packages/plugins/legal-ui/.gitignore new file mode 100644 index 00000000000..a34877c2c0e --- /dev/null +++ b/packages/plugins/legal-ui/.gitignore @@ -0,0 +1,6 @@ +# dependencies +node_modules/ + +# misc +npm-debug.log +dist \ No newline at end of file diff --git a/packages/plugins/legal-ui/.npmignore b/packages/plugins/legal-ui/.npmignore new file mode 100644 index 00000000000..1eb4beb9572 --- /dev/null +++ b/packages/plugins/legal-ui/.npmignore @@ -0,0 +1,4 @@ +# .npmignore + +src/ +node_modules/ diff --git a/packages/plugins/legal-ui/README.md b/packages/plugins/legal-ui/README.md new file mode 100644 index 00000000000..748e6f0a3c1 --- /dev/null +++ b/packages/plugins/legal-ui/README.md @@ -0,0 +1,7 @@ +# @gauzy/plugin-legal-ui + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test plugin-legal-ui` to execute the unit tests. diff --git a/packages/plugins/legal-ui/jest.config.ts b/packages/plugins/legal-ui/jest.config.ts new file mode 100644 index 00000000000..a7779e4aa6f --- /dev/null +++ b/packages/plugins/legal-ui/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'plugin-legal-ui', + preset: '../../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../../coverage/packages/plugins/legal-ui', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$' + } + ] + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment' + ] +}; diff --git a/packages/plugins/legal-ui/ng-package.json b/packages/plugins/legal-ui/ng-package.json new file mode 100644 index 00000000000..56d3167868c --- /dev/null +++ b/packages/plugins/legal-ui/ng-package.json @@ -0,0 +1,10 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../../dist/packages/plugins/legal-ui", + "lib": { + "entryFile": "src/index.ts", + "styleIncludePaths": ["../../../dist/packages/ui-core/static/styles"] + }, + "allowedNonPeerDependencies": ["."], + "assets": [] +} diff --git a/packages/plugins/legal-ui/package.json b/packages/plugins/legal-ui/package.json new file mode 100644 index 00000000000..f4ed44a5c3e --- /dev/null +++ b/packages/plugins/legal-ui/package.json @@ -0,0 +1,54 @@ +{ + "name": "@gauzy/plugin-legal-ui", + "version": "0.1.0", + "type": "commonjs", + "description": "A plugin for the legal UI in the Ever Gauzy platform, providing components and modules for managing legal documents and agreements.", + "author": { + "name": "Ever Co. LTD", + "email": "ever@ever.co", + "url": "https://ever.co" + }, + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "https://github.com/ever-co/ever-gauzy" + }, + "bugs": { + "url": "https://github.com/ever-co/ever-gauzy/issues" + }, + "homepage": "https://ever.co", + "keywords": [ + "legal", + "plugin", + "angular", + "ui", + "gauzy" + ], + "private": true, + "scripts": { + "lib:build": "ng build plugin-legal-ui --configuration=development", + "lib:build:prod": "ng build plugin-legal-ui --configuration=production", + "lib:watch": "ng build plugin-legal-ui --watch --configuration=development" + }, + "peerDependencies": { + "@angular/common": "^16.2.12", + "@angular/core": "^16.2.12" + }, + "dependencies": { + "@angular/router": "^16.2.12", + "@gauzy/ui-core": "^0.1.0", + "@nebular/auth": "^12.0.0", + "@ngx-translate/core": "^15.0.0", + "tslib": "^2.6.2" + }, + "devDependencies": { + "@types/jest": "^29.4.4", + "@types/node": "^20.14.9", + "jest-preset-angular": "^13.1.4" + }, + "engines": { + "node": ">=20.11.1", + "yarn": ">=1.22.19" + }, + "sideEffects": false +} diff --git a/packages/plugins/legal-ui/project.json b/packages/plugins/legal-ui/project.json new file mode 100644 index 00000000000..9d404e20432 --- /dev/null +++ b/packages/plugins/legal-ui/project.json @@ -0,0 +1,47 @@ +{ + "name": "plugin-legal-ui", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/plugins/legal-ui/src", + "prefix": "ga", + "tags": [], + "projectType": "library", + "targets": { + "build": { + "executor": "@nrwl/angular:package", + "outputs": ["{workspaceRoot}/dist/{projectRoot}"], + "options": { + "project": "packages/plugins/legal-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/legal-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/legal-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/plugins/legal-ui/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["packages/plugins/legal-ui/**/*.ts", "packages/plugins/legal-ui/**/*.html"] + } + } + } +} diff --git a/packages/plugins/legal-ui/src/index.ts b/packages/plugins/legal-ui/src/index.ts new file mode 100644 index 00000000000..8d5f6d77256 --- /dev/null +++ b/packages/plugins/legal-ui/src/index.ts @@ -0,0 +1,4 @@ +/** + * Public API Surface of @gauzy/plugin-legal-ui + */ +export * from './lib/public-api'; diff --git a/packages/plugins/legal-ui/src/lib/common-legal.module.ts b/packages/plugins/legal-ui/src/lib/common-legal.module.ts new file mode 100644 index 00000000000..06e7fb6a666 --- /dev/null +++ b/packages/plugins/legal-ui/src/lib/common-legal.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core'; +import { TermsAndConditionsComponent } from './components/terms-and-conditions/terms-and-conditions.component'; +import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-policy.component'; + +@NgModule({ + declarations: [TermsAndConditionsComponent, PrivacyPolicyComponent], + exports: [TermsAndConditionsComponent, PrivacyPolicyComponent] +}) +export class CommonLegalModule {} diff --git a/packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.html b/packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.html similarity index 100% rename from packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.html rename to packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.html diff --git a/packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.scss b/packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.scss similarity index 100% rename from packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.scss rename to packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.scss diff --git a/packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.ts b/packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.ts similarity index 56% rename from packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.ts rename to packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.ts index ae46d8912ee..5f886ed748d 100644 --- a/packages/ui-core/shared/src/lib/legal/privacy-policy/privacy-policy.component.ts +++ b/packages/plugins/legal-ui/src/lib/components/privacy-policy/privacy-policy.component.ts @@ -1,6 +1,6 @@ import { DOCUMENT } from '@angular/common'; import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; -import { LegalService } from '../legal.service'; +import { LegalService } from '../../providers/legal.service'; export const PRIVACY_POLICY_ENDPOINT = 'https://www.iubenda.com/api/privacy-policy/18120170'; export const COOKIE_PRIVACY_POLICY_ENDPOINT = 'https://www.iubenda.com/api/privacy-policy/18120170/cookie-policy'; @@ -10,14 +10,20 @@ export const COOKIE_PRIVACY_POLICY_ENDPOINT = 'https://www.iubenda.com/api/priva styleUrls: ['./privacy-policy.component.scss'] }) export class PrivacyPolicyComponent implements OnInit, OnDestroy { - privacy_policy: string; - cookie_policy: string; + public privacy_policy: string; + public cookie_policy: string; constructor(private readonly legalService: LegalService, @Inject(DOCUMENT) private readonly _document: Document) {} + /** + * Load privacy policy from iubenda + */ ngOnInit(): void { + // Get privacy policy from iubenda this.getPrivacyPolicyJsonFromUrl(PRIVACY_POLICY_ENDPOINT); this.getCookiePolicyJsonFromUrl(COOKIE_PRIVACY_POLICY_ENDPOINT); + + // Add class to body to display privacy policy this._document.body.classList.add('privacy-container'); } @@ -26,12 +32,18 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy { * * @param url https://www.iubenda.com/api/privacy-policy/18120170 */ - getPrivacyPolicyJsonFromUrl(url: string) { - this.legalService.getContentFromFromUrl(PRIVACY_POLICY_ENDPOINT).then((data: any) => { - if (!!data.content) { + async getPrivacyPolicyJsonFromUrl(url: string) { + try { + // Get privacy policy from iubenda + const data: any = await this.legalService.getContentFromFromUrl(PRIVACY_POLICY_ENDPOINT); + + // Add privacy policy to component + if (data?.content) { this.privacy_policy = data.content; } - }); + } catch (error) { + console.error('Error fetching privacy policy:', error); + } } /** @@ -39,14 +51,23 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy { * * @param url https://www.iubenda.com/api/privacy-policy/18120170/cookie-policy */ - getCookiePolicyJsonFromUrl(url: string) { - this.legalService.getContentFromFromUrl(COOKIE_PRIVACY_POLICY_ENDPOINT).then((data: any) => { - if (!!data.content) { + async getCookiePolicyJsonFromUrl(url: string) { + try { + // Get cookie policy from iubenda + const data: any = await this.legalService.getContentFromFromUrl(COOKIE_PRIVACY_POLICY_ENDPOINT); + + // Add cookie policy to component + if (data?.content) { this.cookie_policy = data.content; } - }); + } catch (error) { + console.error('Error fetching cookie policy:', error); + } } + /** + * Remove class to body to hide privacy policy + */ ngOnDestroy() { this._document.body.classList.remove('privacy-container'); } diff --git a/packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.html b/packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.html similarity index 100% rename from packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.html rename to packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.html diff --git a/packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.scss b/packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.scss similarity index 100% rename from packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.scss rename to packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.scss diff --git a/packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.ts b/packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.ts similarity index 70% rename from packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.ts rename to packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.ts index 598f4427f33..e8bf753b9c4 100644 --- a/packages/ui-core/shared/src/lib/legal/terms-and-conditions/terms-and-conditions.component.ts +++ b/packages/plugins/legal-ui/src/lib/components/terms-and-conditions/terms-and-conditions.component.ts @@ -1,6 +1,6 @@ import { DOCUMENT } from '@angular/common'; import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; -import { LegalService } from '../legal.service'; +import { LegalService } from '../../providers/legal.service'; export const TERM_AND_POLICY_ENDPOINT = 'https://www.iubenda.com/api/terms-and-conditions/7927924'; @@ -10,7 +10,7 @@ export const TERM_AND_POLICY_ENDPOINT = 'https://www.iubenda.com/api/terms-and-c styleUrls: ['./terms-and-conditions.component.scss'] }) export class TermsAndConditionsComponent implements OnInit, OnDestroy { - term_and_policy: string; + public term_and_policy: string; constructor(private readonly legalService: LegalService, @Inject(DOCUMENT) private readonly _document: Document) {} @@ -24,14 +24,20 @@ export class TermsAndConditionsComponent implements OnInit, OnDestroy { * * @param url https://www.iubenda.com/api/terms-and-conditions/7927924 */ - getTermJsonFromUrl(url: string) { - this.legalService.getContentFromFromUrl(url).then((data: any) => { - if (!!data.content) { + async getTermJsonFromUrl(url: string) { + try { + const data: any = await this.legalService.getContentFromFromUrl(url); + if (data?.content) { this.term_and_policy = data.content; } - }); + } catch (error) { + console.error('Error fetching terms and conditions:', error); + } } + /** + * Remove class to body to hide terms and conditions + */ ngOnDestroy() { this._document.body.classList.remove('term-container'); } diff --git a/packages/plugins/legal-ui/src/lib/legal.module.ts b/packages/plugins/legal-ui/src/lib/legal.module.ts new file mode 100644 index 00000000000..e7f8589ae1f --- /dev/null +++ b/packages/plugins/legal-ui/src/lib/legal.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { ROUTES } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { createLegalRoutes } from './legal.routes'; +import { CommonLegalModule } from './common-legal.module'; + +@NgModule({ + imports: [CommonLegalModule], + providers: [ + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createLegalRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class LegalModule {} diff --git a/packages/plugins/legal-ui/src/lib/legal.routes.ts b/packages/plugins/legal-ui/src/lib/legal.routes.ts new file mode 100644 index 00000000000..605f912250f --- /dev/null +++ b/packages/plugins/legal-ui/src/lib/legal.routes.ts @@ -0,0 +1,33 @@ +import { Route } from '@angular/router'; +import { NbAuthComponent } from '@nebular/auth'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { TermsAndConditionsComponent } from './components/terms-and-conditions/terms-and-conditions.component'; +import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-policy.component'; + +/** + * Creates legal routes for the application + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createLegalRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + component: NbAuthComponent, + children: [ + { + path: '', + redirectTo: 'terms', + pathMatch: 'full' + }, + { + path: 'terms', + component: TermsAndConditionsComponent + }, + { + path: 'privacy', + component: PrivacyPolicyComponent + } + ] + } +]; diff --git a/packages/plugins/legal-ui/src/lib/page-legal.module.ts b/packages/plugins/legal-ui/src/lib/page-legal.module.ts new file mode 100644 index 00000000000..5ef9fb67e43 --- /dev/null +++ b/packages/plugins/legal-ui/src/lib/page-legal.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { ROUTES } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { createPageLegalRoutes } from './page-legal.routes'; +import { CommonLegalModule } from './common-legal.module'; + +@NgModule({ + imports: [CommonLegalModule], + providers: [ + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createPageLegalRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class PageLegalModule {} diff --git a/packages/plugins/legal-ui/src/lib/page-legal.routes.ts b/packages/plugins/legal-ui/src/lib/page-legal.routes.ts new file mode 100644 index 00000000000..2b415904813 --- /dev/null +++ b/packages/plugins/legal-ui/src/lib/page-legal.routes.ts @@ -0,0 +1,49 @@ +import { Route } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { TermsAndConditionsComponent } from './components/terms-and-conditions/terms-and-conditions.component'; +import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-policy.component'; + +/** + * Creates page legal routes for the application + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createPageLegalRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + children: [ + { + path: '', + redirectTo: 'terms', + pathMatch: 'full' + }, + { + path: 'terms', + component: TermsAndConditionsComponent, + data: { + selectors: { + organization: false, + date: false, + employee: false, + project: false, + team: false + } + } + }, + { + path: 'privacy', + component: PrivacyPolicyComponent, + data: { + selectors: { + organization: false, + date: false, + employee: false, + project: false, + team: false + } + } + } + ] + } +]; diff --git a/packages/ui-core/shared/src/lib/legal/legal.service.ts b/packages/plugins/legal-ui/src/lib/providers/legal.service.ts similarity index 100% rename from packages/ui-core/shared/src/lib/legal/legal.service.ts rename to packages/plugins/legal-ui/src/lib/providers/legal.service.ts index 1d4ee98f207..9c9e721a4e9 100644 --- a/packages/ui-core/shared/src/lib/legal/legal.service.ts +++ b/packages/plugins/legal-ui/src/lib/providers/legal.service.ts @@ -1,5 +1,5 @@ -import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; import { firstValueFrom } from 'rxjs'; @Injectable({ diff --git a/packages/plugins/legal-ui/src/lib/public-api.ts b/packages/plugins/legal-ui/src/lib/public-api.ts new file mode 100644 index 00000000000..d8620ef0ba1 --- /dev/null +++ b/packages/plugins/legal-ui/src/lib/public-api.ts @@ -0,0 +1,10 @@ +/** + * Public API Surface of @gauzy/plugin-legal-ui + */ +export * from './components/terms-and-conditions/terms-and-conditions.component'; +export * from './components/privacy-policy/privacy-policy.component'; +export * from './legal.module'; +export * from './legal.routes'; +export * from './page-legal.module'; +export * from './page-legal.routes'; +export * from './providers/legal.service'; diff --git a/packages/plugins/legal-ui/src/test-setup.ts b/packages/plugins/legal-ui/src/test-setup.ts new file mode 100644 index 00000000000..1100b3e8a6e --- /dev/null +++ b/packages/plugins/legal-ui/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/packages/plugins/legal-ui/tsconfig.json b/packages/plugins/legal-ui/tsconfig.json new file mode 100644 index 00000000000..eea653160cb --- /dev/null +++ b/packages/plugins/legal-ui/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": false, + "noPropertyAccessFromIndexSignature": false, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + "baseUrl": ".", + "paths": { + "@gauzy/ui-core/*": ["./../../../dist/packages/ui-core/*/index.d.ts"], + "@ngx-translate/*": ["./node_modules/@ngx-translate/*"] + } + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/plugins/legal-ui/tsconfig.lib.json b/packages/plugins/legal-ui/tsconfig.lib.json new file mode 100644 index 00000000000..5d1d67c0227 --- /dev/null +++ b/packages/plugins/legal-ui/tsconfig.lib.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/packages/plugins/legal-ui/tsconfig.lib.prod.json b/packages/plugins/legal-ui/tsconfig.lib.prod.json new file mode 100644 index 00000000000..7b29b93f6f3 --- /dev/null +++ b/packages/plugins/legal-ui/tsconfig.lib.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/packages/plugins/legal-ui/tsconfig.spec.json b/packages/plugins/legal-ui/tsconfig.spec.json new file mode 100644 index 00000000000..0b8b86994ff --- /dev/null +++ b/packages/plugins/legal-ui/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/packages/plugins/maintenance-ui/.dockerignore b/packages/plugins/maintenance-ui/.dockerignore new file mode 100644 index 00000000000..6edd0523636 --- /dev/null +++ b/packages/plugins/maintenance-ui/.dockerignore @@ -0,0 +1,20 @@ +docker +tmp +README.md +.env + +# git + +.git +.gitignore +.gitmodules + +# dependencies + +node_modules + +# misc + +npm-debug.log +dist +build diff --git a/packages/plugins/maintenance-ui/.eslintrc.json b/packages/plugins/maintenance-ui/.eslintrc.json new file mode 100644 index 00000000000..32896661eef --- /dev/null +++ b/packages/plugins/maintenance-ui/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "gauzy", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "gauzy", + "style": "kebab-case" + } + ] + }, + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"] + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/packages/plugins/maintenance-ui/.gitignore b/packages/plugins/maintenance-ui/.gitignore new file mode 100644 index 00000000000..a34877c2c0e --- /dev/null +++ b/packages/plugins/maintenance-ui/.gitignore @@ -0,0 +1,6 @@ +# dependencies +node_modules/ + +# misc +npm-debug.log +dist \ No newline at end of file diff --git a/packages/plugins/maintenance-ui/.npmignore b/packages/plugins/maintenance-ui/.npmignore new file mode 100644 index 00000000000..1eb4beb9572 --- /dev/null +++ b/packages/plugins/maintenance-ui/.npmignore @@ -0,0 +1,4 @@ +# .npmignore + +src/ +node_modules/ diff --git a/packages/plugins/maintenance-ui/README.md b/packages/plugins/maintenance-ui/README.md new file mode 100644 index 00000000000..8fa8dd1a1c4 --- /dev/null +++ b/packages/plugins/maintenance-ui/README.md @@ -0,0 +1,7 @@ +# @gauzy/plugin-maintenance-ui + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test plugin-maintenance-ui` to execute the unit tests. diff --git a/packages/plugins/maintenance-ui/jest.config.ts b/packages/plugins/maintenance-ui/jest.config.ts new file mode 100644 index 00000000000..33866b94fcb --- /dev/null +++ b/packages/plugins/maintenance-ui/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'plugin-maintenance-ui', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/packages/plugins/maintenance-ui', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$' + } + ] + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment' + ] +}; diff --git a/packages/plugins/maintenance-ui/ng-package.json b/packages/plugins/maintenance-ui/ng-package.json new file mode 100644 index 00000000000..c86f81f6854 --- /dev/null +++ b/packages/plugins/maintenance-ui/ng-package.json @@ -0,0 +1,10 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../../dist/packages/plugins/maintenance-ui", + "lib": { + "entryFile": "src/index.ts", + "styleIncludePaths": ["../../../dist/packages/ui-core/static/styles"] + }, + "allowedNonPeerDependencies": ["."], + "assets": [] +} diff --git a/packages/plugins/maintenance-ui/package.json b/packages/plugins/maintenance-ui/package.json new file mode 100644 index 00000000000..49928573d18 --- /dev/null +++ b/packages/plugins/maintenance-ui/package.json @@ -0,0 +1,50 @@ +{ + "name": "@gauzy/plugin-maintenance-ui", + "version": "0.1.0", + "type": "commonjs", + "description": "", + "author": { + "name": "Ever Co. LTD", + "email": "ever@ever.co", + "url": "https://ever.co" + }, + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "https://github.com/ever-co/ever-gauzy" + }, + "bugs": { + "url": "https://github.com/ever-co/ever-gauzy/issues" + }, + "homepage": "https://ever.co", + "keywords": [], + "private": true, + "scripts": { + "lib:build": "ng build plugin-maintenance-ui --configuration=development", + "lib:build:prod": "ng build plugin-maintenance-ui --configuration=production", + "lib:watch": "ng build plugin-maintenance-ui --watch --configuration=development" + }, + "peerDependencies": { + "@angular/common": "^16.2.12", + "@angular/core": "^16.2.12" + }, + "dependencies": { + "@angular/router": "^16.2.12", + "@gauzy/contracts": "^0.1.0", + "@gauzy/ui-config": "^0.1.0", + "@gauzy/ui-core": "^0.1.0", + "@nebular/theme": "^12.0.0", + "@ngx-translate/core": "^15.0.0", + "tslib": "^2.6.2" + }, + "devDependencies": { + "@types/jest": "^29.4.4", + "@types/node": "^20.14.9", + "jest-preset-angular": "^13.1.4" + }, + "engines": { + "node": ">=20.11.1", + "yarn": ">=1.22.19" + }, + "sideEffects": false +} diff --git a/packages/plugins/maintenance-ui/project.json b/packages/plugins/maintenance-ui/project.json new file mode 100644 index 00000000000..6accc809213 --- /dev/null +++ b/packages/plugins/maintenance-ui/project.json @@ -0,0 +1,50 @@ +{ + "name": "plugin-maintenance-ui", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/plugins/maintenance-ui/src", + "prefix": "gauzy", + "tags": ["ui"], + "projectType": "library", + "targets": { + "build": { + "executor": "@nrwl/angular:package", + "outputs": ["{workspaceRoot}/dist/{projectRoot}"], + "options": { + "project": "packages/plugins/maintenance-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/maintenance-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/maintenance-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/plugins/maintenance-ui/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": [ + "packages/plugins/maintenance-ui/**/*.ts", + "packages/plugins/maintenance-ui/**/*.html" + ] + } + } + } +} diff --git a/packages/plugins/maintenance-ui/src/index.ts b/packages/plugins/maintenance-ui/src/index.ts new file mode 100644 index 00000000000..c61ef70e321 --- /dev/null +++ b/packages/plugins/maintenance-ui/src/index.ts @@ -0,0 +1,4 @@ +/** + * Entry point for all public APIs of the @gauzy/plugin-maintenance-ui package. + */ +export * from './lib/public-api'; diff --git a/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.html b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.html new file mode 100644 index 00000000000..70f45b32cc6 --- /dev/null +++ b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.html @@ -0,0 +1,12 @@ + + +
+ +
+

{{ 'GAUZY_MAINTENANCE' | translate : { companySite } }}

+
+
+
+
diff --git a/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.scss b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.scss new file mode 100644 index 00000000000..92ea58d71fe --- /dev/null +++ b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.scss @@ -0,0 +1,26 @@ +.info-page { + padding: 0 !important; + + .maintenance-mode-content { + color: white; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + height: 100%; + flex-direction: column; + + img { + max-height: 96px; + max-width: 300px; + width: auto; + } + + .info-message { + h3 { + color: red; + width: 100%; + } + } + } +} diff --git a/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.ts b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.ts new file mode 100644 index 00000000000..4a1f21f35d2 --- /dev/null +++ b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.component.ts @@ -0,0 +1,59 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; +import { environment } from '@gauzy/ui-config'; +import { ServerConnectionService, Store } from '@gauzy/ui-core/core'; + +@Component({ + selector: 'ga-maintenance-mode', + styleUrls: ['./maintenance-mode.component.scss'], + templateUrl: './maintenance-mode.component.html' +}) +export class MaintenanceModeComponent implements OnInit, OnDestroy { + noInternetLogo: string; + interval: any; + + constructor( + private readonly _store: Store, + private readonly _location: Location, + private readonly _serverConnectionService: ServerConnectionService + ) { + this.noInternetLogo = environment['NO_INTERNET_LOGO']; + } + + ngOnInit(): void { + this.checkConnection(); + } + + /** + * Checks the server connection every 5 seconds. + */ + private async checkConnection() { + const url = environment.API_BASE_URL; + console.log('Checking server connection to URL: ', url); + + this.interval = setInterval(async () => { + console.log('Checking server connection...'); + await this._serverConnectionService.checkServerConnection(url); + + // Check if the server is online + if (Number(this._store.serverConnection) === 200) { + console.log('Server is online'); + clearInterval(this.interval); + this._location.back(); + } else { + console.log('Server is offline'); + } + }, 5000); + } + + /** + * Checks if the company site is defined in the environment. + * + * @return {string} The company site name. + */ + public get companySite(): string { + return environment.COMPANY_SITE_NAME; + } + + ngOnDestroy(): void {} +} diff --git a/packages/plugins/maintenance-ui/src/lib/maintenance-mode.module.ts b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.module.ts new file mode 100644 index 00000000000..73d8218367b --- /dev/null +++ b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.module.ts @@ -0,0 +1,37 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HttpClient } from '@angular/common/http'; +import { RouterModule, ROUTES } from '@angular/router'; +import { NbLayoutModule } from '@nebular/theme'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { LanguagesEnum } from '@gauzy/contracts'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { HttpLoaderFactory } from '@gauzy/ui-core/i18n'; +import { createMaintenanceRoutes } from './maintenance-mode.routes'; +import { MaintenanceModeComponent } from './maintenance-mode.component'; + +@NgModule({ + imports: [ + CommonModule, + TranslateModule.forRoot({ + defaultLanguage: LanguagesEnum.ENGLISH, + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient] + } + }), + NbLayoutModule + ], + declarations: [MaintenanceModeComponent], + exports: [RouterModule], + providers: [ + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createMaintenanceRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class MaintenanceModeModule {} diff --git a/packages/plugins/maintenance-ui/src/lib/maintenance-mode.routes.ts b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.routes.ts new file mode 100644 index 00000000000..346427331db --- /dev/null +++ b/packages/plugins/maintenance-ui/src/lib/maintenance-mode.routes.ts @@ -0,0 +1,16 @@ +import { Route } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { MaintenanceModeComponent } from './maintenance-mode.component'; + +/** + * Creates the routes for the maintenance mode plugin. + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createMaintenanceRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + component: MaintenanceModeComponent + } +]; diff --git a/packages/plugins/maintenance-ui/src/lib/public-api.ts b/packages/plugins/maintenance-ui/src/lib/public-api.ts new file mode 100644 index 00000000000..f85e9e6bcbe --- /dev/null +++ b/packages/plugins/maintenance-ui/src/lib/public-api.ts @@ -0,0 +1,6 @@ +/** + * Entry point for all public APIs of the @gauzy/plugin-maintenance-ui package. + */ +export * from './maintenance-mode.module'; +export * from './maintenance-mode.routes'; +export * from './maintenance-mode.component'; diff --git a/packages/plugins/maintenance-ui/src/test-setup.ts b/packages/plugins/maintenance-ui/src/test-setup.ts new file mode 100644 index 00000000000..1100b3e8a6e --- /dev/null +++ b/packages/plugins/maintenance-ui/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/packages/plugins/maintenance-ui/tsconfig.json b/packages/plugins/maintenance-ui/tsconfig.json new file mode 100644 index 00000000000..eea653160cb --- /dev/null +++ b/packages/plugins/maintenance-ui/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": false, + "noPropertyAccessFromIndexSignature": false, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + "baseUrl": ".", + "paths": { + "@gauzy/ui-core/*": ["./../../../dist/packages/ui-core/*/index.d.ts"], + "@ngx-translate/*": ["./node_modules/@ngx-translate/*"] + } + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/plugins/maintenance-ui/tsconfig.lib.json b/packages/plugins/maintenance-ui/tsconfig.lib.json new file mode 100644 index 00000000000..5d1d67c0227 --- /dev/null +++ b/packages/plugins/maintenance-ui/tsconfig.lib.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/packages/plugins/maintenance-ui/tsconfig.lib.prod.json b/packages/plugins/maintenance-ui/tsconfig.lib.prod.json new file mode 100644 index 00000000000..7b29b93f6f3 --- /dev/null +++ b/packages/plugins/maintenance-ui/tsconfig.lib.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/packages/plugins/maintenance-ui/tsconfig.spec.json b/packages/plugins/maintenance-ui/tsconfig.spec.json new file mode 100644 index 00000000000..0b8b86994ff --- /dev/null +++ b/packages/plugins/maintenance-ui/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/packages/plugins/onboarding-ui/.dockerignore b/packages/plugins/onboarding-ui/.dockerignore new file mode 100644 index 00000000000..6edd0523636 --- /dev/null +++ b/packages/plugins/onboarding-ui/.dockerignore @@ -0,0 +1,20 @@ +docker +tmp +README.md +.env + +# git + +.git +.gitignore +.gitmodules + +# dependencies + +node_modules + +# misc + +npm-debug.log +dist +build diff --git a/packages/plugins/onboarding-ui/.eslintrc.json b/packages/plugins/onboarding-ui/.eslintrc.json new file mode 100644 index 00000000000..32896661eef --- /dev/null +++ b/packages/plugins/onboarding-ui/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "gauzy", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "gauzy", + "style": "kebab-case" + } + ] + }, + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"] + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/packages/plugins/onboarding-ui/.gitignore b/packages/plugins/onboarding-ui/.gitignore new file mode 100644 index 00000000000..a34877c2c0e --- /dev/null +++ b/packages/plugins/onboarding-ui/.gitignore @@ -0,0 +1,6 @@ +# dependencies +node_modules/ + +# misc +npm-debug.log +dist \ No newline at end of file diff --git a/packages/plugins/onboarding-ui/.npmignore b/packages/plugins/onboarding-ui/.npmignore new file mode 100644 index 00000000000..1eb4beb9572 --- /dev/null +++ b/packages/plugins/onboarding-ui/.npmignore @@ -0,0 +1,4 @@ +# .npmignore + +src/ +node_modules/ diff --git a/packages/plugins/onboarding-ui/README.md b/packages/plugins/onboarding-ui/README.md new file mode 100644 index 00000000000..df38bcea378 --- /dev/null +++ b/packages/plugins/onboarding-ui/README.md @@ -0,0 +1,7 @@ +# @gauzy/plugin-onboarding-ui + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test plugin-onboarding-ui` to execute the unit tests. diff --git a/packages/plugins/onboarding-ui/jest.config.ts b/packages/plugins/onboarding-ui/jest.config.ts new file mode 100644 index 00000000000..0a77ba5bee5 --- /dev/null +++ b/packages/plugins/onboarding-ui/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'plugin-onboarding-ui', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/packages/plugins/onboarding-ui', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$' + } + ] + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment' + ] +}; diff --git a/packages/plugins/onboarding-ui/ng-package.json b/packages/plugins/onboarding-ui/ng-package.json new file mode 100644 index 00000000000..414787372c2 --- /dev/null +++ b/packages/plugins/onboarding-ui/ng-package.json @@ -0,0 +1,10 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../../dist/packages/plugins/onboarding-ui", + "lib": { + "entryFile": "src/index.ts", + "styleIncludePaths": ["../../../dist/packages/ui-core/static/styles"] + }, + "allowedNonPeerDependencies": ["."], + "assets": [] +} diff --git a/packages/plugins/onboarding-ui/package.json b/packages/plugins/onboarding-ui/package.json new file mode 100644 index 00000000000..9d477606d16 --- /dev/null +++ b/packages/plugins/onboarding-ui/package.json @@ -0,0 +1,58 @@ +{ + "name": "@gauzy/plugin-onboarding-ui", + "version": "0.1.0", + "type": "commonjs", + "description": "A plugin for the onboarding UI in the Ever Gauzy platform, providing user-friendly components and modules to facilitate the onboarding process.", + "author": { + "name": "Ever Co. LTD", + "email": "ever@ever.co", + "url": "https://ever.co" + }, + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "https://github.com/ever-co/ever-gauzy" + }, + "bugs": { + "url": "https://github.com/ever-co/ever-gauzy/issues" + }, + "homepage": "https://ever.co", + "keywords": [ + "onboarding", + "plugin", + "angular", + "ui", + "gauzy" + ], + "private": true, + "scripts": { + "lib:build": "ng build plugin-onboarding-ui --configuration=development", + "lib:build:prod": "ng build plugin-onboarding-ui --configuration=production", + "lib:watch": "ng build plugin-onboarding-ui --watch --configuration=development" + }, + "peerDependencies": { + "@angular/common": "^16.2.12", + "@angular/core": "^16.2.12" + }, + "dependencies": { + "@angular/router": "^16.2.12", + "@gauzy/contracts": "^0.1.0", + "@gauzy/ui-core": "^0.1.0", + "@nebular/theme": "^12.0.0", + "@ngneat/until-destroy": "^9.2.0", + "@ngx-translate/core": "^15.0.0", + "ngx-permissions": "^13.0.1", + "rxjs": "^7.4.0", + "tslib": "^2.6.2" + }, + "devDependencies": { + "@types/jest": "^29.4.4", + "@types/node": "^20.14.9", + "jest-preset-angular": "^13.1.4" + }, + "engines": { + "node": ">=20.11.1", + "yarn": ">=1.22.19" + }, + "sideEffects": false +} diff --git a/packages/plugins/onboarding-ui/project.json b/packages/plugins/onboarding-ui/project.json new file mode 100644 index 00000000000..89152a87414 --- /dev/null +++ b/packages/plugins/onboarding-ui/project.json @@ -0,0 +1,50 @@ +{ + "name": "plugin-onboarding-ui", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/plugins/onboarding-ui/src", + "prefix": "gauzy", + "tags": [], + "projectType": "library", + "targets": { + "build": { + "executor": "@nrwl/angular:package", + "outputs": ["{workspaceRoot}/dist/{projectRoot}"], + "options": { + "project": "packages/plugins/onboarding-ui/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/onboarding-ui/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/onboarding-ui/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/plugins/onboarding-ui/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": [ + "packages/plugins/onboarding-ui/**/*.ts", + "packages/plugins/onboarding-ui/**/*.html" + ] + } + } + } +} diff --git a/packages/plugins/onboarding-ui/src/index.ts b/packages/plugins/onboarding-ui/src/index.ts new file mode 100644 index 00000000000..92b2a0b396d --- /dev/null +++ b/packages/plugins/onboarding-ui/src/index.ts @@ -0,0 +1,4 @@ +/** + * Public API Surface of @gauzy/plugin-onboarding-ui + */ +export * from './lib/public-api'; diff --git a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.html b/packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.html similarity index 81% rename from apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.html rename to packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.html index 6e51bed6a1f..4b1cbd93650 100644 --- a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.html +++ b/packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.html @@ -1,10 +1,14 @@ + + + +
diff --git a/apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.scss b/packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.scss similarity index 100% rename from apps/gauzy/src/app/onboarding/onboarding-complete/onboarding-complete.component.scss rename to packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.scss diff --git a/packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.ts b/packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.ts new file mode 100644 index 00000000000..cd3511c8668 --- /dev/null +++ b/packages/plugins/onboarding-ui/src/lib/components/onboarding-complete/onboarding-complete.component.ts @@ -0,0 +1,78 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { Observable } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { NgxPermissionsService } from 'ngx-permissions'; +import { IFeature, IRolePermission } from '@gauzy/contracts'; +import { ErrorHandlingService, FeatureStoreService, PermissionsService, Store } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ga-onboarding-complete', + templateUrl: './onboarding-complete.component.html', + styleUrls: ['./onboarding-complete.component.scss'] +}) +export class OnboardingCompleteComponent extends TranslationBaseComponent implements OnInit { + blocks$: Observable = this._featureStoreService.blocks$; + features$: Observable = this._featureStoreService.features$; + + constructor( + translationService: TranslateService, + private readonly _ngxPermissionsService: NgxPermissionsService, + private readonly _router: Router, + private readonly _store: Store, + private readonly _permissionsService: PermissionsService, + private readonly _featureStoreService: FeatureStoreService, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translationService); + } + + async ngOnInit() { + const id = this._store.userId; + if (!id) return; + + try { + // Get user permissions + const permissions = await this._permissionsService.getPermissions(); + + // Only enabled permissions assign to logged in user + await this.initializeUiPermissions(permissions.items); + } catch (error) { + console.log('Error while initializing UI permissions', error); + this._errorHandlingService.handleError(error); + } finally { + this.getFeatures(); + } + } + + /** + * Initialize UI permissions + */ + private async initializeUiPermissions(userRolePermissions: IRolePermission[]) { + const permissions = userRolePermissions.map(({ permission }) => permission); // Extract permission from role permissions + this._ngxPermissionsService.flushPermissions(); // Flush permissions + this._ngxPermissionsService.loadPermissions(permissions); // Load permissions + } + + /** + * Get Features + */ + getFeatures() { + this._featureStoreService.loadFeatures(['children']).pipe(untilDestroyed(this)).subscribe(); + } + + /** + * Navigate to the specified link + * + * @param link The relative link to navigate to. + */ + navigateTo(link: string): void { + // Normalize the link by removing leading or trailing slashes if any + const normalizedLink = link.replace(/^\/|\/$/g, ''); + // Construct the URL and navigate + this._router.navigate([`pages/${normalizedLink}`]); + } +} diff --git a/apps/gauzy/src/app/onboarding/onboarding.component.ts b/packages/plugins/onboarding-ui/src/lib/components/onboarding.component.ts similarity index 55% rename from apps/gauzy/src/app/onboarding/onboarding.component.ts rename to packages/plugins/onboarding-ui/src/lib/components/onboarding.component.ts index c29134ca02f..58c38f11afe 100644 --- a/apps/gauzy/src/app/onboarding/onboarding.component.ts +++ b/packages/plugins/onboarding-ui/src/lib/components/onboarding.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'ga-onboarding', @@ -11,10 +11,4 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; ` }) -export class OnboardingComponent implements OnInit, OnDestroy { - constructor() {} - - ngOnInit() {} - - ngOnDestroy() {} -} +export class OnboardingComponent {} diff --git a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.html b/packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.html similarity index 100% rename from apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.html rename to packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.html diff --git a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.scss b/packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.scss similarity index 100% rename from apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.scss rename to packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.scss diff --git a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.ts b/packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.ts similarity index 98% rename from apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.ts rename to packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.ts index c005eca4661..433c1049b42 100644 --- a/apps/gauzy/src/app/onboarding/tenant-onboarding/tenant-onboarding.component.ts +++ b/packages/plugins/onboarding-ui/src/lib/components/tenant-onboarding/tenant-onboarding.component.ts @@ -1,17 +1,17 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, Data, Router } from '@angular/router'; -import { IOrganization, IOrganizationCreateInput, IUser } from '@gauzy/contracts'; import { filter, firstValueFrom, tap } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { IOrganization, IOrganizationCreateInput, IUser } from '@gauzy/contracts'; import { AuthService, EmployeesService, ErrorHandlingService, OrganizationsService, + Store, TenantService, UsersService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; @UntilDestroy() @Component({ diff --git a/packages/plugins/onboarding-ui/src/lib/onboarding.module.ts b/packages/plugins/onboarding-ui/src/lib/onboarding.module.ts new file mode 100644 index 00000000000..533db8dfbcd --- /dev/null +++ b/packages/plugins/onboarding-ui/src/lib/onboarding.module.ts @@ -0,0 +1,66 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ROUTES, RouterModule } from '@angular/router'; +import { NbButtonModule, NbCardModule, NbIconModule, NbLayoutModule, NbSpinnerModule } from '@nebular/theme'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { + AuthService, + FeatureStoreService, + PageRouteRegistryService, + RoleGuard, + TenantService +} from '@gauzy/ui-core/core'; +import { OrganizationsStepFormModule } from '@gauzy/ui-core/shared'; +import { ThemeModule, ThemeSelectorModule, ThemeSettingsModule } from '@gauzy/ui-core/theme'; +import { createOnboardingRoutes } from './onboarding.routes'; +import { OnboardingComponent } from './components/onboarding.component'; +import { TenantOnboardingComponent } from './components/tenant-onboarding/tenant-onboarding.component'; +import { OnboardingCompleteComponent } from './components/onboarding-complete/onboarding-complete.component'; +import { LanguagesEnum } from '@gauzy/contracts'; +import { HttpLoaderFactory } from '@gauzy/ui-core/i18n'; +import { HttpClient } from '@angular/common/http'; +import { NgxPermissionsModule } from 'ngx-permissions'; + +// Nebular Modules +const NB_MODULES = [NbButtonModule, NbCardModule, NbIconModule, NbLayoutModule, NbSpinnerModule]; + +// Third Party Modules +const THIRD_PARTY_MODULES = [ + NgxPermissionsModule.forRoot(), + TranslateModule.forRoot({ + defaultLanguage: LanguagesEnum.ENGLISH, + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient] + } + }) +]; + +@NgModule({ + imports: [ + CommonModule, + RouterModule.forChild([]), + ...NB_MODULES, + ...THIRD_PARTY_MODULES, + ThemeModule, + ThemeSelectorModule, + ThemeSettingsModule, + OrganizationsStepFormModule + ], + exports: [RouterModule], + declarations: [OnboardingComponent, TenantOnboardingComponent, OnboardingCompleteComponent], + providers: [ + AuthService, + FeatureStoreService, + TenantService, + RoleGuard, + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createOnboardingRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class OnboardingModule {} diff --git a/packages/plugins/onboarding-ui/src/lib/onboarding.routes.ts b/packages/plugins/onboarding-ui/src/lib/onboarding.routes.ts new file mode 100644 index 00000000000..8559246c5ea --- /dev/null +++ b/packages/plugins/onboarding-ui/src/lib/onboarding.routes.ts @@ -0,0 +1,29 @@ +import { Route } from '@angular/router'; +import { OnboardingResolver, PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { OnboardingComponent } from './components/onboarding.component'; +import { TenantOnboardingComponent } from './components/tenant-onboarding/tenant-onboarding.component'; +import { OnboardingCompleteComponent } from './components/onboarding-complete/onboarding-complete.component'; + +/** + * Creates onboarding routes for the application + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createOnboardingRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + component: OnboardingComponent, + children: [ + { + path: 'tenant', + component: TenantOnboardingComponent, + resolve: { user: OnboardingResolver } + }, + { + path: 'complete', + component: OnboardingCompleteComponent + } + ] + } +]; diff --git a/packages/plugins/onboarding-ui/src/lib/public-api.ts b/packages/plugins/onboarding-ui/src/lib/public-api.ts new file mode 100644 index 00000000000..9e7f848bd69 --- /dev/null +++ b/packages/plugins/onboarding-ui/src/lib/public-api.ts @@ -0,0 +1,8 @@ +/** + * Public API Surface of @gauzy/plugin-onboarding-ui + */ +export * from './onboarding.module'; +export * from './onboarding.routes'; +export * from './components/onboarding.component'; +export * from './components/tenant-onboarding/tenant-onboarding.component'; +export * from './components/onboarding-complete/onboarding-complete.component'; diff --git a/packages/plugins/onboarding-ui/src/test-setup.ts b/packages/plugins/onboarding-ui/src/test-setup.ts new file mode 100644 index 00000000000..1100b3e8a6e --- /dev/null +++ b/packages/plugins/onboarding-ui/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/packages/plugins/onboarding-ui/tsconfig.json b/packages/plugins/onboarding-ui/tsconfig.json new file mode 100644 index 00000000000..8a309f45a75 --- /dev/null +++ b/packages/plugins/onboarding-ui/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": false, + "noPropertyAccessFromIndexSignature": false, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + "baseUrl": ".", + "paths": { + "@gauzy/ui-core/*": ["./../../../dist/packages/ui-core/*/index.d.ts"], + "@ngx-translate/*": ["./node_modules/@ngx-translate/*"], + "ngx-permissions": ["./node_modules/ngx-permissions"] + } + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/plugins/onboarding-ui/tsconfig.lib.json b/packages/plugins/onboarding-ui/tsconfig.lib.json new file mode 100644 index 00000000000..5d1d67c0227 --- /dev/null +++ b/packages/plugins/onboarding-ui/tsconfig.lib.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/packages/plugins/onboarding-ui/tsconfig.lib.prod.json b/packages/plugins/onboarding-ui/tsconfig.lib.prod.json new file mode 100644 index 00000000000..7b29b93f6f3 --- /dev/null +++ b/packages/plugins/onboarding-ui/tsconfig.lib.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/packages/plugins/onboarding-ui/tsconfig.spec.json b/packages/plugins/onboarding-ui/tsconfig.spec.json new file mode 100644 index 00000000000..0b8b86994ff --- /dev/null +++ b/packages/plugins/onboarding-ui/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/packages/plugins/public-layout-ui/.dockerignore b/packages/plugins/public-layout-ui/.dockerignore new file mode 100644 index 00000000000..6edd0523636 --- /dev/null +++ b/packages/plugins/public-layout-ui/.dockerignore @@ -0,0 +1,20 @@ +docker +tmp +README.md +.env + +# git + +.git +.gitignore +.gitmodules + +# dependencies + +node_modules + +# misc + +npm-debug.log +dist +build diff --git a/packages/plugins/public-layout-ui/.eslintrc.json b/packages/plugins/public-layout-ui/.eslintrc.json new file mode 100644 index 00000000000..32896661eef --- /dev/null +++ b/packages/plugins/public-layout-ui/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "gauzy", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "gauzy", + "style": "kebab-case" + } + ] + }, + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"] + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/packages/plugins/public-layout-ui/.gitignore b/packages/plugins/public-layout-ui/.gitignore new file mode 100644 index 00000000000..a34877c2c0e --- /dev/null +++ b/packages/plugins/public-layout-ui/.gitignore @@ -0,0 +1,6 @@ +# dependencies +node_modules/ + +# misc +npm-debug.log +dist \ No newline at end of file diff --git a/packages/plugins/public-layout-ui/.npmignore b/packages/plugins/public-layout-ui/.npmignore new file mode 100644 index 00000000000..1eb4beb9572 --- /dev/null +++ b/packages/plugins/public-layout-ui/.npmignore @@ -0,0 +1,4 @@ +# .npmignore + +src/ +node_modules/ diff --git a/packages/plugins/public-layout-ui/README.md b/packages/plugins/public-layout-ui/README.md new file mode 100644 index 00000000000..71c3178fd19 --- /dev/null +++ b/packages/plugins/public-layout-ui/README.md @@ -0,0 +1,7 @@ +# @gauzy/plugin-public-layout-ui + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test plugin-public-layout-ui` to execute the unit tests. diff --git a/packages/plugins/public-layout-ui/jest.config.ts b/packages/plugins/public-layout-ui/jest.config.ts new file mode 100644 index 00000000000..52470a93e82 --- /dev/null +++ b/packages/plugins/public-layout-ui/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'plugin-public-layout-ui', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/packages/plugins/public-layout-ui', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$' + } + ] + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment' + ] +}; diff --git a/packages/plugins/public-layout-ui/ng-package.json b/packages/plugins/public-layout-ui/ng-package.json new file mode 100644 index 00000000000..997d702d9c4 --- /dev/null +++ b/packages/plugins/public-layout-ui/ng-package.json @@ -0,0 +1,10 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../../dist/packages/plugins/public-layout-ui", + "lib": { + "entryFile": "src/index.ts", + "styleIncludePaths": ["../../../dist/packages/ui-core/static/styles"] + }, + "allowedNonPeerDependencies": ["."], + "assets": [] +} diff --git a/packages/plugins/public-layout-ui/package.json b/packages/plugins/public-layout-ui/package.json new file mode 100644 index 00000000000..557dfab7f00 --- /dev/null +++ b/packages/plugins/public-layout-ui/package.json @@ -0,0 +1,58 @@ +{ + "name": "@gauzy/plugin-public-layout-ui", + "version": "0.1.0", + "type": "commonjs", + "description": "", + "author": { + "name": "Ever Co. LTD", + "email": "ever@ever.co", + "url": "https://ever.co" + }, + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "https://github.com/ever-co/ever-gauzy" + }, + "bugs": { + "url": "https://github.com/ever-co/ever-gauzy/issues" + }, + "homepage": "https://ever.co", + "keywords": [], + "private": true, + "scripts": { + "lib:build": "ng build plugin-public-layout-ui --configuration=development", + "lib:build:prod": "ng build plugin-public-layout-ui --configuration=production", + "lib:watch": "ng build plugin-public-layout-ui --watch --configuration=development" + }, + "peerDependencies": { + "@angular/common": "^16.2.12", + "@angular/core": "^16.2.12" + }, + "dependencies": { + "@angular/forms": "^16.2.12", + "@angular/router": "^16.2.12", + "@fullcalendar/angular": "~6.1.10", + "@gauzy/contracts": "^0.1.0", + "@gauzy/ui-core": "^0.1.0", + "@nebular/theme": "^12.0.0", + "@ng-select/ng-select": "^11.2.0", + "@ngneat/until-destroy": "^9.2.0", + "@ngx-translate/core": "^15.0.0", + "ckeditor4-angular": "4.0.1", + "moment": "^2.30.1", + "ng2-file-upload": "^5.0.0", + "ngx-permissions": "^13.0.1", + "rxjs": "^7.4.0", + "tslib": "^2.6.2" + }, + "devDependencies": { + "@types/jest": "^29.4.4", + "@types/node": "^20.14.9", + "jest-preset-angular": "^13.1.4" + }, + "engines": { + "node": ">=20.11.1", + "yarn": ">=1.22.19" + }, + "sideEffects": false +} diff --git a/packages/plugins/public-layout-ui/project.json b/packages/plugins/public-layout-ui/project.json new file mode 100644 index 00000000000..12330a0ef63 --- /dev/null +++ b/packages/plugins/public-layout-ui/project.json @@ -0,0 +1,50 @@ +{ + "name": "plugin-public-layout-ui", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/plugins/public-layout/src", + "prefix": "gauzy", + "tags": [], + "projectType": "library", + "targets": { + "build": { + "executor": "@nrwl/angular:package", + "outputs": ["{workspaceRoot}/dist/{projectRoot}"], + "options": { + "project": "packages/plugins/public-layout/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "packages/plugins/public-layout/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/plugins/public-layout/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/plugins/public-layout/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": [ + "packages/plugins/public-layout/**/*.ts", + "packages/plugins/public-layout/**/*.html" + ] + } + } + } +} diff --git a/packages/plugins/public-layout-ui/src/index.ts b/packages/plugins/public-layout-ui/src/index.ts new file mode 100644 index 00000000000..8ae7d585762 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/index.ts @@ -0,0 +1,4 @@ +/** + * Public API Surface of @gauzy/plugin-public-layout-ui + */ +export * from './lib/public-api'; diff --git a/packages/plugins/public-layout-ui/src/lib/components/appointment-form/appointment-form.component.html b/packages/plugins/public-layout-ui/src/lib/components/appointment-form/appointment-form.component.html new file mode 100644 index 00000000000..69a3b3b9536 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/appointment-form/appointment-form.component.html @@ -0,0 +1,12 @@ + + + + + + diff --git a/packages/plugins/public-layout-ui/src/lib/components/appointment-form/appointment-form.component.ts b/packages/plugins/public-layout-ui/src/lib/components/appointment-form/appointment-form.component.ts new file mode 100644 index 00000000000..b2d2193376b --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/appointment-form/appointment-form.component.ts @@ -0,0 +1,80 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { firstValueFrom, switchMap } from 'rxjs'; +import { Router, ActivatedRoute } from '@angular/router'; +import { TranslateService } from '@ngx-translate/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { IEventType, IEmployee } from '@gauzy/contracts'; +import { EmployeesService } from '@gauzy/ui-core/core'; + +@UntilDestroy() +@Component({ + templateUrl: './appointment-form.component.html' +}) +export class AppointmentFormComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public loading: boolean = true; + public selectedRange: { start: Date; end: Date }; + public selectedEventType: IEventType; + public allowedDuration: number; + public employee: IEmployee; + + constructor( + readonly translateService: TranslateService, + private readonly route: ActivatedRoute, + private readonly router: Router, + private readonly employeeService: EmployeesService + ) { + super(translateService); + } + + ngOnInit(): void { + this.selectedRange = { + start: history.state.dateStart, + end: history.state.dateEnd + }; + + this.route.params + .pipe( + switchMap(async (params) => { + if (!params.id) return; + + try { + // Get employee by ID + this.employee = await firstValueFrom(this.employeeService.getEmployeeById(params.id, ['user'])); + + this.selectedEventType = history.state.selectedEventType; + if (this.selectedEventType) { + this.allowedDuration = this.calculateAllowedDuration(this.selectedEventType); + this.loading = false; + } else { + history.go(-1); + } + } catch (error) { + console.log('Error while loading employee', error); + await this.router.navigate(['/share/404']); + } + }), + untilDestroyed(this) + ) + .subscribe(); + } + + /** + * Calculate allowed duration in minutes + * + * @param eventType + * @returns + */ + private calculateAllowedDuration(eventType: any): number { + switch (eventType.durationUnit) { + case 'Day(s)': + return eventType.duration * 24 * 60; + case 'Hour(s)': + return eventType.duration * 60; + default: + return eventType.duration * 1; + } + } + + ngOnDestroy() {} +} diff --git a/packages/plugins/public-layout-ui/src/lib/components/confirm-appointment/confirm-appointment.component.html b/packages/plugins/public-layout-ui/src/lib/components/confirm-appointment/confirm-appointment.component.html new file mode 100644 index 00000000000..2cef460aaf9 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/confirm-appointment/confirm-appointment.component.html @@ -0,0 +1,72 @@ + + + +
+

+ {{ + (appointment.status + ? 'PUBLIC_APPOINTMENTS.APPOINTMENT_INFO' + : 'PUBLIC_APPOINTMENTS.CONFIRM_APPOINTMENT' + ) | translate + }} + +

+
+
+ + +
+ {{ 'PUBLIC_APPOINTMENTS.DETAILS' | translate }} + +
+
+ {{ 'PUBLIC_APPOINTMENTS.HOST' | translate }}: {{ appointment?.employee?.user?.name }} ({{ appointment?.employee?.user?.email }}) +
+
+ {{ 'FORM.LABELS.MEETING_AGENDA' | translate }}: {{ appointment.agenda }} +
+
+ {{ 'FORM.LABELS.MEETING_DESCRIPTION' | translate }}: + {{ appointment.description }} +
+
+ {{ 'PUBLIC_APPOINTMENTS.PARTICIPANTS' | translate }}: + {{ appointment.emails }} +
+
+ {{ 'FORM.LABELS.MEETING_LOCATION' | translate }}: + {{ appointment.location || 'N/A' }} +
+
+ {{ 'FORM.LABELS.DURATION' | translate }}: + {{ formatDuration(appointment?.startDateTime, appointment?.endDateTime) }} +
+
+ +
+ {{ 'PUBLIC_APPOINTMENTS.EMAIL_SENT' | translate }} +
+
+ +
+ {{ 'PUBLIC_APPOINTMENTS.RESCHEDULE' | translate }}: + + {{ 'PUBLIC_APPOINTMENTS.CLICK_HERE' | translate }} + +
+
+ +
+ {{ 'PUBLIC_APPOINTMENTS.EXPIRED_OR_CANCELLED' | translate }} +
+
+
+ +
+
+
+
diff --git a/packages/plugins/public-layout-ui/src/lib/components/confirm-appointment/confirm-appointment.component.ts b/packages/plugins/public-layout-ui/src/lib/components/confirm-appointment/confirm-appointment.component.ts new file mode 100644 index 00000000000..72b83807088 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/confirm-appointment/confirm-appointment.component.ts @@ -0,0 +1,147 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Location } from '@angular/common'; +import { Router, ActivatedRoute, Params, UrlSerializer } from '@angular/router'; +import { EMPTY, Observable, catchError, filter, firstValueFrom, of, switchMap } from 'rxjs'; +import { tap } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; +import { NbDialogService } from '@nebular/theme'; +import * as moment from 'moment'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { EmployeeAppointmentStatus, ID, IEmployee, IEmployeeAppointment } from '@gauzy/contracts'; +import { EmployeeAppointmentService, EmployeesService, ErrorHandlingService } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { AlertModalComponent } from '@gauzy/ui-core/shared'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ga-confirm-appointment', + templateUrl: './confirm-appointment.component.html', + providers: [EmployeeAppointmentService] +}) +export class ConfirmAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public loading: boolean = false; + public employee: IEmployee; + public employee$: Observable; + public appointment: IEmployeeAppointment; + public appointment$: Observable; + public participants: string; + public duration: string; + public rescheduleLink: string; + + constructor( + readonly translateService: TranslateService, + private readonly _route: ActivatedRoute, + private readonly _location: Location, + private readonly _urlSerializer: UrlSerializer, + private readonly _router: Router, + private readonly _dialogService: NbDialogService, + private readonly _employeeService: EmployeesService, + private readonly _employeeAppointmentService: EmployeeAppointmentService, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit(): void { + // Create an observable for the employee based on route parameters + this.appointment$ = this._route.params.pipe( + // Ensure the route parameters are valid + filter((params: Params) => !!params.appointmentId), + // Fetch appointment from the employee appointment service + switchMap((params: Params) => { + // Get the appointment ID from the route parameters + const appointmentId = params.appointmentId; + // Fetch the employee appointment from the service + return this._employeeAppointmentService.getById(appointmentId, ['employee', 'employee.user']); + }), + tap(async (appointment) => await this.getRescheduleLink(appointment)), + // Handle errors + catchError((error: any) => { + // Handle and log errors + this._errorHandlingService.handleError(error); + // Redirect to 404 page + this._router.navigate(['/share/404']); + // Return an empty observable + return EMPTY; + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + } + + /** + * Get the reschedule link for the appointment. + * + * @param appointment The appointment to get the reschedule link for. + */ + async getRescheduleLink(appointment: IEmployeeAppointment): Promise { + // Get the appointment ID from the route parameters + const appointmentId = appointment.id; + // Get the start and end date time of the appointment + const token = await this._employeeAppointmentService.signAppointmentId(appointmentId); + // Get the URL to edit the appointment + const urlTree = this._router.createUrlTree(['/share/employee/edit-appointment'], { queryParams: { token } }); + // As far as I can tell you don't really need the UrlSerializer. + this.rescheduleLink = this._location.prepareExternalUrl(this._urlSerializer.serialize(urlTree)); + } + + /** + * Format the appointment duration. + * + * @param startDateTime The start time of the appointment. + * @param endDateTime The end time of the appointment. + * @returns A formatted string representing the duration. + */ + public formatDuration(startDateTime: Date, endDateTime: Date): string { + const startFormatted = moment(startDateTime).format('llll'); + const endFormatted = moment(endDateTime).format('llll'); + return `${startFormatted} - ${endFormatted}`; + } + + /** + * Cancel the appointment with a confirmation dialog. + * + * @param appointmentId The ID of the appointment to cancel. + */ + async cancelAppointment(appointmentId: ID) { + const confirmed = await this.confirmCancellation(); + if (!confirmed) return; + + // Update the appointment status to 'Cancelled' + await this._employeeAppointmentService.update(appointmentId, { + status: EmployeeAppointmentStatus.CANCELLED + }); + + // Create an observable for the appointment + const appointment = await firstValueFrom( + this._employeeAppointmentService.getById(appointmentId, ['employee', 'employee.user']) + ); + this.appointment$ = of(appointment); + } + + /** + * Opens a confirmation dialog for cancelling an appointment. + * + * @returns A promise that resolves to true if the user confirms, otherwise false. + */ + private async confirmCancellation(): Promise { + // Open a confirmation dialog + const dialog = this._dialogService.open(AlertModalComponent, { + context: { + data: { + title: this.getTranslation('APPOINTMENTS_PAGE.CANCEL_APPOINTMENT'), + message: this.getTranslation('APPOINTMENTS_PAGE.ARE_YOU_SURE'), + status: 'danger' + } + } + }); + + // Wait for the user to confirm cancellation + const response = await firstValueFrom(dialog.onClose); + + // Return true if the user confirmed cancellation, false otherwise + return response === 'yes'; + } + + ngOnDestroy() {} +} diff --git a/packages/plugins/public-layout-ui/src/lib/components/create-appointment/create-appointment.component.html b/packages/plugins/public-layout-ui/src/lib/components/create-appointment/create-appointment.component.html new file mode 100644 index 00000000000..b2661069c9e --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/create-appointment/create-appointment.component.html @@ -0,0 +1,52 @@ + + +
+

{{ 'PUBLIC_APPOINTMENTS.PICK_DATETIME' | translate }}

+
+
+ + + +
+
+ Employee Avatar +
+ + {{ employee.fullName }} + +
+ {{ employee.organizationPosition?.name }} +
+
+ {{ employee.user?.email }} +
+
+
+
+
+
+ {{ 'PUBLIC_APPOINTMENTS.EVENT_TYPE' | translate }} + {{ eventType.title }} +
+
+
+ {{ 'PUBLIC_APPOINTMENTS.DURATION' | translate }} + {{ eventType.duration }} {{ eventType.durationUnit }} +
+
+ {{ eventType.description }} +
+
+
+
+ +
+
+
+
+
diff --git a/packages/plugins/public-layout-ui/src/lib/components/create-appointment/create-appointment.component.ts b/packages/plugins/public-layout-ui/src/lib/components/create-appointment/create-appointment.component.ts new file mode 100644 index 00000000000..cb8b15e68f7 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/create-appointment/create-appointment.component.ts @@ -0,0 +1,83 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Router, ActivatedRoute, Params } from '@angular/router'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { Observable, catchError, filter, of, switchMap, tap } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { IEmployee, IEventType } from '@gauzy/contracts'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { EmployeesService, ErrorHandlingService, EventTypeService } from '@gauzy/ui-core/core'; + +@UntilDestroy() +@Component({ + templateUrl: './create-appointment.component.html', + styleUrls: ['../public-appointment/public-appointment.component.scss'], + providers: [EventTypeService] +}) +export class CreateAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public employee$: Observable; + public employee: IEmployee; + public eventType: IEventType; + public eventType$: Observable; + public loading: boolean = true; + public appointmentFormURL: string; + + constructor( + readonly translateService: TranslateService, + private readonly _route: ActivatedRoute, + private readonly _router: Router, + private readonly _employeeService: EmployeesService, + private readonly _eventTypeService: EventTypeService, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit(): void { + this.employee$ = this._route.params.pipe( + // Ensure the route parameters are valid + filter((params: Params) => !!params.id), + // Fetch the employee from the employee service + switchMap((params: Params) => this._employeeService.getEmployeeById(params.id, ['user'])), + // Store the employee in the 'employee' property + tap((employee: IEmployee) => (this.employee = employee)), + // Handle errors + catchError((error: any) => { + // Handle and log errors + this._errorHandlingService.handleError(error); + // Navigate to the 404 page + this._router.navigate(['/share/404']); + // Return null to avoid breaking the observable chain + return of(null); + }), + tap((employee: IEmployee) => { + if (employee) { + this.loading = false; + this.appointmentFormURL = `/share/employee/${employee.id}/create-appointment`; + } + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + this.eventType$ = this._route.params.pipe( + // Ensure the route parameters are valid + filter((params: Params) => !!params.eventId), + // Fetch the event type from the event type service + switchMap((params: Params) => this._eventTypeService.getEventTypeById(params.eventId)), + // Store the event type in the 'eventType' property + tap((eventType: IEventType) => (this.eventType = eventType)), + // Handle errors + catchError((error: any) => { + // Handle and log errors + this._errorHandlingService.handleError(error); + // Navigate to the 404 page + this._router.navigate(['/share/404']); + // Return null to avoid breaking the observable chain + return of(null); + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + } + + ngOnDestroy() {} +} diff --git a/packages/plugins/public-layout-ui/src/lib/components/edit-appointment/edit-appointment.component.html b/packages/plugins/public-layout-ui/src/lib/components/edit-appointment/edit-appointment.component.html new file mode 100644 index 00000000000..930c1e918a9 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/edit-appointment/edit-appointment.component.html @@ -0,0 +1,7 @@ + + + diff --git a/packages/plugins/public-layout-ui/src/lib/components/edit-appointment/edit-appointment.component.ts b/packages/plugins/public-layout-ui/src/lib/components/edit-appointment/edit-appointment.component.ts new file mode 100644 index 00000000000..39472079e8a --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/edit-appointment/edit-appointment.component.ts @@ -0,0 +1,55 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { EMPTY, Observable, from } from 'rxjs'; +import { catchError, switchMap } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { ID } from '@gauzy/contracts'; +import { EmployeeAppointmentService, ErrorHandlingService } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; + +@UntilDestroy() +@Component({ + selector: 'ga-edit-appointment', + templateUrl: './edit-appointment.component.html' +}) +export class EditAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public loading: boolean; + public appointmentId$: Observable; + + constructor( + readonly translateService: TranslateService, + private readonly _route: ActivatedRoute, + private readonly _router: Router, + private readonly _employeeAppointmentService: EmployeeAppointmentService, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit(): void { + // Create an observable for the appointment based on route parameters + this.appointmentId$ = this._route.queryParams.pipe( + // Ensure the route parameters are valid + switchMap(({ token }) => { + if (!token) { + throw new Error('token missing'); + } + return from(this._employeeAppointmentService.decodeToken(token)); + }), + // Handle errors and redirect to 404 page + catchError((error: any) => { + // Handle and log errors + this._errorHandlingService.handleError(error); + // Redirect to 404 page + this._router.navigate(['/share/404']); + // Return an empty observable to maintain type consistency + return EMPTY; // Return an empty observable to maintain type consistency + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + } + + ngOnDestroy() {} +} diff --git a/apps/gauzy/src/app/share/employee/employee.component.html b/packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.html similarity index 100% rename from apps/gauzy/src/app/share/employee/employee.component.html rename to packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.html diff --git a/apps/gauzy/src/app/share/employee/employee.component.scss b/packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.scss similarity index 100% rename from apps/gauzy/src/app/share/employee/employee.component.scss rename to packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.scss diff --git a/packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.ts b/packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.ts new file mode 100644 index 00000000000..37e1441c457 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/employee/employee.component.ts @@ -0,0 +1,196 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute, Data } from '@angular/router'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable, of } from 'rxjs'; +import { map, tap } from 'rxjs/operators'; +import { NbDialogService } from '@nebular/theme'; +import { PermissionsEnum, IEmployee, IEmployeeAward, IOrganization, IUser, IImageAsset } from '@gauzy/contracts'; +import * as moment from 'moment'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { EmployeesService, ErrorHandlingService, Store, ToastrService, UsersService } from '@gauzy/ui-core/core'; +import { PublicPageEmployeeMutationComponent } from '../mutation/public-page-employee-mutation/public-page-employee-mutation.component'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ngx-employee-share', + templateUrl: './employee.component.html', + styleUrls: ['./employee.component.scss'] +}) +export class EmployeeComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public hasEditPermission$: Observable; + public imageUrl: string; + public imageUpdateButton: boolean; + public organization$: Observable; + public organization: IOrganization; + public employee$: Observable; + public hoverState: boolean; + public employeeAwards: IEmployeeAward[] = []; + + constructor( + readonly translateService: TranslateService, + private readonly _employeeService: EmployeesService, + private readonly _userService: UsersService, + private readonly _route: ActivatedRoute, + private readonly _dialogService: NbDialogService, + private readonly _toastrService: ToastrService, + private readonly _store: Store, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit(): void { + this.organization$ = this._route.data.pipe( + map(({ organization }: Data) => organization), + tap((organization: IOrganization) => (this.organization = organization)) + ); + this.employee$ = this._route.data.pipe( + map(({ employee }: Data) => ({ + ...employee, + startedWorkOn: employee.startedWorkOn ? new Date(employee.startedWorkOn) : null + })), + tap((employee: IEmployee) => (this.imageUrl = employee.user.imageUrl)), + tap((employee: IEmployee) => (this.employeeAwards = employee.awards)) + ); + this.hasEditPermission$ = this._store.userRolePermissions$.pipe( + map(() => this._store.hasPermission(PermissionsEnum.PUBLIC_PAGE_EDIT)) + ); + } + + /** + * Upload organization image/avatar + * + * @param image + */ + updateImageAsset(image: IImageAsset) { + try { + console.log('updated image', image); + } catch (error) { + console.log('Error while updating organization avatars'); + } + } + + /** + * Updates the image url of an employee. + * + * @param url - The image url to be updated. + */ + updateImageUrl(url: string) { + this.imageUrl = url; + this.imageUpdateButton = true; + } + + /** + * Saves the image of an employee. + * + * @param param0 - The user id and image url to be saved. + */ + async saveImage({ userId, imageUrl }): Promise { + try { + await this._userService.update(userId, { imageUrl }); + this._toastrService.success('PUBLIC_PAGE.IMAGE_UPDATED'); + } catch (error) { + this._errorHandlingService.handleError(error); + } + + this.imageUpdateButton = false; + } + + /** + * Opens a dialog to edit an employee. + * + * @param {IEmployee} employee - The employee to be edited. + * @return {void} This function does not return a value. + */ + openEditEmployeeDialog(employee: IEmployee): void { + if (!this._store.hasPermission(PermissionsEnum.PUBLIC_PAGE_EDIT)) { + return; + } + + // Open the dialog. + const dialog$ = this._dialogService.open(PublicPageEmployeeMutationComponent, { + context: { + employee, + employeeAwards: this.employeeAwards + } + }); + + dialog$.onClose + .pipe( + tap(async (formValue) => { + if (formValue) { + await this.handleEmployeeUpdate(employee, formValue); + } + }), + untilDestroyed(this) + ) + .subscribe(); + } + + /** + * Handles the update of an employee. + * + * @param employee + * @param formValue + * @returns + */ + async handleEmployeeUpdate(employee: IEmployee, formValue: any) { + try { + if (!this.organization) return; + + const { id: organizationId, tenantId } = this.organization; + const { username, email, firstName, lastName, preferredLanguage, ...employeeFormValue } = formValue; + + // Update the user. + const updatedUser: IUser = await this._userService.update(employee.user.id, { + username, + email, + firstName, + lastName, + preferredLanguage + }); + + // Update the employee. + const updatedEmployee: IEmployee = await this._employeeService.update(employee.id, { + organizationId, + tenantId, + ...employeeFormValue + }); + + // Update the employee$ observable. + this.employee$ = of({ + ...employee, + ...updatedEmployee, + isActive: employee.isActive, + billRateCurrency: employee.billRateCurrency, + user: { + ...employee.user, + ...updatedUser, + imageUrl: updatedUser.imageUrl ? updatedUser.imageUrl : employee.user.imageUrl + }, + startedWorkOn: updatedEmployee.startedWorkOn + ? moment(updatedEmployee.startedWorkOn).toDate() + : employee.startedWorkOn + }); + + // Display a success toastr. + this._toastrService.success('PUBLIC_PAGE.EMPLOYEE_UPDATED'); + } catch (error) { + console.log('Error while updating employee', error); + this._errorHandlingService.handleError(error); + } + } + + /** + * + * @param error - The error to be handled. + * @return {void} This function does not return a value. + */ + handleImageUploadError(error: any): void { + console.log('Error while uploading image', error); + this._errorHandlingService.handleError(error); + } + + ngOnDestroy(): void {} +} diff --git a/packages/plugins/public-layout-ui/src/lib/components/index.ts b/packages/plugins/public-layout-ui/src/lib/components/index.ts new file mode 100644 index 00000000000..35731023ba5 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/index.ts @@ -0,0 +1,40 @@ +import { AppointmentFormComponent } from './appointment-form/appointment-form.component'; +import { ConfirmAppointmentComponent } from './confirm-appointment/confirm-appointment.component'; +import { CreateAppointmentComponent } from './create-appointment/create-appointment.component'; +import { EditAppointmentComponent } from './edit-appointment/edit-appointment.component'; +import { EmployeeComponent } from './employee/employee.component'; +import { InvoiceEstimateViewComponent } from './invoice-estimate/invoice-estimate-view.component'; +import { OrganizationComponent } from './organization/organization.component'; +import { PickEmployeeComponent } from './pick-employee/pick-employee.component'; +import { PublicAppointmentComponent } from './public-appointment/public-appointment.component'; +import { PublicLayoutComponent } from './public-layout.component'; +import { PublicPageEmployeeMutationComponent } from './mutation/public-page-employee-mutation/public-page-employee-mutation.component'; +import { PublicPageOrganizationMutationComponent } from './mutation/public-page-organization-mutation/public-page-organization-mutation.component'; + +export * from './appointment-form/appointment-form.component'; +export * from './confirm-appointment/confirm-appointment.component'; +export * from './create-appointment/create-appointment.component'; +export * from './edit-appointment/edit-appointment.component'; +export * from './employee/employee.component'; +export * from './invoice-estimate/invoice-estimate-view.component'; +export * from './organization/organization.component'; +export * from './pick-employee/pick-employee.component'; +export * from './public-appointment/public-appointment.component'; +export * from './public-layout.component'; +export * from './mutation/public-page-employee-mutation/public-page-employee-mutation.component'; +export * from './mutation/public-page-organization-mutation/public-page-organization-mutation.component'; + +export const COMPONENTS = [ + AppointmentFormComponent, + ConfirmAppointmentComponent, + CreateAppointmentComponent, + EditAppointmentComponent, + EmployeeComponent, + InvoiceEstimateViewComponent, + OrganizationComponent, + PickEmployeeComponent, + PublicAppointmentComponent, + PublicLayoutComponent, + PublicPageEmployeeMutationComponent, + PublicPageOrganizationMutationComponent +]; diff --git a/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.html b/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.html new file mode 100644 index 00000000000..69c96055d8a --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.html @@ -0,0 +1,10 @@ + + +

+ {{ (invoice.isEstimate ? 'INVOICES_PAGE.VIEW_ESTIMATE' : 'INVOICES_PAGE.VIEW_INVOICE') | translate }} +

+
+ + + +
diff --git a/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.scss b/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.ts b/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.ts new file mode 100644 index 00000000000..4414db88a08 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/invoice-estimate/invoice-estimate-view.component.ts @@ -0,0 +1,58 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Observable, of } from 'rxjs'; +import { catchError, filter, switchMap } from 'rxjs/operators'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { TranslateService } from '@ngx-translate/core'; +import { IInvoice } from '@gauzy/contracts'; +import { ErrorHandlingService, InvoicesService } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'gz-public-invoice-estimate-view', + templateUrl: './invoice-estimate-view.component.html', + styleUrls: ['./invoice-estimate-view.component.scss'] +}) +export class InvoiceEstimateViewComponent extends TranslationBaseComponent implements OnInit { + public invoice$: Observable; + + constructor( + readonly translateService: TranslateService, + private readonly _activatedRoute: ActivatedRoute, + private readonly _invoicesService: InvoicesService, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit() { + // Define relations to fetch + const relations = [ + 'invoiceItems', + 'invoiceItems.employee', + 'invoiceItems.employee.user', + 'invoiceItems.project', + 'invoiceItems.product', + 'invoiceItems.expense', + 'invoiceItems.task', + 'fromOrganization', + 'toContact' + ]; + + this.invoice$ = this._activatedRoute.params.pipe( + // Ensure that id and token are present in route params + filter(({ id, token }) => Boolean(id && token)), + // Fetch the invoice data based on route params + switchMap(({ id, token }) => this._invoicesService.getPublicInvoice(id, token, relations)), + // Handle errors gracefully + catchError((error) => { + console.error('Error while fetching public invoice', error); + this._errorHandlingService.handleError(error); + return of(null); // Return null to ensure observable continues + }), + // Automatically unsubscribe to prevent memory leaks + untilDestroyed(this) + ); + } +} diff --git a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.html b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.html similarity index 56% rename from packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.html rename to packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.html index 261ebf46d18..172b0b8cb30 100644 --- a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.html +++ b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.html @@ -11,35 +11,31 @@
- +
- +
- +
- +
@@ -93,14 +83,11 @@
- + @@ -128,10 +113,7 @@
[nbDatepicker]="datepicker" nbInput fullWidth - placeholder="{{ - 'FORM.PLACEHOLDERS.START_DATE' - | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.START_DATE' | translate }}" formControlName="startedWorkOn" /> @@ -141,19 +123,16 @@
- +
@@ -177,21 +156,17 @@
- + @@ -200,18 +175,11 @@
- - {{ empL.level }} + + + {{ empL.level }}
@@ -222,12 +190,9 @@
- + >
@@ -235,19 +200,14 @@
- @@ -259,44 +219,25 @@
- + - - {{ - payPeriod - | replace: '_':' ' - | titlecase - }} + + {{ payPeriod | replace : '_' : ' ' | titlecase }}
- + step="0.1" nbInput formControlName="billRateValue" - placeholder="{{ - 'FORM.PLACEHOLDERS.BILL_RATE' - | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.BILL_RATE' | translate }}" />
-
- +
+
@@ -329,14 +263,9 @@
- + step="0.1" max="5" formControlName="reWeeklyLimit" - placeholder="{{ - 'FORM.PLACEHOLDERS.RECURRING_WEEKLY_LIMIT' - | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.RECURRING_WEEKLY_LIMIT' | translate }}" />
@@ -358,11 +284,7 @@
- +
@@ -371,82 +293,46 @@
-
- - {{ - 'POP_UPS.AWARDS' | translate - }} + {{ 'POP_UPS.AWARDS' | translate }}
-
-
- +
+
+
-
- +
+
- +
-
+
- - + +
@@ -494,10 +369,7 @@
- {{ - 'POP_UPS.DISPLAY_BONUS_ANONYMOUSLY' - | translate - }} + {{ 'POP_UPS.DISPLAY_BONUS_ANONYMOUSLY' | translate }}
@@ -507,12 +379,7 @@
- diff --git a/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.scss b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.scss new file mode 100644 index 00000000000..52b5f5bbbc0 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.scss @@ -0,0 +1 @@ +@import '../public-page-organization-mutation/public-page-organization-mutation.component.scss'; diff --git a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.ts b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.ts similarity index 98% rename from packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.ts rename to packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.ts index 3b4b8ea38bf..703c6623a83 100644 --- a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.ts +++ b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-employee-mutation/public-page-employee-mutation.component.ts @@ -1,7 +1,11 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { UntypedFormBuilder, Validators, UntypedFormGroup } from '@angular/forms'; +import { Observable, EMPTY } from 'rxjs'; +import { switchMap, map, tap, filter, catchError } from 'rxjs/operators'; import { NbDialogRef } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { CKEditor4 } from 'ckeditor4-angular/ckeditor'; import { IEmployee, ISkill, @@ -13,20 +17,16 @@ import { IEmployeeLevel, IOrganization } from '@gauzy/contracts'; -import { switchMap, map, tap, filter, catchError } from 'rxjs/operators'; -import { Observable, EMPTY } from 'rxjs'; -import { CKEditor4 } from 'ckeditor4-angular/ckeditor'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { EmployeeAwardService, EmployeeLevelService, ErrorHandlingService, OrganizationEmploymentTypesService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; -import { ckEditorConfig } from '../../ckeditor.config'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { ckEditorConfig } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.html b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.html similarity index 100% rename from packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.html rename to packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.html diff --git a/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.scss b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.scss similarity index 100% rename from packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.scss rename to packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.scss diff --git a/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.ts b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.ts similarity index 92% rename from packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.ts rename to packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.ts index b99769259c3..f575971d4c7 100644 --- a/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.component.ts +++ b/packages/plugins/public-layout-ui/src/lib/components/mutation/public-page-organization-mutation/public-page-organization-mutation.component.ts @@ -14,19 +14,17 @@ import { ClientFocusEnum, MinimumProjectSizeEnum } from '@gauzy/contracts'; +import { OrganizationAwardsService, OrganizationLanguagesService, Store, ToastrService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; -import { OrganizationAwardsService, OrganizationLanguagesService } from '@gauzy/ui-core/core'; -import { ckEditorConfig } from '../../ckeditor.config'; +import { ckEditorConfig } from '@gauzy/ui-core/shared'; @Component({ - selector: 'ngx-public-page-mutation', - templateUrl: './public-page-mutation.component.html', - styleUrls: ['./public-page-mutation.component.scss'] + selector: 'ngx-public-page-organization-mutation', + templateUrl: './public-page-organization-mutation.component.html', + styleUrls: ['./public-page-organization-mutation.component.scss'] }) -export class PublicPageMutationComponent extends TranslationBaseComponent implements OnInit { - income?: IIncome; +export class PublicPageOrganizationMutationComponent extends TranslationBaseComponent implements OnInit { + income: IIncome; organization?: IOrganization; client_focus = Object.values(ClientFocusEnum); minimumProjectSizes = Object.values(MinimumProjectSizeEnum); @@ -77,12 +75,12 @@ export class PublicPageMutationComponent extends TranslationBaseComponent implem selectedClientFocus: any; constructor( + readonly translateService: TranslateService, private readonly fb: UntypedFormBuilder, - protected readonly dialogRef: NbDialogRef, + private readonly dialogRef: NbDialogRef, private readonly toastrService: ToastrService, private readonly organizationAwardsService: OrganizationAwardsService, private readonly organizationLanguagesService: OrganizationLanguagesService, - readonly translateService: TranslateService, private readonly store: Store ) { super(translateService); @@ -241,6 +239,9 @@ export class PublicPageMutationComponent extends TranslationBaseComponent implem } } + /** + * Load languages + */ private async loadLanguages() { const { organizationId, tenantId } = this; const res = await this.organizationLanguagesService.getAll({ organizationId, tenantId }, ['language']); diff --git a/apps/gauzy/src/app/share/organization/organization.component.html b/packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.html similarity index 61% rename from apps/gauzy/src/app/share/organization/organization.component.html rename to packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.html index e4546a0170f..aa2c70ea676 100644 --- a/apps/gauzy/src/app/share/organization/organization.component.html +++ b/packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.html @@ -11,16 +11,11 @@ [src]="organization.imageUrl" alt="Organization Avatar" /> -
+
- - - + + +
@@ -87,105 +63,57 @@ {{ 'BUTTONS.UPDATE' | translate }}
-

- +

+
-
- - {{ - 'PUBLIC_PAGE.YEAR_FOUNDED' - | translate - }}: - +
+ {{ 'PUBLIC_PAGE.YEAR_FOUNDED' | translate }}: {{ organization.registrationDate | dateFormat : null : 'Y' }}
-
- - {{ 'PUBLIC_PAGE.COMPANY_SIZE' | translate }}: - +
+ {{ 'PUBLIC_PAGE.COMPANY_SIZE' | translate }}: {{ employeeCounts }}
-
+
- - {{ - 'PUBLIC_PAGE.TOTAL_CLIENTS' - | translate - }}: - + {{ 'PUBLIC_PAGE.TOTAL_CLIENTS' | translate }}: - {{ (clientCounts$ | async) }} + {{ clientCounts$ | async }}
-
+
- - {{ - 'PUBLIC_PAGE.CLIENT_FOCUS' - | translate - }}: - + {{ 'PUBLIC_PAGE.CLIENT_FOCUS' | translate }}:
-
+
- {{ - 'PUBLIC_PAGE.PROFITS' - | translate - }} + {{ 'PUBLIC_PAGE.PROFITS' | translate }} :
@@ -200,10 +128,7 @@
size="small" nbButton > - + {{ 'BUTTONS.EDIT' | translate }} @@ -212,32 +137,14 @@
- - + + - - + + - - + + [tabTitle]="'ORGANIZATIONS_PAGE.CLIENTS' | translate" *ngIf="organization.show_clients" > - +
@@ -262,18 +167,10 @@
-
- {{ - 'PUBLIC_PAGE.TOTAL_PROJECTS' - | translate - }}: +
+ {{ 'PUBLIC_PAGE.TOTAL_PROJECTS' | translate }}:
- +
@@ -283,13 +180,8 @@
-
- {{ - 'PUBLIC_PAGE.TOTAL_INCOME' - | translate - }}: +
+ {{ 'PUBLIC_PAGE.TOTAL_INCOME' | translate }}:
- {{ - 'PUBLIC_PAGE.TOTAL_BONUSES_PAID' - | translate - }}: + {{ 'PUBLIC_PAGE.TOTAL_BONUSES_PAID' | translate }}:
- {{ - 'PUBLIC_PAGE.EMPLOYEES' | translate - }}: + {{ 'PUBLIC_PAGE.EMPLOYEES' | translate }}:
- +
@@ -353,20 +237,10 @@
-
- {{ - 'PUBLIC_PAGE.DESCRIPTION' - | translate - }}: +
+ {{ 'PUBLIC_PAGE.DESCRIPTION' | translate }}:
-
+
@@ -376,17 +250,11 @@
-
- {{ - 'PUBLIC_PAGE.OVERVIEW' | translate - }}: +
+ {{ 'PUBLIC_PAGE.OVERVIEW' | translate }}:
-
+
@@ -397,13 +265,8 @@
-
- {{ - 'POP_UPS.MINIMUM_PROJECT_SIZE' - | translate - }}: +
+ {{ 'POP_UPS.MINIMUM_PROJECT_SIZE' | translate }}:
@@ -420,18 +283,14 @@
-
+
{{ 'PUBLIC_PAGE.SKILLS' | translate }}:
@@ -449,9 +308,7 @@
-
+
{{ 'PUBLIC_PAGE.LANGUAGES' | translate }}:
@@ -478,18 +335,14 @@
-
+
{{ 'PUBLIC_PAGE.AWARDS' | translate }}:
@@ -521,23 +374,13 @@
*ngFor="let employee of employees; let last = last" [ngClass]="{ 'border-bottom': !last }" > - +
@@ -545,10 +388,7 @@
{{ employee?.fullName }} @@ -561,17 +401,9 @@
- -
- {{ - employee.payPeriod - | replace: '_':' ' - | titlecase - }} + +
+ {{ employee.payPeriod | replace : '_' : ' ' | titlecase }}
@@ -579,10 +411,7 @@
- +
- {{ - 'PUBLIC_PAGE.AVERAGE_BONUS' - | translate - }}: + {{ 'PUBLIC_PAGE.AVERAGE_BONUS' | translate }}: - {{ - employee.billRateCurrency - }} - {{ - employee.averageBonus === - null - ? 0 - : employee.averageBonus - }} + {{ employee.billRateCurrency }} + {{ employee.averageBonus === null ? 0 : employee.averageBonus }}
@@ -638,11 +455,7 @@
-
  • +
  • {{ skill.name }} @@ -651,37 +464,19 @@
  • - +
    {{ employee.billRateValue - | currency - : employee.billRateCurrency - : 'symbol' - | position - : organization?.currencyPosition + | currency : employee.billRateCurrency : 'symbol' + | position : organization?.currencyPosition }}/hr
    - -
    - {{ - employee.totalWorkHours - }} - {{ - 'ORGANIZATIONS_PAGE.HOURS_WORKED' - | translate - }} + +
    + {{ employee.totalWorkHours }} + {{ 'ORGANIZATIONS_PAGE.HOURS_WORKED' | translate }}
    @@ -693,33 +488,18 @@
    -
    - A -
    +
    A
    - {{ - 'PUBLIC_PAGE.ANONYMOUS' - | translate - }} -
    -
    - Full Stack Web Developer + {{ 'PUBLIC_PAGE.ANONYMOUS' | translate }}
    +
    Full Stack Web Developer
    - -
    - {{ - employee.payPeriod - | replace: '_':' ' - | titlecase - }} + +
    + {{ employee.payPeriod | replace : '_' : ' ' | titlecase }}
    @@ -727,10 +507,7 @@
    - +
    - {{ - 'PUBLIC_PAGE.AVERAGE_BONUS' - | translate - }}: + {{ 'PUBLIC_PAGE.AVERAGE_BONUS' | translate }}: - {{ - employee.billRateCurrency - }} - {{ - employee.averageBonus === - null - ? 0 - : employee.averageBonus - }} + {{ employee.billRateCurrency }} + {{ employee.averageBonus === null ? 0 : employee.averageBonus }}
    -
  • +
  • {{ skill.name }} @@ -804,11 +565,11 @@
    - +
    @@ -818,9 +579,7 @@
    {{ client?.name }}
    - +
    diff --git a/apps/gauzy/src/app/share/organization/organization.component.scss b/packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.scss similarity index 100% rename from apps/gauzy/src/app/share/organization/organization.component.scss rename to packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.scss diff --git a/apps/gauzy/src/app/share/organization/organization.component.ts b/packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.ts similarity index 74% rename from apps/gauzy/src/app/share/organization/organization.component.ts rename to packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.ts index 1bee1cfe57b..708aa30c9ec 100644 --- a/apps/gauzy/src/app/share/organization/organization.component.ts +++ b/packages/plugins/public-layout-ui/src/lib/components/organization/organization.component.ts @@ -4,19 +4,20 @@ import { TranslateService } from '@ngx-translate/core'; import { IOrganization, PermissionsEnum, IOrganizationContact, IEmployee } from '@gauzy/contracts'; import { NbDialogService, NbTabComponent, NbTabsetComponent } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Observable, of as observableOf, Subject } from 'rxjs'; +import { Observable, of, Subject } from 'rxjs'; import { debounceTime, map, tap } from 'rxjs/operators'; import * as moment from 'moment'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; import { DateRangePickerBuilderService, EmployeeStatisticsService, EmployeesService, + ErrorHandlingService, OrganizationsService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { PublicPageMutationComponent } from '@gauzy/ui-core/shared'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { PublicPageOrganizationMutationComponent } from '../mutation/public-page-organization-mutation/public-page-organization-mutation.component'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -25,22 +26,20 @@ import { PublicPageMutationComponent } from '@gauzy/ui-core/shared'; styleUrls: ['./organization.component.scss'] }) export class OrganizationComponent extends TranslationBaseComponent implements OnInit, OnDestroy { - public hasEditPublicPage$: Observable = observableOf(false); + public hasEditPublicPage$: Observable = of(false); public organization: IOrganization; public organization$: Observable; - public employees$: Observable = observableOf([]); - public employeeCounts$: Observable = observableOf(0); - public clients$: Observable = observableOf([]); - public clientCounts$: Observable = observableOf(0); - public projectCounts$: Observable = observableOf(0); - - bonusesPaid = 0; - totalIncome = 0; - profits = 0; - - imageUrl: string; - hoverState: boolean; - imageUpdateButton = false; + public employees$: Observable = of([]); + public employeeCounts$: Observable = of(0); + public clients$: Observable = of([]); + public clientCounts$: Observable = of(0); + public projectCounts$: Observable = of(0); + public bonusesPaid = 0; + public totalIncome = 0; + public profits = 0; + public imageUrl: string; + public hoverState: boolean; + public imageUpdateButton = false; /** * Reload Resolver Subject @@ -53,6 +52,7 @@ export class OrganizationComponent extends TranslationBaseComponent implements O @ViewChild('profileTab') profileTabEl: NbTabComponent; constructor( + readonly translateService: TranslateService, private readonly router: Router, private readonly route: ActivatedRoute, private readonly organizationsService: OrganizationsService, @@ -62,7 +62,7 @@ export class OrganizationComponent extends TranslationBaseComponent implements O private readonly store: Store, private readonly dateRangePickerService: DateRangePickerBuilderService, private readonly dialogService: NbDialogService, - readonly translateService: TranslateService + private readonly _errorHandlingService: ErrorHandlingService ) { super(translateService); } @@ -100,12 +100,26 @@ export class OrganizationComponent extends TranslationBaseComponent implements O this.router.navigate([this.router.url]); } - updateImageUrl(url: string) { + /** + * Updates the image url of the organization. + * + * @param url - The image url to be updated. + */ + updateImageUrl(url: string): void { this.imageUrl = url; this.imageUpdateButton = true; } - handleImageUploadError(event: any) {} + /** + * Handles the error while uploading an image. + * + * @param event - The error event to be handled. + * @return {void} This function does not return a value. + */ + handleImageUploadError(event: any): void { + console.log('Error while uploading image', event); + this._errorHandlingService.handleError(event); + } /** * GET public information of the clients in the organization @@ -117,13 +131,21 @@ export class OrganizationComponent extends TranslationBaseComponent implements O if (!this.organization) { return; } + + // Extract the organization id and tenant id. const { id: organizationId } = this.organization; + + // Get the clients. if (!!this.organization.show_clients) { + // Get the clients. this.clients$ = this.organizationsService .getAllPublicClients({ organizationId }) .pipe(map(({ items }) => items)); } + + // Get the clients counts. if (!!this.organization.show_clients_count) { + // Get the clients counts. this.clientCounts$ = this.organizationsService.getAllPublicClientCounts({ organizationId }); } } @@ -137,8 +159,13 @@ export class OrganizationComponent extends TranslationBaseComponent implements O if (!this.organization) { return; } + + // Get the project counts. if (!!this.organization.show_projects_count) { + // Extract the organization id and tenant id. const { id: organizationId } = this.organization; + + // Get the project counts. this.projectCounts$ = this.organizationsService.getAllPublicProjectCounts({ organizationId }); } } @@ -153,17 +180,27 @@ export class OrganizationComponent extends TranslationBaseComponent implements O if (!this.organization) { return; } - const { id: organizationId } = this.organization; + + // Get the employees and employee counts. if (!!this.organization.show_employees_count) { + // Extract the organization id and tenant id. + const { id: organizationId } = this.organization; + + // Get the employees. this.employees$ = this.employeesService .getAllPublic({ organizationId }, ['user', 'organizationPosition', 'skills']) .pipe( - tap(({ total }) => (this.employeeCounts$ = observableOf(total))), + tap(({ total }) => (this.employeeCounts$ = of(total))), map(({ items }) => items) ); } } + /** + * GET public information of the employees in the organization + * + * @returns + */ private async getEmployeeStatistics() { if (!this.organization) { return; @@ -208,11 +245,18 @@ export class OrganizationComponent extends TranslationBaseComponent implements O * @return {void} */ editPublicPage(): void { - const dialog$ = this.dialogService.open(PublicPageMutationComponent, { + if (!this.organization) { + return; + } + + // Open the dialog. + const dialog$ = this.dialogService.open(PublicPageOrganizationMutationComponent, { context: { organization: this.organization } }); + + // Close the dialog. dialog$.onClose .pipe( tap(() => this._changeClientsTabIfActiveAndPrivacyIsTurnedOff()), @@ -225,9 +269,12 @@ export class OrganizationComponent extends TranslationBaseComponent implements O currency: this.organization.currency, defaultValueDateType: this.organization.defaultValueDateType }); - this.toastrService.success('TOASTR.MESSAGE.ORGANIZATION_PAGE_UPDATED', { - name: this.organization.name - }); + + // Display a success toastr. + const { name } = this.organization; + this.toastrService.success('TOASTR.MESSAGE.ORGANIZATION_PAGE_UPDATED', { name }); + + // Reload the resolver. this.reload$.next(true); } }); diff --git a/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.html b/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.html new file mode 100644 index 00000000000..ab71c426fee --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.html @@ -0,0 +1,35 @@ + + +
    + +

    + {{ 'APPOINTMENTS_PAGE.SELECT_EMPLOYEE' | translate }} +

    +
    +
    + + +
    +
    + +
    + + + +
    +
    +
    +
    +
    +
    diff --git a/apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.scss b/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.scss similarity index 100% rename from apps/gauzy/src/app/share/public-appointments/pick-employee/pick-employee.component.scss rename to packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.scss diff --git a/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.ts b/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.ts new file mode 100644 index 00000000000..9547242cd93 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/pick-employee/pick-employee.component.ts @@ -0,0 +1,103 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { Router } from '@angular/router'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable, tap } from 'rxjs'; +import { filter } from 'rxjs/operators'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { ID, IOrganization } from '@gauzy/contracts'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { EventTypeService, Store, ToastrService } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { EmployeeSelectorComponent } from '@gauzy/ui-core/shared'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ga-pick-employee', + templateUrl: './pick-employee.component.html', + styleUrls: ['./pick-employee.component.scss'], + providers: [EventTypeService] +}) +export class PickEmployeeComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public loading: boolean; + public organization: IOrganization; + public organization$: Observable; + + @ViewChild('employeeSelector') employeeSelector: EmployeeSelectorComponent; + + constructor( + readonly translateService: TranslateService, + private readonly _router: Router, + private readonly _toastrService: ToastrService, + private readonly _eventTypeService: EventTypeService, + private readonly _store: Store + ) { + super(translateService); + } + + ngOnInit(): void { + this.organization$ = this._store.selectedOrganization$.pipe( + // Ensure the selected organization is valid + filter((organization: IOrganization) => !!organization), + // Fetch the unique organization + distinctUntilChange(), + // Store the organization in the 'organization' property + tap((organization: IOrganization) => (this.organization = organization)), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + } + + /** + * Book an appointment for the selected employee + * + * @returns {Promise} + */ + async bookPublicEmployeeAppointment(): Promise { + if (!this.organization) { + return; + } + + // Extract organization and employee IDs + const { id: organizationId, tenantId } = this.organization; + + // Get the selected employee + const selectedEmployeeId: ID = this.employeeSelector.selectedEmployee?.id; + + // If an employee is selected, fetch the event types + if (selectedEmployeeId) { + try { + let { items } = await this._eventTypeService.getAll(['employee', 'employee.user', 'tags'], { + organizationId, + tenantId, + employee: { id: selectedEmployeeId }, + isActive: true, + isArchived: false + }); + + if (items.length === 0) { + ({ items } = await this._eventTypeService.getAll(['tags'], { + organizationId, + tenantId, + isActive: true, + isArchived: false + })); + } + + // If exactly one event type is found, navigate to its page + const navigatePath = + items.length === 1 + ? `/share/employee/${selectedEmployeeId}/${items[0].id}` + : `/share/employee/${selectedEmployeeId}`; + + this._router.navigate([navigatePath]); + } catch (error) { + console.error('Error while fetching event types:', error); + this._toastrService.danger(this.getTranslation('PUBLIC_APPOINTMENTS.SELECT_EMPLOYEE_ERROR')); + } + } else { + this._toastrService.danger(this.getTranslation('PUBLIC_APPOINTMENTS.SELECT_EMPLOYEE_ERROR')); + } + } + + ngOnDestroy() {} +} diff --git a/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.html b/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.html new file mode 100644 index 00000000000..a063ad3818d --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.html @@ -0,0 +1,51 @@ + + +
    +

    {{ 'PUBLIC_APPOINTMENTS.BOOK_APPOINTMENTS' | translate }}

    +
    +
    + + +
    + Employee Avatar +
    + {{ employee?.fullName }} +
    + {{ employee.organizationPosition?.name }} +
    +
    + {{ employee.user?.email }} +
    +
    +
    +
    +
    +
    + {{ + (eventTypesExist + ? 'PUBLIC_APPOINTMENTS.SELECT_EVENT_TYPES' + : 'PUBLIC_APPOINTMENTS.NO_ACTIVE_EVENT_TYPES' + ) | translate + }} +
    +
    +
    +
    +
    +
    + {{ eventType.title }} +
    +
    +
    + {{ 'PUBLIC_APPOINTMENTS.DURATION' | translate }} + {{ eventType.duration }} {{ eventType.durationUnit }} +
    +
    + +
    +
    +
    +
    +
    diff --git a/apps/gauzy/src/app/share/public-appointments/public-appointments.component.scss b/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.scss similarity index 100% rename from apps/gauzy/src/app/share/public-appointments/public-appointments.component.scss rename to packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.scss diff --git a/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.ts b/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.ts new file mode 100644 index 00000000000..dd489d23787 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/public-appointment/public-appointment.component.ts @@ -0,0 +1,149 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Router, ActivatedRoute, Params } from '@angular/router'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable, catchError, of, switchMap } from 'rxjs'; +import { filter, tap } from 'rxjs/operators'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { ID, IEmployee, IEventType, IOrganization } from '@gauzy/contracts'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { EmployeesService, ErrorHandlingService, EventTypeService, Store } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ga-public-appointment', + templateUrl: './public-appointment.component.html', + styleUrls: ['./public-appointment.component.scss'], + providers: [EventTypeService] +}) +export class PublicAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public employee: IEmployee; + public employee$: Observable; + public organization: IOrganization; + public organization$: Observable; + public loading: boolean = false; + public eventTypes: IEventType[] = []; + public eventTypesExist: boolean; + + constructor( + readonly translateService: TranslateService, + private readonly _router: Router, + private readonly _route: ActivatedRoute, + private readonly _store: Store, + private readonly _employeeService: EmployeesService, + private readonly _eventTypeService: EventTypeService, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit(): void { + // Create an observable for the employee based on route parameters + this.employee$ = this._route.params.pipe( + // Ensure the route parameters are valid + filter((params: Params) => !!params.id), + // Fetch the employee from the employee service + switchMap((params: Params) => this._employeeService.getEmployeeById(params.id, ['user'])), + // Store the employee in the 'employee' property + tap((employee: IEmployee) => (this.employee = employee)), + // Fetch event types + tap(() => this.getEventTypes()), + // Handle errors + catchError((error: any) => { + // Handle and log errors + this._errorHandlingService.handleError(error); + return of(null); + }), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + this.organization$ = this._store.selectedOrganization$.pipe( + // Ensure the selected organization is valid + filter((organization: IOrganization) => !!organization), + // Fetch the unique organization + distinctUntilChange(), + // Store the organization in the 'organization' property + tap((organization: IOrganization) => (this.organization = organization)), + // Handle component lifecycle to avoid memory leaks + untilDestroyed(this) + ); + } + + /** + * Fetches and processes event types based on the organization and employee details. + * + * @returns {Promise} + */ + async getEventTypes(): Promise { + if (!this.organization || !this.employee) { + return; + } + + // Set loading state to true + this.loading = true; + + // Extract organization and employee IDs + const { id: organizationId, tenantId } = this.organization; + const { id: employeeId } = this.employee; + + try { + let { items } = await this._eventTypeService.getAll(['employee', 'employee.user', 'tags'], { + organizationId, + tenantId, + employee: { id: employeeId }, + isActive: true, + isArchived: false + }); + + // If no event types are found for the employee, fetch generic event types + if (items.length === 0) { + ({ items } = await this._eventTypeService.getAll(['tags'], { + organizationId, + tenantId, + isActive: true, + isArchived: false + })); + } + + // If exactly one event type is found, navigate to its page + if (items.length === 1) { + // Get the first event type + const eventType = items[0]; + + // Navigate to the event type page + this._router.navigate([`/share/employee/${employeeId}/${eventType.id}`]); + } else if (items.length > 0) { + this.eventTypesExist = true; + } + + // Sort event types by duration and duration unit + const eventTypesOrder = ['Minute(s)', 'Hour(s)', 'Day(s)']; + + // Sort event types by duration and duration unit + this.eventTypes = items.sort((a, b) => { + // Compare by duration unit first + const comparison = eventTypesOrder.indexOf(a.durationUnit) - eventTypesOrder.indexOf(b.durationUnit); + // If duration units are the same, compare by duration + return comparison !== 0 ? comparison : a.duration - b.duration; + }); + } catch (error) { + console.error('Error while fetching event types:', error); + // Handle and log errors + this._errorHandlingService.handleError(error); + } finally { + // Set loading state to false + this.loading = false; + } + } + + /** + * Select event type + * + * @param id + */ + selectEventType(id: ID) { + this._router.navigate([`${this._router.url}/${id}`]); + } + + ngOnDestroy() {} +} diff --git a/packages/plugins/public-layout-ui/src/lib/components/public-layout.component.ts b/packages/plugins/public-layout-ui/src/lib/components/public-layout.component.ts new file mode 100644 index 00000000000..778b4662876 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/components/public-layout.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; + +@Component({ + selector: 'gz-public-layout', + template: ` + + + + ` +}) +export class PublicLayoutComponent extends TranslationBaseComponent { + constructor(readonly translateService: TranslateService) { + super(translateService); + } +} diff --git a/packages/plugins/public-layout-ui/src/lib/public-api.ts b/packages/plugins/public-layout-ui/src/lib/public-api.ts new file mode 100644 index 00000000000..0ff61ee7fe3 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/public-api.ts @@ -0,0 +1,19 @@ +/** + * Public API Surface of @gauzy/plugin-public-layout-ui + */ +export * from './components/appointment-form/appointment-form.component'; +export * from './components/confirm-appointment/confirm-appointment.component'; +export * from './components/create-appointment/create-appointment.component'; +export * from './components/edit-appointment/edit-appointment.component'; +export * from './components/employee/employee.component'; +export * from './components/invoice-estimate/invoice-estimate-view.component'; +export * from './components/mutation/public-page-employee-mutation/public-page-employee-mutation.component'; +export * from './components/mutation/public-page-organization-mutation/public-page-organization-mutation.component'; +export * from './components/organization/organization.component'; +export * from './components/pick-employee/pick-employee.component'; +export * from './components/public-appointment/public-appointment.component'; +export * from './components/public-layout.component'; +export * from './public-layout.module'; +export * from './public-layout.routes'; +export * from './resolvers/public-employee.resolver'; +export * from './resolvers/public-organization.resolver'; diff --git a/packages/plugins/public-layout-ui/src/lib/public-layout.module.ts b/packages/plugins/public-layout-ui/src/lib/public-layout.module.ts new file mode 100644 index 00000000000..1fbbeefe7dd --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/public-layout.module.ts @@ -0,0 +1,126 @@ +import { NgModule } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { ROUTES, RouterModule } from '@angular/router'; +import { + NbActionsModule, + NbBadgeModule, + NbButtonModule, + NbCardModule, + NbCheckboxModule, + NbDatepickerModule, + NbDialogModule, + NbIconModule, + NbInputModule, + NbListModule, + NbMenuModule, + NbSelectModule, + NbSpinnerModule, + NbTabsetModule, + NbTagModule, + NbToastrModule, + NbToggleModule, + NbTooltipModule, + NbUserModule +} from '@nebular/theme'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CKEditorModule } from 'ckeditor4-angular'; +import { NgxPermissionsModule } from 'ngx-permissions'; +import { LanguagesEnum } from '@gauzy/contracts'; +import { LanguagesService, PageRouteRegistryService, SkillsService } from '@gauzy/ui-core/core'; +import { HttpLoaderFactory } from '@gauzy/ui-core/i18n'; +import { + AppointmentCalendarModule, + CurrencyModule, + ImageUploaderModule, + InvoiceViewInnerModule, + LanguageSelectorModule, + ManageAppointmentModule, + MiscellaneousModule, + SelectorsModule, + SharedModule, + SkillsInputModule, + TableComponentsModule, + TagsColorInputModule, + WorkInProgressModule +} from '@gauzy/ui-core/shared'; +import { ThemeModule } from '@gauzy/ui-core/theme'; +import { COMPONENTS } from './components'; +import { createPublicLayoutRoutes } from './public-layout.routes'; + +// Nebular Modules +const NB_MODULES = [ + NbActionsModule, + NbBadgeModule, + NbButtonModule, + NbCardModule, + NbCheckboxModule, + NbDatepickerModule, + NbDialogModule.forChild(), + NbIconModule, + NbInputModule, + NbListModule, + NbMenuModule, + NbSpinnerModule, + NbSelectModule, + NbTabsetModule, + NbTagModule, + NbToastrModule.forRoot(), + NbToggleModule, + NbTooltipModule, + NbUserModule +]; + +/* + * Third Party Modules + */ +const THIRD_PARTY_MODULES = [ + CKEditorModule, + NgSelectModule, + NgxPermissionsModule.forRoot(), + TranslateModule.forRoot({ + defaultLanguage: LanguagesEnum.ENGLISH, + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient] + } + }) +]; + +/** + * Feature Modules + */ +const FEATURE_MODULES = [ + AppointmentCalendarModule, + CurrencyModule, + ImageUploaderModule, + InvoiceViewInnerModule, + LanguageSelectorModule, + ManageAppointmentModule, + MiscellaneousModule, + SelectorsModule, + SharedModule, + SkillsInputModule, + TableComponentsModule, + TagsColorInputModule, + ThemeModule, + WorkInProgressModule +]; + +@NgModule({ + declarations: [...COMPONENTS], + imports: [RouterModule.forChild([]), ...NB_MODULES, ...THIRD_PARTY_MODULES, ...FEATURE_MODULES], + exports: [...COMPONENTS], + providers: [ + LanguagesService, + SkillsService, + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createPublicLayoutRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class PublicLayoutModule {} diff --git a/packages/plugins/public-layout-ui/src/lib/public-layout.routes.ts b/packages/plugins/public-layout-ui/src/lib/public-layout.routes.ts new file mode 100644 index 00000000000..0692e7dcdec --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/public-layout.routes.ts @@ -0,0 +1,103 @@ +import { Route } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { NotFoundComponent } from '@gauzy/ui-core/shared'; +import { + AppointmentFormComponent, + ConfirmAppointmentComponent, + CreateAppointmentComponent, + EditAppointmentComponent, + EmployeeComponent, + InvoiceEstimateViewComponent, + OrganizationComponent, + PickEmployeeComponent, + PublicAppointmentComponent, + PublicLayoutComponent +} from './components'; +import { PublicEmployeeResolver } from './resolvers/public-employee.resolver'; +import { PublicOrganizationResolver } from './resolvers/public-organization.resolver'; + +/** + * Creates public layout routes for the application + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createPublicLayoutRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + component: PublicLayoutComponent, + children: [ + { + path: 'organization/:profileLink/:organizationId', + children: [ + { + path: '', + component: OrganizationComponent, + data: { + relations: ['skills', 'awards', 'languages', 'languages.language'] + }, + resolve: { + organization: PublicOrganizationResolver + }, + runGuardsAndResolvers: 'always' + }, + { + path: ':slug/:employeeId', + component: EmployeeComponent, + data: { + relations: [] + }, + resolve: { + organization: PublicOrganizationResolver, + employee: PublicEmployeeResolver + }, + runGuardsAndResolvers: 'always' + } + ] + }, + { + path: 'employee', + children: [ + { + path: '', + component: PickEmployeeComponent + }, + { + path: 'edit-appointment', + component: EditAppointmentComponent + }, + { + path: ':id', + children: [ + { + path: '', + component: PublicAppointmentComponent + }, + { + path: 'confirm/:appointmentId', + component: ConfirmAppointmentComponent + }, + { + path: 'create-appointment', + component: AppointmentFormComponent + }, + { + path: ':eventId', + component: CreateAppointmentComponent + } + ] + } + ] + }, + { + path: ':type/:id/:token', + component: InvoiceEstimateViewComponent, + children: [] + }, + { + path: '**', + component: NotFoundComponent + } + ] + } +]; diff --git a/packages/plugins/public-layout-ui/src/lib/resolvers/public-employee.resolver.ts b/packages/plugins/public-layout-ui/src/lib/resolvers/public-employee.resolver.ts new file mode 100644 index 00000000000..983b350d144 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/resolvers/public-employee.resolver.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@angular/core'; +import { Resolve, Router, ActivatedRouteSnapshot } from '@angular/router'; +import { catchError } from 'rxjs/operators'; +import { EMPTY, Observable } from 'rxjs'; +import { IEmployee } from '@gauzy/contracts'; +import { EmployeesService, ErrorHandlingService } from '@gauzy/ui-core/core'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicEmployeeResolver implements Resolve { + constructor( + private readonly _employeesService: EmployeesService, + private readonly _router: Router, + private readonly _errorHandlingService: ErrorHandlingService + ) {} + + /** + * Resolves the public employee data based on the provided route parameters. + * + * @param route ActivatedRouteSnapshot containing route parameters. + * @returns Observable resolving the employee data. + */ + resolve(route: ActivatedRouteSnapshot): Observable { + // Extracting route parameters + const { slug, employeeId } = route.params; + + // Relations to be included in the response + const relations = ['user', 'organizationEmploymentTypes', 'skills', 'awards']; + + // Fetching the public employee data + return this._employeesService.getPublicById(slug, employeeId, relations).pipe( + catchError((error) => { + this._errorHandlingService.handleError(error); + this._router.navigateByUrl('/'); + return EMPTY; + }) + ); + } +} diff --git a/packages/plugins/public-layout-ui/src/lib/resolvers/public-organization.resolver.ts b/packages/plugins/public-layout-ui/src/lib/resolvers/public-organization.resolver.ts new file mode 100644 index 00000000000..ace135e9432 --- /dev/null +++ b/packages/plugins/public-layout-ui/src/lib/resolvers/public-organization.resolver.ts @@ -0,0 +1,43 @@ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot, Router } from '@angular/router'; +import { EMPTY, Observable } from 'rxjs'; +import { catchError } from 'rxjs/operators'; +import { IOrganization } from '@gauzy/contracts'; +import { ErrorHandlingService, OrganizationsService } from '@gauzy/ui-core/core'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicOrganizationResolver implements Resolve { + constructor( + private readonly _organizationsService: OrganizationsService, + private readonly _router: Router, + private readonly _errorHandlingService: ErrorHandlingService + ) {} + + /** + * Resolves the organization data before activating the route. + * + * This method is typically used in route guards to fetch necessary + * data before the route is activated. It retrieves the organization + * by its profile link and ID, handling any potential errors by + * redirecting to the home page if the fetch fails. + * + * @param route The route snapshot containing route parameters and data. + * @returns An observable of the resolved IOrganization object. + */ + resolve(route: ActivatedRouteSnapshot): Observable { + // Extract the route parameters + const { profileLink, organizationId } = route.params; + const relations = route.data.relations || []; + + // Get the organization by its profile link and ID + return this._organizationsService.getByProfileLink(profileLink, organizationId, relations).pipe( + catchError((error) => { + this._errorHandlingService.handleError(error); + this._router.navigateByUrl('/'); + return EMPTY; + }) + ); + } +} diff --git a/packages/plugins/public-layout-ui/src/test-setup.ts b/packages/plugins/public-layout-ui/src/test-setup.ts new file mode 100644 index 00000000000..1100b3e8a6e --- /dev/null +++ b/packages/plugins/public-layout-ui/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/packages/plugins/public-layout-ui/tsconfig.json b/packages/plugins/public-layout-ui/tsconfig.json new file mode 100644 index 00000000000..02800c8a288 --- /dev/null +++ b/packages/plugins/public-layout-ui/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": false, + "noPropertyAccessFromIndexSignature": false, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + "baseUrl": ".", + "paths": { + "@gauzy/ui-core/*": ["./../../../dist/packages/ui-core/*/index.d.ts"], + "@ngx-translate/*": ["./node_modules/@ngx-translate/*"], + "ngx-permissions": ["./node_modules/ngx-permissions"], + "ng2-file-upload": ["./node_modules/ng2-file-upload"], + "@fullcalendar/*": ["./node_modules/@fullcalendar/*"] + } + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/plugins/public-layout-ui/tsconfig.lib.json b/packages/plugins/public-layout-ui/tsconfig.lib.json new file mode 100644 index 00000000000..5d1d67c0227 --- /dev/null +++ b/packages/plugins/public-layout-ui/tsconfig.lib.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/packages/plugins/public-layout-ui/tsconfig.lib.prod.json b/packages/plugins/public-layout-ui/tsconfig.lib.prod.json new file mode 100644 index 00000000000..7b29b93f6f3 --- /dev/null +++ b/packages/plugins/public-layout-ui/tsconfig.lib.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/packages/plugins/public-layout-ui/tsconfig.spec.json b/packages/plugins/public-layout-ui/tsconfig.spec.json new file mode 100644 index 00000000000..0b8b86994ff --- /dev/null +++ b/packages/plugins/public-layout-ui/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/packages/ui-auth/.dockerignore b/packages/ui-auth/.dockerignore new file mode 100644 index 00000000000..6edd0523636 --- /dev/null +++ b/packages/ui-auth/.dockerignore @@ -0,0 +1,20 @@ +docker +tmp +README.md +.env + +# git + +.git +.gitignore +.gitmodules + +# dependencies + +node_modules + +# misc + +npm-debug.log +dist +build diff --git a/packages/ui-auth/.gitignore b/packages/ui-auth/.gitignore new file mode 100644 index 00000000000..a34877c2c0e --- /dev/null +++ b/packages/ui-auth/.gitignore @@ -0,0 +1,6 @@ +# dependencies +node_modules/ + +# misc +npm-debug.log +dist \ No newline at end of file diff --git a/packages/ui-auth/.npmignore b/packages/ui-auth/.npmignore new file mode 100644 index 00000000000..1eb4beb9572 --- /dev/null +++ b/packages/ui-auth/.npmignore @@ -0,0 +1,4 @@ +# .npmignore + +src/ +node_modules/ diff --git a/packages/ui-auth/src/lib/auth.module.ts b/packages/ui-auth/src/lib/auth.module.ts index 03a72f8ca98..b547a7f8ae8 100644 --- a/packages/ui-auth/src/lib/auth.module.ts +++ b/packages/ui-auth/src/lib/auth.module.ts @@ -20,7 +20,13 @@ import { } from '@nebular/theme'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { LanguagesEnum } from '@gauzy/contracts'; -import { ElectronService, InviteService, NoAuthGuard, PageRouteService, RoleService } from '@gauzy/ui-core/core'; +import { + ElectronService, + InviteService, + NoAuthGuard, + PageRouteRegistryService, + RoleService +} from '@gauzy/ui-core/core'; import { ThemeModule, ThemeSelectorModule } from '@gauzy/ui-core/theme'; import { NgxFaqModule, PasswordFormFieldModule, SharedModule } from '@gauzy/ui-core/shared'; import { HttpLoaderFactory } from '@gauzy/ui-core/i18n'; @@ -114,8 +120,9 @@ const THIRD_PARTY_MODULES = [ ElectronService, { provide: ROUTES, - useFactory: (pageRouteService: PageRouteService) => createAuthRoutes(pageRouteService), - deps: [PageRouteService], + useFactory: (pageRouteRegistryService: PageRouteRegistryService) => + createAuthRoutes(pageRouteRegistryService), + deps: [PageRouteRegistryService], multi: true }, InviteService, @@ -125,7 +132,7 @@ const THIRD_PARTY_MODULES = [ export class NgxAuthModule { private static hasRegisteredPageRoutes = false; // Flag to check if routes have been registered - constructor(@Inject(PageRouteService) readonly _pageRouteService: PageRouteService) { + constructor(@Inject(PageRouteRegistryService) readonly _pageRouteRegistryService: PageRouteRegistryService) { // Register the routes this.registerPageRoutes(); } @@ -142,7 +149,7 @@ export class NgxAuthModule { } // Register the login workspace route - this._pageRouteService.registerPageRoutes([ + this._pageRouteRegistryService.registerPageRoutes([ { // Register the location 'auth' location: 'auth', diff --git a/packages/ui-auth/src/lib/auth.routes.ts b/packages/ui-auth/src/lib/auth.routes.ts index 1790d67d2bb..56033cbd4ed 100644 --- a/packages/ui-auth/src/lib/auth.routes.ts +++ b/packages/ui-auth/src/lib/auth.routes.ts @@ -1,6 +1,6 @@ import { Route } from '@angular/router'; import { NbLogoutComponent } from '@nebular/auth'; -import { NoAuthGuard, PageRouteService } from '@gauzy/ui-core/core'; +import { NoAuthGuard, PageRouteRegistryService } from '@gauzy/ui-core/core'; import { NgxAuthComponent } from './components/auth/auth.component'; import { NgxLoginComponent } from './components/login/login.component'; import { NgxForgotPasswordComponent } from './components/forgot-password/forgot-password.component'; @@ -16,10 +16,10 @@ import { AcceptClientInviteComponent } from './components/accept-client-invite/a /** * Creates routes for the auth module. * - * @param _pageRouteService An instance of PageRouteService + * @param _pageRouteRegistryService An instance of PageRouteRegistryService * @returns An array of Route objects */ -export const createAuthRoutes = (_pageRouteService: PageRouteService): Route[] => [ +export const createAuthRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ { path: '', component: NgxAuthComponent, @@ -75,7 +75,7 @@ export const createAuthRoutes = (_pageRouteService: PageRouteService): Route[] = path: 'logout', component: NbLogoutComponent }, - ..._pageRouteService.getPageLocationRoutes('auth') + ..._pageRouteRegistryService.getPageLocationRoutes('auth') ] } ]; diff --git a/packages/ui-auth/src/lib/components/accept-invite/accept-invite.component.ts b/packages/ui-auth/src/lib/components/accept-invite/accept-invite.component.ts index eac47637e25..702563c70d1 100644 --- a/packages/ui-auth/src/lib/components/accept-invite/accept-invite.component.ts +++ b/packages/ui-auth/src/lib/components/accept-invite/accept-invite.component.ts @@ -4,8 +4,7 @@ import { TranslateService } from '@ngx-translate/core'; import { tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IAuthResponse, IInvite, IUserEmailInput, IUserRegistrationInput, IUserTokenInput } from '@gauzy/contracts'; -import { InviteService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { InviteService, Store, ToastrService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-auth/src/lib/components/login-workspace/login-workspace.component.ts b/packages/ui-auth/src/lib/components/login-workspace/login-workspace.component.ts index 81835724688..d1f3386c8ad 100644 --- a/packages/ui-auth/src/lib/components/login-workspace/login-workspace.component.ts +++ b/packages/ui-auth/src/lib/components/login-workspace/login-workspace.component.ts @@ -5,9 +5,7 @@ import { EMPTY, filter } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { HttpStatus, IAuthResponse, IUser, IUserSigninWorkspaceResponse, IWorkspaceResponse } from '@gauzy/contracts'; -import { ErrorHandlingService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; -import { AuthService } from '@gauzy/ui-core/core'; +import { AuthService, ErrorHandlingService, Store } from '@gauzy/ui-core/core'; import { PasswordFormFieldComponent } from '@gauzy/ui-core/shared'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-auth/src/lib/components/magic-login-workspace/magic-login-workspace.component.ts b/packages/ui-auth/src/lib/components/magic-login-workspace/magic-login-workspace.component.ts index e03e9e9784f..3bd83734cdd 100644 --- a/packages/ui-auth/src/lib/components/magic-login-workspace/magic-login-workspace.component.ts +++ b/packages/ui-auth/src/lib/components/magic-login-workspace/magic-login-workspace.component.ts @@ -4,8 +4,8 @@ import { EMPTY, firstValueFrom } from 'rxjs'; import { catchError, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IAuthResponse, IUser, IUserSigninWorkspaceResponse, IWorkspaceResponse } from '@gauzy/contracts'; -import { Store, sleep } from '@gauzy/ui-core/common'; -import { AuthService, ErrorHandlingService } from '@gauzy/ui-core/core'; +import { sleep } from '@gauzy/ui-core/common'; +import { AuthService, ErrorHandlingService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-auth/src/lib/sign-in-success/sign-in-success.component.ts b/packages/ui-auth/src/lib/sign-in-success/sign-in-success.component.ts index 413f71506b9..8024af8b94e 100644 --- a/packages/ui-auth/src/lib/sign-in-success/sign-in-success.component.ts +++ b/packages/ui-auth/src/lib/sign-in-success/sign-in-success.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; -import { Store } from '@gauzy/ui-core/common'; import { ActivatedRoute, Router } from '@angular/router'; import { filter, tap } from 'rxjs/operators'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-sign-in-success', diff --git a/packages/ui-auth/tsconfig.json b/packages/ui-auth/tsconfig.json index f65b4bbb436..9819ec63263 100644 --- a/packages/ui-auth/tsconfig.json +++ b/packages/ui-auth/tsconfig.json @@ -10,12 +10,7 @@ "noFallthroughCasesInSwitch": false, "baseUrl": ".", "paths": { - "@gauzy/ui-core": ["./../../dist/packages/ui-core"], - "@gauzy/ui-core/common": ["./../../dist/packages/ui-core/common"], - "@gauzy/ui-core/core": ["./../../dist/packages/ui-core/core"], - "@gauzy/ui-core/i18n": ["./../../dist/packages/ui-core/i18n"], - "@gauzy/ui-core/shared": ["./../../dist/packages/ui-core/shared"], - "@gauzy/ui-core/theme": ["./../../dist/packages/ui-core/theme"], + "@gauzy/ui-core/*": ["./../../dist/packages/ui-core/*/index.d.ts"], "@ngx-translate/*": ["./node_modules/@ngx-translate/*"], "ngx-permissions": ["./node_modules/ngx-permissions"] } diff --git a/packages/ui-core/.dockerignore b/packages/ui-core/.dockerignore new file mode 100644 index 00000000000..6edd0523636 --- /dev/null +++ b/packages/ui-core/.dockerignore @@ -0,0 +1,20 @@ +docker +tmp +README.md +.env + +# git + +.git +.gitignore +.gitmodules + +# dependencies + +node_modules + +# misc + +npm-debug.log +dist +build diff --git a/packages/ui-core/.gitignore b/packages/ui-core/.gitignore new file mode 100644 index 00000000000..a34877c2c0e --- /dev/null +++ b/packages/ui-core/.gitignore @@ -0,0 +1,6 @@ +# dependencies +node_modules/ + +# misc +npm-debug.log +dist \ No newline at end of file diff --git a/packages/ui-core/.npmignore b/packages/ui-core/.npmignore new file mode 100644 index 00000000000..1eb4beb9572 --- /dev/null +++ b/packages/ui-core/.npmignore @@ -0,0 +1,4 @@ +# .npmignore + +src/ +node_modules/ diff --git a/packages/ui-core/common/src/index.ts b/packages/ui-core/common/src/index.ts index 8473b77980e..989bc5753f0 100644 --- a/packages/ui-core/common/src/index.ts +++ b/packages/ui-core/common/src/index.ts @@ -4,5 +4,4 @@ export * from './lib/common.module'; export * from './lib/constants'; export * from './lib/interfaces'; -export * from './lib/providers/services'; export * from './lib/utils/shared-utils'; diff --git a/packages/ui-core/common/src/lib/constants/timesheet.constants.ts b/packages/ui-core/common/src/lib/constants/timesheet.constants.ts index 665d23fa49e..8d4ebdc7a9c 100644 --- a/packages/ui-core/common/src/lib/constants/timesheet.constants.ts +++ b/packages/ui-core/common/src/lib/constants/timesheet.constants.ts @@ -1,5 +1,8 @@ import { TimeLogType } from '@gauzy/contracts'; +/** + * TimeLogsLabel + */ export const TimeLogsLabel = { [TimeLogType.TRACKED]: { status: 'success', diff --git a/packages/ui-core/common/src/lib/interfaces/backup-strategy.interface.ts b/packages/ui-core/common/src/lib/interfaces/backup-strategy.interface.ts index 960985b4b6a..09a7ca367ea 100644 --- a/packages/ui-core/common/src/lib/interfaces/backup-strategy.interface.ts +++ b/packages/ui-core/common/src/lib/interfaces/backup-strategy.interface.ts @@ -1,6 +1,5 @@ import { GuiDrag } from './gui-drag.abstract'; import { Serializable } from './serializable.interface'; - export interface BackupStrategy extends Serializable { get serializables(): Partial[]; set serializables(value: Partial[]); diff --git a/packages/ui-core/common/src/lib/providers/services/index.ts b/packages/ui-core/common/src/lib/providers/services/index.ts deleted file mode 100644 index 7659a4e8740..00000000000 --- a/packages/ui-core/common/src/lib/providers/services/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './store'; -export * from './time-tracker'; diff --git a/packages/ui-core/core/src/index.ts b/packages/ui-core/core/src/index.ts index 5d6b4e9d912..b6be0396738 100644 --- a/packages/ui-core/core/src/index.ts +++ b/packages/ui-core/core/src/index.ts @@ -2,6 +2,7 @@ * Public API Surface of @gauzy/ui-core/core */ export * from './lib/auth'; +export * from './lib/common/component-registry.types'; export * from './lib/components'; export * from './lib/core.module'; export * from './lib/guards'; diff --git a/packages/ui-core/core/src/lib/auth/auth.guard.ts b/packages/ui-core/core/src/lib/auth/auth.guard.ts index 9f036d0d39e..071cd7f8562 100644 --- a/packages/ui-core/core/src/lib/auth/auth.guard.ts +++ b/packages/ui-core/core/src/lib/auth/auth.guard.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; import { firstValueFrom } from 'rxjs'; -import { Store } from '@gauzy/ui-core/common'; -import { AuthService, AuthStrategy, ElectronService } from '../services'; +import { AuthService, AuthStrategy, ElectronService, Store } from '../services'; @Injectable() export class AuthGuard implements CanActivate { diff --git a/packages/ui-core/core/src/lib/auth/auth.module.ts b/packages/ui-core/core/src/lib/auth/auth.module.ts index cf1f700a4ba..be9ed870a50 100644 --- a/packages/ui-core/core/src/lib/auth/auth.module.ts +++ b/packages/ui-core/core/src/lib/auth/auth.module.ts @@ -2,10 +2,9 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NbAuthModule } from '@nebular/auth'; import { environment } from '@gauzy/ui-config'; -import { Store } from '@gauzy/ui-core/common'; import { AuthGuard } from './auth.guard'; import { NoAuthGuard } from './no-auth.guard'; -import { AuthService, AuthStrategy, ElectronService } from '../services'; +import { AuthService, AuthStrategy, ElectronService, Store } from '../services'; const socialLinks = [ { diff --git a/packages/ui-core/core/src/lib/auth/no-auth.guard.ts b/packages/ui-core/core/src/lib/auth/no-auth.guard.ts index 54caab05de5..e95f4a41b77 100644 --- a/packages/ui-core/core/src/lib/auth/no-auth.guard.ts +++ b/packages/ui-core/core/src/lib/auth/no-auth.guard.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; -import { Store } from '@gauzy/ui-core/common'; -import { AuthService } from '../services'; +import { AuthService, Store } from '../services'; /** * Use for routes which only need to be displayed if user is NOT logged in */ diff --git a/packages/ui-core/core/src/lib/common/component-registry-types.ts b/packages/ui-core/core/src/lib/common/component-registry-types.ts deleted file mode 100644 index 6701622f92c..00000000000 --- a/packages/ui-core/core/src/lib/common/component-registry-types.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @description - * Type representing the possible page locations for dynamic routes and tabs. - * - * This type is used to identify different sections of the application where dynamic - * routes and tabs can be registered. Each value corresponds to a specific page or - * section in the application. This allows for flexible and dynamic routing based - * on the context and requirements of the application. - * - * Possible values: - * - 'auth': The authentication section of the application. - * - 'pages': The main pages section of the application. - * - 'dashboard': The main dashboard page of the application. - * - 'jobs': The jobs or job search section of the application. - */ -export type PageRouteLocationId = 'auth' | 'pages' | 'dashboard' | 'jobs'; diff --git a/packages/ui-core/core/src/lib/common/component-registry.types.ts b/packages/ui-core/core/src/lib/common/component-registry.types.ts new file mode 100644 index 00000000000..6580da4301f --- /dev/null +++ b/packages/ui-core/core/src/lib/common/component-registry.types.ts @@ -0,0 +1,76 @@ +/** + * @description + * Type representing the possible component types for dynamic routes, tabs, and table columns. + * + * This type is used to identify different types of components that can be registered + * for dynamic routes, tabs, and table columns. Each value corresponds to a specific + * component type in the application. This allows for flexible and dynamic registration + * based on the context and requirements of the application. + * + * Possible values: + * - 'table': A table component. + * - 'tab': A tab component. + * - 'route': A route component. + */ +export type ComponentRegistryLocationId = 'table' | 'tab' | 'route'; + +// Define sub-page types for 'jobs', 'employees' and 'sales' +export type JobsSubPageLocationRegistryId = 'job-employee'; +export type SalesSubPageLocationRegistryId = 'proposals'; + +/** + * @description + * Type representing the possible page locations for dynamic routes, tabs, and table columns. + * + * This type is used to identify different sections of the application where dynamic + * routes and tabs can be registered. Each value corresponds to a specific page or + * section in the application. This allows for flexible and dynamic routing based + * on the context and requirements of the application. + * + * Possible values: + * - 'auth': The authentication section of the application. + * - 'pages': The main pages section of the application. + * - 'dashboard': The main dashboard page of the application. + * - 'jobs': The jobs or job search section of the application. + * - 'job-employee': A sub-page under the jobs section. + */ +export type PageLocationRegistryId = + | 'auth' + | 'pages' + | 'dashboard' + | 'jobs' + | JobsSubPageLocationRegistryId + | 'sales' + | SalesSubPageLocationRegistryId; + +/** + * @description + * Type representing the possible dynamic tabs for pages. + * + * This type is used to identify different types of tabs that can be registered + * for dynamic pages. Each value corresponds to a specific + * tab type in the application. This allows for flexible and dynamic registration + * based on the context and requirements of the application. + * + * Possible values: + * - 'timesheet': A timesheet tab. + * - 'time-activity': A time and activity tab. + */ +export type TabsetRegistryId = 'timesheet' | 'time-activity' | 'dashboard'; + +/** + * Enum representing the possible dynamic tabs for pages. + * + * This enum is used to identify different types of tabs that can be registered + * for dynamic pages. Each value corresponds to a specific + * tab type in the application. This allows for flexible and dynamic registration + * based on the context and requirements of the application. + * + * @readonly + * @enum {string} + */ +export enum TabsetRegistryIdEnum { + Timesheet = 'timesheet', // The identifier for the timesheet tabset + TimeActivity = 'time-activity', // The identifier for the time and activity tabset + Dashboard = 'dashboard' // The identifier for the dashboard tabset +} diff --git a/packages/ui-core/core/src/lib/components/base-nav-menu/base-nav-menu.component.ts b/packages/ui-core/core/src/lib/components/base-nav-menu/base-nav-menu.component.ts index f399ab96198..17877065341 100644 --- a/packages/ui-core/core/src/lib/components/base-nav-menu/base-nav-menu.component.ts +++ b/packages/ui-core/core/src/lib/components/base-nav-menu/base-nav-menu.component.ts @@ -4,9 +4,9 @@ import { filter, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { FeatureEnum, IOrganization, PermissionsEnum } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { NavMenuBuilderService, NavMenuSectionItem, SidebarMenuService } from '../../services'; +import { NavMenuBuilderService, NavMenuSectionItem, SidebarMenuService, Store } from '../../services'; @UntilDestroy() @Directive({ diff --git a/packages/ui-core/core/src/lib/components/sidebar-menu/menu-items/concrete/menu-item/menu-item.component.ts b/packages/ui-core/core/src/lib/components/sidebar-menu/menu-items/concrete/menu-item/menu-item.component.ts index bb3ac7a2148..ccdb61f19ba 100644 --- a/packages/ui-core/core/src/lib/components/sidebar-menu/menu-items/concrete/menu-item/menu-item.component.ts +++ b/packages/ui-core/core/src/lib/components/sidebar-menu/menu-items/concrete/menu-item/menu-item.component.ts @@ -4,8 +4,7 @@ import { Router } from '@angular/router'; import { tap } from 'rxjs/operators'; import { NbSidebarService } from '@nebular/theme'; import { IUser } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { JitsuAnalyticsEvents, JitsuAnalyticsEventsEnum, JitsuService } from '../../../../../services'; +import { JitsuAnalyticsEvents, JitsuAnalyticsEventsEnum, JitsuService, Store } from '../../../../../services'; import { IMenuItem } from '../../interface/menu-item.interface'; @Component({ diff --git a/packages/ui-core/core/src/lib/guards/invite.guard.ts b/packages/ui-core/core/src/lib/guards/invite.guard.ts index 1e297c49f93..aba64e5b82f 100644 --- a/packages/ui-core/core/src/lib/guards/invite.guard.ts +++ b/packages/ui-core/core/src/lib/guards/invite.guard.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'; import { firstValueFrom } from 'rxjs'; import { IOrganization, PermissionsEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '../services'; @Injectable() export class InviteGuard implements CanActivate { diff --git a/packages/ui-core/core/src/lib/interceptors/language.interceptor.ts b/packages/ui-core/core/src/lib/interceptors/language.interceptor.ts index 8c85497e29d..097dfb84489 100644 --- a/packages/ui-core/core/src/lib/interceptors/language.interceptor.ts +++ b/packages/ui-core/core/src/lib/interceptors/language.interceptor.ts @@ -2,8 +2,8 @@ import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; import { LanguagesEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; import { I18nService } from '@gauzy/ui-core/i18n'; +import { Store } from '../services/store'; @Injectable() export class LanguageInterceptor implements HttpInterceptor { diff --git a/packages/ui-core/core/src/lib/interceptors/tenant.interceptor.ts b/packages/ui-core/core/src/lib/interceptors/tenant.interceptor.ts index 68bcde0ea43..abffa6e21c3 100644 --- a/packages/ui-core/core/src/lib/interceptors/tenant.interceptor.ts +++ b/packages/ui-core/core/src/lib/interceptors/tenant.interceptor.ts @@ -3,7 +3,7 @@ import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/c import { Observable, combineLatest, switchMap, take, tap } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { RequestMethodEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '../services/store'; @UntilDestroy() @Injectable() diff --git a/packages/ui-core/core/src/lib/interceptors/token.interceptor.ts b/packages/ui-core/core/src/lib/interceptors/token.interceptor.ts index c1c0e847673..42a1bf132b0 100644 --- a/packages/ui-core/core/src/lib/interceptors/token.interceptor.ts +++ b/packages/ui-core/core/src/lib/interceptors/token.interceptor.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '../services/store'; @Injectable() export class TokenInterceptor implements HttpInterceptor { diff --git a/packages/ui-core/core/src/lib/resolvers/integration.resolver.ts b/packages/ui-core/core/src/lib/resolvers/integration.resolver.ts index 6160f44c220..01c9f3c20b0 100644 --- a/packages/ui-core/core/src/lib/resolvers/integration.resolver.ts +++ b/packages/ui-core/core/src/lib/resolvers/integration.resolver.ts @@ -2,8 +2,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; import { catchError, EMPTY, Observable, of } from 'rxjs'; import { IIntegrationTenant } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { IntegrationsService } from '../services'; +import { IntegrationsService, Store } from '../services'; @Injectable({ providedIn: 'root' diff --git a/packages/ui-core/core/src/lib/services/app/app-init-service.ts b/packages/ui-core/core/src/lib/services/app/app-init-service.ts index d778c172704..a827f412108 100644 --- a/packages/ui-core/core/src/lib/services/app/app-init-service.ts +++ b/packages/ui-core/core/src/lib/services/app/app-init-service.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; import { IUser } from '@gauzy/contracts'; import { Router } from '@angular/router'; -import { NgxPermissionsService } from 'ngx-permissions'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '../store/store.service'; import { PermissionsService } from '../permission/permissions.service'; import { UsersService } from '../users'; import { AuthStrategy } from '../auth/auth-strategy.service'; @@ -13,7 +12,6 @@ export class AppInitService { constructor( private readonly _router: Router, - private readonly _ngxPermissionsService: NgxPermissionsService, private readonly _store: Store, private readonly _usersService: UsersService, private readonly _authStrategy: AuthStrategy, diff --git a/packages/ui-core/core/src/lib/services/auth/auth-strategy.service.ts b/packages/ui-core/core/src/lib/services/auth/auth-strategy.service.ts index 6689c744d2b..3216f0954de 100644 --- a/packages/ui-core/core/src/lib/services/auth/auth-strategy.service.ts +++ b/packages/ui-core/core/src/lib/services/auth/auth-strategy.service.ts @@ -6,10 +6,12 @@ import { NbAuthResult, NbAuthStrategy } from '@nebular/auth'; import { NbAuthStrategyClass } from '@nebular/auth'; import { CookieService } from 'ngx-cookie-service'; import { IUser, IAuthResponse, IUserLoginInput, LanguagesEnum } from '@gauzy/contracts'; -import { Store, TimeTrackerService, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { ElectronService } from './electron.service'; import { AuthService } from './auth.service'; import { TimesheetFilterService } from '../timesheet/timesheet-filter.service'; +import { TimeTrackerService } from '../time-tracker/time-tracker.service'; +import { Store } from '../store/store.service'; @Injectable() export class AuthStrategy extends NbAuthStrategy { diff --git a/packages/ui-core/core/src/lib/services/employee/employee-appointment.service.ts b/packages/ui-core/core/src/lib/services/employee/employee-appointment.service.ts index fabdde047a7..b017270504d 100644 --- a/packages/ui-core/core/src/lib/services/employee/employee-appointment.service.ts +++ b/packages/ui-core/core/src/lib/services/employee/employee-appointment.service.ts @@ -1,64 +1,97 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { firstValueFrom } from 'rxjs'; -import { Observable } from 'rxjs'; +import { Observable, firstValueFrom } from 'rxjs'; import { + ID, IEmployeeAppointment, IEmployeeAppointmentCreateInput, IEmployeeAppointmentFindInput, IEmployeeAppointmentUpdateInput } from '@gauzy/contracts'; -import { API_PREFIX } from '@gauzy/ui-core/common'; +import { API_PREFIX, toParams } from '@gauzy/ui-core/common'; @Injectable() export class EmployeeAppointmentService { - EMPLOYEE_APPOINTMENT_URL = `${API_PREFIX}/employee-appointment`; + API_URL = `${API_PREFIX}/employee-appointment`; constructor(private http: HttpClient) {} + /** + * Get all employee appointments. + * + * @param relations + * @param findInput + * @returns + */ getAll( relations?: string[], findInput?: IEmployeeAppointmentFindInput ): Observable<{ items: IEmployeeAppointment[] }> { const data = JSON.stringify({ relations, findInput }); - return this.http.get<{ items: IEmployeeAppointment[] }>(this.EMPLOYEE_APPOINTMENT_URL, { + return this.http.get<{ items: IEmployeeAppointment[] }>(this.API_URL, { params: { data } }); } + /** + * Decode token + * + * @param token + * @returns + */ decodeToken(token: string): Promise { - return firstValueFrom( - this.http.get(this.EMPLOYEE_APPOINTMENT_URL + '/decode/' + token, { - responseType: 'text' - }) - ); + return firstValueFrom(this.http.get(this.API_URL + '/decode/' + token, { responseType: 'text' })); } - signAppointmentId(id: string): Promise { - return firstValueFrom( - this.http.get(this.EMPLOYEE_APPOINTMENT_URL + '/sign/' + id, { - responseType: 'text' - }) - ); + /** + * signAppointmentId + * + * @param id + * @returns + */ + signAppointmentId(id: ID): Promise { + return firstValueFrom(this.http.get(this.API_URL + '/sign/' + id, { responseType: 'text' })); } - getById(id: string = ''): Observable { - return this.http.get(this.EMPLOYEE_APPOINTMENT_URL + '/' + id); + /** + * Get an employee appointment by ID. + * + * @param id + * @param relations + * @returns + */ + getById(id: ID, relations: string[] = []): Observable { + return this.http.get(this.API_URL + '/' + id, { params: toParams({ relations }) }); } - create(employeeAppointment: IEmployeeAppointmentCreateInput): Promise { - return firstValueFrom( - this.http.post(`${this.EMPLOYEE_APPOINTMENT_URL}`, employeeAppointment) - ); + /** + * Create an employee appointment. + * + * @param input + * @returns + */ + create(input: IEmployeeAppointmentCreateInput): Promise { + return firstValueFrom(this.http.post(`${this.API_URL}`, input)); } - update(id: string, employeeAppointment: IEmployeeAppointmentUpdateInput): Promise { - return firstValueFrom( - this.http.put(`${this.EMPLOYEE_APPOINTMENT_URL}/${id}`, employeeAppointment) - ); + /** + * Update an employee appointment by ID. + * + * @param id + * @param input + * @returns + */ + update(id: ID, input: IEmployeeAppointmentUpdateInput): Promise { + return firstValueFrom(this.http.put(`${this.API_URL}/${id}`, input)); } - delete(id: string): Promise { - return firstValueFrom(this.http.delete(`${this.EMPLOYEE_APPOINTMENT_URL}/${id}`)); + /** + * Delete an employee appointment by ID. + * + * @param id + * @returns + */ + delete(id: ID): Promise { + return firstValueFrom(this.http.delete(`${this.API_URL}/${id}`)); } } diff --git a/packages/ui-core/core/src/lib/services/event-type/event-type.service.ts b/packages/ui-core/core/src/lib/services/event-type/event-type.service.ts index 6cb1d6fb4da..77f821568dd 100644 --- a/packages/ui-core/core/src/lib/services/event-type/event-type.service.ts +++ b/packages/ui-core/core/src/lib/services/event-type/event-type.service.ts @@ -1,42 +1,82 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { IEventType, IEventTypeFindInput, IEventTypeCreateInput, IEventTypeUpdateInput } from '@gauzy/contracts'; import { firstValueFrom } from 'rxjs'; +import { + IEventType, + IEventTypeFindInput, + IEventTypeCreateInput, + IEventTypeUpdateInput, + IPagination, + ID +} from '@gauzy/contracts'; import { API_PREFIX } from '@gauzy/ui-core/common'; @Injectable() export class EventTypeService { - EVENT_TYPE_BASE_URI = `${API_PREFIX}/event-type`; + API_BASE_URI = `${API_PREFIX}/event-type`; - constructor(private http: HttpClient) {} + constructor(private readonly http: HttpClient) {} - create(createInput: IEventTypeCreateInput): Promise { - return firstValueFrom(this.http.post(this.EVENT_TYPE_BASE_URI, createInput)); + /** + * Creates a new event type. + * + * @param input - The input data to create a new event type. + * @returns An observable of the created event type. + */ + create(input: IEventTypeCreateInput): Promise { + return firstValueFrom(this.http.post(this.API_BASE_URI, input)); } - getEventTypeById(id: string, relations?: string[]) { + /** + * Gets an event type by ID. + * + * @param id - The ID of the event type to get. + * @param relations - Optional array of relations to include in the response. + * @returns An observable of the event type. + */ + getEventTypeById(id: ID, relations?: string[]) { const data = JSON.stringify({ relations }); return firstValueFrom( - this.http.get(`${this.EVENT_TYPE_BASE_URI}/${id}`, { + this.http.get(`${this.API_BASE_URI}/${id}`, { params: { data } }) ); } - getAll(relations?: string[], findInput?: IEventTypeFindInput): Promise<{ items: IEventType[]; total: number }> { + /** + * Gets all event types. + * + * @param relations + * @param findInput + * @returns + */ + getAll(relations?: string[], findInput?: IEventTypeFindInput): Promise> { const data = JSON.stringify({ relations, findInput }); return firstValueFrom( - this.http.get<{ items: IEventType[]; total: number }>(this.EVENT_TYPE_BASE_URI, { + this.http.get>(this.API_BASE_URI, { params: { data } }) ); } - update(id: string, updateInput: IEventTypeUpdateInput): Promise { - return firstValueFrom(this.http.put(`${this.EVENT_TYPE_BASE_URI}/${id}`, updateInput)); + /** + * Updates an event type. + * + * @param id + * @param input + * @returns + */ + update(id: ID, input: IEventTypeUpdateInput): Promise { + return firstValueFrom(this.http.put(`${this.API_BASE_URI}/${id}`, input)); } - delete(id: string): Promise { - return firstValueFrom(this.http.delete(`${this.EVENT_TYPE_BASE_URI}/${id}`)); + /** + * Deletes an event type. + * + * @param id + * @returns + */ + delete(id: ID): Promise { + return firstValueFrom(this.http.delete(`${this.API_BASE_URI}/${id}`)); } } diff --git a/packages/ui-core/core/src/lib/services/index.ts b/packages/ui-core/core/src/lib/services/index.ts index 8e2d48ecd96..fa1b49b539c 100644 --- a/packages/ui-core/core/src/lib/services/index.ts +++ b/packages/ui-core/core/src/lib/services/index.ts @@ -66,3 +66,5 @@ export * from './upwork'; export * from './users'; export * from './warehouse'; export * from './page'; +export * from './store'; +export * from './time-tracker'; diff --git a/packages/ui-core/core/src/lib/services/invoice/invoices.service.ts b/packages/ui-core/core/src/lib/services/invoice/invoices.service.ts index d9fd165e16e..1a7d2ae7e48 100644 --- a/packages/ui-core/core/src/lib/services/invoice/invoices.service.ts +++ b/packages/ui-core/core/src/lib/services/invoice/invoices.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { + ID, IEstimateEmail, IInvoice, IInvoiceCreateInput, @@ -26,7 +27,7 @@ export class InvoicesService { ); } - getHighestInvoiceNumber(tenantId: string): Promise { + getHighestInvoiceNumber(tenantId: ID): Promise { return firstValueFrom( this.http.get(`${API_PREFIX}/invoices/highest`, { params: toParams({ tenantId }) @@ -34,7 +35,7 @@ export class InvoicesService { ); } - getById(id: string, relations?: string[], findInput?: IInvoiceFindInput) { + getById(id: ID, relations?: string[], findInput?: IInvoiceFindInput) { const data = JSON.stringify({ relations, findInput }); return firstValueFrom( this.http.get(`${API_PREFIX}/invoices/${id}`, { @@ -43,7 +44,7 @@ export class InvoicesService { ); } - getPublicInvoice(id: string, token: string, relations: string[] = []) { + getPublicInvoice(id: ID, token: string, relations: string[] = []) { return firstValueFrom( this.http.get(`${API_PREFIX}/public/invoice/${id}/${token}`, { params: toParams({ relations }) @@ -55,23 +56,19 @@ export class InvoicesService { return firstValueFrom(this.http.post(`${API_PREFIX}/invoices`, invoice)); } - update(id: string, updateInput: IInvoiceUpdateInput): Promise { + update(id: ID, updateInput: IInvoiceUpdateInput): Promise { return firstValueFrom(this.http.put(`${API_PREFIX}/invoices/${id}`, updateInput)); } - updateEstimate(id: string, updateInput: IInvoiceUpdateInput): Promise { + updateEstimate(id: ID, updateInput: IInvoiceUpdateInput): Promise { return firstValueFrom(this.http.put(`${API_PREFIX}/invoices/${id}/estimate`, updateInput)); } - updateAction(id: string, updateInput: IInvoiceUpdateInput): Promise { + updateAction(id: ID, updateInput: IInvoiceUpdateInput): Promise { return firstValueFrom(this.http.put(`${API_PREFIX}/invoices/${id}/action`, updateInput)); } - updateWithoutAuth( - id: IInvoice['id'], - token: IEstimateEmail['token'], - input: IInvoiceUpdateInput - ): Promise { + updateWithoutAuth(id: ID, token: IEstimateEmail['token'], input: IInvoiceUpdateInput): Promise { return firstValueFrom(this.http.put(`${API_PREFIX}/public/invoice/${id}/${token}`, input)); } @@ -79,21 +76,21 @@ export class InvoicesService { return firstValueFrom(this.http.put(`${API_PREFIX}/invoices/${invoice.id}`, invoice)); } - generateLink(id: string): Promise { + generateLink(id: ID): Promise { return firstValueFrom(this.http.put(`${API_PREFIX}/invoices/generate/${id}`, {})); } - delete(id: string): Promise { + delete(id: ID): Promise { return firstValueFrom(this.http.delete(`${API_PREFIX}/invoices/${id}`)); } sendEmail( email: string, invoiceNumber: number, - invoiceId: string, + invoiceId: ID, isEstimate: boolean, - organizationId: string, - tenantId: string + organizationId: ID, + tenantId: ID ): Promise { return firstValueFrom( this.http.put(`${API_PREFIX}/invoices/email/${email}`, { @@ -112,13 +109,13 @@ export class InvoicesService { this.source.next(message); } - downloadInvoicePdf(invoiceId: string) { + downloadInvoicePdf(invoiceId: ID) { return this.http.get(`${API_PREFIX}/invoices/download/${invoiceId}`, { responseType: 'blob' }); } - downloadInvoicePaymentPdf(invoiceId: string) { + downloadInvoicePaymentPdf(invoiceId: ID) { return this.http.get(`${API_PREFIX}/invoices/payment/download/${invoiceId}`, { responseType: 'blob' }); diff --git a/packages/ui-core/core/src/lib/services/language/languages.service.ts b/packages/ui-core/core/src/lib/services/language/languages.service.ts index 171ad1e5940..74b7f7329c7 100644 --- a/packages/ui-core/core/src/lib/services/language/languages.service.ts +++ b/packages/ui-core/core/src/lib/services/language/languages.service.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { firstValueFrom } from 'rxjs'; -import { ILanguage } from '@gauzy/contracts'; -import { toParams } from '@gauzy/ui-core/common'; -import { API_PREFIX } from '@gauzy/ui-core/common'; +import { ID, ILanguage } from '@gauzy/contracts'; +import { API_PREFIX, toParams } from '@gauzy/ui-core/common'; @Injectable() export class LanguagesService { @@ -25,11 +24,11 @@ export class LanguagesService { ); } - delete(id: string): Promise { + delete(id: ID): Promise { return firstValueFrom(this.http.delete(`${API_PREFIX}/languages/${id}`)); } - update(id: string, updateInput: ILanguage) { + update(id: ID, updateInput: ILanguage) { return firstValueFrom(this.http.put(`${API_PREFIX}/languages/${id}`, updateInput)); } diff --git a/packages/ui-core/core/src/lib/services/navigation-builder/navigation-builder.service.ts b/packages/ui-core/core/src/lib/services/navigation-builder/navigation-builder.service.ts index 588bedf2494..278ca942b2e 100644 --- a/packages/ui-core/core/src/lib/services/navigation-builder/navigation-builder.service.ts +++ b/packages/ui-core/core/src/lib/services/navigation-builder/navigation-builder.service.ts @@ -1,7 +1,8 @@ import { Injectable, Type } from '@angular/core'; import { Observable, of as ObservableOf } from 'rxjs'; import { UntilDestroy } from '@ngneat/until-destroy'; -import { isEmpty, Store } from '@gauzy/ui-core/common'; +import { isEmpty } from '@gauzy/ui-core/common'; +import { Store } from '../store/store.service'; export interface ISidebarActionConfig { id: string; diff --git a/packages/ui-core/core/src/lib/services/organization/organization-setting.service.ts b/packages/ui-core/core/src/lib/services/organization/organization-setting.service.ts index 8e7122ea37c..562f419f7e9 100644 --- a/packages/ui-core/core/src/lib/services/organization/organization-setting.service.ts +++ b/packages/ui-core/core/src/lib/services/organization/organization-setting.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; import * as moment from 'moment'; import { DefaultValueDateTypeEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; import { DateRangePickerBuilderService } from '../selector-builder'; +import { Store } from '../store/store.service'; @Injectable({ providedIn: 'root' diff --git a/packages/ui-core/core/src/lib/services/page/data-table/page-data-table-registry.service.ts b/packages/ui-core/core/src/lib/services/page/data-table/page-data-table-registry.service.ts new file mode 100644 index 00000000000..0cd06dd561b --- /dev/null +++ b/packages/ui-core/core/src/lib/services/page/data-table/page-data-table-registry.service.ts @@ -0,0 +1,155 @@ +import { Injectable } from '@angular/core'; +import { Cell, IColumn, IColumns } from 'angular2-smart-table'; +import { I18nService } from '@gauzy/ui-core/i18n'; +import { PageLocationRegistryId } from '../../../common/component-registry.types'; +import { IPageDataTableRegistry, PageDataTableRegistryConfig } from './page-data-table-registry.types'; + +@Injectable({ + providedIn: 'root' +}) +export class PageDataTableRegistryService implements IPageDataTableRegistry { + /** + * Registry for storing page data table column configurations. + * + * This Map stores arrays of PageDataTableRegistryConfig objects, keyed by PageLocationRegistryId. + */ + private readonly registry = new Map(); + + constructor(readonly _i18nService: I18nService) {} + + /** + * Register a column configurations. + * + * This method registers a new column configuration in the service's internal registry. + * It ensures that each configuration has a valid location property and checks if a column with the same + * location and id already exists to prevent duplicate entries. If the configurations are valid and unique, + * it adds them to the registry. + * + * @param config The configuration for the column. + * @throws Will throw an error if a column with the same location and id has already been registered. + */ + public registerPageDataTableColumn(config: PageDataTableRegistryConfig): void { + if (!config.location) { + throw new Error('Page data table column configuration must have a location property'); + } + + // Set the isTranslatable flag to false by default + config.isTranslatable = config.isTranslatable ?? true; + + // Get all registered columns for the specified location + const columns = this.registry.get(config.location) || []; + + // Find the index of the column with the same location and columnId + const existing = columns.findIndex( + (route: PageDataTableRegistryConfig) => + route.location === config.location && route.columnId === config.columnId + ); + + if (existing !== -1) { + // Replace the existing column with the new one + columns[existing] = config; + } else { + // Add the new column configuration to the list + columns.push(config); + } + + // Update the registry with the new list of columns for the specified location + this.registry.set(config.location, columns); + } + + /** + * Register multiple column configurations. + * + * This method registers multiple new column configurations in the service's internal registry. + * It ensures that each configuration has a valid location property and checks if a column with the same + * location and id already exists to prevent duplicate entries. If the configurations are valid and unique, + * it adds them to the registry. + * + * @param configs The array of configurations for the columns. + * @throws Will throw an error if a column with the same location and id has already been registered. + */ + public registerPageDataTableColumns(configs: PageDataTableRegistryConfig[]): void { + configs.forEach((config) => this.registerPageDataTableColumn(config)); + } + + /** + * Retrieves the data table column configurations associated with a specific registry ID. + * + * This method fetches an array of `PageDataTableRegistryConfig` objects that are associated with the provided + * `PageLocationRegistryId`. If any configurations are found, they are sorted based on their `order` property in + * ascending order. If no configurations are found, an empty array is returned. + * + * @param location - The identifier used to look up the data table column configurations. + * @returns An array of `PageDataTableRegistryConfig` objects sorted by the `order` property, or an empty array if none are found. + */ + private getDataTableColumnsByOrder(location: PageLocationRegistryId): PageDataTableRegistryConfig[] { + return this.registry.get(location)?.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) || []; + } + + /** + * Retrieves a list of unique columns for a specific page location, based on the provided location. + * + * This method fetches all registered data table columns for the specified `PageLocationRegistryId`, + * removes any duplicate columns based on their location and ID, and maps the remaining configurations + * to an array of `IColumn` objects. + * + * The uniqueness of each column is determined by the combination of its location and ID. If a duplicate + * column is found (i.e., one with the same location and ID as another), it is filtered out. The resulting + * list of columns is returned. + * + * @param registryId - The identifier used to look up the data table column configurations for a specific page location. + * @returns An array of `IColumn` objects representing the unique columns for the specified page location. + */ + public getPageDataTableColumns(location: PageLocationRegistryId): IColumns { + // Get all registered columns for the specified location + let columns = this.getDataTableColumnsByOrder(location); + + // Use a Set to track unique location-id combinations + const locationIds = new Set(); + + // Filter the configurations to remove duplicates based on the unique identifier + columns = columns.filter((config: PageDataTableRegistryConfig) => { + // Create a unique identifier for the combination of location and id + const identifier = `${config.location}-${config.columnId}`; + + // Check if the unique identifier is already in the Set + if (locationIds.has(identifier)) { + return false; // Duplicate found, filter it out + } + + // Add the unique identifier to the Set + locationIds.add(identifier); + return true; // Not a duplicate, keep it + }); + + // Map each unique configuration to an IColumn object + return columns.reduce((acc: IColumns, config: PageDataTableRegistryConfig) => { + // Create and return a new IColumn object + const column: IColumn = { + title: config.isTranslatable ? this._i18nService.getTranslation(config.title) : config.title, + type: config.type, + width: config.width, + isSortable: config.isSortable ?? false, + isEditable: config.isEditable ?? false, + ...(config.editor && { editor: config.editor }), + ...(config.renderComponent && { renderComponent: config.renderComponent }), + ...(config.valuePrepareFunction && { + valuePrepareFunction: (rawValue: any, cell: Cell) => config.valuePrepareFunction(rawValue, cell) + }), + ...(config.componentInitFunction && { + componentInitFunction: (component: any, cell: Cell) => config.componentInitFunction(component, cell) + }) + }; + + // Check if the column configuration has additional column options + if (config.column) { + Object.assign(column, config.column); + } + + // Add the column configuration to the accumulator object with the columnId as the key + acc[config.columnId] = column; + + return acc; + }, {}); + } +} diff --git a/packages/ui-core/core/src/lib/services/page/data-table/page-data-table-registry.types.ts b/packages/ui-core/core/src/lib/services/page/data-table/page-data-table-registry.types.ts new file mode 100644 index 00000000000..a551b1c3e79 --- /dev/null +++ b/packages/ui-core/core/src/lib/services/page/data-table/page-data-table-registry.types.ts @@ -0,0 +1,46 @@ +import { IColumn } from 'angular2-smart-table'; +import { PageLocationRegistryId } from '../../../common/component-registry.types'; + +/** + * Page route configuration with additional table columns options. + */ +export interface PageDataTableRegistryConfig extends IColumn { + /** + * @description + * The location identifier for the page route. + */ + location: PageLocationRegistryId; + + /** + * @description + * The translatable key for the column title. + */ + isTranslatable?: boolean; + + /** + * @description + * The column identifier for the column. This is used to identify the column in the table for specific page location. + */ + columnId: string; + + /** + * @description + * The order of the column in the table. + * If not provided, the column will be added to the end of the table. + */ + order?: number; + + /** + * @description + * The column configuration for the column. This is used to override the default column configuration. + */ + column?: IColumn; +} + +/** + * Registry for page data table columns. + */ +export interface IPageDataTableRegistry { + registerPageDataTableColumn(config: PageDataTableRegistryConfig): void; // Register a column configuration. + registerPageDataTableColumns(configs: PageDataTableRegistryConfig[]): void; // Register multiple column configurations. +} diff --git a/packages/ui-core/core/src/lib/services/page/index.ts b/packages/ui-core/core/src/lib/services/page/index.ts index 53cc3ee2a49..cf6909867eb 100644 --- a/packages/ui-core/core/src/lib/services/page/index.ts +++ b/packages/ui-core/core/src/lib/services/page/index.ts @@ -1,2 +1,6 @@ -export * from './page-route.service'; -export * from './page-route.types'; +export * from './data-table/page-data-table-registry.service'; +export * from './data-table/page-data-table-registry.types'; +export * from './page-route-registry.service'; +export * from './page-route-registry.types'; +export * from './page-tab-registry.service'; +export * from './page-tab-registry.types'; diff --git a/packages/ui-core/core/src/lib/services/page/page-route.service.ts b/packages/ui-core/core/src/lib/services/page/page-route-registry.service.ts similarity index 75% rename from packages/ui-core/core/src/lib/services/page/page-route.service.ts rename to packages/ui-core/core/src/lib/services/page/page-route-registry.service.ts index 45570d3df6c..9ee53aa5624 100644 --- a/packages/ui-core/core/src/lib/services/page/page-route.service.ts +++ b/packages/ui-core/core/src/lib/services/page/page-route-registry.service.ts @@ -1,18 +1,18 @@ import { Injectable } from '@angular/core'; import { Route } from '@angular/router'; -import { PageRouteConfig } from './page-route.types'; -import { PageRouteLocationId } from '../../common/component-registry-types'; +import { PageLocationRegistryId } from '../../common/component-registry.types'; +import { IPageRouteRegistry, PageRouteRegistryConfig } from './page-route-registry.types'; @Injectable({ providedIn: 'root' }) -export class PageRouteService { +export class PageRouteRegistryService implements IPageRouteRegistry { /** * Registry for storing page route configurations. * - * This Map stores arrays of PageRouteConfig objects, keyed by PageRouteLocationId. + * This Map stores arrays of PageRouteRegistryConfig objects, keyed by PageLocationRegistryId. */ - private readonly registry = new Map(); + private readonly registry = new Map(); /** * Register a single page route configuration. @@ -26,7 +26,7 @@ export class PageRouteService { * @throws Will throw an error if the configuration does not have a location property. * @throws Will throw an error if a route with the same location has already been registered. */ - registerPageRoute(config: PageRouteConfig): void { + registerPageRoute(config: PageRouteRegistryConfig): void { // Check if the configuration has a location property if (!config.location) { throw new Error('Page route configuration must have a location property'); @@ -37,7 +37,7 @@ export class PageRouteService { // Check if a route with the same location and path already exists const isMatchingRoute = routes.some( - (route: PageRouteConfig) => route.location === config.location && route.path === config.path + (route: PageRouteRegistryConfig) => route.location === config.location && route.path === config.path ); // Check if a route with the same location already exists @@ -65,7 +65,7 @@ export class PageRouteService { * @param configs The array of configurations for the page routes. * @throws Will throw an error if a route with the same location and path has already been registered. */ - registerPageRoutes(configs: PageRouteConfig[]): void { + registerPageRoutes(configs: PageRouteRegistryConfig[]): void { configs.forEach((config) => this.registerPageRoute(config)); } @@ -78,7 +78,7 @@ export class PageRouteService { * @param location The page location identifier. * @returns The array of registered routes for the specified location. */ - getPageLocationRoutes(location: PageRouteLocationId): Route[] { + getPageLocationRoutes(location: PageLocationRegistryId): Route[] { // Get all registered routes for the specified location let configs = this.registry.get(location) || []; @@ -86,7 +86,7 @@ export class PageRouteService { const locationPaths = new Set(); // Create a unique identifier for the combination of location and path - configs = configs.filter((config: PageRouteConfig) => { + configs = configs.filter((config: PageRouteRegistryConfig) => { // Create a unique identifier for the combination of location and path const identifier = `${config.location}-${config.path}`; @@ -101,13 +101,13 @@ export class PageRouteService { }); // Map each route configuration to a route object - return configs.map((config: PageRouteConfig) => { + return configs.map((config: PageRouteRegistryConfig) => { // Create a new route object const route: Route = { - path: config.path, - pathMatch: config.path ? 'prefix' : 'full', - data: config.data || {}, - canActivate: config.canActivate || [] + path: config.path, // Add path property + pathMatch: config.path ? 'prefix' : 'full', // Set pathMatch property + data: config.data || {}, // Add data property if it exists + canActivate: config.canActivate || [] // Add canActivate property if it exists }; // Check if the route configuration has a component or loadChildren property @@ -119,6 +119,12 @@ export class PageRouteService { route.loadChildren = config.loadChildren; } + // Check if the route configuration has a resolve property + if (config.resolve) { + // Set the resolve property to the config object + route.resolve = config.resolve; + } + // Check if the route configuration has additional route options if (config.route) { Object.assign(route, config.route); diff --git a/packages/ui-core/core/src/lib/services/page/page-route.types.ts b/packages/ui-core/core/src/lib/services/page/page-route-registry.types.ts similarity index 56% rename from packages/ui-core/core/src/lib/services/page/page-route.types.ts rename to packages/ui-core/core/src/lib/services/page/page-route-registry.types.ts index 11af826387a..fd2265628ae 100644 --- a/packages/ui-core/core/src/lib/services/page/page-route.types.ts +++ b/packages/ui-core/core/src/lib/services/page/page-route-registry.types.ts @@ -1,15 +1,15 @@ import { Type } from '@angular/core'; import { Route } from '@angular/router'; -import { PageRouteLocationId } from '../../common/component-registry-types'; +import { PageLocationRegistryId } from '../../common/component-registry.types'; /** * Page route configuration with additional route options. */ -export interface PageRouteConfig extends Route { +export interface PageRouteRegistryConfig extends Route { /** * The location identifier for the page route. */ - location: PageRouteLocationId; + location: PageLocationRegistryId; /** * The path to navigate to when the page is selected. @@ -32,3 +32,11 @@ export interface PageRouteConfig extends Route { */ route?: Route; } + +/** + * Page registry service interface. + */ +export interface IPageRouteRegistry { + registerPageRoute(config: PageRouteRegistryConfig): void; // Register a single page route configuration. + registerPageRoutes(configs: PageRouteRegistryConfig[]): void; // Register multiple page route configurations. +} diff --git a/packages/ui-core/core/src/lib/services/page/page-tab-registry.service.ts b/packages/ui-core/core/src/lib/services/page/page-tab-registry.service.ts new file mode 100644 index 00000000000..fead8566e5a --- /dev/null +++ b/packages/ui-core/core/src/lib/services/page/page-tab-registry.service.ts @@ -0,0 +1,229 @@ +import { Injectable, Type } from '@angular/core'; +import { TabsetRegistryId } from '../../common/component-registry.types'; +import { IPageTabRegistry, PageTabRegistryConfig } from './page-tab-registry.types'; + +@Injectable({ + providedIn: 'root' +}) +export class PageTabRegistryService implements IPageTabRegistry { + /** + * Registry for storing page tab configurations. + * + * This Map stores arrays of PageTabRegistryConfig objects, keyed by TabsetRegistryId. + */ + private readonly registry = new Map(); + + /** + * Retrieves the current tab registry. + * + * This method returns the internal map that stores the page tab configurations, + * keyed by their tabset identifiers. + * + * @returns A Map where the keys are tabset identifiers and the values are arrays + * of page tab configurations associated with each tabset. + */ + public getRegistry(): Map { + return this.registry; + } + + /** + * Register a single page tab configuration. + * + * This method registers a new page tab configuration in the service's internal registry. + * It ensures that the configuration has a valid tabset property and checks if a tab + * with the same tabsetId already exists to prevent duplicate entries. If the configuration + * is valid and unique, it adds it to the registry. + * + * @param config The configuration for the page tab. + * @throws Will throw an error if the configuration does not have a location property. + * @throws Will throw an error if a tab with the same location has already been registered. + */ + public registerPageTab(config: PageTabRegistryConfig): void { + // Check if the configuration has a location property + if (!config.tabsetId) { + throw new Error('Page tab configuration must have a tabsetId property'); + } + + // Call addPageTab to handle the addition or update of the tab + this.addPageTab(config, config.tabsetId); + } + + /** + * Adds a new page tab to the specified tab set. + * + * @param config The configuration object representing the new tab to add. + * @param tabsetId The identifier of the tab set to which the new tab should be added. + */ + public addPageTab(config: PageTabRegistryConfig, tabsetId: TabsetRegistryId): void { + // Check if the configuration has a location property + if (!config.tabsetId) { + throw new Error('Page tab configuration must have a tabsetId property'); + } + + // Get the list of tabs for the specified tab set from the registry, or initialize as an empty array if not found + const tabs = this.registry.get(tabsetId) || []; + + // Ensure config is defined before accessing its properties + config.order = config.order ?? 0; // Set the default order to 0 if not provided + config.hide = config.hide ?? false; // Set the default hide to false if not provided + config.responsive = config.responsive ?? true; // Set the default responsive to true if not provided + + // Find the index of an existing tab with the same tabId in the specified tab set + const existing = tabs.findIndex((tab) => tab.tabId === config.tabId); + + if (existing !== -1) { + // If the tab exists, replace it with the new configuration + tabs[existing] = config; + } else { + // If the tab does not exist, add the new tab configuration to the list + tabs.push(config); + } + + // Update the registry with the modified list of tabs for the specified tabset + this.registry.set(tabsetId, tabs); + } + + /** + * Removes a page tab from the specified tab set. + * + * This method retrieves the list of tabs associated with the provided `tabsetId`, + * finds the tab with the specified `tabId`, removes it from the list, and updates + * the registry. If the tabset becomes empty after removal, it also removes the tabset + * entry from the registry. + * + * @param tabsetId The identifier of the tab set from which the tab should be removed. + * @param tabId The identifier of the tab to remove. + */ + public removePageTab(tabsetId: TabsetRegistryId, tabId: string): void { + // Retrieve the list of tabs for the specified tabset, or initialize as an empty array if not found + const tabs = this.registry.get(tabsetId) || []; + + // Find the index of the tab with the specified tabId + const index = tabs.findIndex((tab) => tab.tabId === tabId); + + // If the tab exists in the list, remove it + if (index !== -1) { + // Remove the tab from the list + tabs.splice(index, 1); + + // Update the registry with the modified list of tabs + if (tabs.length > 0) { + this.registry.set(tabsetId, tabs); + } else { + // Remove the tabset entry from the registry if no tabs are left + this.registry.delete(tabsetId); + } + } + } + + /** + * Register multiple page tab configurations. + * + * This method registers multiple new page tab configurations in the service's internal registry. + * It ensures that each configuration has a valid tabset property and checks if a tab with the same + * tabsetId already exists to prevent duplicate entries. If the configurations are valid and unique, + * it adds them to the registry. + * + * @param configs The array of configurations for the page tabs. + * @throws Will throw an error if a tab with the same location and path has already been registered. + */ + public registerPageTabs(configs: PageTabRegistryConfig[]): void { + configs.forEach((config: PageTabRegistryConfig) => this.registerPageTab(config)); + } + + /** + * Get all page tabs for a specified tabset, sorted by their order. + * + * This method retrieves the registered tabs for a given `tabsetId` from the registry, + * sorts them based on their `order` property, and returns the sorted array. + * If no tabs are registered for the specified `tabsetId`, it returns an empty array. + * + * @param tabsetId The identifier for the tabset. + * @returns An array of `PageTabRegistryConfig` objects, sorted by their `order` property. + */ + private getPageTabsByOrder(tabsetId: TabsetRegistryId): PageTabRegistryConfig[] { + // Retrieve the tabs for the specified tabsetId from the registry + const tabs = this.registry.get(tabsetId) || []; + + // If tabs exist, sort them by the 'order' property; otherwise, return an empty array + return tabs?.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) || []; + } + + /** + * Retrieves all unique page tabs for a specified tabset. + * + * This method first retrieves all the tabs associated with the given `tabsetId`, then + * ensures that each tab is unique based on its `tabId` by using a `Map`. Finally, it returns + * an array of these unique tabs. + * + * @param tabsetId The identifier for the tabset whose tabs are to be retrieved. + * @returns An array of unique page tabs for the specified tabset. + */ + public getPageTabset(tabsetId: TabsetRegistryId): PageTabRegistryConfig[] { + // Get all registered tabs for the specified tabset, ordered as required + const tabs = this.getPageTabsByOrder(tabsetId); + + // Create a map to track unique tabs based on tabId + const uniqueTabsMap = new Map(); + + // Iterate through tabs and add them to the map if not already present + tabs.forEach((tab) => { + // Ensure only unique tabs are added + uniqueTabsMap.set(tab.tabId, tab); + }); + + // Convert the map values to an array and return + return Array.from(uniqueTabsMap.values()); + } + + /** + * @description + * Deletes a tabset from the registry. + * + * This method removes a tabset identified by the provided `tabsetId` from the internal registry. + * If the specified `tabsetId` does not exist in the registry, the function will simply return + * without making any changes. + * + * @param tabsetId The identifier for the tabset to delete. + */ + public deleteTabset(tabsetId: TabsetRegistryId): void { + // Check if the tabset exists in the registry + if (!this.registry.has(tabsetId)) { + console.warn(`Tabset with id "${tabsetId}" does not exist in the registry.`); + return; + } + + // Remove the tabset from the registry + this.registry.delete(tabsetId); + console.log(`Tabset with id "${tabsetId}" has been successfully removed from the registry.`); + } + + /** + * @description + * Retrieves the component associated with a specific tab ID for a given tabset. + * + * This method looks up the tabset using the provided `tabsetId`, then searches for the tab + * with the specified `tabId` within that tabset. If the tab is found, it returns the associated + * component; otherwise, it returns `undefined`. + * + * @param tabsetId The identifier of the tabset to retrieve tabs from. + * @param tabId The identifier of the tab whose component is to be retrieved. + * @returns The component associated with the specified tab ID, or `undefined` if the tab or component is not found. + */ + public getComponentForTab(tabsetId: TabsetRegistryId, tabId: string): Type | undefined { + // Retrieve the list of tabs for the specified tabsetId + const tabs = this.getPageTabset(tabsetId); + + // Ensure that tabs is an array and check if the tab exists + if (Array.isArray(tabs)) { + // Find the tab with the specified tabId + const tab = tabs.find((t) => t.tabId === tabId); + + // Return the component associated with the tab ID or undefined if not found + return tab?.component; + } + + // Return undefined if the tabs could not be retrieved or are not an array + return undefined; + } +} diff --git a/packages/ui-core/core/src/lib/services/page/page-tab-registry.types.ts b/packages/ui-core/core/src/lib/services/page/page-tab-registry.types.ts new file mode 100644 index 00000000000..6f8a59fe55b --- /dev/null +++ b/packages/ui-core/core/src/lib/services/page/page-tab-registry.types.ts @@ -0,0 +1,72 @@ +import { Type } from '@angular/core'; +import { NbRouteTab } from '@nebular/theme'; +import { TabsetRegistryId } from '../../common/component-registry.types'; + +/** + * Page tab configuration options. + */ +export interface PageTabRegistryConfig extends NbRouteTab { + /** + * @description + * The tabset identifier for the page tabset. + */ + tabsetId: TabsetRegistryId; + + /** + * @description + * The identifier for the tab. + */ + tabId: string; + + /** + * @description + * The translatable key for the tab title. + */ + tabTitle: string | (() => string); + + /** + * @description + * The icon name or icon configuration for the tab. + */ + tabIcon?: string; + + /** + * @description + * The component to be loaded in the tab. This can be a component reference or a string identifier + * for lazy loading the component. + */ + component?: Type; + + /** + * @description + * The order of the tab in the tabs bar. + * If not provided, the tab will be added to the end of the tabs bar. + */ + order?: number; + + /** + * @description + * Type of tabset to use. Can be 'route' for NbRouteTabsetComponent or 'standard' for NbTabsetComponent. + */ + tabsetType: 'route' | 'standard'; + + /** + * @description + * Specifies if the tab is active. + */ + active?: boolean; + + /** + * @description + * Specifies if the tab is hidden for any reason. + */ + hide?: boolean; +} + +/** + * Page registry service interface. + */ +export interface IPageTabRegistry { + registerPageTab(config: PageTabRegistryConfig): void; // Register a single page tab configuration. + registerPageTabs(configs: PageTabRegistryConfig[]): void; // Register multiple page tab configurations. +} diff --git a/packages/ui-core/core/src/lib/services/permission/permissions.service.ts b/packages/ui-core/core/src/lib/services/permission/permissions.service.ts index dd3768fc17c..19274fd1f0b 100644 --- a/packages/ui-core/core/src/lib/services/permission/permissions.service.ts +++ b/packages/ui-core/core/src/lib/services/permission/permissions.service.ts @@ -4,7 +4,8 @@ import { HttpClient } from '@angular/common/http'; import { NgxPermissionsService } from 'ngx-permissions'; import { firstValueFrom } from 'rxjs'; import { IPagination, IRolePermission } from '@gauzy/contracts'; -import { API_PREFIX, Store } from '@gauzy/ui-core/common'; +import { API_PREFIX } from '@gauzy/ui-core/common'; +import { Store } from '../store/store.service'; @Injectable({ providedIn: 'root' diff --git a/packages/ui-core/core/src/lib/services/proposal/proposals.service.ts b/packages/ui-core/core/src/lib/services/proposal/proposals.service.ts index 83308335862..3b5ce599e11 100644 --- a/packages/ui-core/core/src/lib/services/proposal/proposals.service.ts +++ b/packages/ui-core/core/src/lib/services/proposal/proposals.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { firstValueFrom } from 'rxjs'; -import { IPagination, IProposal, IProposalCreateInput, IProposalFindInput, IProposalViewModel } from '@gauzy/contracts'; +import { Observable, firstValueFrom } from 'rxjs'; +import { ID, IPagination, IProposal, IProposalCreateInput, IProposalFindInput } from '@gauzy/contracts'; import { toParams } from '@gauzy/ui-core/common'; import { API_PREFIX } from '@gauzy/ui-core/common'; @@ -11,18 +11,13 @@ import { API_PREFIX } from '@gauzy/ui-core/common'; export class ProposalsService { constructor(private readonly http: HttpClient) {} - create(createInput: IProposalCreateInput): Promise { - return firstValueFrom(this.http.post(`${API_PREFIX}/proposal`, createInput)); - } - - update(id: string, updateInput: IProposalCreateInput): Promise { - return firstValueFrom(this.http.put(`${API_PREFIX}/proposal/${id}`, updateInput)); - } - - delete(id: string): Promise { - return firstValueFrom(this.http.delete(`${API_PREFIX}/proposal/${id}`)); - } - + /** + * Retrieves all proposals with optional filtering by relations and conditions. + * + * @param relations - An array of strings specifying the related entities to include in the results. + * @param where - An optional object specifying the conditions to filter the proposals. + * @returns A promise that resolves to an object containing a list of proposals and pagination details. + */ getAll(relations: string[] = [], where?: IProposalFindInput): Promise> { return firstValueFrom( this.http.get>(`${API_PREFIX}/proposal`, { @@ -31,8 +26,46 @@ export class ProposalsService { ); } - getById(id: string, relations?: string[]) { - return this.http.get(`${API_PREFIX}/proposal/${id}`, { + /** + * Creates a new proposal with the given input data. + * + * @param input - The data required to create a new proposal, conforming to the IProposalCreateInput interface. + * @returns A promise that resolves to the newly created proposal. + */ + create(input: IProposalCreateInput): Promise { + return firstValueFrom(this.http.post(`${API_PREFIX}/proposal`, input)); + } + + /** + * Updates an existing proposal with the given ID using the provided input data. + * + * @param id - The unique identifier of the proposal to update. + * @param input - The data to update the proposal with, conforming to the IProposalCreateInput interface. + * @returns A promise that resolves to the updated proposal. + */ + update(id: ID, input: IProposalCreateInput): Promise { + return firstValueFrom(this.http.put(`${API_PREFIX}/proposal/${id}`, input)); + } + + /** + * Deletes a proposal with the given ID. + * + * @param id - The unique identifier of the proposal to delete. + * @returns A promise that resolves to the deleted proposal. + */ + delete(id: ID): Promise { + return firstValueFrom(this.http.delete(`${API_PREFIX}/proposal/${id}`)); + } + + /** + * Retrieves a proposal by its unique ID, with optional inclusion of related entities. + * + * @param id - The unique identifier of the proposal to retrieve. + * @param relations - An array of strings specifying the related entities to include in the result. + * @returns An observable that emits the retrieved proposal, enriched with the specified relations. + */ + getById(id: ID, relations: string[] = []): Observable { + return this.http.get(`${API_PREFIX}/proposal/${id}`, { params: toParams({ relations }) }); } diff --git a/packages/ui-core/core/src/lib/services/server-connection/server-connection.service.ts b/packages/ui-core/core/src/lib/services/server-connection/server-connection.service.ts index b18dc88d5b6..d0969337bb3 100644 --- a/packages/ui-core/core/src/lib/services/server-connection/server-connection.service.ts +++ b/packages/ui-core/core/src/lib/services/server-connection/server-connection.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '../store/store.service'; @Injectable() export class ServerConnectionService { diff --git a/packages/ui-core/common/src/lib/providers/services/store/index.ts b/packages/ui-core/core/src/lib/services/store/index.ts similarity index 100% rename from packages/ui-core/common/src/lib/providers/services/store/index.ts rename to packages/ui-core/core/src/lib/services/store/index.ts diff --git a/packages/ui-core/common/src/lib/providers/services/store/store.service.ts b/packages/ui-core/core/src/lib/services/store/store.service.ts similarity index 99% rename from packages/ui-core/common/src/lib/providers/services/store/store.service.ts rename to packages/ui-core/core/src/lib/services/store/store.service.ts index 18914f079f5..ad2233ca4ac 100644 --- a/packages/ui-core/common/src/lib/providers/services/store/store.service.ts +++ b/packages/ui-core/core/src/lib/services/store/store.service.ts @@ -19,8 +19,7 @@ import { ComponentLayoutStyleEnum, IOrganizationTeam } from '@gauzy/contracts'; -import { GuiDrag } from '../../../interfaces'; -import { ComponentEnum, SYSTEM_DEFAULT_LAYOUT } from '../../../constants'; +import { ComponentEnum, GuiDrag, SYSTEM_DEFAULT_LAYOUT } from '@gauzy/ui-core/common'; export interface AppState { user: IUser; diff --git a/packages/ui-core/common/src/lib/providers/services/time-tracker/index.ts b/packages/ui-core/core/src/lib/services/time-tracker/index.ts similarity index 100% rename from packages/ui-core/common/src/lib/providers/services/time-tracker/index.ts rename to packages/ui-core/core/src/lib/services/time-tracker/index.ts diff --git a/packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/index.ts b/packages/ui-core/core/src/lib/services/time-tracker/interfaces/index.ts similarity index 100% rename from packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/index.ts rename to packages/ui-core/core/src/lib/services/time-tracker/interfaces/index.ts diff --git a/packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/itimer-icon.ts b/packages/ui-core/core/src/lib/services/time-tracker/interfaces/itimer-icon.ts similarity index 100% rename from packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/itimer-icon.ts rename to packages/ui-core/core/src/lib/services/time-tracker/interfaces/itimer-icon.ts diff --git a/packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/itimer-synced.ts b/packages/ui-core/core/src/lib/services/time-tracker/interfaces/itimer-synced.ts similarity index 100% rename from packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/itimer-synced.ts rename to packages/ui-core/core/src/lib/services/time-tracker/interfaces/itimer-synced.ts diff --git a/packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/timer-icon.ts b/packages/ui-core/core/src/lib/services/time-tracker/interfaces/timer-icon.ts similarity index 100% rename from packages/ui-core/common/src/lib/providers/services/time-tracker/interfaces/timer-icon.ts rename to packages/ui-core/core/src/lib/services/time-tracker/interfaces/timer-icon.ts diff --git a/packages/ui-core/common/src/lib/providers/services/time-tracker/time-tracker.service.ts b/packages/ui-core/core/src/lib/services/time-tracker/time-tracker.service.ts similarity index 98% rename from packages/ui-core/common/src/lib/providers/services/time-tracker/time-tracker.service.ts rename to packages/ui-core/core/src/lib/services/time-tracker/time-tracker.service.ts index 6ae77fe396d..ed1bfbfe0b3 100644 --- a/packages/ui-core/common/src/lib/providers/services/time-tracker/time-tracker.service.ts +++ b/packages/ui-core/core/src/lib/services/time-tracker/time-tracker.service.ts @@ -17,10 +17,10 @@ import { TimeLogSourceEnum, ITimerStatusInput } from '@gauzy/contracts'; +import { toLocal, toParams, toUTC } from '@gauzy/ui-core/common'; +import { API_PREFIX, BACKGROUND_SYNC_INTERVAL } from '@gauzy/ui-core/common'; import { Store as AppStore } from '../store/store.service'; import { ITimerSynced } from './interfaces'; -import { toLocal, toParams, toUTC } from '../../../utils/shared-utils'; -import { API_PREFIX, BACKGROUND_SYNC_INTERVAL } from '../../../constants'; export function createInitialTimerState(): TimerState { let timerConfig = { diff --git a/packages/ui-core/core/src/lib/services/upwork/upwork-store.service.ts b/packages/ui-core/core/src/lib/services/upwork/upwork-store.service.ts index 6270040aa2a..b5fe21d8825 100644 --- a/packages/ui-core/core/src/lib/services/upwork/upwork-store.service.ts +++ b/packages/ui-core/core/src/lib/services/upwork/upwork-store.service.ts @@ -3,8 +3,8 @@ import { BehaviorSubject, Observable, EMPTY } from 'rxjs'; import { tap, switchMap, map } from 'rxjs/operators'; import * as moment from 'moment'; import { ID, IEngagement, IOrganization, IUpworkApiConfig, IUpworkDateRange } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; import { UpworkService } from './upwork.service'; +import { Store } from '../store/store.service'; const DEFAULT_DATE_RANGE = { start: new Date(moment().subtract(1, 'months').format('YYYY-MM-DD')), diff --git a/packages/ui-core/i18n/assets/i18n/ach.json b/packages/ui-core/i18n/assets/i18n/ach.json index f96f845c9df..7ae92d76c16 100644 --- a/packages/ui-core/i18n/assets/i18n/ach.json +++ b/packages/ui-core/i18n/assets/i18n/ach.json @@ -1533,6 +1533,7 @@ "APPLIED": "crwdns3334:0crwdne3334:0", "HIRED": "crwdns3336:0crwdne3336:0", "REJECTED": "crwdns3338:0crwdne3338:0", + "SHOW_REJECTED": "Տեղադրումը մերժված է", "DELETED": "crwdns3340:0crwdne3340:0", "ARCHIVED": "crwdns3940:0crwdne3940:0", "SELECT_EMPLOYEE_MSG": "crwdns3342:0crwdne3342:0", @@ -2017,7 +2018,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "crwdns2411:0crwdne2411:0", - "EDIT": "crwdns2413:0crwdne2413:0", "AUTHOR": "crwdns2415:0crwdne2415:0", "JOB_POST_URL": "crwdns2417:0crwdne2417:0", "PROPOSAL_SENT_ON": "crwdns2419:0crwdne2419:0", @@ -2858,7 +2858,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "crwdns2249:0crwdne2249:0", "TAKE_ME_HOME": "crwdns2251:0crwdne2251:0", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "crwdns2253:0crwdne2253:0" + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "crwdns2253:0crwdne2253:0" }, "HELP_PAGE": { "HELP": "crwdns2255:0crwdne2255:0", @@ -3757,7 +3757,7 @@ "SELECT_EMPLOYEE_ERROR": "crwdns7274:0crwdne7274:0", "EXPIRED_OR_CANCELLED": "crwdns5094:0crwdne5094:0", "EMAIL_SENT": "crwdns4568:0crwdne4568:0", - "NO_ACTIVE_EVENT_TYpES": "crwdns9052:0crwdne9052:0" + "NO_ACTIVE_EVENT_TYPES": "crwdns9052:0crwdne9052:0" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "crwdns10334:0crwdne10334:0", diff --git a/packages/ui-core/i18n/assets/i18n/ar.json b/packages/ui-core/i18n/assets/i18n/ar.json index deade23d7e5..3031ea07d32 100644 --- a/packages/ui-core/i18n/assets/i18n/ar.json +++ b/packages/ui-core/i18n/assets/i18n/ar.json @@ -33,6 +33,7 @@ "INVITE": "دعوة", "SELECT_ALL": "حدد الكل", "COPY_LINK": "نسخ الرابط", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "إدارة المقابلات", "MANAGE_INVITES": "إدارة الدعوات", "MANAGE_SPRINTS": "إدارة السبرنت", @@ -1626,6 +1627,7 @@ "APPLIED": "تم التطبيق", "HIRED": "تم التوظيف", "REJECTED": "مرفوض", + "SHOW_REJECTED": "عرض مرفوض", "DELETED": "تم الحذف", "ARCHIVED": "مؤرشف", "SELECT_EMPLOYEE_MSG": "يرجى اختيار موظف من القائمة أعلاه.", @@ -2183,7 +2185,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "تفاصيل الاقتراح", - "EDIT": "تعديل", "AUTHOR": "المؤلف", "JOB_POST_URL": "رابط منشور الوظيفة", "PROPOSAL_SENT_ON": "تم إرسال الاقتراح في", @@ -3041,7 +3042,8 @@ "PUBLIC_LINK": { "HEADER": "توليد رابط عام", "GENERATE": "أنشئ رابطًا لـ {{ text }} يمكن لأي شخص يمتلك الرابط رؤيته.", - "ACCESS": "أي شخص لديه وصول إلى هذا الرابط يمكنه عرض {{ text }}." + "ACCESS": "أي شخص لديه وصول إلى هذا الرابط يمكنه عرض {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3072,7 +3074,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "الصفحة غير موجودة", "TAKE_ME_HOME": "خذني إلى المنزل", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "الصفحة التي كنت تبحث عنها غير موجودة", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "الصفحة التي كنت تبحث عنها غير موجودة", "REDIRECT_TO_HOME": "سيتم توجيهك إلى الصفحة الرئيسية قريباً" }, "HELP_PAGE": { @@ -4166,8 +4168,9 @@ "NO_RECORD_FOUND": "لم يتم العثور على سجلات. يرجى تحديد نطاق التاريخ، الموظف، أو المشروع." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "لنقم بإنشاء منظمتك الأولى", - "COMPLETE": "أنت جاهز تماما!" + "FIRST_ORGANIZATION": "لنقم بإنشاء مؤسستك الأولى", + "COMPLETE_TITLE": "كل شيء جاهز!", + "COMPLETE_SUB_TITLE": "إلى أين تريد أن تذهب الآن؟" }, "VALIDATION": { "FIELD_REQUIRED": "هذا الحقل مطلوب!", @@ -4235,7 +4238,8 @@ "SELECT_EMPLOYEE_ERROR": "يرجى اختيار موظف.", "EXPIRED_OR_CANCELLED": "تم انتهاء هذا الموعد أو إلغاؤه.", "EMAIL_SENT": "تم إرسال بريد إلكتروني إلى المضيف وإلى جميع المشاركين في هذا الاجتماع.", - "NO_ACTIVE_EVENT_TYpES": "لا توجد أنواع فعالة للأحداث" + "NO_ACTIVE_EVENT_TYPES": "لا توجد أنواع فعالة للأحداث", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "قوالب البريد الإلكتروني", diff --git a/packages/ui-core/i18n/assets/i18n/bg.json b/packages/ui-core/i18n/assets/i18n/bg.json index 000b30f9815..9008174751d 100644 --- a/packages/ui-core/i18n/assets/i18n/bg.json +++ b/packages/ui-core/i18n/assets/i18n/bg.json @@ -33,6 +33,7 @@ "INVITE": "Покана", "SELECT_ALL": "Селектиране на всички", "COPY_LINK": "Копирай линка", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Управление на интервюта", "MANAGE_INVITES": "Управление на покани", "MANAGE_SPRINTS": "Управление на спринтове", @@ -159,47 +160,48 @@ }, "SM_TABLE": { "NO_DATA": { - "RECEIVE_ESTIMATE": "Не сте получили никаква оценка.", - "INCOME": "Не сте създали никакъв доход.", - "EXPENSE_CATEGORY": "Не сте създали никаква категория разходи.", - "REPORT": "Не сте създали никакъв отчет.", - "CONTRACT": "Не сте създали никакъв договор.", - "TEAM": "Не сте създали никакъв екип.", - "HISTORY_RECORD": "Не сте създали никакъв запис.", + "LOADING": "Зареждане, моля, изчакайте...", + "RECEIVE_ESTIMATE": "Не сте получили никакви оценки.", + "INCOME": "Не сте създали никакви доходи.", + "EXPENSE_CATEGORY": "Не сте създали никакви категории разходи.", + "REPORT": "Не сте създали никакви отчети.", + "CONTRACT": "Не сте създали никакви договори.", + "TEAM": "Не сте създали никакви екипи.", + "HISTORY_RECORD": "Не сте създали никакви записи.", "PROFIT_HISTORY": "Не сте създали никаква история на печалбата.", - "EMPLOYEE": "Не сте създали никакъв служител.", - "EXPENSE": "Не сте създали никакъв разход.", - "PAYMENT": "Не сте получили никакво плащане.", - "PROPOSAL_TEMPLATE": "Не сте създали никакъв шаблон за предложение.", - "PROPOSAL": "Не сте създали никакво предложение.", - "PIPELINE": "Не сте създали никакъв тръбопровод.", - "TASK": "Не сте създали никаква задача.", - "INVITE": "Не сте поканили никакъв потребител.", - "APPROVAL_REQUEST": "Не сте създали заявка за одобрение.", - "APPROVAL_POLICY": "Не сте създали никаква политика за одобрение.", + "EMPLOYEE": "Не сте създали никакви служители.", + "EXPENSE": "Не сте създали никакви разходи.", + "PAYMENT": "Не сте получили никакви плащания.", + "PROPOSAL_TEMPLATE": "Не сте създали никакви шаблони за предложения.", + "PROPOSAL": "Не сте създали никакви предложения.", + "PIPELINE": "Не сте създали никакви тръбопроводи.", + "TASK": "Не сте създали никакви задачи.", + "INVITE": "Не сте поканили никакви потребители.", + "APPROVAL_REQUEST": "Не сте създали никакви заявки за одобрение.", + "APPROVAL_POLICY": "Не сте създали никакви политики за одобрение.", "TIME_OFF": "Не сте създали никакво време за отпуск.", - "CANDIDATE": "Не сте създали никакъв кандидат.", - "INTERVIEW": "Не сте създали никакво интервю.", + "CANDIDATE": "Не сте създали никакви кандидати.", + "INTERVIEW": "Не сте създали никакви интервюта.", "EQUIPMENT": "Не сте създали никакво оборудване.", - "EQUIPMENT_SHARING": "Не сте създали никакво споделяне на оборудване.", - "EQUIPMENT_SHARING_POLICY": "Не сте създали никаква политика за споделяне на оборудване.", - "INVENTORY": "Не сте създали никакъв инвентар.", - "MERCHANT": "Не сте създали никакъв търговец.", - "WAREHOUSE": "Не сте създали никакъв склад.", - "WAREHOUSE_PRODUCT": "Няма продукти в склада.", - "PRODUCT_CATEGORY": "Не сте създали никаква категория продукти.", - "TAGS": "Не сте създали никакъв етикет.", - "PROJECT": "Не сте създали никакъв проект.", - "DEPARTMENT": "Не сте създали никакъв отдел.", - "CONTACT": "Не сте създали никакъв контакт.", - "CLIENT": "Не сте създали никакъв клиент.", - "LEAD": "Не сте създали никакъв потенциален клиент.", - "TIME_FRAME": "Не сте създали никакъв времеви период.", - "KPI": "Не сте създали никакъв KPI.", - "INVOICE": "Не сте създали никаква фактура.", - "ESTIMATE": "Не сте създали никаква оценка.", - "EVENT_TYPE": "Не сте създали никакъв тип събитие.", - "PRODUCT_TYPE_NO_DATA": "Не сте създали никакъв тип продукт.", + "EQUIPMENT_SHARING": "Не сте създали никакви записи за споделяне на оборудване.", + "EQUIPMENT_SHARING_POLICY": "Не сте създали никакви политики за споделяне на оборудване.", + "INVENTORY": "Не сте създали никакви инвентари.", + "MERCHANT": "Не сте създали никакви търговци.", + "WAREHOUSE": "Не сте създали никакви складове.", + "WAREHOUSE_PRODUCT": "Не сте създали никакви складови продукти.", + "PRODUCT_CATEGORY": "Не сте създали никакви категории продукти.", + "TAGS": "Не сте създали никакви етикети.", + "PROJECT": "Не сте създали никакви проекти.", + "DEPARTMENT": "Не сте създали никакви отдели.", + "CONTACT": "Не сте създали никакви контакти.", + "CLIENT": "Не сте създали никакви клиенти.", + "LEAD": "Не сте създали никакви потенциални клиенти.", + "TIME_FRAME": "Не сте създали никакви времеви периоди.", + "KPI": "Не сте създали никакви КПИ.", + "INVOICE": "Не сте създали никакви фактури.", + "ESTIMATE": "Не сте създали никакви оценки.", + "EVENT_TYPE": "Не сте създали никакви типове събития.", + "PRODUCT_TYPE_NO_DATA": "Не сте създали никакви типове продукти.", "TEAM_DASHBOARD": "Нямате никакви екипи.", "PLUGIN": "Не сте инсталирали никакви плъгини." }, @@ -1674,6 +1676,7 @@ "APPLIED": "Applied", "HIRED": "Hired", "REJECTED": "Rejected", + "SHOW_REJECTED": "Показване отказано", "DELETED": "Изтрит", "ARCHIVED": "Архивирана", "SELECT_EMPLOYEE_MSG": "Моля селектирайте служител от менюто по-долу.", @@ -2200,40 +2203,39 @@ "ACCEPTED_PROPOSALS": "Приети предложения", "TOTAL_PROPOSALS": "Общо предложения", "SUCCESS_RATE": "Успеваемост", - "PROPOSALS": "Proposals", + "PROPOSALS": "Предложения", "REGISTER": { - "REGISTER_PROPOSALS": "Register Proposal", + "REGISTER_PROPOSALS": "Регистрирай предложение", "AUTHOR": "Автор", - "TEMPLATE": "Template", - "JOB_POST_URL": "Job Post URL", + "TEMPLATE": "Шаблон", + "JOB_POST_URL": "URL на обява за работа", "PICK_A_DATE": "Изберете дата", - "PROPOSAL_DATE": "Proposal Date", - "JOB_POST_CONTENT": "Job Post Content", - "UPLOAD": "Upload", - "PROPOSALS_CONTENT": "Proposal Content", - "REGISTER_PROPOSALS_BUTTON": "Register Proposal" + "PROPOSAL_DATE": "Дата на предложението", + "JOB_POST_CONTENT": "Съдържание на обява за работа", + "UPLOAD": "Качване", + "PROPOSALS_CONTENT": "Съдържание на предложението", + "REGISTER_PROPOSALS_BUTTON": "Регистрирай предложение" }, "PROPOSAL_DETAILS": { - "PROPOSAL_DETAILS": "Proposal Details", - "EDIT": "Редактиране", + "PROPOSAL_DETAILS": "Детайли на предложението", "AUTHOR": "Автор", - "JOB_POST_URL": "Job Post URL", - "PROPOSAL_SENT_ON": "Proposal Sent On", + "JOB_POST_URL": "URL на обява за работа", + "PROPOSAL_SENT_ON": "Предложението е изпратено на", "STATUS": "Статус", - "JOB_POST_CONTENT": "Job Post Content", - "PROPOSAL_CONTENT": "Proposal Content", - "VIEW_JOB_POST": "Преглед на публикация" + "JOB_POST_CONTENT": "Съдържание на обява за работа", + "PROPOSAL_CONTENT": "Съдържание на предложението", + "VIEW_JOB_POST": "Преглед на обява" }, "EDIT_PROPOSAL": { - "EDIT_PROPOSAL": "Edit Proposal", + "EDIT_PROPOSAL": "Редактиране на предложението", "AUTHOR": "Автор", - "JOB_POST_URL": "Job Post URL", - "PROPOSAL_SENT_ON": "Proposal Sent On", - "JOB_POST_CONTENT": "Job Post Content", - "PROPOSAL_CONTENT": "Proposal Content", - "EDIT_PROPOSAL_BUTTON": "Edit Proposal", + "JOB_POST_URL": "URL на обява за работа", + "PROPOSAL_SENT_ON": "Предложението е изпратено на", + "JOB_POST_CONTENT": "Съдържание на обява за работа", + "PROPOSAL_CONTENT": "Съдържание на предложението", + "EDIT_PROPOSAL_BUTTON": "Редактиране на предложението", "PLACEHOLDER": { - "JOB_POST_URL": "Job Post URL" + "JOB_POST_URL": "URL на обява за работа" } } }, @@ -3072,7 +3074,8 @@ "PUBLIC_LINK": { "HEADER": "Generate Public Link", "GENERATE": "Generate a link to the {{ text }} that anyone with the link can view.", - "ACCESS": "Anyone with access to this link can view the {{ text }}." + "ACCESS": "Anyone with access to this link can view the {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3103,7 +3106,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Page Not Found", "TAKE_ME_HOME": "Take me home", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "The page you were looking for doesn't exist", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "The page you were looking for doesn't exist", "REDIRECT_TO_HOME": "You'll be redirected to home page soon" }, "HELP_PAGE": { @@ -4189,7 +4192,8 @@ }, "ONBOARDING": { "FIRST_ORGANIZATION": "Нека създадем първата ви организация", - "COMPLETE": "Готови сте!" + "COMPLETE_TITLE": "Всичко е готово!", + "COMPLETE_SUB_TITLE": "Къде искате да отидете сега?" }, "VALIDATION": { "FIELD_REQUIRED": "This field is required!", @@ -4257,7 +4261,8 @@ "SELECT_EMPLOYEE_ERROR": "Please select an employee.", "EXPIRED_OR_CANCELLED": "**This appointment has expired or has been cancelled.", "EMAIL_SENT": "**An email has been sent to the host as well as to all the participants for this meeting.", - "NO_ACTIVE_EVENT_TYpES": "There are no active event types" + "NO_ACTIVE_EVENT_TYPES": "There are no active event types", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Шаблони на имейли", diff --git a/packages/ui-core/i18n/assets/i18n/de.json b/packages/ui-core/i18n/assets/i18n/de.json index 2dab7b0c34f..422f756e875 100644 --- a/packages/ui-core/i18n/assets/i18n/de.json +++ b/packages/ui-core/i18n/assets/i18n/de.json @@ -33,6 +33,7 @@ "INVITE": "Einladen", "SELECT_ALL": "Alle auswählen", "COPY_LINK": "Kopiere Link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Verwalten von Vorstellungsgesprächen", "MANAGE_INVITES": "Einladungen verwalten", "MANAGE_SPRINTS": "Verwalten Sie Sprints", @@ -1626,6 +1627,7 @@ "APPLIED": "Angewendet", "HIRED": "Angestellt", "REJECTED": "Abgelehnt", + "SHOW_REJECTED": "Anzeige abgelehnt", "DELETED": "Gelöscht", "ARCHIVED": "Archiviert", "SELECT_EMPLOYEE_MSG": "Bitte wählen Sie einen Mitarbeiter aus dem Menü oben aus.", @@ -2180,7 +2182,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Details des Vorschlags", - "EDIT": "Bearbeiten", "AUTHOR": "Autor", "JOB_POST_URL": "Stellenanzeigen-URL", "PROPOSAL_SENT_ON": "Vorschlag gesendet am", @@ -3038,7 +3039,8 @@ "PUBLIC_LINK": { "HEADER": "Generiere öffentlichen Link", "GENERATE": "Erstellen Sie einen Link zu dem {{Text}}, den jeder mit dem Link sehen kann.", - "ACCESS": "Jeder, der Zugriff auf diesen Link hat, kann den {{ Text }} anzeigen." + "ACCESS": "Jeder, der Zugriff auf diesen Link hat, kann den {{ Text }} anzeigen.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3069,7 +3071,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Seite nicht gefunden", "TAKE_ME_HOME": "Bring mich nach Hause", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "Die Seite, nach der du gesucht hast, existiert nicht.", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "Die Seite, nach der du gesucht hast, existiert nicht.", "REDIRECT_TO_HOME": "Sie werden bald zur Startseite weitergeleitet" }, "HELP_PAGE": { @@ -4163,8 +4165,9 @@ "NO_RECORD_FOUND": "Keine Einträge gefunden. Bitte wählen Sie einen Datumsbereich, einen Mitarbeiter oder ein Projekt aus." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Lassen Sie uns Ihre erste Organisation erstellen.", - "COMPLETE": "Du bist fertig!" + "FIRST_ORGANIZATION": "Lass uns deine erste Organisation erstellen", + "COMPLETE_TITLE": "Alles bereit!", + "COMPLETE_SUB_TITLE": "Wohin möchtest du jetzt gehen?" }, "VALIDATION": { "FIELD_REQUIRED": "Dieses Feld ist erforderlich!", @@ -4232,7 +4235,8 @@ "SELECT_EMPLOYEE_ERROR": "Bitte wählen Sie einen Mitarbeiter aus.", "EXPIRED_OR_CANCELLED": "Dieser Termin ist abgelaufen oder wurde abgesagt.", "EMAIL_SENT": "Eine E-Mail wurde an den Gastgeber sowie an alle Teilnehmer für dieses Treffen gesendet.", - "NO_ACTIVE_EVENT_TYpES": "Es gibt keine aktiven Ereignistypen." + "NO_ACTIVE_EVENT_TYPES": "Es gibt keine aktiven Ereignistypen.", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "E-Mail-Vorlagen", diff --git a/packages/ui-core/i18n/assets/i18n/en.json b/packages/ui-core/i18n/assets/i18n/en.json index ff439154f11..9fb300408a3 100644 --- a/packages/ui-core/i18n/assets/i18n/en.json +++ b/packages/ui-core/i18n/assets/i18n/en.json @@ -36,6 +36,7 @@ "INVITE": "Invite", "SELECT_ALL": "Select All", "COPY_LINK": "Copy Link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Manage Interviews", "MANAGE_INVITES": "Manage Invites", "MANAGE_SPRINTS": "Manage Sprints", @@ -169,48 +170,49 @@ }, "SM_TABLE": { "NO_DATA": { - "RECEIVE_ESTIMATE": "You have not received any estimate.", - "INCOME": "You have not created any income.", - "EXPENSE_CATEGORY": "You have not created any expense category.", - "REPORT": "You have not created any report.", - "CONTRACT": "You have not created any contract.", - "TEAM": "You have not created any team.", - "HISTORY_RECORD": "You have not created any record.", - "PROFIT_HISTORY": "You have not created any profit history.", - "EMPLOYEE": "You have not created any employee.", - "EXPENSE": "You have not created any expense.", - "PAYMENT": "You have not received any payment.", - "PROPOSAL_TEMPLATE": "You have not created any proposal template.", - "PROPOSAL": "You have not created any proposal.", - "PIPELINE": "You have not created any pipeline.", - "TASK": "You have not created any task.", - "INVITE": "You have not invited any user.", - "APPROVAL_REQUEST": "You have not created any approval request.", - "APPROVAL_POLICY": "You have not created any approval policy.", - "TIME_OFF": "You have not created any time off.", - "CANDIDATE": "You have not created any candidate.", - "INTERVIEW": "You have not created any interview.", + "LOADING": "Loading, Please wait...", + "RECEIVE_ESTIMATE": "You have not received any estimates.", + "INCOME": "You have not created any incomes.", + "EXPENSE_CATEGORY": "You have not created any expense categories.", + "REPORT": "You have not created any reports.", + "CONTRACT": "You have not created any contracts.", + "TEAM": "You have not created any teams.", + "HISTORY_RECORD": "You have not created any records.", + "PROFIT_HISTORY": "You have not created any profit histories.", + "EMPLOYEE": "You have not created any employees.", + "EXPENSE": "You have not created any expenses.", + "PAYMENT": "You have not received any payments.", + "PROPOSAL_TEMPLATE": "You have not created any proposal templates.", + "PROPOSAL": "You have not created any proposals.", + "PIPELINE": "You have not created any pipelines.", + "TASK": "You have not created any tasks.", + "INVITE": "You have not invited any users.", + "APPROVAL_REQUEST": "You have not created any approval requests.", + "APPROVAL_POLICY": "You have not created any approval policies.", + "TIME_OFF": "You have not created any time offs.", + "CANDIDATE": "You have not created any candidates.", + "INTERVIEW": "You have not created any interviews.", "EQUIPMENT": "You have not created any equipment.", - "EQUIPMENT_SHARING": "You have not created any equipment sharing.", - "EQUIPMENT_SHARING_POLICY": "You have not created any equipment sharing policy.", - "INVENTORY": "You have not created any inventory.", - "MERCHANT": "You have not created any merchant.", - "WAREHOUSE": "You have not created any warehouse.", - "WAREHOUSE_PRODUCT": "No warehouse products here.", - "PRODUCT_CATEGORY": "You have not created any product category.", - "TAGS": "You have not created any tag.", - "PROJECT": "You have not created any project.", - "DEPARTMENT": "You have not created any department.", - "CONTACT": "You have not created any contact.", - "CLIENT": "You have not created any client.", - "LEAD": "You have not created any lead.", - "TIME_FRAME": "You have not created any time frame.", - "KPI": "You have not created any KPI.", - "INVOICE": "You have not created any invoice.", - "ESTIMATE": "You have not created any estimate.", - "EVENT_TYPE": "You have not created any event type.", - "PRODUCT_TYPE_NO_DATA": "You have not created any product type.", - "TEAM_DASHBOARD": "You don't have any teams", + "EQUIPMENT_SHARING": "You have not created any equipment sharing records.", + "EQUIPMENT_SHARING_POLICY": "You have not created any equipment sharing policies.", + "INVENTORY": "You have not created any inventories.", + "MERCHANT": "You have not created any merchants.", + "WAREHOUSE": "You have not created any warehouses.", + "WAREHOUSE_PRODUCT": "You have not created any warehouse products.", + "PRODUCT_CATEGORY": "You have not created any product categories.", + "TAGS": "You have not created any tags.", + "PROJECT": "You have not created any projects.", + "DEPARTMENT": "You have not created any departments.", + "CONTACT": "You have not created any contacts.", + "CLIENT": "You have not created any clients.", + "LEAD": "You have not created any leads.", + "TIME_FRAME": "You have not created any time frames.", + "KPI": "You have not created any KPIs.", + "INVOICE": "You have not created any invoices.", + "ESTIMATE": "You have not created any estimates.", + "EVENT_TYPE": "You have not created any event types.", + "PRODUCT_TYPE_NO_DATA": "You have not created any product types.", + "TEAM_DASHBOARD": "You don't have any teams.", "PLUGIN": "You haven't install any plugin." }, "TRANSACTION_TYPE": "Type", @@ -1716,6 +1718,7 @@ "APPLIED": "Applied", "HIRED": "Hired", "REJECTED": "Rejected", + "SHOW_REJECTED": "Show rejected", "DELETED": "Deleted", "ARCHIVED": "Archived", "SELECT_EMPLOYEE_MSG": "Please select employee from the menu above.", @@ -2306,7 +2309,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Proposal Details", - "EDIT": "Edit", "AUTHOR": "Author", "JOB_POST_URL": "Job Post URL", "PROPOSAL_SENT_ON": "Proposal Sent On", @@ -3164,7 +3166,8 @@ "PUBLIC_LINK": { "HEADER": "Generate Public Link", "GENERATE": "Generate a link to the {{ text }} that anyone with the link can view.", - "ACCESS": "Anyone with access to this link can view the {{ text }}." + "ACCESS": "Anyone with access to this link can view the {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3195,7 +3198,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Page Not Found", "TAKE_ME_HOME": "Take me home", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "The page you were looking for doesn't exist", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "The page you were looking for doesn't exist", "REDIRECT_TO_HOME": "You'll be redirected to home page soon" }, "HELP_PAGE": { @@ -4295,7 +4298,8 @@ }, "ONBOARDING": { "FIRST_ORGANIZATION": "Let's create your first organization", - "COMPLETE": "You're all set!" + "COMPLETE_TITLE": "You're all set!", + "COMPLETE_SUB_TITLE": "Where would you like to go now?" }, "VALIDATION": { "FIELD_REQUIRED": "This field is required!", @@ -4363,7 +4367,8 @@ "SELECT_EMPLOYEE_ERROR": "Please select an employee.", "EXPIRED_OR_CANCELLED": "**This appointment has expired or has been cancelled.", "EMAIL_SENT": "**An email has been sent to the host as well as to all the participants for this meeting.", - "NO_ACTIVE_EVENT_TYpES": "There are no active event types" + "NO_ACTIVE_EVENT_TYPES": "There are no active event types", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Email Templates", diff --git a/packages/ui-core/i18n/assets/i18n/es.json b/packages/ui-core/i18n/assets/i18n/es.json index d4b9b0e0eaa..0c582e993ed 100644 --- a/packages/ui-core/i18n/assets/i18n/es.json +++ b/packages/ui-core/i18n/assets/i18n/es.json @@ -33,6 +33,7 @@ "INVITE": "Invitar", "SELECT_ALL": "Seleccionar todo.", "COPY_LINK": "Copiar enlace.", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Gestionar entrevistas", "MANAGE_INVITES": "Administrar invitaciones", "MANAGE_SPRINTS": "Administrar Scrum", @@ -1628,6 +1629,7 @@ "APPLIED": "Aplicado", "HIRED": "Contratado", "REJECTED": "Rechazado", + "SHOW_REJECTED": "Mostrar rechazado", "DELETED": "Borrado", "ARCHIVED": "Archivado", "SELECT_EMPLOYEE_MSG": "Por favor, seleccione un empleado del menú de arriba.", @@ -2186,7 +2188,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Detalles de la propuesta", - "EDIT": "Editar", "AUTHOR": "Autor", "JOB_POST_URL": "URL de publicación de trabajo", "PROPOSAL_SENT_ON": "Propuesta enviada en", @@ -3044,7 +3045,8 @@ "PUBLIC_LINK": { "HEADER": "Generar Enlace Público", "GENERATE": "Generar un enlace al {{ text }} que cualquier persona con el enlace puede ver.", - "ACCESS": "Cualquier persona con acceso a este enlace puede ver el {{ text }}." + "ACCESS": "Cualquier persona con acceso a este enlace puede ver el {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3075,7 +3077,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Página no encontrada", "TAKE_ME_HOME": "Llévame a casa.", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "La página que estabas buscando no existe.", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "La página que estabas buscando no existe.", "REDIRECT_TO_HOME": "Serás redirigido a la página de inicio pronto" }, "HELP_PAGE": { @@ -4169,8 +4171,9 @@ "NO_RECORD_FOUND": "No se encontraron registros. Por favor, seleccione un rango de fechas, empleado o proyecto." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Creemos tu primera organización.", - "COMPLETE": "¡Estás listo!" + "FIRST_ORGANIZATION": "Vamos a crear tu primera organización", + "COMPLETE_TITLE": "¡Todo listo!", + "COMPLETE_SUB_TITLE": "¿A dónde te gustaría ir ahora?" }, "VALIDATION": { "FIELD_REQUIRED": "¡Este campo es obligatorio!", @@ -4238,7 +4241,8 @@ "SELECT_EMPLOYEE_ERROR": "Por favor, seleccione un empleado.", "EXPIRED_OR_CANCELLED": "Esta cita ha expirado o ha sido cancelada.", "EMAIL_SENT": "Se ha enviado un correo electrónico al anfitrión, así como a todos los participantes de esta reunión.", - "NO_ACTIVE_EVENT_TYpES": "No hay tipos de eventos activos." + "NO_ACTIVE_EVENT_TYPES": "No hay tipos de eventos activos.", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Plantillas de correo electrónico", diff --git a/packages/ui-core/i18n/assets/i18n/fr.json b/packages/ui-core/i18n/assets/i18n/fr.json index c2dc1929633..acf6dc4cdd6 100644 --- a/packages/ui-core/i18n/assets/i18n/fr.json +++ b/packages/ui-core/i18n/assets/i18n/fr.json @@ -33,6 +33,7 @@ "INVITE": "Invitation", "SELECT_ALL": "Sélectionner tout", "COPY_LINK": "Copier le lien", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Gérer les entretiens", "MANAGE_INVITES": "Gérer les invitations", "MANAGE_SPRINTS": "Gérer les sprints", @@ -1627,6 +1628,7 @@ "APPLIED": "Appliqué", "HIRED": "Engagé", "REJECTED": "Rejeté", + "SHOW_REJECTED": "Voir rejeté", "DELETED": "Supprimé", "ARCHIVED": "Archivé", "SELECT_EMPLOYEE_MSG": "Veuillez sélectionner un employé dans le menu ci-dessus.", @@ -2185,7 +2187,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Détails de la proposition", - "EDIT": "Modifier", "AUTHOR": "Auteur", "JOB_POST_URL": "URL de l'annonce d'emploi", "PROPOSAL_SENT_ON": "Proposition envoyée le", @@ -3043,7 +3044,8 @@ "PUBLIC_LINK": { "HEADER": "Générer un lien public", "GENERATE": "Générer un lien vers le {{ text }} que n'importe qui ayant le lien peut visualiser.", - "ACCESS": "Toute personne ayant accès à ce lien peut voir le {{ text }}." + "ACCESS": "Toute personne ayant accès à ce lien peut voir le {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3074,7 +3076,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Page non trouvée", "TAKE_ME_HOME": "Ramené moi à la maison", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "La page que vous recherchiez n'existe pas.", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "La page que vous recherchiez n'existe pas.", "REDIRECT_TO_HOME": "Vous serez bientôt redirigé vers la page d'accueil" }, "HELP_PAGE": { @@ -4168,8 +4170,9 @@ "NO_RECORD_FOUND": "Aucun résultat trouvé. Veuillez sélectionner une plage de dates, un employé ou un projet." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Créons votre première organisation.", - "COMPLETE": "Vous êtes prêt(e) !" + "FIRST_ORGANIZATION": "Créons votre première organisation", + "COMPLETE_TITLE": "Vous êtes prêt !", + "COMPLETE_SUB_TITLE": "Où voulez-vous aller maintenant ?" }, "VALIDATION": { "FIELD_REQUIRED": "Ce champ est obligatoire !", @@ -4237,7 +4240,8 @@ "SELECT_EMPLOYEE_ERROR": "Veuillez sélectionner un employé.", "EXPIRED_OR_CANCELLED": "Ce rendez-vous a expiré ou a été annulé.", "EMAIL_SENT": "Un courriel a été envoyé à l'hôte ainsi qu'à tous les participants pour cette réunion.", - "NO_ACTIVE_EVENT_TYpES": "Il n'y a pas de types d'événements actifs." + "NO_ACTIVE_EVENT_TYPES": "Il n'y a pas de types d'événements actifs.", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Modèles d'e-mails", diff --git a/packages/ui-core/i18n/assets/i18n/he.json b/packages/ui-core/i18n/assets/i18n/he.json index 7c53ee5d789..bf0c689a218 100644 --- a/packages/ui-core/i18n/assets/i18n/he.json +++ b/packages/ui-core/i18n/assets/i18n/he.json @@ -33,6 +33,7 @@ "INVITE": "Invite", "SELECT_ALL": "Select All", "COPY_LINK": "Copy Link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Manage Interviews", "MANAGE_INVITES": "Manage Invites", "MANAGE_SPRINTS": "Manage Sprints", @@ -159,48 +160,49 @@ }, "SM_TABLE": { "NO_DATA": { - "RECEIVE_ESTIMATE": "You have not received any estimate.", - "INCOME": "You have not created any income.", - "EXPENSE_CATEGORY": "You have not created any expense category.", - "REPORT": "You have not created any report.", - "CONTRACT": "You have not created any contract.", - "TEAM": "You have not created any team.", - "HISTORY_RECORD": "You have not created any record.", - "PROFIT_HISTORY": "You have not created any profit history.", - "EMPLOYEE": "You have not created any employee.", - "EXPENSE": "You have not created any expense.", - "PAYMENT": "You have not received any payment.", - "PROPOSAL_TEMPLATE": "You have not created any proposal template.", - "PROPOSAL": "You have not created any proposal.", - "PIPELINE": "You have not created any pipeline.", - "TASK": "You have not created any task.", - "INVITE": "You have not invited any user.", - "APPROVAL_REQUEST": "You have not created any approval request.", - "APPROVAL_POLICY": "You have not created any approval policy.", - "TIME_OFF": "You have not created any time off.", - "CANDIDATE": "You have not created any candidate.", - "INTERVIEW": "You have not created any interview.", - "EQUIPMENT": "You have not created any equipment.", - "EQUIPMENT_SHARING": "You have not created any equipment sharing.", - "EQUIPMENT_SHARING_POLICY": "You have not created any equipment sharing policy.", - "INVENTORY": "You have not created any inventory.", - "MERCHANT": "You have not created any merchant.", - "WAREHOUSE": "You have not created any warehouse.", - "WAREHOUSE_PRODUCT": "No warehouse products here.", - "PRODUCT_CATEGORY": "You have not created any product category.", - "TAGS": "You have not created any tag.", - "PROJECT": "You have not created any project.", - "DEPARTMENT": "You have not created any department.", - "CONTACT": "You have not created any contact.", - "CLIENT": "You have not created any client.", - "LEAD": "You have not created any lead.", - "TIME_FRAME": "You have not created any time frame.", - "KPI": "You have not created any KPI.", - "INVOICE": "You have not created any invoice.", - "ESTIMATE": "You have not created any estimate.", - "EVENT_TYPE": "You have not created any event type.", - "PRODUCT_TYPE_NO_DATA": "You have not created any product type.", - "TEAM_DASHBOARD": "You don't have any teams", + "LOADING": "טוען, אנא המתן...", + "RECEIVE_ESTIMATE": "לא קיבלתם אף הערכה.", + "INCOME": "לא יצרתם הכנסות.", + "EXPENSE_CATEGORY": "לא יצרתם קטגוריות הוצאה.", + "REPORT": "לא יצרתם דוחות.", + "CONTRACT": "לא יצרתם חוזים.", + "TEAM": "לא יצרתם קבוצות.", + "HISTORY_RECORD": "לא יצרתם רשומות.", + "PROFIT_HISTORY": "לא יצרתם היסטוריות רווחים.", + "EMPLOYEE": "לא יצרתם עובדים.", + "EXPENSE": "לא יצרתם הוצאות.", + "PAYMENT": "לא קיבלתם תשלומים.", + "PROPOSAL_TEMPLATE": "לא יצרתם תבניות הצעה.", + "PROPOSAL": "לא יצרתם הצעות.", + "PIPELINE": "לא יצרתם ערוצי עבודה.", + "TASK": "לא יצרתם משימות.", + "INVITE": "לא הזמנתם משתמשים.", + "APPROVAL_REQUEST": "לא יצרתם בקשות אישור.", + "APPROVAL_POLICY": "לא יצרתם מדיניות אישור.", + "TIME_OFF": "לא יצרתם ימי חופשה.", + "CANDIDATE": "לא יצרתם מועמדים.", + "INTERVIEW": "לא יצרתם ראיונות.", + "EQUIPMENT": "לא יצרתם ציוד.", + "EQUIPMENT_SHARING": "לא יצרתם רשומות שיתוף ציוד.", + "EQUIPMENT_SHARING_POLICY": "לא יצרתם מדיניות שיתוף ציוד.", + "INVENTORY": "לא יצרתם מלאי.", + "MERCHANT": "לא יצרתם סוחרים.", + "WAREHOUSE": "לא יצרתם מחסנים.", + "WAREHOUSE_PRODUCT": "לא יצרתם מוצרי מחסן.", + "PRODUCT_CATEGORY": "לא יצרתם קטגוריות מוצרים.", + "TAGS": "לא יצרתם תגים.", + "PROJECT": "לא יצרתם פרויקטים.", + "DEPARTMENT": "לא יצרתם מחלקות.", + "CONTACT": "לא יצרתם אנשי קשר.", + "CLIENT": "לא יצרתם לקוחות.", + "LEAD": "לא יצרתם לידים.", + "TIME_FRAME": "לא יצרתם מסגרות זמן.", + "KPI": "לא יצרתם KPI.", + "INVOICE": "לא יצרתם חשבוניות.", + "ESTIMATE": "לא יצרתם הערכות.", + "EVENT_TYPE": "לא יצרתם סוגי אירועים.", + "PRODUCT_TYPE_NO_DATA": "לא יצרתם סוגי מוצרים.", + "TEAM_DASHBOARD": "אין לך שום צוותים.", "PLUGIN": "לא התקנת שום תוסף." }, "TRANSACTION_TYPE": "סוג", @@ -1667,6 +1669,7 @@ "APPLIED": "Applied", "HIRED": "Hired", "REJECTED": "Rejected", + "SHOW_REJECTED": "הצגה נדחתה", "DELETED": "Deleted", "ARCHIVED": "נשמר בארכיון", "SELECT_EMPLOYEE_MSG": "Please select employee from the menu above.", @@ -2188,45 +2191,44 @@ "ANONYMOUS": "Anonymous" }, "PROPOSALS_PAGE": { - "HEADER": "Proposals Management Page", - "STATISTICS": "Statistics", - "ACCEPTED_PROPOSALS": "Accepted Proposals", - "TOTAL_PROPOSALS": "Total Proposals", - "SUCCESS_RATE": "Success Rate", - "PROPOSALS": "Proposals", + "HEADER": "הצעות - ניהול", + "STATISTICS": "סטטיסטיקה", + "ACCEPTED_PROPOSALS": "הצעות שהתקבלו", + "TOTAL_PROPOSALS": "סך כל ההצעות", + "SUCCESS_RATE": "שיעור הצלחה", + "PROPOSALS": "הצעות", "REGISTER": { - "REGISTER_PROPOSALS": "Register Proposal", - "AUTHOR": "Author", - "TEMPLATE": "Template", - "JOB_POST_URL": "Job Post URL", - "PICK_A_DATE": "תבחר תאריך", - "PROPOSAL_DATE": "Proposal Date", - "JOB_POST_CONTENT": "Job Post Content", - "UPLOAD": "Upload", - "PROPOSALS_CONTENT": "Proposal Content", - "REGISTER_PROPOSALS_BUTTON": "Register Proposal" + "REGISTER_PROPOSALS": "רישום הצעה", + "AUTHOR": "מחבר", + "TEMPLATE": "תבנית", + "JOB_POST_URL": "כתובת URL של משרה", + "PICK_A_DATE": "בחר תאריך", + "PROPOSAL_DATE": "תאריך הצעה", + "JOB_POST_CONTENT": "תוכן משרה", + "UPLOAD": "העלה", + "PROPOSALS_CONTENT": "תוכן הצעה", + "REGISTER_PROPOSALS_BUTTON": "רשום הצעה" }, "PROPOSAL_DETAILS": { - "PROPOSAL_DETAILS": "Proposal Details", - "EDIT": "ערוך", - "AUTHOR": "Author", - "JOB_POST_URL": "Job Post URL", - "PROPOSAL_SENT_ON": "Proposal Sent On", - "STATUS": "עבודה", - "JOB_POST_CONTENT": "Job Post Content", - "PROPOSAL_CONTENT": "Proposal Content", - "VIEW_JOB_POST": "View Job Post" + "PROPOSAL_DETAILS": "פרטי הצעה", + "AUTHOR": "מחבר", + "JOB_POST_URL": "כתובת URL של משרה", + "PROPOSAL_SENT_ON": "הצעה נשלחה בתאריך", + "STATUS": "סטטוס", + "JOB_POST_CONTENT": "תוכן משרה", + "PROPOSAL_CONTENT": "תוכן הצעה", + "VIEW_JOB_POST": "צפה במשרה" }, "EDIT_PROPOSAL": { - "EDIT_PROPOSAL": "Edit Proposal", - "AUTHOR": "Author", - "JOB_POST_URL": "Job Post URL", - "PROPOSAL_SENT_ON": "Proposal Sent On", - "JOB_POST_CONTENT": "Job Post Content", - "PROPOSAL_CONTENT": "Proposal Content", - "EDIT_PROPOSAL_BUTTON": "Edit Proposal", + "EDIT_PROPOSAL": "ערוך הצעה", + "AUTHOR": "מחבר", + "JOB_POST_URL": "כתובת URL של משרה", + "PROPOSAL_SENT_ON": "הצעה נשלחה בתאריך", + "JOB_POST_CONTENT": "תוכן משרה", + "PROPOSAL_CONTENT": "תוכן הצעה", + "EDIT_PROPOSAL_BUTTON": "ערוך הצעה", "PLACEHOLDER": { - "JOB_POST_URL": "Job Post URL" + "JOB_POST_URL": "כתובת URL של משרה" } } }, @@ -3064,7 +3066,8 @@ "PUBLIC_LINK": { "HEADER": "Generate Public Link", "GENERATE": "Generate a link to the {{ text }} that anyone with the link can view.", - "ACCESS": "Anyone with access to this link can view the {{ text }}." + "ACCESS": "Anyone with access to this link can view the {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3095,7 +3098,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Page Not Found", "TAKE_ME_HOME": "Take me home", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "The page you were looking for doesn't exist", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "The page you were looking for doesn't exist", "REDIRECT_TO_HOME": "תופנה לדף הבית בקרוב" }, "HELP_PAGE": { @@ -4178,8 +4181,9 @@ "NO_RECORD_FOUND": "No records found. Please select date range, employee or project." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Let's create your first organization", - "COMPLETE": "You're all set!" + "FIRST_ORGANIZATION": "בואו ניצור את הארגון הראשון שלכם", + "COMPLETE_TITLE": "אתם מוכנים!", + "COMPLETE_SUB_TITLE": "לאן תרצו ללכת עכשיו?" }, "VALIDATION": { "FIELD_REQUIRED": "This field is required!", @@ -4247,7 +4251,8 @@ "SELECT_EMPLOYEE_ERROR": "Please select an employee.", "EXPIRED_OR_CANCELLED": "**This appointment has expired or has been cancelled.", "EMAIL_SENT": "**An email has been sent to the host as well as to all the participants for this meeting.", - "NO_ACTIVE_EVENT_TYpES": "There are no active event types" + "NO_ACTIVE_EVENT_TYPES": "There are no active event types", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Email Templates", diff --git a/packages/ui-core/i18n/assets/i18n/it.json b/packages/ui-core/i18n/assets/i18n/it.json index 9f22593781f..e60dc6cf1a3 100644 --- a/packages/ui-core/i18n/assets/i18n/it.json +++ b/packages/ui-core/i18n/assets/i18n/it.json @@ -33,6 +33,7 @@ "INVITE": "Invitare", "SELECT_ALL": "Seleziona tutto", "COPY_LINK": "Copia il link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Gestire i colloqui di lavoro", "MANAGE_INVITES": "Gestisci inviti", "MANAGE_SPRINTS": "Gestire gli Sprint", @@ -1626,6 +1627,7 @@ "APPLIED": "Applicato", "HIRED": "Assunto", "REJECTED": "Respinto", + "SHOW_REJECTED": "Mostra rifiutata", "DELETED": "Cancellato", "ARCHIVED": "Archiviato", "SELECT_EMPLOYEE_MSG": "Seleziona un dipendente dal menu sopra", @@ -2184,7 +2186,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Dettagli della proposta", - "EDIT": "Modifica", "AUTHOR": "Autore", "JOB_POST_URL": "URL dell'annuncio di lavoro", "PROPOSAL_SENT_ON": "Proposta inviata il", @@ -3042,7 +3043,8 @@ "PUBLIC_LINK": { "HEADER": "Generare collegamento pubblico", "GENERATE": "Genera un collegamento al {{ text }} che chiunque con il collegamento può visualizzare", - "ACCESS": "Chiunque abbia accesso a questo link può visualizzare il {{ text }}" + "ACCESS": "Chiunque abbia accesso a questo link può visualizzare il {{ text }}", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3073,7 +3075,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Pagina non trovata", "TAKE_ME_HOME": "Portami a casa", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "La pagina che stavi cercando non esiste", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "La pagina che stavi cercando non esiste", "REDIRECT_TO_HOME": "Sarai reindirizzato alla pagina principale presto" }, "HELP_PAGE": { @@ -4168,7 +4170,8 @@ }, "ONBOARDING": { "FIRST_ORGANIZATION": "Creiamo la tua prima organizzazione", - "COMPLETE": "Sei pronto!" + "COMPLETE_TITLE": "Tutto pronto!", + "COMPLETE_SUB_TITLE": "Dove vuoi andare adesso?" }, "VALIDATION": { "FIELD_REQUIRED": "Questo campo è obbligatorio!", @@ -4236,7 +4239,8 @@ "SELECT_EMPLOYEE_ERROR": "Seleziona un dipendente, per favore", "EXPIRED_OR_CANCELLED": "Questo appuntamento è scaduto o è stato annullato", "EMAIL_SENT": "È stata inviata un'email all'host oltre che a tutti i partecipanti per questa riunione", - "NO_ACTIVE_EVENT_TYpES": "Non ci sono tipi di eventi attivi" + "NO_ACTIVE_EVENT_TYPES": "Non ci sono tipi di eventi attivi", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Modelli di email", diff --git a/packages/ui-core/i18n/assets/i18n/nl.json b/packages/ui-core/i18n/assets/i18n/nl.json index 0153458c313..f65d0849ab0 100644 --- a/packages/ui-core/i18n/assets/i18n/nl.json +++ b/packages/ui-core/i18n/assets/i18n/nl.json @@ -33,6 +33,7 @@ "INVITE": "Uitnodigen", "SELECT_ALL": "Alles selecteren", "COPY_LINK": "Kopieer Link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Beheren van interviews", "MANAGE_INVITES": "Beheer uitnodigingen", "MANAGE_SPRINTS": "Beheer Sprints", @@ -1626,6 +1627,7 @@ "APPLIED": "Toegepast", "HIRED": "Aangenomen", "REJECTED": "Afgewezen", + "SHOW_REJECTED": "Toon afgewezen", "DELETED": "Verwijderd", "ARCHIVED": "Gearchiveerd", "SELECT_EMPLOYEE_MSG": "Selecteer alstublieft een medewerker uit het bovenstaande menu.", @@ -2184,7 +2186,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Details van het voorstel", - "EDIT": "Bewerken", "AUTHOR": "Auteur", "JOB_POST_URL": "Vacature URL", "PROPOSAL_SENT_ON": "Voorstel verzonden op", @@ -3042,7 +3043,8 @@ "PUBLIC_LINK": { "HEADER": "Genereer openbare link", "GENERATE": "Genereer een link naar de {{ text }} waar iedereen met de link het kan bekijken.", - "ACCESS": "Iedereen met toegang tot deze link kan de {{ text }} bekijken." + "ACCESS": "Iedereen met toegang tot deze link kan de {{ text }} bekijken.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3073,7 +3075,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Pagina niet gevonden", "TAKE_ME_HOME": "Breng me naar huis.", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "De pagina die je zocht bestaat niet", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "De pagina die je zocht bestaat niet", "REDIRECT_TO_HOME": "U wordt binnenkort doorgestuurd naar de startpagina" }, "HELP_PAGE": { @@ -4167,8 +4169,9 @@ "NO_RECORD_FOUND": "Geen gegevens gevonden. Selecteer alstublieft een datumbereik, medewerker of project." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Laten we je eerste organisatie aanmaken.", - "COMPLETE": "Je bent helemaal klaar!" + "FIRST_ORGANIZATION": "Laten we je eerste organisatie maken", + "COMPLETE_TITLE": "Je bent klaar!", + "COMPLETE_SUB_TITLE": "Waar wil je nu heen?" }, "VALIDATION": { "FIELD_REQUIRED": "Dit veld is verplicht!", @@ -4236,7 +4239,8 @@ "SELECT_EMPLOYEE_ERROR": "Selecteer alstublieft een medewerker.", "EXPIRED_OR_CANCELLED": "Deze afspraak is verlopen of geannuleerd.", "EMAIL_SENT": "Er is een e-mail verzonden naar de gastheer en naar alle deelnemers voor deze vergadering.", - "NO_ACTIVE_EVENT_TYpES": "Er zijn geen actieve gebeurtenistypen." + "NO_ACTIVE_EVENT_TYPES": "Er zijn geen actieve gebeurtenistypen.", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "E-mailsjablonen", diff --git a/packages/ui-core/i18n/assets/i18n/pl.json b/packages/ui-core/i18n/assets/i18n/pl.json index 506809554cb..478924c1ae6 100644 --- a/packages/ui-core/i18n/assets/i18n/pl.json +++ b/packages/ui-core/i18n/assets/i18n/pl.json @@ -33,6 +33,7 @@ "INVITE": "Zaproś", "SELECT_ALL": "Zaznacz wszystko", "COPY_LINK": "Skopiuj link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Zarządzaj rozmowami kwalifikacyjnymi", "MANAGE_INVITES": "Zarządzaj zaproszeniami", "MANAGE_SPRINTS": "Zarządzaj sprintami", @@ -1626,6 +1627,7 @@ "APPLIED": "Zastosowany", "HIRED": "Zatrudniony", "REJECTED": "Odrzucone", + "SHOW_REJECTED": "Pokaz odrzucony", "DELETED": "Usunięte", "ARCHIVED": "Zarchiwizowane", "SELECT_EMPLOYEE_MSG": "Proszę wybrać pracownika z menu powyżej", @@ -2184,7 +2186,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Szczegóły propozycji", - "EDIT": "Edytuj", "AUTHOR": "Autor", "JOB_POST_URL": "Adres URL ogłoszenia o pracę", "PROPOSAL_SENT_ON": "Propozycja wysłana dnia", @@ -3042,7 +3043,8 @@ "PUBLIC_LINK": { "HEADER": "Generuj publiczny link", "GENERATE": "Wygeneruj link do {{ text }}, który będzie można przeglądać przez każdą osobę posiadającą link", - "ACCESS": "Każda osoba mająca dostęp do tego linku może zobaczyć {{ text }}" + "ACCESS": "Każda osoba mająca dostęp do tego linku może zobaczyć {{ text }}", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3073,7 +3075,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Strona nie znaleziona", "TAKE_ME_HOME": "Zabierz mnie do domu", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "Strona, której szukałeś, nie istnieje", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "Strona, której szukałeś, nie istnieje", "REDIRECT_TO_HOME": "Za chwilę zostaniesz przekierowany na stronę główną" }, "HELP_PAGE": { @@ -4167,8 +4169,9 @@ "NO_RECORD_FOUND": "Nie znaleziono żadnych rekordów. Proszę wybrać zakres daty, pracownika lub projekt" }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Utwórzmy Twoją pierwszą organizację", - "COMPLETE": "Wszystko gotowe!" + "FIRST_ORGANIZATION": "Let's create your first organization", + "COMPLETE_TITLE": "You're all set!", + "COMPLETE_SUB_TITLE": "Where would you like to go now?" }, "VALIDATION": { "FIELD_REQUIRED": "To pole jest wymagane!", @@ -4236,7 +4239,8 @@ "SELECT_EMPLOYEE_ERROR": "Proszę wybrać pracownika", "EXPIRED_OR_CANCELLED": "To spotkanie wygasło lub zostało anulowane", "EMAIL_SENT": "E-mail został wysłany do organizatora oraz wszystkich uczestników tego spotkania", - "NO_ACTIVE_EVENT_TYpES": "Nie ma aktywnych typów wydarzeń" + "NO_ACTIVE_EVENT_TYPES": "Nie ma aktywnych typów wydarzeń", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Szablony wiadomości e-mail", diff --git a/packages/ui-core/i18n/assets/i18n/pt.json b/packages/ui-core/i18n/assets/i18n/pt.json index 7292e0e181c..bbfbef1e923 100644 --- a/packages/ui-core/i18n/assets/i18n/pt.json +++ b/packages/ui-core/i18n/assets/i18n/pt.json @@ -33,6 +33,7 @@ "INVITE": "Convidar", "SELECT_ALL": "Selecionar Tudo", "COPY_LINK": "Copiar Link", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Gerir Entrevistas", "MANAGE_INVITES": "Gerenciar convites", "MANAGE_SPRINTS": "Gerenciar Sprints", @@ -1626,6 +1627,7 @@ "APPLIED": "Aplicado", "HIRED": "Contratado.", "REJECTED": "Rejeitado", + "SHOW_REJECTED": "Mostrar rejeitado", "DELETED": "Deleteado", "ARCHIVED": "Arquivado", "SELECT_EMPLOYEE_MSG": "Por favor, selecione um funcionário no menu acima.", @@ -2184,7 +2186,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Detalhes da proposta.", - "EDIT": "Editar", "AUTHOR": "Autor", "JOB_POST_URL": "URL da vaga de emprego", "PROPOSAL_SENT_ON": "Proposta Enviada Em", @@ -3042,7 +3043,8 @@ "PUBLIC_LINK": { "HEADER": "Gerar Link Público", "GENERATE": "Gerar um link para o {{ text }} que qualquer pessoa com o link possa visualizar.", - "ACCESS": "Qualquer pessoa com acesso a este link pode visualizar o {{ text }}." + "ACCESS": "Qualquer pessoa com acesso a este link pode visualizar o {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3073,7 +3075,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "Página não encontrada", "TAKE_ME_HOME": "Leve-me para casa", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "A página que você estava procurando não existe.", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "A página que você estava procurando não existe.", "REDIRECT_TO_HOME": "Será redirecionado para a página inicial em breve" }, "HELP_PAGE": { @@ -4167,8 +4169,9 @@ "NO_RECORD_FOUND": "Nenhum registro encontrado. Por favor, selecione o intervalo de datas, funcionário ou projeto." }, "ONBOARDING": { - "FIRST_ORGANIZATION": "Vamos criar sua primeira organização.", - "COMPLETE": "Você está pronto!" + "FIRST_ORGANIZATION": "Vamos criar sua primeira organização", + "COMPLETE_TITLE": "Tudo pronto!", + "COMPLETE_SUB_TITLE": "Para onde você gostaria de ir agora?" }, "VALIDATION": { "FIELD_REQUIRED": "Este campo é obrigatório!", @@ -4236,7 +4239,8 @@ "SELECT_EMPLOYEE_ERROR": "Por favor, selecione um funcionário.", "EXPIRED_OR_CANCELLED": "**Esta consulta expirou ou foi cancelada.", "EMAIL_SENT": "**Um e-mail foi enviado para o anfitrião, bem como para todos os participantes desta reunião.", - "NO_ACTIVE_EVENT_TYpES": "Não há tipos de eventos ativos." + "NO_ACTIVE_EVENT_TYPES": "Não há tipos de eventos ativos.", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Modelos de Email", diff --git a/packages/ui-core/i18n/assets/i18n/ru.json b/packages/ui-core/i18n/assets/i18n/ru.json index 6970d60ef6d..85ba65e924f 100644 --- a/packages/ui-core/i18n/assets/i18n/ru.json +++ b/packages/ui-core/i18n/assets/i18n/ru.json @@ -33,6 +33,7 @@ "INVITE": "Пригласить", "SELECT_ALL": "Выделить все", "COPY_LINK": "Скопировать ссылку", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "Управление интервью", "MANAGE_INVITES": "Управление приглашениями", "MANAGE_SPRINTS": "Управление спринтами", @@ -159,48 +160,49 @@ }, "SM_TABLE": { "NO_DATA": { - "RECEIVE_ESTIMATE": "Вы не получили никаких прогнозов.", - "INCOME": "Вы не создали никакого дохода.", - "EXPENSE_CATEGORY": "Вы не создали никакой категории расходов.", - "REPORT": "Вы не создали отчета.", - "CONTRACT": "Вы не создали никакого контракта.", - "TEAM": "Вы не создали никакой команды.", - "HISTORY_RECORD": "Вы не создали никакой записи.", + "LOADING": "Загрузка, пожалуйста, подождите...", + "RECEIVE_ESTIMATE": "Вы не получили ни одной оценки.", + "INCOME": "Вы не создали ни одного дохода.", + "EXPENSE_CATEGORY": "Вы не создали ни одной категории расходов.", + "REPORT": "Вы не создали ни одного отчета.", + "CONTRACT": "Вы не создали ни одного контракта.", + "TEAM": "Вы не создали ни одной команды.", + "HISTORY_RECORD": "Вы не создали ни одной записи.", "PROFIT_HISTORY": "Вы не создали ни одной истории прибыли.", "EMPLOYEE": "Вы не создали ни одного сотрудника.", - "EXPENSE": "Вы не создали никаких расходов.", + "EXPENSE": "Вы не создали ни одного расхода.", "PAYMENT": "Вы не получили ни одного платежа.", - "PROPOSAL_TEMPLATE": "Вы не создали шаблон предложения.", - "PROPOSAL": "Вы не создали никаких предложений.", - "PIPELINE": "Вы не создали ни одного конвейера.", - "TASK": "Вы не создали никакой задачи.", + "PROPOSAL_TEMPLATE": "Вы не создали ни одного шаблона предложения.", + "PROPOSAL": "Вы не создали ни одного предложения.", + "PIPELINE": "Вы не создали ни одного трубопровода.", + "TASK": "Вы не создали ни одной задачи.", "INVITE": "Вы не пригласили ни одного пользователя.", - "APPROVAL_REQUEST": "Вы не создали ни одного запроса на утверждение.", - "APPROVAL_POLICY": "Вы не создали никакой политики одобрения.", - "TIME_OFF": "Вы не создали никакого времени.", + "APPROVAL_REQUEST": "Вы не создали ни одного запроса на одобрение.", + "APPROVAL_POLICY": "Вы не создали ни одной политики одобрения.", + "TIME_OFF": "Вы не создали ни одного отпуска.", "CANDIDATE": "Вы не создали ни одного кандидата.", - "INTERVIEW": "Вы не создали интервью.", - "EQUIPMENT": "Вы не создали никакого снаряжения.", - "EQUIPMENT_SHARING": "Вы не создали никакого обмена снаряжением.", - "EQUIPMENT_SHARING_POLICY": "Вы не создали политики совместного использования оборудования.", + "INTERVIEW": "Вы не создали ни одного интервью.", + "EQUIPMENT": "Вы не создали ни одного оборудования.", + "EQUIPMENT_SHARING": "Вы не создали ни одной записи о совместном использовании оборудования.", + "EQUIPMENT_SHARING_POLICY": "Вы не создали ни одной политики совместного использования оборудования.", "INVENTORY": "Вы не создали ни одного инвентаря.", - "MERCHANT": "Вы не создали торговца.", + "MERCHANT": "Вы не создали ни одного продавца.", "WAREHOUSE": "Вы не создали ни одного склада.", - "WAREHOUSE_PRODUCT": "Здесь нет товаров на складе.", - "PRODUCT_CATEGORY": "Вы не создали ни одной категории товаров.", + "WAREHOUSE_PRODUCT": "Вы не создали ни одного склада продуктов.", + "PRODUCT_CATEGORY": "Вы не создали ни одной категории продуктов.", "TAGS": "Вы не создали ни одного тега.", "PROJECT": "Вы не создали ни одного проекта.", "DEPARTMENT": "Вы не создали ни одного отдела.", "CONTACT": "Вы не создали ни одного контакта.", "CLIENT": "Вы не создали ни одного клиента.", - "LEAD": "Вы не создали ни одного лидера.", - "TIME_FRAME": "Вы не создали ни одного временного промежутка.", - "KPI": "Вы не создали никакой KPI.", + "LEAD": "Вы не создали ни одного потенциального клиента.", + "TIME_FRAME": "Вы не создали ни одного временного периода.", + "KPI": "Вы не создали ни одного KPI.", "INVOICE": "Вы не создали ни одного счета.", "ESTIMATE": "Вы не создали ни одной оценки.", "EVENT_TYPE": "Вы не создали ни одного типа события.", - "PRODUCT_TYPE_NO_DATA": "Вы не создали ни одного типа товара.", - "TEAM_DASHBOARD": "У вас нет ни одной команды", + "PRODUCT_TYPE_NO_DATA": "Вы не создали ни одного типа продукта.", + "TEAM_DASHBOARD": "У вас нет ни одной команды.", "PLUGIN": "Вы не установили ни одного плагина." }, "TRANSACTION_TYPE": "Тип", @@ -1674,6 +1676,7 @@ "APPLIED": "Применяется", "HIRED": "Наклонный", "REJECTED": "Отклонено", + "SHOW_REJECTED": "Показ отклонен", "DELETED": "Удалено", "ARCHIVED": "Архивирован", "SELECT_EMPLOYEE_MSG": "Пожалуйста, выберите сотрудника из меню выше.", @@ -2195,45 +2198,44 @@ "ANONYMOUS": "Анонимный" }, "PROPOSALS_PAGE": { - "HEADER": "Страница управления предложениями", + "HEADER": "Предложения - управление", "STATISTICS": "Статистика", "ACCEPTED_PROPOSALS": "Принятые предложения", "TOTAL_PROPOSALS": "Всего предложений", - "SUCCESS_RATE": "Скорость успеха", + "SUCCESS_RATE": "Успешность", "PROPOSALS": "Предложения", "REGISTER": { - "REGISTER_PROPOSALS": "Регистрация предложения", + "REGISTER_PROPOSALS": "Зарегистрировать предложение", "AUTHOR": "Автор", "TEMPLATE": "Шаблон", - "JOB_POST_URL": "URL записи задания", - "PICK_A_DATE": "Выбрать дату", + "JOB_POST_URL": "URL объявления о работе", + "PICK_A_DATE": "Выберите дату", "PROPOSAL_DATE": "Дата предложения", - "JOB_POST_CONTENT": "Контент должности", - "UPLOAD": "Выгрузить", + "JOB_POST_CONTENT": "Содержание объявления о работе", + "UPLOAD": "Загрузить", "PROPOSALS_CONTENT": "Содержание предложения", - "REGISTER_PROPOSALS_BUTTON": "Регистрация предложения" + "REGISTER_PROPOSALS_BUTTON": "Зарегистрировать предложение" }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "Детали предложения", - "EDIT": "Редактировать", "AUTHOR": "Автор", - "JOB_POST_URL": "URL записи задания", + "JOB_POST_URL": "URL объявления о работе", "PROPOSAL_SENT_ON": "Предложение отправлено", "STATUS": "Статус", - "JOB_POST_CONTENT": "Контент должности", + "JOB_POST_CONTENT": "Содержание объявления о работе", "PROPOSAL_CONTENT": "Содержание предложения", - "VIEW_JOB_POST": "Просмотр должности" + "VIEW_JOB_POST": "Просмотр объявления" }, "EDIT_PROPOSAL": { - "EDIT_PROPOSAL": "Изменить предложение", + "EDIT_PROPOSAL": "Редактировать предложение", "AUTHOR": "Автор", - "JOB_POST_URL": "URL записи задания", + "JOB_POST_URL": "URL объявления о работе", "PROPOSAL_SENT_ON": "Предложение отправлено", - "JOB_POST_CONTENT": "Контент должности", + "JOB_POST_CONTENT": "Содержание объявления о работе", "PROPOSAL_CONTENT": "Содержание предложения", - "EDIT_PROPOSAL_BUTTON": "Изменить предложение", + "EDIT_PROPOSAL_BUTTON": "Редактировать предложение", "PLACEHOLDER": { - "JOB_POST_URL": "URL записи задания" + "JOB_POST_URL": "URL объявления о работе" } } }, @@ -3071,7 +3073,8 @@ "PUBLIC_LINK": { "HEADER": "Сгенерировать публичную ссылку", "GENERATE": "Генерировать ссылку на {{ text }} , которую могут просматривать любой, кто имеет ссылку.", - "ACCESS": "Любой, у кого есть доступ к этой ссылке, может просмотреть {{ text }}." + "ACCESS": "Любой, у кого есть доступ к этой ссылке, может просмотреть {{ text }}.", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3102,7 +3105,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "страница не найдена", "TAKE_ME_HOME": "Вернуть меня домой", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "Страница, которую вы ищете, не существует", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "Страница, которую вы ищете, не существует", "REDIRECT_TO_HOME": "Вы будете перенаправлены на домашнюю страницу в ближайшее время" }, "HELP_PAGE": { @@ -4187,7 +4190,8 @@ }, "ONBOARDING": { "FIRST_ORGANIZATION": "Давайте создадим вашу первую организацию", - "COMPLETE": "Все готово!" + "COMPLETE_TITLE": "Все готово!", + "COMPLETE_SUB_TITLE": "Куда вы хотите пойти сейчас?" }, "VALIDATION": { "FIELD_REQUIRED": "Это поле обязательно!", @@ -4255,7 +4259,8 @@ "SELECT_EMPLOYEE_ERROR": "Пожалуйста, выберите сотрудника.", "EXPIRED_OR_CANCELLED": "**Срок действия контракта истёк или был отменен.", "EMAIL_SENT": "**Отправлено письмо принимающей стороне, а также всем участникам этого совещания.", - "NO_ACTIVE_EVENT_TYpES": "Нет активных типов событий" + "NO_ACTIVE_EVENT_TYPES": "Нет активных типов событий", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "Шаблоны писем", diff --git a/packages/ui-core/i18n/assets/i18n/zh.json b/packages/ui-core/i18n/assets/i18n/zh.json index 7814b60c0dd..ab2c5dfa9ed 100644 --- a/packages/ui-core/i18n/assets/i18n/zh.json +++ b/packages/ui-core/i18n/assets/i18n/zh.json @@ -33,6 +33,7 @@ "INVITE": "邀请", "SELECT_ALL": "选择所有", "COPY_LINK": "复制链接", + "COPIED": "Copied!", "MANAGE_INTERVIEWS": "管理面试", "MANAGE_INVITES": "管理邀请", "MANAGE_SPRINTS": "管理冲刺", @@ -1626,6 +1627,7 @@ "APPLIED": "应用", "HIRED": "雇佣的", "REJECTED": "被拒绝", + "SHOW_REJECTED": "显示被拒绝", "DELETED": "已刪除", "ARCHIVED": "存档", "SELECT_EMPLOYEE_MSG": "请从上面的菜单中选择员工。", @@ -2184,7 +2186,6 @@ }, "PROPOSAL_DETAILS": { "PROPOSAL_DETAILS": "提案细节", - "EDIT": "编辑", "AUTHOR": "作者", "JOB_POST_URL": "職位網址", "PROPOSAL_SENT_ON": "投递日期", @@ -3042,7 +3043,8 @@ "PUBLIC_LINK": { "HEADER": "生成公共链接", "GENERATE": "生成一个链接,任何具有链接的人都可以查看{{ text }}。", - "ACCESS": "任何有权访问此链接的人都可以查看{{ text }}。" + "ACCESS": "任何有权访问此链接的人都可以查看{{ text }}。", + "COPY_TO_CLIPBOARD_TOOLTIP": "Copy public link to clipboard" } }, "PAYMENTS_PAGE": { @@ -3073,7 +3075,7 @@ "PAGE_NOT_FOUND": { "404_PAGE_NOT_FOUND": "页面未找到", "TAKE_ME_HOME": "带我回家", - "THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST": "您正在寻找的页面不存在。", + "THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST": "您正在寻找的页面不存在。", "REDIRECT_TO_HOME": "您将很快被重定向到主页" }, "HELP_PAGE": { @@ -4167,8 +4169,9 @@ "NO_RECORD_FOUND": "没有找到记录。请选择日期范围、员工或项目。" }, "ONBOARDING": { - "FIRST_ORGANIZATION": "让我们创建你的第一个组织。", - "COMPLETE": "你已准备妥当!" + "FIRST_ORGANIZATION": "让我们创建您的第一个组织", + "COMPLETE_TITLE": "你已经准备好了!", + "COMPLETE_SUB_TITLE": "现在你想去哪儿?" }, "VALIDATION": { "FIELD_REQUIRED": "此字段为必填项!", @@ -4236,7 +4239,8 @@ "SELECT_EMPLOYEE_ERROR": "请选择一个员工。", "EXPIRED_OR_CANCELLED": "该约会已过期或已取消。", "EMAIL_SENT": "已经向主持人和所有参会人员发送了一封电子邮件。", - "NO_ACTIVE_EVENT_TYpES": "没有活动类型。" + "NO_ACTIVE_EVENT_TYPES": "没有活动类型。", + "CLICK_HERE": "Click Here" }, "EMAIL_TEMPLATES_PAGE": { "HEADER": "电子邮件模板", diff --git a/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.html b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.html new file mode 100644 index 00000000000..605ebe87cdb --- /dev/null +++ b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.html @@ -0,0 +1,64 @@ + + + + + +
    + +
    +
    +
    + + +
    +

    + {{ 'MENU.APPOINTMENTS' | translate }} +

    +
    + + + + + +
    +
    +
    + {{ 'PUBLIC_APPOINTMENTS.TIMEZONE' | translate }} + + {{ selectedTimeZoneName }} {{ selectedTimeZoneOffset }} + + + {{ 'PUBLIC_APPOINTMENTS.CHANGE' | translate }} + +
    +
    diff --git a/apps/gauzy/src/app/pages/employees/appointment/appointment.component.scss b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.scss similarity index 89% rename from apps/gauzy/src/app/pages/employees/appointment/appointment.component.scss rename to packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.scss index 614c78147b0..26e8c965613 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/appointment.component.scss +++ b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.scss @@ -1,4 +1,4 @@ -@import '../../payments/payments.component.scss'; +@import '@shared/_payments'; .main-header { display: flex; @@ -23,7 +23,7 @@ nb-card-body { height: calc(100vh - 16.5rem) !important; } - .custom-calendar { + .calendar-container { height: 100%; overflow: auto; } diff --git a/apps/gauzy/src/app/pages/employees/appointment/appointment.component.ts b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.ts similarity index 87% rename from apps/gauzy/src/app/pages/employees/appointment/appointment.component.ts rename to packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.ts index b5a86bd6742..2dc1f916ada 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/appointment.component.ts +++ b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.component.ts @@ -13,15 +13,8 @@ import { FullCalendarComponent } from '@fullcalendar/angular'; import momentTimezonePlugin from '@fullcalendar/moment-timezone'; import { TranslateService } from '@ngx-translate/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import moment from 'moment'; +import * as moment from 'moment'; import * as timezone from 'moment-timezone'; -import { - AppointmentEmployeesService, - AvailabilitySlotsService, - EmployeeAppointmentService, - TimeOffService, - ToastrService -} from '@gauzy/ui-core/core'; import { IEmployeeAppointment, ITimeOff, @@ -31,42 +24,34 @@ import { IOrganization, WeekDaysEnum } from '@gauzy/contracts'; -import { Store, convertLocalToTimezone } from '@gauzy/ui-core/common'; +import { convertLocalToTimezone } from '@gauzy/ui-core/common'; +import { + AppointmentEmployeesService, + AvailabilitySlotsService, + EmployeeAppointmentService, + Store, + TimeOffService, + ToastrService +} from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { dayOfWeekAsString } from '@gauzy/ui-core/shared'; -import { TimezoneSelectorComponent } from './timezone-selector/timezone-selector.component'; +import { dayOfWeekAsString } from '../../selectors/date-range-picker/date-picker.utils'; +import { TimezoneSelectorComponent } from '../timezone-selector/timezone-selector.component'; @UntilDestroy({ checkProperties: true }) @Component({ - selector: 'ga-appointment-calendar', - templateUrl: './appointment.component.html', - styleUrls: ['./appointment.component.scss'], + selector: 'ngx-appointment-calendar', + templateUrl: './appointment-calendar.component.html', + styleUrls: ['./appointment-calendar.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => AppointmentComponent), + useExisting: forwardRef(() => AppointmentCalendarComponent), multi: true } ] }) -export class AppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy { +export class AppointmentCalendarComponent extends TranslationBaseComponent implements OnInit, OnDestroy { organization: IOrganization; - - @Input() - showHeader: boolean = true; - - @Input() - appointmentFormURL: string; - - @Input() - employee: IEmployee; - - @Input() - selectedEventType: IEventType; - - @ViewChild('calendar', { static: true }) - calendarComponent: FullCalendarComponent; - selectedTimeZoneName = timezone.tz.guess(); selectedTimeZoneOffset = timezone.tz(this.selectedTimeZoneName).format('Z'); calendarOptions: CalendarOptions; @@ -90,16 +75,29 @@ export class AppointmentComponent extends TranslationBaseComponent implements On right: 'dayGridMonth,timeGridWeek' }; + /** + * Inputs + */ + @Input() showHeader: boolean = true; + @Input() appointmentFormURL: string; + @Input() employee: IEmployee; + @Input() selectedEventType: IEventType; + + /** + * + */ + @ViewChild('calendar', { static: true }) calendarComponent: FullCalendarComponent; + constructor( - private router: Router, - private store: Store, - private toastrService: ToastrService, - private dialogService: NbDialogService, - private availabilitySlotsService: AvailabilitySlotsService, - private employeeAppointmentService: EmployeeAppointmentService, - private timeOffService: TimeOffService, - private appointmentEmployeesService: AppointmentEmployeesService, - readonly translateService: TranslateService + readonly translateService: TranslateService, + private readonly _router: Router, + private readonly _store: Store, + private readonly _toastrService: ToastrService, + private readonly _dialogService: NbDialogService, + private readonly _availabilitySlotsService: AvailabilitySlotsService, + private readonly _employeeAppointmentService: EmployeeAppointmentService, + private readonly _timeOffService: TimeOffService, + private readonly _appointmentEmployeesService: AppointmentEmployeesService ) { super(translateService); } @@ -115,7 +113,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On ? this.selectedEventType.duration * 60 : this.selectedEventType.duration * 1; } - this.store.selectedOrganization$ + this._store.selectedOrganization$ .pipe( filter((organization) => !!organization), untilDestroyed(this) @@ -130,7 +128,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On } } }); - this.store.selectedEmployee$ + this._store.selectedEmployee$ .pipe( filter((employee) => !!employee), untilDestroyed(this), @@ -168,7 +166,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On eventClick: (event) => { const eventObject = event.event; if (eventObject.extendedProps['type'] !== 'BookedSlot') { - this.router.navigate([this.appointmentFormURL || this.getManageRoute(this._selectedEmployeeId)], { + this._router.navigate([this.appointmentFormURL || this.getManageRoute(this._selectedEmployeeId)], { state: { dateStart: eventObject.start, dateEnd: eventObject.end, @@ -199,7 +197,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On config.dateEnd = new Date(nextSlot.end.toString()); } - this.router.navigate( + this._router.navigate( [this.getManageRoute(this._selectedEmployeeId, eventObject.extendedProps['id'])], { state: config } ); @@ -214,13 +212,13 @@ export class AppointmentComponent extends TranslationBaseComponent implements On weekends: true, height: 'auto', dayHeaderDidMount: this.headerMount.bind(this), - firstDay: dayOfWeekAsString(this.store?.selectedOrganization?.startWeekOn || WeekDaysEnum.MONDAY) + firstDay: dayOfWeekAsString(this._store?.selectedOrganization?.startWeekOn || WeekDaysEnum.MONDAY) }; } async fetchTimeOff() { const data = await firstValueFrom( - this.timeOffService.getAllTimeOffRecords(['employees', 'employees.user'], { + this._timeOffService.getAllTimeOffRecords(['employees', 'employees.user'], { organizationId: this._selectedOrganizationId, tenantId: this.organization.tenantId, employeeId: this._selectedEmployeeId || (this.employee && this.employee.id) || null @@ -232,12 +230,12 @@ export class AppointmentComponent extends TranslationBaseComponent implements On bookPublicAppointment() { this._selectedEmployeeId - ? this.router.navigate([`/share/employee/${this._selectedEmployeeId}`]) - : this.router.navigate(['/share/employee']); + ? this._router.navigate([`/share/employee/${this._selectedEmployeeId}`]) + : this._router.navigate(['/share/employee']); } renderAppointmentsAndSlots(employeeId: string) { - const { tenantId } = this.store.user; + const { tenantId } = this._store.user; const findObj = { status: null, organizationId: this.organization.id, @@ -245,7 +243,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On employeeId: employeeId || null }; - this.employeeAppointmentService + this._employeeAppointmentService .getAll(['employee', 'employee.user'], findObj) .pipe(untilDestroyed(this)) .subscribe(async (appointments) => { @@ -264,7 +262,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On // fetch appointments where the employee is an invitee async fetchEmployeeAppointments(employeeId: string) { const employeeAppointments = await firstValueFrom( - this.appointmentEmployeesService.findEmployeeAppointments(employeeId).pipe(untilDestroyed(this)) + this._appointmentEmployeesService.findEmployeeAppointments(employeeId).pipe(untilDestroyed(this)) ); this.renderBookedAppointments( employeeAppointments.map((o) => o.employeeAppointment).filter((o) => o && o.status !== 'Cancelled') @@ -291,7 +289,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On } private async _fetchAvailableSlots(employeeId: string) { - const { tenantId } = this.store.user; + const { tenantId } = this._store.user; const findObj = { organizationId: this._selectedOrganizationId, tenantId, @@ -299,7 +297,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On }; try { - const slots = await this.availabilitySlotsService.getAll([], findObj); + const slots = await this._availabilitySlotsService.getAll([], findObj); this.slots = slots.items; this.dateSpecificSlots = this.slots.filter((o) => o.type === 'Default'); this.recurringSlots = this.slots.filter((o) => o.type === 'Recurring'); @@ -312,14 +310,14 @@ export class AppointmentComponent extends TranslationBaseComponent implements On dayDiff--; } } catch (error) { - this.toastrService.danger('NOTES.AVAILABILITY_SLOTS.ERROR', null, { + this._toastrService.danger('NOTES.AVAILABILITY_SLOTS.ERROR', null, { error: error.error.message || error.message }); } } openEventTypes() { - this.router.navigate(['/pages/employees/event-types']); + this._router.navigate(['/pages/employees/event-types']); } headerMount(config) { @@ -550,8 +548,11 @@ export class AppointmentComponent extends TranslationBaseComponent implements On } } + /** + * Select timezone + */ selectTimezone() { - this.dialogService + this._dialogService .open(TimezoneSelectorComponent, { context: { selectedTimezone: this.selectedTimeZoneName @@ -588,7 +589,7 @@ export class AppointmentComponent extends TranslationBaseComponent implements On } manageAppointments() { - this.router.navigate([this.getManageRoute()]); + this._router.navigate([this.getManageRoute()]); } ngOnDestroy() {} diff --git a/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.module.ts b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.module.ts new file mode 100644 index 00000000000..5f73bfd97cf --- /dev/null +++ b/packages/ui-core/shared/src/lib/appointments/appointment-calendar/appointment-calendar.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { FullCalendarModule } from '@fullcalendar/angular'; +import { NbButtonModule, NbCardModule, NbIconModule, NbSpinnerModule } from '@nebular/theme'; +import { TranslateModule } from '@ngx-translate/core'; +import { + AppointmentEmployeesService, + AvailabilitySlotsService, + EmployeeAppointmentService, + TimeOffService +} from '@gauzy/ui-core/core'; +import { SharedModule } from '../../shared.module'; +import { AppointmentCalendarComponent } from './appointment-calendar.component'; +import { TimezoneSelectorModule } from '../timezone-selector/timezone-selector.module'; + +const NB_MODULES = [NbButtonModule, NbCardModule, NbIconModule, NbSpinnerModule]; + +@NgModule({ + imports: [...NB_MODULES, FullCalendarModule, TranslateModule.forChild(), SharedModule, TimezoneSelectorModule], + exports: [AppointmentCalendarComponent], + declarations: [AppointmentCalendarComponent], + providers: [EmployeeAppointmentService, AppointmentEmployeesService, AvailabilitySlotsService, TimeOffService] +}) +export class AppointmentCalendarModule {} diff --git a/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.component.html b/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.component.html new file mode 100644 index 00000000000..3c5b227c556 --- /dev/null +++ b/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.component.html @@ -0,0 +1,35 @@ + + + {{ 'EMPLOYEE_SCHEDULES_MODAL.EMPLOYEE' | translate }}: + {{ schedule.employeeName }} + + + {{ + (!schedule.slots.length + ? 'EMPLOYEE_SCHEDULES_MODAL.SLOTS_UNAVAILABLE' + : 'EMPLOYEE_SCHEDULES_MODAL.SLOTS_AVAILABLE' + ) | translate + }} +
    + + + - {{ item.startTime }} to {{ item.endTime }}
    +
    +
    +
    +
    + + + + + + + + +
    diff --git a/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.component.ts b/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.component.ts new file mode 100644 index 00000000000..09251a30d6f --- /dev/null +++ b/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.component.ts @@ -0,0 +1,45 @@ +import { Component, OnInit } from '@angular/core'; +import { NbDialogRef } from '@nebular/theme'; +import { TranslateService } from '@ngx-translate/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import * as timezone from 'moment-timezone'; + +/** + * Interface for the employee schedule + */ +export interface EmployeeSchedule { + employeeName: string; + slots: any; + timezone: string; +} + +@Component({ + selector: 'ga-employee-schedules', + templateUrl: './employee-schedule.component.html' +}) +export class EmployeeScheduleComponent extends TranslationBaseComponent implements OnInit { + schedule: EmployeeSchedule; + + constructor( + readonly translateService: TranslateService, + public readonly dialogRef: NbDialogRef + ) { + super(translateService); + } + + ngOnInit() { + this.schedule.slots.forEach((slot: any) => { + slot.startTime = timezone(slot.startTime).tz(this.schedule.timezone).format('LLLL'); + slot.endTime = timezone(slot.endTime).tz(this.schedule.timezone).format('LLLL'); + }); + } + + /** + * Close dialog + * + * @param value + */ + closeDialog(value: string) { + this.dialogRef.close(value); + } +} diff --git a/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.module.ts b/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.module.ts similarity index 53% rename from apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.module.ts rename to packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.module.ts index 47724f65e31..92370b0db29 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/employee-schedules/employee-schedules.module.ts +++ b/packages/ui-core/shared/src/lib/appointments/employee-schedules/employee-schedule.module.ts @@ -1,12 +1,11 @@ import { NgModule } from '@angular/core'; import { NbButtonModule, NbCardModule } from '@nebular/theme'; import { TranslateModule } from '@ngx-translate/core'; -import { EmployeeSchedulesComponent } from './employee-schedules.component'; +import { EmployeeScheduleComponent } from './employee-schedule.component'; @NgModule({ imports: [NbButtonModule, NbCardModule, TranslateModule.forChild()], - exports: [EmployeeSchedulesComponent], - declarations: [EmployeeSchedulesComponent], - providers: [] + exports: [EmployeeScheduleComponent], + declarations: [EmployeeScheduleComponent] }) -export class EmployeeSchedulesModule {} +export class EmployeeScheduleModule {} diff --git a/packages/ui-core/shared/src/lib/appointments/index.ts b/packages/ui-core/shared/src/lib/appointments/index.ts new file mode 100644 index 00000000000..a77778bc200 --- /dev/null +++ b/packages/ui-core/shared/src/lib/appointments/index.ts @@ -0,0 +1,8 @@ +export * from './appointment-calendar/appointment-calendar.component'; +export * from './appointment-calendar/appointment-calendar.module'; +export * from './employee-schedules/employee-schedule.component'; +export * from './employee-schedules/employee-schedule.module'; +export * from './manage-appointment/manage-appointment.component'; +export * from './manage-appointment/manage-appointment.module'; +export * from './timezone-selector/timezone-selector.component'; +export * from './timezone-selector/timezone-selector.module'; diff --git a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.html b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.html similarity index 67% rename from apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.html rename to packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.html index 3b933c4c5ee..e2a26c80d36 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.html +++ b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.html @@ -2,12 +2,7 @@

    - {{ - (editMode - ? 'APPOINTMENTS_PAGE.EDIT_APPOINTMENT' - : 'APPOINTMENTS_PAGE.ADD_APPOINTMENT' - ) | translate - }} + {{ (editMode ? 'APPOINTMENTS_PAGE.EDIT_APPOINTMENT' : 'APPOINTMENTS_PAGE.ADD_APPOINTMENT') | translate }}

    @@ -16,19 +11,14 @@

    - +
    @@ -47,46 +37,34 @@

    name="selectedRange" formControlName="selectedRange" fromEmployeeAppointment="true" - > - + >

  • - {{ - 'APPOINTMENTS_PAGE.BUFFER_TIME' | translate - }} + {{ 'APPOINTMENTS_PAGE.BUFFER_TIME' | translate }}
    - {{ - 'APPOINTMENTS_PAGE.BUFFER_AT_START' - | translate - }} + {{ 'APPOINTMENTS_PAGE.BUFFER_AT_START' | translate }}
    - {{ - 'APPOINTMENTS_PAGE.BUFFER_AT_END' - | translate - }} + {{ 'APPOINTMENTS_PAGE.BUFFER_AT_END' | translate }}
    -
    +
    nbInput [min]="0" formControlName="bufferTimeInMins" - placeholder="{{ - 'FORM.PLACEHOLDERS.BUFFER_TIME' | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.BUFFER_TIME' | translate }}" />
    @@ -110,10 +86,7 @@

    -
    +
    -
    +
    [min]="0" nbInput formControlName="breakTimeInMins" - placeholder="{{ - 'FORM.PLACEHOLDERS.BREAK_TIME' | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.BREAK_TIME' | translate }}" />
    - +
    @@ -172,10 +135,7 @@

    type="text" nbInput formControlName="description" - placeholder="{{ - 'FORM.PLACEHOLDERS.MEETING_DESCRIPTION' - | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.MEETING_DESCRIPTION' | translate }}" >

    @@ -192,17 +152,14 @@

    [selectedEmployeeIds]="selectedEmployeeIds" [allEmployees]="employees" (selectedChange)="onMembersSelected($event)" - > - + >

    - + multiple="true" bindLabel="emailAddress" formControlName="emails" - placeholder="{{ - 'FORM.PLACEHOLDERS.EMAILS' | translate - }}" - notFoundText="{{ - 'FORM.PLACEHOLDERS.EMAILS' | translate - }}" + placeholder="{{ 'FORM.PLACEHOLDERS.EMAILS' | translate }}" + notFoundText="{{ 'FORM.PLACEHOLDERS.EMAILS' | translate }}" appendTo="body" [ngClass]="{ - 'item-invalid': - emails.invalid && - (emails.dirty || emails.touched), - 'item-valid': - emails.valid && - (emails.dirty || emails.touched) + 'item-invalid': emails.invalid && (emails.dirty || emails.touched), + 'item-valid': emails.valid && (emails.dirty || emails.touched) }" > @@ -239,13 +188,7 @@

    - diff --git a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.scss b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.scss similarity index 100% rename from apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.scss rename to packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.scss diff --git a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.ts b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.ts similarity index 75% rename from apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.ts rename to packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.ts index ae22fb9b40e..3b795958618 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.component.ts +++ b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.component.ts @@ -14,36 +14,39 @@ import { Router, ActivatedRoute } from '@angular/router'; import { NbDialogService } from '@nebular/theme'; import { firstValueFrom } from 'rxjs'; import { filter } from 'rxjs/operators'; -import moment from 'moment'; +import * as moment from 'moment'; import * as timezone from 'moment-timezone'; -import { IEmployee, IEmployeeAppointment, IAvailabilitySlot } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { IEmployee, IEmployeeAppointment, IAvailabilitySlot, ID, EmployeeAppointmentStatus } from '@gauzy/contracts'; import { AppointmentEmployeesService, AvailabilitySlotsService, EmployeeAppointmentService, EmployeesService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { AlertModalComponent, EmployeeSelectComponent } from '@gauzy/ui-core/shared'; -import { EmployeeSchedulesComponent } from '../employee-schedules/employee-schedules.component'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { EmployeeScheduleComponent } from '../employee-schedules/employee-schedule.component'; +import { EmployeeSelectComponent } from '../../employee/employee-multi-select/employee-multi-select.component'; +import { AlertModalComponent } from '../../components/alert-modal/alert-modal.component'; @UntilDestroy({ checkProperties: true }) @Component({ selector: 'ga-manage-appointment', templateUrl: './manage-appointment.component.html', - styleUrls: ['./manage-appointment.component.scss'] + styleUrls: ['./manage-appointment.component.scss'], + providers: [AppointmentEmployeesService, AvailabilitySlotsService, EmployeeAppointmentService] }) export class ManageAppointmentComponent extends TranslationBaseComponent implements OnInit, OnDestroy, AfterViewInit { form: UntypedFormGroup; - employees: IEmployee[]; + employees: IEmployee[] = []; + @Input() employee: IEmployee; @Input() employeeAppointment: IEmployeeAppointment; @Input() disabled: boolean; - @Input() appointmentID: string; + @Input() appointmentId: ID; @Input() allowedDuration: number; @Input() hidePrivateFields: boolean = false; @Input() timezone: string; @@ -69,18 +72,18 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme employeeSelector: EmployeeSelectComponent; constructor( - private route: ActivatedRoute, - private router: Router, - private fb: UntypedFormBuilder, - private store: Store, - private dialogService: NbDialogService, - private employeeService: EmployeesService, - private employeeAppointmentService: EmployeeAppointmentService, - private appointmentEmployeesService: AppointmentEmployeesService, - private availabilitySlotsService: AvailabilitySlotsService, - private toastrService: ToastrService, readonly translateService: TranslateService, - private cdr: ChangeDetectorRef + private readonly _route: ActivatedRoute, + private readonly _router: Router, + private readonly _fb: UntypedFormBuilder, + private readonly _store: Store, + private readonly _dialogService: NbDialogService, + private readonly _employeeService: EmployeesService, + private readonly _employeeAppointmentService: EmployeeAppointmentService, + private readonly _appointmentEmployeesService: AppointmentEmployeesService, + private readonly _availabilitySlotsService: AvailabilitySlotsService, + private readonly _toastrService: ToastrService, + private readonly _cdr: ChangeDetectorRef ) { super(translateService); } @@ -100,7 +103,7 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme this.timezoneOffset = timezone.tz(this.timezone).format('Z'); timezone.tz.setDefault(this.timezone); - this.store.selectedOrganization$ + this._store.selectedOrganization$ .pipe( filter((organization) => !!organization), untilDestroyed(this) @@ -116,7 +119,7 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme } ngAfterViewInit() { - this.cdr.detectChanges(); + this._cdr.detectChanges(); } private _patchFormValue() { @@ -153,7 +156,7 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme } private _initializeForm() { - this.form = this.fb.group({ + this.form = this._fb.group({ emails: ['', Validators.compose([Validators.required, this.emailListValidator])], agenda: ['', Validators.required], location: [''], @@ -172,12 +175,12 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme } private async _loadEmployees() { - const { tenantId } = this.store.user; + const { tenantId } = this._store.user; const organizationId = this._selectedOrganizationId; this.employees = ( await firstValueFrom( - this.employeeService + this._employeeService .getAll(['user'], { tenantId, organizationId @@ -188,13 +191,13 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme } private _parseParams() { - this.route.params.pipe(untilDestroyed(this)).subscribe(async (params) => { - const id = params.appointmentId || this.appointmentID; + this._route.params.pipe(untilDestroyed(this)).subscribe(async (params) => { + const id = params.appointmentId || this.appointmentId; if (id) { this.editMode = true; - const appointment = await firstValueFrom(this.employeeAppointmentService.getById(id)); + const appointment = await firstValueFrom(this._employeeAppointmentService.getById(id)); const selectedEmployees = await firstValueFrom( - this.appointmentEmployeesService.getById(appointment.id).pipe(untilDestroyed(this)) + this._appointmentEmployeesService.getById(appointment.id).pipe(untilDestroyed(this)) ); this.selectedEmployeeIds = selectedEmployees.map((o) => o.employeeId); this.selectedEmployeeAppointmentIds = selectedEmployees.map((o) => o.id); @@ -216,7 +219,7 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme async cancelAppointment() { try { - const dialog = this.dialogService.open(AlertModalComponent, { + const dialog = this._dialogService.open(AlertModalComponent, { context: { data: { title: this.getTranslation('APPOINTMENTS_PAGE.CANCEL_APPOINTMENT'), @@ -228,15 +231,15 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme const response = await firstValueFrom(dialog.onClose); if (!!response) { if (response === 'yes') { - await this.employeeAppointmentService.update(this.employeeAppointment.id, { - status: 'Cancelled' + await this._employeeAppointmentService.update(this.employeeAppointment.id, { + status: EmployeeAppointmentStatus.CANCELLED }); - this.toastrService.success('APPOINTMENTS_PAGE.CANCEL_SUCCESS'); + this._toastrService.success('APPOINTMENTS_PAGE.CANCEL_SUCCESS'); history.back(); } } } catch (error) { - this.toastrService.danger( + this._toastrService.danger( this.getTranslation('APPOINTMENTS_PAGE.CANCEL_FAIL'), this.getTranslation('TOASTR.TITLE.ERROR') ); @@ -244,9 +247,9 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme } async fetchAvailabilitySlotsForAllEmployees() { - const { tenantId } = this.store.user; + const { tenantId } = this._store.user; const slots = ( - await this.availabilitySlotsService.getAll([], { + await this._availabilitySlotsService.getAll([], { organizationId: this._selectedOrganizationId, tenantId }) @@ -255,7 +258,11 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme this.employees = this.employees.filter( (e) => e.id !== - (this.employee ? this.employee.id : this.store.selectedEmployee ? this.store.selectedEmployee.id : null) + (this.employee + ? this.employee.id + : this._store.selectedEmployee + ? this._store.selectedEmployee.id + : null) ); this.employees.map((e) => { @@ -288,8 +295,8 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme async onSaveRequest() { try { let tenantId = null; - if (this.store.user) { - tenantId = this.store.user.tenantId; + if (this._store.user) { + tenantId = this._store.user.tenantId; } const employeeAppointmentRequest = { @@ -310,38 +317,38 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme ), employeeId: this.employee ? this.employee.id - : this.store.selectedEmployee - ? this.store.selectedEmployee.id + : this._store.selectedEmployee + ? this._store.selectedEmployee.id : null, organizationId: this._selectedOrganizationId, tenantId }; if (!this.employeeAppointment) { - this.employeeAppointment = await this.employeeAppointmentService.create(employeeAppointmentRequest); + this.employeeAppointment = await this._employeeAppointmentService.create(employeeAppointmentRequest); } else { - await this.employeeAppointmentService.update(this.employeeAppointment.id, employeeAppointmentRequest); + await this._employeeAppointmentService.update(this.employeeAppointment.id, employeeAppointmentRequest); // Removing all previously selected employee ids for (const id of this.selectedEmployeeAppointmentIds) { - await this.appointmentEmployeesService.delete(id); + await this._appointmentEmployeesService.delete(id); } } for (const e of this.selectedEmployeeIds) { - await this.appointmentEmployeesService.add({ + await this._appointmentEmployeesService.add({ employeeId: e, appointmentId: this.employeeAppointment.id, employeeAppointment: this.employeeAppointment }); } - this.toastrService.success('APPOINTMENTS_PAGE.SAVE_SUCCESS'); + this._toastrService.success('APPOINTMENTS_PAGE.SAVE_SUCCESS'); this.employee - ? this.router.navigate([`/share/employee/${this.employee.id}/confirm/${this.employeeAppointment.id}`]) - : this.router.navigate(['/pages/employees/appointments']); + ? this._router.navigate([`/share/employee/${this.employee.id}/confirm/${this.employeeAppointment.id}`]) + : this._router.navigate(['/pages/employees/appointments']); } catch (error) { - this.toastrService.danger('APPOINTMENTS_PAGE.SAVE_FAILED'); + this._toastrService.danger('APPOINTMENTS_PAGE.SAVE_FAILED'); } } @@ -359,9 +366,9 @@ export class ManageAppointmentComponent extends TranslationBaseComponent impleme ); if ((slots.length > 0 && !slotInSelectedRange) || slots.length === 0) { - const dialog = this.dialogService.open(EmployeeSchedulesComponent, { + const dialog = this._dialogService.open(EmployeeScheduleComponent, { context: { - employeeSchedule: { + schedule: { employeeName: this.employees.find((o) => o.id === added).user.name, slots, timezone: this.timezone diff --git a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.module.ts b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.module.ts similarity index 50% rename from apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.module.ts rename to packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.module.ts index 3eda8da62a7..a8bda02d300 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/manage-appointment/manage-appointment.module.ts +++ b/packages/ui-core/shared/src/lib/appointments/manage-appointment/manage-appointment.module.ts @@ -2,37 +2,35 @@ import { NgModule } from '@angular/core'; import { NbButtonModule, NbCardModule, + NbCheckboxModule, NbIconModule, NbInputModule, - NbSpinnerModule, - NbCheckboxModule + NbSpinnerModule } from '@nebular/theme'; import { NgSelectModule } from '@ng-select/ng-select'; import { TranslateModule } from '@ngx-translate/core'; -import { AppointmentEmployeesService } from '@gauzy/ui-core/core'; -import { EmployeeMultiSelectModule, SharedModule, TimerPickerModule } from '@gauzy/ui-core/shared'; +import { SharedModule } from '../../shared.module'; import { ManageAppointmentComponent } from './manage-appointment.component'; -import { EmployeeSchedulesModule } from '../employee-schedules/employee-schedules.module'; -import { ManageAppointmentRoutingModule } from './manage-appointment-routing.module'; +import { EmployeeScheduleModule } from '../employee-schedules/employee-schedule.module'; +import { TimerPickerModule } from '../../timer-picker/timer-picker.module'; +import { EmployeeMultiSelectModule } from '../../employee/employee-multi-select/employee-multi-select.module'; @NgModule({ imports: [ - ManageAppointmentRoutingModule, - NbCardModule, NbButtonModule, - NbInputModule, - EmployeeSchedulesModule, + NbCardModule, + NbCheckboxModule, NbIconModule, + NbInputModule, NbSpinnerModule, - TimerPickerModule, - NbCheckboxModule, - SharedModule, - EmployeeMultiSelectModule, NgSelectModule, - TranslateModule.forChild() + TranslateModule.forChild(), + SharedModule, + EmployeeScheduleModule, + TimerPickerModule, + EmployeeMultiSelectModule ], exports: [ManageAppointmentComponent], - declarations: [ManageAppointmentComponent], - providers: [AppointmentEmployeesService] + declarations: [ManageAppointmentComponent] }) export class ManageAppointmentModule {} diff --git a/apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.component.html b/packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.component.html similarity index 84% rename from apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.component.html rename to packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.component.html index 2089b5e4bc5..f6668c1dfc7 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.component.html +++ b/packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.component.html @@ -21,10 +21,10 @@

    - - diff --git a/apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.component.ts b/packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.component.ts similarity index 84% rename from apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.component.ts rename to packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.component.ts index ccaf5bc522e..3eea769128c 100644 --- a/apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.component.ts +++ b/packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, Input } from '@angular/core'; import { NbDialogRef } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; -import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import * as timezone from 'moment-timezone'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; @Component({ templateUrl: './timezone-selector.component.html' @@ -11,8 +11,12 @@ export class TimezoneSelectorComponent extends TranslationBaseComponent implemen listOfZones = timezone.tz.names().filter((zone) => zone.includes('/')); @Input() selectedTimezone: string; - constructor(public dialogRef: NbDialogRef, private translate: TranslateService) { - super(translate); + + constructor( + private readonly dialogRef: NbDialogRef, + readonly translateService: TranslateService + ) { + super(translateService); } ngOnInit() {} diff --git a/apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.module.ts b/packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.module.ts similarity index 100% rename from apps/gauzy/src/app/pages/employees/appointment/timezone-selector/timezone-selector.module.ts rename to packages/ui-core/shared/src/lib/appointments/timezone-selector/timezone-selector.module.ts diff --git a/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.component.ts b/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.component.ts index a5183407d5d..7fbe5ebdb40 100644 --- a/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.component.ts @@ -5,7 +5,7 @@ import { NbDialogRef } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { filter, tap } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ApprovalPolicyService, ToastrService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FormHelpers } from '../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.module.ts b/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.module.ts index c39a442666c..81e2224e77b 100644 --- a/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.module.ts +++ b/packages/ui-core/shared/src/lib/approval-policy/approval-policy-mutation.module.ts @@ -13,7 +13,7 @@ import { import { NgSelectModule } from '@ng-select/ng-select'; import { TranslateModule } from '@ngx-translate/core'; import { ApprovalPolicyService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ApprovalPolicyMutationComponent } from './approval-policy-mutation.component'; @NgModule({ diff --git a/packages/ui-core/shared/src/lib/approvals/approvals-mutation.component.ts b/packages/ui-core/shared/src/lib/approvals/approvals-mutation.component.ts index 77537c8f78d..f3740277d10 100644 --- a/packages/ui-core/shared/src/lib/approvals/approvals-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/approvals/approvals-mutation.component.ts @@ -14,7 +14,7 @@ import { } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ApprovalPolicyService, EmployeesService, diff --git a/packages/ui-core/shared/src/lib/approvals/approvals-mutation.module.ts b/packages/ui-core/shared/src/lib/approvals/approvals-mutation.module.ts index a7e9b5b3d24..5279d2794bf 100644 --- a/packages/ui-core/shared/src/lib/approvals/approvals-mutation.module.ts +++ b/packages/ui-core/shared/src/lib/approvals/approvals-mutation.module.ts @@ -13,7 +13,7 @@ import { import { NgSelectModule } from '@ng-select/ng-select'; import { TranslateModule } from '@ngx-translate/core'; import { ApprovalPolicyService, RequestApprovalService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { RequestApprovalMutationComponent } from './approvals-mutation.component'; import { EmployeeMultiSelectModule } from '../employee/employee-multi-select/employee-multi-select.module'; import { TagsColorInputModule } from '../tags/tags-color-input/tags-color-input.module'; diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-calendar-info/candidate-calendar-info.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-calendar-info/candidate-calendar-info.component.ts index b7624eb8acd..05c8dd017a7 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-calendar-info/candidate-calendar-info.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-calendar-info/candidate-calendar-info.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { NbDialogRef } from '@nebular/theme'; -import { CandidateInterviewService } from '@gauzy/ui-core/core'; +import { CandidateInterviewService, Store } from '@gauzy/ui-core/core'; import { firstValueFrom } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { FullCalendarComponent } from '@fullcalendar/angular'; @@ -13,7 +13,7 @@ import interactionPlugin, { DateClickArg } from '@fullcalendar/interaction'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import * as moment from 'moment'; import { IOrganization } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-interview-feedback/candidate-interview-feedback.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-interview-feedback/candidate-interview-feedback.component.ts index 43955a81b0e..b8235ff4c32 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-interview-feedback/candidate-interview-feedback.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-interview-feedback/candidate-interview-feedback.component.ts @@ -18,7 +18,7 @@ import { CandidatesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeeSelectorComponent } from '../../selectors/employee'; @Component({ diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-interview-info/candidate-interview-info.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-interview-info/candidate-interview-info.component.ts index e488c951b68..071302b1e4e 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-interview-info/candidate-interview-info.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-interview-info/candidate-interview-info.component.ts @@ -12,7 +12,7 @@ import { EmployeesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidateInterviewMutationComponent } from '../candidate-interview-mutation/candidate-interview-mutation.component'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-criterions-form/candidate-criterions-form.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-criterions-form/candidate-criterions-form.component.ts index e45abd2f86e..ccbcbd628a1 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-criterions-form/candidate-criterions-form.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-criterions-form/candidate-criterions-form.component.ts @@ -2,7 +2,7 @@ import { ICandidateTechnologies, ICandidatePersonalQualities, IOrganization } fr import { Component, OnInit, OnDestroy, Input } from '@angular/core'; import { UntypedFormBuilder } from '@angular/forms'; import { Subject } from 'rxjs'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidatePersonalQualitiesService, CandidateTechnologiesService } from '@gauzy/ui-core/core'; @Component({ diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-form/candidate-interview-form.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-form/candidate-interview-form.component.ts index 3a59a091537..f2d6469e55c 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-form/candidate-interview-form.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-form/candidate-interview-form.component.ts @@ -17,7 +17,7 @@ import { EmployeesService } from '@gauzy/ui-core/core'; import { NbDialogService } from '@nebular/theme'; import { CandidateCalendarInfoComponent } from '../../candidate-calendar-info/candidate-calendar-info.component'; import { firstValueFrom } from 'rxjs'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-mutation.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-mutation.component.ts index d1d551d3e44..15cdc335aa8 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-interview-mutation/candidate-interview-mutation.component.ts @@ -24,7 +24,7 @@ import { EmployeesService, ErrorHandlingService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidateCriterionsFormComponent } from './candidate-criterions-form/candidate-criterions-form.component'; import { CandidateInterviewFormComponent } from './candidate-interview-form/candidate-interview-form.component'; import { CandidateNotificationFormComponent } from './candidate-notification-form/candidate-notification-form.component'; diff --git a/packages/ui-core/shared/src/lib/candidate/candidate-mutation/candidate-mutation.component.ts b/packages/ui-core/shared/src/lib/candidate/candidate-mutation/candidate-mutation.component.ts index 855a4f6c915..84cc1cae79e 100644 --- a/packages/ui-core/shared/src/lib/candidate/candidate-mutation/candidate-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/candidate-mutation/candidate-mutation.component.ts @@ -14,8 +14,8 @@ import { ICandidateSource, IOrganization } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { CandidatesService, ErrorHandlingService, RoleService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { CandidatesService, ErrorHandlingService, RoleService, Store } from '@gauzy/ui-core/core'; import { BasicInfoFormComponent } from '../../user/forms'; import { CandidateCvComponent } from '../candidate-cv/candidate-cv.component'; diff --git a/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.scss b/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.scss index 4879556e75f..c05e0f07eaa 100644 --- a/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.scss +++ b/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.scss @@ -13,3 +13,15 @@ ngx-avatar ::ng-deep .inner-wrapper { margin: 0 10px; } } +.container { + padding: inherit; + display: flex; + align-items: center; + gap: 2%; + input { + width: inherit; + } +} +nb-checkbox { + text-wrap: nowrap; +} diff --git a/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.ts b/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.ts index 2602fc42364..35c81c9f0ac 100644 --- a/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/selectors/base-candidate-selector.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { EMPTY, Observable, catchError, filter, map, of, switchMap } from 'rxjs'; -import { CandidateStatusEnum, ICandidate, IOrganization, IPagination } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { CandidatesService, ErrorHandlingService } from '@gauzy/ui-core/core'; +import { BehaviorSubject, EMPTY, Observable, catchError, combineLatest, filter, map, of, switchMap } from 'rxjs'; +import { CandidateStatusEnum, ICandidate, IPagination } from '@gauzy/contracts'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { CandidatesService, ErrorHandlingService, Store } from '@gauzy/ui-core/core'; @UntilDestroy() @Component({ @@ -11,6 +11,7 @@ import { CandidatesService, ErrorHandlingService } from '@gauzy/ui-core/core'; }) export class BaseCandidateSelectorComponent implements OnInit { public candidates$: Observable; // Observable for an array of Organization candidates + public showRejected$ = new BehaviorSubject(false); constructor( protected readonly _store: Store, @@ -19,24 +20,25 @@ export class BaseCandidateSelectorComponent implements OnInit { ) {} ngOnInit(): void { - this.candidates$ = this._store.selectedOrganization$.pipe( - filter((organization: IOrganization) => !!organization), + this.candidates$ = combineLatest([this._store.selectedOrganization$, this.showRejected$]).pipe( + filter(([organization]) => !!organization), distinctUntilChange(), - switchMap((organization: IOrganization) => { - // Extract project properties + switchMap(([organization, showRejected]) => { const { id: organizationId, tenantId } = organization; // Ensure there is a valid organization if (!organizationId) { - return of([]); // No valid organization, return empty array of candidates + return of([]); } + const status = showRejected ? CandidateStatusEnum.REJECTED : CandidateStatusEnum.APPLIED; + return this._candidatesService .getAll(['user'], { organizationId, tenantId, isActive: true, isArchived: false, - status: CandidateStatusEnum.APPLIED + status: status }) .pipe( map(({ items }: IPagination) => items), @@ -49,10 +51,14 @@ export class BaseCandidateSelectorComponent implements OnInit { untilDestroyed(this) ); }), - // Handle component lifecycle to avoid memory leaks + // Handle component lifecycle to avoid memory leak untilDestroyed(this) ); } + toggleShowRejected() { + this.showRejected$.next(!this.showRejected$.value); + } + ngOnDestroy(): void {} } diff --git a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-multi-select/candidate-multi-select.component.ts b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-multi-select/candidate-multi-select.component.ts index dfb7a1b7877..cd5c6071251 100644 --- a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-multi-select/candidate-multi-select.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-multi-select/candidate-multi-select.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { ICandidate } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidatesService, ErrorHandlingService } from '@gauzy/ui-core/core'; import { BaseCandidateSelectorComponent } from '../base-candidate-selector.component'; diff --git a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.html b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.html index c3a4e6913ee..3b0e261516a 100644 --- a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.html +++ b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.html @@ -1,16 +1,25 @@ - - - - - +
    + + + + + + + + + + {{ 'CANDIDATES_PAGE.SHOW_REJECTED' | translate }} + +
    diff --git a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.ts b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.ts index 824c60938dc..17971846aaf 100644 --- a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.ts +++ b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.component.ts @@ -1,8 +1,10 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { FormControl } from '@angular/forms'; import { UntilDestroy } from '@ngneat/until-destroy'; +import { Observable } from 'rxjs'; +import { map, startWith, switchMap } from 'rxjs/operators'; import { ICandidate } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidatesService, ErrorHandlingService } from '@gauzy/ui-core/core'; import { BaseCandidateSelectorComponent } from '../base-candidate-selector.component'; @@ -14,14 +16,21 @@ import { BaseCandidateSelectorComponent } from '../base-candidate-selector.compo }) export class CandidateSelectComponent extends BaseCandidateSelectorComponent implements OnInit { public select: FormControl = new FormControl(); + public showRejected: boolean = false; + public searchControl: FormControl = new FormControl(); + public filteredCandidates$: Observable; + private candidatesMap: Map = new Map(); + @Input() placeholder: string; @Input() disabled = false; @Input() public set reset(value: boolean | null) { if (value) { this.select.reset(); + this.searchControl.setValue(''); // Clear the search input as well } } @Output() selectedChange = new EventEmitter(); + @ViewChild('autoInput') input; constructor(store: Store, candidatesService: CandidatesService, errorHandlingService: ErrorHandlingService) { super(store, candidatesService, errorHandlingService); @@ -29,13 +38,34 @@ export class CandidateSelectComponent extends BaseCandidateSelectorComponent imp override ngOnInit(): void { super.ngOnInit(); // Call the parent class's ngOnInit function + this.filteredCandidates$ = this.searchControl.valueChanges.pipe( + startWith(''), + switchMap((term) => + this.candidates$.pipe( + map((candidates) => { + this.candidatesMap.clear(); // Clear previous candidates map + candidates.forEach((candidate) => this.candidatesMap.set(candidate.id, candidate)); + return this.filterCandidatesList(candidates, term); + }) + ) + ) + ); + } + + private filterCandidatesList(candidates: ICandidate[], term: string): ICandidate[] { + const lowerTerm = term.toLowerCase(); + return candidates.filter((candidate) => candidate.user?.name.toLowerCase().includes(lowerTerm)); } /** * * @param candidate */ - onCandidateSelected(candidate: ICandidate['id']): void { - this.selectedChange.emit(candidate); + onCandidateSelected(candidateId: ICandidate['id']): void { + const selectedCandidate = this.candidatesMap.get(candidateId); + if (selectedCandidate) { + this.searchControl.setValue(selectedCandidate.user?.name || ''); + this.selectedChange.emit(candidateId); + } } } diff --git a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.module.ts b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.module.ts index 44dd9cb775b..8deccf59b0e 100644 --- a/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.module.ts +++ b/packages/ui-core/shared/src/lib/candidate/selectors/candidate-select/candidate-select.module.ts @@ -1,13 +1,22 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { NbSelectModule } from '@nebular/theme'; +import { NbAutocompleteModule, NbCheckboxModule, NbSelectModule } from '@nebular/theme'; import { TranslateModule } from '@ngx-translate/core'; import { SharedModule } from '../../../shared.module'; import { CandidateSelectComponent } from './candidate-select.component'; @NgModule({ - imports: [CommonModule, FormsModule, ReactiveFormsModule, NbSelectModule, TranslateModule.forChild(), SharedModule], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + NbCheckboxModule, + NbSelectModule, + NbAutocompleteModule, + TranslateModule.forChild(), + SharedModule + ], declarations: [CandidateSelectComponent], exports: [CandidateSelectComponent], providers: [] diff --git a/packages/ui-core/shared/src/lib/card-grid/card-grid.module.ts b/packages/ui-core/shared/src/lib/card-grid/card-grid.module.ts index 1cfe5c68e04..af2404e9478 100644 --- a/packages/ui-core/shared/src/lib/card-grid/card-grid.module.ts +++ b/packages/ui-core/shared/src/lib/card-grid/card-grid.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { NbButtonModule, NbCardModule, NbIconModule } from '@nebular/theme'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { TranslateModule } from '@ngx-translate/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CardGridComponent } from './card-grid.component'; import { CustomViewComponent } from './card-grid-custom.component'; import { NoDataMessageModule } from '../smart-data-layout/no-data-message/no-data-message.module'; diff --git a/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.html b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.html new file mode 100644 index 00000000000..8e6cc5647dd --- /dev/null +++ b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.html @@ -0,0 +1,18 @@ + + + + + + + + {{ tabs | json }} + + diff --git a/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.scss b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.scss new file mode 100644 index 00000000000..8f29a19bea6 --- /dev/null +++ b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.scss @@ -0,0 +1 @@ +/* Add styles specific to your dynamic tabs component */ diff --git a/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.ts b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.ts new file mode 100644 index 00000000000..569e3e78b60 --- /dev/null +++ b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.component.ts @@ -0,0 +1,153 @@ +import { Component, OnInit, Input, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { NbRouteTab } from '@nebular/theme'; +import { TranslateService } from '@ngx-translate/core'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { tap } from 'rxjs/operators'; +import { Subject } from 'rxjs/internal/Subject'; +import { PageTabRegistryConfig, PageTabRegistryService, TabsetRegistryId } from '@gauzy/ui-core/core'; + +@UntilDestroy() +@Component({ + selector: 'gz-dynamic-tabs', + templateUrl: './dynamic-tabs.component.html', + styleUrls: ['./dynamic-tabs.component.scss'], + providers: [] +}) +export class DynamicTabsComponent implements OnInit, OnDestroy { + public tabs: NbRouteTab[] = []; // Define the structure of tabs according to your needs + public reload$ = new Subject(); // Subject to trigger reload of tabs + + @Input() tabsetId!: TabsetRegistryId; + + /** + * Determines if all tabs in the tabset have the tabsetType set to 'route'. + * + * @returns true if all tabs in the tabset have tabsetType set to 'route', false otherwise. + */ + get isRouterTabset(): boolean { + const tabs = this.getRegisteredTabs(this.tabsetId); + + // If there are no tabs or tabs is undefined, assume it's not a router tabset. + if (!tabs || tabs.length === 0) { + return false; + } + + // Check if every tab has tabsetType set to 'route' + return tabs.every((tab) => tab.tabsetType === 'route'); + } + + constructor( + private readonly _cdr: ChangeDetectorRef, + private readonly _pageTabRegistryService: PageTabRegistryService, + private readonly _translateService: TranslateService + ) {} + + ngOnInit(): void { + this._initializeTabs(); + this._applyTranslationOnTabs(); + this._setupReloadTabsListener(); + } + + /** + * Setup listener for reloading tabs. + */ + private _setupReloadTabsListener(): void { + this.reload$ + .pipe( + tap(() => this._initializeTabs()), + untilDestroyed(this) + ) + .subscribe(); + } + + /** + * Initializes the tabs for the component based on the provided tabset ID. + * + * This function retrieves all registered tabs for the specified tabset ID + * using the `getRegisteredNbTabs` method and assigns them to the `tabs` + * property. This allows the component to display the correct set of tabs + * dynamically. + */ + private _initializeTabs(): void { + // Retrieve and set the tabs based on the tabsetId + this.tabs = this.getRegisteredNbTabs(this.tabsetId); + this._cdr.detectChanges(); + } + + /** + * Retrieve and filter tabs for a specified tabset. + * + * @param tabsetId The identifier for the tabset. + * @returns An array of PageTabRegistryConfig objects for the specified tabset, excluding tabs with hide set to true. + */ + private getRegisteredTabs(tabsetId: TabsetRegistryId): PageTabRegistryConfig[] { + return this._pageTabRegistryService.getPageTabset(tabsetId).filter((tab: PageTabRegistryConfig) => !tab.hide); + } + + /** + * Get all registered tabs for a specified tabset. + * + * This function retrieves the registered tabs from the PageTabRegistryService + * and maps each tab configuration to an NbRouteTab object, which can be used + * by the Nebular tabset component. The title is translated if necessary, + * and other properties like icon, disabled state, responsive behavior, and route + * are mapped accordingly. + * + * @param tabsetId The identifier for the tabset. + * @returns An array of NbRouteTab objects representing the registered tabs. + */ + getRegisteredNbTabs(tabsetId: TabsetRegistryId): NbRouteTab[] { + // Map each tab configuration to an NbRouteTab object + return this.getRegisteredTabs(tabsetId).map((tab: PageTabRegistryConfig): NbRouteTab => { + // Create a new route object + const route: NbRouteTab = { + ...(tab.tabTitle && { + title: typeof tab.tabTitle === 'function' ? tab.tabTitle() : tab.tabTitle + }), + ...(tab.route && { route: tab.route }), + ...(tab.tabIcon && { icon: tab.tabIcon }), + ...(tab.responsive && { responsive: tab.responsive }), + ...(tab.activeLinkOptions && { activeLinkOptions: tab.activeLinkOptions }), + disabled: !!tab.disabled + }; + + // Return the route object + return route; + }); + } + + /** + * Applies translations to dynamic tabs. + * + * This function listens for language change events and re-initializes the tabs + * when the language changes. This ensures that the tabs are always displayed + * in the correct language. + */ + private _applyTranslationOnTabs(): void { + // Listen for language change events from the translation service + this._translateService.onLangChange + .pipe( + // Re-initialize the tabs when the language changes + tap(() => this._initializeTabs()), + // Automatically unsubscribe when the component is destroyed + untilDestroyed(this) + ) + .subscribe(); + } + + /** + * Create dynamic components for the tabs + */ + createDynamicComponents(): void { + // Add logic to create dynamic components for the tabset + } + + /** + * Create static tabs for the tabset + */ + createStaticTabs(): void { + // Add logic to create static tabs for NbTabsetComponent if necessary + } + + ngOnDestroy(): void {} +} diff --git a/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.module.ts b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.module.ts new file mode 100644 index 00000000000..eb5075eb657 --- /dev/null +++ b/packages/ui-core/shared/src/lib/components/dynamic-tabs/dynamic-tabs.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NbRouteTabsetModule, NbTabsetModule } from '@nebular/theme'; +import { DynamicTabsComponent } from './dynamic-tabs.component'; + +// Nebular Modules +const NB_MODULES = [NbTabsetModule, NbRouteTabsetModule]; + +@NgModule({ + imports: [CommonModule, ...NB_MODULES], + declarations: [DynamicTabsComponent], + exports: [DynamicTabsComponent] +}) +export class DynamicTabsModule {} diff --git a/packages/ui-core/shared/src/lib/components/header-title/header-title.component.ts b/packages/ui-core/shared/src/lib/components/header-title/header-title.component.ts index 4533889a177..1d18ca7ebf4 100644 --- a/packages/ui-core/shared/src/lib/components/header-title/header-title.component.ts +++ b/packages/ui-core/shared/src/lib/components/header-title/header-title.component.ts @@ -3,7 +3,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { combineLatest } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { IOrganization, ISelectedEmployee, PermissionsEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/components/index.ts b/packages/ui-core/shared/src/lib/components/index.ts index ba70987107a..91fc375acce 100644 --- a/packages/ui-core/shared/src/lib/components/index.ts +++ b/packages/ui-core/shared/src/lib/components/index.ts @@ -8,3 +8,5 @@ export * from './header-title/header-title.component'; export * from './layout-selector/layout-selector.component'; export * from './popup/popup.component'; export * from './search-input/search-input.component'; +export * from './dynamic-tabs/dynamic-tabs.component'; +export * from './dynamic-tabs/dynamic-tabs.module'; diff --git a/packages/ui-core/shared/src/lib/components/layout-selector/layout-selector.component.ts b/packages/ui-core/shared/src/lib/components/layout-selector/layout-selector.component.ts index 868009d665e..e730448d3cb 100644 --- a/packages/ui-core/shared/src/lib/components/layout-selector/layout-selector.component.ts +++ b/packages/ui-core/shared/src/lib/components/layout-selector/layout-selector.component.ts @@ -1,7 +1,8 @@ import { Component, OnDestroy, OnInit, Input } from '@angular/core'; -import { ComponentLayoutStyleEnum } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { ComponentEnum, Store } from '@gauzy/ui-core/common'; +import { ComponentLayoutStyleEnum } from '@gauzy/contracts'; +import { ComponentEnum } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/contact-select/contact-select.component.ts b/packages/ui-core/shared/src/lib/contact-select/contact-select.component.ts index 7437287d080..c782139c646 100644 --- a/packages/ui-core/shared/src/lib/contact-select/contact-select.component.ts +++ b/packages/ui-core/shared/src/lib/contact-select/contact-select.component.ts @@ -6,7 +6,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { ContactType, IOrganization, IOrganizationContact, PermissionsEnum } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { OrganizationContactService, ErrorHandlingService, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/contact-selector/contact-selector.component.ts b/packages/ui-core/shared/src/lib/contact-selector/contact-selector.component.ts index 6a0d865e996..0cceed61750 100644 --- a/packages/ui-core/shared/src/lib/contact-selector/contact-selector.component.ts +++ b/packages/ui-core/shared/src/lib/contact-selector/contact-selector.component.ts @@ -5,7 +5,7 @@ import { Observable, Subject } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ToastrService } from '@gauzy/ui-core/core'; import { OrganizationContactService } from '@gauzy/ui-core/core'; diff --git a/packages/ui-core/shared/src/lib/dashboard/concretes/strategies/localstorage-strategy.class.ts b/packages/ui-core/shared/src/lib/dashboard/concretes/strategies/local-storage-strategy.class.ts similarity index 91% rename from packages/ui-core/shared/src/lib/dashboard/concretes/strategies/localstorage-strategy.class.ts rename to packages/ui-core/shared/src/lib/dashboard/concretes/strategies/local-storage-strategy.class.ts index 1e2d61f7b72..8bde1a1757d 100644 --- a/packages/ui-core/shared/src/lib/dashboard/concretes/strategies/localstorage-strategy.class.ts +++ b/packages/ui-core/shared/src/lib/dashboard/concretes/strategies/local-storage-strategy.class.ts @@ -1,6 +1,6 @@ import { BackupStrategy, GuiDrag } from '@gauzy/ui-core/common'; -export class LocalstorageStrategy implements BackupStrategy { +export class LocalStorageStrategy implements BackupStrategy { private _serializables: Partial[]; constructor() {} @@ -25,23 +25,19 @@ export class LocalstorageStrategy implements BackupStrategy { : []; } - /** - * - * @returns - */ serialize(): Partial[] { return this.serializables.map((restored: Partial) => restored.toObject()); } /** - * + * Get all serializables */ public get serializables(): Partial[] { return this._serializables; } /** - * + * Set all serializables */ public set serializables(value: Partial[]) { this._serializables = value; diff --git a/packages/ui-core/shared/src/lib/dashboard/profit-history/profit-history.component.ts b/packages/ui-core/shared/src/lib/dashboard/profit-history/profit-history.component.ts index da3e45fcf77..5b90e1fc50a 100644 --- a/packages/ui-core/shared/src/lib/dashboard/profit-history/profit-history.component.ts +++ b/packages/ui-core/shared/src/lib/dashboard/profit-history/profit-history.component.ts @@ -7,7 +7,7 @@ import { NbDialogRef } from '@nebular/theme'; import { LocalDataSource, Cell } from 'angular2-smart-table'; import { IEmployeeStatisticsHistory, IOrganization } from '@gauzy/contracts'; import { distinctUntilChange } from '@gauzy/ui-core/common'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { PaginationFilterBaseComponent } from '../../smart-data-layout/pagination/pagination-filter-base.component'; import { ExpenseTableComponent } from './table-components/expense-table.component'; import { IncomeTableComponent } from './table-components/income-table.component'; diff --git a/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/expense-table.component.ts b/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/expense-table.component.ts index fc2e9cd768e..e7f28d295bc 100644 --- a/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/expense-table.component.ts +++ b/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/expense-table.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/income-table.component.ts b/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/income-table.component.ts index f4dfc0bf9fa..82f84421c78 100644 --- a/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/income-table.component.ts +++ b/packages/ui-core/shared/src/lib/dashboard/profit-history/table-components/income-table.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/dashboard/widget/widget.service.ts b/packages/ui-core/shared/src/lib/dashboard/widget/widget.service.ts index 8b9e9a20603..067939ac026 100644 --- a/packages/ui-core/shared/src/lib/dashboard/widget/widget.service.ts +++ b/packages/ui-core/shared/src/lib/dashboard/widget/widget.service.ts @@ -2,10 +2,11 @@ import { Injectable, OnDestroy, TemplateRef } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Subject } from 'rxjs/internal/Subject'; import { filter, tap } from 'rxjs/operators'; -import { BackupStrategy, GuiDrag, Store } from '@gauzy/ui-core/common'; +import { BackupStrategy, GuiDrag } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { LayoutPersistance } from '../concretes/contexts/layout-persistance.class'; import { PersistanceTakers } from '../concretes/contexts/persistance-takers.class'; -import { LocalstorageStrategy } from '../concretes/strategies/localstorage-strategy.class'; +import { LocalStorageStrategy } from '../concretes/strategies/local-storage-strategy.class'; @UntilDestroy({ checkProperties: true }) @Injectable({ @@ -22,7 +23,7 @@ export class WidgetService implements OnDestroy { constructor(private readonly store: Store) { this._widgetLayoutPersistance = new LayoutPersistance(); - this._localStorage = new LocalstorageStrategy(); + this._localStorage = new LocalStorageStrategy(); this._widgetsTakers = new PersistanceTakers(this._widgetLayoutPersistance); this._widgets$ = new Subject(); this._widgets$ diff --git a/packages/ui-core/shared/src/lib/dashboard/window/window.service.ts b/packages/ui-core/shared/src/lib/dashboard/window/window.service.ts index 75a4c0bd9a6..69cab23bfd6 100644 --- a/packages/ui-core/shared/src/lib/dashboard/window/window.service.ts +++ b/packages/ui-core/shared/src/lib/dashboard/window/window.service.ts @@ -2,10 +2,11 @@ import { Injectable, OnDestroy, TemplateRef } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Subject } from 'rxjs/internal/Subject'; import { filter, tap } from 'rxjs/operators'; -import { BackupStrategy, GuiDrag, Store } from '@gauzy/ui-core/common'; +import { BackupStrategy, GuiDrag } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { LayoutPersistance } from '../concretes/contexts/layout-persistance.class'; import { PersistanceTakers } from '../concretes/contexts/persistance-takers.class'; -import { LocalstorageStrategy } from '../concretes/strategies/localstorage-strategy.class'; +import { LocalStorageStrategy } from '../concretes/strategies/local-storage-strategy.class'; @UntilDestroy({ checkProperties: true }) @Injectable({ @@ -22,7 +23,7 @@ export class WindowService implements OnDestroy { constructor(private readonly store: Store) { this._windowLayoutPersistance = new LayoutPersistance(); - this._localStorage = new LocalstorageStrategy(); + this._localStorage = new LocalStorageStrategy(); this._windowsTakers = new PersistanceTakers(this._windowLayoutPersistance); this._windows$ = new Subject(); this._windows$ diff --git a/packages/ui-core/shared/src/lib/dialogs/quick-actions/quick-actions.component.ts b/packages/ui-core/shared/src/lib/dialogs/quick-actions/quick-actions.component.ts index c8222b38a7b..6558588c8a5 100644 --- a/packages/ui-core/shared/src/lib/dialogs/quick-actions/quick-actions.component.ts +++ b/packages/ui-core/shared/src/lib/dialogs/quick-actions/quick-actions.component.ts @@ -2,8 +2,8 @@ import { Component, Input, OnInit } from '@angular/core'; import { NbDialogRef, NbIconLibraries, NbMenuItem, NbMenuService } from '@nebular/theme'; import { TimeLogType } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; -import { TimeTrackerService } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { TimeTrackerService } from '@gauzy/ui-core/core'; type GroupType = { groupTitle: string; diff --git a/packages/ui-core/shared/src/lib/directives/index.ts b/packages/ui-core/shared/src/lib/directives/index.ts index c0636cf38b5..0eecf4dd9f5 100644 --- a/packages/ui-core/shared/src/lib/directives/index.ts +++ b/packages/ui-core/shared/src/lib/directives/index.ts @@ -7,6 +7,7 @@ import { ReadMoreDirective } from './read-more'; import { TimeTrackingAuthorizedDirective } from './time-tracking-authorized-directive'; import { NoSpaceEdgesDirective } from './no-space-edges.directive'; import { TextMaskDirective } from './text-mask.directive'; +import { TriggerParentClickDirective } from './trigger-parent-click.directive'; export { AutocompleteOffDirective } from './autocomplete-off.directive'; export { DebounceClickDirective } from './debounce-click.directive'; @@ -17,6 +18,7 @@ export { ReadMoreDirective } from './read-more'; export { TimeTrackingAuthorizedDirective } from './time-tracking-authorized-directive'; export { NoSpaceEdgesDirective } from './no-space-edges.directive'; export { TextMaskDirective } from './text-mask.directive'; +export { TriggerParentClickDirective } from './trigger-parent-click.directive'; export const DIRECTIVES = [ AutocompleteOffDirective, @@ -27,5 +29,6 @@ export const DIRECTIVES = [ OutsideDirective, UnderConstructionDirective, NoSpaceEdgesDirective, - TextMaskDirective + TextMaskDirective, + TriggerParentClickDirective ]; diff --git a/packages/ui-core/shared/src/lib/directives/time-tracking-authorized-directive.ts b/packages/ui-core/shared/src/lib/directives/time-tracking-authorized-directive.ts index 44120455549..954b1d0f4e7 100644 --- a/packages/ui-core/shared/src/lib/directives/time-tracking-authorized-directive.ts +++ b/packages/ui-core/shared/src/lib/directives/time-tracking-authorized-directive.ts @@ -3,7 +3,8 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import * as camelcase from 'camelcase'; import { IOrganization } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Directive({ diff --git a/packages/ui-core/shared/src/lib/directives/trigger-parent-click.directive.ts b/packages/ui-core/shared/src/lib/directives/trigger-parent-click.directive.ts new file mode 100644 index 00000000000..92a1d09cf29 --- /dev/null +++ b/packages/ui-core/shared/src/lib/directives/trigger-parent-click.directive.ts @@ -0,0 +1,23 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; + +@Directive({ + selector: '[triggerParentClick]' +}) +export class TriggerParentClickDirective { + constructor(private readonly el: ElementRef) {} + + @HostListener('click', ['$event']) + onClick(event: Event) { + // Get the parent element + const parent = this.el.nativeElement.parentElement; + + // Trigger the click event on the parent element + if (parent) { + const parentClickEvent = new MouseEvent('click', { bubbles: false, cancelable: true }); + parent.dispatchEvent(parentClickEvent); + } + + // Stop the event from propagating to prevent any other handlers + event.stopPropagation(); + } +} diff --git a/packages/ui-core/shared/src/lib/employee/edit-employee-membership-form/edit-employee-membership-form.component.ts b/packages/ui-core/shared/src/lib/employee/edit-employee-membership-form/edit-employee-membership-form.component.ts index 98ec5ed952a..8f353c912be 100644 --- a/packages/ui-core/shared/src/lib/employee/edit-employee-membership-form/edit-employee-membership-form.component.ts +++ b/packages/ui-core/shared/src/lib/employee/edit-employee-membership-form/edit-employee-membership-form.component.ts @@ -1,7 +1,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { IBaseEntityWithMembers, IEditEntityByMemberInput, IEmployee, IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-edit-employee-membership', diff --git a/packages/ui-core/shared/src/lib/employee/employee-location/employee-location.component.ts b/packages/ui-core/shared/src/lib/employee/employee-location/employee-location.component.ts index 51afeccc885..86ea371c18a 100644 --- a/packages/ui-core/shared/src/lib/employee/employee-location/employee-location.component.ts +++ b/packages/ui-core/shared/src/lib/employee/employee-location/employee-location.component.ts @@ -4,7 +4,7 @@ import { IEmployee, ICandidate } from '@gauzy/contracts'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { LatLng } from 'leaflet'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidateStore, EmployeeStore } from '@gauzy/ui-core/core'; import { LeafletMapComponent, LocationFormComponent } from '../../forms'; diff --git a/packages/ui-core/shared/src/lib/employee/employee-multi-select/employee-multi-select.component.ts b/packages/ui-core/shared/src/lib/employee/employee-multi-select/employee-multi-select.component.ts index 69c6cc55fa7..7c148246150 100644 --- a/packages/ui-core/shared/src/lib/employee/employee-multi-select/employee-multi-select.component.ts +++ b/packages/ui-core/shared/src/lib/employee/employee-multi-select/employee-multi-select.component.ts @@ -5,7 +5,7 @@ import { debounceTime } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IDateRangePicker, IEmployee, IOrganization, PermissionsEnum } from '@gauzy/contracts'; import { DateRangePickerBuilderService, EmployeesService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/employee/employee-mutation/employee-mutation.component.ts b/packages/ui-core/shared/src/lib/employee/employee-mutation/employee-mutation.component.ts index fb9ec31efb6..82aa92b58ce 100644 --- a/packages/ui-core/shared/src/lib/employee/employee-mutation/employee-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/employee/employee-mutation/employee-mutation.component.ts @@ -4,8 +4,14 @@ import { NbDialogRef, NbStepperComponent, NbTagComponent } from '@nebular/theme' import { filter, firstValueFrom, tap } from 'rxjs'; import { IEmployee, IUser, IEmployeeCreateInput, CrudActionEnum, IOrganization } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { EmployeeStore, EmployeesService, ErrorHandlingService, OrganizationsService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { + EmployeeStore, + EmployeesService, + ErrorHandlingService, + OrganizationsService, + Store +} from '@gauzy/ui-core/core'; import { BasicInfoFormComponent } from '../../user/forms'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/employee/employee-rates/employee-rates.component.ts b/packages/ui-core/shared/src/lib/employee/employee-rates/employee-rates.component.ts index e690b899603..bc57fac59e9 100644 --- a/packages/ui-core/shared/src/lib/employee/employee-rates/employee-rates.component.ts +++ b/packages/ui-core/shared/src/lib/employee/employee-rates/employee-rates.component.ts @@ -3,7 +3,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms import { IEmployee, PayPeriodEnum, ICandidate, ICurrency } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, tap } from 'rxjs'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CandidateStore, EmployeeStore } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/employee/index.ts b/packages/ui-core/shared/src/lib/employee/index.ts index e75848193b2..97f963b5458 100644 --- a/packages/ui-core/shared/src/lib/employee/index.ts +++ b/packages/ui-core/shared/src/lib/employee/index.ts @@ -10,7 +10,5 @@ export * from './employee-mutation/employee-mutation.component'; export * from './employee-mutation/employee-mutation.module'; export * from './employee-rates/employee-rates.component'; export * from './employee-rates/employee-rates.module'; -export * from './public-page-employee-mutation/public-page-employee-mutation.component'; -export * from './public-page-employee-mutation/public-page-employee-mutation.module'; export * from './employee-start-work/employee-start-work.component'; export * from './employee-start-work/employee-start-work.module'; diff --git a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.scss b/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.scss deleted file mode 100644 index 1e9c4923c2e..00000000000 --- a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../organizations/public-page-mutation/public-page-mutation.component.scss'; \ No newline at end of file diff --git a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.module.ts b/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.module.ts deleted file mode 100644 index fe7cfcd4411..00000000000 --- a/packages/ui-core/shared/src/lib/employee/public-page-employee-mutation/public-page-employee-mutation.module.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { CommonModule } from '@angular/common'; -import { - NbCardModule, - NbListModule, - NbActionsModule, - NbButtonModule, - NbIconModule, - NbDatepickerModule, - NbInputModule, - NbSelectModule, - NbCheckboxModule, - NbTooltipModule, - NbBadgeModule, - NbToggleModule, - NbTabsetModule, - NbTagModule -} from '@nebular/theme'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { CKEditorModule } from 'ckeditor4-angular'; -import { TranslateModule } from '@ngx-translate/core'; -import { SharedModule } from '../../shared.module'; -import { PublicPageEmployeeMutationComponent } from './public-page-employee-mutation.component'; -import { SkillsInputModule } from '../../skills/skills-input/skills-input.module'; -import { TagsColorInputModule } from '../../tags/tags-color-input/tags-color-input.module'; -import { LanguageSelectorModule } from '../../language/language-selector'; -import { CurrencyModule } from '../../modules/currency'; - -@NgModule({ - imports: [ - CommonModule, - SkillsInputModule, - SharedModule, - FormsModule, - NbCardModule, - NbListModule, - NbActionsModule, - ReactiveFormsModule, - NbButtonModule, - NbIconModule, - NgSelectModule, - NbDatepickerModule, - NbInputModule, - NbSelectModule, - NbCheckboxModule, - NbTooltipModule, - SkillsInputModule, - TranslateModule.forChild(), - NbBadgeModule, - NbToggleModule, - NbTabsetModule, - CKEditorModule, - TagsColorInputModule, - CurrencyModule, - LanguageSelectorModule, - NbTagModule - ], - declarations: [PublicPageEmployeeMutationComponent], - providers: [] -}) -export class PublicPageEmployeeMutationModule {} diff --git a/packages/ui-core/shared/src/lib/equipment/equipment-mutation.component.ts b/packages/ui-core/shared/src/lib/equipment/equipment-mutation.component.ts index 7b7249bee73..82c96664aff 100644 --- a/packages/ui-core/shared/src/lib/equipment/equipment-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/equipment/equipment-mutation.component.ts @@ -8,7 +8,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { environment as ENV } from '@gauzy/ui-config'; import { EquipmentService, ImageAssetService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { SelectAssetComponent } from '../select-asset-modal/select-asset.component'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/equipment/equipment-mutation.module.ts b/packages/ui-core/shared/src/lib/equipment/equipment-mutation.module.ts index 22b55e9c5c2..51562955b1a 100644 --- a/packages/ui-core/shared/src/lib/equipment/equipment-mutation.module.ts +++ b/packages/ui-core/shared/src/lib/equipment/equipment-mutation.module.ts @@ -10,7 +10,7 @@ import { NbCheckboxModule } from '@nebular/theme'; import { TranslateModule } from '@ngx-translate/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EquipmentService, ImageAssetService } from '@gauzy/ui-core/core'; import { TagsColorInputModule } from '../tags/tags-color-input/tags-color-input.module'; import { CurrencyModule } from '../modules/currency/currency.module'; diff --git a/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.component.ts b/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.component.ts index 189968b1697..e73488744ad 100644 --- a/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.component.ts @@ -13,7 +13,7 @@ import { EquipmentSharingParticipantEnum } from '@gauzy/contracts'; import { NbDialogRef } from '@nebular/theme'; -import { Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { filter } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; @@ -22,7 +22,8 @@ import { EquipmentService, EquipmentSharingPolicyService, EquipmentSharingService, - OrganizationTeamsService + OrganizationTeamsService, + Store } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; diff --git a/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.module.ts b/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.module.ts index c9611520fba..685323d9ba7 100644 --- a/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.module.ts +++ b/packages/ui-core/shared/src/lib/equipment/equipment-sharing/equipment-sharing-mutation.module.ts @@ -13,7 +13,7 @@ import { } from '@nebular/theme'; import { NgSelectModule } from '@ng-select/ng-select'; import { TranslateModule } from '@ngx-translate/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EquipmentService, EquipmentSharingPolicyService, EquipmentSharingService } from '@gauzy/ui-core/core'; import { EmployeeMultiSelectModule } from '../../employee/employee-multi-select/employee-multi-select.module'; import { EquipmentSharingMutationComponent } from './equipment-sharing-mutation.component'; diff --git a/packages/ui-core/shared/src/lib/expenses/expense-category-select/expense-category-select.component.ts b/packages/ui-core/shared/src/lib/expenses/expense-category-select/expense-category-select.component.ts index 1e3db700775..3e32cefc7a1 100644 --- a/packages/ui-core/shared/src/lib/expenses/expense-category-select/expense-category-select.component.ts +++ b/packages/ui-core/shared/src/lib/expenses/expense-category-select/expense-category-select.component.ts @@ -5,7 +5,7 @@ import { Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ErrorHandlingService, OrganizationExpenseCategoriesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/expenses/expenses-mutation/expenses-mutation.component.ts b/packages/ui-core/shared/src/lib/expenses/expenses-mutation/expenses-mutation.component.ts index 14f0e98a443..ee48f423edd 100644 --- a/packages/ui-core/shared/src/lib/expenses/expenses-mutation/expenses-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/expenses/expenses-mutation/expenses-mutation.component.ts @@ -17,8 +17,8 @@ import { ICurrency } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { OrganizationSettingService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { OrganizationSettingService, Store } from '@gauzy/ui-core/core'; import { AttachReceiptComponent } from './attach-receipt/attach-receipt.component'; import { FormHelpers } from '../../forms/helpers'; import { ALL_EMPLOYEES_SELECTED } from '../../selectors/employee/default-employee'; diff --git a/packages/ui-core/shared/src/lib/expenses/recurring-expense-history/recurring-expense-history.component.ts b/packages/ui-core/shared/src/lib/expenses/recurring-expense-history/recurring-expense-history.component.ts index 36971104e84..07dbc30f69c 100644 --- a/packages/ui-core/shared/src/lib/expenses/recurring-expense-history/recurring-expense-history.component.ts +++ b/packages/ui-core/shared/src/lib/expenses/recurring-expense-history/recurring-expense-history.component.ts @@ -2,9 +2,9 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { debounceTime, filter, tap } from 'rxjs/operators'; -import { monthNames } from '@gauzy/ui-core/core'; +import { Store, monthNames } from '@gauzy/ui-core/core'; import { IOrganization, IRecurringExpenseModel } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/expenses/recurring-expense-mutation/recurring-expense-mutation.component.ts b/packages/ui-core/shared/src/lib/expenses/recurring-expense-mutation/recurring-expense-mutation.component.ts index a23ada139ff..72652c9a28b 100644 --- a/packages/ui-core/shared/src/lib/expenses/recurring-expense-mutation/recurring-expense-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/expenses/recurring-expense-mutation/recurring-expense-mutation.component.ts @@ -12,6 +12,7 @@ import { ErrorHandlingService, ExpenseCategoriesStoreService, OrganizationRecurringExpenseService, + Store, ToastrService, defaultDateFormat } from '@gauzy/ui-core/core'; @@ -24,7 +25,7 @@ import { IOrganization, IExpenseCategory } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { EmployeeSelectorComponent } from '../../selectors/employee/employee.component'; import { DEFAULT_CATEGORIES } from './recurring-expense.setting'; diff --git a/packages/ui-core/shared/src/lib/feature-toggle/feature-toggle.component.ts b/packages/ui-core/shared/src/lib/feature-toggle/feature-toggle.component.ts index a89f2ebf27f..cf206951970 100644 --- a/packages/ui-core/shared/src/lib/feature-toggle/feature-toggle.component.ts +++ b/packages/ui-core/shared/src/lib/feature-toggle/feature-toggle.component.ts @@ -9,7 +9,7 @@ import * as _ from 'underscore'; import { environment } from '@gauzy/ui-config'; import { IFeature, IFeatureOrganization, IFeatureToggle, IOrganization, IUser } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { FeatureStoreService } from '@gauzy/ui-core/core'; import { CountdownConfirmationComponent } from '../user/forms'; diff --git a/packages/ui-core/shared/src/lib/file-uploader-input/file-uploader-input.component.ts b/packages/ui-core/shared/src/lib/file-uploader-input/file-uploader-input.component.ts index 08a577b5083..fca77e71f7f 100644 --- a/packages/ui-core/shared/src/lib/file-uploader-input/file-uploader-input.component.ts +++ b/packages/ui-core/shared/src/lib/file-uploader-input/file-uploader-input.component.ts @@ -1,7 +1,7 @@ import { Component, Input, Output, EventEmitter, AfterViewInit, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; import { IImageAsset } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ImageUploaderBaseComponent } from '../image-uploader/image-uploader-base.component'; @Component({ diff --git a/packages/ui-core/shared/src/lib/goal/goal-custom-unit/goal-custom-unit-select.component.ts b/packages/ui-core/shared/src/lib/goal/goal-custom-unit/goal-custom-unit-select.component.ts index 4bef4ba2093..d5403ca94b2 100644 --- a/packages/ui-core/shared/src/lib/goal/goal-custom-unit/goal-custom-unit-select.component.ts +++ b/packages/ui-core/shared/src/lib/goal/goal-custom-unit/goal-custom-unit-select.component.ts @@ -3,7 +3,7 @@ import { UntypedFormGroup } from '@angular/forms'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { environment as ENV } from '@gauzy/ui-config'; import { KeyResultTypeEnum, KeyResultNumberUnitsEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/goal/goal-level-select/goal-level-select.component.ts b/packages/ui-core/shared/src/lib/goal/goal-level-select/goal-level-select.component.ts index 36809586e93..e3b6ecd0e38 100644 --- a/packages/ui-core/shared/src/lib/goal/goal-level-select/goal-level-select.component.ts +++ b/packages/ui-core/shared/src/lib/goal/goal-level-select/goal-level-select.component.ts @@ -1,7 +1,7 @@ import { Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { GoalLevelEnum, IOrganizationTeam, IEmployee } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { OrganizationTeamsService } from '@gauzy/ui-core/core'; @Component({ diff --git a/packages/ui-core/shared/src/lib/image-uploader/image-uploader-base.component.ts b/packages/ui-core/shared/src/lib/image-uploader/image-uploader-base.component.ts index 9bc6c289f51..0fdaa4dd335 100644 --- a/packages/ui-core/shared/src/lib/image-uploader/image-uploader-base.component.ts +++ b/packages/ui-core/shared/src/lib/image-uploader/image-uploader-base.component.ts @@ -5,7 +5,8 @@ import { Subject } from 'rxjs/internal/Subject'; import { filter, tap } from 'rxjs/operators'; import { IOrganization, IUser } from '@gauzy/contracts'; import { environment } from '@gauzy/ui-config'; -import { API_PREFIX, distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { API_PREFIX, distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/image-uploader/image-uploader.component.ts b/packages/ui-core/shared/src/lib/image-uploader/image-uploader.component.ts index 9ec69fb044b..19c7da27af9 100644 --- a/packages/ui-core/shared/src/lib/image-uploader/image-uploader.component.ts +++ b/packages/ui-core/shared/src/lib/image-uploader/image-uploader.component.ts @@ -4,7 +4,8 @@ import { FileItem, FileUploader, FileUploaderOptions } from 'ng2-file-upload'; import { filter, tap } from 'rxjs/operators'; import { IImageAsset, IOrganization, IUser } from '@gauzy/contracts'; import { environment } from '@gauzy/ui-config'; -import { API_PREFIX, distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { API_PREFIX, distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy() @Component({ @@ -56,7 +57,7 @@ export class ImageUploaderComponent implements AfterViewInit, OnInit { } @Output() changeHoverState = new EventEmitter(); - @Output() uploadedImageAsset = new EventEmitter(); + @Output() uploadedImageAsset = new EventEmitter(); @Output() uploadImageAssetError = new EventEmitter(); constructor(private readonly store: Store) {} diff --git a/packages/ui-core/shared/src/lib/income/income-mutation/income-mutation.component.ts b/packages/ui-core/shared/src/lib/income/income-mutation/income-mutation.component.ts index 845e2f7c883..670df8f0611 100644 --- a/packages/ui-core/shared/src/lib/income/income-mutation/income-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/income/income-mutation/income-mutation.component.ts @@ -5,8 +5,8 @@ import { IIncome, ITag, IOrganization, ICurrency, ISelectedEmployee } from '@gau import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; -import { distinctUntilChange, isNotEmpty, Store } from '@gauzy/ui-core/common'; -import { OrganizationSettingService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { OrganizationSettingService, Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FormHelpers } from '../../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/integrations/github/repository-selector/repository-selector.component.ts b/packages/ui-core/shared/src/lib/integrations/github/repository-selector/repository-selector.component.ts index 8561442c3b5..40923350513 100644 --- a/packages/ui-core/shared/src/lib/integrations/github/repository-selector/repository-selector.component.ts +++ b/packages/ui-core/shared/src/lib/integrations/github/repository-selector/repository-selector.component.ts @@ -6,7 +6,7 @@ import { Observable } from 'rxjs/internal/Observable'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IGithubRepository, IGithubRepositoryResponse, IIntegrationTenant, IOrganization } from '@gauzy/contracts'; import { ErrorHandlingService, GithubService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/invite/forms/email-invite-form/email-invite-form.component.ts b/packages/ui-core/shared/src/lib/invite/forms/email-invite-form/email-invite-form.component.ts index c354c827568..0a2b3b67084 100644 --- a/packages/ui-core/shared/src/lib/invite/forms/email-invite-form/email-invite-form.component.ts +++ b/packages/ui-core/shared/src/lib/invite/forms/email-invite-form/email-invite-form.component.ts @@ -19,7 +19,7 @@ import { NbTagComponent, NbTagInputAddEvent, NbTagInputDirective } from '@nebula import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { AuthService, EmailValidator, InviteService, RoleService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FormHelpers } from '../../../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/invite/invite-mutation/invite-mutation.component.ts b/packages/ui-core/shared/src/lib/invite/invite-mutation/invite-mutation.component.ts index eafb3512bc3..d87472c2ae8 100644 --- a/packages/ui-core/shared/src/lib/invite/invite-mutation/invite-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/invite/invite-mutation/invite-mutation.component.ts @@ -20,7 +20,7 @@ import { OrganizationTeamsService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmailInviteFormComponent } from '../forms/email-invite-form/email-invite-form.component'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/invite/invites/invites.component.ts b/packages/ui-core/shared/src/lib/invite/invites/invites.component.ts index 820746bc3fc..6ee8f364b13 100644 --- a/packages/ui-core/shared/src/lib/invite/invites/invites.component.ts +++ b/packages/ui-core/shared/src/lib/invite/invites/invites.component.ts @@ -10,7 +10,7 @@ import { Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import * as moment from 'moment'; import { ClipboardService, IClipboardResponse } from 'ngx-clipboard'; -import { InviteService, ServerDataSource, ToastrService } from '@gauzy/ui-core/core'; +import { InviteService, ServerDataSource, Store, ToastrService } from '@gauzy/ui-core/core'; import { InvitationTypeEnum, RolesEnum, @@ -21,7 +21,7 @@ import { IInvite, InviteStatusEnum } from '@gauzy/contracts'; -import { API_PREFIX, ComponentEnum, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { API_PREFIX, ComponentEnum, distinctUntilChange } from '@gauzy/ui-core/common'; import { IPaginationBase, PaginationFilterBaseComponent diff --git a/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.html b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.html new file mode 100644 index 00000000000..b80b46b32ba --- /dev/null +++ b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.html @@ -0,0 +1,167 @@ + + +
    +
    +
    +
    +
    +

    + {{ + (!isEstimate ? 'INVOICES_PAGE.INVOICE_NUMBER' : 'INVOICES_PAGE.ESTIMATE_NUMBER') + | translate + }} +

    +

    {{ invoice?.invoiceNumber }}

    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + {{ + (!isEstimate ? 'INVOICES_PAGE.INVOICE_DATE' : 'INVOICES_PAGE.ESTIMATE_DATE') + | translate + }}: +
    +
    + {{ 'INVOICES_PAGE.DUE_DATE' | translate }}: +
    +
    +
    +
    {{ invoice?.invoiceDate | dateFormat }}
    +
    {{ invoice?.dueDate | dateFormat }}
    +
    +
    +
    +
    +
    +
    + {{ 'INVOICES_PAGE.VIEW.FROM' | translate | titlecase }}: +
    +
    {{ invoice?.fromOrganization?.name }}
    +
    +
    +
    + {{ 'INVOICES_PAGE.VIEW.TO' | translate | titlecase }}: +
    +
    {{ invoice?.toContact?.name }}
    +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    {{ 'INVOICES_PAGE.TAX' | translate }}:
    +
    {{ 'INVOICES_PAGE.TAX_2' | translate }}:
    +
    {{ 'INVOICES_PAGE.INVOICES_SELECT_DISCOUNT_VALUE' | translate }}:
    +
    {{ 'INVOICES_PAGE.TOTAL_VALUE' | translate }}:
    + +
    {{ 'INVOICES_PAGE.ALREADY_PAID' | translate }}:
    +
    {{ 'INVOICES_PAGE.AMOUNT_DUE' | translate }}:
    +
    +
    +
    +
    + + {{ + invoice?.tax || 0 + | currency : invoice?.currency + | position : invoice?.fromOrganization.currencyPosition + }} + + + {{ invoice?.tax || 0 }} % + +
    +
    + + {{ + invoice?.tax2 || 0 + | currency : invoice?.currency + | position : invoice?.fromOrganization.currencyPosition + }} + + + {{ invoice?.tax2 || 0 }}% + +
    +
    + + {{ + invoice.discountValue || 0 + | currency : invoice?.currency + | position : invoice?.fromOrganization.currencyPosition + }} + + + {{ invoice?.discountValue || 0 }} + % + +
    +
    + + {{ + invoice?.totalValue || 0 + | currency : invoice?.currency + | position : invoice?.fromOrganization?.currencyPosition + }} + +
    + + + +
    + + {{ + invoice?.alreadyPaid || 0 + | currency : invoice?.currency + | position : invoice?.fromOrganization?.currencyPosition + }} + +
    +
    + + {{ + invoice?.amountDue || 0 + | currency : invoice?.currency + | position : invoice?.fromOrganization?.currencyPosition + }} + +
    +
    +
    +
    + + + +
    +
    {{ 'INVOICES_PAGE.INTERNAL_NOTE.INTERNAL_NOTE' | translate }}:
    + {{ invoice.internalNote }} +
    +
    +
    +
    +
    +
    + + + +
    +
    diff --git a/apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.scss b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.scss similarity index 100% rename from apps/gauzy/src/app/pages/invoices/invoice-view/inner-component/invoice-view-inner.component.scss rename to packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.scss diff --git a/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.ts b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.ts new file mode 100644 index 00000000000..b9128149e44 --- /dev/null +++ b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.component.ts @@ -0,0 +1,198 @@ +import { Component, OnInit, OnDestroy, Input, TemplateRef, ElementRef } from '@angular/core'; +import { CurrencyPipe } from '@angular/common'; +import { TranslateService } from '@ngx-translate/core'; +import { tap } from 'rxjs/operators'; +import { LocalDataSource, Cell } from 'angular2-smart-table'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { DiscountTaxTypeEnum, IInvoice, IInvoiceItem, InvoiceTypeEnum } from '@gauzy/contracts'; +import { ErrorHandlingService, Store, TranslatableService } from '@gauzy/ui-core/core'; +import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { CurrencyPositionPipe } from '../../../pipes/currency-position.pipe'; + +@UntilDestroy({ checkProperties: true }) +@Component({ + selector: 'ga-invoice-view-inner', + templateUrl: './invoice-view-inner.component.html', + styleUrls: ['./invoice-view-inner.component.scss'], + providers: [TranslatableService, CurrencyPipe, CurrencyPositionPipe] +}) +export class InvoiceViewInnerComponent extends TranslationBaseComponent implements OnInit, OnDestroy { + public settingsSmartTable: object; + public smartTableSource = new LocalDataSource(); + public loading: boolean = true; + public discountTaxTypes = DiscountTaxTypeEnum; + public showInternalNote: boolean = !!this._store.user?.tenantId; + + @Input() invoice: IInvoice; + @Input() isEstimate: boolean = false; + @Input() buttonsOutlet: TemplateRef; + + constructor( + readonly translateService: TranslateService, + private readonly _store: Store, + private readonly _translatableService: TranslatableService, + private readonly _currencyPipe: CurrencyPipe, + private readonly _currencyPipePosition: CurrencyPositionPipe, + private readonly _errorHandlingService: ErrorHandlingService + ) { + super(translateService); + } + + ngOnInit() { + this._applyTranslationOnSmartTable(); + this._loadSmartTableSettings(); + this._loadSmartTableData(); + } + + /** + * Load smart table settings + */ + private _loadSmartTableSettings() { + this.settingsSmartTable = { + hideSubHeader: true, + selectedRowIndex: -1, + actions: false, + pager: { + display: false + }, + columns: { + name: { + title: this.getTranslation('INVOICES_PAGE.ITEM'), + type: 'text', + isFilterable: false + }, + description: { + title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.DESCRIPTION'), + type: 'text', + isFilterable: false + }, + quantity: { + title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.QUANTITY'), + type: 'text', + isFilterable: false + }, + price: { + title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.PRICE'), + type: 'text', + isFilterable: false, + valuePrepareFunction: (value: number, cell: Cell) => { + // Get row data + const row = cell.getRow().getData(); + + // Get price transformed + return this.getPipesTransform( + row.price * row.quantity, + row.currency, + this.invoice.fromOrganization.currencyPosition + ); + } + }, + totalValue: { + title: this.getTranslation('INVOICES_PAGE.INVOICE_ITEM.TOTAL_VALUE'), + type: 'text', + isFilterable: false, + valuePrepareFunction: (value: number, cell: Cell) => { + // Get row data + const row = cell.getRow().getData(); + + // Get price transformed + return this.getPipesTransform( + row.price * row.quantity, + row.currency, + this.invoice.fromOrganization.currencyPosition + ); + } + } + } + }; + } + + /** + * Apply translation on smart table + */ + private _applyTranslationOnSmartTable() { + this.translateService.onLangChange + .pipe( + tap(() => this._loadSmartTableSettings()), + untilDestroyed(this) + ) + .subscribe(); + } + + /** + * Load smart table data + */ + async _loadSmartTableData() { + this.loading = true; + + try { + // Map invoice items to smart table data + const data = this.invoice.invoiceItems?.map((item) => { + // Default inclusion + const row = { + description: item.description, + quantity: item.quantity, + price: item.price, + totalValue: +item.totalValue, + currency: this.invoice.currency, + id: item.id // Default inclusion + }; + + // Add name based on invoice type + row['name'] = this.getNameBasedOnInvoiceType(item); + return row; + }); + + this.smartTableSource.load(data); + } catch (error) { + console.log('Error while loading smart table data', error); + this._errorHandlingService.handleError(error); + } finally { + // Set loading to false + this.loading = false; + } + } + + /** + * Determine name based on invoice type + * + * @param item Invoice item + */ + private getNameBasedOnInvoiceType(item: IInvoiceItem): string { + // Return empty string if item is null + if (!item) { + return ''; + } + + switch (this.invoice.invoiceType) { + case InvoiceTypeEnum.BY_EMPLOYEE_HOURS: + return item.employeeId ? `${item.employee?.fullName}` : ''; + case InvoiceTypeEnum.BY_PROJECT_HOURS: + return item.projectId ? item.project?.name : ''; + case InvoiceTypeEnum.BY_TASK_HOURS: + return item.taskId ? item.task?.title : ''; + case InvoiceTypeEnum.BY_PRODUCTS: + return item.productId ? this._translatableService.getTranslatedProperty(item.product, 'name') : ''; + case InvoiceTypeEnum.BY_EXPENSES: + return item.expenseId ? item.expense?.purpose : ''; + default: + delete this.settingsSmartTable['columns']['name']; + return ''; // Default case for name + } + } + + /** + * This function transform simple number to currency format. + * + * @param value should be the number to transform + * @param currencyCode should be the currency code of invoice + * @param position should be the position of currency organization + * @returns should be a string + */ + getPipesTransform(value: number, currencyCode: string, position: string): string { + const transform = this._currencyPipe.transform(value, currencyCode); + return this._currencyPipePosition.transform(transform, position); + } + + ngOnDestroy() {} +} diff --git a/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.module.ts b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.module.ts new file mode 100644 index 00000000000..5f7e0d8b3fa --- /dev/null +++ b/packages/ui-core/shared/src/lib/invoice/components/inner-component/invoice-view-inner.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { NbCardModule } from '@nebular/theme'; +import { TranslateModule } from '@ngx-translate/core'; +import { Angular2SmartTableModule } from 'angular2-smart-table'; +import { InvoicesService } from '@gauzy/ui-core/core'; +import { SharedModule } from './../../../shared.module'; +import { InvoiceViewInnerComponent } from './invoice-view-inner.component'; + +@NgModule({ + imports: [NbCardModule, Angular2SmartTableModule, TranslateModule.forChild(), SharedModule], + declarations: [InvoiceViewInnerComponent], + exports: [InvoiceViewInnerComponent], + providers: [InvoicesService] +}) +export class InvoiceViewInnerModule {} diff --git a/packages/ui-core/shared/src/lib/invoice/index.ts b/packages/ui-core/shared/src/lib/invoice/index.ts index 95da90699df..dd63626198d 100644 --- a/packages/ui-core/shared/src/lib/invoice/index.ts +++ b/packages/ui-core/shared/src/lib/invoice/index.ts @@ -1,2 +1,4 @@ +export * from './components/inner-component/invoice-view-inner.component'; +export * from './components/inner-component/invoice-view-inner.module'; export * from './generate-csv'; export * from './generate-pdf'; diff --git a/packages/ui-core/shared/src/lib/language/language-selector/language-selector.component.ts b/packages/ui-core/shared/src/lib/language/language-selector/language-selector.component.ts index ca154ec2704..000f106a734 100644 --- a/packages/ui-core/shared/src/lib/language/language-selector/language-selector.component.ts +++ b/packages/ui-core/shared/src/lib/language/language-selector/language-selector.component.ts @@ -3,7 +3,7 @@ import { LanguagesService } from '@gauzy/ui-core/core'; import { ILanguage } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TranslateService } from '@ngx-translate/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { filter, tap } from 'rxjs/operators'; import { NbComponentSize } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; diff --git a/packages/ui-core/shared/src/lib/legal/index.ts b/packages/ui-core/shared/src/lib/legal/index.ts deleted file mode 100644 index 592e434327c..00000000000 --- a/packages/ui-core/shared/src/lib/legal/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './privacy-policy/privacy-policy.component'; -export * from './terms-and-conditions/terms-and-conditions.component'; -export * from './legal.module'; -export * from './legal.service'; diff --git a/packages/ui-core/shared/src/lib/legal/legal.module.ts b/packages/ui-core/shared/src/lib/legal/legal.module.ts deleted file mode 100644 index 36a16e1f07c..00000000000 --- a/packages/ui-core/shared/src/lib/legal/legal.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { PrivacyPolicyComponent } from './privacy-policy/privacy-policy.component'; -import { TermsAndConditionsComponent } from './terms-and-conditions/terms-and-conditions.component'; - -@NgModule({ - imports: [TranslateModule.forChild()], - declarations: [TermsAndConditionsComponent, PrivacyPolicyComponent], - exports: [TermsAndConditionsComponent, PrivacyPolicyComponent] -}) -export class MainLegalModule {} diff --git a/apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.html b/packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.html similarity index 88% rename from apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.html rename to packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.html index 6ccdc478f3b..dc39ed0536e 100644 --- a/apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.html +++ b/packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.html @@ -8,7 +8,7 @@

    {{ 'PAGE_NOT_FOUND.404_PAGE_NOT_FOUND' | translate }}

    - {{ 'PAGE_NOT_FOUND.THE_PAGE_YOU_WERE_LOOKING_FOR_DOESNT_EXIST' | translate }} + {{ 'PAGE_NOT_FOUND.THE_PAGE_YOU_WERE_LOOKING_FOR_DOES_NOT_EXIST' | translate }}

    {{ 'PAGE_NOT_FOUND.REDIRECT_TO_HOME' | translate }} diff --git a/apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.scss b/packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.scss similarity index 100% rename from apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.scss rename to packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.scss diff --git a/apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.ts b/packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.ts similarity index 62% rename from apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.ts rename to packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.ts index b2486ac1021..41972a08fd8 100644 --- a/apps/gauzy/src/app/pages/miscellaneous/not-found/not-found.component.ts +++ b/packages/ui-core/shared/src/lib/miscellaneous/components/not-found/not-found.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { AfterViewInit, Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ @@ -6,13 +6,19 @@ import { Router } from '@angular/router'; styleUrls: ['./not-found.component.scss'], templateUrl: './not-found.component.html' }) -export class NotFoundComponent implements OnInit { +export class NotFoundComponent implements AfterViewInit { constructor(private readonly router: Router) {} - ngOnInit() { + /** + * After view init + */ + ngAfterViewInit() { setTimeout(() => this.goToHome(), 3000); } + /** + * Redirect to home page + */ goToHome() { this.router.navigate(['/pages/dashboard']); } diff --git a/packages/ui-core/shared/src/lib/miscellaneous/index.ts b/packages/ui-core/shared/src/lib/miscellaneous/index.ts new file mode 100644 index 00000000000..a7c293ff7a4 --- /dev/null +++ b/packages/ui-core/shared/src/lib/miscellaneous/index.ts @@ -0,0 +1,4 @@ +export * from './miscellaneous.module'; +export * from './miscellaneous.component'; +export * from './miscellaneous.routes'; +export * from './components/not-found/not-found.component'; diff --git a/apps/gauzy/src/app/pages/miscellaneous/miscellaneous.component.ts b/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.component.ts similarity index 78% rename from apps/gauzy/src/app/pages/miscellaneous/miscellaneous.component.ts rename to packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.component.ts index a618506888c..0e50fd9e8e5 100644 --- a/apps/gauzy/src/app/pages/miscellaneous/miscellaneous.component.ts +++ b/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; @Component({ - selector: 'ngx-miscellaneous', + selector: 'ngx-miscellaneous-outlet', template: ` ` }) export class MiscellaneousComponent {} diff --git a/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.module.ts b/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.module.ts new file mode 100644 index 00000000000..acc3757abd0 --- /dev/null +++ b/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ROUTES, RouterModule } from '@angular/router'; +import { NbButtonModule, NbCardModule } from '@nebular/theme'; +import { TranslateModule } from '@ngx-translate/core'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { createRoutes } from './miscellaneous.routes'; +import { MiscellaneousComponent } from './miscellaneous.component'; +import { NotFoundComponent } from './components/not-found/not-found.component'; + +const NB_MODULES = [NbCardModule, NbButtonModule]; + +@NgModule({ + imports: [CommonModule, RouterModule.forChild([]), ...NB_MODULES, TranslateModule.forChild()], + declarations: [MiscellaneousComponent, NotFoundComponent], + exports: [MiscellaneousComponent, NotFoundComponent], + providers: [ + { + provide: ROUTES, + useFactory: (service: PageRouteRegistryService) => createRoutes(service), + deps: [PageRouteRegistryService], + multi: true + } + ] +}) +export class MiscellaneousModule {} diff --git a/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.routes.ts b/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.routes.ts new file mode 100644 index 00000000000..53291313169 --- /dev/null +++ b/packages/ui-core/shared/src/lib/miscellaneous/miscellaneous.routes.ts @@ -0,0 +1,28 @@ +import { Route } from '@angular/router'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; +import { MiscellaneousComponent } from './miscellaneous.component'; +import { NotFoundComponent } from './components/not-found/not-found.component'; + +/** + * Creates miscellaneous routes for the application + * + * @param _pageRouteRegistryService An instance of PageRouteRegistryService + * @returns An array of Route objects + */ +export const createRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ + { + path: '', + component: MiscellaneousComponent, + children: [ + { + path: '', + redirectTo: '404', + pathMatch: 'full' + }, + { + path: '404', + component: NotFoundComponent + } + ] + } +]; diff --git a/packages/ui-core/shared/src/lib/modules/country/country.component.ts b/packages/ui-core/shared/src/lib/modules/country/country.component.ts index 9860699c3a0..b6893ed129b 100644 --- a/packages/ui-core/shared/src/lib/modules/country/country.component.ts +++ b/packages/ui-core/shared/src/lib/modules/country/country.component.ts @@ -9,15 +9,15 @@ import { Output } from '@angular/core'; import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { ICountry, IOrganization } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { filter, Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; +import { ICountry, IOrganization } from '@gauzy/contracts'; import { environment as ENV } from '@gauzy/ui-config'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { CountryService } from '@gauzy/ui-core/core'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { CountryService, Store } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/modules/currency/currency.component.ts b/packages/ui-core/shared/src/lib/modules/currency/currency.component.ts index c4425c29af2..4d8a3f93096 100644 --- a/packages/ui-core/shared/src/lib/modules/currency/currency.component.ts +++ b/packages/ui-core/shared/src/lib/modules/currency/currency.component.ts @@ -16,8 +16,8 @@ import { TranslateService } from '@ngx-translate/core'; import { ICurrency, IOrganization } from '@gauzy/contracts'; import { environment as ENV } from '@gauzy/ui-config'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { CurrencyService } from '@gauzy/ui-core/core'; -import { distinctUntilChange, isNotEmpty, Store } from '@gauzy/ui-core/common'; +import { CurrencyService, Store } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/organizations/index.ts b/packages/ui-core/shared/src/lib/organizations/index.ts index 7ced0ebc622..d1350ae0379 100644 --- a/packages/ui-core/shared/src/lib/organizations/index.ts +++ b/packages/ui-core/shared/src/lib/organizations/index.ts @@ -2,5 +2,3 @@ export * from './organizations-mutation/organizations-mutation.component'; export * from './organizations-mutation/organizations-mutation.module'; export * from './organizations-step-form/organizations-step-form.component'; export * from './organizations-step-form/organizations-step-form.module'; -export * from './public-page-mutation/public-page-mutation.component'; -export * from './public-page-mutation/public-page-mutation.module'; diff --git a/packages/ui-core/shared/src/lib/organizations/organizations-step-form/organizations-step-form.component.ts b/packages/ui-core/shared/src/lib/organizations/organizations-step-form/organizations-step-form.component.ts index d7f1b1929e8..b50c6e59dcd 100644 --- a/packages/ui-core/shared/src/lib/organizations/organizations-step-form/organizations-step-form.component.ts +++ b/packages/ui-core/shared/src/lib/organizations/organizations-step-form/organizations-step-form.component.ts @@ -30,8 +30,8 @@ import { IImageAsset } from '@gauzy/contracts'; import { environment as ENV } from '@gauzy/ui-config'; -import { DUMMY_PROFILE_IMAGE, Store, retrieveNameFromEmail } from '@gauzy/ui-core/common'; -import { ToastrService } from '@gauzy/ui-core/core'; +import { DUMMY_PROFILE_IMAGE, retrieveNameFromEmail } from '@gauzy/ui-core/common'; +import { Store, ToastrService } from '@gauzy/ui-core/core'; import { FormHelpers, LeafletMapComponent, LocationFormComponent } from '../../forms'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.module.ts b/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.module.ts deleted file mode 100644 index 4b9521d257a..00000000000 --- a/packages/ui-core/shared/src/lib/organizations/public-page-mutation/public-page-mutation.module.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { - NbActionsModule, - NbBadgeModule, - NbButtonModule, - NbCardModule, - NbCheckboxModule, - NbDatepickerModule, - NbIconModule, - NbInputModule, - NbListModule, - NbSelectModule, - NbTabsetModule, - NbTagModule, - NbToggleModule, - NbTooltipModule -} from '@nebular/theme'; -import { CKEditorModule } from 'ckeditor4-angular'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { TranslateModule } from '@ngx-translate/core'; -import { LanguagesService, SkillsService } from '@gauzy/ui-core/core'; -import { PublicPageMutationComponent } from './public-page-mutation.component'; -import { SkillsInputModule } from '../../skills/skills-input/skills-input.module'; -import { LanguageSelectorModule } from '../../language/language-selector/language-selector.module'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - ReactiveFormsModule, - NbActionsModule, - NbBadgeModule, - NbButtonModule, - NbCardModule, - NbCheckboxModule, - NbDatepickerModule, - NbIconModule, - NbInputModule, - NbListModule, - NbSelectModule, - NbTabsetModule, - NbTagModule, - NbToggleModule, - NbTooltipModule, - NgSelectModule, - TranslateModule.forChild(), - CKEditorModule, - SkillsInputModule, - LanguageSelectorModule - ], - declarations: [PublicPageMutationComponent], - providers: [SkillsService, LanguagesService] -}) -export class PublicPageMutationModule {} diff --git a/packages/ui-core/shared/src/lib/pipes/date-format.pipe.ts b/packages/ui-core/shared/src/lib/pipes/date-format.pipe.ts index e29816fbecd..07aad42a282 100644 --- a/packages/ui-core/shared/src/lib/pipes/date-format.pipe.ts +++ b/packages/ui-core/shared/src/lib/pipes/date-format.pipe.ts @@ -3,7 +3,8 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import * as moment from 'moment'; import { IOrganization, RegionsEnum } from '@gauzy/contracts'; -import { distinctUntilChange, isEmpty, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Pipe({ diff --git a/packages/ui-core/shared/src/lib/pipes/datetime-format.pipe.ts b/packages/ui-core/shared/src/lib/pipes/datetime-format.pipe.ts index c899c8a9376..b1558863bd8 100644 --- a/packages/ui-core/shared/src/lib/pipes/datetime-format.pipe.ts +++ b/packages/ui-core/shared/src/lib/pipes/datetime-format.pipe.ts @@ -3,7 +3,8 @@ import { filter } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import * as moment from 'moment'; import { IOrganization, RegionsEnum, TimeFormatEnum } from '@gauzy/contracts'; -import { Store, isEmpty } from '@gauzy/ui-core/common'; +import { isEmpty } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Pipe({ diff --git a/packages/ui-core/shared/src/lib/pipes/time-format.pipe.ts b/packages/ui-core/shared/src/lib/pipes/time-format.pipe.ts index d97eb859e8e..2a4a5e169f2 100644 --- a/packages/ui-core/shared/src/lib/pipes/time-format.pipe.ts +++ b/packages/ui-core/shared/src/lib/pipes/time-format.pipe.ts @@ -3,7 +3,7 @@ import { filter, tap } from 'rxjs/operators'; import * as moment from 'moment'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization, TimeFormatEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Pipe({ diff --git a/packages/ui-core/shared/src/lib/product/product-category-selector/product-category-selector.component.ts b/packages/ui-core/shared/src/lib/product/product-category-selector/product-category-selector.component.ts index 2bd2aacd99f..52ace9b10e7 100644 --- a/packages/ui-core/shared/src/lib/product/product-category-selector/product-category-selector.component.ts +++ b/packages/ui-core/shared/src/lib/product/product-category-selector/product-category-selector.component.ts @@ -9,8 +9,8 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { finalize, map, Observable, Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ProductCategoryService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { ProductCategoryService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/product/product-mutation/product-category-mutation/product-category-mutation.component.ts b/packages/ui-core/shared/src/lib/product/product-mutation/product-category-mutation/product-category-mutation.component.ts index f617757fc5a..7c7176306e9 100644 --- a/packages/ui-core/shared/src/lib/product/product-mutation/product-category-mutation/product-category-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/product/product-mutation/product-category-mutation/product-category-mutation.component.ts @@ -14,8 +14,8 @@ import { combineLatest } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ProductCategoryService, ToastrService } from '@gauzy/ui-core/core'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { ProductCategoryService, Store, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/product/product-mutation/product-option-group-translation/product-option-group-translation.component.ts b/packages/ui-core/shared/src/lib/product/product-mutation/product-option-group-translation/product-option-group-translation.component.ts index 4df2a8d58e3..526eaaedae8 100644 --- a/packages/ui-core/shared/src/lib/product/product-mutation/product-option-group-translation/product-option-group-translation.component.ts +++ b/packages/ui-core/shared/src/lib/product/product-mutation/product-option-group-translation/product-option-group-translation.component.ts @@ -4,7 +4,7 @@ import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { IProductCategoryTranslatable, IProductOptionGroupTranslatable } from '@gauzy/contracts'; import { TranslateService } from '@ngx-translate/core'; import { NbDialogRef } from '@nebular/theme'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; @@ -100,10 +100,10 @@ export class ProductOptionGroupTranslationsComponent extends TranslationBaseComp this.activeGroupValueLng = languageCode; this.activeOptionValueLng = ''; - let newtr = this.productOptionGroup.translations.find((tr) => tr.languageCode == languageCode); + let newTranslation = this.productOptionGroup.translations.find((tr) => tr.languageCode == languageCode); - if (newtr && newtr.name) { - this.form.get(languageCode).setValue(newtr.name); + if (newTranslation && newTranslation.name) { + this.form.get(languageCode).setValue(newTranslation.name); } } @@ -120,10 +120,10 @@ export class ProductOptionGroupTranslationsComponent extends TranslationBaseComp this.activeOptionValueLng = languageCode; this.activeOption = option; this.activeGroupValueLng = ''; - let newtr = option.translations.find((tr) => tr.languageCode == languageCode); + let newTranslation = option.translations.find((tr) => tr.languageCode == languageCode); - if (newtr && newtr.name) { - this.form.get(languageCode).setValue(newtr.name); + if (newTranslation && newTranslation.name) { + this.form.get(languageCode).setValue(newTranslation.name); } } diff --git a/packages/ui-core/shared/src/lib/product/product-mutation/product-type-mutation/product-type-mutation.component.ts b/packages/ui-core/shared/src/lib/product/product-mutation/product-type-mutation/product-type-mutation.component.ts index 7175c2834ed..61731adc4ea 100644 --- a/packages/ui-core/shared/src/lib/product/product-mutation/product-type-mutation/product-type-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/product/product-mutation/product-type-mutation/product-type-mutation.component.ts @@ -11,10 +11,10 @@ import { TranslateService } from '@ngx-translate/core'; import { NbDialogRef } from '@nebular/theme'; import { combineLatest } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { ProductTypeService, ToastrService } from '@gauzy/ui-core/core'; +import { ProductTypeService, Store, ToastrService } from '@gauzy/ui-core/core'; import { HttpErrorResponse } from '@angular/common/http'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/product/product-type-selector/product-type-selector.component.ts b/packages/ui-core/shared/src/lib/product/product-type-selector/product-type-selector.component.ts index 9c33a0fe289..e4611c06e47 100644 --- a/packages/ui-core/shared/src/lib/product/product-type-selector/product-type-selector.component.ts +++ b/packages/ui-core/shared/src/lib/product/product-type-selector/product-type-selector.component.ts @@ -10,8 +10,8 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { finalize, map, Observable, Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, ProductTypeService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, ProductTypeService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/project/project-mutation/project-mutation.component.ts b/packages/ui-core/shared/src/lib/project/project-mutation/project-mutation.component.ts index 0fcef87d5bf..c433a552461 100644 --- a/packages/ui-core/shared/src/lib/project/project-mutation/project-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/project/project-mutation/project-mutation.component.ts @@ -37,9 +37,10 @@ import { OrganizationTeamsService, CompareDateValidator, ErrorHandlingService, - ToastrService + ToastrService, + Store } from '@gauzy/ui-core/core'; -import { DUMMY_PROFILE_IMAGE, Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { DUMMY_PROFILE_IMAGE, distinctUntilChange } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { patterns } from '../../regex/regex-patterns.const'; import { FormHelpers } from '../../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/proposal-template-select/proposal-template-select/proposal-template-select.component.ts b/packages/ui-core/shared/src/lib/proposal-template-select/proposal-template-select/proposal-template-select.component.ts index 9ac6190137f..136adbf67f6 100644 --- a/packages/ui-core/shared/src/lib/proposal-template-select/proposal-template-select/proposal-template-select.component.ts +++ b/packages/ui-core/shared/src/lib/proposal-template-select/proposal-template-select/proposal-template-select.component.ts @@ -4,8 +4,8 @@ import { Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ID, IEmployeeProposalTemplate, IOrganization } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, ProposalTemplateService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, ProposalTemplateService, Store } from '@gauzy/ui-core/core'; @UntilDestroy() @Component({ diff --git a/packages/ui-core/shared/src/lib/public-api.ts b/packages/ui-core/shared/src/lib/public-api.ts index e08a98fe601..42473478233 100644 --- a/packages/ui-core/shared/src/lib/public-api.ts +++ b/packages/ui-core/shared/src/lib/public-api.ts @@ -2,6 +2,7 @@ * Public API Surface of @gauzy/ui-core/shared */ export * from './shared.module'; +export * from './appointments'; export * from './approval-policy'; export * from './approvals'; export * from './candidate'; @@ -30,7 +31,6 @@ export * from './gauzy-button-action'; export * from './invite'; export * from './income'; export * from './invoice'; -export * from './legal'; export * from './integrations'; export * from './single-statistic'; export * from './sidebar'; @@ -71,3 +71,4 @@ export * from './user'; export * from './workspaces'; export * from './work-in-progress'; export * from './goal'; +export * from './miscellaneous'; diff --git a/packages/ui-core/shared/src/lib/report/activities-report-grid/activities-report-grid.component.ts b/packages/ui-core/shared/src/lib/report/activities-report-grid/activities-report-grid.component.ts index dcf7261efcb..5ffee010f6c 100644 --- a/packages/ui-core/shared/src/lib/report/activities-report-grid/activities-report-grid.component.ts +++ b/packages/ui-core/shared/src/lib/report/activities-report-grid/activities-report-grid.component.ts @@ -11,8 +11,8 @@ import { pick } from 'underscore'; import { filter, tap } from 'rxjs/operators'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { TranslateService } from '@ngx-translate/core'; -import { ActivityService, DateRangePickerBuilderService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { ActivityService, DateRangePickerBuilderService, Store } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, TimeZoneService } from '../../timesheet/gauzy-filters'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/report/amounts-owed-grid/amounts-owed-grid.component.ts b/packages/ui-core/shared/src/lib/report/amounts-owed-grid/amounts-owed-grid.component.ts index 451f0175deb..98139887922 100644 --- a/packages/ui-core/shared/src/lib/report/amounts-owed-grid/amounts-owed-grid.component.ts +++ b/packages/ui-core/shared/src/lib/report/amounts-owed-grid/amounts-owed-grid.component.ts @@ -10,8 +10,8 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { filter, tap } from 'rxjs/operators'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; -import { DateRangePickerBuilderService, TimesheetService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { BaseSelectorFilterComponent, TimeZoneService } from '../../timesheet/gauzy-filters'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/report/daily-grid/daily-grid.component.ts b/packages/ui-core/shared/src/lib/report/daily-grid/daily-grid.component.ts index 7c8621727dd..855e0dcada1 100644 --- a/packages/ui-core/shared/src/lib/report/daily-grid/daily-grid.component.ts +++ b/packages/ui-core/shared/src/lib/report/daily-grid/daily-grid.component.ts @@ -12,8 +12,8 @@ import { ReportGroupFilterEnum } from '@gauzy/contracts'; import { Environment, environment } from '@gauzy/ui-config'; -import { Store, distinctUntilChange, isEmpty, progressStatus } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, TimesheetService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty, progressStatus } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store, TimesheetService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, TimeZoneService } from '../../timesheet/gauzy-filters'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/report/daily-statistics/daily-statistics/daily-statistics.component.ts b/packages/ui-core/shared/src/lib/report/daily-statistics/daily-statistics/daily-statistics.component.ts index c034ce82ed6..5b6923eebe3 100644 --- a/packages/ui-core/shared/src/lib/report/daily-statistics/daily-statistics/daily-statistics.component.ts +++ b/packages/ui-core/shared/src/lib/report/daily-statistics/daily-statistics/daily-statistics.component.ts @@ -6,11 +6,12 @@ import { debounceTime, filter, tap } from 'rxjs/operators'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import * as moment from 'moment'; import { TranslateService } from '@ngx-translate/core'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; import { DateRangePickerBuilderService, EmployeesService, OrganizationProjectsService, + Store, TimesheetStatisticsService } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, TimeZoneService } from '../../../timesheet/gauzy-filters'; diff --git a/packages/ui-core/shared/src/lib/report/expenses-report-grid/expenses-report-grid.component.ts b/packages/ui-core/shared/src/lib/report/expenses-report-grid/expenses-report-grid.component.ts index 9f9fd4a23ba..8bee04112a9 100644 --- a/packages/ui-core/shared/src/lib/report/expenses-report-grid/expenses-report-grid.component.ts +++ b/packages/ui-core/shared/src/lib/report/expenses-report-grid/expenses-report-grid.component.ts @@ -10,8 +10,8 @@ import { ReportGroupByFilter, ReportGroupFilterEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, ExpensesService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, ExpensesService, Store } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, TimeZoneService } from '../../timesheet/gauzy-filters'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/report/payment-report-grid/payment-report-grid.component.ts b/packages/ui-core/shared/src/lib/report/payment-report-grid/payment-report-grid.component.ts index 1e2aa119b5c..41b59904f81 100644 --- a/packages/ui-core/shared/src/lib/report/payment-report-grid/payment-report-grid.component.ts +++ b/packages/ui-core/shared/src/lib/report/payment-report-grid/payment-report-grid.component.ts @@ -10,8 +10,8 @@ import { ReportGroupByFilter, ReportGroupFilterEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; -import { DateRangePickerBuilderService, PaymentService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, PaymentService, Store } from '@gauzy/ui-core/core'; import { BaseSelectorFilterComponent, TimeZoneService } from '../../timesheet/gauzy-filters'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/select-asset-modal/select-asset.component.ts b/packages/ui-core/shared/src/lib/select-asset-modal/select-asset.component.ts index 03e59592f44..f850fb8af91 100644 --- a/packages/ui-core/shared/src/lib/select-asset-modal/select-asset.component.ts +++ b/packages/ui-core/shared/src/lib/select-asset-modal/select-asset.component.ts @@ -6,7 +6,7 @@ import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IImageAsset, IOrganization } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ImageAssetService } from '@gauzy/ui-core/core'; export interface SelectAssetSettings { diff --git a/packages/ui-core/shared/src/lib/selectors/date-range-picker/date-range-picker.component.ts b/packages/ui-core/shared/src/lib/selectors/date-range-picker/date-range-picker.component.ts index dc81e43bcad..b16930a6b27 100644 --- a/packages/ui-core/shared/src/lib/selectors/date-range-picker/date-range-picker.component.ts +++ b/packages/ui-core/shared/src/lib/selectors/date-range-picker/date-range-picker.component.ts @@ -17,10 +17,11 @@ import { NavigationService, OrganizationsService, SelectorBuilderService, + Store, TimesheetFilterService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { Arrow } from './arrow/context/arrow.class'; import { Next, Previous } from './arrow/strategies'; import { dayOfWeekAsString, shiftUTCtoLocal } from './date-picker.utils'; diff --git a/packages/ui-core/shared/src/lib/selectors/date/date.component.ts b/packages/ui-core/shared/src/lib/selectors/date/date.component.ts index cd68c5ed598..4fdca68a10c 100644 --- a/packages/ui-core/shared/src/lib/selectors/date/date.component.ts +++ b/packages/ui-core/shared/src/lib/selectors/date/date.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { NbCalendarMonthPickerComponent } from '@nebular/theme'; import { min, addYears, subYears } from 'date-fns'; import { monthNames } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ga-date-selector', diff --git a/packages/ui-core/shared/src/lib/selectors/employee/employee.component.ts b/packages/ui-core/shared/src/lib/selectors/employee/employee.component.ts index 924377edc7c..a581de1dfcf 100644 --- a/packages/ui-core/shared/src/lib/selectors/employee/employee.component.ts +++ b/packages/ui-core/shared/src/lib/selectors/employee/employee.component.ts @@ -28,9 +28,10 @@ import { EmployeeStore, EmployeesService, NavigationService, + Store, ToastrService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { TruncatePipe } from '../../pipes'; import { ALL_EMPLOYEES_SELECTED } from './default-employee'; diff --git a/packages/ui-core/shared/src/lib/selectors/organization/organization.component.ts b/packages/ui-core/shared/src/lib/selectors/organization/organization.component.ts index 892d2f250ed..fb3e46adfa1 100644 --- a/packages/ui-core/shared/src/lib/selectors/organization/organization.component.ts +++ b/packages/ui-core/shared/src/lib/selectors/organization/organization.component.ts @@ -5,10 +5,11 @@ import { Observable } from 'rxjs/internal/Observable'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { uniq } from 'underscore'; import { IOrganization, CrudActionEnum, PermissionsEnum } from '@gauzy/contracts'; -import { distinctUntilChange, isNotEmpty, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { NavigationService, OrganizationEditStore, + Store, ToastrService, UsersOrganizationsService } from '@gauzy/ui-core/core'; diff --git a/packages/ui-core/shared/src/lib/selectors/project/project/project.component.ts b/packages/ui-core/shared/src/lib/selectors/project/project/project.component.ts index 33b4079c8b6..2b412baa160 100644 --- a/packages/ui-core/shared/src/lib/selectors/project/project/project.component.ts +++ b/packages/ui-core/shared/src/lib/selectors/project/project/project.component.ts @@ -5,11 +5,12 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { map, Observable, Subject, switchMap } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; +import { distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; import { NavigationService, OrganizationProjectStore, OrganizationProjectsService, + Store, ToastrService } from '@gauzy/ui-core/core'; import { TruncatePipe } from '../../../pipes'; diff --git a/packages/ui-core/shared/src/lib/selectors/team/team/team.component.ts b/packages/ui-core/shared/src/lib/selectors/team/team/team.component.ts index e7ca05e7a90..7bfedc3ffb4 100644 --- a/packages/ui-core/shared/src/lib/selectors/team/team/team.component.ts +++ b/packages/ui-core/shared/src/lib/selectors/team/team/team.component.ts @@ -5,8 +5,14 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { map, Observable, Subject, switchMap } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; -import { NavigationService, OrganizationTeamStore, OrganizationTeamsService, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isEmpty, isNotEmpty } from '@gauzy/ui-core/common'; +import { + NavigationService, + OrganizationTeamStore, + OrganizationTeamsService, + Store, + ToastrService +} from '@gauzy/ui-core/core'; import { TruncatePipe } from '../../../pipes'; import { ALL_TEAM_SELECTED } from './default-team'; diff --git a/packages/ui-core/shared/src/lib/sidebar/knowledeg-base/knowledeg-base.component.ts b/packages/ui-core/shared/src/lib/sidebar/knowledeg-base/knowledeg-base.component.ts index 68aa6c67480..1a008e21d11 100644 --- a/packages/ui-core/shared/src/lib/sidebar/knowledeg-base/knowledeg-base.component.ts +++ b/packages/ui-core/shared/src/lib/sidebar/knowledeg-base/knowledeg-base.component.ts @@ -4,7 +4,7 @@ import { NbDialogRef } from '@nebular/theme'; import { TranslateService } from '@ngx-translate/core'; import { HelpCenterActionEnum, HelpCenterFlagEnum, IHelpCenter, ILanguage } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { HelpCenterService } from '@gauzy/ui-core/core'; @Component({ diff --git a/packages/ui-core/shared/src/lib/sidebar/sidebar.component.ts b/packages/ui-core/shared/src/lib/sidebar/sidebar.component.ts index 3f67943946b..80bf4b18469 100644 --- a/packages/ui-core/shared/src/lib/sidebar/sidebar.component.ts +++ b/packages/ui-core/shared/src/lib/sidebar/sidebar.component.ts @@ -10,7 +10,7 @@ import { filter, tap } from 'rxjs/operators'; import { DeleteCategoryComponent } from './delete-category/delete-category.component'; import { DeleteBaseComponent } from './delete-base/delete-base.component'; import { HelpCenterService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { KnowledgeBaseComponent } from './knowledeg-base/knowledeg-base.component'; import { firstValueFrom } from 'rxjs'; diff --git a/packages/ui-core/shared/src/lib/smart-data-layout/smart-table-toggle/smart-table-toggle.component.html b/packages/ui-core/shared/src/lib/smart-data-layout/smart-table-toggle/smart-table-toggle.component.html index e95f1d888b7..8b830e016d5 100644 --- a/packages/ui-core/shared/src/lib/smart-data-layout/smart-table-toggle/smart-table-toggle.component.html +++ b/packages/ui-core/shared/src/lib/smart-data-layout/smart-table-toggle/smart-table-toggle.component.html @@ -1 +1,3 @@ - +

    + +
    diff --git a/packages/ui-core/shared/src/lib/smtp/smtp.component.ts b/packages/ui-core/shared/src/lib/smtp/smtp.component.ts index 83af8966ff8..ea698ef3744 100644 --- a/packages/ui-core/shared/src/lib/smtp/smtp.component.ts +++ b/packages/ui-core/shared/src/lib/smtp/smtp.component.ts @@ -5,7 +5,7 @@ import { ICustomSmtp, IOrganization, IUser, PermissionsEnum, SMTPSecureEnum } fr import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { filter, pairwise, tap } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CustomSmtpService, ToastrService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { FormHelpers } from '../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/table-components/employee-with-links/employee-with-links.component.ts b/packages/ui-core/shared/src/lib/table-components/employee-with-links/employee-with-links.component.ts index c7fede5301e..d8e7c1546b6 100644 --- a/packages/ui-core/shared/src/lib/table-components/employee-with-links/employee-with-links.component.ts +++ b/packages/ui-core/shared/src/lib/table-components/employee-with-links/employee-with-links.component.ts @@ -1,7 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { IEmployee, ISelectedEmployee } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ngx-employee-with-links', diff --git a/packages/ui-core/shared/src/lib/table-components/invoice-total-value/invoice-total-value.component.ts b/packages/ui-core/shared/src/lib/table-components/invoice-total-value/invoice-total-value.component.ts index b563a613eba..6703861d4c3 100644 --- a/packages/ui-core/shared/src/lib/table-components/invoice-total-value/invoice-total-value.component.ts +++ b/packages/ui-core/shared/src/lib/table-components/invoice-total-value/invoice-total-value.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { filter, tap } from 'rxjs/operators'; import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy'; import { IOrganization } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/table-filters/organization-team-filter.component.ts b/packages/ui-core/shared/src/lib/table-filters/organization-team-filter.component.ts index 4084db86c51..fda5228a837 100644 --- a/packages/ui-core/shared/src/lib/table-filters/organization-team-filter.component.ts +++ b/packages/ui-core/shared/src/lib/table-filters/organization-team-filter.component.ts @@ -4,8 +4,8 @@ import { combineLatest, Subject } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IOrganization, IOrganizationTeam, ISelectedEmployee } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { OrganizationTeamsService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { OrganizationTeamsService, Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/tags/tags-color-input/tags-color-input.component.ts b/packages/ui-core/shared/src/lib/tags/tags-color-input/tags-color-input.component.ts index ebdea715315..f483e5696a5 100644 --- a/packages/ui-core/shared/src/lib/tags/tags-color-input/tags-color-input.component.ts +++ b/packages/ui-core/shared/src/lib/tags/tags-color-input/tags-color-input.component.ts @@ -18,8 +18,8 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import * as randomColor from 'randomcolor'; import { ITag, IOrganization, PermissionsEnum, ITagCreateInput } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { TagsService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store, TagsService } from '@gauzy/ui-core/core'; import { PictureNameTagsComponent } from '../../table-components'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/tags/tags-mutation.component.ts b/packages/ui-core/shared/src/lib/tags/tags-mutation.component.ts index 429784a7ecd..410e5f508a2 100644 --- a/packages/ui-core/shared/src/lib/tags/tags-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/tags/tags-mutation.component.ts @@ -4,7 +4,7 @@ import { NbDialogRef, NbThemeService } from '@nebular/theme'; import { firstValueFrom } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { ITag } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TagsService } from '@gauzy/ui-core/core'; import { NotesWithTagsComponent } from '../table-components'; diff --git a/packages/ui-core/shared/src/lib/tasks-sprint-settings-view/tasks-sprint-settings-view.component.ts b/packages/ui-core/shared/src/lib/tasks-sprint-settings-view/tasks-sprint-settings-view.component.ts index fd42b328949..9abdd1c55ce 100644 --- a/packages/ui-core/shared/src/lib/tasks-sprint-settings-view/tasks-sprint-settings-view.component.ts +++ b/packages/ui-core/shared/src/lib/tasks-sprint-settings-view/tasks-sprint-settings-view.component.ts @@ -6,7 +6,7 @@ import { filter, map, tap } from 'rxjs/operators'; import { IOrganizationSprint, IOrganizationProject, IOrganization } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { SprintStoreService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ItemActionType } from '../editable-grid/gauzy-editable-grid.component'; @UntilDestroy() diff --git a/packages/ui-core/shared/src/lib/tasks/add-task-dialog/add-task-dialog.component.ts b/packages/ui-core/shared/src/lib/tasks/add-task-dialog/add-task-dialog.component.ts index 27ac32614c6..c9996613723 100644 --- a/packages/ui-core/shared/src/lib/tasks/add-task-dialog/add-task-dialog.component.ts +++ b/packages/ui-core/shared/src/lib/tasks/add-task-dialog/add-task-dialog.component.ts @@ -7,7 +7,7 @@ import * as moment from 'moment'; import { firstValueFrom } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { IEmployee, IOrganization, @@ -20,7 +20,7 @@ import { TaskStatusEnum } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { EmployeesService, OrganizationTeamsService, TasksService } from '@gauzy/ui-core/core'; +import { EmployeesService, OrganizationTeamsService, Store, TasksService } from '@gauzy/ui-core/core'; import { richTextCKEditorConfig } from '../../ckeditor.config'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/tasks/task-number/task-number-field.component.ts b/packages/ui-core/shared/src/lib/tasks/task-number/task-number-field.component.ts index 66405b4cdda..a3c5cab1d1b 100644 --- a/packages/ui-core/shared/src/lib/tasks/task-number/task-number-field.component.ts +++ b/packages/ui-core/shared/src/lib/tasks/task-number/task-number-field.component.ts @@ -6,7 +6,7 @@ import { filter, tap } from 'rxjs/operators'; import { Subject } from 'rxjs/internal/Subject'; import { IOrganization } from '@gauzy/contracts'; import { distinctUntilChange } from '@gauzy/ui-core/common'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TasksService } from '@gauzy/ui-core/core'; diff --git a/packages/ui-core/shared/src/lib/tasks/task-priority-select/task-priority-select.component.ts b/packages/ui-core/shared/src/lib/tasks/task-priority-select/task-priority-select.component.ts index 6cd2bc159cd..f767e9b5f58 100644 --- a/packages/ui-core/shared/src/lib/tasks/task-priority-select/task-priority-select.component.ts +++ b/packages/ui-core/shared/src/lib/tasks/task-priority-select/task-priority-select.component.ts @@ -14,7 +14,7 @@ import { } from '@gauzy/contracts'; import { distinctUntilChange, sluggable } from '@gauzy/ui-core/common'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TaskPrioritiesService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { ToastrService } from '@gauzy/ui-core/core'; diff --git a/packages/ui-core/shared/src/lib/tasks/task-select/task/task.component.ts b/packages/ui-core/shared/src/lib/tasks/task-select/task/task.component.ts index 69eeb8846d7..e94aa68390e 100644 --- a/packages/ui-core/shared/src/lib/tasks/task-select/task/task.component.ts +++ b/packages/ui-core/shared/src/lib/tasks/task-select/task/task.component.ts @@ -1,11 +1,11 @@ import { Component, OnInit, OnDestroy, Input, forwardRef } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; -import { IOrganization, ITask, PermissionsEnum, TaskStatusEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Subject, firstValueFrom, Observable } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; -import { AuthService, TasksService, ToastrService } from '@gauzy/ui-core/core'; +import { IOrganization, ITask, PermissionsEnum, TaskStatusEnum } from '@gauzy/contracts'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { AuthService, Store, TasksService, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/shared/src/lib/tasks/task-size-select/task-size-select.component.ts b/packages/ui-core/shared/src/lib/tasks/task-size-select/task-size-select.component.ts index 853301cf52f..0807b18dfe0 100644 --- a/packages/ui-core/shared/src/lib/tasks/task-size-select/task-size-select.component.ts +++ b/packages/ui-core/shared/src/lib/tasks/task-size-select/task-size-select.component.ts @@ -16,7 +16,7 @@ import { distinctUntilChange, sluggable } from '@gauzy/ui-core/common'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TaskSizesService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/tasks/task-status-select/task-status-select.component.ts b/packages/ui-core/shared/src/lib/tasks/task-status-select/task-status-select.component.ts index 3696b13dcaa..bec127f29f3 100644 --- a/packages/ui-core/shared/src/lib/tasks/task-status-select/task-status-select.component.ts +++ b/packages/ui-core/shared/src/lib/tasks/task-status-select/task-status-select.component.ts @@ -12,9 +12,9 @@ import { ITaskStatusFindInput, TaskStatusEnum } from '@gauzy/contracts'; -import { distinctUntilChange, sluggable, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange, sluggable } from '@gauzy/ui-core/common'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { TaskStatusesService, ToastrService } from '@gauzy/ui-core/core'; +import { Store, TaskStatusesService, ToastrService } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/time-off/settings-mutation/time-off-settings-mutation.component.ts b/packages/ui-core/shared/src/lib/time-off/settings-mutation/time-off-settings-mutation.component.ts index d5887cb79f8..98c2dc9561b 100644 --- a/packages/ui-core/shared/src/lib/time-off/settings-mutation/time-off-settings-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/time-off/settings-mutation/time-off-settings-mutation.component.ts @@ -3,7 +3,7 @@ import { filter, firstValueFrom, tap } from 'rxjs'; import { NbDialogRef } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IEmployee, IOrganization, IOrganizationTeam, ITimeOffPolicy } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { EmployeesService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/time-off/time-off-holiday-mutation/time-off-holiday-mutation.component.ts b/packages/ui-core/shared/src/lib/time-off/time-off-holiday-mutation/time-off-holiday-mutation.component.ts index 95d68d65980..f26b40448ea 100644 --- a/packages/ui-core/shared/src/lib/time-off/time-off-holiday-mutation/time-off-holiday-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/time-off/time-off-holiday-mutation/time-off-holiday-mutation.component.ts @@ -6,8 +6,8 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms import { debounceTime, filter, first, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import * as moment from 'moment'; -import { CompareDateValidator, EmployeesService, ToastrService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { CompareDateValidator, EmployeesService, Store, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { environment as ENV } from '@gauzy/ui-config'; import { FormHelpers } from '../../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/time-off/time-off-policy-select/time-off-policy-select.component.ts b/packages/ui-core/shared/src/lib/time-off/time-off-policy-select/time-off-policy-select.component.ts index c81092da7fb..4a70a9982b5 100644 --- a/packages/ui-core/shared/src/lib/time-off/time-off-policy-select/time-off-policy-select.component.ts +++ b/packages/ui-core/shared/src/lib/time-off/time-off-policy-select/time-off-policy-select.component.ts @@ -5,7 +5,7 @@ import { Subject } from 'rxjs/internal/Subject'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { distinctUntilChange } from '@gauzy/ui-core/common'; import { IOrganization, ITimeOffPolicy } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { TimeOffService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/time-off/time-off-request-mutation/time-off-request-mutation.component.ts b/packages/ui-core/shared/src/lib/time-off/time-off-request-mutation/time-off-request-mutation.component.ts index f79a20b09ca..b6f18dce1aa 100644 --- a/packages/ui-core/shared/src/lib/time-off/time-off-request-mutation/time-off-request-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/time-off/time-off-request-mutation/time-off-request-mutation.component.ts @@ -11,8 +11,8 @@ import { } from '@gauzy/contracts'; import { debounceTime, filter, first, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { CompareDateValidator, OrganizationDocumentsService } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; +import { CompareDateValidator, OrganizationDocumentsService, Store } from '@gauzy/ui-core/core'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { EmployeeSelectorComponent } from '../../selectors/employee/employee.component'; import { FormHelpers } from '../../forms/helpers'; diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/browser-extension-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/browser-extension-timer-icon.ts index 21754c1f524..bea5fe7dd19 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/browser-extension-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/browser-extension-timer-icon.ts @@ -1,6 +1,6 @@ import { faBox } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class BrowserExtensionTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/desktop-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/desktop-timer-icon.ts index d7a7e9bb430..e6422b6626e 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/desktop-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/desktop-timer-icon.ts @@ -1,6 +1,6 @@ import { faDesktop } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class DesktopTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/hubstaff-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/hubstaff-timer-icon.ts index f585e18a1bc..c2a1040c165 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/hubstaff-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/hubstaff-timer-icon.ts @@ -1,6 +1,6 @@ import { faArrowsTurnToDots } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class HubstaffTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/mobile-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/mobile-timer-icon.ts index 4d6daa05325..9cc70a496cd 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/mobile-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/mobile-timer-icon.ts @@ -1,6 +1,6 @@ import { faMobile } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class MobileTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/team-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/team-timer-icon.ts index 5082a554aba..8c646ba9510 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/team-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/team-timer-icon.ts @@ -1,6 +1,6 @@ import { faUsers } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class TeamTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/timer-synced.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/timer-synced.ts index 78ff8664dd2..c4532a1a404 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/timer-synced.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/timer-synced.ts @@ -1,5 +1,5 @@ import { ITimeLog, TimeLogSourceEnum } from '@gauzy/contracts'; -import { ITimerSynced } from '@gauzy/ui-core/common'; +import { ITimerSynced } from '@gauzy/ui-core/core'; export class TimerSynced implements ITimerSynced { private _source: TimeLogSourceEnum; diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/upwork-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/upwork-timer-icon.ts index b03b896aa85..181017f2701 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/upwork-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/upwork-timer-icon.ts @@ -1,6 +1,6 @@ import { faArrowTurnUp } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class UpworkTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/web-timer-icon.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/web-timer-icon.ts index aba83c1aa38..8b3eb92dc0e 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/web-timer-icon.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/concretes/web-timer-icon.ts @@ -1,6 +1,6 @@ import { faGlobe } from '@fortawesome/free-solid-svg-icons'; import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { TimerIcon } from '@gauzy/ui-core/common'; +import { TimerIcon } from '@gauzy/ui-core/core'; export class WebTimerIcon extends TimerIcon { constructor() { diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/factory/timer-icon-factory.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/factory/timer-icon-factory.ts index 3161443caba..cce0c8b4296 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/factory/timer-icon-factory.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/factory/timer-icon-factory.ts @@ -1,5 +1,5 @@ import { TimeLogSourceEnum } from '@gauzy/contracts'; -import { ITimerIcon } from '@gauzy/ui-core/common'; +import { ITimerIcon } from '@gauzy/ui-core/core'; import { BrowserExtensionTimerIcon, DesktopTimerIcon, diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.component.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.component.ts index aa68b1537de..bd2cbb60757 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.component.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; -import { ITimerIcon } from '@gauzy/ui-core/common'; +import { ITimerIcon } from '@gauzy/ui-core/core'; import { TimeTrackerStatusService } from './time-tracker-status.service'; @Component({ diff --git a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.service.ts b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.service.ts index 20b592e0b7b..d250c73da41 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.service.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/components/time-tracker-status/time-tracker-status.service.ts @@ -14,8 +14,9 @@ import { switchMap, tap } from 'rxjs'; -import { ITimerIcon, ITimerSynced, Store, TimeTrackerService, distinctUntilChange } from '@gauzy/ui-core/common'; import { IEmployee, ITimerStatus, IUser } from '@gauzy/contracts'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { ITimerIcon, ITimerSynced, Store, TimeTrackerService } from '@gauzy/ui-core/core'; import { TimerIconFactory } from './factory'; import { TimerSynced } from './concretes'; diff --git a/packages/ui-core/shared/src/lib/time-tracker/time-tracker.module.ts b/packages/ui-core/shared/src/lib/time-tracker/time-tracker.module.ts index 98561020623..66527fb5f76 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/time-tracker.module.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/time-tracker.module.ts @@ -14,7 +14,7 @@ import { NgxDraggableDomModule } from 'ngx-draggable-dom'; import { NgxPermissionsModule } from 'ngx-permissions'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { TranslateModule } from '@ngx-translate/core'; -import { TimeTrackerService } from '@gauzy/ui-core/common'; +import { TimeTrackerService } from '@gauzy/ui-core/core'; import { TimeTrackerComponent } from './time-tracker/time-tracker.component'; import { TimeTrackerStatusModule } from './components/time-tracker-status/time-tracker-status.module'; import { SharedModule } from '../shared.module'; diff --git a/packages/ui-core/shared/src/lib/time-tracker/time-tracker/time-tracker.component.ts b/packages/ui-core/shared/src/lib/time-tracker/time-tracker/time-tracker.component.ts index ba6850f7c72..c17923c44d2 100644 --- a/packages/ui-core/shared/src/lib/time-tracker/time-tracker/time-tracker.component.ts +++ b/packages/ui-core/shared/src/lib/time-tracker/time-tracker/time-tracker.component.ts @@ -18,8 +18,15 @@ import { TimeLogSourceEnum, IEmployee } from '@gauzy/contracts'; -import { ITimerSynced, Store, TimeTrackerService, distinctUntilChange, toLocal, toUTC } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange, toLocal, toUTC } from '@gauzy/ui-core/common'; +import { + ErrorHandlingService, + ITimerSynced, + Store, + TimeTrackerService, + TimesheetService, + ToastrService +} from '@gauzy/ui-core/core'; import { TimeTrackerStatusService } from '../components/time-tracker-status/time-tracker-status.service'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.html b/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.html index 4e45b325420..3a38fa4ffb6 100644 --- a/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.html +++ b/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.html @@ -1,29 +1,16 @@
    - - +
    - {{ - (mode == 'update' - ? 'TIMESHEET.EDIT_TIME_LOGS' - : 'TIMESHEET.ADD_TIME_LOGS' - ) | translate - }} + {{ (mode == 'update' ? 'TIMESHEET.EDIT_TIME_LOGS' : 'TIMESHEET.ADD_TIME_LOGS') | translate }}
    -
    -
    +
    +
    -
    +
    {{ 'TIMESHEET.VALIDATION.EMPLOYEE' | translate }}
    @@ -65,31 +47,22 @@
    - +
    {{ timeDiff | durationFormat }}
    - +
    - + {{ 'TIMESHEET.TIME_OVERLAPS' | translate }}

    {{ 'TIMESHEET.OVERLAP_MESSAGE' | translate }}

    -
    +
    {{ 'TIMESHEET.PROJECT' | translate }} / {{ 'TIMESHEET.TODO' | translate }} @@ -107,46 +80,27 @@ *ngFor="let overlapTimeLog of overlaps" >
    - + {{ overlapTimeLog?.project?.name }} - {{ - 'TIMESHEET.NO_PROJECT' | translate - }} + {{ 'TIMESHEET.NO_PROJECT' | translate }}
    - + {{ - 'TIMESHEET.TODO' | translate - }} + >{{ 'TIMESHEET.TODO' | translate }} : {{ overlapTimeLog?.task?.title }} - {{ - 'TIMESHEET.NO_TODO' | translate - }} + {{ 'TIMESHEET.NO_TODO' | translate }}
    - {{ - overlapTimeLog.overlapDuration - | durationFormat - }} + {{ overlapTimeLog.overlapDuration | durationFormat }}
    @@ -156,11 +110,7 @@
    - + {{ 'TIMER_TRACKER.IS_BILLABLE' | translate }}
    @@ -168,9 +118,7 @@
    - +
    -
    - {{ - 'TIMER_TRACKER.VALIDATION.CLIENT_REQUIRED' - | translate - }} +
    + {{ 'TIMER_TRACKER.VALIDATION.CLIENT_REQUIRED' | translate }}
    - + -
    +
    {{ 'TIMESHEET.VALIDATION.PROJECT' | translate }}
    @@ -240,10 +166,7 @@ formControlName="taskId" [required]="organization?.requireTask" > -
    +
    {{ 'TIMESHEET.VALIDATION.TASK' | translate }}
    @@ -263,10 +186,7 @@ formControlName="description" [required]="organization?.requireDescription" > -
    +
    {{ 'TIMESHEET.VALIDATION.DESCRIPTION' | translate }}
    @@ -276,26 +196,31 @@
    - + + + + + {{ reason }} + + + +
    -
    -
    - {{ 'TIMESHEET.VALIDATION.REASON' | translate }} -
    +
    +
    + {{ 'TIMESHEET.VALIDATION.REASON' | translate }}
    +
    @@ -308,20 +233,10 @@ nbSpinnerStatus="primary" > - {{ - (mode == 'create' - ? 'TIMESHEET.ADD_TIME' - : 'TIMESHEET.UPDATE_TIME' - ) | translate - }} + {{ (mode == 'create' ? 'TIMESHEET.ADD_TIME' : 'TIMESHEET.UPDATE_TIME') | translate }} - - + + diff --git a/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.ts b/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.ts index a51cc7118ad..858b78cfc1c 100644 --- a/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.component.ts @@ -17,8 +17,8 @@ import { TimeLogType, TimeLogSourceEnum } from '@gauzy/contracts'; -import { toUTC, toLocal, distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { TimesheetService, ToastrService } from '@gauzy/ui-core/core'; +import { toUTC, toLocal, distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -43,7 +43,8 @@ export class EditTimeLogModalComponent implements OnInit, AfterViewInit, OnDestr subject$: Subject = new Subject(); changeSelectedEmployee: boolean; - + reasons = ['Worked offline', 'Internet issue', 'Forgot to track', 'Usability issue', 'App issue']; + selectedReason: string = ''; private _timeLog: ITimeLog | Partial; get timeLog(): ITimeLog | Partial { return this._timeLog; @@ -227,6 +228,7 @@ export class EditTimeLogModalComponent implements OnInit, AfterViewInit, OnDestr const payload = { ..._.omit(this.form.value, ['selectedRange']), + startedAt, stoppedAt, organizationId, diff --git a/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.module.ts b/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.module.ts index 2448a174b43..85fd260b070 100644 --- a/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.module.ts +++ b/packages/ui-core/shared/src/lib/timesheet/edit-time-log-modal/edit-time-log-modal.module.ts @@ -2,11 +2,15 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { + NbAutocompleteModule, NbButtonModule, NbCardModule, NbCheckboxModule, + NbFormFieldModule, NbIconModule, NbInputModule, + NbOptionModule, + NbSelectModule, NbSpinnerModule, NbTooltipModule } from '@nebular/theme'; @@ -31,10 +35,14 @@ import { TaskSelectModule } from '../../tasks/task-select/task-select.module'; NbButtonModule, NbCardModule, NbCheckboxModule, + NbAutocompleteModule, + NbFormFieldModule, NbIconModule, NbInputModule, NbSpinnerModule, NbTooltipModule, + NbSelectModule, + NbOptionModule, NgxPermissionsModule.forChild(), TranslateModule.forChild(), SharedModule, diff --git a/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/base-selector-filter/base-selector-filter.component.ts b/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/base-selector-filter/base-selector-filter.component.ts index f5bff22118c..7d9eee1291a 100644 --- a/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/base-selector-filter/base-selector-filter.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/base-selector-filter/base-selector-filter.component.ts @@ -5,9 +5,9 @@ import { IOrganization, ITimeLogFilters } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { pick } from 'underscore'; -import { Store, toUtcOffset } from '@gauzy/ui-core/common'; +import { toUtcOffset } from '@gauzy/ui-core/common'; +import { DateRangePickerBuilderService, Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { DateRangePickerBuilderService } from '@gauzy/ui-core/core'; import { TimeZoneService } from '../timezone-filter'; import { getAdjustDateRangeFutureAllowed } from '../../../selectors/date-range-picker/date-picker.utils'; diff --git a/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts b/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts index 0e92f74a34e..582acfb702b 100644 --- a/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts @@ -14,8 +14,8 @@ import { TimeFormatEnum, TimeZoneEnum } from '@gauzy/contracts'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { NavigationService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { NavigationService, Store } from '@gauzy/ui-core/core'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { TimeZoneService } from './time-zone.service'; diff --git a/packages/ui-core/shared/src/lib/timesheet/screenshots/screenshots-item/screenshots-item.component.ts b/packages/ui-core/shared/src/lib/timesheet/screenshots/screenshots-item/screenshots-item.component.ts index 64a9866201a..b872280d943 100644 --- a/packages/ui-core/shared/src/lib/timesheet/screenshots/screenshots-item/screenshots-item.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/screenshots/screenshots-item/screenshots-item.component.ts @@ -4,8 +4,8 @@ import { NbDialogService } from '@nebular/theme'; import { filter, take, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { sortBy } from 'underscore'; -import { DEFAULT_SVG, Store, distinctUntilChange, isNotEmpty, progressStatus } from '@gauzy/ui-core/common'; -import { ErrorHandlingService, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; +import { DEFAULT_SVG, distinctUntilChange, isNotEmpty, progressStatus } from '@gauzy/ui-core/common'; +import { ErrorHandlingService, Store, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; import { GalleryItem } from '../../../gallery/gallery.directive'; import { ViewScreenshotsModalComponent } from '../view-screenshots-modal/view-screenshots-modal.component'; import { GalleryService } from '../../../gallery/gallery.service'; diff --git a/packages/ui-core/shared/src/lib/timesheet/screenshots/view-screenshots-modal/view-screenshots-modal.component.ts b/packages/ui-core/shared/src/lib/timesheet/screenshots/view-screenshots-modal/view-screenshots-modal.component.ts index 8ee3819eb9b..abfb42e1573 100644 --- a/packages/ui-core/shared/src/lib/timesheet/screenshots/view-screenshots-modal/view-screenshots-modal.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/screenshots/view-screenshots-modal/view-screenshots-modal.component.ts @@ -13,8 +13,8 @@ import { PermissionsEnum, TimeFormatEnum } from '@gauzy/contracts'; -import { TimeLogsLabel, isNotEmpty, progressStatus, Store } from '@gauzy/ui-core/common'; -import { TimesheetService, ToastrService } from '@gauzy/ui-core/core'; +import { TimeLogsLabel, isNotEmpty, progressStatus } from '@gauzy/ui-core/common'; +import { Store, TimesheetService, ToastrService } from '@gauzy/ui-core/core'; import { ViewTimeLogModalComponent } from '../../view-time-log-modal'; import { TimeZoneService } from '../../gauzy-filters/timezone-filter'; diff --git a/packages/ui-core/shared/src/lib/timesheet/view-time-log-modal/view-time-log-modal.component.ts b/packages/ui-core/shared/src/lib/timesheet/view-time-log-modal/view-time-log-modal.component.ts index c2479d65b6e..7992266f1c6 100644 --- a/packages/ui-core/shared/src/lib/timesheet/view-time-log-modal/view-time-log-modal.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/view-time-log-modal/view-time-log-modal.component.ts @@ -4,8 +4,8 @@ import { filter, tap } from 'rxjs/operators'; import { NbDialogRef, NbDialogService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ITimeLog, PermissionsEnum, IOrganization, TimeLogSourceEnum } from '@gauzy/contracts'; -import { Store, TimeLogsLabel, TimeTrackerService } from '@gauzy/ui-core/common'; -import { TimesheetService } from '@gauzy/ui-core/core'; +import { TimeLogsLabel } from '@gauzy/ui-core/common'; +import { Store, TimeTrackerService, TimesheetService } from '@gauzy/ui-core/core'; import { EditTimeLogModalComponent } from './../edit-time-log-modal'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/timesheet/view-time-log/view-time-log.component.ts b/packages/ui-core/shared/src/lib/timesheet/view-time-log/view-time-log.component.ts index ca17b9d8c81..dc097728136 100644 --- a/packages/ui-core/shared/src/lib/timesheet/view-time-log/view-time-log.component.ts +++ b/packages/ui-core/shared/src/lib/timesheet/view-time-log/view-time-log.component.ts @@ -4,8 +4,7 @@ import * as moment from 'moment'; import { NbDialogService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, tap } from 'rxjs/operators'; -import { Store, TimeTrackerService } from '@gauzy/ui-core/common'; -import { TimesheetService } from '@gauzy/ui-core/core'; +import { Store, TimeTrackerService, TimesheetService } from '@gauzy/ui-core/core'; import { EditTimeLogModalComponent } from './../edit-time-log-modal'; import { ViewTimeLogModalComponent } from './../view-time-log-modal'; diff --git a/packages/ui-core/shared/src/lib/user/edit-profile-form/edit-profile-form.component.ts b/packages/ui-core/shared/src/lib/user/edit-profile-form/edit-profile-form.component.ts index 831e8d849b0..55d3aa51484 100644 --- a/packages/ui-core/shared/src/lib/user/edit-profile-form/edit-profile-form.component.ts +++ b/packages/ui-core/shared/src/lib/user/edit-profile-form/edit-profile-form.component.ts @@ -4,7 +4,7 @@ import { IUser, ITag, IRole, IUserUpdateInput, RolesEnum, IImageAsset, DEFAULT_T import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Subject, firstValueFrom } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { AuthService, ErrorHandlingService, diff --git a/packages/ui-core/shared/src/lib/user/forms/basic-info/basic-info-form.component.ts b/packages/ui-core/shared/src/lib/user/forms/basic-info/basic-info-form.component.ts index 99091d107d5..a1e1c4a811f 100644 --- a/packages/ui-core/shared/src/lib/user/forms/basic-info/basic-info-form.component.ts +++ b/packages/ui-core/shared/src/lib/user/forms/basic-info/basic-info-form.component.ts @@ -25,9 +25,10 @@ import { ErrorHandlingService, RoleService, CompareDateValidator, - UrlPatternValidator + UrlPatternValidator, + Store } from '@gauzy/ui-core/core'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { FormHelpers } from '../../../forms/helpers'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/user/forms/fields/role/role.component.ts b/packages/ui-core/shared/src/lib/user/forms/fields/role/role.component.ts index 75b45fd0c32..b88d166afc2 100644 --- a/packages/ui-core/shared/src/lib/user/forms/fields/role/role.component.ts +++ b/packages/ui-core/shared/src/lib/user/forms/fields/role/role.component.ts @@ -5,7 +5,7 @@ import { tap } from 'rxjs/operators'; import { NbComponentSize } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { IRole, IUser, RolesEnum } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { RoleService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/user/user-mutation/user-mutation.component.ts b/packages/ui-core/shared/src/lib/user/user-mutation/user-mutation.component.ts index 2f11f1a6b2f..554e1e895d1 100644 --- a/packages/ui-core/shared/src/lib/user/user-mutation/user-mutation.component.ts +++ b/packages/ui-core/shared/src/lib/user/user-mutation/user-mutation.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { RolesEnum, IUser, IOrganization } from '@gauzy/contracts'; import { NbDialogRef } from '@nebular/theme'; -import { ToastrService } from '@gauzy/ui-core/core'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { Store, ToastrService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; import { BasicInfoFormComponent } from '../forms/basic-info/basic-info-form.component'; import { filter, tap } from 'rxjs/operators'; diff --git a/packages/ui-core/shared/src/lib/vendor-select/vendor-select.component.ts b/packages/ui-core/shared/src/lib/vendor-select/vendor-select.component.ts index 25f01eebe1a..318199a5259 100644 --- a/packages/ui-core/shared/src/lib/vendor-select/vendor-select.component.ts +++ b/packages/ui-core/shared/src/lib/vendor-select/vendor-select.component.ts @@ -5,7 +5,7 @@ import { Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { ErrorHandlingService, ToastrService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { OrganizationVendorsService } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.module.ts b/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.module.ts index 4d91462dcbb..8c63e58b415 100644 --- a/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.module.ts +++ b/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.module.ts @@ -3,19 +3,21 @@ import { CommonModule } from '@angular/common'; import { ROUTES, RouterModule } from '@angular/router'; import { NbCardModule, NbIconModule } from '@nebular/theme'; import { TranslateModule } from '@ngx-translate/core'; -import { PageRouteService } from '@gauzy/ui-core/core'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; import { WorkInProgressComponent } from './work-in-progress.component'; -import { createRoutes } from './work-in-progress.routes'; +import { createWorkInProgressRoutes } from './work-in-progress.routes'; + +const NB_MODULES = [NbCardModule, NbIconModule]; @NgModule({ - imports: [CommonModule, RouterModule.forChild([]), NbCardModule, NbIconModule, TranslateModule.forChild()], + imports: [CommonModule, RouterModule.forChild([]), ...NB_MODULES, TranslateModule.forChild()], declarations: [WorkInProgressComponent], exports: [WorkInProgressComponent], providers: [ { provide: ROUTES, - useFactory: (pageRouteService: PageRouteService) => createRoutes(pageRouteService), - deps: [PageRouteService], + useFactory: (service: PageRouteRegistryService) => createWorkInProgressRoutes(service), + deps: [PageRouteRegistryService], multi: true } ] diff --git a/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.routes.ts b/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.routes.ts index 022e3359ce4..468d211e726 100644 --- a/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.routes.ts +++ b/packages/ui-core/shared/src/lib/work-in-progress/work-in-progress.routes.ts @@ -1,14 +1,14 @@ import { Route } from '@angular/router'; -import { PageRouteService } from '@gauzy/ui-core/core'; +import { PageRouteRegistryService } from '@gauzy/ui-core/core'; import { WorkInProgressComponent } from './work-in-progress.component'; /** * Creates work in progress routes for the application * - * @param _pageRouteService An instance of PageRouteService + * @param _pageRouteRegistryService An instance of PageRouteRegistryService * @returns An array of Route objects */ -export const createRoutes = (_pageRouteService: PageRouteService): Route[] => [ +export const createWorkInProgressRoutes = (_pageRouteRegistryService: PageRouteRegistryService): Route[] => [ { path: '', component: WorkInProgressComponent diff --git a/packages/ui-core/shared/src/lib/workspaces/workspaces.component.ts b/packages/ui-core/shared/src/lib/workspaces/workspaces.component.ts index a062aaec7d2..ea3599818e6 100644 --- a/packages/ui-core/shared/src/lib/workspaces/workspaces.component.ts +++ b/packages/ui-core/shared/src/lib/workspaces/workspaces.component.ts @@ -7,7 +7,8 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { IUser } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; interface IWorkSpace { id: string; diff --git a/packages/ui-core/theme/src/lib/components/footer/footer.component.ts b/packages/ui-core/theme/src/lib/components/footer/footer.component.ts index 88323a284bd..de466983822 100644 --- a/packages/ui-core/theme/src/lib/components/footer/footer.component.ts +++ b/packages/ui-core/theme/src/lib/components/footer/footer.component.ts @@ -4,7 +4,7 @@ import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; import { IUser } from '@gauzy/contracts'; import { filter, tap } from 'rxjs/operators'; import { Environment, GAUZY_ENV } from '@gauzy/ui-config'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Component({ selector: 'ngx-footer', diff --git a/packages/ui-core/theme/src/lib/components/gauzy-logo/gauzy-logo.component.ts b/packages/ui-core/theme/src/lib/components/gauzy-logo/gauzy-logo.component.ts index 53e88572afa..8928c2ef71b 100644 --- a/packages/ui-core/theme/src/lib/components/gauzy-logo/gauzy-logo.component.ts +++ b/packages/ui-core/theme/src/lib/components/gauzy-logo/gauzy-logo.component.ts @@ -14,8 +14,9 @@ import { tap, debounceTime, filter } from 'rxjs/operators'; import { NbThemeService } from '@nebular/theme'; import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy'; import { FeatureEnum, IOrganization, PermissionsEnum } from '@gauzy/contracts'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; import { Environment, GAUZY_ENV } from '@gauzy/ui-config'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/theme/src/lib/components/header/header.component.ts b/packages/ui-core/theme/src/lib/components/header/header.component.ts index 5602ab04732..7b0401a742f 100644 --- a/packages/ui-core/theme/src/lib/components/header/header.component.ts +++ b/packages/ui-core/theme/src/lib/components/header/header.component.ts @@ -7,7 +7,6 @@ import { TranslateService } from '@ngx-translate/core'; import * as moment from 'moment'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import hotkeys, { HotkeysEvent } from 'hotkeys-js'; -import { Store, TimeTrackerService, distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { CrudActionEnum, IDateRangePicker, @@ -18,29 +17,30 @@ import { TimeLogSourceEnum, TimeLogType } from '@gauzy/contracts'; +import { environment } from '@gauzy/ui-config'; import { TranslationBaseComponent } from '@gauzy/ui-core/i18n'; +import { distinctUntilChange, isNotEmpty } from '@gauzy/ui-core/common'; import { DEFAULT_SELECTOR_VISIBILITY, DateRangePickerBuilderService, + EmployeeStore, + EmployeesService, ISelectorVisibility, + ISidebarActionConfig, LayoutService, + NavigationBuilderService, + OrganizationEditStore, + OrganizationProjectStore, + OrganizationProjectsService, OrganizationTeamStore, + OrganizationTeamsService, OrganizationsService, SelectorBuilderService, + Store, + TimeTrackerService, UsersOrganizationsService } from '@gauzy/ui-core/core'; import { ALL_EMPLOYEES_SELECTED, NO_EMPLOYEE_SELECTED, QuickActionsComponent } from '@gauzy/ui-core/shared'; -import { environment } from '@gauzy/ui-config'; -import { - EmployeesService, - EmployeeStore, - ISidebarActionConfig, - NavigationBuilderService, - OrganizationEditStore, - OrganizationProjectsService, - OrganizationProjectStore, - OrganizationTeamsService -} from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/layout-selector/layout-selector.component.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/layout-selector/layout-selector.component.ts index 96ff90293f3..b4448e5b990 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/layout-selector/layout-selector.component.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/layout-selector/layout-selector.component.ts @@ -3,7 +3,7 @@ import { ComponentLayoutStyleEnum, IUser, IUserUpdateInput } from '@gauzy/contra import { filter, tap } from 'rxjs/operators'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { UsersService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @UntilDestroy({ checkProperties: true }) @Component({ diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.component.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.component.ts index 5dd148fcb67..4a4b7697a8d 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.component.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.component.ts @@ -3,7 +3,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { debounceTime, filter, tap, from, concatMap } from 'rxjs'; import { ILanguage, IUser, IUserUpdateInput, LanguagesEnum } from '@gauzy/contracts'; import { LanguagesService, UsersService } from '@gauzy/ui-core/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { I18nService } from '@gauzy/ui-core/i18n'; import { ThemeLanguageSelectorService } from './theme-language-selector.service'; diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.service.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.service.ts index d7260432a2b..715a362952d 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.service.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.service.ts @@ -3,8 +3,8 @@ import { LanguagesEnum } from '@gauzy/contracts'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter, from, tap } from 'rxjs'; import { NbLayoutDirection, NbLayoutDirectionService } from '@nebular/theme'; -import { distinctUntilChange, Store } from '@gauzy/ui-core/common'; -import { ElectronService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { ElectronService, Store } from '@gauzy/ui-core/core'; import { I18nService } from '@gauzy/ui-core/i18n'; @UntilDestroy({ checkProperties: true }) diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.component.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.component.ts index c231b7a01fa..e83607796d9 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.component.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.component.ts @@ -1,7 +1,7 @@ import { Component, Input } from '@angular/core'; import { ThemeSelectorComponent } from '../theme-selector.component'; import { NbThemeService } from '@nebular/theme'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { SwitchThemeService } from './switch-theme.service'; import { ActivatedRoute } from '@angular/router'; import { filter, tap } from 'rxjs/operators'; diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.service.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.service.ts index 7558b72ecf4..5a2209e6943 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.service.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/switch-theme/switch-theme.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; @Injectable({ providedIn: 'root' diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector-image/theme-selector-image.component.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector-image/theme-selector-image.component.ts index 64d6074d7f3..7b1b27156f7 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector-image/theme-selector-image.component.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector-image/theme-selector-image.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { NbThemeService } from '@nebular/theme'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { ThemeSelectorComponent } from '../theme-selector.component'; @Component({ diff --git a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector.component.ts b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector.component.ts index 32e2ba6f743..13ceacbc8ba 100644 --- a/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector.component.ts +++ b/packages/ui-core/theme/src/lib/components/theme-sidebar/theme-settings/components/theme-selector/theme-selector.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { BehaviorSubject, map, Observable } from 'rxjs'; import { NbThemeService } from '@nebular/theme'; import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy'; -import { Store } from '@gauzy/ui-core/common'; +import { Store } from '@gauzy/ui-core/core'; import { CORPORATE_THEME, COSMIC_THEME, diff --git a/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.html b/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.html index 437a33090b0..e8b6981a0f4 100644 --- a/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.html +++ b/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.html @@ -35,12 +35,11 @@
    - +
    @@ -67,28 +62,19 @@
    Download Apps: - +

    - {{ - 'USER_MENU.HELP' | translate - }} + {{ 'USER_MENU.HELP' | translate }}

    - +

    diff --git a/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.ts b/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.ts index 25ed380f3e1..2836ea2d559 100644 --- a/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.ts +++ b/packages/ui-core/theme/src/lib/components/user-menu/user-menu.component.ts @@ -16,6 +16,7 @@ export class UserMenuComponent implements OnInit { private _user$: Observable; private _employee$: BehaviorSubject; private _isSubmit$: BehaviorSubject; + platFormWebSiteUrl: string; @Output() public close: EventEmitter = new EventEmitter(null); @@ -52,6 +53,7 @@ export class UserMenuComponent implements OnInit { this._user$ = new Observable(); this._employee$ = new BehaviorSubject(null); this._isSubmit$ = new BehaviorSubject(false); + this.platFormWebSiteUrl = environment.PLATFORM_WEBSITE_URL; } ngOnInit(): void { diff --git a/packages/ui-core/theme/src/lib/layouts/one-column/one-column.layout.ts b/packages/ui-core/theme/src/lib/layouts/one-column/one-column.layout.ts index 7db937c68d0..ba5340f341a 100644 --- a/packages/ui-core/theme/src/lib/layouts/one-column/one-column.layout.ts +++ b/packages/ui-core/theme/src/lib/layouts/one-column/one-column.layout.ts @@ -4,8 +4,7 @@ import { Observable } from 'rxjs'; import { NbLayoutComponent, NbSidebarService } from '@nebular/theme'; import { UntilDestroy } from '@ngneat/until-destroy'; import { IUser } from '@gauzy/contracts'; -import { Store } from '@gauzy/ui-core/common'; -import { LayoutService, NavigationBuilderService } from '@gauzy/ui-core/core'; +import { LayoutService, NavigationBuilderService, Store } from '@gauzy/ui-core/core'; import { WindowModeBlockScrollService } from '../../services'; import { DEFAULT_SIDEBARS } from '../../components/theme-sidebar/default-sidebars'; import { ThemeLanguageSelectorService } from '../../components/theme-sidebar/theme-settings/components/theme-language-selector/theme-language-selector.service'; diff --git a/packages/ui-core/theme/src/lib/layouts/public/public.layout.ts b/packages/ui-core/theme/src/lib/layouts/public/public.layout.ts index 465f9b9628b..b5009cd3457 100644 --- a/packages/ui-core/theme/src/lib/layouts/public/public.layout.ts +++ b/packages/ui-core/theme/src/lib/layouts/public/public.layout.ts @@ -3,13 +3,13 @@ import { isPlatformBrowser } from '@angular/common'; import { tap } from 'rxjs/operators'; import { NbLayoutComponent, NbThemeService } from '@nebular/theme'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Store, distinctUntilChange } from '@gauzy/ui-core/common'; -import { UsersService } from '@gauzy/ui-core/core'; +import { distinctUntilChange } from '@gauzy/ui-core/common'; +import { Store, UsersService } from '@gauzy/ui-core/core'; import { WindowModeBlockScrollService } from '../../services'; @UntilDestroy({ checkProperties: true }) @Component({ - selector: 'ga-public-layout', + selector: 'ngx-public-layout', styleUrls: ['./public.layout.scss'], templateUrl: './public.layout.html' }) diff --git a/packages/ui-core/tsconfig.json b/packages/ui-core/tsconfig.json index b354bff10cf..2c6d3014e30 100644 --- a/packages/ui-core/tsconfig.json +++ b/packages/ui-core/tsconfig.json @@ -10,16 +10,12 @@ "noFallthroughCasesInSwitch": true, "baseUrl": ".", "paths": { - "@gauzy/ui-core": ["./src/index.ts"], - "@gauzy/ui-core/common": ["./common/src/index.ts"], - "@gauzy/ui-core/core": ["./core/src/index.ts"], - "@gauzy/ui-core/i18n": ["./i18n/src/index.ts"], - "@gauzy/ui-core/shared": ["./shared/src/index.ts"], - "@gauzy/ui-core/theme": ["./theme/src/index.ts"], + "@gauzy/ui-core/*": ["./*/src/index.ts"], "@ngx-translate/*": ["./node_modules/@ngx-translate/*"], "ngx-draggable-dom": ["./node_modules/ngx-draggable-dom"], "ngx-permissions": ["./node_modules/ngx-permissions"], - "ngx-infinite-scroll": ["./node_modules/ngx-infinite-scroll"] + "ngx-infinite-scroll": ["./node_modules/ngx-infinite-scroll"], + "@fullcalendar/*": ["./node_modules/@fullcalendar/*"] } }, "files": [], diff --git a/project.json b/project.json index 286789754be..8cddf666f51 100644 --- a/project.json +++ b/project.json @@ -42,12 +42,24 @@ "gauzy-server-ui": { "tags": [] }, + "job-employee-ui": { + "tags": [] + }, "plugin-job-matching-ui": { "tags": [] }, "plugin-job-search-ui": { "tags": [] }, + "plugin-public-layout-ui": { + "tags": [] + }, + "plugin-onboarding-ui": { + "tags": [] + }, + "plugin-legal-ui": { + "tags": [] + }, "ui-auth": { "tags": [] }, diff --git a/tsconfig.json b/tsconfig.json index f6ecf1d094d..298183d2ded 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,22 +5,26 @@ "typeRoots": ["node_modules/@types"], "paths": { "@angular/*": ["./node_modules/@angular/*"], - "@env-desktop/environment": ["apps/desktop/src/environments/environment.ts"], - "@gauzy/desktop-timer": ["packages/desktop-timer/src/index.ts"], - "@gauzy/desktop-ui-lib": ["packages/desktop-ui-lib/src/index.ts"], - "@gauzy/desktop-window": ["packages/desktop-window/src/index.ts"], - "@gauzy/plugins/job-employee-ui": ["packages/plugins/job-employee-ui/src/index.ts"], - "@gauzy/plugins/job-matching-ui": ["packages/plugins/job-matching-ui/src/index.ts"], - "@gauzy/plugins/job-search-ui": ["packages/plugins/job-search-ui/src/index.ts"], - "@gauzy/plugins/job-proposal-ui": ["packages/plugins/job-proposal-ui/src/index.ts"], - "@gauzy/ui-auth": ["packages/ui-auth/src/index.ts"], - "@gauzy/ui-config": ["packages/ui-config/src/index.ts"], - "@gauzy/ui-core": ["packages/ui-core/src/index.ts"], - "@gauzy/ui-core/common": ["packages/ui-core/common/src/index.ts"], - "@gauzy/ui-core/core": ["packages/ui-core/core/src/index.ts"], - "@gauzy/ui-core/i18n": ["packages/ui-core/i18n/src/index.ts"], - "@gauzy/ui-core/shared": ["packages/ui-core/shared/src/index.ts"], - "@gauzy/ui-core/theme": ["packages/ui-core/theme/src/index.ts"], + "@env-desktop/environment": ["./apps/desktop/src/environments/environment.ts"], + "@gauzy/desktop-timer": ["./packages/desktop-timer/src/index.ts"], + "@gauzy/desktop-ui-lib": ["./packages/desktop-ui-lib/src/index.ts"], + "@gauzy/desktop-window": ["./packages/desktop-window/src/index.ts"], + "@gauzy/plugin-job-employee-ui": ["./packages/plugins/job-employee-ui/src/index.ts"], + "@gauzy/plugin-job-matching-ui": ["./packages/plugins/job-matching-ui/src/index.ts"], + "@gauzy/plugin-job-search-ui": ["./packages/plugins/job-search-ui/src/index.ts"], + "@gauzy/plugin-job-proposal-ui": ["./packages/plugins/job-proposal-ui/src/index.ts"], + "@gauzy/plugin-legal-ui": ["./packages/plugins/legal-ui/src/index.ts"], + "@gauzy/plugin-maintenance-ui": ["./packages/plugins/maintenance-ui/src/index.ts"], + "@gauzy/plugin-onboarding-ui": ["./packages/plugins/onboarding-ui/src/index.ts"], + "@gauzy/plugin-public-layout-ui": ["packages/plugins/public-layout-ui/src/index.ts"], + "@gauzy/ui-auth": ["./packages/ui-auth/src/index.ts"], + "@gauzy/ui-config": ["./packages/ui-config/src/index.ts"], + "@gauzy/ui-core": ["./packages/ui-core/src/index.ts"], + "@gauzy/ui-core/common": ["./packages/ui-core/common/src/index.ts"], + "@gauzy/ui-core/core": ["./packages/ui-core/core/src/index.ts"], + "@gauzy/ui-core/i18n": ["./packages/ui-core/i18n/src/index.ts"], + "@gauzy/ui-core/shared": ["./packages/ui-core/shared/src/index.ts"], + "@gauzy/ui-core/theme": ["./packages/ui-core/theme/src/index.ts"], "@nebular/*": ["./node_modules/@nebular/*"], "ng2-completer": ["./node_modules/@akveo/ng2-completer"], "ngx-daterangepicker-material/*": ["./node_modules/ngx-daterangepicker-material/*"] diff --git a/yarn.lock b/yarn.lock index 75d1ab817b8..cfed5b2505a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18954,9 +18954,9 @@ electron@28.1.0: extract-zip "^2.0.1" elliptic@^6.5.3, elliptic@^6.5.5: - version "6.5.5" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded" - integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw== + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== dependencies: bn.js "^4.11.9" brorand "^1.1.0"