@masterteam/workflow 0.0.43 → 0.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,7 @@
21
21
  "role": "الدور",
22
22
  "selectGroup": "اختر المجموعة",
23
23
  "selectRole": "اختر الدور",
24
+ "groupMissing": "المجموعة المحددة لم تعد موجودة. الرجاء اختيار مجموعة صالحة.",
24
25
  "sla": "اتفاقية مستوى الخدمة",
25
26
  "enterSla": "أدخل اتفاقية مستوى الخدمة",
26
27
  "action": "الإجراء",
@@ -21,6 +21,7 @@
21
21
  "role": "Role",
22
22
  "selectGroup": "Select Group",
23
23
  "selectRole": "Select Role",
24
+ "groupMissing": "The selected group no longer exists. Please choose a valid group.",
24
25
  "sla": "SLA",
25
26
  "enterSla": "Enter SLA",
26
27
  "action": "Action",
@@ -2231,7 +2231,7 @@ class WorkflowBuilder {
2231
2231
  }, ...(ngDevMode ? [{ debugName: "connectionForm" }] : /* istanbul ignore next */ []));
2232
2232
  connectionFormulaConfig = signal({
2233
2233
  codeOnly: true,
2234
- toolbarTabs: ['functions', 'operators'],
2234
+ toolbarTabs: ['functions', 'properties', 'operators'],
2235
2235
  isProcessBuilder: true,
2236
2236
  }, ...(ngDevMode ? [{ debugName: "connectionFormulaConfig" }] : /* istanbul ignore next */ []));
2237
2237
  steps = computed(() => this.workflowFacade.steps().map((step) => {
@@ -2347,6 +2347,13 @@ class WorkflowBuilder {
2347
2347
  this.rebuildAppActionConfigEditor(this.getCurrentAppActionConfigJson(), descriptor?.configSchemaJson ?? null, descriptor);
2348
2348
  this.lastAppActionDescriptorSignature = signature;
2349
2349
  });
2350
+ effect(() => {
2351
+ this.groups();
2352
+ if (this.isPatchingStepForm) {
2353
+ return;
2354
+ }
2355
+ this.stepForm.controls.group.updateValueAndValidity({ emitEvent: false });
2356
+ });
2350
2357
  this.stepForm.controls.targetType.valueChanges
2351
2358
  .pipe(takeUntilDestroyed())
2352
2359
  .subscribe(() => this.syncUserInputValidators());
@@ -2868,6 +2875,18 @@ class WorkflowBuilder {
2868
2875
  }
2869
2876
  this.stepForm.controls.type.enable({ emitEvent: false });
2870
2877
  }
2878
+ groupExistsValidator = (control) => {
2879
+ const value = control.value;
2880
+ if (value === null || value === undefined || value === '') {
2881
+ return null;
2882
+ }
2883
+ const groups = this.groups();
2884
+ if (!groups.length) {
2885
+ return null;
2886
+ }
2887
+ const exists = groups.some((group) => Number(group.id) === Number(value));
2888
+ return exists ? null : { groupMissing: true };
2889
+ };
2871
2890
  syncUserInputValidators() {
2872
2891
  const groupControl = this.stepForm.controls.group;
2873
2892
  const roleControl = this.stepForm.controls.role;
@@ -2877,7 +2896,10 @@ class WorkflowBuilder {
2877
2896
  if (this.currentStepType() === 'UserInput' &&
2878
2897
  !this.isEditingInitialNode() &&
2879
2898
  targetType === '1') {
2880
- groupControl.addValidators(Validators.required);
2899
+ groupControl.addValidators([
2900
+ Validators.required,
2901
+ this.groupExistsValidator,
2902
+ ]);
2881
2903
  }
2882
2904
  if (this.currentStepType() === 'UserInput' &&
2883
2905
  !this.isEditingInitialNode() &&
@@ -3037,6 +3059,9 @@ class WorkflowBuilder {
3037
3059
  if (this.appActionSettingsForm.invalid) {
3038
3060
  return true;
3039
3061
  }
3062
+ if (this.appActionConfigForm.invalid) {
3063
+ return true;
3064
+ }
3040
3065
  return this.getAppActionConfigMessages().length > 0;
3041
3066
  }
3042
3067
  normalizeRoleValue(value) {
@@ -3061,7 +3086,7 @@ class WorkflowBuilder {
3061
3086
  return '';
3062
3087
  }
3063
3088
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkflowBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
3064
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkflowBuilder, isStandalone: true, selector: "mt-workflow-builder", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'workflow.builder'\">\r\n <div class=\"h-full flex flex-col\" id=\"workflow-builder-card\">\r\n <div class=\"flex justify-center w-full py-2\">\r\n <mt-tabs\r\n [active]=\"mainTab()\"\r\n (activeChange)=\"onMainTabChange($event)\"\r\n [options]=\"mainTabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n </div>\r\n @switch (mainTab()) {\r\n @case (\"workflow\") {\r\n @if (!loading()) {\r\n <mt-structure-builder\r\n class=\"flex-1\"\r\n [structureMode]=\"'workflow'\"\r\n [availableNodes]=\"availableNodes()\"\r\n [availableNodesLabel]=\"t('stepTemplates')\"\r\n [connectionForm]=\"connectionForm()\"\r\n [connectionFormulaSchemaId]=\"connectionFormulaSchemaId()\"\r\n [connectionFormulaConfig]=\"connectionFormulaConfig()\"\r\n [nodeActions]=\"nodeActions()\"\r\n [nodes]=\"steps()\"\r\n [connections]=\"connections()\"\r\n (action)=\"onStructureAction($event)\"\r\n [addModalType]=\"'drawer'\"\r\n [addModalStyleClass]=\"editorDrawerStyleClass\"\r\n [updateModalStyleClass]=\"editorDrawerStyleClass\"\r\n [addModalHeader]=\"editorAddHeader\"\r\n [updateModalHeader]=\"editorUpdateHeader\"\r\n [nodeDialogFooterConfig]=\"nodeDialogFooterConfig\"\r\n [appendTo]=\"'page-content'\"\r\n [nodeFields]=\"nodeFields()\"\r\n [availableTabsClass]=\"hasMultipleWorkflows() ? '!mt-28' : ''\"\r\n [layoutDirection]=\"'LR'\"\r\n >\r\n <div flowContent class=\"pointer-events-none\">\r\n @if (hasMultipleWorkflows()) {\r\n <div class=\"pointer-events-auto absolute top-4 start-4 z-10\">\r\n <mt-card class=\"w-64\">\r\n <mt-select-field\r\n [options]=\"workflows()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [ngModel]=\"selectedWorkflowId()\"\r\n (ngModelChange)=\"onWorkflowChange($event)\"\r\n class=\"mt-2\"\r\n />\r\n </mt-card>\r\n </div>\r\n }\r\n <div class=\"pointer-events-auto absolute top-4 end-4 z-10\">\r\n <div class=\"flex flex-col gap-2 w-80\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-10\">\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"dev.dataflow-01\"\r\n />\r\n <label>{{\r\n \"workflow.builder.enableWorkflow\" | transloco\r\n }}</label>\r\n </div>\r\n <mt-toggle-field\r\n [ngModel]=\"isPublished()\"\r\n (ngModelChange)=\"onPublishToggle($event)\"\r\n [disabled]=\"isPublishDisabled()\"\r\n ></mt-toggle-field>\r\n </div>\r\n </mt-card>\r\n\r\n @if (publishError()) {\r\n <mt-card>\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ publishError() }}\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template\r\n #nodeDialog\r\n let-close=\"close\"\r\n let-save=\"save\"\r\n let-node=\"node\"\r\n let-drawerController=\"drawerController\"\r\n >\r\n <div class=\"p-4\">\r\n @if (loadingStep()) {\r\n <div class=\"space-y-4\">\r\n <div class=\"flex gap-2 mb-4\">\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <!-- Form fields skeleton -->\r\n <div class=\"space-y-4\">\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"3rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"4rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-tabs\r\n [active]=\"selectedTab()\"\r\n (activeChange)=\"onNodeDialogTabChange($event)\"\r\n [options]=\"tabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n @switch (selectedTab()) {\r\n @case (\"tab1\") {\r\n <div class=\"mt-4 space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <mt-text-field\r\n [label]=\"t('nameEnglish')\"\r\n [placeholder]=\"t('enterNameEnglish')\"\r\n [formControl]=\"stepForm.controls.nameEn\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n <mt-text-field\r\n [label]=\"t('nameArabic')\"\r\n [placeholder]=\"t('enterNameArabic')\"\r\n [formControl]=\"stepForm.controls.nameAr\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n </div>\r\n\r\n @if (currentStepType() === \"UserInput\") {\r\n @if (!isEditingInitialNode()) {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"approver\") }}\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('approver')\"\r\n [options]=\"[\r\n { label: t('group'), value: '1' },\r\n { label: t('role'), value: '2' },\r\n ]\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.targetType\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n @if (\r\n stepForm.controls.targetType.value === \"1\"\r\n ) {\r\n <mt-select-field\r\n [label]=\"t('group')\"\r\n [placeholder]=\"t('selectGroup')\"\r\n [options]=\"groups()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [formControl]=\"stepForm.controls.group\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n } @else {\r\n <mt-select-field\r\n [label]=\"t('role')\"\r\n [placeholder]=\"t('selectRole')\"\r\n [options]=\"roles()\"\r\n [group]=\"hasGroupedRoles()\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.role\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n }\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n }\r\n } @else {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"app\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-700\"\r\n >\r\n {{ t(\"appLabelPplus\") }}\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"action\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-900\"\r\n [title]=\"getAppActionKey()\"\r\n >\r\n {{ getAppActionDisplayName() }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n getAppActionDescription();\r\n as description\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-muted-color\"\r\n >\r\n {{ description }}\r\n </div>\r\n }\r\n\r\n @if (\r\n getAppActionDiscoveryMessage();\r\n as discoveryMessage\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ discoveryMessage }}\r\n </div>\r\n }\r\n\r\n @if (isAppActionMissing()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n <div class=\"font-semibold\">\r\n {{ t(\"unknownAppAction\") }}\r\n </div>\r\n <div class=\"mt-1 text-xs\">\r\n {{ t(\"unknownAppActionHint\") }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div>\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionConfiguration\") }}\r\n </div>\r\n <div class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"appActionConfigurationDescription\") }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n loadingAppActionDetail() &&\r\n appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div class=\"space-y-3\">\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"6rem\"\r\n ></p-skeleton>\r\n </div>\r\n } @else if (\r\n !appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface-300 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionUnavailable\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"schema\" &&\r\n appActionConfigDefinition().fields.length === 0\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionNoConfigRequired\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"raw\"\r\n ) {\r\n <div class=\"space-y-3\">\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionRawConfigFallback\") }}\r\n </div>\r\n <mt-textarea-field\r\n [label]=\"t('appActionConfigJson')\"\r\n [placeholder]=\"\r\n t('enterAppActionConfigJson')\r\n \"\r\n [formControl]=\"appActionRawConfigControl\"\r\n [rows]=\"'10'\"\r\n ></mt-textarea-field>\r\n </div>\r\n } @else {\r\n <div class=\"space-y-3\">\r\n @for (\r\n field of appActionConfigDefinition().fields;\r\n track field.key\r\n ) {\r\n <div class=\"space-y-2\">\r\n @switch (field.kind) {\r\n @case (\"text\") {\r\n <mt-text-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-text-field>\r\n }\r\n @case (\"number\") {\r\n <mt-number-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-number-field>\r\n }\r\n @case (\"toggle\") {\r\n <mt-toggle-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n ></mt-toggle-field>\r\n }\r\n @case (\"select\") {\r\n <mt-select-field\r\n [label]=\"field.title\"\r\n [options]=\"\r\n getAppActionEnumOptions(field)\r\n \"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-select-field>\r\n }\r\n @case (\"json\") {\r\n <mt-textarea-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n [rows]=\"'8'\"\r\n ></mt-textarea-field>\r\n }\r\n }\r\n\r\n @if (field.description) {\r\n <div class=\"text-xs text-muted-color\">\r\n {{ field.description }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getAppActionConfigMessages().length) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-3 text-sm text-red-700\"\r\n >\r\n @for (\r\n message of getAppActionConfigMessages();\r\n track message\r\n ) {\r\n <div>{{ message }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n @if (isAppActionAfterCommitOnly()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-3 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionAfterCommitGuidance\") }}\r\n </div>\r\n }\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"advancedExecution\") }}\r\n </div>\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n\r\n <mt-select-field\r\n [label]=\"t('failureBehavior')\"\r\n [options]=\"failureBehaviorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.failureBehavior\r\n \"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n <mt-number-field\r\n [label]=\"t('timeoutSeconds')\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.timeoutSeconds\r\n \"\r\n [required]=\"true\"\r\n [min]=\"1\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n\r\n <!--\r\n Read-only informational sections moved to the\r\n end of the form (lowest priority). Both default\r\n collapsed; the entire header is a click target\r\n with a visible \"Show / Hide\" affordance.\r\n -->\r\n @if (getAppActionRuntimeInputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"\r\n resolvedAutomaticallyOpen.set(\r\n !resolvedAutomaticallyOpen()\r\n )\r\n \"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionResolvedAutomatically\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionRuntimeInputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionResolvedAutomaticallyHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n resolvedAutomaticallyOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n resolvedAutomaticallyOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (resolvedAutomaticallyOpen()) {\r\n <mt-card>\r\n <div class=\"space-y-2\">\r\n @for (\r\n input of getAppActionRuntimeInputs();\r\n track input.key\r\n ) {\r\n <div\r\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface-200 bg-surface-50 px-3 py-2\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ input.key }}\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{\r\n describeRuntimeInputSource(input)\r\n }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 rounded-full bg-surface-200 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-surface-600\"\r\n >\r\n {{ t(\"appActionRuntime\") }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n\r\n @if (getAppActionOutputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"outputsOpen.set(!outputsOpen())\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionOutputs\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionOutputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionOutputsHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n outputsOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n outputsOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (outputsOpen()) {\r\n <mt-card>\r\n <div class=\"flex flex-wrap gap-1.5\">\r\n @for (\r\n output of getAppActionOutputs();\r\n track output.key\r\n ) {\r\n <span\r\n class=\"rounded-md bg-surface-100 px-2 py-0.5 text-xs font-mono text-surface-700\"\r\n [title]=\"output.description ?? ''\"\r\n >\r\n {{ output.key }}:{{ output.type }}\r\n </span>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @case (\"tab2\") {\r\n <div class=\"mt-4\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-4\">\r\n <div class=\"flex flex-1 items-center gap-3\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"file.file-check-02\"\r\n />\r\n <div class=\"flex flex-col\">\r\n <label class=\"font-medium\">{{\r\n t(\"configureForm\")\r\n }}</label>\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"configureForm-description\")\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mt-3 flex gap-2\">\r\n <mt-button\r\n [label]=\"t('configureForm')\"\r\n size=\"small\"\r\n (onClick)=\"openFormModal()\"\r\n ></mt-button>\r\n <mt-button\r\n [label]=\"t('resetForm')\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n [loading]=\"isResettingForm()\"\r\n (onClick)=\"onResetForm()\"\r\n ></mt-button>\r\n </div>\r\n </mt-card>\r\n </div>\r\n }\r\n @case (\"tab3\") {\r\n <div class=\"mt-4\">\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('show-hide')\"\r\n [descriptionCard]=\"t('show-hide-notifications')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"showHideControl\"\r\n >\r\n <ng-template #toggleCardBottom>\r\n @if (showHideControl.value) {\r\n <div class=\"mt-3\">\r\n <mt-button\r\n [label]=\"t('configureNotifications')\"\r\n size=\"small\"\r\n (onClick)=\"openNotificationsModal()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-toggle-field>\r\n </div>\r\n }\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n </mt-structure-builder>\r\n } @else {\r\n <p-skeleton width=\"100%\" height=\"50rem\" />\r\n }\r\n }\r\n @case (\"notification\") {\r\n <div class=\"flex-1 flex justify-center items-start p-4\">\r\n <div class=\"w-1/2 max-[1025px]:w-full\">\r\n <mt-card [title]=\"t('notifications')\" paddingless>\r\n <mt-notification-template />\r\n </mt-card>\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "availableNodesLabel", "nodeForm", "nodeDialogFooterConfig", "connectionForm", "connectionFormulaSchemaId", "connectionFormulaConfig", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "structureMode", "nodeStyle", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: i2.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: NotificationTemplate, selector: "mt-notification-template" }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "hint", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape", "markCurrentUser"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "maxLength", "icon", "iconPosition"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required", "maxLength"] }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
3089
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkflowBuilder, isStandalone: true, selector: "mt-workflow-builder", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'workflow.builder'\">\r\n <div class=\"h-full flex flex-col\" id=\"workflow-builder-card\">\r\n <div class=\"flex justify-center w-full py-2\">\r\n <mt-tabs\r\n [active]=\"mainTab()\"\r\n (activeChange)=\"onMainTabChange($event)\"\r\n [options]=\"mainTabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n </div>\r\n @switch (mainTab()) {\r\n @case (\"workflow\") {\r\n @if (!loading()) {\r\n <mt-structure-builder\r\n class=\"flex-1\"\r\n [structureMode]=\"'workflow'\"\r\n [availableNodes]=\"availableNodes()\"\r\n [availableNodesLabel]=\"t('stepTemplates')\"\r\n [connectionForm]=\"connectionForm()\"\r\n [connectionFormulaSchemaId]=\"connectionFormulaSchemaId()\"\r\n [connectionFormulaConfig]=\"connectionFormulaConfig()\"\r\n [nodeActions]=\"nodeActions()\"\r\n [nodes]=\"steps()\"\r\n [connections]=\"connections()\"\r\n (action)=\"onStructureAction($event)\"\r\n [addModalType]=\"'drawer'\"\r\n [addModalStyleClass]=\"editorDrawerStyleClass\"\r\n [updateModalStyleClass]=\"editorDrawerStyleClass\"\r\n [addModalHeader]=\"editorAddHeader\"\r\n [updateModalHeader]=\"editorUpdateHeader\"\r\n [nodeDialogFooterConfig]=\"nodeDialogFooterConfig\"\r\n [appendTo]=\"'page-content'\"\r\n [nodeFields]=\"nodeFields()\"\r\n [availableTabsClass]=\"hasMultipleWorkflows() ? '!mt-28' : ''\"\r\n [layoutDirection]=\"'LR'\"\r\n >\r\n <div flowContent class=\"pointer-events-none\">\r\n @if (hasMultipleWorkflows()) {\r\n <div class=\"pointer-events-auto absolute top-4 start-4 z-10\">\r\n <mt-card class=\"w-64\">\r\n <mt-select-field\r\n [options]=\"workflows()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [ngModel]=\"selectedWorkflowId()\"\r\n (ngModelChange)=\"onWorkflowChange($event)\"\r\n class=\"mt-2\"\r\n />\r\n </mt-card>\r\n </div>\r\n }\r\n <div class=\"pointer-events-auto absolute top-4 end-4 z-10\">\r\n <div class=\"flex flex-col gap-2 w-80\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-10\">\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"dev.dataflow-01\"\r\n />\r\n <label>{{\r\n \"workflow.builder.enableWorkflow\" | transloco\r\n }}</label>\r\n </div>\r\n <mt-toggle-field\r\n [ngModel]=\"isPublished()\"\r\n (ngModelChange)=\"onPublishToggle($event)\"\r\n [disabled]=\"isPublishDisabled()\"\r\n ></mt-toggle-field>\r\n </div>\r\n </mt-card>\r\n\r\n @if (publishError()) {\r\n <mt-card>\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ publishError() }}\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template\r\n #nodeDialog\r\n let-close=\"close\"\r\n let-save=\"save\"\r\n let-node=\"node\"\r\n let-drawerController=\"drawerController\"\r\n >\r\n <div class=\"p-4\">\r\n @if (loadingStep()) {\r\n <div class=\"space-y-4\">\r\n <div class=\"flex gap-2 mb-4\">\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <!-- Form fields skeleton -->\r\n <div class=\"space-y-4\">\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"3rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"4rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-tabs\r\n [active]=\"selectedTab()\"\r\n (activeChange)=\"onNodeDialogTabChange($event)\"\r\n [options]=\"tabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n @switch (selectedTab()) {\r\n @case (\"tab1\") {\r\n <div class=\"mt-4 space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <mt-text-field\r\n [label]=\"t('nameEnglish')\"\r\n [placeholder]=\"t('enterNameEnglish')\"\r\n [formControl]=\"stepForm.controls.nameEn\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n <mt-text-field\r\n [label]=\"t('nameArabic')\"\r\n [placeholder]=\"t('enterNameArabic')\"\r\n [formControl]=\"stepForm.controls.nameAr\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n </div>\r\n\r\n @if (currentStepType() === \"UserInput\") {\r\n @if (!isEditingInitialNode()) {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"approver\") }}\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('approver')\"\r\n [options]=\"[\r\n { label: t('group'), value: '1' },\r\n { label: t('role'), value: '2' },\r\n ]\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.targetType\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n @if (\r\n stepForm.controls.targetType.value === \"1\"\r\n ) {\r\n <mt-select-field\r\n [label]=\"t('group')\"\r\n [placeholder]=\"t('selectGroup')\"\r\n [options]=\"groups()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [formControl]=\"stepForm.controls.group\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n @if (\r\n stepForm.controls.group.hasError(\r\n \"groupMissing\"\r\n )\r\n ) {\r\n <p class=\"text-sm text-red-700\">\r\n {{ t(\"groupMissing\") }}\r\n </p>\r\n }\r\n } @else {\r\n <mt-select-field\r\n [label]=\"t('role')\"\r\n [placeholder]=\"t('selectRole')\"\r\n [options]=\"roles()\"\r\n [group]=\"hasGroupedRoles()\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.role\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n }\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n }\r\n } @else {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"app\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-700\"\r\n >\r\n {{ t(\"appLabelPplus\") }}\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"action\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-900\"\r\n [title]=\"getAppActionKey()\"\r\n >\r\n {{ getAppActionDisplayName() }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n getAppActionDescription();\r\n as description\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-muted-color\"\r\n >\r\n {{ description }}\r\n </div>\r\n }\r\n\r\n @if (\r\n getAppActionDiscoveryMessage();\r\n as discoveryMessage\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ discoveryMessage }}\r\n </div>\r\n }\r\n\r\n @if (isAppActionMissing()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n <div class=\"font-semibold\">\r\n {{ t(\"unknownAppAction\") }}\r\n </div>\r\n <div class=\"mt-1 text-xs\">\r\n {{ t(\"unknownAppActionHint\") }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div>\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionConfiguration\") }}\r\n </div>\r\n <div class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"appActionConfigurationDescription\") }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n loadingAppActionDetail() &&\r\n appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div class=\"space-y-3\">\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"6rem\"\r\n ></p-skeleton>\r\n </div>\r\n } @else if (\r\n !appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface-300 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionUnavailable\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"schema\" &&\r\n appActionConfigDefinition().fields.length === 0\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionNoConfigRequired\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"raw\"\r\n ) {\r\n <div class=\"space-y-3\">\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionRawConfigFallback\") }}\r\n </div>\r\n <mt-textarea-field\r\n [label]=\"t('appActionConfigJson')\"\r\n [placeholder]=\"\r\n t('enterAppActionConfigJson')\r\n \"\r\n [formControl]=\"appActionRawConfigControl\"\r\n [rows]=\"'10'\"\r\n ></mt-textarea-field>\r\n </div>\r\n } @else {\r\n <div class=\"space-y-3\">\r\n @for (\r\n field of appActionConfigDefinition().fields;\r\n track field.key\r\n ) {\r\n <div class=\"space-y-2\">\r\n @switch (field.kind) {\r\n @case (\"text\") {\r\n <mt-text-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-text-field>\r\n }\r\n @case (\"number\") {\r\n <mt-number-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-number-field>\r\n }\r\n @case (\"toggle\") {\r\n <mt-toggle-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n ></mt-toggle-field>\r\n }\r\n @case (\"select\") {\r\n <mt-select-field\r\n [label]=\"field.title\"\r\n [options]=\"\r\n getAppActionEnumOptions(field)\r\n \"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-select-field>\r\n }\r\n @case (\"json\") {\r\n <mt-textarea-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n [rows]=\"'8'\"\r\n ></mt-textarea-field>\r\n }\r\n }\r\n\r\n @if (field.description) {\r\n <div class=\"text-xs text-muted-color\">\r\n {{ field.description }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getAppActionConfigMessages().length) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-3 text-sm text-red-700\"\r\n >\r\n @for (\r\n message of getAppActionConfigMessages();\r\n track message\r\n ) {\r\n <div>{{ message }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n @if (isAppActionAfterCommitOnly()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-3 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionAfterCommitGuidance\") }}\r\n </div>\r\n }\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"advancedExecution\") }}\r\n </div>\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n\r\n <mt-select-field\r\n [label]=\"t('failureBehavior')\"\r\n [options]=\"failureBehaviorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.failureBehavior\r\n \"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n <mt-number-field\r\n [label]=\"t('timeoutSeconds')\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.timeoutSeconds\r\n \"\r\n [required]=\"true\"\r\n [min]=\"1\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n\r\n <!--\r\n Read-only informational sections moved to the\r\n end of the form (lowest priority). Both default\r\n collapsed; the entire header is a click target\r\n with a visible \"Show / Hide\" affordance.\r\n -->\r\n @if (getAppActionRuntimeInputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"\r\n resolvedAutomaticallyOpen.set(\r\n !resolvedAutomaticallyOpen()\r\n )\r\n \"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionResolvedAutomatically\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionRuntimeInputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionResolvedAutomaticallyHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n resolvedAutomaticallyOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n resolvedAutomaticallyOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (resolvedAutomaticallyOpen()) {\r\n <mt-card>\r\n <div class=\"space-y-2\">\r\n @for (\r\n input of getAppActionRuntimeInputs();\r\n track input.key\r\n ) {\r\n <div\r\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface-200 bg-surface-50 px-3 py-2\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ input.key }}\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{\r\n describeRuntimeInputSource(input)\r\n }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 rounded-full bg-surface-200 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-surface-600\"\r\n >\r\n {{ t(\"appActionRuntime\") }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n\r\n @if (getAppActionOutputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"outputsOpen.set(!outputsOpen())\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionOutputs\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionOutputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionOutputsHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n outputsOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n outputsOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (outputsOpen()) {\r\n <mt-card>\r\n <div class=\"flex flex-wrap gap-1.5\">\r\n @for (\r\n output of getAppActionOutputs();\r\n track output.key\r\n ) {\r\n <span\r\n class=\"rounded-md bg-surface-100 px-2 py-0.5 text-xs font-mono text-surface-700\"\r\n [title]=\"output.description ?? ''\"\r\n >\r\n {{ output.key }}:{{ output.type }}\r\n </span>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @case (\"tab2\") {\r\n <div class=\"mt-4\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-4\">\r\n <div class=\"flex flex-1 items-center gap-3\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"file.file-check-02\"\r\n />\r\n <div class=\"flex flex-col\">\r\n <label class=\"font-medium\">{{\r\n t(\"configureForm\")\r\n }}</label>\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"configureForm-description\")\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mt-3 flex gap-2\">\r\n <mt-button\r\n [label]=\"t('configureForm')\"\r\n size=\"small\"\r\n (onClick)=\"openFormModal()\"\r\n ></mt-button>\r\n <mt-button\r\n [label]=\"t('resetForm')\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n [loading]=\"isResettingForm()\"\r\n (onClick)=\"onResetForm()\"\r\n ></mt-button>\r\n </div>\r\n </mt-card>\r\n </div>\r\n }\r\n @case (\"tab3\") {\r\n <div class=\"mt-4\">\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('show-hide')\"\r\n [descriptionCard]=\"t('show-hide-notifications')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"showHideControl\"\r\n >\r\n <ng-template #toggleCardBottom>\r\n @if (showHideControl.value) {\r\n <div class=\"mt-3\">\r\n <mt-button\r\n [label]=\"t('configureNotifications')\"\r\n size=\"small\"\r\n (onClick)=\"openNotificationsModal()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-toggle-field>\r\n </div>\r\n }\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n </mt-structure-builder>\r\n } @else {\r\n <p-skeleton width=\"100%\" height=\"50rem\" />\r\n }\r\n }\r\n @case (\"notification\") {\r\n <div class=\"flex-1 flex justify-center items-start p-4\">\r\n <div class=\"w-1/2 max-[1025px]:w-full\">\r\n <mt-card [title]=\"t('notifications')\" paddingless>\r\n <mt-notification-template />\r\n </mt-card>\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "availableNodesLabel", "nodeForm", "nodeDialogFooterConfig", "connectionForm", "connectionFormulaSchemaId", "connectionFormulaConfig", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "structureMode", "nodeStyle", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: i2.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: NotificationTemplate, selector: "mt-notification-template" }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "hint", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape", "markCurrentUser"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "maxLength", "icon", "iconPosition"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "hint", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required", "maxLength"] }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
3065
3090
  }
3066
3091
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkflowBuilder, decorators: [{
3067
3092
  type: Component,
@@ -3080,7 +3105,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
3080
3105
  TextField,
3081
3106
  NumberField,
3082
3107
  TextareaField,
3083
- ], host: {}, template: "<ng-container *transloco=\"let t; prefix: 'workflow.builder'\">\r\n <div class=\"h-full flex flex-col\" id=\"workflow-builder-card\">\r\n <div class=\"flex justify-center w-full py-2\">\r\n <mt-tabs\r\n [active]=\"mainTab()\"\r\n (activeChange)=\"onMainTabChange($event)\"\r\n [options]=\"mainTabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n </div>\r\n @switch (mainTab()) {\r\n @case (\"workflow\") {\r\n @if (!loading()) {\r\n <mt-structure-builder\r\n class=\"flex-1\"\r\n [structureMode]=\"'workflow'\"\r\n [availableNodes]=\"availableNodes()\"\r\n [availableNodesLabel]=\"t('stepTemplates')\"\r\n [connectionForm]=\"connectionForm()\"\r\n [connectionFormulaSchemaId]=\"connectionFormulaSchemaId()\"\r\n [connectionFormulaConfig]=\"connectionFormulaConfig()\"\r\n [nodeActions]=\"nodeActions()\"\r\n [nodes]=\"steps()\"\r\n [connections]=\"connections()\"\r\n (action)=\"onStructureAction($event)\"\r\n [addModalType]=\"'drawer'\"\r\n [addModalStyleClass]=\"editorDrawerStyleClass\"\r\n [updateModalStyleClass]=\"editorDrawerStyleClass\"\r\n [addModalHeader]=\"editorAddHeader\"\r\n [updateModalHeader]=\"editorUpdateHeader\"\r\n [nodeDialogFooterConfig]=\"nodeDialogFooterConfig\"\r\n [appendTo]=\"'page-content'\"\r\n [nodeFields]=\"nodeFields()\"\r\n [availableTabsClass]=\"hasMultipleWorkflows() ? '!mt-28' : ''\"\r\n [layoutDirection]=\"'LR'\"\r\n >\r\n <div flowContent class=\"pointer-events-none\">\r\n @if (hasMultipleWorkflows()) {\r\n <div class=\"pointer-events-auto absolute top-4 start-4 z-10\">\r\n <mt-card class=\"w-64\">\r\n <mt-select-field\r\n [options]=\"workflows()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [ngModel]=\"selectedWorkflowId()\"\r\n (ngModelChange)=\"onWorkflowChange($event)\"\r\n class=\"mt-2\"\r\n />\r\n </mt-card>\r\n </div>\r\n }\r\n <div class=\"pointer-events-auto absolute top-4 end-4 z-10\">\r\n <div class=\"flex flex-col gap-2 w-80\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-10\">\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"dev.dataflow-01\"\r\n />\r\n <label>{{\r\n \"workflow.builder.enableWorkflow\" | transloco\r\n }}</label>\r\n </div>\r\n <mt-toggle-field\r\n [ngModel]=\"isPublished()\"\r\n (ngModelChange)=\"onPublishToggle($event)\"\r\n [disabled]=\"isPublishDisabled()\"\r\n ></mt-toggle-field>\r\n </div>\r\n </mt-card>\r\n\r\n @if (publishError()) {\r\n <mt-card>\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ publishError() }}\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template\r\n #nodeDialog\r\n let-close=\"close\"\r\n let-save=\"save\"\r\n let-node=\"node\"\r\n let-drawerController=\"drawerController\"\r\n >\r\n <div class=\"p-4\">\r\n @if (loadingStep()) {\r\n <div class=\"space-y-4\">\r\n <div class=\"flex gap-2 mb-4\">\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <!-- Form fields skeleton -->\r\n <div class=\"space-y-4\">\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"3rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"4rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-tabs\r\n [active]=\"selectedTab()\"\r\n (activeChange)=\"onNodeDialogTabChange($event)\"\r\n [options]=\"tabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n @switch (selectedTab()) {\r\n @case (\"tab1\") {\r\n <div class=\"mt-4 space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <mt-text-field\r\n [label]=\"t('nameEnglish')\"\r\n [placeholder]=\"t('enterNameEnglish')\"\r\n [formControl]=\"stepForm.controls.nameEn\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n <mt-text-field\r\n [label]=\"t('nameArabic')\"\r\n [placeholder]=\"t('enterNameArabic')\"\r\n [formControl]=\"stepForm.controls.nameAr\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n </div>\r\n\r\n @if (currentStepType() === \"UserInput\") {\r\n @if (!isEditingInitialNode()) {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"approver\") }}\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('approver')\"\r\n [options]=\"[\r\n { label: t('group'), value: '1' },\r\n { label: t('role'), value: '2' },\r\n ]\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.targetType\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n @if (\r\n stepForm.controls.targetType.value === \"1\"\r\n ) {\r\n <mt-select-field\r\n [label]=\"t('group')\"\r\n [placeholder]=\"t('selectGroup')\"\r\n [options]=\"groups()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [formControl]=\"stepForm.controls.group\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n } @else {\r\n <mt-select-field\r\n [label]=\"t('role')\"\r\n [placeholder]=\"t('selectRole')\"\r\n [options]=\"roles()\"\r\n [group]=\"hasGroupedRoles()\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.role\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n }\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n }\r\n } @else {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"app\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-700\"\r\n >\r\n {{ t(\"appLabelPplus\") }}\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"action\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-900\"\r\n [title]=\"getAppActionKey()\"\r\n >\r\n {{ getAppActionDisplayName() }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n getAppActionDescription();\r\n as description\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-muted-color\"\r\n >\r\n {{ description }}\r\n </div>\r\n }\r\n\r\n @if (\r\n getAppActionDiscoveryMessage();\r\n as discoveryMessage\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ discoveryMessage }}\r\n </div>\r\n }\r\n\r\n @if (isAppActionMissing()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n <div class=\"font-semibold\">\r\n {{ t(\"unknownAppAction\") }}\r\n </div>\r\n <div class=\"mt-1 text-xs\">\r\n {{ t(\"unknownAppActionHint\") }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div>\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionConfiguration\") }}\r\n </div>\r\n <div class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"appActionConfigurationDescription\") }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n loadingAppActionDetail() &&\r\n appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div class=\"space-y-3\">\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"6rem\"\r\n ></p-skeleton>\r\n </div>\r\n } @else if (\r\n !appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface-300 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionUnavailable\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"schema\" &&\r\n appActionConfigDefinition().fields.length === 0\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionNoConfigRequired\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"raw\"\r\n ) {\r\n <div class=\"space-y-3\">\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionRawConfigFallback\") }}\r\n </div>\r\n <mt-textarea-field\r\n [label]=\"t('appActionConfigJson')\"\r\n [placeholder]=\"\r\n t('enterAppActionConfigJson')\r\n \"\r\n [formControl]=\"appActionRawConfigControl\"\r\n [rows]=\"'10'\"\r\n ></mt-textarea-field>\r\n </div>\r\n } @else {\r\n <div class=\"space-y-3\">\r\n @for (\r\n field of appActionConfigDefinition().fields;\r\n track field.key\r\n ) {\r\n <div class=\"space-y-2\">\r\n @switch (field.kind) {\r\n @case (\"text\") {\r\n <mt-text-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-text-field>\r\n }\r\n @case (\"number\") {\r\n <mt-number-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-number-field>\r\n }\r\n @case (\"toggle\") {\r\n <mt-toggle-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n ></mt-toggle-field>\r\n }\r\n @case (\"select\") {\r\n <mt-select-field\r\n [label]=\"field.title\"\r\n [options]=\"\r\n getAppActionEnumOptions(field)\r\n \"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-select-field>\r\n }\r\n @case (\"json\") {\r\n <mt-textarea-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n [rows]=\"'8'\"\r\n ></mt-textarea-field>\r\n }\r\n }\r\n\r\n @if (field.description) {\r\n <div class=\"text-xs text-muted-color\">\r\n {{ field.description }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getAppActionConfigMessages().length) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-3 text-sm text-red-700\"\r\n >\r\n @for (\r\n message of getAppActionConfigMessages();\r\n track message\r\n ) {\r\n <div>{{ message }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n @if (isAppActionAfterCommitOnly()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-3 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionAfterCommitGuidance\") }}\r\n </div>\r\n }\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"advancedExecution\") }}\r\n </div>\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n\r\n <mt-select-field\r\n [label]=\"t('failureBehavior')\"\r\n [options]=\"failureBehaviorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.failureBehavior\r\n \"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n <mt-number-field\r\n [label]=\"t('timeoutSeconds')\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.timeoutSeconds\r\n \"\r\n [required]=\"true\"\r\n [min]=\"1\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n\r\n <!--\r\n Read-only informational sections moved to the\r\n end of the form (lowest priority). Both default\r\n collapsed; the entire header is a click target\r\n with a visible \"Show / Hide\" affordance.\r\n -->\r\n @if (getAppActionRuntimeInputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"\r\n resolvedAutomaticallyOpen.set(\r\n !resolvedAutomaticallyOpen()\r\n )\r\n \"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionResolvedAutomatically\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionRuntimeInputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionResolvedAutomaticallyHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n resolvedAutomaticallyOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n resolvedAutomaticallyOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (resolvedAutomaticallyOpen()) {\r\n <mt-card>\r\n <div class=\"space-y-2\">\r\n @for (\r\n input of getAppActionRuntimeInputs();\r\n track input.key\r\n ) {\r\n <div\r\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface-200 bg-surface-50 px-3 py-2\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ input.key }}\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{\r\n describeRuntimeInputSource(input)\r\n }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 rounded-full bg-surface-200 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-surface-600\"\r\n >\r\n {{ t(\"appActionRuntime\") }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n\r\n @if (getAppActionOutputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"outputsOpen.set(!outputsOpen())\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionOutputs\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionOutputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionOutputsHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n outputsOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n outputsOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (outputsOpen()) {\r\n <mt-card>\r\n <div class=\"flex flex-wrap gap-1.5\">\r\n @for (\r\n output of getAppActionOutputs();\r\n track output.key\r\n ) {\r\n <span\r\n class=\"rounded-md bg-surface-100 px-2 py-0.5 text-xs font-mono text-surface-700\"\r\n [title]=\"output.description ?? ''\"\r\n >\r\n {{ output.key }}:{{ output.type }}\r\n </span>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @case (\"tab2\") {\r\n <div class=\"mt-4\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-4\">\r\n <div class=\"flex flex-1 items-center gap-3\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"file.file-check-02\"\r\n />\r\n <div class=\"flex flex-col\">\r\n <label class=\"font-medium\">{{\r\n t(\"configureForm\")\r\n }}</label>\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"configureForm-description\")\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mt-3 flex gap-2\">\r\n <mt-button\r\n [label]=\"t('configureForm')\"\r\n size=\"small\"\r\n (onClick)=\"openFormModal()\"\r\n ></mt-button>\r\n <mt-button\r\n [label]=\"t('resetForm')\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n [loading]=\"isResettingForm()\"\r\n (onClick)=\"onResetForm()\"\r\n ></mt-button>\r\n </div>\r\n </mt-card>\r\n </div>\r\n }\r\n @case (\"tab3\") {\r\n <div class=\"mt-4\">\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('show-hide')\"\r\n [descriptionCard]=\"t('show-hide-notifications')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"showHideControl\"\r\n >\r\n <ng-template #toggleCardBottom>\r\n @if (showHideControl.value) {\r\n <div class=\"mt-3\">\r\n <mt-button\r\n [label]=\"t('configureNotifications')\"\r\n size=\"small\"\r\n (onClick)=\"openNotificationsModal()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-toggle-field>\r\n </div>\r\n }\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n </mt-structure-builder>\r\n } @else {\r\n <p-skeleton width=\"100%\" height=\"50rem\" />\r\n }\r\n }\r\n @case (\"notification\") {\r\n <div class=\"flex-1 flex justify-center items-start p-4\">\r\n <div class=\"w-1/2 max-[1025px]:w-full\">\r\n <mt-card [title]=\"t('notifications')\" paddingless>\r\n <mt-notification-template />\r\n </mt-card>\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</ng-container>\r\n" }]
3108
+ ], host: {}, template: "<ng-container *transloco=\"let t; prefix: 'workflow.builder'\">\r\n <div class=\"h-full flex flex-col\" id=\"workflow-builder-card\">\r\n <div class=\"flex justify-center w-full py-2\">\r\n <mt-tabs\r\n [active]=\"mainTab()\"\r\n (activeChange)=\"onMainTabChange($event)\"\r\n [options]=\"mainTabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n </div>\r\n @switch (mainTab()) {\r\n @case (\"workflow\") {\r\n @if (!loading()) {\r\n <mt-structure-builder\r\n class=\"flex-1\"\r\n [structureMode]=\"'workflow'\"\r\n [availableNodes]=\"availableNodes()\"\r\n [availableNodesLabel]=\"t('stepTemplates')\"\r\n [connectionForm]=\"connectionForm()\"\r\n [connectionFormulaSchemaId]=\"connectionFormulaSchemaId()\"\r\n [connectionFormulaConfig]=\"connectionFormulaConfig()\"\r\n [nodeActions]=\"nodeActions()\"\r\n [nodes]=\"steps()\"\r\n [connections]=\"connections()\"\r\n (action)=\"onStructureAction($event)\"\r\n [addModalType]=\"'drawer'\"\r\n [addModalStyleClass]=\"editorDrawerStyleClass\"\r\n [updateModalStyleClass]=\"editorDrawerStyleClass\"\r\n [addModalHeader]=\"editorAddHeader\"\r\n [updateModalHeader]=\"editorUpdateHeader\"\r\n [nodeDialogFooterConfig]=\"nodeDialogFooterConfig\"\r\n [appendTo]=\"'page-content'\"\r\n [nodeFields]=\"nodeFields()\"\r\n [availableTabsClass]=\"hasMultipleWorkflows() ? '!mt-28' : ''\"\r\n [layoutDirection]=\"'LR'\"\r\n >\r\n <div flowContent class=\"pointer-events-none\">\r\n @if (hasMultipleWorkflows()) {\r\n <div class=\"pointer-events-auto absolute top-4 start-4 z-10\">\r\n <mt-card class=\"w-64\">\r\n <mt-select-field\r\n [options]=\"workflows()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [ngModel]=\"selectedWorkflowId()\"\r\n (ngModelChange)=\"onWorkflowChange($event)\"\r\n class=\"mt-2\"\r\n />\r\n </mt-card>\r\n </div>\r\n }\r\n <div class=\"pointer-events-auto absolute top-4 end-4 z-10\">\r\n <div class=\"flex flex-col gap-2 w-80\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-10\">\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"dev.dataflow-01\"\r\n />\r\n <label>{{\r\n \"workflow.builder.enableWorkflow\" | transloco\r\n }}</label>\r\n </div>\r\n <mt-toggle-field\r\n [ngModel]=\"isPublished()\"\r\n (ngModelChange)=\"onPublishToggle($event)\"\r\n [disabled]=\"isPublishDisabled()\"\r\n ></mt-toggle-field>\r\n </div>\r\n </mt-card>\r\n\r\n @if (publishError()) {\r\n <mt-card>\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ publishError() }}\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template\r\n #nodeDialog\r\n let-close=\"close\"\r\n let-save=\"save\"\r\n let-node=\"node\"\r\n let-drawerController=\"drawerController\"\r\n >\r\n <div class=\"p-4\">\r\n @if (loadingStep()) {\r\n <div class=\"space-y-4\">\r\n <div class=\"flex gap-2 mb-4\">\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <!-- Form fields skeleton -->\r\n <div class=\"space-y-4\">\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"8rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"3rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"6rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n <div>\r\n <p-skeleton\r\n width=\"4rem\"\r\n height=\"1rem\"\r\n styleClass=\"mb-2\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n borderRadius=\"0.5rem\"\r\n ></p-skeleton>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-tabs\r\n [active]=\"selectedTab()\"\r\n (activeChange)=\"onNodeDialogTabChange($event)\"\r\n [options]=\"tabsList()\"\r\n size=\"large\"\r\n ></mt-tabs>\r\n @switch (selectedTab()) {\r\n @case (\"tab1\") {\r\n <div class=\"mt-4 space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <mt-text-field\r\n [label]=\"t('nameEnglish')\"\r\n [placeholder]=\"t('enterNameEnglish')\"\r\n [formControl]=\"stepForm.controls.nameEn\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n <mt-text-field\r\n [label]=\"t('nameArabic')\"\r\n [placeholder]=\"t('enterNameArabic')\"\r\n [formControl]=\"stepForm.controls.nameAr\"\r\n [required]=\"true\"\r\n ></mt-text-field>\r\n </div>\r\n\r\n @if (currentStepType() === \"UserInput\") {\r\n @if (!isEditingInitialNode()) {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"approver\") }}\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('approver')\"\r\n [options]=\"[\r\n { label: t('group'), value: '1' },\r\n { label: t('role'), value: '2' },\r\n ]\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.targetType\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n @if (\r\n stepForm.controls.targetType.value === \"1\"\r\n ) {\r\n <mt-select-field\r\n [label]=\"t('group')\"\r\n [placeholder]=\"t('selectGroup')\"\r\n [options]=\"groups()\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"id\"\r\n [formControl]=\"stepForm.controls.group\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n @if (\r\n stepForm.controls.group.hasError(\r\n \"groupMissing\"\r\n )\r\n ) {\r\n <p class=\"text-sm text-red-700\">\r\n {{ t(\"groupMissing\") }}\r\n </p>\r\n }\r\n } @else {\r\n <mt-select-field\r\n [label]=\"t('role')\"\r\n [placeholder]=\"t('selectRole')\"\r\n [options]=\"roles()\"\r\n [group]=\"hasGroupedRoles()\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n optionLabel=\"name.display\"\r\n optionValue=\"value\"\r\n [formControl]=\"stepForm.controls.role\"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n }\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n }\r\n } @else {\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div class=\"grid gap-3\">\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"app\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-700\"\r\n >\r\n {{ t(\"appLabelPplus\") }}\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid gap-1\">\r\n <label\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ t(\"action\") }}\r\n </label>\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-surface-900\"\r\n [title]=\"getAppActionKey()\"\r\n >\r\n {{ getAppActionDisplayName() }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n getAppActionDescription();\r\n as description\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-2 text-sm text-muted-color\"\r\n >\r\n {{ description }}\r\n </div>\r\n }\r\n\r\n @if (\r\n getAppActionDiscoveryMessage();\r\n as discoveryMessage\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700\"\r\n >\r\n {{ discoveryMessage }}\r\n </div>\r\n }\r\n\r\n @if (isAppActionMissing()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n <div class=\"font-semibold\">\r\n {{ t(\"unknownAppAction\") }}\r\n </div>\r\n <div class=\"mt-1 text-xs\">\r\n {{ t(\"unknownAppActionHint\") }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div>\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionConfiguration\") }}\r\n </div>\r\n <div class=\"mt-1 text-sm text-muted-color\">\r\n {{ t(\"appActionConfigurationDescription\") }}\r\n </div>\r\n </div>\r\n\r\n @if (\r\n loadingAppActionDetail() &&\r\n appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div class=\"space-y-3\">\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"2.5rem\"\r\n ></p-skeleton>\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"6rem\"\r\n ></p-skeleton>\r\n </div>\r\n } @else if (\r\n !appActionSettingsForm.controls.actionKey.value\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-dashed border-surface-300 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionUnavailable\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"schema\" &&\r\n appActionConfigDefinition().fields.length === 0\r\n ) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-3 py-4 text-sm text-muted-color\"\r\n >\r\n {{ t(\"appActionNoConfigRequired\") }}\r\n </div>\r\n } @else if (\r\n appActionConfigDefinition().mode === \"raw\"\r\n ) {\r\n <div class=\"space-y-3\">\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionRawConfigFallback\") }}\r\n </div>\r\n <mt-textarea-field\r\n [label]=\"t('appActionConfigJson')\"\r\n [placeholder]=\"\r\n t('enterAppActionConfigJson')\r\n \"\r\n [formControl]=\"appActionRawConfigControl\"\r\n [rows]=\"'10'\"\r\n ></mt-textarea-field>\r\n </div>\r\n } @else {\r\n <div class=\"space-y-3\">\r\n @for (\r\n field of appActionConfigDefinition().fields;\r\n track field.key\r\n ) {\r\n <div class=\"space-y-2\">\r\n @switch (field.kind) {\r\n @case (\"text\") {\r\n <mt-text-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-text-field>\r\n }\r\n @case (\"number\") {\r\n <mt-number-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-number-field>\r\n }\r\n @case (\"toggle\") {\r\n <mt-toggle-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n ></mt-toggle-field>\r\n }\r\n @case (\"select\") {\r\n <mt-select-field\r\n [label]=\"field.title\"\r\n [options]=\"\r\n getAppActionEnumOptions(field)\r\n \"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n ></mt-select-field>\r\n }\r\n @case (\"json\") {\r\n <mt-textarea-field\r\n [label]=\"field.title\"\r\n [formControl]=\"\r\n getAppActionConfigControl(\r\n field.key\r\n )\r\n \"\r\n [required]=\"field.required\"\r\n [rows]=\"'8'\"\r\n ></mt-textarea-field>\r\n }\r\n }\r\n\r\n @if (field.description) {\r\n <div class=\"text-xs text-muted-color\">\r\n {{ field.description }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getAppActionConfigMessages().length) {\r\n <div\r\n class=\"rounded-xl border border-red-200 bg-red-50 px-3 py-3 text-sm text-red-700\"\r\n >\r\n @for (\r\n message of getAppActionConfigMessages();\r\n track message\r\n ) {\r\n <div>{{ message }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n @if (isAppActionAfterCommitOnly()) {\r\n <div\r\n class=\"rounded-xl border border-amber-200 bg-amber-50 px-3 py-3 text-sm text-amber-800\"\r\n >\r\n {{ t(\"appActionAfterCommitGuidance\") }}\r\n </div>\r\n }\r\n\r\n <mt-card>\r\n <div class=\"space-y-4\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"advancedExecution\") }}\r\n </div>\r\n\r\n <mt-number-field\r\n [label]=\"t('sla')\"\r\n [placeholder]=\"t('enterSla')\"\r\n [formControl]=\"stepForm.controls.sla\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n ></mt-number-field>\r\n\r\n <mt-select-field\r\n [label]=\"t('failureBehavior')\"\r\n [options]=\"failureBehaviorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.failureBehavior\r\n \"\r\n [required]=\"true\"\r\n ></mt-select-field>\r\n\r\n <mt-number-field\r\n [label]=\"t('timeoutSeconds')\"\r\n [formControl]=\"\r\n appActionSettingsForm.controls.timeoutSeconds\r\n \"\r\n [required]=\"true\"\r\n [min]=\"1\"\r\n ></mt-number-field>\r\n </div>\r\n </mt-card>\r\n\r\n <!--\r\n Read-only informational sections moved to the\r\n end of the form (lowest priority). Both default\r\n collapsed; the entire header is a click target\r\n with a visible \"Show / Hide\" affordance.\r\n -->\r\n @if (getAppActionRuntimeInputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"\r\n resolvedAutomaticallyOpen.set(\r\n !resolvedAutomaticallyOpen()\r\n )\r\n \"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionResolvedAutomatically\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionRuntimeInputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionResolvedAutomaticallyHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n resolvedAutomaticallyOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n resolvedAutomaticallyOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (resolvedAutomaticallyOpen()) {\r\n <mt-card>\r\n <div class=\"space-y-2\">\r\n @for (\r\n input of getAppActionRuntimeInputs();\r\n track input.key\r\n ) {\r\n <div\r\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface-200 bg-surface-50 px-3 py-2\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-medium text-surface-900\"\r\n >\r\n {{ input.key }}\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{\r\n describeRuntimeInputSource(input)\r\n }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 rounded-full bg-surface-200 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-surface-600\"\r\n >\r\n {{ t(\"appActionRuntime\") }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n\r\n @if (getAppActionOutputs().length) {\r\n <button\r\n type=\"button\"\r\n class=\"group flex w-full items-center justify-between gap-3 rounded-xl border border-surface-200 bg-surface-50 px-3 py-2.5 text-start transition-colors hover:bg-surface-100\"\r\n (click)=\"outputsOpen.set(!outputsOpen())\"\r\n >\r\n <div class=\"min-w-0\">\r\n <div\r\n class=\"text-sm font-semibold text-surface-900\"\r\n >\r\n {{ t(\"appActionOutputs\") }}\r\n <span\r\n class=\"ms-1 text-xs font-normal text-muted-color\"\r\n >\r\n ({{ getAppActionOutputs().length }})\r\n </span>\r\n </div>\r\n <div class=\"text-xs text-muted-color\">\r\n {{ t(\"appActionOutputsHint\") }}\r\n </div>\r\n </div>\r\n <span\r\n class=\"shrink-0 inline-flex items-center gap-1 text-xs font-medium text-primary\"\r\n >\r\n {{\r\n outputsOpen()\r\n ? t(\"hideDetails\")\r\n : t(\"showDetails\")\r\n }}\r\n <mt-icon\r\n [icon]=\"\r\n outputsOpen()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n \"\r\n />\r\n </span>\r\n </button>\r\n @if (outputsOpen()) {\r\n <mt-card>\r\n <div class=\"flex flex-wrap gap-1.5\">\r\n @for (\r\n output of getAppActionOutputs();\r\n track output.key\r\n ) {\r\n <span\r\n class=\"rounded-md bg-surface-100 px-2 py-0.5 text-xs font-mono text-surface-700\"\r\n [title]=\"output.description ?? ''\"\r\n >\r\n {{ output.key }}:{{ output.type }}\r\n </span>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @case (\"tab2\") {\r\n <div class=\"mt-4\">\r\n <mt-card>\r\n <div class=\"flex items-center gap-4\">\r\n <div class=\"flex flex-1 items-center gap-3\">\r\n <mt-button\r\n [severity]=\"'secondary'\"\r\n icon=\"file.file-check-02\"\r\n />\r\n <div class=\"flex flex-col\">\r\n <label class=\"font-medium\">{{\r\n t(\"configureForm\")\r\n }}</label>\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"configureForm-description\")\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mt-3 flex gap-2\">\r\n <mt-button\r\n [label]=\"t('configureForm')\"\r\n size=\"small\"\r\n (onClick)=\"openFormModal()\"\r\n ></mt-button>\r\n <mt-button\r\n [label]=\"t('resetForm')\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n [loading]=\"isResettingForm()\"\r\n (onClick)=\"onResetForm()\"\r\n ></mt-button>\r\n </div>\r\n </mt-card>\r\n </div>\r\n }\r\n @case (\"tab3\") {\r\n <div class=\"mt-4\">\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('show-hide')\"\r\n [descriptionCard]=\"t('show-hide-notifications')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"showHideControl\"\r\n >\r\n <ng-template #toggleCardBottom>\r\n @if (showHideControl.value) {\r\n <div class=\"mt-3\">\r\n <mt-button\r\n [label]=\"t('configureNotifications')\"\r\n size=\"small\"\r\n (onClick)=\"openNotificationsModal()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-toggle-field>\r\n </div>\r\n }\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n </mt-structure-builder>\r\n } @else {\r\n <p-skeleton width=\"100%\" height=\"50rem\" />\r\n }\r\n }\r\n @case (\"notification\") {\r\n <div class=\"flex-1 flex justify-center items-start p-4\">\r\n <div class=\"w-1/2 max-[1025px]:w-full\">\r\n <mt-card [title]=\"t('notifications')\" paddingless>\r\n <mt-notification-template />\r\n </mt-card>\r\n </div>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</ng-container>\r\n" }]
3084
3109
  }], ctorParameters: () => [] });
3085
3110
 
3086
3111
  // store/app.state.ts