diff --git a/dist.zip b/dist.zip deleted file mode 100644 index ccf80b20..00000000 Binary files a/dist.zip and /dev/null differ diff --git a/src/app/adf-admins/df-manage-admins/df-manage-admins.component.html b/src/app/adf-admins/df-manage-admins/df-manage-admins.component.html index 434775b2..1a671e56 100644 --- a/src/app/adf-admins/df-manage-admins/df-manage-admins.component.html +++ b/src/app/adf-admins/df-manage-admins/df-manage-admins.component.html @@ -7,6 +7,8 @@ (change)="uploadAdminList($event)" style="display: none" /> - diff --git a/src/app/adf-api-docs/df-api-docs/df-api-docs.component.ts b/src/app/adf-api-docs/df-api-docs/df-api-docs.component.ts index 54073781..f9ebe5e8 100644 --- a/src/app/adf-api-docs/df-api-docs/df-api-docs.component.ts +++ b/src/app/adf-api-docs/df-api-docs/df-api-docs.component.ts @@ -14,6 +14,8 @@ import { UntilDestroy } from '@ngneat/until-destroy'; import { DfUserDataService } from 'src/app/shared/services/df-user-data.service'; import { SESSION_TOKEN_HEADER } from 'src/app/shared/constants/http-headers'; import { mapCamelToSnake } from 'src/app/shared/utilities/case'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; +import { AsyncPipe } from '@angular/common'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -21,7 +23,7 @@ import { mapCamelToSnake } from 'src/app/shared/utilities/case'; templateUrl: './df-api-docs.component.html', styleUrls: ['./df-api-docs.component.scss'], standalone: true, - imports: [MatButtonModule, TranslocoModule], + imports: [MatButtonModule, TranslocoModule, AsyncPipe], }) export class DfApiDocsComponent implements OnInit, AfterContentInit { @ViewChild('apiDocumentation', { static: true }) apiDocElement: @@ -33,17 +35,17 @@ export class DfApiDocsComponent implements OnInit, AfterContentInit { constructor( private activatedRoute: ActivatedRoute, private router: Router, - private userDataService: DfUserDataService + private userDataService: DfUserDataService, + private themeService: DfThemeService ) {} - + isDarkMode = this.themeService.darkMode$; ngOnInit(): void { this.activatedRoute.data.subscribe(({ data }) => { if (data) { - this.apiDocJson = mapCamelToSnake(data); + this.apiDocJson = { ...data, paths: mapCamelToSnake(data.paths) }; } }); } - ngAfterContentInit(): void { const apiDocumentation = this.apiDocJson; SwaggerUI({ diff --git a/src/app/adf-apps/df-app-details/df-app-details.component.html b/src/app/adf-apps/df-app-details/df-app-details.component.html index 8d734272..2cad7acd 100644 --- a/src/app/adf-apps/df-app-details/df-app-details.component.html +++ b/src/app/adf-apps/df-app-details/df-app-details.component.html @@ -1,271 +1,307 @@ - - {{ alertMsg }} - -
- - - {{ 'apps.createApp.applicationName.label' | transloco }} - - - - - {{ 'apps.createApp.applicationName.error' | transloco }} - - - - {{ 'apps.createApp.defaultRole.label' | transloco }} - - - - - {{ role.name }} - - - - - {{ 'apps.createApp.description.label' | transloco }} - - - - {{ - 'apps.createApp.active' | transloco - }} - - - - {{ - 'apps.createApp.apiKey.label' | transloco - }} - - - {{ editApp.apiKey }} - - - - - - - -
-

- {{ 'apps.createApp.appLocation.label' | transloco - }} -

- - {{ - 'apps.createApp.appLocation.options.noStorage' | transloco - }} - {{ - 'apps.createApp.appLocation.options.fileStorage.label' | transloco - }} - {{ - 'apps.createApp.appLocation.options.webServer.label' | transloco - }} - {{ - 'apps.createApp.appLocation.options.remoteUrl.label' | transloco - }} - -
- -
- - {{ - 'apps.createApp.appLocation.options.fileStorage.storageService.label' - | transloco - }} - - - {{ - 'apps.createApp.appLocation.options.fileStorage.storageService.options.file' - | transloco - }} - - - {{ - 'apps.createApp.appLocation.options.fileStorage.storageService.options.log' - | transloco - }} - - - - - - {{ - 'apps.createApp.appLocation.options.fileStorage.storageFolder.label' - | transloco - }} +
+ + {{ alertMsg }} + + + + + {{ 'apps.createApp.applicationName.label' | transloco }} + + placeholder="{{ 'apps.createApp.applicationName.label' | transloco }}" + formControlName="name" + required /> + [matTooltip]="'apps.createApp.applicationName.tooltip' | transloco" /> + + {{ 'apps.createApp.applicationName.error' | transloco }} + - - - {{ - 'apps.createApp.appLocation.options.fileStorage.launchPath.label' - | transloco - }} - - - {{ - 'apps.createApp.appLocation.options.webServer.pathToApp.label' - | transloco - }} - + subscriptSizing="dynamic" + appearance="outline" + class="dynamic-width"> + {{ + 'apps.createApp.defaultRole.label' | transloco + }} + formControlName="defaultRole" + [matAutocomplete]="auto" + (input)="filter()" + (focus)="filter()" /> + [matTooltip]="'apps.createApp.defaultRole.tooltip' | transloco" /> + + + {{ role.name }} + + - - - {{ 'apps.createApp.appLocation.options.remoteUrl.label' | transloco }} - - + {{ + 'apps.createApp.description.label' | transloco + }} + + [matTooltip]="'apps.createApp.description.tooltip' | transloco" /> - + {{ 'apps.createApp.active' | transloco }} + + *ngIf="editApp" + class="full-width api-card" + [style]="{ 'word-break': 'break-all' }"> {{ - 'apps.createApp.appLocation.options.urlPath.label' | transloco + 'apps.createApp.apiKey.label' | transloco }} - {{ getAppLocationUrl() }} + {{ editApp.apiKey }} - + -
- -
- - -
- + +
+

+ {{ 'apps.createApp.appLocation.label' | transloco + }} +

+ + {{ + 'apps.createApp.appLocation.options.noStorage' | transloco + }} + {{ + 'apps.createApp.appLocation.options.fileStorage.label' | transloco + }} + {{ + 'apps.createApp.appLocation.options.webServer.label' | transloco + }} + {{ + 'apps.createApp.appLocation.options.remoteUrl.label' | transloco + }} + +
+ +
+ + {{ + 'apps.createApp.appLocation.options.fileStorage.storageService.label' + | transloco + }} + + + {{ + 'apps.createApp.appLocation.options.fileStorage.storageService.options.file' + | transloco + }} + + + {{ + 'apps.createApp.appLocation.options.fileStorage.storageService.options.log' + | transloco + }} + + + + + + {{ + 'apps.createApp.appLocation.options.fileStorage.storageFolder.label' + | transloco + }} + + + + + + + {{ + 'apps.createApp.appLocation.options.fileStorage.launchPath.label' + | transloco + }} + + + {{ + 'apps.createApp.appLocation.options.webServer.pathToApp.label' + | transloco + }} + + + + + + + {{ 'apps.createApp.appLocation.options.remoteUrl.label' | transloco }} + + + + + + + + {{ + 'apps.createApp.appLocation.options.urlPath.label' | transloco + }} + + + {{ getAppLocationUrl() }} + + + + + +
+ +
+ + +
+ +
diff --git a/src/app/adf-apps/df-app-details/df-app-details.component.scss b/src/app/adf-apps/df-app-details/df-app-details.component.scss index aa1a659f..fc684160 100644 --- a/src/app/adf-apps/df-app-details/df-app-details.component.scss +++ b/src/app/adf-apps/df-app-details/df-app-details.component.scss @@ -1,3 +1,15 @@ +@use '@angular/material' as mat; +@use 'src/theme' as theme; +$df-purple-palette: mat.define-palette(theme.$df-purple-palette); + mat-card { word-wrap: break-word; } +.api-card, +.location-card { + background-color: mat.get-color-from-palette($df-purple-palette, 100); +} +.action-bar { + display: flex; + justify-content: flex-end; +} diff --git a/src/app/adf-apps/df-app-details/df-app-details.component.ts b/src/app/adf-apps/df-app-details/df-app-details.component.ts index 9ac447f6..b23e2f77 100644 --- a/src/app/adf-apps/df-app-details/df-app-details.component.ts +++ b/src/app/adf-apps/df-app-details/df-app-details.component.ts @@ -24,7 +24,7 @@ import { MatCardModule } from '@angular/material/card'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatOptionModule } from '@angular/material/core'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { NgIf, NgFor } from '@angular/common'; +import { NgIf, NgFor, AsyncPipe } from '@angular/common'; import { MatInputModule } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import { @@ -41,7 +41,7 @@ import { catchError, throwError } from 'rxjs'; import { AlertType } from 'src/app/shared/components/df-alert/df-alert.component'; import { DfAlertComponent } from 'src/app/shared/components/df-alert/df-alert.component'; import { RoleType } from 'src/app/shared/types/role'; - +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; @UntilDestroy({ checkProperties: true }) @Component({ selector: 'df-app-details', @@ -65,6 +65,7 @@ import { RoleType } from 'src/app/shared/types/role'; TranslocoPipe, MatTooltipModule, DfAlertComponent, + AsyncPipe, ], }) export class DfAppDetailsComponent implements OnInit { @@ -87,7 +88,8 @@ export class DfAppDetailsComponent implements OnInit { private appsService: DfBaseCrudService, private systemConfigDataService: DfSystemConfigDataService, private activatedRoute: ActivatedRoute, - private router: Router + private router: Router, + private themeService: DfThemeService ) { this.urlOrigin = window.location.origin; @@ -103,7 +105,7 @@ export class DfAppDetailsComponent implements OnInit { url: [''], // type 2 }); } - + isDarkMode = this.themeService.darkMode$; ngOnInit(): void { this.activatedRoute.data.subscribe(({ roles, appData }) => { this.roles = roles.resource || []; diff --git a/src/app/adf-config/df-cache/df-cache-table.component.ts b/src/app/adf-config/df-cache/df-cache-table.component.ts index fe49d22d..84d1c415 100644 --- a/src/app/adf-config/df-cache/df-cache-table.component.ts +++ b/src/app/adf-config/df-cache/df-cache-table.component.ts @@ -27,7 +27,7 @@ import { Actions } from 'src/app/shared/types/table'; export class DfCacheTableComponent extends DfManageTableComponent { constructor( @Inject(CACHE_SERVICE_TOKEN) - private cacheService: DfBaseCrudService, + cacheService: DfBaseCrudService, router: Router, activatedRoute: ActivatedRoute, liveAnnouncer: LiveAnnouncer, diff --git a/src/app/adf-config/df-cache/df-cache.component.html b/src/app/adf-config/df-cache/df-cache.component.html index 2454499b..877468d7 100644 --- a/src/app/adf-config/df-cache/df-cache.component.html +++ b/src/app/adf-config/df-cache/df-cache.component.html @@ -6,7 +6,7 @@ - diff --git a/src/app/adf-config/df-cors/df-cors-config-details.component.ts b/src/app/adf-config/df-cors/df-cors-config-details.component.ts index a6c68dbe..321d6fb7 100644 --- a/src/app/adf-config/df-cors/df-cors-config-details.component.ts +++ b/src/app/adf-config/df-cors/df-cors-config-details.component.ts @@ -30,6 +30,8 @@ import { GenericUpdateResponse, } from 'src/app/shared/types/generic-http'; import { catchError, throwError } from 'rxjs'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; +import { AsyncPipe } from '@angular/common'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -52,6 +54,7 @@ import { catchError, throwError } from 'rxjs'; TranslocoPipe, DfVerbPickerComponent, DfAlertComponent, + AsyncPipe, ], }) export class DfCorsConfigDetailsComponent implements OnInit { @@ -68,7 +71,8 @@ export class DfCorsConfigDetailsComponent implements OnInit { private corsConfigService: DfBaseCrudService, private router: Router, private activatedRoute: ActivatedRoute, - private formBuilder: FormBuilder + private formBuilder: FormBuilder, + private themeService: DfThemeService ) { this.corsForm = this.formBuilder.group({ path: ['', Validators.required], @@ -82,6 +86,7 @@ export class DfCorsConfigDetailsComponent implements OnInit { enabled: [true], }); } + isDarkMode = this.themeService.darkMode$; ngOnInit(): void { this.activatedRoute.data.subscribe(data => { diff --git a/src/app/adf-config/df-email-template-details/df-email-template-details.component.html b/src/app/adf-config/df-email-template-details/df-email-template-details.component.html index 073fe00c..6f9a3762 100644 --- a/src/app/adf-config/df-email-template-details/df-email-template-details.component.html +++ b/src/app/adf-config/df-email-template-details/df-email-template-details.component.html @@ -6,12 +6,13 @@ + + + +
+

+ {{ 'scheduler.logs.statusCode' | transloco }}: + {{ scheduleToEdit?.taskLogByTaskId?.statusCode }} +

+ +
- -
- -
-

- {{ 'scheduler.logs.statusCode' | transloco }}: - {{ scheduleToEdit?.taskLogByTaskId?.statusCode }} -

- - -
-
- + + + diff --git a/src/app/adf-scheduler/df-scheduler-details/df-scheduler-details.component.ts b/src/app/adf-scheduler/df-scheduler-details/df-scheduler-details.component.ts index 4cf759ce..d0cb4684 100644 --- a/src/app/adf-scheduler/df-scheduler-details/df-scheduler-details.component.ts +++ b/src/app/adf-scheduler/df-scheduler-details/df-scheduler-details.component.ts @@ -30,6 +30,8 @@ import { AlertType, DfAlertComponent, } from 'src/app/shared/components/df-alert/df-alert.component'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; + import { catchError, throwError } from 'rxjs'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -75,9 +77,12 @@ export class DfSchedulerDetailsComponent implements OnInit { private activatedRoute: ActivatedRoute, private router: Router, @Inject(BASE_SERVICE_TOKEN) - private accessListService: DfBaseCrudService + private accessListService: DfBaseCrudService, + private themeService: DfThemeService ) {} + isDarkMode = this.themeService.darkMode$; + ngOnInit(): void { this.formGroup = this.formBuilder.group({ name: ['', Validators.required], diff --git a/src/app/adf-schema/df-field-details/df-field-details.component.html b/src/app/adf-schema/df-field-details/df-field-details.component.html index e0342193..0cef71d1 100644 --- a/src/app/adf-schema/df-field-details/df-field-details.component.html +++ b/src/app/adf-schema/df-field-details/df-field-details.component.html @@ -1,9 +1,13 @@
- + {{ 'schema.fieldDetailsForm.controls.name' | transloco }} @@ -15,7 +19,10 @@
- + {{ 'schema.fieldDetailsForm.controls.alias.label' | transloco }} @@ -28,7 +35,10 @@ 'schema.fieldDetailsForm.controls.alias.tooltip' | transloco " /> - + {{ 'schema.fieldDetailsForm.controls.label.label' | transloco }} @@ -42,7 +52,10 @@ " /> - + {{ 'schema.fieldDetailsForm.controls.type.label' | transloco }} @@ -61,7 +74,10 @@ 'schema.fieldDetailsForm.controls.type.tooltip' | transloco " /> - + {{ 'schema.fieldDetailsForm.controls.databaseType.label' | transloco }} @@ -74,63 +90,128 @@ 'schema.fieldDetailsForm.controls.databaseType.tooltip' | transloco " /> - + {{ 'schema.fieldDetailsForm.controls.length' | transloco }} - + {{ 'schema.fieldDetailsForm.controls.precision' | transloco }} - + {{ 'schema.fieldDetailsForm.controls.scale' | transloco }} - + {{ 'schema.fieldDetailsForm.controls.defaultValue' | transloco }} - {{ - 'schema.fieldDetailsForm.controls.isVirtual' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.isAggregate' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.fixedLength' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.supportsMultibyte' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.allowNull' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.autoIncrement' | transloco - }} + {{ + 'schema.fieldDetailsForm.controls.isVirtual' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.isAggregate' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.fixedLength' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.supportsMultibyte' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.allowNull' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.autoIncrement' | transloco + }} - {{ - 'schema.fieldDetailsForm.controls.isIndex' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.isUnique' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.isPrimaryKey' | transloco - }} - {{ - 'schema.fieldDetailsForm.controls.isForeignKey' | transloco - }} + {{ + 'schema.fieldDetailsForm.controls.isIndex' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.isUnique' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.isPrimaryKey' | transloco + }} + {{ + 'schema.fieldDetailsForm.controls.isForeignKey' | transloco + }} - + {{ 'schema.fieldDetailsForm.controls.refTable' | transloco }} @@ -142,7 +223,10 @@ - + {{ 'schema.fieldDetailsForm.controls.refField' | transloco }} @@ -154,7 +238,10 @@ > - + {{ 'schema.fieldDetailsForm.controls.validation.label' | transloco }} @@ -181,7 +268,10 @@ formArrayName="dbFunction" class="full-width"> + > {{ 'schema.fieldDetailsForm.controls.picklist' | transloco }} @@ -193,8 +283,14 @@
- - +
diff --git a/src/app/adf-schema/df-field-details/df-field-details.component.ts b/src/app/adf-schema/df-field-details/df-field-details.component.ts index 197319b4..287f3e1f 100644 --- a/src/app/adf-schema/df-field-details/df-field-details.component.ts +++ b/src/app/adf-schema/df-field-details/df-field-details.component.ts @@ -26,6 +26,7 @@ import { DatabaseSchemaFieldType } from './df-field-details.types'; import { CsvValidator } from '../validators/csv.validator'; import { faCircleInfo } from '@fortawesome/free-solid-svg-icons'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; @Component({ selector: 'df-field-details', @@ -95,7 +96,8 @@ export class DfFieldDetailsComponent implements OnInit { private service: DfBaseCrudService, private formBuilder: FormBuilder, private activatedRoute: ActivatedRoute, - private router: Router + private router: Router, + private themeService: DfThemeService ) { this.fieldDetailsForm = this.formBuilder.group({ name: ['', Validators.required], @@ -125,6 +127,8 @@ export class DfFieldDetailsComponent implements OnInit { }); } + isDarkMode = this.themeService.darkMode$; + ngOnInit(): void { this.activatedRoute.data.subscribe(data => { this.type = data['type']; diff --git a/src/app/adf-schema/df-manage-tables-table/df-manage-tables-table.component.ts b/src/app/adf-schema/df-manage-tables-table/df-manage-tables-table.component.ts index 08ba6e71..f109e6d4 100644 --- a/src/app/adf-schema/df-manage-tables-table/df-manage-tables-table.component.ts +++ b/src/app/adf-schema/df-manage-tables-table/df-manage-tables-table.component.ts @@ -66,12 +66,17 @@ export class DfManageTablesTableComponent extends DfManageTableComponent - - - - - {{ 'schema.tableName' | transloco }} - - - - {{ 'schema.alerts.tableNameError' | transloco }} - - +
+ + + + + + {{ 'schema.tableName' | transloco }} + + + + {{ 'schema.alerts.tableNameError' | transloco }} + + - - - {{ 'schema.alias' | transloco }} - - - - - - {{ 'schema.label' | transloco }} - - - - - {{ 'schema.plural' | transloco }} - - - - {{ 'schema.description' | transloco }} - - + + + {{ 'schema.alias' | transloco }} + + + + + + {{ 'schema.label' | transloco }} + + + + + {{ 'schema.plural' | transloco }} + + + + {{ 'schema.description' | transloco }} + + -
-

{{ 'schema.fields' | transloco }}

- -
+
+

{{ 'schema.fields' | transloco }}

+ +
-
-

{{ 'schema.relationships.heading' | transloco }}

- -
+
+

{{ 'schema.relationships.heading' | transloco }}

+ +
+
+ + +
+ +
+ +
- -
- -
- - -
- - -
-
-
+ + +
diff --git a/src/app/adf-schema/df-table-details/df-table-details.component.ts b/src/app/adf-schema/df-table-details/df-table-details.component.ts index b0676ef1..df09dcf0 100644 --- a/src/app/adf-schema/df-table-details/df-table-details.component.ts +++ b/src/app/adf-schema/df-table-details/df-table-details.component.ts @@ -23,6 +23,8 @@ import { UntilDestroy } from '@ngneat/until-destroy'; import { AceEditorMode } from 'src/app/shared/types/scripts'; import { GenericListResponse } from 'src/app/shared/types/generic-http'; import { TableDetailsType } from './df-table-details.types'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; + @UntilDestroy({ checkProperties: true }) @Component({ selector: 'df-table-details', @@ -59,7 +61,8 @@ export class DfTableDetailsComponent implements OnInit { private fb: FormBuilder, private activatedRoute: ActivatedRoute, public breakpointService: DfBreakpointService, - private router: Router + private router: Router, + private themeService: DfThemeService ) { this.tableDetailsForm = this.fb.group({ name: ['', Validators.required], @@ -69,6 +72,7 @@ export class DfTableDetailsComponent implements OnInit { description: [null], }); } + isDarkMode = this.themeService.darkMode$; ngOnInit(): void { this.activatedRoute.data.subscribe(data => { diff --git a/src/app/adf-services/df-manage-services/df-manage-services-table.component.ts b/src/app/adf-services/df-manage-services/df-manage-services-table.component.ts index 4a578c17..c30065cd 100644 --- a/src/app/adf-services/df-manage-services/df-manage-services-table.component.ts +++ b/src/app/adf-services/df-manage-services/df-manage-services-table.component.ts @@ -110,7 +110,8 @@ export class DfManageServicesTableComponent extends DfManageTableComponent>({ limit, offset, filter, + refresh, }) .subscribe(data => { this.dataSource.data = this.mapDataToTable(data.resource); diff --git a/src/app/adf-services/df-service-details/df-service-details.component.html b/src/app/adf-services/df-service-details/df-service-details.component.html index d8e1032a..72800520 100644 --- a/src/app/adf-services/df-service-details/df-service-details.component.html +++ b/src/app/adf-services/df-service-details/df-service-details.component.html @@ -1,4 +1,8 @@ -
+ @@ -64,7 +68,9 @@

class="card-icon" [src]="getBackgroundImage(type.name)" [alt]="type.label" /> -

{{ type.label }}

+

+ {{ type.label }} +

@@ -84,7 +90,9 @@

{{ type.label }}

class="card-icon" [src]="getBackgroundImage(type.name)" [alt]="type.label" /> -

{{ type.label }}

+

+ {{ type.label }} +

@@ -164,6 +172,7 @@

{{ type.label }}

{{ 'active' | transloco }}{{ type.label }}
- -
@@ -300,7 +313,7 @@

{{ type.label }}

{{ 'services.controls.label.label' | transloco }} @@ -327,17 +340,50 @@

{{ type.label }}

{{ 'active' | transloco }}{{ 'active' | transloco }} {{ 'services.options' | transloco }} + >{{ 'services.options' | transloco }}s
+ + + JSON + YAML + + + Service Definition + + + + + + {{ type.label }} 'file_certificate' ].includes(item.type) " + color="primary" [schema]="item" [formControl]="getConfigControl(item.name)" [class.dynamic-width]="item.type !== 'file_certificate'" @@ -385,10 +432,14 @@

{{ type.label }}

- -
diff --git a/src/app/adf-services/df-service-details/df-service-details.component.scss b/src/app/adf-services/df-service-details/df-service-details.component.scss index aa697ac7..6b1b750b 100644 --- a/src/app/adf-services/df-service-details/df-service-details.component.scss +++ b/src/app/adf-services/df-service-details/df-service-details.component.scss @@ -1,3 +1,7 @@ +@use '@angular/material' as mat; +@use 'src/theme' as theme; +$df-purple-palette: mat.define-palette(theme.$df-purple-palette); + .grid-wrapper { display: flex; flex-wrap: wrap; @@ -80,11 +84,15 @@ label.radio-card { .card-content { width: 100%; + text-align: center; img { margin-bottom: 10px; width: 100%; height: 110px; } + h4 { + color: #000; + } } } @@ -112,3 +120,34 @@ mat-icon { right: -55px; color: red; } + +.action-bar { + display: flex; + justify-content: flex-end; +} + +::ng-deep .mat-expansion-panel-header > .mat-expansion-indicator::after { + color: unset !important; +} +::ng-deep .mat-mdc-select-arrow { + color: unset !important; +} + +.dark-theme { + label.radio-card { + .card-content-wrapper { + background: #000; + border: 1px solid #fff; + } + + .check-icon { + border: solid 2px #2d2d2d; + } + + .card-content { + h4 { + color: #fff; + } + } + } +} diff --git a/src/app/adf-services/df-service-details/df-service-details.component.ts b/src/app/adf-services/df-service-details/df-service-details.component.ts index b6e3b073..ad09f635 100644 --- a/src/app/adf-services/df-service-details/df-service-details.component.ts +++ b/src/app/adf-services/df-service-details/df-service-details.component.ts @@ -39,7 +39,7 @@ import { Service } from 'src/app/shared/types/files'; import { AceEditorMode } from 'src/app/shared/types/scripts'; import { DfScriptEditorComponent } from 'src/app/shared/components/df-script-editor/df-script-editor.component'; import { DfSystemConfigDataService } from 'src/app/shared/services/df-system-config-data.service'; -import { forkJoin, map, switchMap } from 'rxjs'; +import { map, switchMap } from 'rxjs'; import { GOLD_SERVICES, SILVER_SERVICES, @@ -49,6 +49,8 @@ import { CommonModule } from '@angular/common'; import { MatIconModule } from '@angular/material/icon'; import { HttpClient } from '@angular/common/http'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -80,11 +82,13 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog'; MatStepperModule, CommonModule, MatIconModule, + MatButtonToggleModule, ], }) export class DfServiceDetailsComponent implements OnInit { edit = false; isDatabase = false; + isNetworkService = false; serviceTypes: Array; notIncludedServices: Array; serviceForm: FormGroup; @@ -93,6 +97,8 @@ export class DfServiceDetailsComponent implements OnInit { configSchema: Array; images: Array; search = ''; + serviceDefinition: string; + serviceDefinitionType: string; systemEvents: Array<{ label: string; value: string }>; @@ -104,7 +110,8 @@ export class DfServiceDetailsComponent implements OnInit { private router: Router, private systemConfigDataService: DfSystemConfigDataService, private http: HttpClient, - public dialog: MatDialog + public dialog: MatDialog, + private themeService: DfThemeService ) { this.serviceForm = this.fb.group({ type: ['', Validators.required], @@ -112,13 +119,17 @@ export class DfServiceDetailsComponent implements OnInit { label: [''], description: [''], isActive: [true], + service_doc_by_service_id: this.fb.group({ + format: [], + content: [''], + }), }); const id = this.activatedRoute.snapshot.paramMap.get('id'); if (id) { this.edit = true; } } - + isDarkMode = this.themeService.darkMode$; ngOnInit(): void { this.http .get>('assets/img/databaseImages.json') @@ -135,6 +146,12 @@ export class DfServiceDetailsComponent implements OnInit { if (route['groups'] && route['groups'][0] === 'Database') { this.isDatabase = true; } + if ( + (route['groups'] && route['groups'][0] === 'Remote Service') || + (route['groups'] && route['groups'][0] === 'Script') + ) { + this.isNetworkService = true; + } const { data, serviceTypes, groups } = route; const licenseType = env.platform?.license; this.serviceTypes = serviceTypes; @@ -181,7 +198,8 @@ export class DfServiceDetailsComponent implements OnInit { ...data, config: data.config, }); - this.serviceForm.controls['type'].disable(); + (this.serviceDefinition = data?.serviceDocByServiceId.content), + this.serviceForm.controls['type'].disable(); } else { this.serviceForm.controls['type'].valueChanges.subscribe(value => { this.serviceForm.removeControl('config'); @@ -190,11 +208,13 @@ export class DfServiceDetailsComponent implements OnInit { }); } }); - this.serviceForm.controls['type'].valueChanges.subscribe(value => { - this.serviceForm.patchValue({ - label: value, + if (this.isDatabase) { + this.serviceForm.controls['type'].valueChanges.subscribe(value => { + this.serviceForm.patchValue({ + label: value, + }); }); - }); + } } initializeConfig() { @@ -205,12 +225,12 @@ export class DfServiceDetailsComponent implements OnInit { if (control.required) { validator.push(Validators.required); } - config.addControl( + config?.addControl( control.name, new FormControl(control.default, validator) ); }); - this.serviceForm.addControl('config', config); + this.serviceForm?.addControl('config', config); } } @@ -264,6 +284,28 @@ export class DfServiceDetailsComponent implements OnInit { return; } const data = this.serviceForm.getRawValue(); + data.service_doc_by_service_id.content = this.serviceDefinition; + data.service_doc_by_service_id.format = Number(this.serviceDefinitionType); + type Params = { + snackbarError: string; + snackbarSuccess: string; + fields?: string; + related?: string; + }; + + let params: Params = { + snackbarError: 'server', + snackbarSuccess: 'services.createSuccessMsg', + }; + + if (this.isNetworkService) { + params = { + ...params, + fields: '*', + related: 'service_doc_by_service_id', + }; + } + if (this.edit) { this.servicesService .update(this.serviceData.id, data, { @@ -276,11 +318,10 @@ export class DfServiceDetailsComponent implements OnInit { } else { this.servicesService .create( - { resource: [data] }, { - snackbarError: 'server', - snackbarSuccess: 'services.createSuccessMsg', - } + resource: [data], + }, + params ) .subscribe(() => { this.router.navigate([`/api-connections/api-docs/${data.name}`]); @@ -292,8 +333,8 @@ export class DfServiceDetailsComponent implements OnInit { this.router.navigate(['../'], { relativeTo: this.activatedRoute }); } - getBackgroundImage(typeLable: string) { - const image = this.images?.find(img => img.label == typeLable); + getBackgroundImage(typeLabel: string) { + const image = this.images?.find(img => img.label == typeLabel); if (!image) { return ''; } @@ -315,8 +356,11 @@ export class DfServiceDetailsComponent implements OnInit { openDialog() { const dialogRef = this.dialog.open(DfPaywallModal); - // eslint-disable-next-line @typescript-eslint/no-empty-function - dialogRef.afterClosed().subscribe(result => {}); + dialogRef.afterClosed().subscribe(); + } + + onServiceDefinitionTypeChange(value: string) { + this.serviceDefinitionType = value; } } interface ImageObject { diff --git a/src/app/adf-user-management/adf-user-management.scss b/src/app/adf-user-management/adf-user-management.scss index 07253a51..c8ecdfff 100644 --- a/src/app/adf-user-management/adf-user-management.scss +++ b/src/app/adf-user-management/adf-user-management.scss @@ -3,11 +3,16 @@ flex-direction: column; justify-content: center; height: 100%; + .user-management-card { padding: 16px 16px; margin: 0 auto; min-width: 300px; max-width: 445px; + box-shadow: var(--mdc-elevated-card-container-elevation); + --mdc-elevated-card-container-shape: 4px; + --mdc-outlined-card-container-shape: 4px; + --mdc-outlined-card-outline-width: 1px; mat-card-header { padding-bottom: 16px; } @@ -33,3 +38,12 @@ } } } + +.user-management-card-container { + margin-top: 20vh; + + &.dark-theme { + background-color: #1e1e1e; + color: #fff; + } +} diff --git a/src/app/adf-user-management/df-forgot-password/df-forgot-password.component.html b/src/app/adf-user-management/df-forgot-password/df-forgot-password.component.html index 63ad0d6f..8ddbccc2 100644 --- a/src/app/adf-user-management/df-forgot-password/df-forgot-password.component.html +++ b/src/app/adf-user-management/df-forgot-password/df-forgot-password.component.html @@ -18,7 +18,7 @@ [formGroup]="forgetPasswordForm" (ngSubmit)="requestReset()" *ngIf="!hasSecurityQuestion"> - + {{ 'userManagement.controls.email.label' | transloco }} @@ -39,7 +39,9 @@ - + {{ 'userManagement.controls.username.altLabel' | transloco }} @@ -58,7 +60,7 @@ [formGroup]="securityQuestionForm" (ngSubmit)="resetPassword()" *ngIf="hasSecurityQuestion"> - + {{ 'userManagement.controls.securityQuestion.label' | transloco @@ -70,7 +72,7 @@ formControlName="securityQuestion" [readonly]="true" /> - + {{ 'userManagement.controls.securityAnswer.label' | transloco @@ -85,7 +87,7 @@ }} - + {{ 'userManagement.controls.password.label' | transloco }} @@ -104,7 +106,7 @@ - + {{ 'userManagement.controls.confirmPassword.label' | transloco }} diff --git a/src/app/adf-user-management/df-login/df-login.component.html b/src/app/adf-user-management/df-login/df-login.component.html index 3c134266..6c5c73cc 100644 --- a/src/app/adf-user-management/df-login/df-login.component.html +++ b/src/app/adf-user-management/df-login/df-login.component.html @@ -1,4 +1,6 @@ -
+
- + {{ 'userManagement.controls.email.label' | transloco }} @@ -45,7 +45,9 @@ - + {{ 'userManagement.controls.username.altLabel' | transloco }} @@ -56,7 +58,7 @@ - + {{ 'userManagement.controls.confirmationCode.label' | transloco @@ -71,7 +73,7 @@ }} - + {{ 'userManagement.controls.password.' + (type === 'reset' ? 'label' : 'altLabel') | transloco @@ -87,7 +89,7 @@ - + {{ 'userManagement.controls.confirmPassword.' + (type === 'reset' ? 'label' : 'altLabel') | transloco diff --git a/src/app/adf-user-management/services/df-password.service.ts b/src/app/adf-user-management/services/df-password.service.ts index 48e33754..8ee0ba56 100644 --- a/src/app/adf-user-management/services/df-password.service.ts +++ b/src/app/adf-user-management/services/df-password.service.ts @@ -35,9 +35,14 @@ export class DfPasswordService { } updatePassword(data: UpdatePasswordRequest) { - const url = this.userDataService.userData?.isSysAdmin - ? URLS.ADMIN_PASSWORD - : URLS.USER_PASSWORD; + let isSysAdmin = false; + // const url = this.userDataService.userData?.isSysAdmin + // ? URLS.ADMIN_PASSWORD + // : URLS.USER_PASSWORD; + this.userDataService.userData$.subscribe(userData => { + isSysAdmin = !!userData?.isSysAdmin; + }); + const url = isSysAdmin ? URLS.ADMIN_PASSWORD : URLS.USER_PASSWORD; return this.http .post(url, data, { headers: SHOW_LOADING_HEADER, diff --git a/src/app/adf-users/df-manage-users/df-manage-users.component.html b/src/app/adf-users/df-manage-users/df-manage-users.component.html index c13e202d..31561647 100644 --- a/src/app/adf-users/df-manage-users/df-manage-users.component.html +++ b/src/app/adf-users/df-manage-users/df-manage-users.component.html @@ -7,6 +7,8 @@ (change)="uploadUserList($event)" style="display: none" />
+
diff --git a/src/app/shared/components/df-ace-editor/df-ace-editor.component.ts b/src/app/shared/components/df-ace-editor/df-ace-editor.component.ts index 11518bb3..ab8b84f8 100644 --- a/src/app/shared/components/df-ace-editor/df-ace-editor.component.ts +++ b/src/app/shared/components/df-ace-editor/df-ace-editor.component.ts @@ -11,15 +11,18 @@ import { SimpleChanges, ViewChild, forwardRef, + inject, } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { AceEditorMode } from '../../types/scripts'; - +import { DfThemeService } from '../../services/df-theme.service'; +import { AsyncPipe } from '@angular/common'; @Component({ selector: 'df-ace-editor', templateUrl: './df-ace-editor.component.html', styleUrls: ['./df-ace-editor.component.scss'], standalone: true, + imports: [AsyncPipe], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -42,6 +45,8 @@ export class DfAceEditorComponent onChange: (value: string) => void; onTouched: () => void; + themeService = inject(DfThemeService); + isDarkMode = this.themeService.darkMode$; ngAfterViewInit(): void { this.init(this.elementRef, this.mode); diff --git a/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.html b/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.html index afde76ea..66d3c07c 100644 --- a/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.html +++ b/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.html @@ -1,84 +1,87 @@ - - {{ schema.label }} - + + {{ schema.label }} + + + + {{ option.label }} + + + + + + + {{ control.value ? control.value.name : ('noFileSelected' | transloco) }} + + - - - {{ option.label }} - - - - - - - {{ control.value ? control.value.name : ('noFileSelected' | transloco) }} - -{{ - schema.label - }} - - {{ schema.label }} - - - - {{ option }} - - - + [matTooltip]="schema.description ?? ''" + [attr.aria-label]="schema.label" + >{{ schema.label }} + + {{ schema.label }} + + + + {{ option }} + + + +
diff --git a/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.ts b/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.ts index 813c1831..abc28bb4 100644 --- a/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.ts +++ b/src/app/shared/components/df-dynamic-field/df-dynamic-field.component.ts @@ -29,6 +29,7 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { Observable, map, startWith } from 'rxjs'; import { ActivatedRoute } from '@angular/router'; import { addGroupEntries } from '../../utilities/eventScripts'; +import { DfThemeService } from '../../services/df-theme.service'; @UntilDestroy({ checkProperties: true }) @Component({ selector: 'df-dynamic-field', @@ -62,13 +63,15 @@ export class DfDynamicFieldComponent implements OnInit, DoCheck { constructor( @Optional() @Self() public controlDir: NgControl, - private activedRoute: ActivatedRoute + private activedRoute: ActivatedRoute, + private themeService: DfThemeService ) { controlDir.valueAccessor = this; } eventList: string[]; filteredEventList: Observable; + isDarkMode = this.themeService.darkMode$; ngOnInit(): void { if (this.schema.type === 'event_picklist') { diff --git a/src/app/shared/components/df-field-array/df-array-field.component.html b/src/app/shared/components/df-field-array/df-array-field.component.html index ba307f30..f3d0cc98 100644 --- a/src/app/shared/components/df-field-array/df-array-field.component.html +++ b/src/app/shared/components/df-field-array/df-array-field.component.html @@ -1,4 +1,4 @@ - + {{ schema.label }} - + - diff --git a/src/app/shared/components/df-lookup-keys/df-lookup-keys.component.ts b/src/app/shared/components/df-lookup-keys/df-lookup-keys.component.ts index dd480bf7..76304fe6 100644 --- a/src/app/shared/components/df-lookup-keys/df-lookup-keys.component.ts +++ b/src/app/shared/components/df-lookup-keys/df-lookup-keys.component.ts @@ -19,6 +19,9 @@ import { MatExpansionModule } from '@angular/material/expansion'; import { faPlus, faTrashCan } from '@fortawesome/free-solid-svg-icons'; import { TranslocoPipe } from '@ngneat/transloco'; import { UntilDestroy } from '@ngneat/until-destroy'; +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; +import { AsyncPipe } from '@angular/common'; + @UntilDestroy({ checkProperties: true }) @Component({ selector: 'df-lookup-keys', @@ -38,6 +41,7 @@ import { UntilDestroy } from '@ngneat/until-destroy'; FontAwesomeModule, MatExpansionModule, TranslocoPipe, + AsyncPipe, ], }) export class DfLookupKeysComponent implements OnInit { @@ -49,8 +53,11 @@ export class DfLookupKeysComponent implements OnInit { faPlus = faPlus; @Input() showAccordion = true; - constructor(private rootFormGroup: FormGroupDirective) {} - + constructor( + private rootFormGroup: FormGroupDirective, + private themeService: DfThemeService + ) {} + isDarkMode = this.themeService.darkMode$; ngOnInit() { this.rootForm = this.rootFormGroup.control; this.rootFormGroup.ngSubmit.subscribe(() => { diff --git a/src/app/shared/components/df-manage-table/df-manage-table.component.html b/src/app/shared/components/df-manage-table/df-manage-table.component.html index a4880881..13a9f982 100644 --- a/src/app/shared/components/df-manage-table/df-manage-table.component.html +++ b/src/app/shared/components/df-manage-table/df-manage-table.component.html @@ -1,24 +1,34 @@ -
+
+
{{ 'search' | transloco }}
-
+
- - - - - - -
- +
+ +
+ + + + + + + + + +
    +
  • + {{ getTranslationKey(result.path) | transloco }} +
      +
    • + +
    • +
    +
  • +
+
+
+
+ +
diff --git a/src/app/shared/components/df-search-dialog/df-search-dialog.component.scss b/src/app/shared/components/df-search-dialog/df-search-dialog.component.scss index bfb572fc..8afd2627 100644 --- a/src/app/shared/components/df-search-dialog/df-search-dialog.component.scss +++ b/src/app/shared/components/df-search-dialog/df-search-dialog.component.scss @@ -1,5 +1,11 @@ +@use '@angular/material' as mat; +@use 'src/theme' as theme; +$df-purple-palette: mat.define-palette(theme.$df-purple-palette); +.search-dialog { + padding-top: 20px; +} + .search-bar { - margin-top: 16px; min-width: 275px; } .search-container { @@ -20,3 +26,13 @@ justify-content: left; margin: 2px 0; } + +.dark-theme { + &.search-dialog { + background-color: mat.get-color-from-palette( + $df-purple-palette, + 1003 + ) !important; + border: 1px solid white; + } +} diff --git a/src/app/shared/components/df-search-dialog/df-search-dialog.component.ts b/src/app/shared/components/df-search-dialog/df-search-dialog.component.ts index 62d62b29..014d1910 100644 --- a/src/app/shared/components/df-search-dialog/df-search-dialog.component.ts +++ b/src/app/shared/components/df-search-dialog/df-search-dialog.component.ts @@ -13,6 +13,7 @@ import { DfSearchService } from '../../services/df-search.service'; import { DfBreakpointService } from '../../services/df-breakpoint.service'; import { faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { DfThemeService } from '../../services/df-theme.service'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -46,9 +47,12 @@ export class DfSearchDialogComponent implements OnInit { public dialogRef: MatDialogRef, private searchService: DfSearchService, private router: Router, - private breakpointService: DfBreakpointService + private breakpointService: DfBreakpointService, + private themeService: DfThemeService ) {} + isDarkMode = this.themeService.darkMode$; + getTranslationKey(path: string) { return `nav.${path.replaceAll('/', '.')}.nav`; } diff --git a/src/app/shared/components/df-side-nav/df-side-nav.component.html b/src/app/shared/components/df-side-nav/df-side-nav.component.html index 45f0ed49..6dcc6016 100644 --- a/src/app/shared/components/df-side-nav/df-side-nav.component.html +++ b/src/app/shared/components/df-side-nav/df-side-nav.component.html @@ -1,16 +1,29 @@
- - - + +
+ + +
+ @@ -85,12 +99,6 @@

API Scripting

- - - + +
+
-
-
-
@@ -142,15 +152,25 @@

class="nav-item" [class.active]="isActive(item)" (click)="handleNavClick(item)"> - {{ navLabel(item.path) | transloco }} + + + + + {{ navLabel(item.path) | transloco }} +

- {{ navLabel(item.path) | transloco }} + + + {{ navLabel(item.path) | transloco }} + span { + background-color: mat.get-color-from-palette( + $df-purple-palette, + 600 + ) !important; + } + } + + img { + filter: invert(1) !important; + } + } + .banner, + .main { + background-color: mat.get-color-from-palette( + $df-purple-palette, + 1002 + ) !important; + color: white; + .page-header { + color: mat.get-color-from-palette($df-purple-palette, 10) !important; + } + } + .sidenav-content { + background-color: mat.get-color-from-palette( + $df-purple-palette, + 1003 + ) !important; + color: white; + .page-header { + color: mat.get-color-from-palette($df-purple-palette, 10) !important; + } + } + + .content-wrapper { + padding: 2px; + border: 1px solid mat.get-color-from-palette($df-purple-palette, 1001) !important; + background-color: mat.get-color-from-palette( + $df-purple-palette, + 1002 + ) !important; + border-radius: 6px !important; + } } diff --git a/src/app/shared/components/df-side-nav/df-side-nav.component.ts b/src/app/shared/components/df-side-nav/df-side-nav.component.ts index 6535fed8..61f7d108 100644 --- a/src/app/shared/components/df-side-nav/df-side-nav.component.ts +++ b/src/app/shared/components/df-side-nav/df-side-nav.component.ts @@ -10,12 +10,16 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { DfAuthService } from 'src/app/adf-user-management/services/df-auth.service'; import { DfBreakpointService } from 'src/app/shared/services/df-breakpoint.service'; import { DfUserDataService } from 'src/app/shared/services/df-user-data.service'; +import { DfThemeService } from '../../services/df-theme.service'; + import { faAngleDown, faBars, faLanguage, faMagnifyingGlass, faUser, + faRefresh, + faPlus, } from '@fortawesome/free-solid-svg-icons'; import { routes } from 'src/app/routes'; import { @@ -28,11 +32,16 @@ import { TranslocoPipe, TranslocoService } from '@ngneat/transloco'; import { AsyncPipe, NgFor, NgIf, NgTemplateOutlet } from '@angular/common'; import { DfErrorService } from 'src/app/shared/services/df-error.service'; import { DfLicenseCheckService } from '../../services/df-license-check.service'; -import { of, switchMap } from 'rxjs'; +import { debounceTime, distinctUntilChanged, of, switchMap } from 'rxjs'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { DfSearchDialogComponent } from '../df-search-dialog/df-search-dialog.component'; import { UntilDestroy } from '@ngneat/until-destroy'; import { CommonModule } from '@angular/common'; +import { DfSearchService } from '../../services/df-search.service'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { DfThemeToggleComponent } from '../df-theme-toggle/df-theme-toggle.component'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; @UntilDestroy({ checkProperties: true }) @Component({ selector: 'df-side-nav', @@ -55,6 +64,10 @@ import { CommonModule } from '@angular/common'; NgTemplateOutlet, MatDialogModule, CommonModule, + MatFormFieldModule, + DfThemeToggleComponent, + ReactiveFormsModule, + MatInputModule, ], }) export class DfSideNavComponent implements OnInit { @@ -69,7 +82,11 @@ export class DfSideNavComponent implements OnInit { faMagnifyingGlass = faMagnifyingGlass; faUser = faUser; faLanguage = faLanguage; - + search = new FormControl(); + results$ = this.searchService.results$; + smallScreen$ = this.breakpointService.isSmallScreen; + faPlus = faPlus; + faRefresh = faRefresh; constructor( private breakpointService: DfBreakpointService, private userDataService: DfUserDataService, @@ -78,7 +95,9 @@ export class DfSideNavComponent implements OnInit { private errorService: DfErrorService, private licenseCheckService: DfLicenseCheckService, private dialog: MatDialog, - private transloco: TranslocoService + private transloco: TranslocoService, + private themeService: DfThemeService, + private searchService: DfSearchService ) {} ngOnInit(): void { @@ -118,8 +137,19 @@ export class DfSideNavComponent implements OnInit { this.nav = transformRoutes(routes); } }); + this.search.valueChanges + .pipe( + debounceTime(1000), + distinctUntilChanged(), + switchMap(value => this.searchService.search(value)) + ) + .subscribe(() => { + this.dialog.open(DfSearchDialogComponent, { + position: { top: '60px' }, + }); + }); } - + isDarkMode = this.themeService.darkMode$; logout() { this.authService.logout(); } @@ -151,6 +181,12 @@ export class DfSideNavComponent implements OnInit { localStorage.setItem('language', language); } + onSubmit() { + this.searchService.search(this.search.value).subscribe(() => { + this.dialog.open(DfSearchDialogComponent, { position: { top: '60px' } }); + }); + } + get activeLanguage() { return this.transloco.getActiveLang(); } diff --git a/src/app/shared/components/df-theme-toggle/df-theme-toggle.component.html b/src/app/shared/components/df-theme-toggle/df-theme-toggle.component.html new file mode 100644 index 00000000..fa8385ca --- /dev/null +++ b/src/app/shared/components/df-theme-toggle/df-theme-toggle.component.html @@ -0,0 +1,4 @@ + diff --git a/src/app/shared/components/df-theme-toggle/df-theme-toggle.component.ts b/src/app/shared/components/df-theme-toggle/df-theme-toggle.component.ts new file mode 100644 index 00000000..40249dcd --- /dev/null +++ b/src/app/shared/components/df-theme-toggle/df-theme-toggle.component.ts @@ -0,0 +1,22 @@ +import { Component, inject } from '@angular/core'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { DfThemeService } from '../../services/df-theme.service'; +import { BehaviorSubject } from 'rxjs'; +import { AsyncPipe } from '@angular/common'; +@Component({ + selector: 'df-theme-toggle', + templateUrl: './df-theme-toggle.component.html', + standalone: true, + imports: [MatSlideToggleModule, AsyncPipe], +}) +export class DfThemeToggleComponent { + isDarkMode$: BehaviorSubject = new BehaviorSubject(true); + themeService = inject(DfThemeService); + + toggle() { + this.isDarkMode$.subscribe(isDarkMode => { + this.themeService.setThemeMode(!isDarkMode); + }); + this.isDarkMode$.next(!this.isDarkMode$.value); + } +} diff --git a/src/app/shared/components/df-user-details/df-user-details-base.component.html b/src/app/shared/components/df-user-details/df-user-details-base.component.html index 85aa4bd7..9f09dc47 100644 --- a/src/app/shared/components/df-user-details/df-user-details-base.component.html +++ b/src/app/shared/components/df-user-details/df-user-details-base.component.html @@ -4,11 +4,15 @@ (alertClosed)="showAlert = false"> {{ alertMsg }} - +
- {{ + {{ 'active' | transloco }} @@ -62,7 +66,7 @@ userForm.get('pass-invite')?.value === 'password' || userForm.get('setPassword')?.value "> - + {{ 'userManagement.controls.password.label' | transloco }} @@ -78,7 +82,7 @@ {{ 'userManagement.controls.password.errors.length' | transloco }} - + {{ 'userManagement.controls.confirmPassword.label' | transloco }} @@ -152,10 +156,14 @@

{{ userType + '.accessByTabs' | transloco }}

[roles]="roles">
- -
diff --git a/src/app/shared/components/df-user-details/df-user-details-base.component.ts b/src/app/shared/components/df-user-details/df-user-details-base.component.ts index 665541b5..4e766353 100644 --- a/src/app/shared/components/df-user-details/df-user-details-base.component.ts +++ b/src/app/shared/components/df-user-details/df-user-details-base.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { FormArray, FormBuilder, @@ -21,6 +21,7 @@ import { faEnvelope } from '@fortawesome/free-solid-svg-icons'; import { UntilDestroy } from '@ngneat/until-destroy'; import { DfPaywallService } from '../../services/df-paywall.service'; import { of, switchMap } from 'rxjs'; +import { DfThemeService } from '../../services/df-theme.service'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -64,7 +65,7 @@ export abstract class DfUserDetailsBaseComponent implements OnInit { ) { this.userForm = this.fb.group({ profileDetailsGroup: this.fb.group({ - username: [''], + username: ['', Validators.minLength(6)], email: ['', Validators.email], firstName: [''], lastName: [''], @@ -77,6 +78,8 @@ export abstract class DfUserDetailsBaseComponent implements OnInit { appRoles: this.fb.array([]), }); } + themeService = inject(DfThemeService); + isDarkMode = this.themeService.darkMode$; get cancelRoute() { let route = `/${ROUTES.ADMIN_SETTINGS}/`; diff --git a/src/app/shared/components/df-verb-picker/df-verb-picker.component.html b/src/app/shared/components/df-verb-picker/df-verb-picker.component.html index 5c94abaf..bae179a9 100644 --- a/src/app/shared/components/df-verb-picker/df-verb-picker.component.html +++ b/src/app/shared/components/df-verb-picker/df-verb-picker.component.html @@ -1,17 +1,19 @@ - - {{ schema.label }} - - - {{ verb.label }} - - - - +
+ + {{ schema.label }} + + + {{ verb.label }} + + + + +
diff --git a/src/app/shared/components/df-verb-picker/df-verb-picker.component.ts b/src/app/shared/components/df-verb-picker/df-verb-picker.component.ts index 9b75b3ff..941b51c7 100644 --- a/src/app/shared/components/df-verb-picker/df-verb-picker.component.ts +++ b/src/app/shared/components/df-verb-picker/df-verb-picker.component.ts @@ -15,7 +15,8 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faCircleInfo } from '@fortawesome/free-solid-svg-icons'; import { UntilDestroy } from '@ngneat/until-destroy'; - +import { DfThemeService } from 'src/app/shared/services/df-theme.service'; +import { AsyncPipe } from '@angular/common'; type Verb = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -31,6 +32,7 @@ type Verb = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; NgIf, MatTooltipModule, FontAwesomeModule, + AsyncPipe, ], }) export class DfVerbPickerComponent implements ControlValueAccessor, DoCheck { @@ -71,9 +73,13 @@ export class DfVerbPickerComponent implements ControlValueAccessor, DoCheck { onChange: (value: number | Verb | Array) => void; onTouched: () => void; - constructor(@Self() public controlDir: NgControl) { + constructor( + @Self() public controlDir: NgControl, + private themeService: DfThemeService + ) { controlDir.valueAccessor = this; } + isDarkMode = this.themeService.darkMode$; ngDoCheck(): void { if ( diff --git a/src/app/shared/services/df-base-crud.service.ts b/src/app/shared/services/df-base-crud.service.ts index 4dfe2f62..7bd2c4de 100644 --- a/src/app/shared/services/df-base-crud.service.ts +++ b/src/app/shared/services/df-base-crud.service.ts @@ -183,6 +183,9 @@ export class DfBaseCrudService { if (options.includeCount !== undefined) { params.include_count = options.includeCount; } + if (options.refresh) { + params.refresh = options.refresh; + } if (options.additionalParams) { options.additionalParams.forEach(param => { diff --git a/src/app/shared/services/df-theme.service.ts b/src/app/shared/services/df-theme.service.ts new file mode 100644 index 00000000..eb288357 --- /dev/null +++ b/src/app/shared/services/df-theme.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) +export class DfThemeService { + darkMode$ = new BehaviorSubject(false); + + constructor() { + this.loadInitialTheme(); + } + + setThemeMode(isDarkMode: boolean): void { + this.darkMode$.next(isDarkMode); + localStorage.setItem('isDarkMode', JSON.stringify(isDarkMode)); + } + + loadInitialTheme(): void { + const storedTheme = localStorage.getItem('isDarkMode'); + if (storedTheme) { + this.darkMode$.next(JSON.parse(storedTheme)); + } + } +} diff --git a/src/app/shared/types/generic-http.ts b/src/app/shared/types/generic-http.ts index 917eea33..d8457131 100644 --- a/src/app/shared/types/generic-http.ts +++ b/src/app/shared/types/generic-http.ts @@ -41,6 +41,7 @@ export interface RequestOptions { additionalParams: KeyValuePair[]; additionalHeaders: KeyValuePair[]; includeCacheControl: boolean; + refresh: boolean; } export type GenericCreateResponse = GenericListResponse<{ id: number }>; diff --git a/src/app/shared/types/nav.ts b/src/app/shared/types/nav.ts index 6599c37c..c3a125c0 100644 --- a/src/app/shared/types/nav.ts +++ b/src/app/shared/types/nav.ts @@ -3,6 +3,7 @@ import { ROUTES } from './routes'; export interface Nav { path: string; route: ROUTES; + icon?: string; subRoutes?: Nav[]; serviceGroups?: Array; } diff --git a/src/app/shared/types/service.ts b/src/app/shared/types/service.ts index 55c5c452..868efa62 100644 --- a/src/app/shared/types/service.ts +++ b/src/app/shared/types/service.ts @@ -79,6 +79,7 @@ export interface Service { lastModifiedById: number | null; config: any; serviceDocByServiceId: number | null; + refresh: boolean; } export interface ServiceRow { diff --git a/src/app/shared/utilities/route.ts b/src/app/shared/utilities/route.ts index bf15fbdb..489d2f19 100644 --- a/src/app/shared/utilities/route.ts +++ b/src/app/shared/utilities/route.ts @@ -13,6 +13,14 @@ const filteredFromNav = [ ROUTES.LICENSE_EXPIRED, ]; +const navIcons = [ + 'home', + 'admin-settings', + 'api-connections', + 'api-security', + 'system-settings', +]; + export function transformRoutes(routes: Routes, root = ''): Array