From 7cf76482c97b0c85d76cfa3c83ef84da81fb5eee Mon Sep 17 00:00:00 2001 From: Christian Badura <93912698+cbadura@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:26:51 +0200 Subject: [PATCH] Create slot for list-workspaces-using-theme (#271) * feat: set up slot for list workspaces * feat: make slot work, prepare translations * feat: finish slot setup, implement new tab structure * feat: use tab tooltips * fix: tests --------- Co-authored-by: Christian Badura --- helm/values.yaml | 6 ++++ src/app/onecx-theme-remote.module.ts | 2 ++ src/app/shared/shared.module.ts | 3 ++ .../theme-detail/theme-detail.component.html | 36 +++++++++++++++++-- .../theme-intern/theme-intern.component.html | 19 ---------- .../theme-intern.component.spec.ts | 11 +----- .../theme-intern/theme-intern.component.ts | 20 +++++++---- .../theme-use/theme-use.component.html | 8 +++++ .../theme-use/theme-use.component.spec.ts | 35 ++++++++++++++++++ .../theme-use/theme-use.component.ts | 27 ++++++++++++++ src/app/theme/theme.module.ts | 4 ++- src/assets/i18n/de.json | 9 +++-- src/assets/i18n/en.json | 11 ++++-- 13 files changed, 146 insertions(+), 45 deletions(-) create mode 100644 src/app/theme/theme-detail/theme-use/theme-use.component.html create mode 100644 src/app/theme/theme-detail/theme-use/theme-use.component.spec.ts create mode 100644 src/app/theme/theme-detail/theme-use/theme-use.component.ts diff --git a/helm/values.yaml b/helm/values.yaml index 21acb37..eb6eef4 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -36,5 +36,11 @@ app: VIEW: View mode for theme IMPORT: Import theme EXPORT: Export theme + slot: + enabled: true + specs: + onecx-theme-list-workspaces-using-theme: + name: 'onecx-theme-list-workspaces-using-theme' + description: 'List of Workspaces using the given Theme' # PIPE Config diff --git a/src/app/onecx-theme-remote.module.ts b/src/app/onecx-theme-remote.module.ts index 0f0fc26..5465fce 100644 --- a/src/app/onecx-theme-remote.module.ts +++ b/src/app/onecx-theme-remote.module.ts @@ -19,6 +19,7 @@ import { AngularAuthModule } from '@onecx/angular-auth' import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { environment } from 'src/environments/environment' import { Configuration } from './shared/generated' +import { SLOT_SERVICE, SlotService } from '@onecx/angular-remote-components' function apiConfigProvider(configService: ConfigurationService, appStateService: AppStateService) { return new PortalApiConfiguration(Configuration, environment.apiPrefix, configService, appStateService) @@ -58,6 +59,7 @@ const routes: Routes = [ deps: [Router, AppStateService] }, { provide: Configuration, useFactory: apiConfigProvider, deps: [ConfigurationService, AppStateService] }, + { provide: SLOT_SERVICE, useExisting: SlotService }, provideHttpClient(withInterceptorsFromDi()) ], schemas: [] diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c3e6406..0b92421 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -28,6 +28,7 @@ import { TableModule } from 'primeng/table' import { ToastModule } from 'primeng/toast' import { PortalCoreModule } from '@onecx/portal-integration-angular' +import { AngularRemoteComponentsModule } from '@onecx/angular-remote-components' import { LabelResolver } from './label.resolver' import { ImageContainerComponent } from './image-container/image-container.component' @@ -38,6 +39,7 @@ import { ThemeColorBoxComponent } from './theme-color-box/theme-color-box.compon imports: [ PortalCoreModule.forMicroFrontend(), AutoCompleteModule, + AngularRemoteComponentsModule, CheckboxModule, ColorSketchModule, CommonModule, @@ -65,6 +67,7 @@ import { ThemeColorBoxComponent } from './theme-color-box/theme-color-box.compon ], exports: [ AutoCompleteModule, + AngularRemoteComponentsModule, CheckboxModule, CommonModule, ColorSketchModule, diff --git a/src/app/theme/theme-detail/theme-detail.component.html b/src/app/theme/theme-detail/theme-detail.component.html index 9f23d2d..6b15050 100644 --- a/src/app/theme/theme-detail/theme-detail.component.html +++ b/src/app/theme/theme-detail/theme-detail.component.html @@ -17,7 +17,14 @@ - +
@@ -77,11 +84,34 @@
- + - + + + + +
             {{ theme?.properties | json }}
diff --git a/src/app/theme/theme-detail/theme-intern/theme-intern.component.html b/src/app/theme/theme-detail/theme-intern/theme-intern.component.html
index 4fc36ce..e860b7a 100644
--- a/src/app/theme/theme-detail/theme-intern/theme-intern.component.html
+++ b/src/app/theme/theme-detail/theme-intern/theme-intern.component.html
@@ -103,24 +103,5 @@
         
       
- -
- - - - -
diff --git a/src/app/theme/theme-detail/theme-intern/theme-intern.component.spec.ts b/src/app/theme/theme-detail/theme-intern/theme-intern.component.spec.ts index 828c079..63a01ca 100644 --- a/src/app/theme/theme-detail/theme-intern/theme-intern.component.spec.ts +++ b/src/app/theme/theme-detail/theme-intern/theme-intern.component.spec.ts @@ -1,4 +1,4 @@ -import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing' +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' import { ThemeInternComponent } from './theme-intern.component' import { TranslateModule, TranslateService } from '@ngx-translate/core' import { TranslateTestingModule } from 'ngx-translate-testing' @@ -49,13 +49,4 @@ describe('ThemeInternComponent', () => { component.ngOnChanges() expect(component.operator).toBeFalse() }) - - it('should update usedInWorkspaces.nativeElement.innerHTML with workspaceList', fakeAsync(() => { - const nativeElement = document.createElement('textarea') - component.usedInWorkspaces = { nativeElement } - component.workspaceList = 'Workspace 1, Workspace 2' - component.ngOnChanges() - tick(1000) - expect(nativeElement?.innerHTML).toBe('Workspace 1, Workspace 2') - })) }) diff --git a/src/app/theme/theme-detail/theme-intern/theme-intern.component.ts b/src/app/theme/theme-detail/theme-intern/theme-intern.component.ts index bed7837..f1a0c7c 100644 --- a/src/app/theme/theme-detail/theme-intern/theme-intern.component.ts +++ b/src/app/theme/theme-detail/theme-intern/theme-intern.component.ts @@ -1,6 +1,8 @@ -import { Component, ElementRef, Input, OnChanges, ViewChild } from '@angular/core' +import { Component, Input, OnChanges } from '@angular/core' import { TranslateService } from '@ngx-translate/core' +import { SlotService } from '@onecx/angular-remote-components' +import { Observable } from 'rxjs' import { Theme } from 'src/app/shared/generated' @Component({ @@ -11,17 +13,21 @@ export class ThemeInternComponent implements OnChanges { @Input() theme: Theme | undefined @Input() dateFormat = 'medium' @Input() workspaceList: string | undefined - - @ViewChild('usedInWorkspaces') usedInWorkspaces: ElementRef = {} as ElementRef + public isListWorkspacesUsingThemeComponentDefined$: Observable | undefined + public listWorkspacesUsingThemeSlotName = 'onecx-theme-list-workspaces-using-theme' public operator = false - constructor(private translate: TranslateService) {} + constructor( + private readonly translate: TranslateService, + private readonly slotService: SlotService + ) { + this.isListWorkspacesUsingThemeComponentDefined$ = this.slotService.isSomeComponentDefinedForSlot( + this.listWorkspacesUsingThemeSlotName + ) + } public ngOnChanges(): void { if (this.theme) this.operator = this.theme.operator ?? false - setTimeout(() => { - if (this.usedInWorkspaces?.nativeElement) this.usedInWorkspaces.nativeElement.innerHTML = this.workspaceList - }, 2) } } diff --git a/src/app/theme/theme-detail/theme-use/theme-use.component.html b/src/app/theme/theme-detail/theme-use/theme-use.component.html new file mode 100644 index 0000000..fc7cac9 --- /dev/null +++ b/src/app/theme/theme-detail/theme-use/theme-use.component.html @@ -0,0 +1,8 @@ +
+ + +
diff --git a/src/app/theme/theme-detail/theme-use/theme-use.component.spec.ts b/src/app/theme/theme-detail/theme-use/theme-use.component.spec.ts new file mode 100644 index 0000000..b73d9de --- /dev/null +++ b/src/app/theme/theme-detail/theme-use/theme-use.component.spec.ts @@ -0,0 +1,35 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' +import { ThemeUseComponent } from './theme-use.component' +import { TranslateModule, TranslateService } from '@ngx-translate/core' +import { TranslateTestingModule } from 'ngx-translate-testing' +import { NO_ERRORS_SCHEMA } from '@angular/core' + +describe('ThemeUseComponent', () => { + let component: ThemeUseComponent + let fixture: ComponentFixture + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ThemeUseComponent], + imports: [ + TranslateModule.forRoot(), + TranslateTestingModule.withTranslations({ + de: require('src/assets/i18n/de.json'), + en: require('src/assets/i18n/en.json') + }).withDefaultLanguage('de') + ], + providers: [TranslateService], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents() + })) + + beforeEach(() => { + fixture = TestBed.createComponent(ThemeUseComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) +}) diff --git a/src/app/theme/theme-detail/theme-use/theme-use.component.ts b/src/app/theme/theme-detail/theme-use/theme-use.component.ts new file mode 100644 index 0000000..2786d7f --- /dev/null +++ b/src/app/theme/theme-detail/theme-use/theme-use.component.ts @@ -0,0 +1,27 @@ +import { Component, Input } from '@angular/core' +import { TranslateService } from '@ngx-translate/core' + +import { SlotService } from '@onecx/angular-remote-components' +import { Observable } from 'rxjs' +import { Theme } from 'src/app/shared/generated' + +@Component({ + selector: 'app-theme-use', + templateUrl: './theme-use.component.html' +}) +export class ThemeUseComponent { + @Input() theme: Theme | undefined + public isListWorkspacesUsingThemeComponentDefined$: Observable | undefined + public listWorkspacesUsingThemeSlotName = 'onecx-theme-list-workspaces-using-theme' + + public operator = false + + constructor( + private readonly translate: TranslateService, + private readonly slotService: SlotService + ) { + this.isListWorkspacesUsingThemeComponentDefined$ = this.slotService.isSomeComponentDefinedForSlot( + this.listWorkspacesUsingThemeSlotName + ) + } +} diff --git a/src/app/theme/theme.module.ts b/src/app/theme/theme.module.ts index 6338a8a..d2f27b7 100644 --- a/src/app/theme/theme.module.ts +++ b/src/app/theme/theme.module.ts @@ -16,6 +16,7 @@ import { ThemeSearchComponent } from './theme-search/theme-search.component' import { ThemeImportComponent } from './theme-import/theme-import.component' import { ThemeDetailComponent } from './theme-detail/theme-detail.component' import { ThemeInternComponent } from './theme-detail/theme-intern/theme-intern.component' +import { ThemeUseComponent } from './theme-detail/theme-use/theme-use.component' import { ThemeDesignerComponent } from './theme-designer/theme-designer.component' const routes: Routes = [ @@ -58,7 +59,8 @@ const routes: Routes = [ ThemeDetailComponent, ThemeDesignerComponent, ThemeImportComponent, - ThemeInternComponent + ThemeInternComponent, + ThemeUseComponent ], imports: [ CommonModule, diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 08a40e5..4d85d0b 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -149,8 +149,13 @@ "NO_PROPERTIES": "Keine Farbwerte enthalten", "TABS": { "INTERN": "Intern", - "PROPERTIES": "Eigenschaften", - "VARIABLES": "Theme Variablen" + "INTERN_TOOLTIP": "Interne Informationen zum Theme", + "PROPERTIES": "Eigenschaften des Themes", + "PROPERTIES_TOOLTIP": "Eigenschaften", + "USE": "Verwendung", + "USE_TOOLTIP": "Liste der Workspaces, die das Theme verwenden", + "VARIABLES": "Theme-Variablen", + "VARIABLES_TOOLTIP": "JSON-Darstellung der Theme-Variablen" }, "IMPORT": { "HEADER": "Import Theme", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 5ee8a3b..960044b 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -82,8 +82,8 @@ "CREATION_USER": "Created by", "MODIFICATION_DATE": "Changed on", "MODIFICATION_USER": "Changed by", - "OPERATOR": "Automated created", - "OPERATOR_MESSAGE": "This Theme was automated created. All changes will be lost during the next deployment.", + "OPERATOR": "Created by automation", + "OPERATOR_MESSAGE": "This Theme was created by automation. All changes will be lost during the next deployment.", "TOOLTIPS": { "CREATION_DATE": "Timestamp of the creation", "CREATION_USER": "Name of the user of the creation", @@ -149,8 +149,13 @@ "NO_PROPERTIES": "No properties specified", "TABS": { "INTERN": "Internal", + "INTERN_TOOLTIP": "Internal information for the Theme", "PROPERTIES": "Properties", - "VARIABLES": "Theme Variables" + "PROPERTIES_TOOLTIP": "Properties of the Theme", + "USE": "Use", + "USE_TOOLTIP": "List of Workspaces using the Theme", + "VARIABLES": "Theme Variables", + "VARIABLES_TOOLTIP": "JSON representation of Theme Variables" }, "IMPORT": { "HEADER": "Import Theme",