Skip to content

Commit

Permalink
Merge branch 'master' into feat/app-config-header-footer-props
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismclarke authored Dec 20, 2024
2 parents 23421bf + a18985e commit 7c105b2
Show file tree
Hide file tree
Showing 23 changed files with 251 additions and 135 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@
"@angular/platform-browser-dynamic": "~17.2.2",
"@angular/router": "~17.2.2",
"@capacitor-community/file-opener": "^6.0.0",
"@capacitor-firebase/authentication": "^6.1.0",
"@capacitor-firebase/crashlytics": "^6.1.0",
"@capacitor-firebase/performance": "^6.1.0",
"@capacitor-firebase/authentication": "^6.3.1",
"@capacitor-firebase/crashlytics": "^6.3.1",
"@capacitor-firebase/performance": "^6.3.1",
"@capacitor/android": "^6.0.0",
"@capacitor/app": "^6.0.0",
"@capacitor/clipboard": "^6.0.0",
Expand Down
9 changes: 5 additions & 4 deletions packages/data-models/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,11 @@ const APP_SIDEMENU_DEFAULTS = {
should_show_deployment_name: false,
};

const APP_AUTHENTICATION_DEFAULTS = {
enforceLogin: false,
signInTemplate: "sign_in",
};
/**
* @deprecated 0.18.0
* Use `deployment.auth` to configure auth
*/
const APP_AUTHENTICATION_DEFAULTS = {};

type IAppLaunchAction = {
type: "template_popup" | "tour_start";
Expand Down
15 changes: 9 additions & 6 deletions packages/data-models/deployment.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { IGdriveEntry } from "../@idemsInternational/gdrive-tools";
import type { IAppConfig, IAppConfigOverride } from "./appConfig";

/** Update version to force recompile next time deployment set (e.g. after default config update) */
export const DEPLOYMENT_CONFIG_VERSION = 20241111.0;
export const DEPLOYMENT_CONFIG_VERSION = 20241215.1;

/** Configuration settings available to runtime application */
export interface IDeploymentRuntimeConfig {
Expand Down Expand Up @@ -36,6 +36,13 @@ export interface IDeploymentRuntimeConfig {
/** sentry/glitchtip logging dsn */
dsn: string;
};
/** Enable auth actions by specifying auth provider */
auth: {
/** provider to use with authentication actions. actions will be disabled if no provider specified */
provider?: "firebase" | "supabase";
/** prevent user accessing app pages without being logged in. Specified template will be shown until logged in */
enforceLoginTemplate?: string;
};
/**
* Specify if using firebase for auth and crashlytics.
* Requires firebase config available through encrypted config */
Expand All @@ -51,10 +58,6 @@ export interface IDeploymentRuntimeConfig {
appId: string;
measurementId: string;
};
auth: {
/** Enables `auth` actions to allow user sign-in/out */
enabled: boolean;
};
crashlytics: {
/** Enables app crash reports to firebase crashlytics */
enabled: boolean;
Expand Down Expand Up @@ -200,9 +203,9 @@ export const DEPLOYMENT_RUNTIME_CONFIG_DEFAULTS: IDeploymentRuntimeConfig = {
endpoint: "https://apps-server.idems.international/analytics",
},
app_config: {},
auth: {},
firebase: {
config: null,
auth: { enabled: false },
crashlytics: { enabled: true },
},
supabase: {
Expand Down
3 changes: 2 additions & 1 deletion packages/scripts/src/tasks/providers/appData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const copyDeploymentDataToApp = async () => {
const optimiseBuild = async () => new AppDataOptimiser(WorkflowRunner.config).run();

function generateRuntimeConfig(deploymentConfig: IDeploymentConfigJson): IDeploymentRuntimeConfig {
const { analytics, api, app_config, error_logging, firebase, git, name, supabase, web } =
const { analytics, api, app_config, auth, error_logging, firebase, git, name, supabase, web } =
deploymentConfig;

return {
Expand All @@ -77,6 +77,7 @@ function generateRuntimeConfig(deploymentConfig: IDeploymentConfigJson): IDeploy
analytics,
api,
app_config,
auth,
error_logging,
firebase,
name,
Expand Down
26 changes: 0 additions & 26 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ export class AppComponent {
public templateTranslateService: TemplateTranslateService,
private crashlyticsService: CrashlyticsService,
private appDataService: AppDataService,
private authService: AuthService,
private seoService: SeoService,
private taskService: TaskService,
private feedbackService: FeedbackService,
Expand All @@ -135,7 +134,6 @@ export class AppComponent {
this.hackSetDeveloperOptions();
const isDeveloperMode = this.templateFieldService.getField("user_mode") === false;
const user = this.userMetaService.userMeta;
await this.loadAuthConfig();

if (!user.first_app_open) {
await this.userMetaService.setUserMeta({ first_app_open: new Date().toISOString() });
Expand Down Expand Up @@ -174,29 +172,6 @@ export class AppComponent {
}
}

/**
* Authentication requires verified domain and app ids populated to firebase console
* Currently only run on native where specified (but can comment out for testing locally)
*/
private async loadAuthConfig() {
const { firebase } = this.deploymentService.config;
const { enforceLogin, signInTemplate } =
this.appConfigService.appConfig().APP_AUTHENTICATION_DEFAULTS;
const ensureLogin = firebase.config && enforceLogin && Capacitor.isNativePlatform();
if (ensureLogin) {
this.authService.ready();
const authUser = await this.authService.getCurrentUser();
if (!authUser) {
const { modal } = await this.templateService.runStandaloneTemplate(signInTemplate, {
showCloseButton: false,
waitForDismiss: false,
});
await this.authService.waitForSignInComplete();
await modal.dismiss();
}
}
}

/**
* Various services set core app data which may be used in templates such as current app day,
* user id etc. Make sure these services have run their initialisation logic before proceeding.
Expand Down Expand Up @@ -241,7 +216,6 @@ export class AppComponent {
this.templateService,
this.templateProcessService,
this.appDataService,
this.authService,
this.serverService,
this.seoService,
this.feedbackService,
Expand Down
4 changes: 2 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ export function lottiePlayerFactory() {
BrowserAnimationsModule,
IonicModule.forRoot(),
AppRoutingModule,
TemplateComponentsModule,
DeploymentFeaturesModule,
HttpClientModule,
SharedModule,
FormsModule,
LottieModule.forRoot({ player: lottiePlayerFactory }),
// NOTE CC 2021-11-04 not sure if cache causes issues or not https://github.com/ngx-lottie/ngx-lottie/issues/115
// LottieCacheModule.forRoot(),
TemplateComponentsModule,
TourModule,
ContextMenuModule,
DeploymentFeaturesModule,
],
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
Expand Down
3 changes: 2 additions & 1 deletion src/app/deployment-features.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NgModule } from "@angular/core";

import { AnalyticsModule } from "./shared/services/analytics";
import { NavStackModule } from "./feature/nav-stack/nav-stack.module";
import { AuthModule } from "./shared/services/auth/auth.module";

/**
* Module imports required for specific deployment features
Expand All @@ -14,5 +15,5 @@ import { NavStackModule } from "./feature/nav-stack/nav-stack.module";
*
* This is a feature marked for future implementation
*/
@NgModule({ imports: [AnalyticsModule, NavStackModule] })
@NgModule({ imports: [AuthModule, AnalyticsModule, NavStackModule] })
export class DeploymentFeaturesModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div
class="container-radio"
[class.checked-radio]="form.get('answer').value === radio.name"
*ngFor="let radio of valuesFromListAnswers"
*ngFor="let radio of answerOptions()"
>
<label>
<input
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Component, Input, OnInit } from "@angular/core";
import { Component, input, Input, OnInit } from "@angular/core";
import { FlowTypes } from "src/app/shared/model";
import {
getAnswerListParamFromTemplateRow,
getBooleanParamFromTemplateRow,
getNumberParamFromTemplateRow,
getStringParamFromTemplateRow,
Expand All @@ -16,8 +15,8 @@ import { ModalController } from "@ionic/angular";
styleUrls: ["./combo-box-modal.component.scss"],
})
export class ComboBoxModalComponent implements OnInit {
public answerOptions = input.required<IAnswerListItem[]>();
@Input() row: FlowTypes.TemplateRow;
@Input() template: FlowTypes.Template;
@Input() selectedValue: string;
@Input() customAnswerSelected: boolean;
@Input() style: string;
Expand All @@ -29,15 +28,17 @@ export class ComboBoxModalComponent implements OnInit {
inputPosition: boolean = false;
maxLength: number = 30;
placeholder: string = "";
constructor(private fb: FormBuilder, private modalController: ModalController) {}
constructor(
private fb: FormBuilder,
private modalController: ModalController
) {}

ngOnInit() {
this.getParams();
this.calculateAnswer();
}

getParams() {
this.valuesFromListAnswers = getAnswerListParamFromTemplateRow(this.row, "answer_list", null);
this.textTitle = getStringParamFromTemplateRow(this.row, "text", null);
this.inputAllowed = getBooleanParamFromTemplateRow(this.row, "input_allowed", false);
this.inputPosition =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, Input, OnDestroy, OnInit } from "@angular/core";
import { FlowTypes } from "../../../../model";
import { Component, computed, OnDestroy, OnInit } from "@angular/core";
import { ModalController } from "@ionic/angular";
import { ComboBoxModalComponent } from "./combo-box-modal/combo-box-modal.component";
import {
Expand All @@ -10,8 +9,9 @@ import {
} from "src/app/shared/utils";
import { TemplateBaseComponent } from "../base";
import { ITemplateRowProps } from "../../models";
import { TemplateService } from "../../services/template.service";
import { ReplaySubject } from "rxjs";
import { ReplaySubject, map, filter, switchMap } from "rxjs";
import { DataItemsService } from "../data-items/data-items.service";
import { toObservable, toSignal } from "@angular/core/rxjs-interop";

@Component({
selector: "plh-combo-box",
Expand All @@ -22,19 +22,34 @@ export class TmplComboBoxComponent
extends TemplateBaseComponent
implements ITemplateRowProps, OnInit, OnDestroy
{
@Input() template: FlowTypes.Template;
placeholder: string;
prioritisePlaceholder: boolean;
style: string;
text = "";
customAnswerSelected: boolean = false;
customAnswerText: string;
answerList: IAnswerListItem[];
public placeholder: string;
public prioritisePlaceholder: boolean;
private style: string;
public text = "";
private customAnswerSelected: boolean = false;
private customAnswerText: string;
private componentDestroyed$ = new ReplaySubject(1);

// HACK - allow combo_box to include data_items child row to define answer list
private dataItemRows = toSignal(
toObservable(this.rows).pipe(
map((rows) => rows.find((r) => r.type === "data_items")),
filter((row) => row !== undefined),
switchMap((row) => this.dataItemsService.getItemsObservable(row, this.parent.templateRowMap))
)
);

private answerOptions = computed(() => {
const dataItemRows = this.dataItemRows();
if (dataItemRows !== undefined) {
return (dataItemRows as IAnswerListItem[]) || [];
}
return getAnswerListParamFromTemplateRow(this.rowSignal(), "answer_list", []);
});

constructor(
private modalController: ModalController,
private templateService: TemplateService
private dataItemsService: DataItemsService
) {
super();
}
Expand All @@ -43,15 +58,16 @@ export class TmplComboBoxComponent
this.getParams();

this.customAnswerSelected =
this.answerList.length > 0 && this._row.value
? !this.answerList.find((x) => x.name === this._row.value)
this.answerOptions().length > 0 && this._row.value
? !this.answerOptions().find((x) => x.name === this._row.value)
: false;

this.text = "";
if (this._row.value) {
this.text = this.customAnswerSelected
? this.customAnswerText
: this.answerList.find((answerListItem) => answerListItem.name === this._row.value)?.text;
: this.answerOptions().find((answerListItem) => answerListItem.name === this._row.value)
?.text;
}
}

Expand All @@ -63,16 +79,15 @@ export class TmplComboBoxComponent
false
);
this.style = getStringParamFromTemplateRow(this._row, "style", "");
this.answerList = getAnswerListParamFromTemplateRow(this._row, "answer_list", []);
}

async openModal() {
const modal = await this.modalController.create({
component: ComboBoxModalComponent,
cssClass: "combo-box-modal",
componentProps: {
answerOptions: this.answerOptions,
row: this._row,
template: this.template,
selectedValue: this.customAnswerSelected ? this.text : this._row.value,
customAnswerSelected: this.customAnswerSelected,
style: this.style,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export class DataItemsService {
const parsedItemList = await this.hackParseDataList(data);
const itemProcessor = new ItemProcessor(parsedItemList, parameter_list);
const { itemTemplateRows, itemData } = itemProcessor.process(rows);
// if no child rows for data_items loop assume want back raw items
if (rows.length === 0) {
return itemData;
}
// otherwise process generated template rows
const itemRowsWithMeta = updateItemMeta(itemTemplateRows, itemData, dataListName);
const parsedItemRows = await this.hackProcessRows(
itemRowsWithMeta,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class="popup-backdrop"
(click)="dismissOnBackdrop($event)"
[attr.data-fullscreen]="props.fullscreen ? true : null"
[dir]="templateTranslateService.languageDirection()"
[attr.data-variant]="props.variant ? props.variant : null"
>
<div class="popup-container">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Input } from "@angular/core";
import { ModalController } from "@ionic/angular";
import { FlowTypes } from "../../../models";
import { TemplateContainerComponent } from "../../../template-container.component";
import { TemplateTranslateService } from "../../../services/template-translate.service";

@Component({
templateUrl: "./popup.component.html",
Expand All @@ -14,7 +15,12 @@ import { TemplateContainerComponent } from "../../../template-container.componen
export class TemplatePopupComponent {
@Input() props: ITemplatePopupComponentProps;

constructor(private modalCtrl: ModalController) {}
constructor(
private modalCtrl: ModalController,
// HACK: Since pop-ups can be launched outside of main app container (e.g. as part of launch actions),
// handle RTL language support directly in this component
public templateTranslateService: TemplateTranslateService
) {}

/**
* When templates emit completed/uncompleted value from standalone popup close the popup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { TemplateService } from "../template.service";
import { TemplateTranslateService } from "../template-translate.service";
import { EventService } from "src/app/shared/services/event/event.service";
import { DBSyncService } from "src/app/shared/services/db/db-sync.service";
import { AuthService } from "src/app/shared/services/auth/auth.service";
import { SkinService } from "src/app/shared/services/skin/skin.service";
import { ThemeService } from "src/app/feature/theme/services/theme.service";
import { getGlobalService } from "src/app/shared/services/global.service";
Expand Down Expand Up @@ -65,9 +64,6 @@ export class TemplateActionService extends SyncServiceBase {
private get dbSyncService() {
return getGlobalService(this.injector, DBSyncService);
}
private get authService() {
return getGlobalService(this.injector, AuthService);
}
private get skinService() {
return getGlobalService(this.injector, SkinService);
}
Expand All @@ -93,7 +89,6 @@ export class TemplateActionService extends SyncServiceBase {
this.analyticsService,
this.templateService,
this.eventService,
this.authService,
this.skinService,
]);
}
Expand Down
Loading

0 comments on commit 7c105b2

Please sign in to comment.