@memberjunction/ng-base-forms 5.38.0 → 5.39.0

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.
Files changed (79) hide show
  1. package/README.md +53 -0
  2. package/dist/lib/base-form-component.d.ts +18 -0
  3. package/dist/lib/base-form-component.d.ts.map +1 -1
  4. package/dist/lib/base-form-component.js +31 -2
  5. package/dist/lib/base-form-component.js.map +1 -1
  6. package/dist/lib/container/record-form-container.component.d.ts +14 -0
  7. package/dist/lib/container/record-form-container.component.d.ts.map +1 -1
  8. package/dist/lib/container/record-form-container.component.js +59 -33
  9. package/dist/lib/container/record-form-container.component.js.map +1 -1
  10. package/dist/lib/field/fk-search-utils.d.ts +31 -0
  11. package/dist/lib/field/fk-search-utils.d.ts.map +1 -0
  12. package/dist/lib/field/fk-search-utils.js +47 -0
  13. package/dist/lib/field/fk-search-utils.js.map +1 -0
  14. package/dist/lib/field/form-field.component.d.ts +401 -6
  15. package/dist/lib/field/form-field.component.d.ts.map +1 -1
  16. package/dist/lib/field/form-field.component.js +1646 -214
  17. package/dist/lib/field/form-field.component.js.map +1 -1
  18. package/dist/lib/field/linked-field-options.d.ts +76 -0
  19. package/dist/lib/field/linked-field-options.d.ts.map +1 -0
  20. package/dist/lib/field/linked-field-options.js +80 -0
  21. package/dist/lib/field/linked-field-options.js.map +1 -0
  22. package/dist/lib/host/entity-form-host.component.d.ts +159 -0
  23. package/dist/lib/host/entity-form-host.component.d.ts.map +1 -0
  24. package/dist/lib/host/entity-form-host.component.js +539 -0
  25. package/dist/lib/host/entity-form-host.component.js.map +1 -0
  26. package/dist/lib/isa-related-panel/isa-related-card.component.js +2 -2
  27. package/dist/lib/overlays/base-form-overlay.d.ts +114 -0
  28. package/dist/lib/overlays/base-form-overlay.d.ts.map +1 -0
  29. package/dist/lib/overlays/base-form-overlay.js +227 -0
  30. package/dist/lib/overlays/base-form-overlay.js.map +1 -0
  31. package/dist/lib/overlays/form-dialog.component.d.ts +35 -0
  32. package/dist/lib/overlays/form-dialog.component.d.ts.map +1 -0
  33. package/dist/lib/overlays/form-dialog.component.js +92 -0
  34. package/dist/lib/overlays/form-dialog.component.js.map +1 -0
  35. package/dist/lib/overlays/form-presenter.service.d.ts +37 -0
  36. package/dist/lib/overlays/form-presenter.service.d.ts.map +1 -0
  37. package/dist/lib/overlays/form-presenter.service.js +130 -0
  38. package/dist/lib/overlays/form-presenter.service.js.map +1 -0
  39. package/dist/lib/overlays/form-presenter.types.d.ts +65 -0
  40. package/dist/lib/overlays/form-presenter.types.d.ts.map +1 -0
  41. package/dist/lib/overlays/form-presenter.types.js +25 -0
  42. package/dist/lib/overlays/form-presenter.types.js.map +1 -0
  43. package/dist/lib/overlays/form-slide-in.component.d.ts +38 -0
  44. package/dist/lib/overlays/form-slide-in.component.d.ts.map +1 -0
  45. package/dist/lib/overlays/form-slide-in.component.js +106 -0
  46. package/dist/lib/overlays/form-slide-in.component.js.map +1 -0
  47. package/dist/lib/overlays/form-window.component.d.ts +32 -0
  48. package/dist/lib/overlays/form-window.component.d.ts.map +1 -0
  49. package/dist/lib/overlays/form-window.component.js +93 -0
  50. package/dist/lib/overlays/form-window.component.js.map +1 -0
  51. package/dist/lib/panel/collapsible-panel.component.d.ts +19 -2
  52. package/dist/lib/panel/collapsible-panel.component.d.ts.map +1 -1
  53. package/dist/lib/panel/collapsible-panel.component.js +70 -13
  54. package/dist/lib/panel/collapsible-panel.component.js.map +1 -1
  55. package/dist/lib/resolver/form-resolver.service.d.ts +139 -0
  56. package/dist/lib/resolver/form-resolver.service.d.ts.map +1 -0
  57. package/dist/lib/resolver/form-resolver.service.js +235 -0
  58. package/dist/lib/resolver/form-resolver.service.js.map +1 -0
  59. package/dist/lib/section-manager/section-manager.component.js +2 -2
  60. package/dist/lib/toolbar/form-toolbar.component.js +2 -2
  61. package/dist/lib/types/entity-form-config.d.ts +125 -0
  62. package/dist/lib/types/entity-form-config.d.ts.map +1 -0
  63. package/dist/lib/types/entity-form-config.js +75 -0
  64. package/dist/lib/types/entity-form-config.js.map +1 -0
  65. package/dist/lib/types/form-types.d.ts +24 -0
  66. package/dist/lib/types/form-types.d.ts.map +1 -1
  67. package/dist/lib/types/form-types.js.map +1 -1
  68. package/dist/lib/types/navigation-events.d.ts +46 -2
  69. package/dist/lib/types/navigation-events.d.ts.map +1 -1
  70. package/dist/lib/types/navigation-events.js.map +1 -1
  71. package/dist/module.d.ts +12 -8
  72. package/dist/module.d.ts.map +1 -1
  73. package/dist/module.js +26 -7
  74. package/dist/module.js.map +1 -1
  75. package/dist/public-api.d.ts +11 -0
  76. package/dist/public-api.d.ts.map +1 -1
  77. package/dist/public-api.js +14 -0
  78. package/dist/public-api.js.map +1 -1
  79. package/package.json +17 -13
@@ -0,0 +1,37 @@
1
+ import { MJFormPresenterOptions, MJFormRef } from './form-presenter.types';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Imperatively opens any MemberJunction entity form as a dialog or slide-in
5
+ * from anywhere — one call, no template wiring.
6
+ *
7
+ * ```typescript
8
+ * const ref = this.formPresenter.Open({
9
+ * EntityName: 'MJ: AI Agents',
10
+ * RecordId: agentId,
11
+ * Presentation: 'slide-in',
12
+ * Config: { ShowRelatedEntities: false },
13
+ * });
14
+ * const saved = await ref.AfterSaved(); // BaseEntity | null
15
+ * ```
16
+ *
17
+ * Mounts the (standalone) overlay shell onto `document.body`, wires its outputs
18
+ * to the returned {@link MJFormRef}, and tears everything down after close.
19
+ */
20
+ export declare class MJFormPresenterService {
21
+ private readonly appRef;
22
+ private readonly envInjector;
23
+ Open(options: MJFormPresenterOptions): MJFormRef;
24
+ /**
25
+ * Handle navigation events bubbling up from a form hosted inside an overlay. Currently
26
+ * the only one the presenter acts on is `create-related` — it opens a nested form and
27
+ * hands the saved record back via the event's `Complete` callback.
28
+ */
29
+ private handleOverlayNavigate;
30
+ /** Maps a presentation to its (standalone) overlay shell component. */
31
+ private shellFor;
32
+ /** Copies presenter options onto the overlay instance. */
33
+ private applyInputs;
34
+ static ɵfac: i0.ɵɵFactoryDeclaration<MJFormPresenterService, never>;
35
+ static ɵprov: i0.ɵɵInjectableDeclaration<MJFormPresenterService>;
36
+ }
37
+ //# sourceMappingURL=form-presenter.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-presenter.service.d.ts","sourceRoot":"","sources":["../../../src/lib/overlays/form-presenter.service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAsB,MAAM,wBAAwB,CAAC;;AAG/F;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAE3D,IAAI,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS;IAyDhD;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAW7B,uEAAuE;IACvE,OAAO,CAAC,QAAQ;IAQhB,0DAA0D;IAC1D,OAAO,CAAC,WAAW;yCAvFR,sBAAsB;6CAAtB,sBAAsB;CA4GlC"}
@@ -0,0 +1,130 @@
1
+ import { Injectable, ApplicationRef, EnvironmentInjector, createComponent, inject } from '@angular/core';
2
+ import { MjFormDialogComponent } from './form-dialog.component';
3
+ import { MjFormSlideInComponent } from './form-slide-in.component';
4
+ import { MjFormWindowComponent } from './form-window.component';
5
+ import { MJFormRef } from './form-presenter.types';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * Imperatively opens any MemberJunction entity form as a dialog or slide-in
9
+ * from anywhere — one call, no template wiring.
10
+ *
11
+ * ```typescript
12
+ * const ref = this.formPresenter.Open({
13
+ * EntityName: 'MJ: AI Agents',
14
+ * RecordId: agentId,
15
+ * Presentation: 'slide-in',
16
+ * Config: { ShowRelatedEntities: false },
17
+ * });
18
+ * const saved = await ref.AfterSaved(); // BaseEntity | null
19
+ * ```
20
+ *
21
+ * Mounts the (standalone) overlay shell onto `document.body`, wires its outputs
22
+ * to the returned {@link MJFormRef}, and tears everything down after close.
23
+ */
24
+ export class MJFormPresenterService {
25
+ appRef = inject(ApplicationRef);
26
+ envInjector = inject(EnvironmentInjector);
27
+ Open(options) {
28
+ const presentation = options.Presentation ?? 'dialog';
29
+ const hostEl = document.createElement('div');
30
+ document.body.appendChild(hostEl);
31
+ const ref = createComponent(this.shellFor(presentation), { environmentInjector: this.envInjector, hostElement: hostEl });
32
+ this.applyInputs(ref.instance, options, presentation);
33
+ this.appRef.attachView(ref.hostView);
34
+ // ── Promises wired to the overlay outputs ──
35
+ let savedEntity = null;
36
+ let resolveSaved;
37
+ let resolveClosed;
38
+ const savedPromise = new Promise(r => (resolveSaved = r));
39
+ const closedPromise = new Promise(r => (resolveClosed = r));
40
+ const subs = [
41
+ ref.instance.Saved.subscribe(e => { savedEntity = e; }),
42
+ ref.instance.Closed.subscribe(reason => {
43
+ resolveSaved(savedEntity);
44
+ resolveClosed(reason);
45
+ // Allow the close animation to finish before destroying the view.
46
+ setTimeout(() => teardown(), 350);
47
+ }),
48
+ // A form rendered INSIDE this overlay can ask to create a related record (e.g. an
49
+ // FK field's "+ Create" footer). Handle it by opening a nested form and handing the
50
+ // saved record back. This makes inline-create work for overlay-hosted forms, the same
51
+ // way SingleRecordComponent handles it for tab-hosted forms.
52
+ ref.instance.Navigate.subscribe((e) => this.handleOverlayNavigate(e)),
53
+ ];
54
+ let destroyed = false;
55
+ const teardown = () => {
56
+ if (destroyed)
57
+ return;
58
+ destroyed = true;
59
+ subs.forEach(s => s.unsubscribe());
60
+ this.appRef.detachView(ref.hostView);
61
+ ref.destroy();
62
+ hostEl.remove();
63
+ };
64
+ // Show + run an initial CD pass so the overlay renders immediately.
65
+ ref.instance.Visible = true;
66
+ ref.changeDetectorRef.detectChanges();
67
+ return new MJFormRef(savedPromise, closedPromise, () => ref.instance.onCancel(), () => ref.instance.formInstance);
68
+ }
69
+ /**
70
+ * Handle navigation events bubbling up from a form hosted inside an overlay. Currently
71
+ * the only one the presenter acts on is `create-related` — it opens a nested form and
72
+ * hands the saved record back via the event's `Complete` callback.
73
+ */
74
+ handleOverlayNavigate(e) {
75
+ if (e.Kind !== 'create-related')
76
+ return;
77
+ const childRef = this.Open({
78
+ EntityName: e.EntityName,
79
+ Presentation: e.Presentation ?? 'dialog',
80
+ NewRecordValues: e.NewRecordValues,
81
+ Provider: e.Provider,
82
+ });
83
+ childRef.AfterSaved().then(created => e.Complete(created));
84
+ }
85
+ /** Maps a presentation to its (standalone) overlay shell component. */
86
+ shellFor(p) {
87
+ switch (p) {
88
+ case 'slide-in': return MjFormSlideInComponent;
89
+ case 'window': return MjFormWindowComponent;
90
+ default: return MjFormDialogComponent;
91
+ }
92
+ }
93
+ /** Copies presenter options onto the overlay instance. */
94
+ applyInputs(inst, o, presentation) {
95
+ inst.EntityName = o.EntityName ?? null;
96
+ if (o.PrimaryKey)
97
+ inst.PrimaryKey = o.PrimaryKey;
98
+ if (o.RecordId)
99
+ inst.RecordID = o.RecordId;
100
+ inst.Record = o.Record ?? null;
101
+ inst.NewRecordValues = o.NewRecordValues ?? null;
102
+ inst.SectionName = o.SectionName ?? null;
103
+ inst.EditMode = o.EditMode ?? null;
104
+ if (o.Config)
105
+ inst.Config = o.Config;
106
+ if (o.Title)
107
+ inst.Title = o.Title;
108
+ inst.Provider = o.Provider ?? null;
109
+ if (o.ShowFooter !== undefined)
110
+ inst.ShowFooter = o.ShowFooter;
111
+ if (o.SaveButtonText)
112
+ inst.SaveButtonText = o.SaveButtonText;
113
+ if (o.CancelButtonText)
114
+ inst.CancelButtonText = o.CancelButtonText;
115
+ if (presentation === 'slide-in') {
116
+ if (o.WidthPx != null)
117
+ inst.WidthPx = o.WidthPx;
118
+ }
119
+ else if (o.Width != null) {
120
+ inst.Width = o.Width;
121
+ }
122
+ }
123
+ static ɵfac = function MJFormPresenterService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJFormPresenterService)(); };
124
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MJFormPresenterService, factory: MJFormPresenterService.ɵfac, providedIn: 'root' });
125
+ }
126
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJFormPresenterService, [{
127
+ type: Injectable,
128
+ args: [{ providedIn: 'root' }]
129
+ }], null, null); })();
130
+ //# sourceMappingURL=form-presenter.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-presenter.service.js","sourceRoot":"","sources":["../../../src/lib/overlays/form-presenter.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Injectable, ApplicationRef, EnvironmentInjector, createComponent, inject, ComponentRef, Type\n} from '@angular/core';\nimport { BaseEntity } from '@memberjunction/core';\nimport { Subscription } from 'rxjs';\n\nimport { MjFormDialogComponent } from './form-dialog.component';\nimport { MjFormSlideInComponent } from './form-slide-in.component';\nimport { MjFormWindowComponent } from './form-window.component';\nimport { BaseFormOverlay, FormOverlayCloseReason } from './base-form-overlay';\nimport { MJFormPresenterOptions, MJFormRef, MJFormPresentation } from './form-presenter.types';\nimport { FormNavigationEvent } from '../types/navigation-events';\n\n/**\n * Imperatively opens any MemberJunction entity form as a dialog or slide-in\n * from anywhere — one call, no template wiring.\n *\n * ```typescript\n * const ref = this.formPresenter.Open({\n * EntityName: 'MJ: AI Agents',\n * RecordId: agentId,\n * Presentation: 'slide-in',\n * Config: { ShowRelatedEntities: false },\n * });\n * const saved = await ref.AfterSaved(); // BaseEntity | null\n * ```\n *\n * Mounts the (standalone) overlay shell onto `document.body`, wires its outputs\n * to the returned {@link MJFormRef}, and tears everything down after close.\n */\n@Injectable({ providedIn: 'root' })\nexport class MJFormPresenterService {\n private readonly appRef = inject(ApplicationRef);\n private readonly envInjector = inject(EnvironmentInjector);\n\n Open(options: MJFormPresenterOptions): MJFormRef {\n const presentation: MJFormPresentation = options.Presentation ?? 'dialog';\n const hostEl = document.createElement('div');\n document.body.appendChild(hostEl);\n\n const ref: ComponentRef<BaseFormOverlay> = createComponent(\n this.shellFor(presentation),\n { environmentInjector: this.envInjector, hostElement: hostEl },\n );\n\n this.applyInputs(ref.instance, options, presentation);\n this.appRef.attachView(ref.hostView);\n\n // ── Promises wired to the overlay outputs ──\n let savedEntity: BaseEntity | null = null;\n let resolveSaved!: (e: BaseEntity | null) => void;\n let resolveClosed!: (r: FormOverlayCloseReason) => void;\n const savedPromise = new Promise<BaseEntity | null>(r => (resolveSaved = r));\n const closedPromise = new Promise<FormOverlayCloseReason>(r => (resolveClosed = r));\n\n const subs: Subscription[] = [\n ref.instance.Saved.subscribe(e => { savedEntity = e; }),\n ref.instance.Closed.subscribe(reason => {\n resolveSaved(savedEntity);\n resolveClosed(reason);\n // Allow the close animation to finish before destroying the view.\n setTimeout(() => teardown(), 350);\n }),\n // A form rendered INSIDE this overlay can ask to create a related record (e.g. an\n // FK field's \"+ Create\" footer). Handle it by opening a nested form and handing the\n // saved record back. This makes inline-create work for overlay-hosted forms, the same\n // way SingleRecordComponent handles it for tab-hosted forms.\n ref.instance.Navigate.subscribe((e: FormNavigationEvent) => this.handleOverlayNavigate(e)),\n ];\n\n let destroyed = false;\n const teardown = () => {\n if (destroyed) return;\n destroyed = true;\n subs.forEach(s => s.unsubscribe());\n this.appRef.detachView(ref.hostView);\n ref.destroy();\n hostEl.remove();\n };\n\n // Show + run an initial CD pass so the overlay renders immediately.\n ref.instance.Visible = true;\n ref.changeDetectorRef.detectChanges();\n\n return new MJFormRef(\n savedPromise,\n closedPromise,\n () => ref.instance.onCancel(),\n () => ref.instance.formInstance,\n );\n }\n\n /**\n * Handle navigation events bubbling up from a form hosted inside an overlay. Currently\n * the only one the presenter acts on is `create-related` — it opens a nested form and\n * hands the saved record back via the event's `Complete` callback.\n */\n private handleOverlayNavigate(e: FormNavigationEvent): void {\n if (e.Kind !== 'create-related') return;\n const childRef = this.Open({\n EntityName: e.EntityName,\n Presentation: e.Presentation ?? 'dialog',\n NewRecordValues: e.NewRecordValues,\n Provider: e.Provider,\n });\n childRef.AfterSaved().then(created => e.Complete(created));\n }\n\n /** Maps a presentation to its (standalone) overlay shell component. */\n private shellFor(p: MJFormPresentation): Type<BaseFormOverlay> {\n switch (p) {\n case 'slide-in': return MjFormSlideInComponent;\n case 'window': return MjFormWindowComponent;\n default: return MjFormDialogComponent;\n }\n }\n\n /** Copies presenter options onto the overlay instance. */\n private applyInputs(inst: BaseFormOverlay, o: MJFormPresenterOptions, presentation: MJFormPresentation): void {\n inst.EntityName = o.EntityName ?? null;\n if (o.PrimaryKey) inst.PrimaryKey = o.PrimaryKey;\n if (o.RecordId) inst.RecordID = o.RecordId;\n inst.Record = o.Record ?? null;\n inst.NewRecordValues = o.NewRecordValues ?? null;\n inst.SectionName = o.SectionName ?? null;\n inst.EditMode = o.EditMode ?? null;\n if (o.Config) inst.Config = o.Config;\n if (o.Title) inst.Title = o.Title;\n inst.Provider = o.Provider ?? null;\n if (o.ShowFooter !== undefined) inst.ShowFooter = o.ShowFooter;\n if (o.SaveButtonText) inst.SaveButtonText = o.SaveButtonText;\n if (o.CancelButtonText) inst.CancelButtonText = o.CancelButtonText;\n\n if (presentation === 'slide-in') {\n if (o.WidthPx != null) (inst as MjFormSlideInComponent).WidthPx = o.WidthPx;\n } else if (o.Width != null) {\n (inst as MjFormDialogComponent | MjFormWindowComponent).Width = o.Width;\n }\n }\n}\n"]}
@@ -0,0 +1,65 @@
1
+ import { BaseEntity, CompositeKey, IMetadataProvider } from '@memberjunction/core';
2
+ import { BaseFormComponent } from '../base-form-component';
3
+ import { EntityFormConfig } from '../types/entity-form-config';
4
+ import { FormOverlayCloseReason } from './base-form-overlay';
5
+ /** How a form should be presented by {@link MJFormPresenterService}. */
6
+ export type MJFormPresentation = 'dialog' | 'slide-in' | 'window';
7
+ /**
8
+ * Options for {@link MJFormPresenterService.Open}. Supply EITHER a pre-loaded
9
+ * `Record`, OR `EntityName` + (`RecordId` / `PrimaryKey`) to load it (omit both
10
+ * keys for a new record).
11
+ */
12
+ export interface MJFormPresenterOptions {
13
+ /** Dialog (default), slide-in, or floating non-modal window. */
14
+ Presentation?: MJFormPresentation;
15
+ /** Entity name to load (ignored when `Record` is supplied). */
16
+ EntityName?: string;
17
+ /** Single-column ('ID') key convenience. */
18
+ RecordId?: string;
19
+ /** Full composite key (beats `RecordId`). */
20
+ PrimaryKey?: CompositeKey;
21
+ /** Pre-loaded record to bind directly. */
22
+ Record?: BaseEntity;
23
+ /** New-record default values (URL-segment string or object). */
24
+ NewRecordValues?: string | Record<string, unknown>;
25
+ /** Render a single registered form section instead of the full form. */
26
+ SectionName?: string;
27
+ /** Force edit mode (default: new → edit, existing → read). */
28
+ EditMode?: boolean;
29
+ /** Per-instance form config; defaults to the surface's preset. */
30
+ Config?: EntityFormConfig;
31
+ /** Chrome title; derived from the record when omitted. */
32
+ Title?: string;
33
+ /** Metadata provider for multi-provider apps. */
34
+ Provider?: IMetadataProvider;
35
+ /** Dialog width (px or CSS). */
36
+ Width?: number | string;
37
+ /** Slide-in initial width in px. */
38
+ WidthPx?: number;
39
+ /** Show the Save/Cancel footer. Default: true. */
40
+ ShowFooter?: boolean;
41
+ /** Save button label. */
42
+ SaveButtonText?: string;
43
+ /** Cancel button label. */
44
+ CancelButtonText?: string;
45
+ }
46
+ /**
47
+ * Handle to a form opened via {@link MJFormPresenterService.Open}.
48
+ * Resolve {@link AfterSaved} / {@link AfterClosed} or imperatively {@link Close}.
49
+ */
50
+ export declare class MJFormRef {
51
+ private readonly _saved;
52
+ private readonly _closed;
53
+ private readonly _closeFn;
54
+ private readonly _form;
55
+ constructor(_saved: Promise<BaseEntity | null>, _closed: Promise<FormOverlayCloseReason>, _closeFn: () => void, _form: () => BaseFormComponent | null);
56
+ /** Resolves with the saved entity, or `null` if the form was cancelled. */
57
+ AfterSaved(): Promise<BaseEntity | null>;
58
+ /** Resolves with how the overlay closed ('save' | 'cancel'). */
59
+ AfterClosed(): Promise<FormOverlayCloseReason>;
60
+ /** Programmatically close the overlay (treated as cancel — reverts edits). */
61
+ Close(): void;
62
+ /** The live form component instance (null before load / after teardown). */
63
+ get Form(): BaseFormComponent | null;
64
+ }
65
+ //# sourceMappingURL=form-presenter.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-presenter.types.d.ts","sourceRoot":"","sources":["../../../src/lib/overlays/form-presenter.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,wEAAwE;AACxE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,gEAAgE;IAChE,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAGlC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,kEAAkE;IAClE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2BAA2B;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,SAAS;IAElB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAHL,MAAM,EAAE,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAClC,OAAO,EAAE,OAAO,CAAC,sBAAsB,CAAC,EACxC,QAAQ,EAAE,MAAM,IAAI,EACpB,KAAK,EAAE,MAAM,iBAAiB,GAAG,IAAI;IAGxD,2EAA2E;IAC3E,UAAU,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAExC,gEAAgE;IAChE,WAAW,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAE9C,8EAA8E;IAC9E,KAAK,IAAI,IAAI;IAEb,4EAA4E;IAC5E,IAAI,IAAI,IAAI,iBAAiB,GAAG,IAAI,CAAyB;CAC9D"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Handle to a form opened via {@link MJFormPresenterService.Open}.
3
+ * Resolve {@link AfterSaved} / {@link AfterClosed} or imperatively {@link Close}.
4
+ */
5
+ export class MJFormRef {
6
+ _saved;
7
+ _closed;
8
+ _closeFn;
9
+ _form;
10
+ constructor(_saved, _closed, _closeFn, _form) {
11
+ this._saved = _saved;
12
+ this._closed = _closed;
13
+ this._closeFn = _closeFn;
14
+ this._form = _form;
15
+ }
16
+ /** Resolves with the saved entity, or `null` if the form was cancelled. */
17
+ AfterSaved() { return this._saved; }
18
+ /** Resolves with how the overlay closed ('save' | 'cancel'). */
19
+ AfterClosed() { return this._closed; }
20
+ /** Programmatically close the overlay (treated as cancel — reverts edits). */
21
+ Close() { this._closeFn(); }
22
+ /** The live form component instance (null before load / after teardown). */
23
+ get Form() { return this._form(); }
24
+ }
25
+ //# sourceMappingURL=form-presenter.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-presenter.types.js","sourceRoot":"","sources":["../../../src/lib/overlays/form-presenter.types.ts"],"names":[],"mappings":"AAoDA;;;GAGG;AACH,MAAM,OAAO,SAAS;IAED;IACA;IACA;IACA;IAJnB,YACmB,MAAkC,EAClC,OAAwC,EACxC,QAAoB,EACpB,KAAqC;QAHrC,WAAM,GAAN,MAAM,CAA4B;QAClC,YAAO,GAAP,OAAO,CAAiC;QACxC,aAAQ,GAAR,QAAQ,CAAY;QACpB,UAAK,GAAL,KAAK,CAAgC;IACrD,CAAC;IAEJ,2EAA2E;IAC3E,UAAU,KAAiC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhE,gEAAgE;IAChE,WAAW,KAAsC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEvE,8EAA8E;IAC9E,KAAK,KAAW,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAElC,4EAA4E;IAC5E,IAAI,IAAI,KAA+B,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;CAC9D","sourcesContent":["import { BaseEntity, CompositeKey, IMetadataProvider } from '@memberjunction/core';\nimport { BaseFormComponent } from '../base-form-component';\nimport { EntityFormConfig } from '../types/entity-form-config';\nimport { FormOverlayCloseReason } from './base-form-overlay';\n\n/** How a form should be presented by {@link MJFormPresenterService}. */\nexport type MJFormPresentation = 'dialog' | 'slide-in' | 'window';\n\n/**\n * Options for {@link MJFormPresenterService.Open}. Supply EITHER a pre-loaded\n * `Record`, OR `EntityName` + (`RecordId` / `PrimaryKey`) to load it (omit both\n * keys for a new record).\n */\nexport interface MJFormPresenterOptions {\n /** Dialog (default), slide-in, or floating non-modal window. */\n Presentation?: MJFormPresentation;\n\n // ── Record selection ──\n /** Entity name to load (ignored when `Record` is supplied). */\n EntityName?: string;\n /** Single-column ('ID') key convenience. */\n RecordId?: string;\n /** Full composite key (beats `RecordId`). */\n PrimaryKey?: CompositeKey;\n /** Pre-loaded record to bind directly. */\n Record?: BaseEntity;\n /** New-record default values (URL-segment string or object). */\n NewRecordValues?: string | Record<string, unknown>;\n /** Render a single registered form section instead of the full form. */\n SectionName?: string;\n /** Force edit mode (default: new → edit, existing → read). */\n EditMode?: boolean;\n\n // ── Presentation / config ──\n /** Per-instance form config; defaults to the surface's preset. */\n Config?: EntityFormConfig;\n /** Chrome title; derived from the record when omitted. */\n Title?: string;\n /** Metadata provider for multi-provider apps. */\n Provider?: IMetadataProvider;\n /** Dialog width (px or CSS). */\n Width?: number | string;\n /** Slide-in initial width in px. */\n WidthPx?: number;\n /** Show the Save/Cancel footer. Default: true. */\n ShowFooter?: boolean;\n /** Save button label. */\n SaveButtonText?: string;\n /** Cancel button label. */\n CancelButtonText?: string;\n}\n\n/**\n * Handle to a form opened via {@link MJFormPresenterService.Open}.\n * Resolve {@link AfterSaved} / {@link AfterClosed} or imperatively {@link Close}.\n */\nexport class MJFormRef {\n constructor(\n private readonly _saved: Promise<BaseEntity | null>,\n private readonly _closed: Promise<FormOverlayCloseReason>,\n private readonly _closeFn: () => void,\n private readonly _form: () => BaseFormComponent | null,\n ) {}\n\n /** Resolves with the saved entity, or `null` if the form was cancelled. */\n AfterSaved(): Promise<BaseEntity | null> { return this._saved; }\n\n /** Resolves with how the overlay closed ('save' | 'cancel'). */\n AfterClosed(): Promise<FormOverlayCloseReason> { return this._closed; }\n\n /** Programmatically close the overlay (treated as cancel — reverts edits). */\n Close(): void { this._closeFn(); }\n\n /** The live form component instance (null before load / after teardown). */\n get Form(): BaseFormComponent | null { return this._form(); }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { BaseFormOverlay } from './base-form-overlay';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Opens any MemberJunction entity form inside a right-edge slide-in panel.
6
+ *
7
+ * Wraps {@link MjEntityFormHostComponent} in `<mj-slide-panel>` (resizable) with
8
+ * a sticky Save/Cancel footer. Defaults to {@link SLIDEIN_FORM_CONFIG} (no in-form
9
+ * toolbar, related grids hidden, full-width body, in-form links inert).
10
+ *
11
+ * Standalone — import it directly:
12
+ * ```typescript
13
+ * import { MjFormSlideInComponent } from '@memberjunction/ng-base-forms';
14
+ * ```
15
+ *
16
+ * @example Declarative
17
+ * ```html
18
+ * <mj-form-slide-in [EntityName]="'MJ: Credentials'" [Record]="cred"
19
+ * [(Visible)]="open" (Saved)="refresh()"></mj-form-slide-in>
20
+ * ```
21
+ */
22
+ export declare class MjFormSlideInComponent extends BaseFormOverlay implements OnInit {
23
+ /** Initial panel width in px (resizable by the user; persisted per-entity). */
24
+ WidthPx: number;
25
+ /** Whether the panel is user-resizable. */
26
+ Resizable: boolean;
27
+ /** Form config. Defaults to the slide-in preset; consumers can override. */
28
+ protected get PresetConfig(): import("../types/entity-form-config").EntityFormConfig;
29
+ /** Entity used to scope the persisted width (resolved on init). */
30
+ private widthEntity;
31
+ ngOnInit(): void;
32
+ /** Persist the user's resize, scoped per-entity (cross-device via User Settings). */
33
+ onWidthChanged(width: number): void;
34
+ private widthKey;
35
+ static ɵfac: i0.ɵɵFactoryDeclaration<MjFormSlideInComponent, never>;
36
+ static ɵcmp: i0.ɵɵComponentDeclaration<MjFormSlideInComponent, "mj-form-slide-in", never, { "WidthPx": { "alias": "WidthPx"; "required": false; }; "Resizable": { "alias": "Resizable"; "required": false; }; }, {}, never, never, true, never>;
37
+ }
38
+ //# sourceMappingURL=form-slide-in.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-slide-in.component.d.ts","sourceRoot":"","sources":["../../../src/lib/overlays/form-slide-in.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,MAAM,eAAe,CAAC;AAMzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;;AAGtD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAOa,sBAAuB,SAAQ,eAAgB,YAAW,MAAM;IAC3E,+EAA+E;IACtE,OAAO,SAAO;IACvB,2CAA2C;IAClC,SAAS,UAAQ;IAE1B,4EAA4E;IAC5E,cAAuB,YAAY,2DAAkC;IAErE,mEAAmE;IACnE,OAAO,CAAC,WAAW,CAAuB;IAE1C,QAAQ,IAAI,IAAI;IAWhB,qFAAqF;IACrF,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOnC,OAAO,CAAC,QAAQ;yCA/BL,sBAAsB;2CAAtB,sBAAsB;CAkClC"}
@@ -0,0 +1,106 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { MjSlidePanelComponent, MJButtonDirective } from '@memberjunction/ng-ui-components';
4
+ import { UserInfoEngine } from '@memberjunction/core-entities';
5
+ import { BaseFormsModule } from '../../module';
6
+ import { BaseFormOverlay } from './base-form-overlay';
7
+ import { SLIDEIN_FORM_CONFIG } from '../types/entity-form-config';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "../host/entity-form-host.component";
10
+ function MjFormSlideInComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
11
+ const _r2 = i0.ɵɵgetCurrentView();
12
+ i0.ɵɵelementStart(0, "div", 5)(1, "button", 6);
13
+ i0.ɵɵlistener("click", function MjFormSlideInComponent_Conditional_5_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSaveClick()); });
14
+ i0.ɵɵtext(2);
15
+ i0.ɵɵelementEnd();
16
+ i0.ɵɵelementStart(3, "button", 7);
17
+ i0.ɵɵlistener("click", function MjFormSlideInComponent_Conditional_5_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCancel()); });
18
+ i0.ɵɵtext(4);
19
+ i0.ɵɵelementEnd()();
20
+ } if (rf & 2) {
21
+ const ctx_r2 = i0.ɵɵnextContext();
22
+ i0.ɵɵadvance();
23
+ i0.ɵɵproperty("disabled", ctx_r2.saving);
24
+ i0.ɵɵadvance();
25
+ i0.ɵɵtextInterpolate(ctx_r2.SaveButtonText);
26
+ i0.ɵɵadvance();
27
+ i0.ɵɵproperty("disabled", ctx_r2.saving);
28
+ i0.ɵɵadvance();
29
+ i0.ɵɵtextInterpolate(ctx_r2.CancelButtonText);
30
+ } }
31
+ /**
32
+ * Opens any MemberJunction entity form inside a right-edge slide-in panel.
33
+ *
34
+ * Wraps {@link MjEntityFormHostComponent} in `<mj-slide-panel>` (resizable) with
35
+ * a sticky Save/Cancel footer. Defaults to {@link SLIDEIN_FORM_CONFIG} (no in-form
36
+ * toolbar, related grids hidden, full-width body, in-form links inert).
37
+ *
38
+ * Standalone — import it directly:
39
+ * ```typescript
40
+ * import { MjFormSlideInComponent } from '@memberjunction/ng-base-forms';
41
+ * ```
42
+ *
43
+ * @example Declarative
44
+ * ```html
45
+ * <mj-form-slide-in [EntityName]="'MJ: Credentials'" [Record]="cred"
46
+ * [(Visible)]="open" (Saved)="refresh()"></mj-form-slide-in>
47
+ * ```
48
+ */
49
+ export class MjFormSlideInComponent extends BaseFormOverlay {
50
+ /** Initial panel width in px (resizable by the user; persisted per-entity). */
51
+ WidthPx = 720;
52
+ /** Whether the panel is user-resizable. */
53
+ Resizable = true;
54
+ /** Form config. Defaults to the slide-in preset; consumers can override. */
55
+ get PresetConfig() { return SLIDEIN_FORM_CONFIG; }
56
+ /** Entity used to scope the persisted width (resolved on init). */
57
+ widthEntity = null;
58
+ ngOnInit() {
59
+ // Resolve the entity up-front so we can restore the user's saved width
60
+ // before the panel animates in (avoids a mid-render resize).
61
+ this.widthEntity = this.EntityName ?? this.Record?.EntityInfo?.Name ?? null;
62
+ if (this.widthEntity) {
63
+ const saved = UserInfoEngine.Instance.GetSetting(this.widthKey(this.widthEntity));
64
+ const px = saved ? parseInt(saved, 10) : 0;
65
+ if (px > 0)
66
+ this.WidthPx = px;
67
+ }
68
+ }
69
+ /** Persist the user's resize, scoped per-entity (cross-device via User Settings). */
70
+ onWidthChanged(width) {
71
+ this.WidthPx = width;
72
+ if (this.widthEntity) {
73
+ UserInfoEngine.Instance.SetSettingDebounced(this.widthKey(this.widthEntity), String(width));
74
+ }
75
+ }
76
+ widthKey(entity) {
77
+ return `mj.formSlideIn.width.${entity.toLowerCase()}`;
78
+ }
79
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMjFormSlideInComponent_BaseFactory; return function MjFormSlideInComponent_Factory(__ngFactoryType__) { return (ɵMjFormSlideInComponent_BaseFactory || (ɵMjFormSlideInComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MjFormSlideInComponent)))(__ngFactoryType__ || MjFormSlideInComponent); }; })();
80
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjFormSlideInComponent, selectors: [["mj-form-slide-in"]], inputs: { WidthPx: "WidthPx", Resizable: "Resizable" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 13, consts: [["host", ""], ["Mode", "slide", 3, "WidthChanged", "Closed", "Visible", "Title", "Resizable", "WidthPx"], [1, "mj-form-slide-in-layout"], [1, "mj-form-slide-in-body"], [3, "Saved", "Dismissed", "FormCreated", "Navigate", "Notification", "RecordDeleted", "RecordSaveFailed", "ValidationFailed", "LoadError", "EntityName", "PrimaryKey", "Record", "NewRecordValues", "SectionName", "EditMode", "Config", "Provider"], [1, "mj-form-slide-in-footer"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"]], template: function MjFormSlideInComponent_Template(rf, ctx) { if (rf & 1) {
81
+ const _r1 = i0.ɵɵgetCurrentView();
82
+ i0.ɵɵelementStart(0, "mj-slide-panel", 1);
83
+ i0.ɵɵlistener("WidthChanged", function MjFormSlideInComponent_Template_mj_slide_panel_WidthChanged_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onWidthChanged($event)); })("Closed", function MjFormSlideInComponent_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCancel()); });
84
+ i0.ɵɵelementStart(1, "div", 2)(2, "div", 3)(3, "mj-entity-form-host", 4, 0);
85
+ i0.ɵɵlistener("Saved", function MjFormSlideInComponent_Template_mj_entity_form_host_Saved_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onHostSaved($event)); })("Dismissed", function MjFormSlideInComponent_Template_mj_entity_form_host_Dismissed_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onHostDismissed()); })("FormCreated", function MjFormSlideInComponent_Template_mj_entity_form_host_FormCreated_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFormCreated($event)); })("Navigate", function MjFormSlideInComponent_Template_mj_entity_form_host_Navigate_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.Navigate.emit($event)); })("Notification", function MjFormSlideInComponent_Template_mj_entity_form_host_Notification_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.Notification.emit($event)); })("RecordDeleted", function MjFormSlideInComponent_Template_mj_entity_form_host_RecordDeleted_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.RecordDeleted.emit($event)); })("RecordSaveFailed", function MjFormSlideInComponent_Template_mj_entity_form_host_RecordSaveFailed_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.RecordSaveFailed.emit($event)); })("ValidationFailed", function MjFormSlideInComponent_Template_mj_entity_form_host_ValidationFailed_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.ValidationFailed.emit($event)); })("LoadError", function MjFormSlideInComponent_Template_mj_entity_form_host_LoadError_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.LoadError.emit($event)); });
86
+ i0.ɵɵelementEnd()();
87
+ i0.ɵɵconditionalCreate(5, MjFormSlideInComponent_Conditional_5_Template, 5, 4, "div", 5);
88
+ i0.ɵɵelementEnd()();
89
+ } if (rf & 2) {
90
+ i0.ɵɵproperty("Visible", ctx.Visible)("Title", ctx.effectiveTitle)("Resizable", ctx.Resizable)("WidthPx", ctx.WidthPx);
91
+ i0.ɵɵadvance(3);
92
+ i0.ɵɵproperty("EntityName", ctx.EntityName)("PrimaryKey", ctx.effectivePrimaryKey)("Record", ctx.Record)("NewRecordValues", ctx.NewRecordValues)("SectionName", ctx.SectionName)("EditMode", ctx.EditMode)("Config", ctx.EffectiveConfig)("Provider", ctx.Provider);
93
+ i0.ɵɵadvance(2);
94
+ i0.ɵɵconditional(ctx.ShowFooter ? 5 : -1);
95
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjEntityFormHostComponent, MjSlidePanelComponent, MJButtonDirective], styles: [".mj-form-slide-in-layout[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n}\n\n.mj-form-slide-in-body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n\n.mj-form-slide-in-footer[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}"] });
96
+ }
97
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjFormSlideInComponent, [{
98
+ type: Component,
99
+ args: [{ standalone: true, selector: 'mj-form-slide-in', imports: [CommonModule, BaseFormsModule, MjSlidePanelComponent, MJButtonDirective], template: "<mj-slide-panel\n Mode=\"slide\"\n [Visible]=\"Visible\"\n [Title]=\"effectiveTitle\"\n [Resizable]=\"Resizable\"\n [WidthPx]=\"WidthPx\"\n (WidthChanged)=\"onWidthChanged($event)\"\n (Closed)=\"onCancel()\">\n\n <div class=\"mj-form-slide-in-layout\">\n <div class=\"mj-form-slide-in-body\">\n <mj-entity-form-host #host\n [EntityName]=\"EntityName\"\n [PrimaryKey]=\"effectivePrimaryKey!\"\n [Record]=\"Record\"\n [NewRecordValues]=\"NewRecordValues\"\n [SectionName]=\"SectionName\"\n [EditMode]=\"EditMode\"\n [Config]=\"EffectiveConfig\"\n [Provider]=\"Provider\"\n (Saved)=\"onHostSaved($event)\"\n (Dismissed)=\"onHostDismissed()\"\n (FormCreated)=\"onFormCreated($event)\"\n (Navigate)=\"Navigate.emit($event)\"\n (Notification)=\"Notification.emit($event)\"\n (RecordDeleted)=\"RecordDeleted.emit($event)\"\n (RecordSaveFailed)=\"RecordSaveFailed.emit($event)\"\n (ValidationFailed)=\"ValidationFailed.emit($event)\"\n (LoadError)=\"LoadError.emit($event)\">\n </mj-entity-form-host>\n </div>\n\n @if (ShowFooter) {\n <div class=\"mj-form-slide-in-footer\">\n <button mjButton variant=\"primary\" [disabled]=\"saving\" (click)=\"onSaveClick()\">{{ SaveButtonText }}</button>\n <button mjButton [disabled]=\"saving\" (click)=\"onCancel()\">{{ CancelButtonText }}</button>\n </div>\n }\n </div>\n</mj-slide-panel>\n", styles: [".mj-form-slide-in-layout {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n}\n\n.mj-form-slide-in-body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n\n.mj-form-slide-in-footer {\n flex-shrink: 0;\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n"] }]
100
+ }], null, { WidthPx: [{
101
+ type: Input
102
+ }], Resizable: [{
103
+ type: Input
104
+ }] }); })();
105
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjFormSlideInComponent, { className: "MjFormSlideInComponent", filePath: "src/lib/overlays/form-slide-in.component.ts", lineNumber: 35 }); })();
106
+ //# sourceMappingURL=form-slide-in.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-slide-in.component.js","sourceRoot":"","sources":["../../../src/lib/overlays/form-slide-in.component.ts","../../../src/lib/overlays/form-slide-in.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAU,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;;;;;IC2B1D,AADF,8BAAqC,gBAC4C;IAAxB,0LAAS,oBAAa,KAAC;IAAC,YAAoB;IAAA,iBAAS;IAC5G,iCAA0D;IAArB,0LAAS,iBAAU,KAAC;IAAC,YAAsB;IAClF,AADkF,iBAAS,EACrF;;;IAF+B,cAAmB;IAAnB,wCAAmB;IAAyB,cAAoB;IAApB,2CAAoB;IAClF,cAAmB;IAAnB,wCAAmB;IAAsB,cAAsB;IAAtB,6CAAsB;;AD1BxF;;;;;;;;;;;;;;;;;GAiBG;AAQH,MAAM,OAAO,sBAAuB,SAAQ,eAAe;IACzD,+EAA+E;IACtE,OAAO,GAAG,GAAG,CAAC;IACvB,2CAA2C;IAClC,SAAS,GAAG,IAAI,CAAC;IAE1B,4EAA4E;IAC5E,IAAuB,YAAY,KAAK,OAAO,mBAAmB,CAAC,CAAC,CAAC;IAErE,mEAAmE;IAC3D,WAAW,GAAkB,IAAI,CAAC;IAE1C,QAAQ;QACN,uEAAuE;QACvE,6DAA6D;QAC7D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,CAAC;QAC5E,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAClF,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,EAAE,GAAG,CAAC;gBAAE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,qFAAqF;IACrF,cAAc,CAAC,KAAa;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,MAAc;QAC7B,OAAO,wBAAwB,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;IACxD,CAAC;qQAjCU,sBAAsB,yBAAtB,sBAAsB;6DAAtB,sBAAsB;;YClCnC,yCAOwB;YAAtB,AADA,qKAAgB,0BAAsB,KAAC,sIAC7B,cAAU,KAAC;YAIjB,AADF,AADF,8BAAqC,aACA,gCAkBM;YAArC,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,4JAAS,uBAAmB,KAAC,iJAChB,qBAAiB,KAAC,2JAChB,yBAAqB,KAAC,qJACzB,yBAAqB,KAAC,6JAClB,6BAAyB,KAAC,+JACzB,8BAA0B,KAAC,qKACxB,iCAA6B,KAAC,qKAC9B,iCAA6B,KAAC,uJACrC,0BAAsB,KAAC;YAExC,AADE,iBAAsB,EAClB;YAEN,wFAAkB;YAOtB,AADE,iBAAM,EACS;;YAlCf,AADA,AADA,AADA,qCAAmB,6BACK,4BACD,wBACJ;YAOb,eAAyB;YAOzB,AADA,AADA,AADA,AADA,AADA,AADA,AADA,2CAAyB,uCACU,sBAClB,wCACkB,gCACR,0BACN,+BACK,0BACL;YAazB,eAKC;YALD,yCAKC;4BDPO,YAAY,EAAE,eAAe,gCAAE,qBAAqB,EAAE,iBAAiB;;iFAItE,sBAAsB;cAPlC,SAAS;6BACI,IAAI,YACN,kBAAkB,WACnB,CAAC,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,iBAAiB,CAAC;;kBAMjF,KAAK;;kBAEL,KAAK;;kFAJK,sBAAsB","sourcesContent":["import { Component, Input, OnInit } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MjSlidePanelComponent, MJButtonDirective } from '@memberjunction/ng-ui-components';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\n\nimport { BaseFormsModule } from '../../module';\nimport { BaseFormOverlay } from './base-form-overlay';\nimport { SLIDEIN_FORM_CONFIG } from '../types/entity-form-config';\n\n/**\n * Opens any MemberJunction entity form inside a right-edge slide-in panel.\n *\n * Wraps {@link MjEntityFormHostComponent} in `<mj-slide-panel>` (resizable) with\n * a sticky Save/Cancel footer. Defaults to {@link SLIDEIN_FORM_CONFIG} (no in-form\n * toolbar, related grids hidden, full-width body, in-form links inert).\n *\n * Standalone — import it directly:\n * ```typescript\n * import { MjFormSlideInComponent } from '@memberjunction/ng-base-forms';\n * ```\n *\n * @example Declarative\n * ```html\n * <mj-form-slide-in [EntityName]=\"'MJ: Credentials'\" [Record]=\"cred\"\n * [(Visible)]=\"open\" (Saved)=\"refresh()\"></mj-form-slide-in>\n * ```\n */\n@Component({\n standalone: true,\n selector: 'mj-form-slide-in',\n imports: [CommonModule, BaseFormsModule, MjSlidePanelComponent, MJButtonDirective],\n templateUrl: './form-slide-in.component.html',\n styleUrls: ['./form-slide-in.component.css'],\n})\nexport class MjFormSlideInComponent extends BaseFormOverlay implements OnInit {\n /** Initial panel width in px (resizable by the user; persisted per-entity). */\n @Input() WidthPx = 720;\n /** Whether the panel is user-resizable. */\n @Input() Resizable = true;\n\n /** Form config. Defaults to the slide-in preset; consumers can override. */\n protected override get PresetConfig() { return SLIDEIN_FORM_CONFIG; }\n\n /** Entity used to scope the persisted width (resolved on init). */\n private widthEntity: string | null = null;\n\n ngOnInit(): void {\n // Resolve the entity up-front so we can restore the user's saved width\n // before the panel animates in (avoids a mid-render resize).\n this.widthEntity = this.EntityName ?? this.Record?.EntityInfo?.Name ?? null;\n if (this.widthEntity) {\n const saved = UserInfoEngine.Instance.GetSetting(this.widthKey(this.widthEntity));\n const px = saved ? parseInt(saved, 10) : 0;\n if (px > 0) this.WidthPx = px;\n }\n }\n\n /** Persist the user's resize, scoped per-entity (cross-device via User Settings). */\n onWidthChanged(width: number): void {\n this.WidthPx = width;\n if (this.widthEntity) {\n UserInfoEngine.Instance.SetSettingDebounced(this.widthKey(this.widthEntity), String(width));\n }\n }\n\n private widthKey(entity: string): string {\n return `mj.formSlideIn.width.${entity.toLowerCase()}`;\n }\n}\n","<mj-slide-panel\n Mode=\"slide\"\n [Visible]=\"Visible\"\n [Title]=\"effectiveTitle\"\n [Resizable]=\"Resizable\"\n [WidthPx]=\"WidthPx\"\n (WidthChanged)=\"onWidthChanged($event)\"\n (Closed)=\"onCancel()\">\n\n <div class=\"mj-form-slide-in-layout\">\n <div class=\"mj-form-slide-in-body\">\n <mj-entity-form-host #host\n [EntityName]=\"EntityName\"\n [PrimaryKey]=\"effectivePrimaryKey!\"\n [Record]=\"Record\"\n [NewRecordValues]=\"NewRecordValues\"\n [SectionName]=\"SectionName\"\n [EditMode]=\"EditMode\"\n [Config]=\"EffectiveConfig\"\n [Provider]=\"Provider\"\n (Saved)=\"onHostSaved($event)\"\n (Dismissed)=\"onHostDismissed()\"\n (FormCreated)=\"onFormCreated($event)\"\n (Navigate)=\"Navigate.emit($event)\"\n (Notification)=\"Notification.emit($event)\"\n (RecordDeleted)=\"RecordDeleted.emit($event)\"\n (RecordSaveFailed)=\"RecordSaveFailed.emit($event)\"\n (ValidationFailed)=\"ValidationFailed.emit($event)\"\n (LoadError)=\"LoadError.emit($event)\">\n </mj-entity-form-host>\n </div>\n\n @if (ShowFooter) {\n <div class=\"mj-form-slide-in-footer\">\n <button mjButton variant=\"primary\" [disabled]=\"saving\" (click)=\"onSaveClick()\">{{ SaveButtonText }}</button>\n <button mjButton [disabled]=\"saving\" (click)=\"onCancel()\">{{ CancelButtonText }}</button>\n </div>\n }\n </div>\n</mj-slide-panel>\n"]}
@@ -0,0 +1,32 @@
1
+ import { BaseFormOverlay } from './base-form-overlay';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Opens any MemberJunction entity form inside a floating, **non-modal** window
5
+ * (draggable + resizable, no backdrop). Good for "keep this open while I work
6
+ * elsewhere" scenarios — comparing records, reference-while-editing, etc.
7
+ *
8
+ * Same host + event surface as {@link MjFormDialogComponent}; only the chrome
9
+ * differs (`mj-window` instead of `mj-dialog`). Defaults to
10
+ * {@link DIALOG_FORM_CONFIG} (no in-form toolbar; the window footer owns
11
+ * Save/Cancel).
12
+ *
13
+ * Standalone — import it directly:
14
+ * ```typescript
15
+ * import { MjFormWindowComponent } from '@memberjunction/ng-base-forms';
16
+ * ```
17
+ */
18
+ export declare class MjFormWindowComponent extends BaseFormOverlay {
19
+ /** Window width (px or CSS string). */
20
+ Width: number | string | null;
21
+ /** Window height (px or CSS string). */
22
+ Height: number | string | null;
23
+ /** Whether the window can be dragged by its titlebar. */
24
+ Draggable: boolean;
25
+ /** Whether the window can be resized. */
26
+ Resizable: boolean;
27
+ /** Form config. Defaults to the dialog preset (no in-form toolbar). */
28
+ protected get PresetConfig(): import("../types/entity-form-config").EntityFormConfig;
29
+ static ɵfac: i0.ɵɵFactoryDeclaration<MjFormWindowComponent, never>;
30
+ static ɵcmp: i0.ɵɵComponentDeclaration<MjFormWindowComponent, "mj-form-window", never, { "Width": { "alias": "Width"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; "Draggable": { "alias": "Draggable"; "required": false; }; "Resizable": { "alias": "Resizable"; "required": false; }; }, {}, never, never, true, never>;
31
+ }
32
+ //# sourceMappingURL=form-window.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-window.component.d.ts","sourceRoot":"","sources":["../../../src/lib/overlays/form-window.component.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;;AAGtD;;;;;;;;;;;;;;GAcG;AACH,qBAMa,qBAAsB,SAAQ,eAAe;IACxD,uCAAuC;IAC9B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAO;IAC7C,wCAAwC;IAC/B,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAO;IAC9C,yDAAyD;IAChD,SAAS,UAAQ;IAC1B,yCAAyC;IAChC,SAAS,UAAQ;IAE1B,uEAAuE;IACvE,cAAuB,YAAY,2DAAiC;yCAXzD,qBAAqB;2CAArB,qBAAqB;CAYjC"}
@@ -0,0 +1,93 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { MJWindowComponent, MJWindowActionsComponent, MJButtonDirective } from '@memberjunction/ng-ui-components';
4
+ import { BaseFormsModule } from '../../module';
5
+ import { BaseFormOverlay } from './base-form-overlay';
6
+ import { DIALOG_FORM_CONFIG } from '../types/entity-form-config';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "../host/entity-form-host.component";
9
+ function MjFormWindowComponent_Conditional_0_Conditional_3_Template(rf, ctx) { if (rf & 1) {
10
+ const _r3 = i0.ɵɵgetCurrentView();
11
+ i0.ɵɵelementStart(0, "mj-window-actions")(1, "button", 4);
12
+ i0.ɵɵlistener("click", function MjFormWindowComponent_Conditional_0_Conditional_3_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onSaveClick()); });
13
+ i0.ɵɵtext(2);
14
+ i0.ɵɵelementEnd();
15
+ i0.ɵɵelementStart(3, "button", 5);
16
+ i0.ɵɵlistener("click", function MjFormWindowComponent_Conditional_0_Conditional_3_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onCancel()); });
17
+ i0.ɵɵtext(4);
18
+ i0.ɵɵelementEnd()();
19
+ } if (rf & 2) {
20
+ const ctx_r1 = i0.ɵɵnextContext(2);
21
+ i0.ɵɵadvance();
22
+ i0.ɵɵproperty("disabled", ctx_r1.saving);
23
+ i0.ɵɵadvance();
24
+ i0.ɵɵtextInterpolate(ctx_r1.SaveButtonText);
25
+ i0.ɵɵadvance();
26
+ i0.ɵɵproperty("disabled", ctx_r1.saving);
27
+ i0.ɵɵadvance();
28
+ i0.ɵɵtextInterpolate(ctx_r1.CancelButtonText);
29
+ } }
30
+ function MjFormWindowComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
31
+ const _r1 = i0.ɵɵgetCurrentView();
32
+ i0.ɵɵelementStart(0, "mj-window", 2);
33
+ i0.ɵɵlistener("Close", function MjFormWindowComponent_Conditional_0_Template_mj_window_Close_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCancel()); });
34
+ i0.ɵɵelementStart(1, "mj-entity-form-host", 3, 0);
35
+ i0.ɵɵlistener("Saved", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_Saved_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onHostSaved($event)); })("Dismissed", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_Dismissed_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onHostDismissed()); })("FormCreated", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_FormCreated_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFormCreated($event)); })("Navigate", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Navigate.emit($event)); })("Notification", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_Notification_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Notification.emit($event)); })("RecordDeleted", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_RecordDeleted_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RecordDeleted.emit($event)); })("RecordSaveFailed", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_RecordSaveFailed_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RecordSaveFailed.emit($event)); })("ValidationFailed", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_ValidationFailed_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ValidationFailed.emit($event)); })("LoadError", function MjFormWindowComponent_Conditional_0_Template_mj_entity_form_host_LoadError_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.LoadError.emit($event)); });
36
+ i0.ɵɵelementEnd();
37
+ i0.ɵɵconditionalCreate(3, MjFormWindowComponent_Conditional_0_Conditional_3_Template, 5, 4, "mj-window-actions");
38
+ i0.ɵɵelementEnd();
39
+ } if (rf & 2) {
40
+ const ctx_r1 = i0.ɵɵnextContext();
41
+ i0.ɵɵproperty("Visible", true)("Title", ctx_r1.effectiveTitle)("Width", ctx_r1.Width)("Height", ctx_r1.Height)("Draggable", ctx_r1.Draggable)("Resizable", ctx_r1.Resizable);
42
+ i0.ɵɵadvance();
43
+ i0.ɵɵproperty("EntityName", ctx_r1.EntityName)("PrimaryKey", ctx_r1.effectivePrimaryKey)("Record", ctx_r1.Record)("NewRecordValues", ctx_r1.NewRecordValues)("SectionName", ctx_r1.SectionName)("EditMode", ctx_r1.EditMode)("Config", ctx_r1.EffectiveConfig)("Provider", ctx_r1.Provider);
44
+ i0.ɵɵadvance(2);
45
+ i0.ɵɵconditional(ctx_r1.ShowFooter ? 3 : -1);
46
+ } }
47
+ /**
48
+ * Opens any MemberJunction entity form inside a floating, **non-modal** window
49
+ * (draggable + resizable, no backdrop). Good for "keep this open while I work
50
+ * elsewhere" scenarios — comparing records, reference-while-editing, etc.
51
+ *
52
+ * Same host + event surface as {@link MjFormDialogComponent}; only the chrome
53
+ * differs (`mj-window` instead of `mj-dialog`). Defaults to
54
+ * {@link DIALOG_FORM_CONFIG} (no in-form toolbar; the window footer owns
55
+ * Save/Cancel).
56
+ *
57
+ * Standalone — import it directly:
58
+ * ```typescript
59
+ * import { MjFormWindowComponent } from '@memberjunction/ng-base-forms';
60
+ * ```
61
+ */
62
+ export class MjFormWindowComponent extends BaseFormOverlay {
63
+ /** Window width (px or CSS string). */
64
+ Width = 760;
65
+ /** Window height (px or CSS string). */
66
+ Height = 560;
67
+ /** Whether the window can be dragged by its titlebar. */
68
+ Draggable = true;
69
+ /** Whether the window can be resized. */
70
+ Resizable = true;
71
+ /** Form config. Defaults to the dialog preset (no in-form toolbar). */
72
+ get PresetConfig() { return DIALOG_FORM_CONFIG; }
73
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMjFormWindowComponent_BaseFactory; return function MjFormWindowComponent_Factory(__ngFactoryType__) { return (ɵMjFormWindowComponent_BaseFactory || (ɵMjFormWindowComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MjFormWindowComponent)))(__ngFactoryType__ || MjFormWindowComponent); }; })();
74
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjFormWindowComponent, selectors: [["mj-form-window"]], inputs: { Width: "Width", Height: "Height", Draggable: "Draggable", Resizable: "Resizable" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["host", ""], [3, "Visible", "Title", "Width", "Height", "Draggable", "Resizable"], [3, "Close", "Visible", "Title", "Width", "Height", "Draggable", "Resizable"], [3, "Saved", "Dismissed", "FormCreated", "Navigate", "Notification", "RecordDeleted", "RecordSaveFailed", "ValidationFailed", "LoadError", "EntityName", "PrimaryKey", "Record", "NewRecordValues", "SectionName", "EditMode", "Config", "Provider"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"]], template: function MjFormWindowComponent_Template(rf, ctx) { if (rf & 1) {
75
+ i0.ɵɵconditionalCreate(0, MjFormWindowComponent_Conditional_0_Template, 4, 15, "mj-window", 1);
76
+ } if (rf & 2) {
77
+ i0.ɵɵconditional(ctx.Visible ? 0 : -1);
78
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjEntityFormHostComponent, MJWindowComponent, MJWindowActionsComponent, MJButtonDirective], encapsulation: 2 });
79
+ }
80
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjFormWindowComponent, [{
81
+ type: Component,
82
+ args: [{ standalone: true, selector: 'mj-form-window', imports: [CommonModule, BaseFormsModule, MJWindowComponent, MJWindowActionsComponent, MJButtonDirective], template: "@if (Visible) {\n <mj-window\n [Visible]=\"true\"\n [Title]=\"effectiveTitle\"\n [Width]=\"Width\"\n [Height]=\"Height\"\n [Draggable]=\"Draggable\"\n [Resizable]=\"Resizable\"\n (Close)=\"onCancel()\">\n\n <mj-entity-form-host #host\n [EntityName]=\"EntityName\"\n [PrimaryKey]=\"effectivePrimaryKey!\"\n [Record]=\"Record\"\n [NewRecordValues]=\"NewRecordValues\"\n [SectionName]=\"SectionName\"\n [EditMode]=\"EditMode\"\n [Config]=\"EffectiveConfig\"\n [Provider]=\"Provider\"\n (Saved)=\"onHostSaved($event)\"\n (Dismissed)=\"onHostDismissed()\"\n (FormCreated)=\"onFormCreated($event)\"\n (Navigate)=\"Navigate.emit($event)\"\n (Notification)=\"Notification.emit($event)\"\n (RecordDeleted)=\"RecordDeleted.emit($event)\"\n (RecordSaveFailed)=\"RecordSaveFailed.emit($event)\"\n (ValidationFailed)=\"ValidationFailed.emit($event)\"\n (LoadError)=\"LoadError.emit($event)\">\n </mj-entity-form-host>\n\n @if (ShowFooter) {\n <mj-window-actions>\n <button mjButton variant=\"primary\" [disabled]=\"saving\" (click)=\"onSaveClick()\">{{ SaveButtonText }}</button>\n <button mjButton [disabled]=\"saving\" (click)=\"onCancel()\">{{ CancelButtonText }}</button>\n </mj-window-actions>\n }\n </mj-window>\n}\n" }]
83
+ }], null, { Width: [{
84
+ type: Input
85
+ }], Height: [{
86
+ type: Input
87
+ }], Draggable: [{
88
+ type: Input
89
+ }], Resizable: [{
90
+ type: Input
91
+ }] }); })();
92
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjFormWindowComponent, { className: "MjFormWindowComponent", filePath: "src/lib/overlays/form-window.component.ts", lineNumber: 30 }); })();
93
+ //# sourceMappingURL=form-window.component.js.map