From c66ce03fd10f317d59f05b80f585e7ac404945bc Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 28 Sep 2023 12:51:48 +0200 Subject: [PATCH 1/3] fix: 0 value is ignored --- .../dynamic-component.directive.spec.ts | 72 +++++++++++++++++++ .../dynamic-component.directive.ts | 6 +- 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/app/core/config/dynamic-components/dynamic-component.directive.spec.ts diff --git a/src/app/core/config/dynamic-components/dynamic-component.directive.spec.ts b/src/app/core/config/dynamic-components/dynamic-component.directive.spec.ts new file mode 100644 index 0000000000..ac739e4887 --- /dev/null +++ b/src/app/core/config/dynamic-components/dynamic-component.directive.spec.ts @@ -0,0 +1,72 @@ +import { TestBed } from "@angular/core/testing"; +import { ChangeDetectorRef, ViewContainerRef } from "@angular/core"; +import { DynamicComponentDirective } from "./dynamic-component.directive"; +import { ComponentRegistry } from "../../../dynamic-components"; + +describe("DynamicComponentDirective", () => { + let directive: DynamicComponentDirective; + let mockContainer: jasmine.SpyObj; + let mockDetector: jasmine.SpyObj; + let mockRegistry: jasmine.SpyObj; + + beforeEach(() => { + mockContainer = jasmine.createSpyObj(["clear", "createComponent"]); + mockDetector = jasmine.createSpyObj(["detectChanges"]); + mockRegistry = jasmine.createSpyObj(["get"]); + TestBed.configureTestingModule({ + providers: [ + { provide: ViewContainerRef, useValue: mockContainer }, + { provide: ChangeDetectorRef, useValue: mockDetector }, + { provide: ComponentRegistry, useValue: mockRegistry }, + DynamicComponentDirective, + ], + }); + directive = TestBed.inject(DynamicComponentDirective); + }); + + it("should create the configured component", async () => { + directive.appDynamicComponent = { component: "TestComp" }; + const comp = {} as any; + mockRegistry.get.and.returnValue(() => Promise.resolve(comp)); + + await directive.ngOnChanges(); + + expect(mockRegistry.get).toHaveBeenCalledWith("TestComp"); + expect(mockContainer.createComponent).toHaveBeenCalledWith(comp); + }); + + it("should assign the properties to the component", async () => { + directive.appDynamicComponent = { + component: "TestComp", + config: { + numberProp: 0, + stringProp: "should exist", + missingProp: "should not exist", + }, + }; + const changesSpy = jasmine.createSpy(); + const comp: any = { + prototype: { + constructor: { + ["ɵcmp"]: { + inputs: { numberProp: {}, stringProp: {}, otherProp: {} }, + }, + }, + }, + }; + const compRef: any = { instance: { ngOnChanges: changesSpy } }; + mockRegistry.get.and.returnValue(() => Promise.resolve(comp)); + mockContainer.createComponent.and.returnValue(compRef); + + await directive.ngOnChanges(); + + expect(compRef.instance.numberProp).toBe(0); + expect(compRef.instance.stringProp).toBe("should exist"); + expect(compRef.instance.missingProp).toBeUndefined(); + expect(compRef.instance.otherProp).toBeUndefined(); + expect(compRef.instance.ngOnChanges).toHaveBeenCalledWith({ + numberProp: jasmine.anything(), + stringProp: jasmine.anything(), + }); + }); +}); diff --git a/src/app/core/config/dynamic-components/dynamic-component.directive.ts b/src/app/core/config/dynamic-components/dynamic-component.directive.ts index 667c39163b..175e9e083e 100644 --- a/src/app/core/config/dynamic-components/dynamic-component.directive.ts +++ b/src/app/core/config/dynamic-components/dynamic-component.directive.ts @@ -31,8 +31,8 @@ export class DynamicComponentDirective implements OnChanges { private changeDetector: ChangeDetectorRef, ) {} - async ngOnChanges() { - await this.loadDynamicComponent(); + ngOnChanges() { + return this.loadDynamicComponent(); } private async loadDynamicComponent() { @@ -57,7 +57,7 @@ export class DynamicComponentDirective implements OnChanges { private setInputProperties(proto, component) { const inputs = Object.keys(proto.constructor["ɵcmp"].inputs).filter( - (input) => this.appDynamicComponent.config?.[input], + (input) => this.appDynamicComponent.config?.[input] !== undefined, ); const inputValues = pick(this.appDynamicComponent.config, inputs); const initialValues = pick(component, inputs); From b9f763a922cb55a1d17cf4277868940bbf64b5aa Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 2 Oct 2023 15:20:52 +0200 Subject: [PATCH 2/3] refactor: fix typo and storybook path --- .../display-dynamic-percentage.component.spec.ts | 0 .../display-dynamic-percentage.component.ts | 0 .../display-dynamic-percentage.stories.ts | 4 ++-- src/app/core/core-components.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/app/core/basic-datatypes/number/{display-dyanamic-percentage => display-dynamic-percentage}/display-dynamic-percentage.component.spec.ts (100%) rename src/app/core/basic-datatypes/number/{display-dyanamic-percentage => display-dynamic-percentage}/display-dynamic-percentage.component.ts (100%) rename src/app/core/basic-datatypes/number/{display-dyanamic-percentage => display-dynamic-percentage}/display-dynamic-percentage.stories.ts (84%) diff --git a/src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.component.spec.ts b/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.component.spec.ts similarity index 100% rename from src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.component.spec.ts rename to src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.component.spec.ts diff --git a/src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.component.ts b/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.component.ts similarity index 100% rename from src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.component.ts rename to src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.component.ts diff --git a/src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.stories.ts b/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts similarity index 84% rename from src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.stories.ts rename to src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts index 8189aa7f97..72f0219501 100644 --- a/src/app/core/basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.stories.ts +++ b/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts @@ -1,10 +1,10 @@ -import { Meta, StoryFn, applicationConfig } from "@storybook/angular"; +import { applicationConfig, Meta, StoryFn } from "@storybook/angular"; import { StorybookBaseModule } from "app/utils/storybook-base.module"; import { DisplayDynamicPercentageComponent } from "./display-dynamic-percentage.component"; import { importProvidersFrom } from "@angular/core"; export default { - title: "Core/Entities/Display Properties/DisplayDynamicPercentage", + title: "Core/Entities/Properties/number/DisplayDynamicPercentage", component: DisplayDynamicPercentageComponent, decorators: [ applicationConfig({ diff --git a/src/app/core/core-components.ts b/src/app/core/core-components.ts index 16a0541db6..eb43460952 100644 --- a/src/app/core/core-components.ts +++ b/src/app/core/core-components.ts @@ -159,7 +159,7 @@ export const coreComponents: ComponentTuple[] = [ "DisplayDynamicPercentage", () => import( - "./basic-datatypes/number/display-dyanamic-percentage/display-dynamic-percentage.component" + "./basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.component" ).then((c) => c.DisplayDynamicPercentageComponent), ], [ From 7f39409467199191892d7268a993b6f2b3a63f40 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 2 Oct 2023 15:31:55 +0200 Subject: [PATCH 3/3] fix: also display for number viewComponents --- .../display-dynamic-percentage.stories.ts | 10 ++++++++++ .../display-percentage/display-percentage.component.ts | 3 ++- .../display-percentage/display-percentage.stories.ts | 2 +- .../number/display-unit/display-unit.component.ts | 2 +- .../number/display-unit/display-unit.stories.ts | 6 ++++++ src/app/core/basic-datatypes/number/number.datatype.ts | 1 + 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts b/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts index 72f0219501..7baf5d8805 100644 --- a/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts +++ b/src/app/core/basic-datatypes/number/display-dynamic-percentage/display-dynamic-percentage.stories.ts @@ -28,3 +28,13 @@ Primary.args = { decimalPlaces: 3, }, }; + +export const Zero = Template.bind({}); +Zero.args = { + entity: { allDays: 110, presentDays: 0 }, + config: { + actual: "presentDays", + total: "allDays", + decimalPlaces: 3, + }, +}; diff --git a/src/app/core/basic-datatypes/number/display-percentage/display-percentage.component.ts b/src/app/core/basic-datatypes/number/display-percentage/display-percentage.component.ts index c3b54bab8f..80cf7623d1 100644 --- a/src/app/core/basic-datatypes/number/display-percentage/display-percentage.component.ts +++ b/src/app/core/basic-datatypes/number/display-percentage/display-percentage.component.ts @@ -6,7 +6,8 @@ import { CommonModule } from "@angular/common"; @DynamicComponent("DisplayPercentage") @Component({ selector: "app-display-percentage", - template: "{{ value ? (value | number : numberFormat) + '%' : '-' }}", + template: + "{{ value !== undefined ? (value | number : numberFormat) + '%' : '-' }}", standalone: true, imports: [CommonModule], }) diff --git a/src/app/core/basic-datatypes/number/display-percentage/display-percentage.stories.ts b/src/app/core/basic-datatypes/number/display-percentage/display-percentage.stories.ts index 1bfeb68263..f32777bfdc 100644 --- a/src/app/core/basic-datatypes/number/display-percentage/display-percentage.stories.ts +++ b/src/app/core/basic-datatypes/number/display-percentage/display-percentage.stories.ts @@ -29,7 +29,7 @@ const Template: StoryFn = ( export const Low = Template.bind({}); Low.args = { - value: 5, + value: 0, }; export const Medium = Template.bind({}); Medium.args = { diff --git a/src/app/core/basic-datatypes/number/display-unit/display-unit.component.ts b/src/app/core/basic-datatypes/number/display-unit/display-unit.component.ts index e7a61e87da..6ca851dfa3 100644 --- a/src/app/core/basic-datatypes/number/display-unit/display-unit.component.ts +++ b/src/app/core/basic-datatypes/number/display-unit/display-unit.component.ts @@ -5,7 +5,7 @@ import { DynamicComponent } from "../../../config/dynamic-components/dynamic-com @DynamicComponent("DisplayUnit") @Component({ selector: "app-display-unit", - template: '{{ value ? value + " " + config : "" }}', + template: '{{ value !== undefined ? value + " " + config : "" }}', standalone: true, }) export class DisplayUnitComponent extends ViewDirective {} diff --git a/src/app/core/basic-datatypes/number/display-unit/display-unit.stories.ts b/src/app/core/basic-datatypes/number/display-unit/display-unit.stories.ts index c86fd2a813..832ff958af 100644 --- a/src/app/core/basic-datatypes/number/display-unit/display-unit.stories.ts +++ b/src/app/core/basic-datatypes/number/display-unit/display-unit.stories.ts @@ -25,6 +25,12 @@ Basic.args = { config: "kg", }; +export const Zero = Template.bind({}); +Zero.args = { + value: 0, + config: "kg", +}; + export const WithoutValue = Template.bind({}); WithoutValue.args = { value: undefined, diff --git a/src/app/core/basic-datatypes/number/number.datatype.ts b/src/app/core/basic-datatypes/number/number.datatype.ts index ead7e41a09..6e7052a709 100644 --- a/src/app/core/basic-datatypes/number/number.datatype.ts +++ b/src/app/core/basic-datatypes/number/number.datatype.ts @@ -33,6 +33,7 @@ import { Injectable } from "@angular/core"; @Injectable() export class NumberDatatype extends DefaultDatatype { static dataType = "number"; + viewComponent = "DisplayText"; editComponent = "EditNumber"; transformToDatabaseFormat(value) {