mirror of
https://github.com/ever-co/ever-gauzy.git
synced 2026-10-02 01:54:50 +08:00
[chore] Migrate desktop apps standalone (#9417)
* refactor(desktop-ui): convert components and directives to standalone Migrate numerous components, directives, and pipes within the desktop UI library to Angular's standalone architecture. This update involves: - Removing 'standalone: false' from component and directive decorators. - Adding necessary dependencies to the 'imports' array of individual standalone components. - Moving declarations from NgModule metadata to the 'imports' array. - Updating test suites to use 'imports' instead of 'declarations' for standalone components. * refactor: remove redundant modules in favor of standalone components Clean up the codebase by removing several intermediate Angular modules, including DesktopDirectiveModule, NoDataMessageModule, and PaginationModule. Components and directives are now imported directly into consuming modules, streamlining the dependency structure and supporting the transition to standalone components. * refactor(ui): migrate templates to angular control flow syntax Update various components to use the new @if and @for control flow syntax instead of *ngIf and *ngFor structural directives. This change also removes unnecessary NgIf and NgFor imports from the component metadata. * perf(desktop-ui): use loadComponent for lazy loading routes Replace static component imports with dynamic imports using the loadComponent property in routing configurations. This optimization enables lazy loading for these components, which helps reduce the initial bundle size and improves the application's startup time. * refactor: streamline component imports and remove unused modules * refactor(desktop-ui-lib): update component imports and clean up modules Add PipeModule to various recap components to provide necessary pipes. Remove several standalone components from NgModule declarations and exports as they are now managed via lazy loading or direct component imports. Clean up and reorder imports across affected files for consistency. * refactor(time-tracker): remove form value accessor and clean up imports Remove the NG_VALUE_ACCESSOR implementation and provider from the TimeTrackerComponent. Clean up redundant component references in TimeTrackerModule and reorganize imports for better maintainability. * refactor(desktop-timer): migrate to standalone application architecture Migrate the desktop-timer application from a module-based architecture to a standalone application architecture using Angular's bootstrapApplication API. - Delete AppModule and move its logic to main.ts. - Update AppRoutingModule to use loadComponent for route-level lazy loading of components from @gauzy/desktop-ui-lib. - Refactor RecapModule and SettingsModule to remove unnecessary component declarations and exports. - Consolidate application providers and third-party module initializations in the bootstrap process. * refactor(desktop-timer): convert AppComponent to standalone and simplify refresh Convert the root AppComponent to a standalone component and add the RouterOutlet to its imports. Simplify the initialization logic by removing manual token checks before starting the token refresh service. * refactor(desktop-ui-lib): replace LanguageModule with TranslateModule Replace the internal LanguageModule with TranslateModule from @ngx-translate/core in the recap and task-table modules. Additionally, import PipeModule in GauzyFiltersComponent to ensure required pipes are available. * refactor(desktop): migrate to standalone bootstrapping Remove AppModule and transition to the bootstrapApplication API in main.ts. This includes moving all providers and imported modules from the deleted app.module.ts into the bootstrap configuration, and replacing BrowserAnimationsModule with provideAnimations. * refactor(desktop): implement lazy loading and standalone component Update the routing configuration to use lazy loading for all component routes in app-routing.module.ts. Refactor AppComponent to support standalone imports and simplify the token refresh service initialization logic. * refactor(agent): migrate to standalone bootstrap api Remove the AppModule and use the bootstrapApplication function to initialize the app. Convert AppComponent to a standalone component and consolidate providers and module configurations in main.ts. * perf(agent): use lazy loading for routes and simplify token refresh Implement lazy loading for all routes in the agent application using the `loadComponent` syntax. This improves the initial bundle size and startup performance by loading component code only when needed. Additionally, simplify the initialization of the token refresh service in `AppComponent` by removing the manual check for existing tokens, allowing the service to handle its own internal state logic. * style(server): fix indentation in app component spec Correct the whitespace and indentation in the app component specification file to align with the project's formatting standards. * refactor: migrate server applications to standalone bootstrapping Remove AppModule from both server and server-api applications and transition to the Angular standalone bootstrap API. Provider configurations are moved to main.ts using bootstrapApplication and importProvidersFrom. * perf(routing): use lazy loading for desktop ui components Replace static component imports with dynamic imports using the loadComponent property in both server and server-api routing modules. This optimization reduces the initial bundle size and improves application startup performance by loading components from the @gauzy/desktop-ui-lib only when needed. * refactor(app): update component to use standalone imports for RouterOutlet * refactor(routing): update auth routes to use consistent lazy loading and guards * feat(build): add quick build script for mac agent * refactor(routing): add AuthGuard to server-dashboard route for enhanced security * feat(desktop): initialize TranslateModule in bootstrap process Configure the ngx-translate TranslateModule within the application bootstrap logic. This setup includes the HttpLoaderFactory and HttpClient dependencies to enable internationalization support. * build(gauzy): add nebular default theme styles Include the @nebular/theme prebuilt default CSS file in the project styles configuration to ensure UI components render correctly. * refactor(apps): simplify bootstrap process and update providers Streamline the bootstrap process for server and server-api applications by removing unused Nebular and feature modules. Configure the TranslateModule with HttpLoaderFactory and add Store to the application providers. Additionally, remove the AuthConnectionGuard from routing configurations and update global style paths in project.json.
This commit is contained in:
@@ -1,28 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import {
|
||||
AboutComponent,
|
||||
AgentDashboardComponent,
|
||||
AlwaysOnComponent,
|
||||
AuthConnectionGuard,
|
||||
ScreenCaptureComponent,
|
||||
ServerDownPage,
|
||||
SettingsComponent,
|
||||
SetupComponent,
|
||||
SplashScreenComponent,
|
||||
UpdaterComponent
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { AuthConnectionGuard, AuthGuard } from '@gauzy/desktop-ui-lib';
|
||||
import { AppModuleGuard } from './app.module.guards';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'setup',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'auth',
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.authRoutes),
|
||||
canActivate: [AppModuleGuard]
|
||||
canActivate: [AppModuleGuard],
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.AuthModule)
|
||||
},
|
||||
{
|
||||
path: 'plugins',
|
||||
@@ -31,36 +20,37 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SettingsComponent)
|
||||
},
|
||||
{
|
||||
path: 'updater',
|
||||
component: UpdaterComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.UpdaterComponent)
|
||||
},
|
||||
{
|
||||
path: 'splash-screen',
|
||||
component: SplashScreenComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SplashScreenComponent)
|
||||
},
|
||||
{
|
||||
path: 'server-down',
|
||||
component: ServerDownPage
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ServerDownPage)
|
||||
},
|
||||
{
|
||||
path: 'always-on',
|
||||
component: AlwaysOnComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AlwaysOnComponent)
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AboutComponent)
|
||||
},
|
||||
{
|
||||
path: 'server-dashboard',
|
||||
component: AgentDashboardComponent,
|
||||
canActivate: [AppModuleGuard, AuthConnectionGuard, AuthGuard],
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AgentDashboardComponent),
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.agentDashboardRoutes)
|
||||
},
|
||||
{
|
||||
path: 'screen-capture',
|
||||
component: ScreenCaptureComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ScreenCaptureComponent)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AfterViewInit, Component, HostBinding, NgZone, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import {
|
||||
ActivityWatchElectronService,
|
||||
AuthStrategy,
|
||||
@@ -19,7 +20,7 @@ import { AppService } from './app.service';
|
||||
selector: 'agent-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
standalone: false
|
||||
imports: [RouterOutlet]
|
||||
})
|
||||
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@HostBinding('class.login-small-height') isLoginPage = false;
|
||||
@@ -48,13 +49,8 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.checkAuthValidation();
|
||||
const nebularLinkMedia = document.querySelector('link[media="print"]');
|
||||
if (nebularLinkMedia) this._renderer.setAttribute(nebularLinkMedia, 'media', 'all');
|
||||
|
||||
this.electronService.ipcRenderer.send('app_is_init');
|
||||
|
||||
// Start token refresh timer if user is authenticated
|
||||
if (this.store.token && this.store.refreshToken) {
|
||||
this.tokenRefreshService.start();
|
||||
}
|
||||
this.tokenRefreshService.start();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { APP_INITIALIZER, ErrorHandler, Injector, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { Router } from '@angular/router';
|
||||
import {
|
||||
APIInterceptor,
|
||||
AboutModule,
|
||||
AgentDashboardModule,
|
||||
AlwaysOnModule,
|
||||
AuthGuard,
|
||||
AuthModule,
|
||||
AuthService,
|
||||
AuthStrategy,
|
||||
DEFAULT_TIMEOUT,
|
||||
ElectronService,
|
||||
ErrorHandlerService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
ImageViewerModule,
|
||||
LanguageInterceptor,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
NoAuthGuard,
|
||||
OrganizationInterceptor,
|
||||
RefreshTokenInterceptor,
|
||||
ScreenCaptureModule,
|
||||
ServerConnectionService,
|
||||
ServerDashboardModule,
|
||||
ServerDownModule,
|
||||
ServerErrorInterceptor,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
SplashScreenModule,
|
||||
Store,
|
||||
TenantInterceptor,
|
||||
TimeoutInterceptor,
|
||||
TokenInterceptor,
|
||||
UnauthorizedInterceptor,
|
||||
UpdaterModule,
|
||||
serverConnectionFactory
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDatepickerModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbSidebarModule,
|
||||
NbSidebarService,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import { NgSelectModule } from '@ng-select/ng-select';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppModuleGuard } from './app.module.guards';
|
||||
import { AppService } from './app.service';
|
||||
import { initializeSentry } from './sentry';
|
||||
|
||||
/**
|
||||
* Initializes Sentry based on the environment configuration.
|
||||
* If a valid Sentry DSN is provided, Sentry is initialized with the specified configuration.
|
||||
* If the DSN is set to 'DOCKER_SENTRY_DSN', a warning is logged indicating that the environment
|
||||
* is running inside Docker without a Sentry DSN.
|
||||
*/
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent],
|
||||
exports: [],
|
||||
imports: [
|
||||
NbLayoutModule,
|
||||
AuthModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NbSidebarModule.forRoot(),
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
SetupModule,
|
||||
SettingsModule,
|
||||
UpdaterModule,
|
||||
ServerDashboardModule,
|
||||
ScreenCaptureModule,
|
||||
ImageViewerModule,
|
||||
NgSelectModule,
|
||||
SplashScreenModule,
|
||||
ServerDownModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
LanguageModule.forRoot(),
|
||||
NbDatepickerModule.forRoot(),
|
||||
AboutModule,
|
||||
AgentDashboardModule,
|
||||
AlwaysOnModule
|
||||
],
|
||||
providers: [
|
||||
AppService,
|
||||
NbDialogService,
|
||||
NbSidebarService,
|
||||
AuthGuard,
|
||||
NoAuthGuard,
|
||||
AppModuleGuard,
|
||||
AuthStrategy,
|
||||
AuthService,
|
||||
ServerConnectionService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
Store,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: RefreshTokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TenantInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: OrganizationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: APIInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LanguageInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TimeoutInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: UnauthorizedInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ServerErrorInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useClass: ErrorHandlerService
|
||||
},
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: serverConnectionFactory,
|
||||
deps: [ServerConnectionService, Store, Router, Injector],
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: () => () => {},
|
||||
deps: [Sentry.TraceService],
|
||||
multi: true
|
||||
},
|
||||
{ provide: DEFAULT_TIMEOUT, useValue: 80000 },
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi())
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
+209
-9
@@ -1,9 +1,67 @@
|
||||
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { APP_INITIALIZER, ErrorHandler, Injector, enableProdMode, importProvidersFrom } from '@angular/core';
|
||||
import { BrowserModule, bootstrapApplication } from '@angular/platform-browser';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { Router } from '@angular/router';
|
||||
import { akitaConfig, enableAkitaProdMode, persistState } from '@datorama/akita';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import {
|
||||
APIInterceptor,
|
||||
AboutModule,
|
||||
AgentDashboardModule,
|
||||
AlwaysOnModule,
|
||||
AuthGuard,
|
||||
AuthModule,
|
||||
AuthService,
|
||||
AuthStrategy,
|
||||
DEFAULT_TIMEOUT,
|
||||
ElectronService,
|
||||
ErrorHandlerService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
ImageViewerModule,
|
||||
LanguageInterceptor,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
NoAuthGuard,
|
||||
OrganizationInterceptor,
|
||||
RefreshTokenInterceptor,
|
||||
ServerConnectionService,
|
||||
ServerDashboardModule,
|
||||
ServerDownModule,
|
||||
ServerErrorInterceptor,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
SplashScreenModule,
|
||||
Store,
|
||||
TenantInterceptor,
|
||||
TimeoutInterceptor,
|
||||
TokenInterceptor,
|
||||
UnauthorizedInterceptor,
|
||||
serverConnectionFactory
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDatepickerModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbSidebarModule,
|
||||
NbSidebarService,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import { NgSelectModule } from '@ng-select/ng-select';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { AppRoutingModule } from './app/app-routing.module';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { AppModuleGuard } from './app/app.module.guards';
|
||||
import { AppService } from './app/app.service';
|
||||
import { initializeSentry } from './app/sentry';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
@@ -11,6 +69,21 @@ if (environment.production) {
|
||||
enableAkitaProdMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes Sentry based on the environment configuration.
|
||||
* If a valid Sentry DSN is provided, Sentry is initialized with the specified configuration.
|
||||
* If the DSN is set to 'DOCKER_SENTRY_DSN', a warning is logged indicating that the environment
|
||||
* is running inside Docker without a Sentry DSN.
|
||||
*/
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
persistState({
|
||||
key: '_gauzyStore'
|
||||
});
|
||||
@@ -19,9 +92,136 @@ akitaConfig({
|
||||
resettable: true
|
||||
});
|
||||
|
||||
platformBrowser()
|
||||
.bootstrapModule(AppModule, {
|
||||
preserveWhitespaces: false
|
||||
})
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
importProvidersFrom(
|
||||
NbLayoutModule,
|
||||
AuthModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NbSidebarModule.forRoot(),
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
SetupModule,
|
||||
SettingsModule,
|
||||
ServerDashboardModule,
|
||||
ImageViewerModule,
|
||||
NgSelectModule,
|
||||
SplashScreenModule,
|
||||
ServerDownModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
LanguageModule.forRoot(),
|
||||
NbDatepickerModule.forRoot(),
|
||||
AboutModule,
|
||||
AgentDashboardModule,
|
||||
AlwaysOnModule
|
||||
),
|
||||
AppService,
|
||||
NbDialogService,
|
||||
NbSidebarService,
|
||||
AuthGuard,
|
||||
NoAuthGuard,
|
||||
AppModuleGuard,
|
||||
AuthStrategy,
|
||||
AuthService,
|
||||
ServerConnectionService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
Store,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: RefreshTokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TenantInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: OrganizationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: APIInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LanguageInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TimeoutInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: UnauthorizedInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ServerErrorInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useClass: ErrorHandlerService
|
||||
},
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: serverConnectionFactory,
|
||||
deps: [ServerConnectionService, Store, Router, Injector],
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: () => () => {},
|
||||
deps: [Sentry.TraceService],
|
||||
multi: true
|
||||
},
|
||||
{ provide: DEFAULT_TIMEOUT, useValue: 80000 },
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations()
|
||||
]
|
||||
})
|
||||
.then(() => console.log(`Bootstrap Success!`))
|
||||
.catch((error) => console.error(error));
|
||||
|
||||
@@ -1,50 +1,41 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import {
|
||||
AboutComponent,
|
||||
AlwaysOnComponent,
|
||||
AUTH_CONNECTION_GUARD_CONFIG,
|
||||
AuthConnectionGuard,
|
||||
AuthGuard,
|
||||
DEFAULT_AUTH_CONNECTION_GUARD_CONFIG,
|
||||
ImageViewerComponent,
|
||||
ScreenCaptureComponent,
|
||||
ServerDownPage,
|
||||
SettingsComponent,
|
||||
SetupComponent,
|
||||
SplashScreenComponent,
|
||||
TimeTrackerComponent,
|
||||
UpdaterComponent
|
||||
DEFAULT_AUTH_CONNECTION_GUARD_CONFIG
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { AppModuleGuard } from './app.module.guards';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'setup',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'auth',
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.AuthModule),
|
||||
canActivate: [AppModuleGuard, AuthConnectionGuard]
|
||||
canActivate: [AppModuleGuard, AuthConnectionGuard],
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.AuthModule)
|
||||
},
|
||||
{
|
||||
path: 'time-tracker',
|
||||
component: TimeTrackerComponent,
|
||||
canActivate: [AppModuleGuard, AuthGuard, AuthConnectionGuard],
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.TimeTrackerComponent),
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.RecapModule)
|
||||
},
|
||||
{
|
||||
path: 'screen-capture',
|
||||
component: ScreenCaptureComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ScreenCaptureComponent)
|
||||
},
|
||||
{
|
||||
path: 'always-on',
|
||||
component: AlwaysOnComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AlwaysOnComponent)
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SettingsComponent)
|
||||
},
|
||||
{
|
||||
path: 'plugins',
|
||||
@@ -53,29 +44,29 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'updater',
|
||||
component: UpdaterComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.UpdaterComponent)
|
||||
},
|
||||
{
|
||||
path: 'viewer',
|
||||
component: ImageViewerComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ImageViewerComponent)
|
||||
},
|
||||
{
|
||||
path: 'splash-screen',
|
||||
component: SplashScreenComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SplashScreenComponent)
|
||||
},
|
||||
{
|
||||
path: 'server-down',
|
||||
component: ServerDownPage
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ServerDownPage)
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: TimeTrackerComponent,
|
||||
canActivate: [AppModuleGuard, AuthGuard, AuthConnectionGuard],
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.TimeTrackerComponent),
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.RecapModule)
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AboutComponent)
|
||||
}
|
||||
];
|
||||
|
||||
@@ -96,4 +87,4 @@ const config: ExtraOptions = {
|
||||
}
|
||||
]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
export class AppRoutingModule {}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AfterViewInit, Component, NgZone, OnInit, Renderer2 } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import {
|
||||
ActivityWatchElectronService,
|
||||
AuthStrategy,
|
||||
@@ -19,7 +20,7 @@ import { AppService } from './app.service';
|
||||
selector: 'gauzy-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
standalone: false
|
||||
imports: [RouterOutlet]
|
||||
})
|
||||
export class AppComponent implements OnInit, AfterViewInit {
|
||||
constructor(
|
||||
@@ -43,11 +44,8 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
if (nebularLinkMedia) this._renderer.setAttribute(nebularLinkMedia, 'media', 'all');
|
||||
|
||||
this.electronService.ipcRenderer.send('app_is_init');
|
||||
|
||||
// Start token refresh timer if user is authenticated
|
||||
if (this.store.token && this.store.refreshToken) {
|
||||
this.tokenRefreshService.start();
|
||||
}
|
||||
// Start token refresh timer if we have a token and refresh token
|
||||
this.tokenRefreshService.start();
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { ErrorHandler, Injector, NgModule, inject, provideAppInitializer } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { Router } from '@angular/router';
|
||||
import {
|
||||
APIInterceptor,
|
||||
AboutModule,
|
||||
ActivityWatchInterceptor,
|
||||
ActivityWatchModule,
|
||||
AlwaysOnModule,
|
||||
AuthGuard,
|
||||
AuthModule,
|
||||
AuthService,
|
||||
AuthStrategy,
|
||||
DEFAULT_TIMEOUT,
|
||||
ElectronService,
|
||||
ErrorHandlerService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
ImageViewerModule,
|
||||
LanguageInterceptor,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
NoAuthGuard,
|
||||
OrganizationInterceptor,
|
||||
PluginsModule,
|
||||
RecapModule,
|
||||
RefreshTokenInterceptor,
|
||||
ScreenCaptureModule,
|
||||
ServerConnectionService,
|
||||
ServerDownModule,
|
||||
ServerErrorInterceptor,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
SplashScreenModule,
|
||||
Store,
|
||||
TaskTableModule,
|
||||
TenantInterceptor,
|
||||
TimeTrackerModule,
|
||||
TimeoutInterceptor,
|
||||
TokenInterceptor,
|
||||
UnauthorizedInterceptor,
|
||||
UpdaterModule,
|
||||
serverConnectionFactory
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDatepickerModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import { NgSelectModule } from '@ng-select/ng-select';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppModuleGuard } from './app.module.guards';
|
||||
import { AppService } from './app.service';
|
||||
import { initializeSentry } from './sentry';
|
||||
|
||||
/**
|
||||
* Initializes Sentry based on the environment configuration.
|
||||
* If a valid Sentry DSN is provided, Sentry is initialized with the specified configuration.
|
||||
* If the DSN is set to 'DOCKER_SENTRY_DSN', a warning is logged indicating that the environment
|
||||
* is running inside Docker without a Sentry DSN.
|
||||
*/
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent],
|
||||
exports: [],
|
||||
imports: [
|
||||
NbLayoutModule,
|
||||
AuthModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
SetupModule,
|
||||
TimeTrackerModule,
|
||||
ScreenCaptureModule,
|
||||
SettingsModule,
|
||||
UpdaterModule,
|
||||
ImageViewerModule,
|
||||
NgSelectModule,
|
||||
SplashScreenModule,
|
||||
ServerDownModule,
|
||||
AlwaysOnModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
LanguageModule.forRoot(),
|
||||
NbDatepickerModule.forRoot(),
|
||||
AboutModule,
|
||||
ActivityWatchModule,
|
||||
RecapModule,
|
||||
TaskTableModule,
|
||||
PluginsModule
|
||||
],
|
||||
providers: [
|
||||
AppService,
|
||||
NbDialogService,
|
||||
AuthGuard,
|
||||
NoAuthGuard,
|
||||
AppModuleGuard,
|
||||
AuthStrategy,
|
||||
AuthService,
|
||||
ServerConnectionService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
Store,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TenantInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ActivityWatchInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: OrganizationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: APIInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LanguageInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TimeoutInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: RefreshTokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: UnauthorizedInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ServerErrorInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useClass: ErrorHandlerService
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = serverConnectionFactory(
|
||||
inject(ServerConnectionService),
|
||||
inject(Store),
|
||||
inject(Router),
|
||||
inject(Injector)
|
||||
);
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{ provide: DEFAULT_TIMEOUT, useValue: 80000 },
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi())
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -1,8 +1,76 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import {
|
||||
enableProdMode,
|
||||
ErrorHandler,
|
||||
importProvidersFrom,
|
||||
inject,
|
||||
Injector,
|
||||
provideAppInitializer
|
||||
} from '@angular/core';
|
||||
import { bootstrapApplication, BrowserModule } from '@angular/platform-browser';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { Router } from '@angular/router';
|
||||
import { akitaConfig, enableAkitaProdMode, persistState } from '@datorama/akita';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import {
|
||||
AboutModule,
|
||||
ActivityWatchInterceptor,
|
||||
ActivityWatchModule,
|
||||
AlwaysOnModule,
|
||||
APIInterceptor,
|
||||
AuthGuard,
|
||||
AuthModule,
|
||||
AuthService,
|
||||
AuthStrategy,
|
||||
DEFAULT_TIMEOUT,
|
||||
ElectronService,
|
||||
ErrorHandlerService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
ImageViewerModule,
|
||||
LanguageInterceptor,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
NoAuthGuard,
|
||||
OrganizationInterceptor,
|
||||
PluginsModule,
|
||||
RecapModule,
|
||||
RefreshTokenInterceptor,
|
||||
serverConnectionFactory,
|
||||
ServerConnectionService,
|
||||
ServerDownModule,
|
||||
ServerErrorInterceptor,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
SplashScreenModule,
|
||||
Store,
|
||||
TaskTableModule,
|
||||
TenantInterceptor,
|
||||
TimeoutInterceptor,
|
||||
TimeTrackerModule,
|
||||
TokenInterceptor,
|
||||
UnauthorizedInterceptor
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDatepickerModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import { NgSelectModule } from '@ng-select/ng-select';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { AppRoutingModule } from './app/app-routing.module';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { AppModuleGuard } from './app/app.module.guards';
|
||||
import { AppService } from './app/app.service';
|
||||
import { initializeSentry } from './app/sentry';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
@@ -10,6 +78,15 @@ if (environment.production) {
|
||||
enableAkitaProdMode();
|
||||
}
|
||||
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
persistState({
|
||||
key: '_gauzyStore'
|
||||
});
|
||||
@@ -18,9 +95,143 @@ akitaConfig({
|
||||
resettable: true
|
||||
});
|
||||
|
||||
platformBrowser()
|
||||
.bootstrapModule(AppModule, {
|
||||
preserveWhitespaces: false
|
||||
})
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
importProvidersFrom(
|
||||
NbLayoutModule,
|
||||
AuthModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NgxDesktopThemeModule,
|
||||
NgxLoginModule,
|
||||
SetupModule,
|
||||
TimeTrackerModule,
|
||||
SettingsModule,
|
||||
ImageViewerModule,
|
||||
NgSelectModule,
|
||||
SplashScreenModule,
|
||||
ServerDownModule,
|
||||
AlwaysOnModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
LanguageModule.forRoot(),
|
||||
NbDatepickerModule.forRoot(),
|
||||
AboutModule,
|
||||
ActivityWatchModule,
|
||||
RecapModule,
|
||||
TaskTableModule,
|
||||
PluginsModule
|
||||
),
|
||||
AppService,
|
||||
NbDialogService,
|
||||
AuthGuard,
|
||||
NoAuthGuard,
|
||||
AppModuleGuard,
|
||||
AuthStrategy,
|
||||
AuthService,
|
||||
ServerConnectionService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
Store,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TenantInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ActivityWatchInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: OrganizationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: APIInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LanguageInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TimeoutInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: RefreshTokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: UnauthorizedInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ServerErrorInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useClass: ErrorHandlerService
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = serverConnectionFactory(
|
||||
inject(ServerConnectionService),
|
||||
inject(Store),
|
||||
inject(Router),
|
||||
inject(Injector)
|
||||
);
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{ provide: DEFAULT_TIMEOUT, useValue: 80000 },
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations()
|
||||
]
|
||||
})
|
||||
.then(() => console.log(`Bootstrap Success!`))
|
||||
.catch((error) => console.error(error));
|
||||
|
||||
@@ -1,35 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import {
|
||||
AboutComponent,
|
||||
AlwaysOnComponent,
|
||||
AuthConnectionGuard,
|
||||
ImageViewerComponent,
|
||||
ScreenCaptureComponent,
|
||||
SettingsComponent,
|
||||
SetupComponent,
|
||||
SplashScreenComponent,
|
||||
TimeTrackerComponent,
|
||||
UpdaterComponent
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { AuthConnectionGuard } from '@gauzy/desktop-ui-lib';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: TimeTrackerComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.TimeTrackerComponent)
|
||||
},
|
||||
{
|
||||
path: 'setup',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'time-tracker',
|
||||
component: TimeTrackerComponent,
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.TimeTrackerComponent),
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.recapRoutes)
|
||||
},
|
||||
{
|
||||
path: 'screen-capture',
|
||||
component: ScreenCaptureComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ScreenCaptureComponent)
|
||||
},
|
||||
{
|
||||
path: 'plugins',
|
||||
@@ -38,27 +27,27 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SettingsComponent)
|
||||
},
|
||||
{
|
||||
path: 'updater',
|
||||
component: UpdaterComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.UpdaterComponent)
|
||||
},
|
||||
{
|
||||
path: 'viewer',
|
||||
component: ImageViewerComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ImageViewerComponent)
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AboutComponent)
|
||||
},
|
||||
{
|
||||
path: 'splash-screen',
|
||||
component: SplashScreenComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SplashScreenComponent)
|
||||
},
|
||||
{
|
||||
path: 'always-on',
|
||||
component: AlwaysOnComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AlwaysOnComponent)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AfterViewInit, Component, NgZone, OnInit } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import {
|
||||
ActivityWatchElectronService,
|
||||
ElectronService,
|
||||
@@ -11,7 +12,7 @@ import { AppService } from './app.service';
|
||||
@Component({
|
||||
selector: 'gauzy-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
standalone: false
|
||||
imports: [RouterOutlet]
|
||||
})
|
||||
export class AppComponent implements OnInit, AfterViewInit {
|
||||
public title: string;
|
||||
@@ -36,11 +37,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
this._electronService.ipcRenderer.send('app_is_init');
|
||||
this._isInitialized = true;
|
||||
}
|
||||
|
||||
// Start token refresh timer if user is authenticated
|
||||
if (this._store.token && this._store.refreshToken) {
|
||||
this.tokenRefreshService.start();
|
||||
}
|
||||
this.tokenRefreshService.start();
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { ErrorHandler, inject, NgModule, provideAppInitializer } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import {
|
||||
AboutModule,
|
||||
ActivityWatchInterceptor,
|
||||
AlwaysOnModule,
|
||||
APIInterceptor,
|
||||
AuthGuard,
|
||||
AuthService,
|
||||
AuthStrategy,
|
||||
DEFAULT_TIMEOUT,
|
||||
ElectronService,
|
||||
ErrorHandlerService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
ImageViewerModule,
|
||||
LanguageInterceptor,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
NoAuthGuard,
|
||||
OrganizationInterceptor,
|
||||
PluginsModule,
|
||||
RecapModule,
|
||||
RefreshTokenInterceptor,
|
||||
ScreenCaptureModule,
|
||||
ServerErrorInterceptor,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
Store,
|
||||
TenantInterceptor,
|
||||
TimeoutInterceptor,
|
||||
TimeTrackerModule,
|
||||
TokenInterceptor,
|
||||
UpdaterModule
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDatepickerModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppService } from './app.service';
|
||||
import { initializeSentry } from './sentry';
|
||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||
|
||||
/**
|
||||
* Initializes Sentry based on the environment configuration.
|
||||
* If a valid Sentry DSN is provided, Sentry is initialized with the specified configuration.
|
||||
* If the DSN is set to 'DOCKER_SENTRY_DSN', a warning is logged indicating that the environment
|
||||
* is running inside Docker without a Sentry DSN.
|
||||
*/
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [
|
||||
NbLayoutModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NgxDesktopThemeModule,
|
||||
SetupModule,
|
||||
TimeTrackerModule,
|
||||
ScreenCaptureModule,
|
||||
SettingsModule,
|
||||
UpdaterModule,
|
||||
ImageViewerModule,
|
||||
NbDatepickerModule.forRoot(),
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
LanguageModule.forRoot(),
|
||||
AboutModule,
|
||||
AlwaysOnModule,
|
||||
RecapModule,
|
||||
PluginsModule
|
||||
],
|
||||
providers: [
|
||||
AppService,
|
||||
NbDialogService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
AuthGuard,
|
||||
NoAuthGuard,
|
||||
AuthStrategy,
|
||||
AuthService,
|
||||
Store,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: RefreshTokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TenantInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: OrganizationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => { })(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useClass: ErrorHandlerService
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ServerErrorInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ActivityWatchInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: APIInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LanguageInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TimeoutInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{ provide: DEFAULT_TIMEOUT, useValue: 80000 },
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi())
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
+186
-6
@@ -1,7 +1,59 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { enableProdMode, ErrorHandler, importProvidersFrom, inject, provideAppInitializer } from '@angular/core';
|
||||
import { bootstrapApplication, BrowserModule } from '@angular/platform-browser';
|
||||
import { akitaConfig, enableAkitaProdMode, persistState } from '@datorama/akita';
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import {
|
||||
AboutModule,
|
||||
ActivityWatchInterceptor,
|
||||
AlwaysOnModule,
|
||||
APIInterceptor,
|
||||
AuthGuard,
|
||||
AuthService,
|
||||
AuthStrategy,
|
||||
DEFAULT_TIMEOUT,
|
||||
ElectronService,
|
||||
ErrorHandlerService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
ImageViewerModule,
|
||||
LanguageInterceptor,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
NoAuthGuard,
|
||||
OrganizationInterceptor,
|
||||
PluginsModule,
|
||||
RecapModule,
|
||||
RefreshTokenInterceptor,
|
||||
ServerErrorInterceptor,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
Store,
|
||||
TenantInterceptor,
|
||||
TimeoutInterceptor,
|
||||
TimeTrackerModule,
|
||||
TokenInterceptor
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDatepickerModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { AppRoutingModule } from './app/app-routing.module';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { AppService } from './app/app.service';
|
||||
import { initializeSentry } from './app/sentry';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
@@ -9,6 +61,21 @@ if (environment.production) {
|
||||
enableAkitaProdMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes Sentry based on the environment configuration.
|
||||
* If a valid Sentry DSN is provided, Sentry is initialized with the specified configuration.
|
||||
* If the DSN is set to 'DOCKER_SENTRY_DSN', a warning is logged indicating that the environment
|
||||
* is running inside Docker without a Sentry DSN.
|
||||
*/
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
persistState({
|
||||
key: '_gauzyStore'
|
||||
});
|
||||
@@ -17,6 +84,119 @@ akitaConfig({
|
||||
resettable: true
|
||||
});
|
||||
|
||||
platformBrowser()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch((error) => console.error(error));
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
importProvidersFrom(
|
||||
NbLayoutModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NgxDesktopThemeModule,
|
||||
SetupModule,
|
||||
TimeTrackerModule,
|
||||
SettingsModule,
|
||||
ImageViewerModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
NbDatepickerModule.forRoot(),
|
||||
LanguageModule.forRoot(),
|
||||
AboutModule,
|
||||
AlwaysOnModule,
|
||||
RecapModule,
|
||||
PluginsModule
|
||||
),
|
||||
AppService,
|
||||
NbDialogService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
AuthGuard,
|
||||
NoAuthGuard,
|
||||
AuthStrategy,
|
||||
AuthService,
|
||||
Store,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: RefreshTokenInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TenantInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: OrganizationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useClass: ErrorHandlerService
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ServerErrorInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: ActivityWatchInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: APIInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LanguageInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TimeoutInterceptor,
|
||||
multi: true
|
||||
},
|
||||
{ provide: DEFAULT_TIMEOUT, useValue: 80000 },
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations()
|
||||
]
|
||||
}).catch((error) => console.error(error));
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/@nebular/theme/styles/prebuilt/default.css",
|
||||
"node_modules/bootstrap/dist/css/bootstrap.css",
|
||||
"node_modules/typeface-exo/index.css",
|
||||
"node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
"node_modules/socicon/css/socicon.css",
|
||||
"node_modules/@ali-hm/angular-tree-component/css/angular-tree-component.css",
|
||||
"node_modules/leaflet/dist/leaflet.css",
|
||||
"apps/server-api/src/styles.css",
|
||||
"node_modules/@ng-select/ng-select/themes/default.theme.css",
|
||||
"apps/server-api/src/assets/styles/styles.scss",
|
||||
"node_modules/@ng-select/ng-select/themes/default.theme.css"
|
||||
"packages/ui-core/static/styles/styles.scss"
|
||||
],
|
||||
"scripts": [],
|
||||
"allowedCommonJsDependencies": [
|
||||
|
||||
@@ -1,48 +1,38 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import {
|
||||
AboutComponent,
|
||||
AuthConnectionGuard,
|
||||
ServerDashboardComponent,
|
||||
SettingsComponent,
|
||||
SetupComponent,
|
||||
SplashScreenComponent,
|
||||
UpdaterComponent
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'setup',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'plugins',
|
||||
canActivate: [AuthConnectionGuard],
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.PluginRoutingModule)
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SettingsComponent)
|
||||
},
|
||||
{
|
||||
path: 'updater',
|
||||
component: UpdaterComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.UpdaterComponent)
|
||||
},
|
||||
{
|
||||
path: 'server-dashboard',
|
||||
component: ServerDashboardComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ServerDashboardComponent)
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AboutComponent)
|
||||
},
|
||||
{
|
||||
path: 'splash-screen',
|
||||
component: SplashScreenComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SplashScreenComponent)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { LanguageElectronService } from '@gauzy/desktop-ui-lib';
|
||||
|
||||
@Component({
|
||||
selector: 'gauzy-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
standalone: false
|
||||
selector: 'gauzy-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
imports: [RouterOutlet]
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
constructor(private readonly languageElectronService: LanguageElectronService) {}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { ErrorHandler, NgModule, inject, provideAppInitializer } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import {
|
||||
AboutModule,
|
||||
ElectronService,
|
||||
GAUZY_ENV,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
PluginsModule,
|
||||
ServerDashboardModule,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
UpdaterModule
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbMenuModule,
|
||||
NbSidebarModule,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppService } from './app.service';
|
||||
import { initializeSentry } from './sentry';
|
||||
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent],
|
||||
imports: [
|
||||
NbLayoutModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NgxDesktopThemeModule,
|
||||
NbMenuModule.forRoot(),
|
||||
NbSidebarModule.forRoot(),
|
||||
SetupModule,
|
||||
SettingsModule,
|
||||
UpdaterModule,
|
||||
ServerDashboardModule,
|
||||
AboutModule,
|
||||
LanguageModule.forRoot(),
|
||||
PluginsModule
|
||||
],
|
||||
providers: [
|
||||
AppService,
|
||||
NbDialogService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi())
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -1,12 +1,91 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { AppModule } from './app/app.module';
|
||||
import { enableProdMode, ErrorHandler, importProvidersFrom, inject, provideAppInitializer } from '@angular/core';
|
||||
import { bootstrapApplication, BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import {
|
||||
ElectronService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
Store
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import { NbTablerIconsModule } from '@gauzy/ui-core/theme';
|
||||
import { NbDialogModule, NbDialogService, NbMenuModule, NbSidebarModule, NbToastrModule } from '@nebular/theme';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { AppRoutingModule } from './app/app-routing.module';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { AppService } from './app/app.service';
|
||||
import { initializeSentry } from './app/sentry';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowser()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch((err) => console.error(err));
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
importProvidersFrom(
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
BrowserModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
NbMenuModule.forRoot(),
|
||||
NbSidebarModule.forRoot(),
|
||||
LanguageModule.forRoot(),
|
||||
NgxDesktopThemeModule,
|
||||
NbTablerIconsModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
})
|
||||
),
|
||||
AppService,
|
||||
NbDialogService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
Store,
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations()
|
||||
]
|
||||
}).catch((err) => console.error(err));
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
@@ -48,7 +48,6 @@
|
||||
"node_modules/socicon/css/socicon.css",
|
||||
"node_modules/@ali-hm/angular-tree-component/css/angular-tree-component.css",
|
||||
"node_modules/leaflet/dist/leaflet.css",
|
||||
"apps/server/src/styles.css",
|
||||
"apps/server/src/assets/styles/styles.scss",
|
||||
"node_modules/@ng-select/ng-select/themes/default.theme.css"
|
||||
],
|
||||
|
||||
@@ -1,48 +1,38 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import {
|
||||
AboutComponent,
|
||||
AuthConnectionGuard,
|
||||
ServerDashboardComponent,
|
||||
SettingsComponent,
|
||||
SetupComponent,
|
||||
SplashScreenComponent,
|
||||
UpdaterComponent
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'setup',
|
||||
component: SetupComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SetupComponent)
|
||||
},
|
||||
{
|
||||
path: 'plugins',
|
||||
canActivate: [AuthConnectionGuard],
|
||||
loadChildren: () => import('@gauzy/desktop-ui-lib').then((m) => m.PluginRoutingModule)
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SettingsComponent)
|
||||
},
|
||||
{
|
||||
path: 'updater',
|
||||
component: UpdaterComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.UpdaterComponent)
|
||||
},
|
||||
{
|
||||
path: 'server-dashboard',
|
||||
component: ServerDashboardComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.ServerDashboardComponent)
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.AboutComponent)
|
||||
},
|
||||
{
|
||||
path: 'splash-screen',
|
||||
component: SplashScreenComponent
|
||||
loadComponent: () => import('@gauzy/desktop-ui-lib').then((m) => m.SplashScreenComponent)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ import { RouterTestingModule } from '@angular/router/testing';
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule],
|
||||
declarations: [AppComponent]
|
||||
}).compileComponents();
|
||||
imports: [RouterTestingModule],
|
||||
declarations: [AppComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
it('should create the app', () => {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { LanguageElectronService } from '@gauzy/desktop-ui-lib';
|
||||
|
||||
@Component({
|
||||
selector: 'gauzy-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
standalone: false
|
||||
selector: 'gauzy-root',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
imports: [RouterOutlet]
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
constructor(private readonly languageElectronService: LanguageElectronService) {}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { ErrorHandler, NgModule, inject, provideAppInitializer } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import {
|
||||
AboutModule,
|
||||
ElectronService,
|
||||
GAUZY_ENV,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
PluginsModule,
|
||||
ServerDashboardModule,
|
||||
SettingsModule,
|
||||
SetupModule,
|
||||
UpdaterModule
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbDialogModule,
|
||||
NbDialogService,
|
||||
NbLayoutModule,
|
||||
NbMenuModule,
|
||||
NbSidebarModule,
|
||||
NbThemeModule,
|
||||
NbToastrModule
|
||||
} from '@nebular/theme';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppService } from './app.service';
|
||||
import { initializeSentry } from './sentry';
|
||||
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent],
|
||||
imports: [
|
||||
NbLayoutModule,
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
NbThemeModule,
|
||||
NgxDesktopThemeModule,
|
||||
NbMenuModule.forRoot(),
|
||||
NbSidebarModule.forRoot(),
|
||||
SetupModule,
|
||||
SettingsModule,
|
||||
UpdaterModule,
|
||||
ServerDashboardModule,
|
||||
AboutModule,
|
||||
LanguageModule.forRoot(),
|
||||
PluginsModule
|
||||
],
|
||||
providers: [
|
||||
AppService,
|
||||
NbDialogService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi())
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
+85
-6
@@ -1,12 +1,91 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { AppModule } from './app/app.module';
|
||||
import { enableProdMode, ErrorHandler, importProvidersFrom, inject, provideAppInitializer } from '@angular/core';
|
||||
import { bootstrapApplication, BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import {
|
||||
ElectronService,
|
||||
GAUZY_ENV,
|
||||
HttpLoaderFactory,
|
||||
LanguageModule,
|
||||
LoggerService,
|
||||
NgxDesktopThemeModule,
|
||||
Store
|
||||
} from '@gauzy/desktop-ui-lib';
|
||||
import { environment as gauzyEnvironment } from '@gauzy/ui-config';
|
||||
import { NbTablerIconsModule } from '@gauzy/ui-core/theme';
|
||||
import { NbDialogModule, NbDialogService, NbMenuModule, NbSidebarModule, NbToastrModule } from '@nebular/theme';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { AppRoutingModule } from './app/app-routing.module';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { AppService } from './app/app.service';
|
||||
import { initializeSentry } from './app/sentry';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowser()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch((err) => console.error(err));
|
||||
if (environment.SENTRY_DSN) {
|
||||
if (environment.SENTRY_DSN === 'DOCKER_SENTRY_DSN') {
|
||||
console.warn('You are running inside Docker but does not have SENTRY_DSN env set');
|
||||
} else {
|
||||
console.log(`Enabling Sentry with DSN: ${environment.SENTRY_DSN}`);
|
||||
initializeSentry();
|
||||
}
|
||||
}
|
||||
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
importProvidersFrom(
|
||||
NbDialogModule.forRoot(),
|
||||
NbToastrModule.forRoot(),
|
||||
BrowserModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
NbMenuModule.forRoot(),
|
||||
NbSidebarModule.forRoot(),
|
||||
LanguageModule.forRoot(),
|
||||
NgxDesktopThemeModule,
|
||||
NbTablerIconsModule,
|
||||
TranslateModule.forRoot({
|
||||
extend: true,
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
})
|
||||
),
|
||||
AppService,
|
||||
NbDialogService,
|
||||
ElectronService,
|
||||
LoggerService,
|
||||
Store,
|
||||
{
|
||||
provide: ErrorHandler,
|
||||
useValue: Sentry.createErrorHandler({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
{
|
||||
provide: Sentry.TraceService,
|
||||
deps: [Router]
|
||||
},
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = ((trace: Sentry.TraceService) => () => {})(inject(Sentry.TraceService));
|
||||
return initializerFn();
|
||||
}),
|
||||
{
|
||||
provide: GAUZY_ENV,
|
||||
useValue: {
|
||||
...gauzyEnvironment,
|
||||
...environment
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations()
|
||||
]
|
||||
}).catch((err) => console.error(err));
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
@@ -433,6 +433,7 @@
|
||||
"build:agent:linux:release:gh:x64": "yarn run pack --desktop=agent --arch=x64 --platform=linux && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:agent && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --linux --x64 --publish=always --project dist/apps/agent",
|
||||
"build:agent:linux:release:gh:arm64": "yarn run pack --desktop=agent --arch=arm64 --platform=linux && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:agent && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --linux --arm64 --publish=always --project dist/apps/agent",
|
||||
"build:agent:mac": "yarn run build:agent && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --mac --project dist/apps/agent",
|
||||
"build:agent:mac:quick": "yarn run build:agent:mac -c.mac.identity=null",
|
||||
"build:agent:mac:release": "yarn run build:agent && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --mac --publish=always --project dist/apps/agent",
|
||||
"copy-assets-agent": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/agent/data/sound/",
|
||||
"build:mcp-server": "yarn nx build mcp-server",
|
||||
|
||||
@@ -9,11 +9,11 @@ export * from './lib/always-on/always-on.component';
|
||||
export * from './lib/always-on/always-on.module';
|
||||
export * from './lib/auth';
|
||||
export * from './lib/constants';
|
||||
export * from './lib/desktop-ui-lib.module';
|
||||
|
||||
export * from './lib/dialogs/about/about.component';
|
||||
export * from './lib/dialogs/about/about.module';
|
||||
export * from './lib/dialogs/alert/alert.component';
|
||||
export * from './lib/dialogs/alert/alert.module';
|
||||
|
||||
export * from './lib/electron/services';
|
||||
export * from './lib/image-viewer/image-viewer.component';
|
||||
export * from './lib/image-viewer/image-viewer.module';
|
||||
@@ -33,7 +33,7 @@ export * from './lib/recap/recap-routing.module';
|
||||
export * from './lib/recap/recap.module';
|
||||
export * from './lib/recap/weekly/features/weekly-recap/weekly-recap.component';
|
||||
export * from './lib/screen-capture/screen-capture.component';
|
||||
export * from './lib/screen-capture/screen-capture.module';
|
||||
|
||||
export * from './lib/server-connection.factory';
|
||||
export * from './lib/server-dashboard/server-dashboard.component';
|
||||
export * from './lib/server-dashboard/server-dashboard.module';
|
||||
@@ -60,7 +60,7 @@ export * from './lib/time-tracker/time-tracker.component';
|
||||
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';
|
||||
|
||||
|
||||
/**
|
||||
* Auth Module
|
||||
|
||||
+4
-5
@@ -3,11 +3,10 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { StatusMapper } from '../../../shared/utils/queue-status-mapper.util';
|
||||
|
||||
@Component({
|
||||
selector: 'app-status-badge',
|
||||
templateUrl: './status-render.html',
|
||||
styleUrls: ['./status-render.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'app-status-badge',
|
||||
templateUrl: './status-render.html',
|
||||
styleUrls: ['./status-render.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class StatusBadgeComponent {
|
||||
@Input() value: string;
|
||||
|
||||
+55
-51
@@ -1,63 +1,67 @@
|
||||
<nb-card>
|
||||
<nb-card-header class="d-flex justify-content-between align-items-center">
|
||||
<h6>Queue Item Details</h6>
|
||||
<button nbButton ghost size="small" (click)="close()">
|
||||
<nb-icon icon="close-outline"></nb-icon>
|
||||
</button>
|
||||
</nb-card-header>
|
||||
<nb-card-header class="d-flex justify-content-between align-items-center">
|
||||
<h6>Queue Item Details</h6>
|
||||
<button nbButton ghost size="small" (click)="close()">
|
||||
<nb-icon icon="close-outline"></nb-icon>
|
||||
</button>
|
||||
</nb-card-header>
|
||||
|
||||
<nb-card-body>
|
||||
<div class="detail-section">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">ID:</span>
|
||||
<span class="detail-value">{{ data.id || 'N/A' }}</span>
|
||||
</div>
|
||||
<nb-card-body>
|
||||
<div class="detail-section">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">ID:</span>
|
||||
<span class="detail-value">{{ data.id || 'N/A' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Queue ID:</span>
|
||||
<span class="detail-value">{{ data.queue_id || 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Queue ID:</span>
|
||||
<span class="detail-value">{{ data.queue_id || 'N/A' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Queue:</span>
|
||||
<span class="detail-value">{{ data.queue || 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Queue:</span>
|
||||
<span class="detail-value">{{ data.queue || 'N/A' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Status:</span>
|
||||
<span [class]="'status-chip status-' + getStatusClass(data.status)">
|
||||
{{ data.status || 'N/A' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Status:</span>
|
||||
<span [class]="'status-chip status-' + getStatusClass(data.status)">
|
||||
{{ data.status || 'N/A' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Attempts:</span>
|
||||
<span class="detail-value">{{ data.attempts || 0 }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Attempts:</span>
|
||||
<span class="detail-value">{{ data.attempts || 0 }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Priority:</span>
|
||||
<span class="detail-value">{{ data.priority || 0 }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Priority:</span>
|
||||
<span class="detail-value">{{ data.priority || 0 }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Created At:</span>
|
||||
<span class="detail-value">{{ getFormattedDate(data.created_at) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Created At:</span>
|
||||
<span class="detail-value">{{ getFormattedDate(data.created_at) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row" *ngIf="data.last_error">
|
||||
<span class="detail-label">Last Error:</span>
|
||||
<span class="detail-value error-text">{{ data.last_error }}</span>
|
||||
</div>
|
||||
@if (data.last_error) {
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Last Error:</span>
|
||||
<span class="detail-value error-text">{{ data.last_error }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="detail-row full-width" *ngIf="data.data">
|
||||
<span class="detail-label">Data:</span>
|
||||
<pre class="data-json">{{ getFormattedData() }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
@if (data.data) {
|
||||
<div class="detail-row full-width">
|
||||
<span class="detail-label">Data:</span>
|
||||
<pre class="data-json">{{ getFormattedData() }}</pre>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</nb-card-body>
|
||||
|
||||
<nb-card-footer class="text-right">
|
||||
<button nbButton status="basic" (click)="close()">Close</button>
|
||||
</nb-card-footer>
|
||||
<nb-card-footer class="text-right">
|
||||
<button nbButton status="basic" (click)="close()">Close</button>
|
||||
</nb-card-footer>
|
||||
</nb-card>
|
||||
|
||||
+6
-5
@@ -1,13 +1,14 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { NbDialogRef } from '@nebular/theme';
|
||||
import { NbDialogRef, NbCardModule, NbButtonModule, NbIconModule } from '@nebular/theme';
|
||||
import { QueueItem } from '../../models/logs.models';
|
||||
import { StatusMapper } from '../../../shared/utils/queue-status-mapper.util';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-activity-sync-detail-modal',
|
||||
templateUrl: './activity-sync-detail-modal.component.html',
|
||||
styleUrls: ['./activity-sync-detail-modal.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-activity-sync-detail-modal',
|
||||
templateUrl: './activity-sync-detail-modal.component.html',
|
||||
styleUrls: ['./activity-sync-detail-modal.component.scss'],
|
||||
imports: [NbCardModule, NbButtonModule, NbIconModule]
|
||||
})
|
||||
export class ActivitySyncDetailModalComponent {
|
||||
@Input() data: QueueItem;
|
||||
|
||||
+22
-22
@@ -19,26 +19,26 @@
|
||||
</nb-card>
|
||||
|
||||
<ng-template #tableView>
|
||||
<div class="row grow">
|
||||
<div class="col-12 custom-table">
|
||||
<div class="table-scroll-container grow" style="max-height: calc(100vh - 145px);">
|
||||
<ng-container *ngIf="loading$ | async">
|
||||
<div class="smart-table" [nbSpinner]="true" nbSpinnerSize="small"></div>
|
||||
</ng-container>
|
||||
<angular2-smart-table
|
||||
#smartTable
|
||||
[settings]="smartTableSettings"
|
||||
[source]="smartTableSource"
|
||||
style="cursor: pointer"
|
||||
(userRowSelect)="onRowClick($event)"
|
||||
>
|
||||
</angular2-smart-table>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #noTask>
|
||||
<div class="no-data col-12">
|
||||
<ngx-no-data-message [message]="'SM_TABLE.NO_DATA.TASK' | translate"> </ngx-no-data-message>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="row grow">
|
||||
<div class="col-12 custom-table">
|
||||
<div class="table-scroll-container grow" style="max-height: calc(100vh - 145px);">
|
||||
@if (loading$ | async) {
|
||||
<div class="smart-table" [nbSpinner]="true" nbSpinnerSize="small"></div>
|
||||
}
|
||||
<angular2-smart-table
|
||||
#smartTable
|
||||
[settings]="smartTableSettings"
|
||||
[source]="smartTableSource"
|
||||
style="cursor: pointer"
|
||||
(userRowSelect)="onRowClick($event)"
|
||||
>
|
||||
</angular2-smart-table>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #noTask>
|
||||
<div class="no-data col-12">
|
||||
<ngx-no-data-message [message]="'SM_TABLE.NO_DATA.TASK' | translate"> </ngx-no-data-message>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
+7
-6
@@ -3,18 +3,19 @@ import { combineLatest, Subject, Observable } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { QueueItem, SyncHealth } from '../models/logs.models';
|
||||
import { LogService } from '../services/logs.service';
|
||||
import { Angular2SmartTableComponent, Cell, LocalDataSource } from 'angular2-smart-table';
|
||||
import { Angular2SmartTableComponent, Cell, LocalDataSource, Angular2SmartTableModule } from 'angular2-smart-table';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { StatusBadgeComponent } from './activity-render/status-render';
|
||||
import { LocalDateParse } from '../pipes/date.pipe';
|
||||
import { NbDialogService } from '@nebular/theme';
|
||||
import { NbDialogService, NbCardModule, NbTabsetModule, NbSpinnerModule } from '@nebular/theme';
|
||||
import { StatusMapper } from '../../shared/utils/queue-status-mapper.util';
|
||||
import { NgTemplateOutlet, AsyncPipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sync-page',
|
||||
templateUrl: './activity-sync.component.html',
|
||||
styleUrls: ['./activity-sync.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-sync-page',
|
||||
templateUrl: './activity-sync.component.html',
|
||||
styleUrls: ['./activity-sync.component.scss'],
|
||||
imports: [NbCardModule, NbTabsetModule, NgTemplateOutlet, NbSpinnerModule, Angular2SmartTableModule, AsyncPipe]
|
||||
})
|
||||
export class SyncPageComponent implements OnInit, OnDestroy {
|
||||
items$: Observable<QueueItem[]> = this.svc.queueStream$;
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { Component, Inject, OnInit, OnDestroy } from '@angular/core';
|
||||
import { NbMenuItem, NbSidebarState } from '@nebular/theme';
|
||||
import { NbMenuItem, NbSidebarState, NbLayoutModule, NbSidebarModule, NbMenuModule } from '@nebular/theme';
|
||||
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
||||
import { GAUZY_ENV } from '../constants';
|
||||
import { IpcService } from './services/ipc.service';
|
||||
import { TasksService } from './services/tasks-service';
|
||||
import { NgClass } from '@angular/common';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-agent-dashboard',
|
||||
templateUrl: './agent-dashboard.component.html',
|
||||
styleUrls: ['./agent-dashboard.component.scss'],
|
||||
standalone: false
|
||||
selector: 'ngx-agent-dashboard',
|
||||
templateUrl: './agent-dashboard.component.html',
|
||||
styleUrls: ['./agent-dashboard.component.scss'],
|
||||
imports: [NbLayoutModule, NbSidebarModule, NgClass, NbMenuModule, RouterOutlet]
|
||||
})
|
||||
export class AgentDashboardComponent implements OnInit, OnDestroy {
|
||||
menu: NbMenuItem[] = [
|
||||
|
||||
@@ -42,49 +42,47 @@ import { StatusBadgeComponent } from './activity-sync/activity-render/status-ren
|
||||
import { ActivitySyncDetailModalComponent } from './activity-sync/activity-sync-detail-modal/activity-sync-detail-modal.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AgentDashboardComponent,
|
||||
LogsPageComponent,
|
||||
SyncPageComponent,
|
||||
StatusBadgeComponent,
|
||||
ActivitySyncDetailModalComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
RouterModule,
|
||||
NbThemeModule.forRoot({ name: 'dark' }),
|
||||
NbLayoutModule,
|
||||
NbSidebarModule.forRoot(),
|
||||
NbMenuModule,
|
||||
NbIconModule,
|
||||
NbTablerIconsModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbActionsModule,
|
||||
NbSelectModule,
|
||||
NbToggleModule,
|
||||
NbListModule,
|
||||
NbBadgeModule,
|
||||
NbUserModule,
|
||||
NbTabsetModule,
|
||||
NbTooltipModule,
|
||||
NbProgressBarModule,
|
||||
NbSpinnerModule,
|
||||
NbContextMenuModule,
|
||||
NbInputModule,
|
||||
NbCheckboxModule,
|
||||
NbAlertModule,
|
||||
FilterStatusPipe,
|
||||
LocalDateParse,
|
||||
NbRouteTabsetModule,
|
||||
NbDialogModule.forChild(),
|
||||
TasksModule,
|
||||
Angular2SmartTableModule
|
||||
],
|
||||
exports: [FilterStatusPipe, LocalDateParse]
|
||||
imports: [
|
||||
CommonModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
RouterModule,
|
||||
NbThemeModule.forRoot({ name: 'dark' }),
|
||||
NbLayoutModule,
|
||||
NbSidebarModule.forRoot(),
|
||||
NbMenuModule,
|
||||
NbIconModule,
|
||||
NbTablerIconsModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbActionsModule,
|
||||
NbSelectModule,
|
||||
NbToggleModule,
|
||||
NbListModule,
|
||||
NbBadgeModule,
|
||||
NbUserModule,
|
||||
NbTabsetModule,
|
||||
NbTooltipModule,
|
||||
NbProgressBarModule,
|
||||
NbSpinnerModule,
|
||||
NbContextMenuModule,
|
||||
NbInputModule,
|
||||
NbCheckboxModule,
|
||||
NbAlertModule,
|
||||
FilterStatusPipe,
|
||||
LocalDateParse,
|
||||
NbRouteTabsetModule,
|
||||
NbDialogModule.forChild(),
|
||||
TasksModule,
|
||||
Angular2SmartTableModule,
|
||||
AgentDashboardComponent,
|
||||
LogsPageComponent,
|
||||
SyncPageComponent,
|
||||
StatusBadgeComponent,
|
||||
ActivitySyncDetailModalComponent
|
||||
],
|
||||
exports: [FilterStatusPipe, LocalDateParse]
|
||||
})
|
||||
export class AgentDashboardModule {}
|
||||
|
||||
@@ -2,12 +2,15 @@ import { Component, ViewChild, ElementRef, AfterViewChecked, OnDestroy, OnInit }
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { LogEntry } from '../models/logs.models';
|
||||
import { LogService } from '../services/logs.service';
|
||||
import { NbCardModule, NbSelectModule, NbOptionModule, NbInputModule, NbCheckboxModule } from '@nebular/theme';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgClass, AsyncPipe, DatePipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-logs-page',
|
||||
templateUrl: './logs.component.html',
|
||||
styleUrls: ['./logs.component.scss'],
|
||||
standalone: false
|
||||
selector: 'app-logs-page',
|
||||
templateUrl: './logs.component.html',
|
||||
styleUrls: ['./logs.component.scss'],
|
||||
imports: [NbCardModule, NbSelectModule, NbOptionModule, NbInputModule, FormsModule, NbCheckboxModule, NgClass, AsyncPipe, DatePipe]
|
||||
})
|
||||
export class LogsPageComponent implements AfterViewChecked, OnDestroy, OnInit {
|
||||
@ViewChild('logContainer') private logContainer: ElementRef;
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { Component, NgZone, OnDestroy, OnInit, Inject, Renderer2, HostBinding, HostListener } from '@angular/core';
|
||||
import { NbIconLibraries } from '@nebular/theme';
|
||||
import { NbIconLibraries, NbLayoutModule, NbCardModule, NbButtonModule, NbIconModule, NbTooltipModule } from '@nebular/theme';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject, Observable, Subscription, tap } from 'rxjs';
|
||||
import { LanguageElectronService } from '../language/language-electron.service';
|
||||
import { AlwaysOnService, AlwaysOnStateEnum, ITimeCounter, ITimerStatus } from './always-on.service';
|
||||
import { faPlay, faPause, faStopwatch, faBars, faDollar } from '@fortawesome/free-solid-svg-icons';
|
||||
import { GAUZY_ENV } from '../constants';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { NgClass, AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'gauzy-always-on',
|
||||
templateUrl: './always-on.component.html',
|
||||
styleUrls: ['./always-on.component.scss'],
|
||||
standalone: false
|
||||
selector: 'gauzy-always-on',
|
||||
templateUrl: './always-on.component.html',
|
||||
styleUrls: ['./always-on.component.scss'],
|
||||
imports: [NbLayoutModule, NbCardModule, FaIconComponent, NgClass, NbButtonModule, NbIconModule, NbTooltipModule, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class AlwaysOnComponent implements OnInit, OnDestroy {
|
||||
@HostBinding('class.rounded-theme') isRounded = false;
|
||||
|
||||
@@ -9,19 +9,19 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import { NbTablerIconsModule } from '@gauzy/ui-core/theme';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AlwaysOnComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbLayoutModule,
|
||||
LanguageModule.forChild(),
|
||||
NbIconModule,
|
||||
NbTablerIconsModule,
|
||||
NbTooltipModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
FormsModule,
|
||||
FontAwesomeModule
|
||||
],
|
||||
providers: [AlwaysOnService]
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbLayoutModule,
|
||||
LanguageModule.forChild(),
|
||||
NbIconModule,
|
||||
NbTablerIconsModule,
|
||||
NbTooltipModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
FormsModule,
|
||||
FontAwesomeModule,
|
||||
AlwaysOnComponent
|
||||
],
|
||||
providers: [AlwaysOnService]
|
||||
})
|
||||
export class AlwaysOnModule {}
|
||||
|
||||
@@ -6,10 +6,10 @@ import {
|
||||
NbRequestPasswordComponent,
|
||||
NbResetPasswordComponent
|
||||
} from '@nebular/auth';
|
||||
import { NgxLoginComponent } from '../login';
|
||||
import { NgxLoginMagicComponent } from '../login/features/login-magic/login-magic.component';
|
||||
import { NgxLoginWorkspaceComponent } from '../login/features/login-workspace/login-workspace.component';
|
||||
import { NgxMagicSignInWorkspaceComponent } from '../login/features/magic-login-workspace/magic-login-workspace.component';
|
||||
|
||||
|
||||
|
||||
|
||||
import { NoAuthGuard } from './no-auth.guard';
|
||||
|
||||
export const authRoutes: Route[] = [
|
||||
@@ -24,7 +24,7 @@ export const authRoutes: Route[] = [
|
||||
},
|
||||
{
|
||||
path: 'login',
|
||||
component: NgxLoginComponent,
|
||||
loadComponent: () => import('../login').then(m => m.NgxLoginComponent),
|
||||
canActivate: [NoAuthGuard]
|
||||
},
|
||||
{
|
||||
@@ -50,7 +50,7 @@ export const authRoutes: Route[] = [
|
||||
// Register the path 'login-workspace'
|
||||
path: 'login-workspace',
|
||||
// Register the component to load component: NgxLoginWorkspaceComponent,
|
||||
component: NgxLoginWorkspaceComponent,
|
||||
loadComponent: () => import('../login/features/login-workspace/login-workspace.component').then(m => m.NgxLoginWorkspaceComponent),
|
||||
// Register the data object
|
||||
canActivate: [NoAuthGuard]
|
||||
},
|
||||
@@ -58,7 +58,7 @@ export const authRoutes: Route[] = [
|
||||
// Register the path 'login-magic'
|
||||
path: 'login-magic',
|
||||
// Register the component to load component: NgxLoginMagicComponent,
|
||||
component: NgxLoginMagicComponent,
|
||||
loadComponent: () => import('../login/features/login-magic/login-magic.component').then(m => m.NgxLoginMagicComponent),
|
||||
// Register the data object
|
||||
canActivate: [NoAuthGuard]
|
||||
},
|
||||
@@ -66,7 +66,7 @@ export const authRoutes: Route[] = [
|
||||
// Register the path 'magic-sign-in'
|
||||
path: 'magic-sign-in',
|
||||
// Register the component to load component: NgxMagicSignInWorkspaceComponent,
|
||||
component: NgxMagicSignInWorkspaceComponent,
|
||||
loadComponent: () => import('../login/features/magic-login-workspace/magic-login-workspace.component').then(m => m.NgxMagicSignInWorkspaceComponent),
|
||||
// Register the data object
|
||||
canActivate: [NoAuthGuard]
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule]
|
||||
})
|
||||
export class DesktopUiLibModule {}
|
||||
@@ -4,12 +4,14 @@ import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { GAUZY_ENV } from '../../constants';
|
||||
import { ElectronService } from '../../electron/services';
|
||||
import { LanguageElectronService } from '../../language/language-electron.service';
|
||||
import { NbLayoutModule, NbCardModule } from '@nebular/theme';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'gauzy-about',
|
||||
templateUrl: './about.component.html',
|
||||
styleUrls: ['./about.component.scss'],
|
||||
standalone: false
|
||||
selector: 'gauzy-about',
|
||||
templateUrl: './about.component.html',
|
||||
styleUrls: ['./about.component.scss'],
|
||||
imports: [NbLayoutModule, NbCardModule, TranslatePipe]
|
||||
})
|
||||
export class AboutComponent implements OnInit {
|
||||
private _application = {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { LanguageModule } from '../../language/language.module';
|
||||
import { AboutComponent } from './about.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AboutComponent],
|
||||
imports: [CommonModule, NbCardModule, NbButtonModule, NbLayoutModule, LanguageModule.forChild()]
|
||||
imports: [CommonModule, NbCardModule, NbButtonModule, NbLayoutModule, LanguageModule.forChild(), AboutComponent]
|
||||
})
|
||||
export class AboutModule {}
|
||||
|
||||
@@ -8,8 +8,8 @@ describe('AlertComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [AlertComponent]
|
||||
}).compileComponents();
|
||||
imports: [AlertComponent]
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { NbDialogRef } from '@nebular/theme';
|
||||
import { NbDialogRef, NbCardModule, NbButtonModule } from '@nebular/theme';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
export interface AlertDialogOptions {
|
||||
title?: string;
|
||||
@@ -9,10 +10,10 @@ export interface AlertDialogOptions {
|
||||
dismissText?: string;
|
||||
}
|
||||
@Component({
|
||||
selector: 'ngx-alert',
|
||||
templateUrl: './alert.component.html',
|
||||
styleUrls: ['./alert.component.scss'],
|
||||
standalone: false
|
||||
selector: 'ngx-alert',
|
||||
templateUrl: './alert.component.html',
|
||||
styleUrls: ['./alert.component.scss'],
|
||||
imports: [NbCardModule, NbButtonModule, TranslatePipe]
|
||||
})
|
||||
export class AlertComponent {
|
||||
@Input() data: AlertDialogOptions;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { AlertComponent } from './alert.component';
|
||||
import {
|
||||
NbLayoutModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbButtonModule,
|
||||
NbAlertModule
|
||||
} from '@nebular/theme';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AlertComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbLayoutModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbButtonModule,
|
||||
NbAlertModule,
|
||||
TranslateModule
|
||||
],
|
||||
exports: [AlertComponent]
|
||||
})
|
||||
export class AlertModule {}
|
||||
@@ -2,10 +2,7 @@ import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output
|
||||
import { Subject, Subscription, tap } from 'rxjs';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
|
||||
@Directive({
|
||||
selector: '[debounceClick]',
|
||||
standalone: false
|
||||
})
|
||||
@Directive({ selector: '[debounceClick]' })
|
||||
export class DebounceClickDirective implements OnInit, OnDestroy {
|
||||
private clicks: Subject<Event> = new Subject<Event>();
|
||||
private subscription: Subscription;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NbSpinnerModule } from '@nebular/theme';
|
||||
import { DebounceClickDirective } from './debounce-click.directive';
|
||||
import { DynamicDirective } from './dynamic.directive';
|
||||
import { SpinnerButtonDirective } from './spinner-button.directive';
|
||||
import { TextMaskDirective } from './text-mask.directive';
|
||||
import { ReadMoreDirective } from './read-more.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
SpinnerButtonDirective,
|
||||
DynamicDirective,
|
||||
TextMaskDirective,
|
||||
DebounceClickDirective,
|
||||
ReadMoreDirective
|
||||
],
|
||||
exports: [SpinnerButtonDirective, DynamicDirective, TextMaskDirective, DebounceClickDirective, ReadMoreDirective],
|
||||
imports: [CommonModule, NbSpinnerModule]
|
||||
})
|
||||
export class DesktopDirectiveModule {}
|
||||
@@ -1,9 +1,6 @@
|
||||
import { Directive, ViewContainerRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[dynamicDirective]',
|
||||
standalone: false
|
||||
})
|
||||
@Directive({ selector: '[dynamicDirective]' })
|
||||
export class DynamicDirective {
|
||||
constructor(public viewContainerRef: ViewContainerRef) {}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { AfterViewInit, Directive, ElementRef, Input, Renderer2 } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[readMore]',
|
||||
standalone: false
|
||||
})
|
||||
@Directive({ selector: '[readMore]' })
|
||||
export class ReadMoreDirective implements AfterViewInit {
|
||||
@Input('readMore') maxLength = 100;
|
||||
@Input() readMoreText = 'Read More';
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { Directive, Input, Renderer2, TemplateRef, ViewContainerRef, inject } from '@angular/core';
|
||||
import { NbSpinnerComponent } from '@nebular/theme';
|
||||
|
||||
@Directive({
|
||||
selector: '[gauzySpinnerButton]',
|
||||
standalone: false
|
||||
})
|
||||
@Directive({ selector: '[gauzySpinnerButton]' })
|
||||
export class SpinnerButtonDirective {
|
||||
private _isSpinning: boolean | null = null;
|
||||
private _spinner: HTMLElement | null = null;
|
||||
|
||||
@@ -8,10 +8,7 @@ interface IMaskConfig {
|
||||
maskFromLeft: boolean; // New property to control mask direction
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[gaTextMask]',
|
||||
standalone: false
|
||||
})
|
||||
@Directive({ selector: '[gaTextMask]' })
|
||||
export class TextMaskDirective {
|
||||
// Default configuration for text masking
|
||||
private readonly _config: IMaskConfig = {
|
||||
|
||||
@@ -7,8 +7,8 @@ describe('ImageViewerComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ImageViewerComponent],
|
||||
}).compileComponents();
|
||||
imports: [ImageViewerComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -4,7 +4,9 @@ import { ElectronService } from '../electron/services';
|
||||
import { SafeUrl } from '@angular/platform-browser';
|
||||
import { ImageViewerService } from './image-viewer.service';
|
||||
import { from } from 'rxjs';
|
||||
import { NbIconLibraries } from '@nebular/theme';
|
||||
import { NbIconLibraries, NbLayoutModule, NbButtonModule, NbIconModule, NbSpinnerModule } from '@nebular/theme';
|
||||
import { NgTemplateOutlet, NgClass, AsyncPipe } from '@angular/common';
|
||||
import { DateTimePipe } from '../time-tracker/pipes/date-time.pipe';
|
||||
|
||||
export const fadeInOutAnimation = trigger('fadeInOut', [
|
||||
transition(':enter', [
|
||||
@@ -19,11 +21,11 @@ export const fadeInOutAnimation = trigger('fadeInOut', [
|
||||
]);
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-image-viewer',
|
||||
templateUrl: './image-viewer.component.html',
|
||||
styleUrls: ['./image-viewer.component.scss'],
|
||||
animations: [fadeInOutAnimation],
|
||||
standalone: false
|
||||
selector: 'ngx-image-viewer',
|
||||
templateUrl: './image-viewer.component.html',
|
||||
styleUrls: ['./image-viewer.component.scss'],
|
||||
animations: [fadeInOutAnimation],
|
||||
imports: [NbLayoutModule, NbButtonModule, NbIconModule, NbSpinnerModule, NgTemplateOutlet, NgClass, AsyncPipe, DateTimePipe]
|
||||
})
|
||||
export class ImageViewerComponent implements OnInit {
|
||||
active_index: number;
|
||||
|
||||
@@ -16,19 +16,19 @@ import { ImageViewerService } from './image-viewer.service';
|
||||
import { NbTablerIconsModule } from '@gauzy/ui-core/theme';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ImageViewerComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbLayoutModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbTablerIconsModule,
|
||||
NbDialogModule,
|
||||
NbButtonModule,
|
||||
NbSpinnerModule,
|
||||
PipeModule
|
||||
],
|
||||
exports: [ImageViewerComponent],
|
||||
providers: [NbDialogService, ImageViewerService, ImageCacheService, StorageService, Store]
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbLayoutModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbTablerIconsModule,
|
||||
NbDialogModule,
|
||||
NbButtonModule,
|
||||
NbSpinnerModule,
|
||||
PipeModule,
|
||||
ImageViewerComponent
|
||||
],
|
||||
exports: [ImageViewerComponent],
|
||||
providers: [NbDialogService, ImageViewerService, ImageCacheService, StorageService, Store]
|
||||
})
|
||||
export class ImageViewerModule {}
|
||||
|
||||
+3
-4
@@ -8,9 +8,8 @@ import { ActivityWatchViewService } from './activity-watch-view.service';
|
||||
import { ActivityWatchElectronService } from './activity-watch-electron.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ActivityWatchComponent],
|
||||
exports: [ActivityWatchComponent],
|
||||
imports: [CommonModule, NbIconModule, NbTooltipModule, NbToggleModule, TranslateModule],
|
||||
providers: [ActivityWatchEventService, ActivityWatchViewService, ActivityWatchElectronService]
|
||||
exports: [ActivityWatchComponent],
|
||||
imports: [CommonModule, NbIconModule, NbTooltipModule, NbToggleModule, TranslateModule, ActivityWatchComponent],
|
||||
providers: [ActivityWatchEventService, ActivityWatchViewService, ActivityWatchElectronService]
|
||||
})
|
||||
export class ActivityWatchModule {}
|
||||
|
||||
+4
-1
@@ -1,12 +1,15 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ActivityWatchViewService } from '../activity-watch-view.service';
|
||||
import { NbTooltipModule, NbToggleModule, NbIconModule } from '@nebular/theme';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'gauzy-activity-watch',
|
||||
templateUrl: './activity-watch.component.html',
|
||||
styleUrls: ['./activity-watch.component.scss'],
|
||||
standalone: false
|
||||
imports: [NbTooltipModule, NbToggleModule, NbIconModule, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class ActivityWatchComponent {
|
||||
constructor(private readonly activityWatchViewService: ActivityWatchViewService) {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AfterViewInit, Component, Input, NgZone, OnInit } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
||||
import { ILanguage, IUser, IUserUpdateInput, LanguagesEnum } from '@gauzy/contracts';
|
||||
import { distinctUntilChange } from '@gauzy/ui-core/common';
|
||||
import { UserOrganizationService } from '../time-tracker/organization-selector/user-organization.service';
|
||||
@@ -9,13 +9,15 @@ import { tap, filter, from, BehaviorSubject, Observable, concatMap, Subject } fr
|
||||
import { Store } from '../services';
|
||||
import { LanguageSelectorService } from './language-selector.service';
|
||||
import { ElectronService } from '../electron/services';
|
||||
import { NbSelectModule, NbOptionModule } from '@nebular/theme';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'gauzy-language-selector',
|
||||
templateUrl: './language-selector.component.html',
|
||||
styleUrls: ['./language-selector.component.scss'],
|
||||
standalone: false
|
||||
imports: [NbSelectModule, NbOptionModule, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class LanguageSelectorComponent implements OnInit, AfterViewInit {
|
||||
private _user: IUser;
|
||||
|
||||
@@ -10,9 +10,8 @@ import { LanguageSelectorService } from './language-selector.service';
|
||||
import { LanguageService } from './language.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [LanguageSelectorComponent],
|
||||
imports: [CommonModule, NgxTranslateModule, NbSelectModule],
|
||||
exports: [LanguageSelectorComponent, NgxTranslateModule]
|
||||
imports: [CommonModule, NgxTranslateModule, NbSelectModule, LanguageSelectorComponent],
|
||||
exports: [LanguageSelectorComponent, NgxTranslateModule]
|
||||
})
|
||||
export class LanguageModule {
|
||||
static forRoot(): ModuleWithProviders<LanguageModule> {
|
||||
|
||||
+11
-3
@@ -1,19 +1,27 @@
|
||||
import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { AbstractControl, FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { ActivatedRoute, Params, Router, RouterLink } from '@angular/router';
|
||||
import { NB_AUTH_OPTIONS, NbAuthService, NbLoginComponent } from '@nebular/auth';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { EMPTY, Subscription, catchError, filter, finalize, firstValueFrom, interval, tap } from 'rxjs';
|
||||
import { AuthService } from '../../../auth';
|
||||
import { GAUZY_ENV, patterns } from '../../../constants';
|
||||
import { ErrorHandlerService } from '../../../services';
|
||||
import { LogoComponent } from '../../shared/ui/logo/logo.component';
|
||||
import { SwitchThemeComponent } from '../../../theme-selector/switch-theme/switch-theme.component';
|
||||
import { NgClass, NgStyle } from '@angular/common';
|
||||
import { NbFormFieldModule, NbInputModule, NbIconModule, NbButtonModule } from '@nebular/theme';
|
||||
import { DebounceClickDirective } from '../../../directives/debounce-click.directive';
|
||||
import { SpinnerButtonDirective } from '../../../directives/spinner-button.directive';
|
||||
import { SocialLinksComponent } from '../../shared/ui/social-links/social-links.component';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-login-magic',
|
||||
templateUrl: './login-magic.component.html',
|
||||
styleUrls: ['./login-magic.component.scss'],
|
||||
standalone: false
|
||||
imports: [LogoComponent, SwitchThemeComponent, NgClass, FormsModule, ReactiveFormsModule, NbFormFieldModule, NbInputModule, NbIconModule, DebounceClickDirective, NbButtonModule, SpinnerButtonDirective, NgStyle, RouterLink, SocialLinksComponent, TranslatePipe]
|
||||
})
|
||||
export class NgxLoginMagicComponent extends NbLoginComponent implements OnInit {
|
||||
public countdown: number;
|
||||
|
||||
+9
-3
@@ -1,18 +1,24 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { NavigationExtras, Router } from '@angular/router';
|
||||
import { FormBuilder, FormControl, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { NavigationExtras, Router, RouterLink } from '@angular/router';
|
||||
import { HttpStatus, IAuthResponse, IUser, IUserSigninWorkspaceResponse, IWorkspaceResponse } from '@gauzy/contracts';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { asyncScheduler, catchError, EMPTY, filter, tap } from 'rxjs';
|
||||
import { AuthService } from '../../../auth';
|
||||
import { ErrorHandlerService, Store, TimeTrackerDateManager } from '../../../services';
|
||||
import { WorkspaceSelectionComponent } from '../../shared/ui/workspace-selection/workspace-selection.component';
|
||||
import { LogoComponent } from '../../shared/ui/logo/logo.component';
|
||||
import { NgTemplateOutlet, NgStyle } from '@angular/common';
|
||||
import { NbInputModule, NbFormFieldModule, NbButtonModule, NbIconModule } from '@nebular/theme';
|
||||
import { SpinnerButtonDirective } from '../../../directives/spinner-button.directive';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-login-workspace',
|
||||
templateUrl: './login-workspace.component.html',
|
||||
styleUrls: ['./login-workspace.component.scss'],
|
||||
standalone: false
|
||||
imports: [WorkspaceSelectionComponent, LogoComponent, NgTemplateOutlet, RouterLink, FormsModule, ReactiveFormsModule, NbInputModule, NbFormFieldModule, NbButtonModule, NbIconModule, SpinnerButtonDirective, NgStyle, TranslatePipe]
|
||||
})
|
||||
export class NgxLoginWorkspaceComponent implements OnInit {
|
||||
public confirmedEmail: string;
|
||||
|
||||
+4
-1
@@ -5,13 +5,16 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { asyncScheduler, catchError, EMPTY, filter, firstValueFrom, tap } from 'rxjs';
|
||||
import { AuthService } from '../../../auth';
|
||||
import { ErrorHandlerService, Store, TimeTrackerDateManager } from '../../../services';
|
||||
import { WorkspaceSelectionComponent } from '../../shared/ui/workspace-selection/workspace-selection.component';
|
||||
import { LogoComponent } from '../../shared/ui/logo/logo.component';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-magic-sign-in-workspace',
|
||||
templateUrl: './magic-login-workspace.component.html',
|
||||
styleUrls: ['./magic-login-workspace.component.scss'],
|
||||
standalone: false
|
||||
imports: [WorkspaceSelectionComponent, LogoComponent, TranslatePipe]
|
||||
})
|
||||
export class NgxMagicSignInWorkspaceComponent implements OnInit {
|
||||
public error: boolean = false;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChangeDetectorRef, Component, Inject, OnInit, ViewChild } from '@angular/core';
|
||||
import { NgForm } from '@angular/forms';
|
||||
import { NavigationExtras, Router } from '@angular/router';
|
||||
import { NgForm, FormsModule } from '@angular/forms';
|
||||
import { NavigationExtras, Router, RouterLink } from '@angular/router';
|
||||
import { HttpStatus, IUserSigninWorkspaceResponse } from '@gauzy/contracts';
|
||||
import { NB_AUTH_OPTIONS, NbAuthService, NbLoginComponent } from '@nebular/auth';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
@@ -10,13 +10,20 @@ import { GAUZY_ENV } from '../constants';
|
||||
import { ElectronService } from '../electron/services';
|
||||
import { LanguageElectronService } from '../language/language-electron.service';
|
||||
import { ErrorHandlerService } from '../services';
|
||||
import { LogoComponent } from './shared/ui/logo/logo.component';
|
||||
import { SwitchThemeComponent } from '../theme-selector/switch-theme/switch-theme.component';
|
||||
import { NbAlertModule, NbInputModule, NbFormFieldModule, NbButtonModule, NbIconModule, NbCheckboxModule } from '@nebular/theme';
|
||||
import { SpinnerButtonDirective } from '../directives/spinner-button.directive';
|
||||
import { NgStyle } from '@angular/common';
|
||||
import { SocialLinksComponent } from './shared/ui/social-links/social-links.component';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-desktop-timer-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.scss'],
|
||||
standalone: false
|
||||
imports: [LogoComponent, SwitchThemeComponent, NbAlertModule, FormsModule, NbInputModule, NbFormFieldModule, NbButtonModule, NbIconModule, NbCheckboxModule, SpinnerButtonDirective, NgStyle, RouterLink, SocialLinksComponent, TranslatePipe]
|
||||
})
|
||||
export class NgxLoginComponent extends NbLoginComponent implements OnInit {
|
||||
@ViewChild('form')
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
NbInputModule,
|
||||
NbListModule
|
||||
} from '@nebular/theme';
|
||||
import { DesktopDirectiveModule } from '../directives/desktop-directive.module';
|
||||
|
||||
import { LanguageModule } from '../language/language.module';
|
||||
import { AvatarModule } from '../shared/components/ui/avatar/avatar.module';
|
||||
import { SwitchThemeModule } from '../theme-selector/switch-theme/switch-theme.module';
|
||||
|
||||
|
||||
import { NgxLoginMagicComponent } from './features/login-magic/login-magic.component';
|
||||
import { NgxLoginWorkspaceComponent } from './features/login-workspace/login-workspace.component';
|
||||
import { NgxMagicSignInWorkspaceComponent } from './features/magic-login-workspace/magic-login-workspace.component';
|
||||
@@ -33,26 +33,23 @@ const shared = [
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
RouterModule,
|
||||
NbAlertModule,
|
||||
NbAuthModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbCheckboxModule,
|
||||
NbIconModule,
|
||||
NbInputModule,
|
||||
NbFormFieldModule,
|
||||
DesktopDirectiveModule,
|
||||
LanguageModule.forChild(),
|
||||
ReactiveFormsModule,
|
||||
SwitchThemeModule,
|
||||
NbListModule,
|
||||
AvatarModule
|
||||
],
|
||||
declarations: [LogoComponent, SocialLinksComponent, WorkspaceSelectionComponent, ...shared],
|
||||
exports: [...shared]
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
RouterModule,
|
||||
NbAlertModule,
|
||||
NbAuthModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbCheckboxModule,
|
||||
NbIconModule,
|
||||
NbInputModule,
|
||||
NbFormFieldModule,
|
||||
LanguageModule.forChild(),
|
||||
ReactiveFormsModule,
|
||||
NbListModule,
|
||||
LogoComponent, SocialLinksComponent, WorkspaceSelectionComponent, ...shared
|
||||
],
|
||||
exports: [...shared]
|
||||
})
|
||||
export class NgxLoginModule {}
|
||||
|
||||
@@ -5,8 +5,7 @@ import { GAUZY_ENV } from '../../../../constants';
|
||||
@Component({
|
||||
selector: 'gauzy-logo',
|
||||
templateUrl: './logo.component.html',
|
||||
styleUrls: ['./logo.component.scss'],
|
||||
standalone: false
|
||||
styleUrls: ['./logo.component.scss']
|
||||
})
|
||||
export class LogoComponent {
|
||||
constructor(
|
||||
|
||||
+13
-24
@@ -3,33 +3,22 @@
|
||||
{{ 'LOGIN_PAGE.OR_SIGN_IN_WITH' | translate }}
|
||||
<div class="socials">
|
||||
@for (socialLink of socialLinks; track socialLink) { @if (socialLink.link) {
|
||||
<a
|
||||
[routerLink]="socialLink.link"
|
||||
[attr.target]="socialLink.target"
|
||||
[attr.rel]="socialLink.target === '_blank' ? 'noopener noreferrer' : null"
|
||||
class="social-link"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="linkContentEl; context: { $implicit: socialLink }"></ng-container>
|
||||
<a [routerLink]="socialLink.link" [attr.target]="socialLink.target" class="social-link">
|
||||
@if (socialLink.icon) {
|
||||
<nb-icon [icon]="socialLink.icon"></nb-icon>
|
||||
} @else {
|
||||
{{ socialLink.title }}
|
||||
}
|
||||
</a>
|
||||
} @else if (socialLink.url) {
|
||||
<a
|
||||
[attr.href]="socialLink.url"
|
||||
[attr.target]="socialLink.target"
|
||||
[attr.rel]="socialLink.target === '_blank' ? 'noopener noreferrer' : null"
|
||||
class="social-link"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="linkContentEl; context: { $implicit: socialLink }"></ng-container>
|
||||
} @if (socialLink.url) {
|
||||
<a [attr.href]="socialLink.url" [attr.target]="socialLink.target" class="social-link">
|
||||
@if (socialLink.icon) {
|
||||
<nb-icon [icon]="socialLink.icon"></nb-icon>
|
||||
} @else {
|
||||
{{ socialLink.title }}
|
||||
}
|
||||
</a>
|
||||
} }
|
||||
</div>
|
||||
</div>
|
||||
} }
|
||||
|
||||
<!-- Reusable template for social link content (icon or title) -->
|
||||
<ng-template let-socialLink #linkContentEl>
|
||||
@if (socialLink.icon) {
|
||||
<nb-icon [icon]="socialLink.icon"></nb-icon>
|
||||
} @else {
|
||||
{{ socialLink.title }}
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
+5
-1
@@ -2,6 +2,10 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { socialLinks } from '../../../../constants';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { NbIconModule } from '@nebular/theme';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
/**
|
||||
* Interface representing a social link.
|
||||
@@ -24,7 +28,7 @@ export interface ISocialLink {
|
||||
selector: 'ngx-social-links',
|
||||
templateUrl: './social-links.component.html',
|
||||
styleUrls: ['./social-links.component.scss'],
|
||||
standalone: false
|
||||
imports: [RouterLink, NbIconModule, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class SocialLinksComponent implements OnInit {
|
||||
/** */
|
||||
|
||||
+7
-1
@@ -1,11 +1,17 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { IWorkspaceResponse } from '@gauzy/contracts';
|
||||
import { LogoComponent } from '../logo/logo.component';
|
||||
import { NbCardModule, NbListModule, NbIconModule } from '@nebular/theme';
|
||||
import { DebounceClickDirective } from '../../../../directives/debounce-click.directive';
|
||||
import { AvatarComponent } from '../../../../shared/components/ui/avatar/avatar.component';
|
||||
import { SpinnerButtonDirective } from '../../../../directives/spinner-button.directive';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-workspace-selection',
|
||||
templateUrl: './workspace-selection.component.html',
|
||||
styleUrls: ['./workspace-selection.component.scss'],
|
||||
standalone: false
|
||||
imports: [LogoComponent, NbCardModule, NbListModule, DebounceClickDirective, AvatarComponent, SpinnerButtonDirective, NbIconModule, TranslatePipe]
|
||||
})
|
||||
export class WorkspaceSelectionComponent {
|
||||
selected: IWorkspaceResponse = null;
|
||||
|
||||
@@ -5,8 +5,13 @@ import { AutoRefreshService } from '../../+state/auto-refresh/auto-refresh.servi
|
||||
import { RecapQuery } from '../../+state/recap.query';
|
||||
import { RecapService } from '../../+state/recap.service';
|
||||
import { RequestQuery } from '../../+state/request/request.query';
|
||||
import { IStatisticItem } from '../../shared/ui/statistic/statistic.component';
|
||||
import { IStatisticItem, StatisticComponent } from '../../shared/ui/statistic/statistic.component';
|
||||
import { ActivityStatisticsAdapter } from '../../shared/utils/adapters/activity.adapter';
|
||||
import { NbCardModule } from '@nebular/theme';
|
||||
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { NoDataMessageComponent } from '../../../time-tracker/no-data-message/no-data-message.component';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
@@ -14,7 +19,7 @@ import { ActivityStatisticsAdapter } from '../../shared/utils/adapters/activity.
|
||||
templateUrl: './activities.component.html',
|
||||
styleUrls: ['./activities.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbCardModule, StatisticComponent, NoDataMessageComponent, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class ActivitiesComponent implements OnInit {
|
||||
constructor(
|
||||
|
||||
@@ -7,8 +7,8 @@ describe('FilterComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [FilterComponent]
|
||||
}).compileComponents();
|
||||
imports: [FilterComponent]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FilterComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
@@ -3,13 +3,17 @@ import { ITimeLogFilters } from '@gauzy/contracts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RequestQuery } from '../../+state/request/request.query';
|
||||
import { RequestStore } from '../../+state/request/request.store';
|
||||
import { NbButtonModule, NbPopoverModule, NbIconModule } from '@nebular/theme';
|
||||
import { GauzyFiltersComponent } from '../../shared/features/gauzy-filters/gauzy-filters.component';
|
||||
import { AutoRefreshComponent } from '../../shared/ui/auto-refresh/auto-refresh.component';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-filter',
|
||||
templateUrl: './filter.component.html',
|
||||
styleUrls: ['./filter.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbButtonModule, NbPopoverModule, NbIconModule, GauzyFiltersComponent, AutoRefreshComponent, AsyncPipe]
|
||||
})
|
||||
export class FilterComponent {
|
||||
constructor(private readonly store: RequestStore, private readonly query: RequestQuery) {}
|
||||
|
||||
@@ -5,8 +5,13 @@ import { AutoRefreshService } from '../../+state/auto-refresh/auto-refresh.servi
|
||||
import { RecapQuery } from '../../+state/recap.query';
|
||||
import { RecapService } from '../../+state/recap.service';
|
||||
import { RequestQuery } from '../../+state/request/request.query';
|
||||
import { IStatisticItem } from '../../shared/ui/statistic/statistic.component';
|
||||
import { IStatisticItem, StatisticComponent } from '../../shared/ui/statistic/statistic.component';
|
||||
import { ProjectStatisticsAdapter } from '../../shared/utils/adapters/project.adapter';
|
||||
import { NbCardModule } from '@nebular/theme';
|
||||
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { NoDataMessageComponent } from '../../../time-tracker/no-data-message/no-data-message.component';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
@@ -14,7 +19,7 @@ import { ProjectStatisticsAdapter } from '../../shared/utils/adapters/project.ad
|
||||
templateUrl: './projects.component.html',
|
||||
styleUrls: ['./projects.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbCardModule, StatisticComponent, NoDataMessageComponent, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class ProjectsComponent implements OnInit {
|
||||
constructor(
|
||||
|
||||
@@ -4,6 +4,12 @@ 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';
|
||||
import { NbCardModule, NbIconModule } from '@nebular/theme';
|
||||
import { SegmentedControlComponent } from '../../shared/features/segmented-control/segmented-control.component';
|
||||
import { DateRangePickerComponent } from '../../shared/features/date-range-picker/date-range-picker.component';
|
||||
import { FilterComponent } from '../filter/filter.component';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
@@ -11,7 +17,7 @@ import { IDateRangePicker } from '../../shared/features/date-range-picker/date-p
|
||||
templateUrl: './recap.component.html',
|
||||
styleUrls: ['./recap.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbCardModule, SegmentedControlComponent, NbIconModule, DateRangePickerComponent, FilterComponent, RouterOutlet, AsyncPipe]
|
||||
})
|
||||
export class RecapComponent {
|
||||
private readonly basePath = ['/', 'time-tracker', 'daily'];
|
||||
|
||||
@@ -5,8 +5,13 @@ import { AutoRefreshService } from '../../+state/auto-refresh/auto-refresh.servi
|
||||
import { RecapQuery } from '../../+state/recap.query';
|
||||
import { RecapService } from '../../+state/recap.service';
|
||||
import { RequestQuery } from '../../+state/request/request.query';
|
||||
import { IStatisticItem } from '../../shared/ui/statistic/statistic.component';
|
||||
import { IStatisticItem, StatisticComponent } from '../../shared/ui/statistic/statistic.component';
|
||||
import { TaskStatisticsAdapter } from '../../shared/utils/adapters/task.adapter';
|
||||
import { NbCardModule } from '@nebular/theme';
|
||||
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { NoDataMessageComponent } from '../../../time-tracker/no-data-message/no-data-message.component';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
@@ -14,7 +19,7 @@ import { TaskStatisticsAdapter } from '../../shared/utils/adapters/task.adapter'
|
||||
templateUrl: './tasks.component.html',
|
||||
styleUrls: ['./tasks.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbCardModule, StatisticComponent, NoDataMessageComponent, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class TasksComponent implements OnInit {
|
||||
constructor(
|
||||
|
||||
+17
-3
@@ -1,13 +1,18 @@
|
||||
import { AsyncPipe, PercentPipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ITimeSlot } from '@gauzy/contracts';
|
||||
import { progressStatus } from '@gauzy/ui-core/common';
|
||||
import { NbBadgeModule, NbCardModule } from '@nebular/theme';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject, combineLatest, concatMap, from, map } from 'rxjs';
|
||||
import { Observable } from 'rxjs';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { BarChartModule } from '@swimlane/ngx-charts';
|
||||
import { BehaviorSubject, combineLatest, concatMap, from, map, Observable } from 'rxjs';
|
||||
import { AutoRefreshService } from '../../+state/auto-refresh/auto-refresh.service';
|
||||
import { RecapQuery } from '../../+state/recap.query';
|
||||
import { RecapService } from '../../+state/recap.service';
|
||||
import { RequestQuery } from '../../+state/request/request.query';
|
||||
import { NoDataMessageComponent } from '../../../time-tracker/no-data-message/no-data-message.component';
|
||||
import { PipeModule } from '../../../time-tracker/pipes/pipe.module';
|
||||
import { IChartData } from '../../shared/utils/adapters/chart.adapter';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@@ -16,7 +21,16 @@ import { IChartData } from '../../shared/utils/adapters/chart.adapter';
|
||||
templateUrl: './time-tracking-charts.component.html',
|
||||
styleUrls: ['./time-tracking-charts.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [
|
||||
NbCardModule,
|
||||
BarChartModule,
|
||||
NbBadgeModule,
|
||||
NoDataMessageComponent,
|
||||
AsyncPipe,
|
||||
PercentPipe,
|
||||
TranslatePipe,
|
||||
PipeModule
|
||||
]
|
||||
})
|
||||
export class TimeTrackingChartsComponent implements OnInit {
|
||||
private readonly _chartData$: BehaviorSubject<IChartData[]> = new BehaviorSubject([]);
|
||||
|
||||
+3
-1
@@ -2,13 +2,15 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { map } from 'rxjs';
|
||||
import { MonthlyRecapService } from '../../+state/monthly.service';
|
||||
import { IDateRangePicker } from '../../../shared/features/date-range-picker/date-picker.interface';
|
||||
import { DateRangePickerComponent } from '../../../shared/features/date-range-picker/date-range-picker.component';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-monthly-calendar',
|
||||
templateUrl: './monthly-calendar.component.html',
|
||||
styleUrls: ['./monthly-calendar.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [DateRangePickerComponent, AsyncPipe]
|
||||
})
|
||||
export class MonthlyCalendarComponent {
|
||||
constructor(private readonly monthlyRecapService: MonthlyRecapService) {}
|
||||
|
||||
+11
-5
@@ -3,6 +3,12 @@ import { ReportDayData } from '@gauzy/contracts';
|
||||
import { map, tap } from 'rxjs';
|
||||
import { MonthlyRecapService } from '../../+state/monthly.service';
|
||||
import { updateMonthWeeks, weekDateRange } from '../../../shared/features/date-range-picker';
|
||||
import { ProgressStatusComponent } from '../../../shared/ui/progress-status/progress-status.component';
|
||||
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { NoDataMessageComponent } from '../../../../time-tracker/no-data-message/no-data-message.component';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
|
||||
export interface IMonthWeekdays {
|
||||
week: string;
|
||||
@@ -10,11 +16,11 @@ export interface IMonthWeekdays {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-monthly-progress',
|
||||
templateUrl: './monthly-progress.component.html',
|
||||
styleUrls: ['./monthly-progress.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-monthly-progress',
|
||||
templateUrl: './monthly-progress.component.html',
|
||||
styleUrls: ['./monthly-progress.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ProgressStatusComponent, NoDataMessageComponent, AsyncPipe, TranslatePipe, PipeModule]
|
||||
})
|
||||
export class MonthlyProgressComponent {
|
||||
public monthWeekdays: IMonthWeekdays[] = [];
|
||||
|
||||
+7
-1
@@ -5,6 +5,12 @@ import { MonthlyRecapService } from '../../+state/monthly.service';
|
||||
import { AutoRefreshService } from '../../../+state/auto-refresh/auto-refresh.service';
|
||||
import { RequestQuery } from '../../../+state/request/request.query';
|
||||
import { LoggerService } from '../../../../electron/services';
|
||||
import { NbCardModule, NbIconModule } from '@nebular/theme';
|
||||
import { MonthlyCalendarComponent } from '../monthly-calendar/monthly-calendar.component';
|
||||
import { FilterComponent } from '../../../features/filter/filter.component';
|
||||
import { MonthlyStatisticComponent } from '../monthly-statistic/monthly-statistic.component';
|
||||
import { MonthlyProgressComponent } from '../monthly-progress/monthly-progress.component';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
@@ -12,7 +18,7 @@ import { LoggerService } from '../../../../electron/services';
|
||||
templateUrl: './monthly-recap.component.html',
|
||||
styleUrls: ['./monthly-recap.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbCardModule, NbIconModule, MonthlyCalendarComponent, FilterComponent, MonthlyStatisticComponent, MonthlyProgressComponent, AsyncPipe]
|
||||
})
|
||||
export class MonthlyRecapComponent implements OnInit {
|
||||
public isLoading$ = new BehaviorSubject(false);
|
||||
|
||||
+9
-5
@@ -1,13 +1,17 @@
|
||||
import { AsyncPipe, PercentPipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { NbCardModule } from '@nebular/theme';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { map } from 'rxjs';
|
||||
import { MonthlyRecapService } from '../../+state/monthly.service';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-monthly-statistic',
|
||||
templateUrl: './monthly-statistic.component.html',
|
||||
styleUrls: ['./monthly-statistic.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-monthly-statistic',
|
||||
templateUrl: './monthly-statistic.component.html',
|
||||
styleUrls: ['./monthly-statistic.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [NbCardModule, AsyncPipe, PercentPipe, TranslatePipe, PipeModule]
|
||||
})
|
||||
export class MonthlyStatisticComponent {
|
||||
constructor(private readonly monthlyRecapService: MonthlyRecapService) {}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { TimeTrackingChartsComponent } from './features/time-tracking-charts/time-tracking-charts.component';
|
||||
import { ActivityReportComponent } from './shared/features/activity-report/activity-report.component';
|
||||
import { TasksComponent } from './features/tasks/tasks.component';
|
||||
import { ProjectsComponent } from './features/projects/projects.component';
|
||||
|
||||
export const recapChildRoutes: Routes = [
|
||||
{
|
||||
@@ -12,19 +8,23 @@ export const recapChildRoutes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'hourly',
|
||||
component: TimeTrackingChartsComponent
|
||||
loadComponent: () =>
|
||||
import('./features/time-tracking-charts/time-tracking-charts.component').then(
|
||||
(m) => m.TimeTrackingChartsComponent
|
||||
)
|
||||
},
|
||||
{
|
||||
path: 'activities',
|
||||
component: ActivityReportComponent
|
||||
loadComponent: () =>
|
||||
import('./shared/features/activity-report/activity-report.component').then((m) => m.ActivityReportComponent)
|
||||
},
|
||||
{
|
||||
path: 'tasks',
|
||||
component: TasksComponent
|
||||
loadComponent: () => import('./features/tasks/tasks.component').then((m) => m.TasksComponent)
|
||||
},
|
||||
{
|
||||
path: 'projects',
|
||||
component: ProjectsComponent
|
||||
loadComponent: () => import('./features/projects/projects.component').then((m) => m.ProjectsComponent)
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { RecapComponent } from './features/recap/recap.component';
|
||||
|
||||
import { recapChildRoutes } from './recap-children-routing.module';
|
||||
import { WeeklyRecapComponent } from './weekly/features/weekly-recap/weekly-recap.component';
|
||||
import { MonthlyRecapComponent } from './monthly/features/monthly-recap/monthly-recap.component';
|
||||
|
||||
export const recapRoutes: Routes = [
|
||||
{
|
||||
@@ -12,21 +10,22 @@ export const recapRoutes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'daily',
|
||||
component: RecapComponent,
|
||||
loadComponent: () => import('./features/recap/recap.component').then((m) => m.RecapComponent),
|
||||
children: recapChildRoutes
|
||||
},
|
||||
{
|
||||
path: 'weekly',
|
||||
component: WeeklyRecapComponent
|
||||
loadComponent: () =>
|
||||
import('./weekly/features/weekly-recap/weekly-recap.component').then((m) => m.WeeklyRecapComponent)
|
||||
},
|
||||
{
|
||||
path: 'monthly',
|
||||
component: MonthlyRecapComponent
|
||||
loadComponent: () =>
|
||||
import('./monthly/features/monthly-recap/monthly-recap.component').then((m) => m.MonthlyRecapComponent)
|
||||
},
|
||||
{
|
||||
path: 'tasks',
|
||||
loadChildren: () =>
|
||||
import('../time-tracker/task-table/task-table.module').then((m) => m.TaskTableModule)
|
||||
loadChildren: () => import('../time-tracker/task-table/task-table.module').then((m) => m.TaskTableModule)
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
|
||||
@@ -16,9 +16,9 @@ import {
|
||||
NbToggleModule
|
||||
} from '@nebular/theme';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
import { LanguageModule } from '../language/language.module';
|
||||
import { ToastrNotificationService } from '../services';
|
||||
import { NoDataMessageModule } from '../time-tracker/no-data-message/no-data-message.module';
|
||||
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { PipeModule } from '../time-tracker/pipes/pipe.module';
|
||||
import { AutoRefreshQuery } from './+state/auto-refresh/auto-refresh.query';
|
||||
import { AutoRefreshService } from './+state/auto-refresh/auto-refresh.service';
|
||||
@@ -28,52 +28,12 @@ import { RecapService } from './+state/recap.service';
|
||||
import { RecapStore } from './+state/recap.store';
|
||||
import { RequestQuery } from './+state/request/request.query';
|
||||
import { RequestStore } from './+state/request/request.store';
|
||||
import { ActivitiesComponent } from './features/activities/activities.component';
|
||||
import { FilterComponent } from './features/filter/filter.component';
|
||||
import { ProjectsComponent } from './features/projects/projects.component';
|
||||
import { RecapComponent } from './features/recap/recap.component';
|
||||
import { TasksComponent } from './features/tasks/tasks.component';
|
||||
import { TimeTrackingChartsComponent } from './features/time-tracking-charts/time-tracking-charts.component';
|
||||
import { MonthlyCalendarComponent } from './monthly/features/monthly-calendar/monthly-calendar.component';
|
||||
import { MonthlyProgressComponent } from './monthly/features/monthly-progress/monthly-progress.component';
|
||||
import { MonthlyRecapComponent } from './monthly/features/monthly-recap/monthly-recap.component';
|
||||
import { MonthlyStatisticComponent } from './monthly/features/monthly-statistic/monthly-statistic.component';
|
||||
import { recapRoutes } from './recap-routing.module';
|
||||
import { ActivityService, TimesheetService, TimesheetStatisticsService } from './services/timesheet';
|
||||
import { ActivityReportComponent } from './shared/features/activity-report/activity-report.component';
|
||||
import { DateRangePickerModule } from './shared/features/date-range-picker/date-range-picker.module';
|
||||
import { GauzyFiltersModule } from './shared/features/gauzy-filters';
|
||||
import { SegmentedControlComponent } from './shared/features/segmented-control/segmented-control.component';
|
||||
import { AutoRefreshComponent } from './shared/ui/auto-refresh/auto-refresh.component';
|
||||
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';
|
||||
import { recapRoutes } from './recap-routing.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
RecapComponent,
|
||||
ProjectsComponent,
|
||||
TasksComponent,
|
||||
ActivitiesComponent,
|
||||
TimeTrackingChartsComponent,
|
||||
FilterComponent,
|
||||
StatisticComponent,
|
||||
AutoRefreshComponent,
|
||||
ActivityReportComponent,
|
||||
SegmentedControlComponent,
|
||||
WeeklyRecapComponent,
|
||||
WeeklyCalendarComponent,
|
||||
WeeklyProgressComponent,
|
||||
WeeklyStatisticComponent,
|
||||
MonthlyRecapComponent,
|
||||
MonthlyCalendarComponent,
|
||||
MonthlyProgressComponent,
|
||||
MonthlyStatisticComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbLayoutModule,
|
||||
@@ -82,7 +42,6 @@ import { recapRoutes } from './recap-routing.module';
|
||||
NbProgressBarModule,
|
||||
NbIconModule,
|
||||
NbButtonModule,
|
||||
NoDataMessageModule,
|
||||
NbPopoverModule,
|
||||
NbTableModule,
|
||||
NgxChartsModule,
|
||||
@@ -92,10 +51,8 @@ import { recapRoutes } from './recap-routing.module';
|
||||
GauzyFiltersModule,
|
||||
NbBadgeModule,
|
||||
NbToggleModule,
|
||||
ProjectColumnViewModule,
|
||||
ProgressStatusModule,
|
||||
NbSpinnerModule,
|
||||
LanguageModule.forChild(),
|
||||
TranslateModule.forChild(),
|
||||
RouterModule.forChild(recapRoutes)
|
||||
],
|
||||
providers: [
|
||||
@@ -111,7 +68,6 @@ import { recapRoutes } from './recap-routing.module';
|
||||
AutoRefreshStore,
|
||||
RequestQuery,
|
||||
RequestStore
|
||||
],
|
||||
exports: [RecapComponent, WeeklyRecapComponent, MonthlyRecapComponent]
|
||||
]
|
||||
})
|
||||
export class RecapModule {}
|
||||
|
||||
+20
-5
@@ -1,19 +1,34 @@
|
||||
import { AsyncPipe, NgTemplateOutlet } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { IDailyActivity } from '@gauzy/contracts';
|
||||
import { NbCardModule, NbSpinnerModule } from '@nebular/theme';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, combineLatest, concatMap, map, Observable } from 'rxjs';
|
||||
import { AutoRefreshService } from '../../../+state/auto-refresh/auto-refresh.service';
|
||||
import { RecapQuery } from '../../../+state/recap.query';
|
||||
import { RecapService } from '../../../+state/recap.service';
|
||||
import { RequestQuery } from '../../../+state/request/request.query';
|
||||
import { NoDataMessageComponent } from '../../../../time-tracker/no-data-message/no-data-message.component';
|
||||
import { ProgressStatusComponent } from '../../ui/progress-status/progress-status.component';
|
||||
import { ProjectColumnViewComponent } from '../../ui/project-column-view/project-column-view.component';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-activity-report',
|
||||
templateUrl: './activity-report.component.html',
|
||||
styleUrls: ['./activity-report.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-activity-report',
|
||||
templateUrl: './activity-report.component.html',
|
||||
styleUrls: ['./activity-report.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
NbSpinnerModule,
|
||||
NbCardModule,
|
||||
NgTemplateOutlet,
|
||||
NoDataMessageComponent,
|
||||
ProgressStatusComponent,
|
||||
ProjectColumnViewComponent,
|
||||
AsyncPipe,
|
||||
TranslatePipe
|
||||
]
|
||||
})
|
||||
export class ActivityReportComponent implements OnInit {
|
||||
public isLoading$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
+9
-10
@@ -14,11 +14,7 @@ import { distinctUntilChange } from '@gauzy/ui-core/common';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import * as moment from 'moment-timezone';
|
||||
import {
|
||||
DaterangepickerDirective as DateRangePickerDirective,
|
||||
LocaleConfig,
|
||||
DaterangepickerComponent as NgxDateRangePickerComponent
|
||||
} from 'ngx-daterangepicker-material';
|
||||
import { DaterangepickerDirective as DateRangePickerDirective, LocaleConfig, DaterangepickerComponent as NgxDateRangePickerComponent, NgxDaterangepickerMd } from 'ngx-daterangepicker-material';
|
||||
import { BehaviorSubject, filter, Subject } from 'rxjs';
|
||||
import { debounceTime, tap } from 'rxjs/operators';
|
||||
import { RecapQuery } from '../../../+state/recap.query';
|
||||
@@ -27,14 +23,17 @@ import { Arrow } from './arrow/context/arrow.class';
|
||||
import { Next, Previous } from './arrow/strategies';
|
||||
import { DateRangeKeyEnum, DateRanges, IDateRangePicker, TimePeriod } from './date-picker.interface';
|
||||
import { dayOfWeekAsString, shiftUTCtoLocal } from './date-picker.utils';
|
||||
import { NbButtonModule, NbIconModule, NbInputModule } from '@nebular/theme';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgClass } from '@angular/common';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-date-range-picker',
|
||||
templateUrl: './date-range-picker.component.html',
|
||||
styleUrls: ['./date-range-picker.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-date-range-picker',
|
||||
templateUrl: './date-range-picker.component.html',
|
||||
styleUrls: ['./date-range-picker.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [NbButtonModule, NbIconModule, NbInputModule, NgxDaterangepickerMd, FormsModule, NgClass]
|
||||
})
|
||||
export class DateRangePickerComponent implements OnInit, OnDestroy {
|
||||
public picker: NgxDateRangePickerComponent;
|
||||
|
||||
+17
-17
@@ -13,22 +13,22 @@ import { dayOfWeekAsString } from './date-picker.utils';
|
||||
import { DateRangePickerComponent } from './date-range-picker.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [DateRangePickerComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
NbButtonModule,
|
||||
NbIconModule,
|
||||
NbInputModule,
|
||||
NgSelectModule,
|
||||
TranslateModule,
|
||||
PipeModule,
|
||||
NgxDateRangePickerMd.forRoot({
|
||||
firstDay: dayOfWeekAsString(WeekDaysEnum.MONDAY)
|
||||
})
|
||||
],
|
||||
providers: [RecapStore, RecapQuery],
|
||||
exports: [DateRangePickerComponent]
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
NbButtonModule,
|
||||
NbIconModule,
|
||||
NbInputModule,
|
||||
NgSelectModule,
|
||||
TranslateModule,
|
||||
PipeModule,
|
||||
NgxDateRangePickerMd.forRoot({
|
||||
firstDay: dayOfWeekAsString(WeekDaysEnum.MONDAY)
|
||||
}),
|
||||
DateRangePickerComponent
|
||||
],
|
||||
providers: [RecapStore, RecapQuery],
|
||||
exports: [DateRangePickerComponent]
|
||||
})
|
||||
export class DateRangePickerModule {}
|
||||
|
||||
+31
-9
@@ -1,17 +1,39 @@
|
||||
import { ChangeContext, NgxSliderModule, Options } from '@angular-slider/ngx-slider';
|
||||
import { KeyValuePipe, TitleCasePipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { ChangeContext, Options } from '@angular-slider/ngx-slider';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { tap } from 'rxjs';
|
||||
import { ITimeLogFilters, PermissionsEnum, TimeFormatEnum, TimeLogSourceEnum, TimeLogType } from '@gauzy/contracts';
|
||||
import {
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbOptionModule,
|
||||
NbPopoverModule,
|
||||
NbSelectModule
|
||||
} from '@nebular/theme';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import { tap } from 'rxjs';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-gauzy-filters',
|
||||
templateUrl: './gauzy-filters.component.html',
|
||||
styleUrls: ['./gauzy-filters.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-gauzy-filters',
|
||||
templateUrl: './gauzy-filters.component.html',
|
||||
styleUrls: ['./gauzy-filters.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
NbCardModule,
|
||||
NbButtonModule,
|
||||
NbIconModule,
|
||||
NbSelectModule,
|
||||
NbOptionModule,
|
||||
NbPopoverModule,
|
||||
NgxSliderModule,
|
||||
TitleCasePipe,
|
||||
KeyValuePipe,
|
||||
TranslatePipe,
|
||||
PipeModule
|
||||
]
|
||||
})
|
||||
export class GauzyFiltersComponent implements OnInit, OnDestroy {
|
||||
// declaration of variables
|
||||
|
||||
+15
-15
@@ -9,20 +9,20 @@ import { PipeModule } from './../../../../time-tracker/pipes/pipe.module';
|
||||
import { GauzyFiltersComponent } from './gauzy-filters.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [GauzyFiltersComponent],
|
||||
exports: [GauzyFiltersComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbPopoverModule,
|
||||
NbSelectModule,
|
||||
NgxSliderModule,
|
||||
TranslateModule,
|
||||
PipeModule
|
||||
],
|
||||
providers: [TimesheetFilterService]
|
||||
exports: [GauzyFiltersComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
NbButtonModule,
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
NbPopoverModule,
|
||||
NbSelectModule,
|
||||
NgxSliderModule,
|
||||
TranslateModule,
|
||||
PipeModule,
|
||||
GauzyFiltersComponent
|
||||
],
|
||||
providers: [TimesheetFilterService]
|
||||
})
|
||||
export class GauzyFiltersModule {}
|
||||
|
||||
+4
-1
@@ -3,13 +3,16 @@ import { Router } from '@angular/router';
|
||||
import { Observable, from } from 'rxjs';
|
||||
import { SegmentControlService } from './+state/segment-control.service';
|
||||
import { ISegmentControlState } from './+state/segment-control.store';
|
||||
import { NgClass, AsyncPipe } from '@angular/common';
|
||||
import { NbIconModule } from '@nebular/theme';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-segmented-control',
|
||||
templateUrl: './segmented-control.component.html',
|
||||
styleUrls: ['./segmented-control.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NgClass, NbIconModule, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class SegmentedControlComponent implements OnInit {
|
||||
@Input()
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ describe('AutoRefreshComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [AutoRefreshComponent]
|
||||
}).compileComponents();
|
||||
imports: [AutoRefreshComponent]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(AutoRefreshComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
+4
-1
@@ -2,6 +2,9 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AutoRefreshService } from '../../../+state/auto-refresh/auto-refresh.service';
|
||||
import { NbToggleModule, NbButtonModule, NbIconModule } from '@nebular/theme';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
@@ -9,7 +12,7 @@ import { AutoRefreshService } from '../../../+state/auto-refresh/auto-refresh.se
|
||||
templateUrl: './auto-refresh.component.html',
|
||||
styleUrls: ['./auto-refresh.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
imports: [NbToggleModule, NbButtonModule, NbIconModule, AsyncPipe, TranslatePipe]
|
||||
})
|
||||
export class AutoRefreshComponent {
|
||||
private service = inject(AutoRefreshService);
|
||||
|
||||
+3
-3
@@ -8,9 +8,9 @@ describe('ProgressStatusComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ProgressStatusComponent],
|
||||
teardown: { destroyAfterEach: false }
|
||||
}).compileComponents();
|
||||
imports: [ProgressStatusComponent],
|
||||
teardown: { destroyAfterEach: false }
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { progressStatus } from '@gauzy/ui-core/common';
|
||||
import { NbComponentOrCustomStatus } from '@nebular/theme';
|
||||
import { NbComponentOrCustomStatus, NbProgressBarModule } from '@nebular/theme';
|
||||
import { PercentPipe } from '@angular/common';
|
||||
|
||||
export interface IProgressStatusDisplayValue {
|
||||
in?: boolean;
|
||||
@@ -11,7 +12,7 @@ export interface IProgressStatusDisplayValue {
|
||||
selector: 'ngx-progress-status',
|
||||
templateUrl: './progress-status.component.html',
|
||||
styleUrls: ['./progress-status.component.scss'],
|
||||
standalone: false
|
||||
imports: [NbProgressBarModule, PercentPipe]
|
||||
})
|
||||
export class ProgressStatusComponent {
|
||||
/*
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NbProgressBarModule } from '@nebular/theme';
|
||||
import { ProgressStatusComponent } from './progress-status.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, NbProgressBarModule],
|
||||
declarations: [ProgressStatusComponent],
|
||||
exports: [ProgressStatusComponent]
|
||||
})
|
||||
export class ProgressStatusModule {}
|
||||
+1
-2
@@ -5,8 +5,7 @@ import { DEFAULT_SVG } from '@gauzy/ui-core/common';
|
||||
@Component({
|
||||
selector: 'ga-project-column-view',
|
||||
templateUrl: './project-column-view.component.html',
|
||||
styleUrls: ['./project-column-view.component.scss'],
|
||||
standalone: false
|
||||
styleUrls: ['./project-column-view.component.scss']
|
||||
})
|
||||
export class ProjectColumnViewComponent {
|
||||
fallbackSvg = DEFAULT_SVG;
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ProjectColumnViewComponent } from './project-column-view.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ProjectColumnViewComponent],
|
||||
exports: [ProjectColumnViewComponent]
|
||||
})
|
||||
export class ProjectColumnViewModule {}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { progressStatus } from '@gauzy/ui-core/common';
|
||||
import { NbListModule, NbProgressBarModule } from '@nebular/theme';
|
||||
|
||||
export interface IStatisticItem {
|
||||
imageUrl?: string;
|
||||
@@ -9,11 +10,11 @@ export interface IStatisticItem {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-statistic',
|
||||
templateUrl: './statistic.component.html',
|
||||
styleUrls: ['./statistic.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-statistic',
|
||||
templateUrl: './statistic.component.html',
|
||||
styleUrls: ['./statistic.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [NbListModule, NbProgressBarModule]
|
||||
})
|
||||
export class StatisticComponent {
|
||||
private _items: IStatisticItem[] = [];
|
||||
|
||||
+8
-5
@@ -1,14 +1,17 @@
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { map } from 'rxjs';
|
||||
import { WeeklyRecapService } from '../../+state/weekly.service';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
import { IDateRangePicker } from '../../../shared/features/date-range-picker/date-picker.interface';
|
||||
import { DateRangePickerComponent } from '../../../shared/features/date-range-picker/date-range-picker.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-weekly-calendar',
|
||||
templateUrl: './weekly-calendar.component.html',
|
||||
styleUrls: ['./weekly-calendar.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-weekly-calendar',
|
||||
templateUrl: './weekly-calendar.component.html',
|
||||
styleUrls: ['./weekly-calendar.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [DateRangePickerComponent, AsyncPipe, PipeModule]
|
||||
})
|
||||
export class WeeklyCalendarComponent {
|
||||
constructor(private readonly weeklyRecapService: WeeklyRecapService) {}
|
||||
|
||||
+11
-5
@@ -2,13 +2,19 @@ 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';
|
||||
import { ProgressStatusComponent } from '../../../shared/ui/progress-status/progress-status.component';
|
||||
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { NoDataMessageComponent } from '../../../../time-tracker/no-data-message/no-data-message.component';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-weekly-progress',
|
||||
templateUrl: './weekly-progress.component.html',
|
||||
styleUrls: ['./weekly-progress.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-weekly-progress',
|
||||
templateUrl: './weekly-progress.component.html',
|
||||
styleUrls: ['./weekly-progress.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ProgressStatusComponent, NoDataMessageComponent, AsyncPipe, TranslatePipe, PipeModule]
|
||||
})
|
||||
export class WeeklyProgressComponent {
|
||||
public weekDays: string[] = [];
|
||||
|
||||
+28
-9
@@ -1,18 +1,34 @@
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { NbCardModule, NbIconModule } from '@nebular/theme';
|
||||
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';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
import { FilterComponent } from '../../../features/filter/filter.component';
|
||||
import { WeeklyCalendarComponent } from '../weekly-calendar/weekly-calendar.component';
|
||||
import { WeeklyProgressComponent } from '../weekly-progress/weekly-progress.component';
|
||||
import { WeeklyStatisticComponent } from '../weekly-statistic/weekly-statistic.component';
|
||||
|
||||
@UntilDestroy({ checkProperties: true })
|
||||
@Component({
|
||||
selector: 'ngx-weekly-recap',
|
||||
templateUrl: './weekly-recap.component.html',
|
||||
styleUrls: ['./weekly-recap.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-weekly-recap',
|
||||
templateUrl: './weekly-recap.component.html',
|
||||
styleUrls: ['./weekly-recap.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
NbCardModule,
|
||||
NbIconModule,
|
||||
WeeklyCalendarComponent,
|
||||
FilterComponent,
|
||||
WeeklyStatisticComponent,
|
||||
WeeklyProgressComponent,
|
||||
AsyncPipe,
|
||||
PipeModule
|
||||
]
|
||||
})
|
||||
export class WeeklyRecapComponent implements OnInit {
|
||||
public isLoading$ = new BehaviorSubject(false);
|
||||
@@ -35,11 +51,14 @@ export class WeeklyRecapComponent implements OnInit {
|
||||
public async load(): Promise<void> {
|
||||
try {
|
||||
this.isLoading$.next(true);
|
||||
await Promise.allSettled([this.weeklyRecapService.getCounts(), this.weeklyRecapService.getWeeklyActivities()]);
|
||||
await Promise.allSettled([
|
||||
this.weeklyRecapService.getCounts(),
|
||||
this.weeklyRecapService.getWeeklyActivities()
|
||||
]);
|
||||
} catch (error) {
|
||||
this.logger.error(error)
|
||||
}finally {
|
||||
this.isLoading$.next(false)
|
||||
this.logger.error(error);
|
||||
} finally {
|
||||
this.isLoading$.next(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-5
@@ -1,13 +1,17 @@
|
||||
import { AsyncPipe, PercentPipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { NbCardModule } from '@nebular/theme';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { map } from 'rxjs';
|
||||
import { WeeklyRecapService } from '../../+state/weekly.service';
|
||||
import { PipeModule } from '../../../../time-tracker/pipes/pipe.module';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-weekly-statistic',
|
||||
templateUrl: './weekly-statistic.component.html',
|
||||
styleUrls: ['./weekly-statistic.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false
|
||||
selector: 'ngx-weekly-statistic',
|
||||
templateUrl: './weekly-statistic.component.html',
|
||||
styleUrls: ['./weekly-statistic.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [NbCardModule, AsyncPipe, PercentPipe, TranslatePipe, PipeModule]
|
||||
})
|
||||
export class WeeklyStatisticComponent {
|
||||
constructor(private readonly weeklyRecapService: WeeklyRecapService) {}
|
||||
|
||||
@@ -8,8 +8,8 @@ describe('ScreenCaptureComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ScreenCaptureComponent]
|
||||
}).compileComponents();
|
||||
imports: [ScreenCaptureComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user