Skip to content

Commit

Permalink
fix(Admin UI): make photo and percentage field types available for co…
Browse files Browse the repository at this point in the history
…nfiguration (#2546)

by adding them as new Datatype implementations

closes #2503, closes #2121 

---------

Co-authored-by: Sebastian <sebastian@aam-digital.com>
  • Loading branch information
sadaf895 and sleidig authored Sep 4, 2024
1 parent f884a06 commit 482feae
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 7 deletions.
5 changes: 3 additions & 2 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ COPY --from=base-with-dependencies /opt/app /opt/app

RUN apt-get update && apt-get install -y curl
WORKDIR /tmp
# 121.0.6167.139-1~deb12u1 -> 2024-02-01
ARG CHROMIUM_VERSION=121.0.6167.139-1~deb12u1
# 120.0.6099.224-1~deb11u1 -> 2024-02-01
# 128.0.6613.113-1~deb12u1-> 2024-08-30
ARG CHROMIUM_VERSION=128.0.6613.113-1~deb12u1
RUN curl -o chromium-common.deb https://ftp.debian.org/debian/pool/main/c/chromium/chromium-common_${CHROMIUM_VERSION}_$(dpkg --print-architecture).deb
RUN curl -o chromium.deb https://ftp.debian.org/debian/pool/main/c/chromium/chromium_${CHROMIUM_VERSION}_$(dpkg --print-architecture).deb
RUN apt-get install -y ./chromium-common.deb ./chromium.deb build-essential git libssl-dev
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Injectable } from "@angular/core";
import { NumberDatatype } from "../number.datatype";

/** Datatype for percentage values */
@Injectable()
export class PercentageDatatype extends NumberDatatype {
static override dataType = "percentage";
static override label: string = $localize`:datatype-label:Percentage`;

override viewComponent = "DisplayPercentage";
override editComponent = "EditNumber";
}
7 changes: 2 additions & 5 deletions src/app/core/config/config-fix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1018,9 +1018,8 @@ export const defaultJsonConfig = {
label: $localize`:Label for the remarks about a dropout of a child:Dropout remarks`,
},
photo: {
dataType: "file",
dataType: "photo",
label: $localize`:Label for the file field of a photo of a child:Photo`,
editComponent: "EditPhoto",
},
phone: {
dataType: "string",
Expand Down Expand Up @@ -1301,10 +1300,8 @@ export const defaultJsonConfig = {
anonymize: "retain",
},
result: {
dataType: "number",
dataType: "percentage",
label: $localize`:Label for the percentage result of a relation:Result`,
viewComponent: "DisplayPercentage",
editComponent: "EditNumber",
validators: {
min: 0,
max: 100,
Expand Down
85 changes: 85 additions & 0 deletions src/app/core/config/config.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,4 +550,89 @@ describe("ConfigService", () => {
const actualFromNew = service.getConfig("view:X");
expect(actualFromNew).toEqual(newFormat);
}));

it("should migrate to new photo dataType", fakeAsync(() => {
const config = new Config();
const oldFormat = {
attributes: {
myPhoto: {
dataType: "file",
editComponent: "EditPhoto",
label: "My Photo",
},
simpleFile: {
dataType: "file",
label: "Simple File attachment",
},
},
};

const newFormat: EntityConfig = {
attributes: {
myPhoto: {
dataType: "photo",
label: "My Photo",
},
simpleFile: {
dataType: "file",
label: "Simple File attachment",
},
},
};

config.data = { "entity:X": oldFormat };
updateSubject.next({ entity: config, type: "update" });
tick();
const actualFromOld = service.getConfig<EntityConfig>("entity:X");
expect(actualFromOld).toEqual(newFormat);

config.data = { "entity:X": newFormat };
updateSubject.next({ entity: config, type: "update" });
tick();
const actualFromNew = service.getConfig<EntityConfig>("entity:X");
expect(actualFromNew).toEqual(newFormat);
}));

it("should migrate to Percentage dataType", fakeAsync(() => {
const config = new Config();
const oldFormat = {
attributes: {
myPercentage: {
dataType: "number",
viewComponent: "DisplayPercentage",
editComponent: "EditNumber",
label: "My Percentage",
},
simpleNumber: {
dataType: "number",
label: "Simple Number",
},
},
};

const newFormat: EntityConfig = {
attributes: {
myPercentage: {
dataType: "percentage",
label: "My Percentage",
},
simpleNumber: {
dataType: "number",
label: "Simple Number",
},
},
};

config.data = { "entity:X": oldFormat };
updateSubject.next({ entity: config, type: "update" });
tick();
const actualFromOld = service.getConfig<EntityConfig>("entity:X");
expect(actualFromOld).toEqual(newFormat);

config.data = { "entity:X": newFormat };
updateSubject.next({ entity: config, type: "update" });
tick();
const actualFromNew = service.getConfig<EntityConfig>("entity:X");
expect(actualFromNew).toEqual(newFormat);
}));
});
28 changes: 28 additions & 0 deletions src/app/core/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export class ConfigService extends LatestEntityLoader<Config> {
migrateEntitySchemaDefaultValue,
migrateChildrenListConfig,
migrateHistoricalDataComponent,
migratePhotoDatatype,
migratePercentageDatatype,
];

// TODO: execute this on server via ndb-admin
Expand Down Expand Up @@ -259,6 +261,32 @@ const migrateEntityArrayDatatype: ConfigMigration = (key, configPart) => {
return configPart;
};

/** Migrate the "file" datatype to use the new "photo" datatype and remove editComponent if no longer needed */
const migratePhotoDatatype: ConfigMigration = (key, configPart) => {
if (
configPart?.dataType === "file" &&
configPart?.editComponent === "EditPhoto"
) {
configPart.dataType = "photo";
delete configPart.editComponent;
}
return configPart;
};

/** Migrate the number datatype to use the new "percentage" datatype */
const migratePercentageDatatype: ConfigMigration = (key, configPart) => {
if (
configPart?.dataType === "number" &&
configPart?.viewComponent === "DisplayPercentage"
) {
configPart.dataType = "percentage";
delete configPart.viewComponent;
delete configPart.editComponent;
}

return configPart;
};

const migrateEntitySchemaDefaultValue: ConfigMigration = (
key: string,
configPart: any,
Expand Down
2 changes: 2 additions & 0 deletions src/app/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { LongTextDatatype } from "./basic-datatypes/string/long-text.datatype";
import { UpdateMetadataDatatype } from "./entity/model/update-metadata.datatype";
import { CurrentUserSubject } from "./session/current-user-subject";
import { SessionSubject } from "./session/auth/session-info";
import { PercentageDatatype } from "./basic-datatypes/number/display-percentage/percentage.datatype";

/**
* Core module registering basic parts like datatypes and components.
Expand All @@ -37,6 +38,7 @@ import { SessionSubject } from "./session/auth/session-info";
{ provide: DefaultDatatype, useClass: MonthDatatype, multi: true },
{ provide: DefaultDatatype, useClass: DateDatatype, multi: true },
{ provide: DefaultDatatype, useClass: EntityDatatype, multi: true },
{ provide: DefaultDatatype, useClass: PercentageDatatype, multi: true },
],
imports: [CommonModule],
})
Expand Down
2 changes: 2 additions & 0 deletions src/app/features/file/file.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ComponentRegistry } from "../../dynamic-components";
import { fileComponents } from "./file-components";
import { DefaultDatatype } from "../../core/entity/default-datatype/default.datatype";
import { FileDatatype } from "./file.datatype";
import { PhotoDatatype } from "./photo.datatype";

@NgModule({
providers: [
Expand All @@ -20,6 +21,7 @@ import { FileDatatype } from "./file.datatype";
: injector.get(MockFileService);
}),
{ provide: DefaultDatatype, useClass: FileDatatype, multi: true },
{ provide: DefaultDatatype, useClass: PhotoDatatype, multi: true },
],
})
export class FileModule {
Expand Down
11 changes: 11 additions & 0 deletions src/app/features/file/photo.datatype.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable } from "@angular/core";
import { FileDatatype } from "./file.datatype";

/** Datatype for saving a photo on an entity property.*/
@Injectable()
export class PhotoDatatype extends FileDatatype {
static override dataType = "photo";
static override label: string = $localize`:datatype-label:profile photo`;

override editComponent = "EditPhoto";
}

0 comments on commit 482feae

Please sign in to comment.