cv-dialog-sdk
Version:
Catavolt Dialog Javascript API
347 lines (295 loc) • 17 kB
text/typescript
import {DialogProxyTools} from "../proxy/DialogProxyTools";
import {DialogRequest} from "../proxy/DialogRequest";
import {RecordSetVisitor} from "../proxy/RecordSetVisitor";
import {RecordVisitor} from "../proxy/RecordVisitor";
import {SessionVisitor} from "../proxy/SessionVisitor";
import {storage as clientStorage} from "../storage";
import {Log} from "../util/Log";
import {StringDictionary} from "../util/StringDictionary";
import {BriefcaseVisitor} from "./BriefcaseVisitor";
import {Briefcase_Briefcase_Details_RECORD} from "./samples/Briefcase_Briefcase_Details_RECORD";
import {SdaDialogDelegateStateVisitor} from "./SdaDialogDelegateStateVisitor";
// @FIX_THIS
// remove this:
const storage = clientStorage;
// uncomment this
// const storage = clientStorage.getSecureInstance();
// Set the secret key like this:
// storage.secretKey = 'secret_key';
export class SdaDialogDelegateTools {
// Briefcase Dialog Ids
public static BRIEFCASE_ROOT_DIALOG_ID = 'briefcase';
public static BRIEFCASE_COMMENTS_DIALOG_ID = SdaDialogDelegateTools.BRIEFCASE_ROOT_DIALOG_ID + '_comments';
public static BRIEFCASE_DETAILS_DIALOG_ID = SdaDialogDelegateTools.BRIEFCASE_ROOT_DIALOG_ID + '_details';
public static BRIEFCASE_WORK_PACKAGES_DIALOG_ID = SdaDialogDelegateTools.BRIEFCASE_ROOT_DIALOG_ID + '_workPackages';
public static BRIEFCASE_ENTER_OFFLINE_DETAILS_DIALOG_ID = SdaDialogDelegateTools.BRIEFCASE_ROOT_DIALOG_ID + '_enter_offline_details';
public static BRIEFCASE_ENTER_OFFLINE_ROOT_DIALOG_ID = SdaDialogDelegateTools.BRIEFCASE_ROOT_DIALOG_ID + '_enter_offline';
// Dialog Names
public static BRIEFCASE_DETAILS_DIALOG_NAME = 'Briefcase_Briefcase_Details';
public static BRIEFCASE_MOBILE_COMMENTS_DIALOG_NAME = 'Briefcase_Briefcase_MobileComments';
public static BRIEFCASE_ROOT_DIALOG_NAME = 'Briefcase_Briefcase_FORM';
public static BRIEFCASE_WORK_PACKAGES_DIALOG_NAME = 'Briefcase_Briefcase_Workpackages';
public static BRIEFCASE_ENTER_OFFLINE_DETAILS_DIALOG_NAME = 'Briefcase_EnterOfflineMode';
public static DOCUMENTS_LIST_DIALOG_NAME = 'Workpackage_Documents_Documents';
public static DOCUMENTS_PROPERTIES_DIALOG_NAME = 'Workpackage_Documents_Properties';
public static DOCUMENTS_ROOT_DIALOG_NAME = 'Workpackage_Documents_FORM';
public static MOBILE_COMMENT_DETAILS_PROPERTIES_DIALOG_NAME = 'MobileComment_Details_Properties';
public static MOBILE_COMMENT_DETAILS_ROOT_DIALOG_NAME = 'MobileComment_Details_FORM';
public static MOBILE_COMMENT_IMAGE_NOT_AVAILABLE_DETAILS_DIALOG_ID = 'image_not_available_details';
public static MOBILE_COMMENT_IMAGE_NOT_AVAILABLE_DETAILS_DIALOG_NAME = 'MobileComment_ImageNotAvailable';
public static MOBILE_COMMENT_IMAGE_NOT_AVAILABLE_ROOT_DIALOG_ID = 'image_not_available';
public static MOBILE_COMMENT_IMAGE_NOT_AVAILABLE_ROOT_DIALOG_NAME = 'MobileComment_ImageNotAvailable_FORM';
public static MOBILE_COMMENT_COMMENT_NOT_AVAILABLE_DETAILS_DIALOG_ID = 'comment_not_available_details';
public static MOBILE_COMMENT_COMMENT_NOT_AVAILABLE_DETAILS_DIALOG_NAME = 'MobileComment_CommentNotAvailable';
public static MOBILE_COMMENT_COMMENT_NOT_AVAILABLE_ROOT_DIALOG_ID = 'comment_not_available';
public static MOBILE_COMMENT_COMMENT_NOT_AVAILABLE_ROOT_DIALOG_NAME = 'MobileComment_CommentNotAvailable_FORM';
public static TAGS_ROOT_DIALOG_NAME = 'Workpackage_Tags_FORM';
public static TAGS_PROPERTIES_DIALOG_NAME = 'Workpackage_Tags_Properties';
public static TAGS_LIST_DIALOG_NAME = 'Workpackage_Tags_Tags';
public static TAG_DETAILS_ROOT_DIALOG_NAME = 'Tag_Details_FORM';
public static TAG_DETAILS_PROPERTIES_DIALOG_NAME = 'Tag_Details_Properties';
public static TAG_DETAILS_LIST_DIALOG_NAME = 'Tag_Details_Documents';
public static WORK_PACKAGES_LIST_DIALOG_NAME = 'Workpackage_General';
public static WORK_PACKAGES_ROOT_DIALOG_NAME = 'Workpackage_General_FORM';
// Dynamic Dialog Ids -- PRIVATE
private static OFFLINE_DOCUMENTS_DIALOG_PROPERTIES_ID_PREFIX = 'offline_documents_properties_';
private static OFFLINE_TAGS_DIALOG_PROPERTIES_ID_PREFIX = 'offline_tags_properties_';
// Action Ids
private static ADD_TO_BRIEFCASE_MENU_ACTION_ID = 'alias_AddToBriefcase';
private static BRIEFCASE_WORKBENCH_ACTION_ID = 'Briefcase';
private static ENTER_OFFLINE_MODE_MENU_ACTION_ID = 'alias_EnterOfflineMode';
private static EXIT_OFFLINE_MODE_MENU_ACTION_ID = 'alias_ExitOfflineMode';
private static REMOVE_FROM_BRIEFCASE_MENU_ACTION_ID = 'alias_RemoveFromBriefcase';
// Model Types
private static EDITOR_DIALOG_MODEL_TYPE = 'hxgn.api.dialog.EditorDialog';
private static RECORD_SET_MODEL_TYPE = 'hxgn.api.dialog.RecordSet';
private static SESSION_ID_MODEL_TYPE = 'hxgn.api.dialog.SessionId';
// Storage Keys
private static DIALOG_DELEGATE_STATE_KEY_SUFFIX = 'SdaDialogDelegate.delegatestate';
private static DIALOG_DELEGATE_STATE_KEY = '${userId}.${tenantId}.' + SdaDialogDelegateTools.DIALOG_DELEGATE_STATE_KEY_SUFFIX;
private static OFFLINE_SESSION_KEY = '${userId}.${tenantId}.offlinesession';
public static constructAddToBriefcaseNullRedirection(tenantId: string, sessionId: string, referringDialogId: string): StringDictionary {
const nullRedirectionId = DialogProxyTools.constructNullRedirectionId();
return {
"tenantId": tenantId,
"referringObject": {
"dialogMode": "LIST",
"dialogAlias": "Workpackage_AddToBriefcase_FORM",
"actionId": "alias_AddToBriefcase",
"type": "hxgn.api.dialog.ReferringDialog",
"dialogId": referringDialogId
},
"refreshNeeded": true,
"sessionId": sessionId,
"id": nullRedirectionId,
"type": "hxgn.api.dialog.NullRedirection"
};
}
public static constructBriefcaseEnterOfflineDetailsNullRedirection(tenantId: string, sessionId: string, refreshNeeded: boolean): StringDictionary {
const nullRedirectionId = DialogProxyTools.constructNullRedirectionId();
// TODO: What should a ReferringDialog contain as an action id when the action is a 'PUT viewMode'?
return {
"tenantId": tenantId,
"referringObject": {
"dialogMode": "DESTROYED",
"dialogName": this.BRIEFCASE_ENTER_OFFLINE_DETAILS_DIALOG_NAME,
"dialogAlias": this.BRIEFCASE_ENTER_OFFLINE_DETAILS_DIALOG_NAME,
"type": "hxgn.api.dialog.ReferringDialog",
"dialogId": this.BRIEFCASE_ENTER_OFFLINE_DETAILS_DIALOG_ID
},
"refreshNeeded": refreshNeeded,
"sessionId": sessionId,
"id": nullRedirectionId,
"type": "hxgn.api.dialog.NullRedirection"
};
}
public static constructExitOfflineModeNullRedirection(tenantId: string, sessionId: string): StringDictionary {
const nullRedirectionId = DialogProxyTools.constructNullRedirectionId();
return {
"tenantId": tenantId,
"referringObject": {
"dialogMode": "READ",
"dialogAlias": "Briefcase_Briefcase_Details",
"actionId": this.EXIT_OFFLINE_MODE_MENU_ACTION_ID,
"type": "hxgn.api.dialog.ReferringDialog",
"dialogId": this.BRIEFCASE_DETAILS_DIALOG_ID
},
"refreshNeeded": true,
"sessionId": sessionId,
"id": nullRedirectionId,
"type": "hxgn.api.dialog.NullRedirection"
};
}
public static constructOfflineLogoutResponse(sessionId: string) {
return {
"sessionId": sessionId,
"type": this.SESSION_ID_MODEL_TYPE
};
}
public static constructRemoveFromBriefcaseNullRedirection(tenantId: string, sessionId: string, referringDialogId: string): StringDictionary {
const nullRedirectionId = DialogProxyTools.constructNullRedirectionId();
return {
"tenantId": tenantId,
"referringObject": {
"dialogMode": "LIST",
"dialogAlias": "Workpackage_RemoveFromBriefcase_FORM",
"actionId": "alias_RemoveFromBriefcase",
"type": "hxgn.api.dialog.ReferringDialog",
"dialogId": referringDialogId
},
"refreshNeeded": true,
"sessionId": sessionId,
"id": nullRedirectionId,
"type": "hxgn.api.dialog.NullRedirection"
};
}
public static createOfflineLoginHash(tenantId: string, sessionId: string, userId: string, password: string): string {
const source =`OFFLINE_LOGIN:${tenantId}/${sessionId}/${userId}/${password}`;
// TODO: insert crypto hashing here
return source;
}
public static isBriefcaseEnterOfflineDetailsDialogId(dialogId: string): boolean {
return dialogId === this.BRIEFCASE_ENTER_OFFLINE_DETAILS_DIALOG_ID;
}
public static isBriefcaseEnterOfflineDialogId(dialogId: string): boolean {
return dialogId === this.BRIEFCASE_ENTER_OFFLINE_ROOT_DIALOG_ID;
}
public static isBriefcaseWorkbenchActionRequest(dialogRequest: DialogRequest): boolean {
return dialogRequest.isPostWorkbenchActionPathWithActionId(SdaDialogDelegateTools.BRIEFCASE_WORKBENCH_ACTION_ID);
}
public static isEnterOfflineModeMenuActionRequest(dialogRequest: DialogRequest): boolean {
return dialogRequest.isPostMenuActionPathWithActionId(SdaDialogDelegateTools.ENTER_OFFLINE_MODE_MENU_ACTION_ID);
}
public static isExitOfflineModeMenuActionRequest(dialogRequest: DialogRequest): boolean {
return dialogRequest.isPostMenuActionPathWithActionId(SdaDialogDelegateTools.EXIT_OFFLINE_MODE_MENU_ACTION_ID);
}
public static isOfflineBriefcaseCommentsRecordSetRequest(dialogRequest: DialogRequest): boolean {
return dialogRequest.isPostRecordsPathWithDialogId(this.BRIEFCASE_COMMENTS_DIALOG_ID);
}
public static isOfflineBriefcaseDialogId(dialogId: string): boolean {
return dialogId === this.BRIEFCASE_ROOT_DIALOG_ID;
}
public static isOfflineBriefcaseDetailsDialogId(dialogId: string): boolean {
return dialogId === this.BRIEFCASE_DETAILS_DIALOG_ID;
}
public static isOfflineBriefcaseWorkPackagesDialogId(dialogId: string): boolean {
return dialogId === this.BRIEFCASE_WORK_PACKAGES_DIALOG_ID;
}
public static isOfflineBriefcaseWorkPackagesRequest(dialogRequest: DialogRequest): boolean {
if (!dialogRequest.isPostRecordsPath()) {
return false;
}
const pathFields = dialogRequest.deconstructPostRecordsPath();
return SdaDialogDelegateTools.isOfflineBriefcaseWorkPackagesDialogId(pathFields.dialogId);
}
public static isOfflineDocumentsPropertiesDialogId(dialogId: string): boolean {
return dialogId.startsWith(this.OFFLINE_DOCUMENTS_DIALOG_PROPERTIES_ID_PREFIX);
}
public static isOfflineTagsPropertiesDialogId(dialogId: string): boolean {
return dialogId.startsWith(this.OFFLINE_TAGS_DIALOG_PROPERTIES_ID_PREFIX);
}
public static isWorkPackagesAddToBriefcaseMenuActionRequest(dialogRequest: DialogRequest): boolean {
return dialogRequest.isPostMenuActionPathWithActionId(SdaDialogDelegateTools.ADD_TO_BRIEFCASE_MENU_ACTION_ID);
}
public static isWorkPackagesListRecordSet(dialogRequest: DialogRequest, jsonObject: any): boolean {
if (!dialogRequest.isPostRecordsPath()) {
return false;
}
if (!jsonObject || !jsonObject.type || !jsonObject.dialogName) {
return false;
}
return jsonObject.type === this.RECORD_SET_MODEL_TYPE &&
jsonObject.dialogName === this.WORK_PACKAGES_LIST_DIALOG_NAME;
}
public static isWorkPackagesRemoveFromBriefcaseMenuActionRequest(dialogRequest: DialogRequest): boolean {
if (!dialogRequest.isPostMenuActionPath()) {
return false;
}
const pathFields = dialogRequest.deconstructPostMenuActionPath();
return pathFields.actionId === SdaDialogDelegateTools.REMOVE_FROM_BRIEFCASE_MENU_ACTION_ID;
}
public static isWorkPackagesRootDialog(jsonObject: any): boolean {
if (!jsonObject || !jsonObject.type || !jsonObject.dialogName) {
return false;
}
return jsonObject.type === this.EDITOR_DIALOG_MODEL_TYPE &&
jsonObject.dialogName === this.WORK_PACKAGES_ROOT_DIALOG_NAME;
}
public static insertBriefcaseMetaDataIntoWorkPackagesDialog(originalDialog: StringDictionary): StringDictionary {
const workPackagesQueryDialog = originalDialog.children[0];
const propertyDefs = workPackagesQueryDialog.recordDef.propertyDefs;
propertyDefs.push({
"writeAllowed": false,
"propertyName": "briefcase",
"canCauseSideEffects": false,
"upperCaseOnly": false,
"propertyType": "boolean",
"type": "hxgn.api.dialog.PropertyDef",
"writeEnabled": false
});
const columns = workPackagesQueryDialog.view.columns;
columns.push({
"propertyName": "briefcase",
"heading": "Briefcase",
"type": "hxgn.api.dialog.Column"
});
// Return original dialog WITH patches
return originalDialog;
}
public static async readDialogDelegateStateKeys(tenantId: string): Promise<string[]> {
const keys: string[] = await storage.getAllKeys();
const dialogDelegateStateKeysForTenant = [];
for (const k of keys) {
if (k.endsWith(this.DIALOG_DELEGATE_STATE_KEY_SUFFIX) && k.includes(`.${tenantId}.`)) {
dialogDelegateStateKeysForTenant.push(k);
}
}
return dialogDelegateStateKeysForTenant;
}
public static readDialogDelegateStateVisitor(tenantId: string, userId: string): Promise<SdaDialogDelegateStateVisitor> {
const key = this.createStorageKey(tenantId, userId, this.DIALOG_DELEGATE_STATE_KEY);
return storage.getJson(key).then(jsonObject => {
if (!jsonObject) {
const briefcase = Briefcase_Briefcase_Details_RECORD.copyOfResponse();
BriefcaseVisitor.visitAndSetOnline(briefcase, true);
jsonObject = {
briefcase: Briefcase_Briefcase_Details_RECORD.copyOfResponse(),
selectedWorkPackageIds: [],
userId: null,
workPackages: RecordSetVisitor.emptyRecordSetVisitor().enclosedJsonObject(),
mobileComments: RecordSetVisitor.emptyRecordSetVisitor().enclosedJsonObject()
};
// // Log.info('SdaDialogDelegateTools::readDelegateState -- returning defaults: ' + JSON.stringify(jsonObject));
}
return new SdaDialogDelegateStateVisitor(jsonObject);
});
}
public static readOfflineDocumentsPropertiesRecord(tenantId: string, userId: string, dialogId: string): Promise<RecordVisitor> {
const key = `${userId}.${tenantId}.ppm.sda.workPackages.documents.dialog.${dialogId}.record`;
return storage.getJson(key).then(jsonObject => new RecordVisitor(jsonObject));
}
public static readOfflineSession(tenantId: string, userId: string): Promise<SessionVisitor> {
const key = this.createStorageKey(tenantId, userId, this.OFFLINE_SESSION_KEY);
return storage.getJson(key).then(jsonObject => new SessionVisitor(jsonObject));
}
public static readOfflineTagsPropertiesRecord(tenantId: string, userId: string, dialogId: string): Promise<RecordVisitor> {
const key = `${userId}.${tenantId}.ppm.sda.workPackages.tags.dialog.${dialogId}.record`;
return storage.getJson(key).then(jsonObject => new RecordVisitor(jsonObject));
}
public static startsWithBriefcaseRootDialogId(dialogId: string): boolean {
return dialogId.startsWith(this.BRIEFCASE_ROOT_DIALOG_ID);
}
public static writeDialogDelegateState(tenantId: string, stateVisitor: SdaDialogDelegateStateVisitor): Promise<void> {
const userId = stateVisitor.visitUserId();
const key = this.createStorageKey(tenantId, userId, this.DIALOG_DELEGATE_STATE_KEY);
return storage.setJson(key, stateVisitor.enclosedJsonObject());
}
public static writeOfflineSession(tenantId: string, userId: string, offlineSessionVisitor: SessionVisitor): Promise<void> {
const key = this.createStorageKey(tenantId, userId, this.OFFLINE_SESSION_KEY);
return storage.setJson(key, offlineSessionVisitor.enclosedJsonObject());
}
private static createStorageKey(tenantId: string, userId: string, keyTemplate: string): string {
const key = keyTemplate.replace('${tenantId}', tenantId);
return key.replace('${userId}', userId);
}
}