@maro-tech/form 0.0.11 → 0.0.12

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.
@@ -2920,8 +2920,16 @@ class UiActionFormModalComponent {
2920
2920
  onValueChange(value) {
2921
2921
  this.formValue.set(value);
2922
2922
  }
2923
- onLookupCompleted(_event) {
2924
- // Lookup results are already applied by the dynamic form and emitted via valueChange.
2923
+ onLookupCompleted(event) {
2924
+ const redirectTo = String(this.formConfig()?.redirectTo || '').trim();
2925
+ if (!redirectTo)
2926
+ return;
2927
+ const response = this.extractData(event.response) || event.response;
2928
+ const target = this.resolveTemplate(redirectTo, response);
2929
+ if (target && !target.includes('{{') && !target.includes(':')) {
2930
+ this.closed.emit();
2931
+ void this.router.navigateByUrl(target.startsWith('/') ? target : `/${target}`);
2932
+ }
2925
2933
  }
2926
2934
  onUploadingChange(uploading) {
2927
2935
  this.isUploading.set(uploading);
@@ -3022,19 +3030,23 @@ class UiActionFormModalComponent {
3022
3030
  if (!redirect)
3023
3031
  return;
3024
3032
  const data = this.extractData(response) || {};
3025
- const target = redirect.replace(/:([a-zA-Z_][a-zA-Z0-9_.]*)/g, (_match, key) => {
3026
- const value = String(key).split('.').reduce((current, part) => current && typeof current === 'object' ? current[part] : undefined, data);
3027
- return value == null ? '' : String(value);
3028
- });
3033
+ const target = this.resolveTemplate(redirect, data);
3029
3034
  if (target && !target.includes(':'))
3030
3035
  void this.router.navigateByUrl(target.startsWith('/') ? target : `/${target}`);
3031
3036
  }
3037
+ resolveTemplate(template, data) {
3038
+ return String(template || '').replace(/\{\{([a-zA-Z_][a-zA-Z0-9_.]*)\}\}|:([a-zA-Z_][a-zA-Z0-9_.]*)/g, (_match, bracesKey, colonKey) => {
3039
+ const key = String(bracesKey || colonKey || '');
3040
+ const value = key.split('.').reduce((current, part) => current && typeof current === 'object' ? current[part] : undefined, data);
3041
+ return value == null || value === '' ? '' : encodeURIComponent(String(value));
3042
+ });
3043
+ }
3032
3044
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiActionFormModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3033
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: UiActionFormModalComponent, isStandalone: true, selector: "forms-action-form-modal", inputs: { formId: { classPropertyName: "formId", publicName: "formId", isSignal: true, isRequired: false, transformFunction: null }, recordId: { classPropertyName: "recordId", publicName: "recordId", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, uploadPhoto: { classPropertyName: "uploadPhoto", publicName: "uploadPhoto", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", completed: "completed" }, usesOnChanges: true, ngImport: i0, template: "@if (isOpen()) {\n <div class=\"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-slate-950/40 p-4 sm:items-center sm:p-6\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"my-2 flex min-h-0 max-h-[calc(100vh-1rem)] w-full flex-col overflow-hidden rounded-2xl bg-slate-50 shadow-2xl sm:my-0 sm:max-h-[calc(100vh-3rem)]\" [ngClass]=\"panelClass()\">\n <div class=\"flex shrink-0 items-center justify-between border-b border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <h2 class=\"text-lg font-semibold\">{{ formConfig()?.title || 'Form' }}</h2>\n <button type=\"button\" class=\"text-xl text-slate-400 hover:text-slate-900\" aria-label=\"Close\" (click)=\"close()\">\u00D7</button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto p-4 sm:p-6\">\n @if (isLoading()) {\n <p class=\"text-sm text-slate-500\">Loading form\u2026</p>\n } @else {\n <forms-dynamic-form [fields]=\"fields()\" [value]=\"formValue()\" [showSubmit]=\"false\" [uploadPhoto]=\"uploadPhoto()\" (valueChange)=\"onValueChange($event)\" (lookupCompleted)=\"onLookupCompleted($event)\" (uploadingChange)=\"onUploadingChange($event)\" (fieldActionTriggered)=\"onFieldActionTriggered($event)\"></forms-dynamic-form>\n }\n </div>\n <div class=\"relative z-10 flex shrink-0 justify-end gap-3 border-t border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <ui-button variant=\"ghost\" (click)=\"close()\">Cancel</ui-button>\n @if (submitAction()) { <ui-button variant=\"primary\" [disabled]=\"isLoading() || isSubmitting() || isUploading()\" (click)=\"confirm()\">{{ submitLabel() }}</ui-button> }\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "withShadow", "icon", "iconOnly", "ariaLabel"] }, { kind: "component", type: UiDynamicFormComponent, selector: "forms-dynamic-form", inputs: ["fields", "value", "errors", "submitLabel", "showSubmit", "disabled", "uploadPhoto"], outputs: ["valueChange", "lookupCompleted", "submitted", "filesChange", "uploadingChange", "fieldActionTriggered"] }] });
3045
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: UiActionFormModalComponent, isStandalone: true, selector: "forms-action-form-modal", inputs: { formId: { classPropertyName: "formId", publicName: "formId", isSignal: true, isRequired: false, transformFunction: null }, recordId: { classPropertyName: "recordId", publicName: "recordId", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, uploadPhoto: { classPropertyName: "uploadPhoto", publicName: "uploadPhoto", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", completed: "completed" }, usesOnChanges: true, ngImport: i0, template: "@if (isOpen()) {\n <div class=\"fixed inset-0 z-50 flex min-h-full items-center justify-center overflow-y-auto bg-slate-950/40 p-4 sm:p-6\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"my-0 flex min-h-0 max-h-[calc(100vh-2rem)] w-full flex-col overflow-hidden rounded-2xl bg-slate-50 shadow-2xl sm:max-h-[calc(100vh-3rem)]\" [ngClass]=\"panelClass()\">\n <div class=\"flex shrink-0 items-center justify-between border-b border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <h2 class=\"text-lg font-semibold\">{{ formConfig()?.title || 'Form' }}</h2>\n <button type=\"button\" class=\"text-xl text-slate-400 hover:text-slate-900\" aria-label=\"Close\" (click)=\"close()\">\u00D7</button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto p-4 sm:p-6\">\n @if (isLoading()) {\n <p class=\"text-sm text-slate-500\">Loading form\u2026</p>\n } @else {\n <forms-dynamic-form [fields]=\"fields()\" [value]=\"formValue()\" [showSubmit]=\"false\" [uploadPhoto]=\"uploadPhoto()\" (valueChange)=\"onValueChange($event)\" (lookupCompleted)=\"onLookupCompleted($event)\" (uploadingChange)=\"onUploadingChange($event)\" (fieldActionTriggered)=\"onFieldActionTriggered($event)\"></forms-dynamic-form>\n }\n </div>\n <div class=\"relative z-10 flex shrink-0 justify-end gap-3 border-t border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <ui-button variant=\"ghost\" (click)=\"close()\">Cancel</ui-button>\n @if (submitAction()) { <ui-button variant=\"primary\" [disabled]=\"isLoading() || isSubmitting() || isUploading()\" (click)=\"confirm()\">{{ submitLabel() }}</ui-button> }\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "withShadow", "icon", "iconOnly", "ariaLabel"] }, { kind: "component", type: UiDynamicFormComponent, selector: "forms-dynamic-form", inputs: ["fields", "value", "errors", "submitLabel", "showSubmit", "disabled", "uploadPhoto"], outputs: ["valueChange", "lookupCompleted", "submitted", "filesChange", "uploadingChange", "fieldActionTriggered"] }] });
3034
3046
  }
3035
3047
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiActionFormModalComponent, decorators: [{
3036
3048
  type: Component,
3037
- args: [{ selector: 'forms-action-form-modal', standalone: true, imports: [CommonModule, UiButtonComponent, UiDynamicFormComponent], template: "@if (isOpen()) {\n <div class=\"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-slate-950/40 p-4 sm:items-center sm:p-6\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"my-2 flex min-h-0 max-h-[calc(100vh-1rem)] w-full flex-col overflow-hidden rounded-2xl bg-slate-50 shadow-2xl sm:my-0 sm:max-h-[calc(100vh-3rem)]\" [ngClass]=\"panelClass()\">\n <div class=\"flex shrink-0 items-center justify-between border-b border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <h2 class=\"text-lg font-semibold\">{{ formConfig()?.title || 'Form' }}</h2>\n <button type=\"button\" class=\"text-xl text-slate-400 hover:text-slate-900\" aria-label=\"Close\" (click)=\"close()\">\u00D7</button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto p-4 sm:p-6\">\n @if (isLoading()) {\n <p class=\"text-sm text-slate-500\">Loading form\u2026</p>\n } @else {\n <forms-dynamic-form [fields]=\"fields()\" [value]=\"formValue()\" [showSubmit]=\"false\" [uploadPhoto]=\"uploadPhoto()\" (valueChange)=\"onValueChange($event)\" (lookupCompleted)=\"onLookupCompleted($event)\" (uploadingChange)=\"onUploadingChange($event)\" (fieldActionTriggered)=\"onFieldActionTriggered($event)\"></forms-dynamic-form>\n }\n </div>\n <div class=\"relative z-10 flex shrink-0 justify-end gap-3 border-t border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <ui-button variant=\"ghost\" (click)=\"close()\">Cancel</ui-button>\n @if (submitAction()) { <ui-button variant=\"primary\" [disabled]=\"isLoading() || isSubmitting() || isUploading()\" (click)=\"confirm()\">{{ submitLabel() }}</ui-button> }\n </div>\n </div>\n </div>\n}\n" }]
3049
+ args: [{ selector: 'forms-action-form-modal', standalone: true, imports: [CommonModule, UiButtonComponent, UiDynamicFormComponent], template: "@if (isOpen()) {\n <div class=\"fixed inset-0 z-50 flex min-h-full items-center justify-center overflow-y-auto bg-slate-950/40 p-4 sm:p-6\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"my-0 flex min-h-0 max-h-[calc(100vh-2rem)] w-full flex-col overflow-hidden rounded-2xl bg-slate-50 shadow-2xl sm:max-h-[calc(100vh-3rem)]\" [ngClass]=\"panelClass()\">\n <div class=\"flex shrink-0 items-center justify-between border-b border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <h2 class=\"text-lg font-semibold\">{{ formConfig()?.title || 'Form' }}</h2>\n <button type=\"button\" class=\"text-xl text-slate-400 hover:text-slate-900\" aria-label=\"Close\" (click)=\"close()\">\u00D7</button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto p-4 sm:p-6\">\n @if (isLoading()) {\n <p class=\"text-sm text-slate-500\">Loading form\u2026</p>\n } @else {\n <forms-dynamic-form [fields]=\"fields()\" [value]=\"formValue()\" [showSubmit]=\"false\" [uploadPhoto]=\"uploadPhoto()\" (valueChange)=\"onValueChange($event)\" (lookupCompleted)=\"onLookupCompleted($event)\" (uploadingChange)=\"onUploadingChange($event)\" (fieldActionTriggered)=\"onFieldActionTriggered($event)\"></forms-dynamic-form>\n }\n </div>\n <div class=\"relative z-10 flex shrink-0 justify-end gap-3 border-t border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <ui-button variant=\"ghost\" (click)=\"close()\">Cancel</ui-button>\n @if (submitAction()) { <ui-button variant=\"primary\" [disabled]=\"isLoading() || isSubmitting() || isUploading()\" (click)=\"confirm()\">{{ submitLabel() }}</ui-button> }\n </div>\n </div>\n </div>\n}\n" }]
3038
3050
  }], propDecorators: { formId: [{ type: i0.Input, args: [{ isSignal: true, alias: "formId", required: false }] }], recordId: [{ type: i0.Input, args: [{ isSignal: true, alias: "recordId", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }], initialValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValue", required: false }] }], uploadPhoto: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadPhoto", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], completed: [{ type: i0.Output, args: ["completed"] }] } });
3039
3051
 
3040
3052
  class UiInputComponent {