Skip to content

Commit

Permalink
Merge branch 'master' into feat/sticky-display-group
Browse files Browse the repository at this point in the history
  • Loading branch information
jfmcquade authored Dec 2, 2024
2 parents 9fd016c + 6662b2a commit 36ad01c
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 106 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/reusable-android-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ env:
PARENT_DEPLOYMENT_NAME: ${{vars.PARENT_DEPLOYMENT_NAME}}
PARENT_DEPLOYMENT_BRANCH: ${{vars.PARENT_DEPLOYMENT_BRANCH}}
GOOGLE_SERVICES_JSON: ${{secrets.GOOGLE_SERVICES_JSON}}
DEPLOYMENT_PRIVATE_KEY: ${{secrets.DEPLOYMENT_PRIVATE_KEY}}
SIGNING_KEY: ${{secrets.SIGNING_KEY}}
ALIAS: ${{secrets.ALIAS}}
KEY_STORE_PASSWORD: ${{secrets.KEY_STORE_PASSWORD}}
Expand Down Expand Up @@ -74,6 +75,10 @@ jobs:
with:
path: ".idems_app/deployments/${{env.DEPLOYMENT_NAME}}"

- name: Populate Encryption key
if: env.DEPLOYMENT_PRIVATE_KEY != ''
run: echo "${{env.DEPLOYMENT_PRIVATE_KEY}}" > ./.idems_app/deployments/${{env.DEPLOYMENT_NAME}}/encrypted/private.key

- name: Populate google-services.json
env:
GOOGLE_SERVICES_JSON: ${{ env.GOOGLE_SERVICES_JSON }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/reusable-content-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
# git checkout -b automated-changes

- name: Create Pull Request
uses: peter-evans/create-pull-request@v5.0.2
uses: peter-evans/create-pull-request@v7.0.5
with:
token: ${{ env.PAT }}
# Relative path under $GITHUB_WORKSPACE to the repository. Defaults to $GITHUB_WORKSPACE.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe("Template Parser PostProcessor", () => {
});
expect(case4.value).toEqual([
{ key_1a: "textValue", key_1b: "@local.value" },
{ key_2a: "", key_2b: "5" },
{ key_2a: "", key_2b: 5 },
]);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import BaseProcessor from "./base";
import { existsSync } from "fs-extra";
import { IContentsEntry, parseAppDataCollectionString } from "../utils";

const cacheVersion = 20230509.1;
const cacheVersion = 20241118.0;

export class XLSXWorkbookProcessor extends BaseProcessor<IContentsEntry> {
constructor(paths: IConverterPaths) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FlowTypes } from "data-models";
import { setNestedProperty, booleanStringToBoolean } from "../utils";
import { setNestedProperty } from "../utils";
import { parseStringValue } from "shared/src/utils";

/**
* Convert app data map string to object
Expand Down Expand Up @@ -50,9 +51,13 @@ export function parseAppDataCollectionString(
// handle keys that define deeper nesting, such as time.hours: 7
if (key.includes(".")) {
const [base, ...nested] = key.split(".");
collection[base] = setNestedProperty(nested.join("."), value, collection[base]);
collection[base] = setNestedProperty(
nested.join("."),
parseStringValue(value),
collection[base]
);
} else {
collection[key] = booleanStringToBoolean(value);
collection[key] = parseStringValue(value);
}
});
return collection;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input } from "@angular/core";
import { ModalController } from "@ionic/angular";
import { FlowTypes, ITemplateContainerProps } from "../../../models";
import { FlowTypes } from "../../../models";
import { TemplateContainerComponent } from "../../../template-container.component";

@Component({
Expand Down Expand Up @@ -41,11 +41,15 @@ export class TemplatePopupComponent {
}
}

export interface ITemplatePopupComponentProps extends ITemplateContainerProps {
/** Required inputs to pass on to TemplateContainer component */
interface IContainerProps {
name: string;
templatename: string;
parent?: TemplateContainerComponent;
row?: FlowTypes.TemplateRow;
parent?: TemplateContainerComponent;
}

export interface ITemplatePopupComponentProps extends IContainerProps {
showCloseButton?: boolean;
/** Dismiss popup when completed or uncompleted is emitted from child template */
dismissOnEmit?: boolean;
Expand Down
14 changes: 0 additions & 14 deletions src/app/shared/components/template/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,6 @@ import { FlowTypes } from "src/app/shared/model";
import { TemplateContainerComponent } from "../template-container.component";
export { FlowTypes } from "src/app/shared/model";

/**
* Properties passed to a template container instance
* @param templateName - flow_name of template to lookup
* @param name - unique name for the template, in cases where multiple child templates of the same type may exist (e.g. multiple buttons)
* @param row - reference to the full row if template instantiated from a parent
* @param parent - reference to parent template (when nested)
*/
export interface ITemplateContainerProps {
templatename: string;
name: string;
parent?: { name: string; component?: any };
row?: FlowTypes.TemplateRow;
}

/**
* Properties passed to a template row instance
* @param row specific data used in component rendering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Router } from "@angular/router";
import { toSignal } from "@angular/core/rxjs-interop";
import { ngRouterMergedSnapshot$ } from "src/app/shared/utils/angular.utils";
import { isEqual } from "packages/shared/src/utils/object-utils";
import { AppConfigService } from "src/app/shared/services/app-config/app-config.service";

/**
* Service responsible for handling metadata of the current top-level template,
Expand All @@ -26,6 +27,7 @@ export class TemplateMetadataService extends SyncServiceBase {

constructor(
private templateService: TemplateService,
private appConfigService: AppConfigService,
private router: Router
) {
super("TemplateMetadata");
Expand All @@ -42,5 +44,13 @@ export class TemplateMetadataService extends SyncServiceBase {
},
{ allowSignalWrites: true }
);
// apply any template-specific appConfig overrides on change
effect(
() => {
const templateAppConfig = this.parameterList().app_config;
this.appConfigService.setAppConfig(templateAppConfig, "template");
},
{ allowSignalWrites: true }
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
ITemplatePopupComponentProps,
TemplatePopupComponent,
} from "../components/layout/popup/popup.component";
import { ITemplateContainerProps } from "../models";
import { TemplateContainerComponent } from "../template-container.component";

// Toggle logs used across full service for debugging purposes (there's quite a few and tedious to comment)
Expand Down Expand Up @@ -40,7 +39,7 @@ export class TemplateNavService extends SyncServiceBase {
* unless specifically closed (e.g. nav triggered from modal)
*/
private openPopupsByName: {
[templatename: string]: { modal: HTMLIonModalElement; props: ITemplateContainerProps };
[templatename: string]: { modal: HTMLIonModalElement; props: ITemplatePopupComponentProps };
} = {};

public async handleQueryParamChange(
Expand Down
3 changes: 2 additions & 1 deletion src/app/shared/components/template/template-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ export class TemplateComponent implements OnInit, AfterContentInit, ITemplateRow
componentRef.instance.row = row;
componentRef.instance.parent = this.parent;
componentRef.instance.name = row.name;
componentRef.instance.templatename = row.value;
// assign templatename input using signal
componentRef.setInput("templatename", row.value);
this.componentRef = componentRef;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<ng-template [ngIf]="debugMode && !parent" [ngIfElse]="noDebugger">
<!-- Debugger Mode -->
<div class="debug-name">
<div>template: {{ templatename || "(undefined)" }}</div>
<div>template: {{ templatename() || "(undefined)" }}</div>
<div>name: {{ name || "(undefined)" }}</div>
</div>
<!-- Template Component-->
Expand Down
29 changes: 18 additions & 11 deletions src/app/shared/components/template/template-container.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
ChangeDetectorRef,
Component,
effect,
ElementRef,
EventEmitter,
HostBinding,
Injector,
input,
Input,
OnDestroy,
OnInit,
Expand All @@ -13,7 +15,7 @@ import {
import { ActivatedRoute } from "@angular/router";
import { takeUntil } from "rxjs/operators";
import { Subject } from "rxjs";
import { FlowTypes, ITemplateContainerProps } from "./models";
import { FlowTypes } from "./models";
import { TemplateActionService } from "./services/instance/template-action.service";
import { TemplateNavService } from "./services/template-nav.service";
import { TemplateRowService } from "./services/instance/template-row.service";
Expand All @@ -37,12 +39,14 @@ let log_groupEnd = SHOW_DEBUG_LOGS ? console.groupEnd : () => null;
* - Track dynamic variable dependency (to know when to trigger row change based on set_local/field/global events)
* - Consider case of template container re-render (some draft cached code exists, but not sure if this is a valid use-case or not)
*/
export class TemplateContainerComponent implements OnInit, OnDestroy, ITemplateContainerProps {
export class TemplateContainerComponent implements OnInit, OnDestroy {
/** unique instance_name of template if created as a child of another template */
@Input() name: string;
/** flow_name of template for lookup */
@Input() templatename: string;
templatename = input.required<string>();
/** reference to parent template (when nested) */
@Input() parent?: TemplateContainerComponent;
/** reference to the full row if template instantiated from a parent */
@Input() row?: FlowTypes.TemplateRow;
/** Allow parents to also see emitted value (note - currently responding to emit is done in service, not output bindings except for ) */
@Output() emittedValue = new EventEmitter<{ emit_value: string; emit_data: any }>();
Expand Down Expand Up @@ -73,13 +77,17 @@ export class TemplateContainerComponent implements OnInit, OnDestroy, ITemplateC
public elRef?: ElementRef,
private route?: ActivatedRoute
) {
effect(() => {
// re-render template whenever input template name changes
const templatename = this.templatename();
this.hostTemplateName = templatename;
this.renderTemplate(templatename);
});
this.templateActionService = new TemplateActionService(injector, this);
this.templateRowService = new TemplateRowService(injector, this);
}
/** Assign the templatename as metdaata on the component for easier debugging and testing */
@HostBinding("attr.data-templatename") get getTemplatename() {
return this.templatename;
}
@HostBinding("attr.data-templatename") public hostTemplateName: string;

async ngOnInit() {
if (!this.ignoreQueryParamChanges) {
Expand All @@ -90,7 +98,6 @@ export class TemplateContainerComponent implements OnInit, OnDestroy, ITemplateC
this.setLogging(true);
this.templateRowService.setLogging(true);
}
await this.renderTemplate();
}

ngOnDestroy(): void {
Expand Down Expand Up @@ -136,7 +143,7 @@ export class TemplateContainerComponent implements OnInit, OnDestroy, ITemplateC
this.templateRowService.renderedRows = [];
// allow time for other pending ops to finish
await _wait(50);
await this.renderTemplate();
await this.renderTemplate(this.templatename());
} else {
await this.templateRowService.processRowUpdates();
console.log("[Force Reprocess]", this.name, this.templateRowService.renderedRows);
Expand Down Expand Up @@ -174,13 +181,13 @@ export class TemplateContainerComponent implements OnInit, OnDestroy, ITemplateC
* Template Initialisation
**************************************************************************************/

private async renderTemplate() {
private async renderTemplate(templatename: string) {
// Lookup template
const template = await this.templateService.getTemplateByName(
this.templatename,
templatename,
this.row?.is_override_target
);
this.name = this.name || this.templatename;
this.name = this.name || templatename;
this.templateBreadcrumbs = [...(this.parent?.templateBreadcrumbs || []), this.name];
this.template = template;
log_group("[Template Render Start]", this.name);
Expand Down
50 changes: 34 additions & 16 deletions src/app/shared/services/app-config/app-config.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ import { TestBed } from "@angular/core/testing";
import { AppConfigService } from "./app-config.service";
import { BehaviorSubject } from "rxjs/internal/BehaviorSubject";
import { IAppConfig } from "../../model";
import { signal } from "@angular/core";
import { signal, WritableSignal } from "@angular/core";
import { DeploymentService } from "../deployment/deployment.service";
import {
getDefaultAppConfig,
IAppConfigOverride,
IDeploymentRuntimeConfig,
} from "packages/data-models";
import { IAppConfigOverride, IDeploymentRuntimeConfig } from "packages/data-models";
import { deepMergeObjects } from "../../utils";
import { firstValueFrom } from "rxjs/internal/firstValueFrom";
import { MockDeploymentService } from "../deployment/deployment.service.spec";
Expand Down Expand Up @@ -46,6 +42,7 @@ const MOCK_DEPLOYMENT_CONFIG: Partial<IDeploymentRuntimeConfig> = {
*/
describe("AppConfigService", () => {
let service: AppConfigService;
let appConfigSetSpy: jasmine.Spy<WritableSignal<IAppConfig>>;

beforeEach(() => {
TestBed.configureTestingModule({
Expand All @@ -54,24 +51,20 @@ describe("AppConfigService", () => {
],
});
service = TestBed.inject(AppConfigService);
appConfigSetSpy = spyOn(service.appConfig, "set").and.callThrough();
});

it("applies default config overrides on init", () => {
expect(service.appConfig().APP_HEADER_DEFAULTS.title).toEqual(
getDefaultAppConfig().APP_HEADER_DEFAULTS.title
);
expect(service.appConfig().APP_HEADER_DEFAULTS.title).toEqual("App");
});

it("applies deployment-specific config overrides on init", () => {
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("mock_footer");
});

it("applies overrides to app config", () => {
service.setAppConfig({ APP_HEADER_DEFAULTS: { title: "updated" } });
expect(service.appConfig().APP_HEADER_DEFAULTS).toEqual({
...getDefaultAppConfig().APP_HEADER_DEFAULTS,
title: "updated",
});
it("applies skin-level overrides to app config", () => {
service.setAppConfig({ APP_HEADER_DEFAULTS: { title: "updated" } }, "skin");
expect(service.appConfig().APP_HEADER_DEFAULTS.title).toEqual("updated");
// also ensure doesn't unset default deployment
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("mock_footer");
});
Expand All @@ -80,7 +73,32 @@ describe("AppConfigService", () => {
firstValueFrom(service.changes$).then((v) => {
expect(v).toEqual({ APP_HEADER_DEFAULTS: { title: "partial changes" } });
});
service.setAppConfig({ APP_HEADER_DEFAULTS: { title: "partial changes" } }, "skin");
expect(appConfigSetSpy).toHaveBeenCalledTimes(1);
});

it("ignores lower-order updates when higher order exists", async () => {
service.setAppConfig({ APP_FOOTER_DEFAULTS: { templateName: "template_footer" } }, "template");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("template_footer");
service.setAppConfig({ APP_FOOTER_DEFAULTS: { templateName: "skin_footer" } }, "skin");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("template_footer");
// the second service set should not trigger any changes to appConfig signal (or observable)
expect(appConfigSetSpy).toHaveBeenCalledTimes(1);
});

it("reverts to initial config values when all overrides removed", async () => {
service.setAppConfig({ APP_FOOTER_DEFAULTS: { templateName: "template_footer" } }, "template");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("template_footer");
service.setAppConfig({}, "template");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("mock_footer");
});

service.setAppConfig({ APP_HEADER_DEFAULTS: { title: "partial changes" } });
it("reverts to lower order config values when higher order override removed", async () => {
service.setAppConfig({ APP_FOOTER_DEFAULTS: { templateName: "skin_footer" } }, "skin");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("skin_footer");
service.setAppConfig({ APP_FOOTER_DEFAULTS: { templateName: "template_footer" } }, "template");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("template_footer");
service.setAppConfig({}, "template");
expect(service.appConfig().APP_FOOTER_DEFAULTS.templateName).toEqual("skin_footer");
});
});
Loading

0 comments on commit 36ad01c

Please sign in to comment.