@memberjunction/core-actions 6.2.0-edge.2 → 6.2.0-edge.3

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 (62) hide show
  1. package/dist/custom/ai/execute-agent.action.d.ts +10 -0
  2. package/dist/custom/ai/execute-agent.action.d.ts.map +1 -1
  3. package/dist/custom/ai/execute-agent.action.js +24 -1
  4. package/dist/custom/ai/execute-agent.action.js.map +1 -1
  5. package/dist/custom/ai/execute-ai-prompt.action.d.ts.map +1 -1
  6. package/dist/custom/ai/execute-ai-prompt.action.js +3 -0
  7. package/dist/custom/ai/execute-ai-prompt.action.js.map +1 -1
  8. package/dist/custom/ai/generate-image.action.d.ts +5 -2
  9. package/dist/custom/ai/generate-image.action.d.ts.map +1 -1
  10. package/dist/custom/ai/generate-image.action.js +18 -8
  11. package/dist/custom/ai/generate-image.action.js.map +1 -1
  12. package/dist/custom/ai/summarize-content.action.d.ts.map +1 -1
  13. package/dist/custom/ai/summarize-content.action.js +3 -0
  14. package/dist/custom/ai/summarize-content.action.js.map +1 -1
  15. package/dist/custom/data/run-adhoc-query.action.d.ts.map +1 -1
  16. package/dist/custom/data/run-adhoc-query.action.js +3 -0
  17. package/dist/custom/data/run-adhoc-query.action.js.map +1 -1
  18. package/dist/custom/interactive-forms/_shared.d.ts +113 -31
  19. package/dist/custom/interactive-forms/_shared.d.ts.map +1 -1
  20. package/dist/custom/interactive-forms/_shared.js +198 -74
  21. package/dist/custom/interactive-forms/_shared.js.map +1 -1
  22. package/dist/custom/interactive-forms/activate-form-contribution-version.action.d.ts +23 -0
  23. package/dist/custom/interactive-forms/activate-form-contribution-version.action.d.ts.map +1 -0
  24. package/dist/custom/interactive-forms/activate-form-contribution-version.action.js +151 -0
  25. package/dist/custom/interactive-forms/activate-form-contribution-version.action.js.map +1 -0
  26. package/dist/custom/interactive-forms/activate-interactive-form-version.action.d.ts +23 -7
  27. package/dist/custom/interactive-forms/activate-interactive-form-version.action.d.ts.map +1 -1
  28. package/dist/custom/interactive-forms/activate-interactive-form-version.action.js +114 -58
  29. package/dist/custom/interactive-forms/activate-interactive-form-version.action.js.map +1 -1
  30. package/dist/custom/interactive-forms/create-form-contribution.action.d.ts +35 -0
  31. package/dist/custom/interactive-forms/create-form-contribution.action.d.ts.map +1 -0
  32. package/dist/custom/interactive-forms/create-form-contribution.action.js +149 -0
  33. package/dist/custom/interactive-forms/create-form-contribution.action.js.map +1 -0
  34. package/dist/custom/interactive-forms/get-active-form-for-entity.action.d.ts +3 -0
  35. package/dist/custom/interactive-forms/get-active-form-for-entity.action.d.ts.map +1 -1
  36. package/dist/custom/interactive-forms/get-active-form-for-entity.action.js +5 -1
  37. package/dist/custom/interactive-forms/get-active-form-for-entity.action.js.map +1 -1
  38. package/dist/custom/interactive-forms/get-form-composition-for-entity.action.d.ts +59 -0
  39. package/dist/custom/interactive-forms/get-form-composition-for-entity.action.d.ts.map +1 -0
  40. package/dist/custom/interactive-forms/get-form-composition-for-entity.action.js +313 -0
  41. package/dist/custom/interactive-forms/get-form-composition-for-entity.action.js.map +1 -0
  42. package/dist/custom/interactive-forms/get-form-contributions-for-entity.action.d.ts +47 -0
  43. package/dist/custom/interactive-forms/get-form-contributions-for-entity.action.d.ts.map +1 -0
  44. package/dist/custom/interactive-forms/get-form-contributions-for-entity.action.js +115 -0
  45. package/dist/custom/interactive-forms/get-form-contributions-for-entity.action.js.map +1 -0
  46. package/dist/custom/interactive-forms/index.d.ts +5 -0
  47. package/dist/custom/interactive-forms/index.d.ts.map +1 -1
  48. package/dist/custom/interactive-forms/index.js +5 -0
  49. package/dist/custom/interactive-forms/index.js.map +1 -1
  50. package/dist/custom/interactive-forms/modify-form-contribution.action.d.ts +36 -0
  51. package/dist/custom/interactive-forms/modify-form-contribution.action.d.ts.map +1 -0
  52. package/dist/custom/interactive-forms/modify-form-contribution.action.js +181 -0
  53. package/dist/custom/interactive-forms/modify-form-contribution.action.js.map +1 -0
  54. package/dist/custom/interactive-forms/modify-interactive-form.action.d.ts +13 -11
  55. package/dist/custom/interactive-forms/modify-interactive-form.action.d.ts.map +1 -1
  56. package/dist/custom/interactive-forms/modify-interactive-form.action.js +65 -64
  57. package/dist/custom/interactive-forms/modify-interactive-form.action.js.map +1 -1
  58. package/dist/custom/interactive-forms/revert-interactive-form.action.d.ts +12 -0
  59. package/dist/custom/interactive-forms/revert-interactive-form.action.d.ts.map +1 -1
  60. package/dist/custom/interactive-forms/revert-interactive-form.action.js +29 -4
  61. package/dist/custom/interactive-forms/revert-interactive-form.action.js.map +1 -1
  62. package/package.json +42 -42
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form-contribution.action.d.ts","sourceRoot":"","sources":["../../../src/custom/interactive-forms/create-form-contribution.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAiBrD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,4BAA6B,SAAQ,UAAU;cAExC,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiEvF;;;;OAIG;YACW,iBAAiB;IAwB/B,OAAO,CAAC,aAAa;CAkBxB;AAED,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD"}
@@ -0,0 +1,149 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { BaseAction } from "@memberjunction/actions";
8
+ import { Metadata, LogError, RunView } from "@memberjunction/core";
9
+ import { EscapeSQLString, RegisterClass } from "@memberjunction/global";
10
+ import { AddOutput, Failure, GetPrecedenceParam, GetStringParam, InsertComponent, InsertContribution, LintFormPanelSpec, ParseSpecParam, ResolveContributionRegistration, WriteAtomically, } from "./_shared.js";
11
+ /**
12
+ * Create a net-new form contribution for the requesting user.
13
+ *
14
+ * Reads the registration intent from `spec.formContribution` (slot, key, claims,
15
+ * presentation, title). Writes a `MJ: Components` row (Type='Widget', v1.0.0, Draft)
16
+ * and a `MJ: Entity Form Contributions` row (Scope='User', Status='Pending').
17
+ * Activation is a separate step (`Activate Form Contribution Version`), which the
18
+ * "Add to my form" apply flow runs immediately after Create.
19
+ *
20
+ * **Security clamp — Scope.** This action *always* writes `Scope='User'`,
21
+ * `UserID=ctx.user.ID`. An agent cannot write Global or Role contributions that would
22
+ * change other users' forms. Promotion is a deliberate human act.
23
+ *
24
+ * `Precedence` is honored when supplied (the apply flow passes `incumbent + 1` after
25
+ * the user confirms replacing an installed contribution). It only ever affects the
26
+ * calling user's own form, so it is not clamped.
27
+ *
28
+ * **Atomicity.** The spec's claim is checked (INVALID_CLAIM) before anything is written, and
29
+ * the Component and row inserts run in one entity transaction, so a refused row leaves no
30
+ * Component behind.
31
+ */
32
+ let CreateFormContributionAction = class CreateFormContributionAction extends BaseAction {
33
+ async InternalRunAction(params) {
34
+ try {
35
+ const inputs = this.extractInputs(params);
36
+ if ('error' in inputs)
37
+ return inputs.error;
38
+ const provider = params.Provider ?? Metadata.Provider;
39
+ if (!provider)
40
+ return Failure("NO_PROVIDER", "No metadata provider available.");
41
+ const user = params.ContextUser;
42
+ if (!user)
43
+ return Failure("NO_USER", "Action requires a ContextUser to clamp contribution scope.");
44
+ const entityInfo = provider.EntityByName(inputs.EntityName);
45
+ if (!entityInfo) {
46
+ return Failure("ENTITY_NOT_FOUND", `Entity '${inputs.EntityName}' is not registered with the active metadata provider.`);
47
+ }
48
+ // Lint before any persistence — fail-hard.
49
+ const lintFail = await LintFormPanelSpec(inputs.Spec, user);
50
+ if (lintFail)
51
+ return lintFail;
52
+ const registration = ResolveContributionRegistration(provider, inputs.Spec);
53
+ if ('error' in registration)
54
+ return registration.error;
55
+ // The duplicate check runs before the Component row is written, so a rejected
56
+ // create leaves nothing behind.
57
+ const writeKey = registration.WriteKey;
58
+ const keyCheck = writeKey
59
+ ? await this.checkKeyAvailable(provider, user, entityInfo.ID, inputs.EntityName, writeKey)
60
+ : null;
61
+ if (keyCheck)
62
+ return keyCheck;
63
+ const written = await WriteAtomically(provider, async () => {
64
+ const componentInsert = await InsertComponent({
65
+ provider, user, spec: inputs.Spec, fallbackName: inputs.Name, description: inputs.Description,
66
+ version: "1.0.0", versionSequence: 1, componentStatus: 'Pending', componentType: 'Widget',
67
+ });
68
+ if ('error' in componentInsert)
69
+ return componentInsert;
70
+ const rowInsert = await InsertContribution({
71
+ provider, user, entityID: entityInfo.ID, componentID: componentInsert.id,
72
+ name: inputs.Name, description: inputs.Description, notes: inputs.Notes,
73
+ registration, status: 'Pending', precedence: inputs.Precedence,
74
+ });
75
+ if ('error' in rowInsert)
76
+ return rowInsert;
77
+ return { componentID: componentInsert.id, contributionID: rowInsert.id };
78
+ });
79
+ if ('error' in written)
80
+ return written.error;
81
+ AddOutput(params, "ContributionID", written.contributionID);
82
+ AddOutput(params, "ComponentID", written.componentID);
83
+ AddOutput(params, "Version", "1.0.0");
84
+ return {
85
+ Success: true, ResultCode: "SUCCESS",
86
+ Message: JSON.stringify({
87
+ ContributionID: written.contributionID, ComponentID: written.componentID, EntityName: entityInfo.Name,
88
+ ContributionKey: writeKey, Slot: registration.Contribution.slot,
89
+ Scope: "User", Status: "Pending", Version: "1.0.0",
90
+ }),
91
+ };
92
+ }
93
+ catch (err) {
94
+ const message = err instanceof Error ? err.message : String(err);
95
+ LogError(`CreateFormContributionAction: ${message}`);
96
+ return Failure("UNEXPECTED_ERROR", message);
97
+ }
98
+ }
99
+ /**
100
+ * Rejects a key the caller already holds on this entity, and fails with QUERY_FAILED when
101
+ * that cannot be checked. Covers derived keys too, because the key it tests is the one the
102
+ * row will actually carry.
103
+ */
104
+ async checkKeyAvailable(provider, user, entityID, entityName, writeKey) {
105
+ const rv = RunView.FromMetadataProvider(provider);
106
+ const dup = await rv.RunView({
107
+ EntityName: "MJ: Entity Form Contributions",
108
+ ExtraFilter: `EntityID='${EscapeSQLString(entityID)}' AND Scope='User' AND UserID='${EscapeSQLString(user.ID)}' AND ContributionKey='${EscapeSQLString(writeKey)}' AND Status IN ('Active','Pending')`,
109
+ Fields: ['ID', 'Status'], ResultType: 'simple', MaxRows: 1,
110
+ }, user);
111
+ if (!dup.Success) {
112
+ return Failure("QUERY_FAILED", `Duplicate-key lookup failed: ${dup.ErrorMessage ?? 'unknown error'}`);
113
+ }
114
+ if ((dup.Results ?? []).length > 0) {
115
+ const existing = dup.Results[0];
116
+ return Failure("ALREADY_EXISTS", `A ${existing.Status} User-scope contribution '${writeKey}' already exists on '${entityName}' (ContributionID=${existing.ID}). Use 'Modify Form Contribution' on it.`);
117
+ }
118
+ return null;
119
+ }
120
+ extractInputs(params) {
121
+ const entityName = GetStringParam(params, "EntityName");
122
+ if (!entityName)
123
+ return { error: Failure("MISSING_PARAMETER", "Parameter 'EntityName' is required.") };
124
+ const name = GetStringParam(params, "Name");
125
+ if (!name)
126
+ return { error: Failure("MISSING_PARAMETER", "Parameter 'Name' is required.") };
127
+ const specRaw = params.Params.find(x => x.Name?.trim().toLowerCase() === "spec")?.Value;
128
+ if (specRaw == null)
129
+ return { error: Failure("MISSING_PARAMETER", "Parameter 'Spec' is required.") };
130
+ const parsed = ParseSpecParam(specRaw);
131
+ if ('error' in parsed)
132
+ return { error: Failure("LINT_FAILED", `Spec is not valid JSON: ${parsed.error}`) };
133
+ return {
134
+ EntityName: entityName, Spec: parsed, Name: name,
135
+ Description: GetStringParam(params, "Description"), Notes: GetStringParam(params, "Notes"),
136
+ Precedence: GetPrecedenceParam(params) ?? 0,
137
+ };
138
+ }
139
+ };
140
+ CreateFormContributionAction = __decorate([
141
+ RegisterClass(BaseAction, "__CreateFormContribution")
142
+ ], CreateFormContributionAction);
143
+ export { CreateFormContributionAction };
144
+ export function LoadCreateFormContributionAction() {
145
+ if (false) {
146
+ const _ = CreateFormContributionAction;
147
+ }
148
+ }
149
+ //# sourceMappingURL=create-form-contribution.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form-contribution.action.js","sourceRoot":"","sources":["../../../src/custom/interactive-forms/create-form-contribution.action.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,9 @@ import { BaseAction } from "@memberjunction/actions";
13
13
  * full variants list includes 'Pending' rows so the agent can recognize
14
14
  * an in-flight refinement loop and reuse the Pending row instead of
15
15
  * spawning a new one.
16
+ * - On an identity or permission entity only the caller's own `User` rows
17
+ * apply ({@link FormScopeAllowedOnEntity}), so a Role or Global form there
18
+ * is neither active nor listed.
16
19
  *
17
20
  * Output shape (JSON in `Message`, also surfaced as a `Result` output param):
18
21
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"get-active-form-for-entity.action.d.ts","sourceRoot":"","sources":["../../../src/custom/interactive-forms/get-active-form-for-entity.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAKrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBACa,4BAA6B,SAAQ,UAAU;cAExC,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkKvF,OAAO,CAAC,cAAc;CAOzB;AAMD,qDAAqD;AACrD,wBAAgB,gCAAgC,IAAI,IAAI,CAIvD"}
1
+ {"version":3,"file":"get-active-form-for-entity.action.d.ts","sourceRoot":"","sources":["../../../src/custom/interactive-forms/get-active-form-for-entity.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAMrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBACa,4BAA6B,SAAQ,UAAU;cAExC,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkKvF,OAAO,CAAC,cAAc;CAOzB;AAMD,qDAAqD;AACrD,wBAAgB,gCAAgC,IAAI,IAAI,CAIvD"}
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { BaseAction } from "@memberjunction/actions";
8
8
  import { Metadata, LogError, RunView } from "@memberjunction/core";
9
9
  import { RegisterClass } from "@memberjunction/global";
10
+ import { FormScopeAllowedOnEntity } from "@memberjunction/core-entities";
10
11
  /**
11
12
  * Read-only action that returns the currently-resolved interactive-form
12
13
  * override (if any) for the (entity, user) pair plus the full list of
@@ -20,6 +21,9 @@ import { RegisterClass } from "@memberjunction/global";
20
21
  * full variants list includes 'Pending' rows so the agent can recognize
21
22
  * an in-flight refinement loop and reuse the Pending row instead of
22
23
  * spawning a new one.
24
+ * - On an identity or permission entity only the caller's own `User` rows
25
+ * apply ({@link FormScopeAllowedOnEntity}), so a Role or Global form there
26
+ * is neither active nor listed.
23
27
  *
24
28
  * Output shape (JSON in `Message`, also surfaced as a `Result` output param):
25
29
  * ```
@@ -83,7 +87,7 @@ let GetActiveFormForEntityAction = class GetActiveFormForEntityAction extends Ba
83
87
  if (!overrideResult.Success) {
84
88
  return failure("QUERY_FAILED", `Override lookup failed: ${overrideResult.ErrorMessage ?? 'unknown error'}`);
85
89
  }
86
- const overrides = overrideResult.Results ?? [];
90
+ const overrides = (overrideResult.Results ?? []).filter(o => FormScopeAllowedOnEntity(entity.Name, o.Scope));
87
91
  if (overrides.length === 0) {
88
92
  const payload = { EntityName: entityName, Active: null, Variants: [] };
89
93
  params.Params.push({ Name: "Result", Type: "Output", Value: payload });
@@ -1 +1 @@
1
- {"version":3,"file":"get-active-form-for-entity.action.js","sourceRoot":"","sources":["../../../src/custom/interactive-forms/get-active-form-for-entity.action.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-active-form-for-entity.action.js","sourceRoot":"","sources":["../../../src/custom/interactive-forms/get-active-form-for-entity.action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { ActionResultSimple, RunActionParams } from "@memberjunction/actions-base";
2
+ import { BaseAction } from "@memberjunction/actions";
3
+ /**
4
+ * Server-side composition of an entity's form, for agents with no browser snapshot.
5
+ *
6
+ * The client context is the better source for sections — it reports what a form actually
7
+ * rendered. This reproduces the part derivable from metadata alone: field sections by CodeGen
8
+ * rule, `DisplayInForm` related grids with their L1 inclusion, the caller's Active metadata
9
+ * contributions as the caller's form draws them, and the L3 rule count.
10
+ *
11
+ * Contributions are reported for the form this user sees: one row per key (highest
12
+ * `Precedence`, then the narrower scope, the browser's collapse rule), the panels the user hid
13
+ * marked `Hidden`, and on an identity or permission entity only the user's own rows
14
+ * ({@link FormScopeAllowedOnEntity}). Any failed query returns `QUERY_FAILED` rather than an
15
+ * answer built from a partial read. With metadata contributions switched off
16
+ * ({@link MetadataContributionsOn}) no row is read or listed, and `MetadataContributionsEnabled`
17
+ * is false.
18
+ *
19
+ * Compiled `BaseFormPanel` registrations live in the browser bundle, so they are absent and
20
+ * the `Note` says so.
21
+ *
22
+ * Slots are reported from `GENERATED_FORM_CONTRIBUTION_SLOTS` rather than guessed: what CodeGen
23
+ * emits is fixed, so the set is known for every generated form without opening one. A
24
+ * hand-written custom form can emit a different set, and the `Note` says so.
25
+ */
26
+ export declare class GetFormCompositionForEntityAction extends BaseAction {
27
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
28
+ /**
29
+ * Whether a full custom form renders for this caller.
30
+ *
31
+ * Mirrors `FormResolverService.pickActive` in the browser, which is what actually
32
+ * decides. A stored pick wins when the user may pick it: an Active form, or their own
33
+ * form set aside by a later apply ({@link IsSelectableFormOverride}). The explicit-default sentinel
34
+ * means they asked for the generated form, so no custom form renders at all. With no
35
+ * pick, or a pick naming a form that has gone or cannot be picked, the auto-pick rule
36
+ * applies: the first Active override, if there is one.
37
+ */
38
+ private rendersFullCustomForm;
39
+ private readLayout;
40
+ /**
41
+ * Field sections, by CodeGen's own rule: a field marked `Category` groups under its
42
+ * category title, everything else lands in Details, and primary-key / `__mj_` audit
43
+ * fields form System Metadata, which CodeGen always emits last.
44
+ */
45
+ private deriveSections;
46
+ /**
47
+ * Related grids the form shows, in the order it shows them. IS-A children are excluded:
48
+ * they share the parent's key and render as part of the record, not as a grid beside it.
49
+ */
50
+ private deriveRelated;
51
+ /**
52
+ * Two relationships to the same entity (Bill-To and Ship-To, say) would collide on a
53
+ * bare entity-name key, so those are disambiguated by join field — matching what the
54
+ * form itself does.
55
+ */
56
+ private relatedSectionKey;
57
+ }
58
+ export declare function LoadGetFormCompositionForEntityAction(): void;
59
+ //# sourceMappingURL=get-form-composition-for-entity.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-composition-for-entity.action.d.ts","sourceRoot":"","sources":["../../../src/custom/interactive-forms/get-form-composition-for-entity.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AA8DrD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBACa,iCAAkC,SAAQ,UAAU;cAE7C,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwFvF;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAqCtB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAerB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAI5B;AA8GD,wBAAgB,qCAAqC,IAAI,IAAI,CAE5D"}
@@ -0,0 +1,313 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { BaseAction } from "@memberjunction/actions";
8
+ import { Metadata, LogError, RunView, ReadRelationshipInclusion } from "@memberjunction/core";
9
+ import { EscapeSQLString, RegisterClass, UUIDsEqual } from "@memberjunction/global";
10
+ import { FormContributionOutranks, FormPanelHideSettingKey, FormScopeAllowedOnEntity, IsSelectableFormOverride, ParseClaimedFieldNames, ParseHiddenFormPanelKeys, } from "@memberjunction/core-entities";
11
+ import { AddOutput, Failure, GetStringParam, ContributionScopeFilter, MetadataContributionsOn } from "./_shared.js";
12
+ import { FORM_VARIANT_EXPLICIT_DEFAULT, FormSectionCamelCase, FormVariantSettingKey, GENERATED_FORM_CONTRIBUTION_SLOTS, RelatedGridSectionKey, ResolveContributionWriteKey, StripJoinFieldBrackets, } from "@memberjunction/interactive-component-types/forms";
13
+ const SERVER_DERIVATION_NOTE = 'Derived from metadata on the server. Compiled BaseFormPanel contributions exist only in the ' +
14
+ 'browser and are not listed. SlotsPresent is what CodeGen emits plus the container terminator; ' +
15
+ 'a hand-written custom form can differ. Section keys and field names come from current field ' +
16
+ 'metadata, which a ' +
17
+ 'form generated earlier may not match. The client form context (AppContext.AdditionalContext.Form), ' +
18
+ 'when present, lists the sections the open form actually draws and is authoritative for those.';
19
+ const FULL_CUSTOM_FORM_NOTE = 'A full custom entity form is the one THIS USER sees for this entity, and it renders the whole ' +
20
+ 'body: no field sections, no related grids, no panel contribution and no slot. Propose a new ' +
21
+ 'version of the full form rather than a panel. The container still supplies the toolbar, ' +
22
+ 'Save/Delete, History and Record Changes, so the form body does not implement those. The user ' +
23
+ 'can switch to the generated form from the form picker in the toolbar, and a panel becomes ' +
24
+ 'possible again the moment they do.';
25
+ /**
26
+ * Server-side composition of an entity's form, for agents with no browser snapshot.
27
+ *
28
+ * The client context is the better source for sections — it reports what a form actually
29
+ * rendered. This reproduces the part derivable from metadata alone: field sections by CodeGen
30
+ * rule, `DisplayInForm` related grids with their L1 inclusion, the caller's Active metadata
31
+ * contributions as the caller's form draws them, and the L3 rule count.
32
+ *
33
+ * Contributions are reported for the form this user sees: one row per key (highest
34
+ * `Precedence`, then the narrower scope, the browser's collapse rule), the panels the user hid
35
+ * marked `Hidden`, and on an identity or permission entity only the user's own rows
36
+ * ({@link FormScopeAllowedOnEntity}). Any failed query returns `QUERY_FAILED` rather than an
37
+ * answer built from a partial read. With metadata contributions switched off
38
+ * ({@link MetadataContributionsOn}) no row is read or listed, and `MetadataContributionsEnabled`
39
+ * is false.
40
+ *
41
+ * Compiled `BaseFormPanel` registrations live in the browser bundle, so they are absent and
42
+ * the `Note` says so.
43
+ *
44
+ * Slots are reported from `GENERATED_FORM_CONTRIBUTION_SLOTS` rather than guessed: what CodeGen
45
+ * emits is fixed, so the set is known for every generated form without opening one. A
46
+ * hand-written custom form can emit a different set, and the `Note` says so.
47
+ */
48
+ let GetFormCompositionForEntityAction = class GetFormCompositionForEntityAction extends BaseAction {
49
+ async InternalRunAction(params) {
50
+ try {
51
+ const entityName = GetStringParam(params, "EntityName");
52
+ if (!entityName)
53
+ return Failure("MISSING_PARAMETER", "Parameter 'EntityName' is required.");
54
+ const provider = params.Provider ?? Metadata.Provider;
55
+ if (!provider)
56
+ return Failure("NO_PROVIDER", "No metadata provider available.");
57
+ const user = params.ContextUser;
58
+ if (!user)
59
+ return Failure("NO_USER", "Action requires a ContextUser — contributions are user-scoped.");
60
+ const entity = provider.EntityByName(entityName);
61
+ if (!entity)
62
+ return Failure("ENTITY_NOT_FOUND", `Entity '${entityName}' is not registered.`);
63
+ const rv = RunView.FromMetadataProvider(provider);
64
+ const contributionsOn = await MetadataContributionsOn(provider, user);
65
+ const scope = ContributionScopeFilter(entity.ID, user);
66
+ const variantKey = FormVariantSettingKey(entity.Name);
67
+ const hideKey = FormPanelHideSettingKey(entity.Name);
68
+ const [rules, rows, overrides, settings] = await Promise.all([
69
+ rv.RunView({
70
+ EntityName: "MJ: Form Chrome Rules",
71
+ ExtraFilter: `EntityID='${EscapeSQLString(entity.ID)}'`,
72
+ Fields: ['ID'],
73
+ ResultType: 'simple',
74
+ }, user),
75
+ contributionsOn
76
+ ? rv.RunView({
77
+ EntityName: "MJ: Entity Form Contributions",
78
+ ExtraFilter: `${scope} AND Status='Active'`,
79
+ Fields: ['ID', 'ContributionKey', 'Scope', 'Slot', 'Title', 'Name', 'Presentation', 'Precedence', 'Inclusion', 'SortKey',
80
+ 'InSectionKey', 'SectionPosition', 'ReplacesFieldNames', 'ReplacesSectionKey', 'ReplacesSectionKeys',
81
+ 'RelatedEntityID', 'RelatedEntity', 'RelatedJoinField'],
82
+ OrderBy: 'Precedence DESC, SortKey DESC',
83
+ ResultType: 'simple',
84
+ }, user)
85
+ : Promise.resolve(noRows()),
86
+ rv.RunView({
87
+ EntityName: "MJ: Entity Form Overrides",
88
+ ExtraFilter: `${scope} AND Status<>'Pending'`,
89
+ Fields: ['ID', 'Status', 'Scope'],
90
+ ResultType: 'simple',
91
+ }, user),
92
+ rv.RunView({
93
+ EntityName: "MJ: User Settings",
94
+ ExtraFilter: `UserID='${EscapeSQLString(user.ID)}' AND Setting IN ('${EscapeSQLString(variantKey)}','${EscapeSQLString(hideKey)}')`,
95
+ Fields: ['Setting', 'Value'],
96
+ ResultType: 'simple',
97
+ }, user),
98
+ ]);
99
+ const failed = firstFailure([
100
+ ["MJ: Form Chrome Rules", rules], ["MJ: Entity Form Contributions", rows],
101
+ ["MJ: Entity Form Overrides", overrides], ["MJ: User Settings", settings],
102
+ ]);
103
+ if (failed)
104
+ return Failure("QUERY_FAILED", failed);
105
+ // Which form the CALLER sees, not merely whether a custom one exists. They can
106
+ // pick any form on offer, the generated one included, and that pick is a
107
+ // per-user setting — reading only the override rows answered for a form the
108
+ // user may have switched away from, and refused a panel on the form they were
109
+ // looking at.
110
+ const offered = (overrides.Results ?? []).filter(o => FormScopeAllowedOnEntity(entity.Name, o.Scope));
111
+ const fullCustomForm = this.rendersFullCustomForm(offered, settingValue(settings.Results ?? [], variantKey));
112
+ const hidden = new Set(ParseHiddenFormPanelKeys(settingValue(settings.Results ?? [], hideKey)));
113
+ const applicable = (rows.Results ?? []).filter(r => FormScopeAllowedOnEntity(entity.Name, r.Scope));
114
+ const payload = {
115
+ Entity: entity.Name,
116
+ Layout: this.readLayout(entity),
117
+ FullCustomForm: fullCustomForm,
118
+ MetadataContributionsEnabled: contributionsOn,
119
+ Sections: fullCustomForm ? [] : this.deriveSections(entity),
120
+ Related: fullCustomForm ? [] : this.deriveRelated(entity),
121
+ Contributions: fullCustomForm ? [] : contributionsUserSees(applicable, hidden),
122
+ SlotsPresent: fullCustomForm ? [] : [...GENERATED_FORM_CONTRIBUTION_SLOTS],
123
+ ChromeRuleCount: (rules.Results ?? []).length,
124
+ Note: fullCustomForm ? FULL_CUSTOM_FORM_NOTE : SERVER_DERIVATION_NOTE,
125
+ };
126
+ AddOutput(params, "Result", payload);
127
+ return { Success: true, ResultCode: "SUCCESS", Message: JSON.stringify(payload) };
128
+ }
129
+ catch (err) {
130
+ const message = err instanceof Error ? err.message : String(err);
131
+ LogError(`GetFormCompositionForEntityAction: ${message}`);
132
+ return Failure("UNEXPECTED_ERROR", message);
133
+ }
134
+ }
135
+ /**
136
+ * Whether a full custom form renders for this caller.
137
+ *
138
+ * Mirrors `FormResolverService.pickActive` in the browser, which is what actually
139
+ * decides. A stored pick wins when the user may pick it: an Active form, or their own
140
+ * form set aside by a later apply ({@link IsSelectableFormOverride}). The explicit-default sentinel
141
+ * means they asked for the generated form, so no custom form renders at all. With no
142
+ * pick, or a pick naming a form that has gone or cannot be picked, the auto-pick rule
143
+ * applies: the first Active override, if there is one.
144
+ */
145
+ rendersFullCustomForm(overrides, preference) {
146
+ const selected = (preference ?? '').trim();
147
+ if (selected === FORM_VARIANT_EXPLICIT_DEFAULT)
148
+ return false;
149
+ if (selected && overrides.some(o => IsSelectableFormOverride(o) && UUIDsEqual(o.ID, selected)))
150
+ return true;
151
+ return overrides.some(o => o.Status === 'Active');
152
+ }
153
+ readLayout(entity) {
154
+ const configured = entity
155
+ .ConfigurationObject?.UI?.Form?.Layout;
156
+ return configured === 'left-nav' ? 'left-nav' : 'accordion';
157
+ }
158
+ /**
159
+ * Field sections, by CodeGen's own rule: a field marked `Category` groups under its
160
+ * category title, everything else lands in Details, and primary-key / `__mj_` audit
161
+ * fields form System Metadata, which CodeGen always emits last.
162
+ */
163
+ deriveSections(entity) {
164
+ const fieldsByTitle = new Map();
165
+ const titleOrder = [];
166
+ const fileUnder = (title, field) => {
167
+ if (!fieldsByTitle.has(title)) {
168
+ fieldsByTitle.set(title, []);
169
+ titleOrder.push(title);
170
+ }
171
+ fieldsByTitle.get(title).push(field);
172
+ };
173
+ for (const f of entity.Fields) {
174
+ if (f.Name.startsWith('__mj_') || f.Name === 'ID')
175
+ continue;
176
+ const category = f.Category?.trim();
177
+ const type = f.GeneratedFormSectionType;
178
+ const field = { Name: f.Name, Label: f.DisplayNameOrName };
179
+ fileUnder(type === 'Category' && category ? category : 'Details', field);
180
+ }
181
+ const ordered = [
182
+ ...(fieldsByTitle.has('Details') ? ['Details'] : []),
183
+ ...titleOrder.filter(t => t !== 'Details'),
184
+ 'System Metadata',
185
+ ];
186
+ return ordered.map(title => ({
187
+ Key: FormSectionCamelCase(title),
188
+ Title: title,
189
+ Variant: 'default',
190
+ Group: null,
191
+ Hidden: false,
192
+ // Named so a contribution can stand in for one field rather than the whole
193
+ // section. Metadata-derived, so these are the entity's fields rather than the
194
+ // ones a form generated earlier actually draws — SERVER_DERIVATION_NOTE says so.
195
+ Fields: fieldsByTitle.get(title) ?? [],
196
+ }));
197
+ }
198
+ /**
199
+ * Related grids the form shows, in the order it shows them. IS-A children are excluded:
200
+ * they share the parent's key and render as part of the record, not as a grid beside it.
201
+ */
202
+ deriveRelated(entity) {
203
+ const isaChildIDs = (entity.ChildEntities ?? []).map(c => c.ID);
204
+ const visible = entity.RelatedEntities
205
+ .filter(r => r.DisplayInForm && !isaChildIDs.some(id => UUIDsEqual(id, r.RelatedEntityID)))
206
+ .sort((a, b) => (a.Sequence ?? 999999) - (b.Sequence ?? 999999) || a.RelatedEntity.localeCompare(b.RelatedEntity));
207
+ return visible.map(r => ({
208
+ Entity: r.RelatedEntity,
209
+ JoinField: StripJoinFieldBrackets(r.RelatedEntityJoinField),
210
+ SectionKey: this.relatedSectionKey(r, visible),
211
+ Inclusion: ReadRelationshipInclusion(r.Configuration) ?? 'Auto',
212
+ Source: 'baked',
213
+ }));
214
+ }
215
+ /**
216
+ * Two relationships to the same entity (Bill-To and Ship-To, say) would collide on a
217
+ * bare entity-name key, so those are disambiguated by join field — matching what the
218
+ * form itself does.
219
+ */
220
+ relatedSectionKey(rel, peers) {
221
+ const sharesRelatedEntity = peers.filter(p => UUIDsEqual(p.RelatedEntityID, rel.RelatedEntityID)).length > 1;
222
+ return RelatedGridSectionKey(rel.RelatedEntity, rel.RelatedEntityJoinField, sharesRelatedEntity);
223
+ }
224
+ };
225
+ GetFormCompositionForEntityAction = __decorate([
226
+ RegisterClass(BaseAction, "__GetFormCompositionForEntity")
227
+ ], GetFormCompositionForEntityAction);
228
+ export { GetFormCompositionForEntityAction };
229
+ /** An empty, successful result, which stands in for a query that is not run. */
230
+ function noRows() {
231
+ return { Success: true, Results: [], RowCount: 0, TotalRowCount: 0, ExecutionTime: 0, ErrorMessage: '' };
232
+ }
233
+ /** The message for the first failed query, or null when every query succeeded. */
234
+ function firstFailure(results) {
235
+ const failed = results.find(([, result]) => !result.Success);
236
+ if (!failed)
237
+ return null;
238
+ const [entityName, result] = failed;
239
+ return `Could not read the form's composition: the ${entityName} lookup failed (${result.ErrorMessage || 'unknown error'}).`;
240
+ }
241
+ /** The stored value of one setting. Keys are matched case-insensitively, as the database compares them. */
242
+ function settingValue(rows, key) {
243
+ return rows.find(r => (r.Setting ?? '').toLowerCase() === key.toLowerCase())?.Value ?? null;
244
+ }
245
+ /** The key a row is collapsed and hidden by, as the browser derives it; null for a row with none. */
246
+ function contributionRowKey(row) {
247
+ return ResolveContributionWriteKey({ contributionKey: row.ContributionKey ?? undefined, relatedJoinField: row.RelatedJoinField ?? undefined }, row.RelatedEntity ?? null);
248
+ }
249
+ /** One row per key, the one {@link FormContributionOutranks} picks; rows without a key never collapse. */
250
+ function collapseByKey(rows) {
251
+ const winners = new Map();
252
+ let unique = 0;
253
+ for (const row of rows) {
254
+ const key = contributionRowKey(row) ?? `__unique:${unique++}`;
255
+ const incumbent = winners.get(key);
256
+ if (!incumbent || FormContributionOutranks(row, incumbent))
257
+ winners.set(key, row);
258
+ }
259
+ return [...winners.values()];
260
+ }
261
+ /**
262
+ * The contributions on the form this user sees.
263
+ *
264
+ * A panel the user hid is out of the collapse, so a row it outranked can draw in its place, as
265
+ * in the browser. The user's own rows are never hidden. A hidden panel whose key nothing else
266
+ * draws is still listed, marked `Hidden`, because it holds that key.
267
+ */
268
+ function contributionsUserSees(rows, hiddenKeys) {
269
+ const isHidden = (row) => {
270
+ if (row.Scope === 'User')
271
+ return false;
272
+ const key = contributionRowKey(row);
273
+ return !!key && hiddenKeys.has(key);
274
+ };
275
+ const drawn = collapseByKey(rows.filter(r => !isHidden(r)));
276
+ const drawnKeys = new Set(drawn.map(contributionRowKey).filter((k) => !!k));
277
+ const hiddenOnly = collapseByKey(rows.filter(isHidden)).filter(r => !drawnKeys.has(contributionRowKey(r) ?? ''));
278
+ return [
279
+ ...drawn.map(r => contributionSummary(r, r.Inclusion === 'None')),
280
+ ...hiddenOnly.map(r => contributionSummary(r, true)),
281
+ ];
282
+ }
283
+ function contributionSummary(r, hidden) {
284
+ return {
285
+ Key: contributionRowKey(r) ?? `contribution:${r.ID}`,
286
+ Slot: r.Slot,
287
+ Source: 'metadata',
288
+ Title: r.Title ?? r.Name ?? r.ID,
289
+ Presentation: r.Presentation,
290
+ Hidden: hidden,
291
+ Precedence: r.Precedence ?? 0,
292
+ SortKey: r.SortKey ?? 0,
293
+ InSectionKey: r.InSectionKey ?? undefined,
294
+ SectionPosition: r.SectionPosition ?? undefined,
295
+ FieldNames: ParseClaimedFieldNames(r.ReplacesFieldNames),
296
+ SectionKeys: replacedSectionKeyList(r),
297
+ ReplacesPlace: !!(r.ReplacesSectionKey || r.ReplacesSectionKeys || r.RelatedEntityID),
298
+ };
299
+ }
300
+ /** The blocks a row stands in for: the list when set, else the single key. */
301
+ function replacedSectionKeyList(row) {
302
+ const listed = ParseClaimedFieldNames(row.ReplacesSectionKeys);
303
+ if (listed.length > 0)
304
+ return listed;
305
+ const single = (row.ReplacesSectionKey ?? '').trim();
306
+ return single ? [single] : [];
307
+ }
308
+ export function LoadGetFormCompositionForEntityAction() {
309
+ if (false) {
310
+ const _ = GetFormCompositionForEntityAction;
311
+ }
312
+ }
313
+ //# sourceMappingURL=get-form-composition-for-entity.action.js.map