@happyvertical/smrt-fields 0.40.61 → 0.40.63
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.
- package/AGENTS.md +18 -0
- package/README.md +125 -112
- package/dist/chunks/FieldPolicyCollection--RxukfCX.js +1218 -0
- package/dist/chunks/FieldPolicyCollection--RxukfCX.js.map +1 -0
- package/dist/collections/FieldPolicySuggestionCollection.d.ts +160 -0
- package/dist/collections/FieldPolicySuggestionCollection.d.ts.map +1 -0
- package/dist/collections/FieldUsageCounterCollection.d.ts +143 -0
- package/dist/collections/FieldUsageCounterCollection.d.ts.map +1 -0
- package/dist/deterministic-id.d.ts +18 -0
- package/dist/deterministic-id.d.ts.map +1 -0
- package/dist/field-definitions.d.ts +8 -0
- package/dist/field-definitions.d.ts.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1565 -1077
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1442 -188
- package/dist/models/FieldPolicySuggestion.d.ts +132 -0
- package/dist/models/FieldPolicySuggestion.d.ts.map +1 -0
- package/dist/models/FieldUsageCounter.d.ts +178 -0
- package/dist/models/FieldUsageCounter.d.ts.map +1 -0
- package/dist/models/FieldUsageReportReceipt.d.ts +25 -0
- package/dist/models/FieldUsageReportReceipt.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +404 -7
- package/dist/svelte/__tests__/FieldPolicyControlPanel.test.js +54 -0
- package/dist/svelte/__tests__/FormHelp.test.js +8 -0
- package/dist/svelte/__tests__/ObjectForm.test.js +131 -0
- package/dist/svelte/__tests__/UsageLearning.test.js +140 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte +21 -4
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts +5 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts.map +1 -1
- package/dist/svelte/__tests__/fixtures/SuggestionGearFixture.svelte +23 -0
- package/dist/svelte/__tests__/fixtures/SuggestionGearFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/SuggestionGearFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/playground.test.js +66 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte +28 -1
- package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts +3 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts.map +1 -1
- package/dist/svelte/components/FieldPolicyGearButton.svelte +8 -1
- package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts.map +1 -1
- package/dist/svelte/components/FieldPolicyGearProvider.svelte +34 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts +3 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts.map +1 -1
- package/dist/svelte/components/FieldPolicySuggestionQueue.svelte +135 -0
- package/dist/svelte/components/FieldPolicySuggestionQueue.svelte.d.ts +11 -0
- package/dist/svelte/components/FieldPolicySuggestionQueue.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FormHelp.svelte +16 -1
- package/dist/svelte/components/FormHelp.svelte.d.ts.map +1 -1
- package/dist/svelte/components/ObjectForm.svelte +91 -2
- package/dist/svelte/components/ObjectForm.svelte.d.ts +11 -1
- package/dist/svelte/components/ObjectForm.svelte.d.ts.map +1 -1
- package/dist/svelte/context.svelte.d.ts +15 -0
- package/dist/svelte/context.svelte.d.ts.map +1 -1
- package/dist/svelte/context.svelte.js +15 -0
- package/dist/svelte/gear-context.svelte.d.ts +2 -0
- package/dist/svelte/gear-context.svelte.d.ts.map +1 -1
- package/dist/svelte/index.d.ts +6 -1
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +4 -1
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte +18 -12
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts.map +1 -1
- package/dist/svelte/suggestions.d.ts +38 -0
- package/dist/svelte/suggestions.d.ts.map +1 -0
- package/dist/svelte/suggestions.js +68 -0
- package/dist/svelte/usage-capture.d.ts +63 -0
- package/dist/svelte/usage-capture.d.ts.map +1 -0
- package/dist/svelte/usage-capture.js +61 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -1
- package/dist/types.js.map +1 -1
- package/dist/usage-learning.d.ts +201 -0
- package/dist/usage-learning.d.ts.map +1 -0
- package/dist/usage-schedules.d.ts +110 -0
- package/dist/usage-schedules.d.ts.map +1 -0
- package/dist/users-module.d.ts +30 -0
- package/dist/users-module.d.ts.map +1 -0
- package/package.json +9 -9
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import { type FieldPolicyEditorAdapter, type FieldPolicyOrganizationScope } from '../field-policy-editor.js';
|
|
3
3
|
import type { FieldInputRegistry } from '../input-registry.js';
|
|
4
|
+
import { type FieldPolicySuggestionAdapter } from '../suggestions.js';
|
|
4
5
|
import type { ObjectFormFieldDefinition } from '../types.js';
|
|
5
6
|
interface Props {
|
|
6
7
|
objectRef: string;
|
|
@@ -9,6 +10,8 @@ interface Props {
|
|
|
9
10
|
inputRegistry?: FieldInputRegistry;
|
|
10
11
|
/** Hosts in an app-wide context pass app; tenant hosts retain the default. */
|
|
11
12
|
organizationScope?: FieldPolicyOrganizationScope;
|
|
13
|
+
/** Optional reviewed-suggestion transport for the gear badge. */
|
|
14
|
+
suggestionAdapter?: FieldPolicySuggestionAdapter;
|
|
12
15
|
children?: Snippet;
|
|
13
16
|
}
|
|
14
17
|
declare const FieldPolicyGearProvider: import("svelte").Component<Props, {}, "">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldPolicyGearProvider.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/FieldPolicyGearProvider.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EAElC,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAI7D,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC5D,OAAO,EAAE,wBAAwB,CAAC;IAClC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"FieldPolicyGearProvider.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/FieldPolicyGearProvider.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EAElC,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EACL,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAI7D,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC5D,OAAO,EAAE,wBAAwB,CAAC;IAClC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,iEAAiE;IACjE,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoJD,QAAA,MAAM,uBAAuB,2CAAwC,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/** Accessible, host-transport-neutral review queue for pending suggestions. */
|
|
3
|
+
import { Button } from '@happyvertical/smrt-ui/ui';
|
|
4
|
+
import {
|
|
5
|
+
type FieldPolicySuggestion,
|
|
6
|
+
type FieldPolicySuggestionAdapter,
|
|
7
|
+
fieldPolicySuggestionEvidence,
|
|
8
|
+
parsePendingFieldPolicySuggestions,
|
|
9
|
+
} from '../suggestions.js';
|
|
10
|
+
|
|
11
|
+
export interface FieldPolicySuggestionQueueProps {
|
|
12
|
+
adapter: FieldPolicySuggestionAdapter;
|
|
13
|
+
objectRefs?: readonly string[];
|
|
14
|
+
heading?: string;
|
|
15
|
+
onchanged?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
adapter,
|
|
20
|
+
objectRefs,
|
|
21
|
+
heading = 'Pending field suggestions',
|
|
22
|
+
onchanged,
|
|
23
|
+
}: FieldPolicySuggestionQueueProps = $props();
|
|
24
|
+
|
|
25
|
+
let suggestions = $state<FieldPolicySuggestion[]>([]);
|
|
26
|
+
let total = $state(0);
|
|
27
|
+
let loading = $state(false);
|
|
28
|
+
let busyId = $state<string | null>(null);
|
|
29
|
+
let error = $state<string | null>(null);
|
|
30
|
+
let generation = 0;
|
|
31
|
+
|
|
32
|
+
async function load(): Promise<void> {
|
|
33
|
+
const token = ++generation;
|
|
34
|
+
loading = true;
|
|
35
|
+
error = null;
|
|
36
|
+
try {
|
|
37
|
+
const result = parsePendingFieldPolicySuggestions(
|
|
38
|
+
await adapter.pendingSuggestions(
|
|
39
|
+
objectRefs?.length ? { objectRefs } : undefined,
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
if (token !== generation) return;
|
|
43
|
+
suggestions = result.suggestions;
|
|
44
|
+
total = result.total;
|
|
45
|
+
} catch (cause) {
|
|
46
|
+
if (token !== generation) return;
|
|
47
|
+
suggestions = [];
|
|
48
|
+
total = 0;
|
|
49
|
+
error =
|
|
50
|
+
cause instanceof Error
|
|
51
|
+
? cause.message
|
|
52
|
+
: 'Unable to load pending field suggestions.';
|
|
53
|
+
} finally {
|
|
54
|
+
if (token === generation) loading = false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function decide(
|
|
59
|
+
suggestion: FieldPolicySuggestion,
|
|
60
|
+
decision: 'approve' | 'dismiss',
|
|
61
|
+
): Promise<void> {
|
|
62
|
+
if (busyId) return;
|
|
63
|
+
busyId = suggestion.id;
|
|
64
|
+
error = null;
|
|
65
|
+
try {
|
|
66
|
+
if (decision === 'approve') {
|
|
67
|
+
await adapter.acceptSuggestion({ id: suggestion.id });
|
|
68
|
+
} else {
|
|
69
|
+
await adapter.dismissSuggestion({ id: suggestion.id });
|
|
70
|
+
}
|
|
71
|
+
await load();
|
|
72
|
+
onchanged?.();
|
|
73
|
+
} catch (cause) {
|
|
74
|
+
error =
|
|
75
|
+
cause instanceof Error
|
|
76
|
+
? cause.message
|
|
77
|
+
: 'Unable to update this field suggestion.';
|
|
78
|
+
} finally {
|
|
79
|
+
busyId = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
$effect(() => {
|
|
84
|
+
adapter;
|
|
85
|
+
objectRefs;
|
|
86
|
+
void load();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
function description(suggestion: FieldPolicySuggestion): string {
|
|
90
|
+
return suggestion.kind === 'promote'
|
|
91
|
+
? `Promote ${suggestion.fieldName} to the basic form.`
|
|
92
|
+
: `Set an organization default for ${suggestion.fieldName}.`;
|
|
93
|
+
}
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<section class="field-policy-suggestion-queue" aria-label={heading}>
|
|
97
|
+
<header>
|
|
98
|
+
<h2>{heading}</h2>
|
|
99
|
+
{#if !loading}<span class="field-policy-suggestion-queue__count">{total}</span>{/if}
|
|
100
|
+
</header>
|
|
101
|
+
{#if loading}
|
|
102
|
+
<p role="status" aria-live="polite">Loading pending suggestions…</p>
|
|
103
|
+
{:else if error}
|
|
104
|
+
<p role="alert">{error}</p>
|
|
105
|
+
{:else if suggestions.length === 0}
|
|
106
|
+
<p>No pending field suggestions.</p>
|
|
107
|
+
{:else}
|
|
108
|
+
<ul>
|
|
109
|
+
{#each suggestions as suggestion (suggestion.id)}
|
|
110
|
+
<li>
|
|
111
|
+
<article>
|
|
112
|
+
<h3>{suggestion.objectRef} · {suggestion.fieldName}</h3>
|
|
113
|
+
<p>{description(suggestion)}</p>
|
|
114
|
+
<p>{fieldPolicySuggestionEvidence(suggestion)}</p>
|
|
115
|
+
<div class="field-policy-suggestion-queue__actions">
|
|
116
|
+
<Button type="button" disabled={busyId !== null} onclick={() => decide(suggestion, 'approve')}>Approve</Button>
|
|
117
|
+
<Button type="button" variant="ghost" disabled={busyId !== null} onclick={() => decide(suggestion, 'dismiss')}>Dismiss</Button>
|
|
118
|
+
</div>
|
|
119
|
+
</article>
|
|
120
|
+
</li>
|
|
121
|
+
{/each}
|
|
122
|
+
</ul>
|
|
123
|
+
{/if}
|
|
124
|
+
</section>
|
|
125
|
+
|
|
126
|
+
<style>
|
|
127
|
+
.field-policy-suggestion-queue { display: grid; gap: var(--smrt-spacing-3, 0.75rem); }
|
|
128
|
+
.field-policy-suggestion-queue header { align-items: center; display: flex; gap: var(--smrt-spacing-2, 0.5rem); }
|
|
129
|
+
.field-policy-suggestion-queue h2, .field-policy-suggestion-queue h3 { margin: 0; }
|
|
130
|
+
.field-policy-suggestion-queue__count { border-radius: 999px; background: var(--smrt-color-secondary-container, #e8def8); min-inline-size: 1.5rem; padding: 0.125rem 0.4rem; text-align: center; }
|
|
131
|
+
.field-policy-suggestion-queue ul { display: grid; gap: var(--smrt-spacing-3, 0.75rem); list-style: none; margin: 0; padding: 0; }
|
|
132
|
+
.field-policy-suggestion-queue article { border: 1px solid var(--smrt-color-outline-variant, currentColor); border-radius: var(--smrt-radius-small, 0.25rem); display: grid; gap: var(--smrt-spacing-2, 0.5rem); padding: var(--smrt-spacing-3, 0.75rem); }
|
|
133
|
+
.field-policy-suggestion-queue article p { margin: 0; }
|
|
134
|
+
.field-policy-suggestion-queue__actions { display: flex; flex-wrap: wrap; gap: var(--smrt-spacing-2, 0.5rem); }
|
|
135
|
+
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FieldPolicySuggestionAdapter } from '../suggestions.js';
|
|
2
|
+
export interface FieldPolicySuggestionQueueProps {
|
|
3
|
+
adapter: FieldPolicySuggestionAdapter;
|
|
4
|
+
objectRefs?: readonly string[];
|
|
5
|
+
heading?: string;
|
|
6
|
+
onchanged?: () => void;
|
|
7
|
+
}
|
|
8
|
+
declare const FieldPolicySuggestionQueue: import("svelte").Component<FieldPolicySuggestionQueueProps, {}, "">;
|
|
9
|
+
type FieldPolicySuggestionQueue = ReturnType<typeof FieldPolicySuggestionQueue>;
|
|
10
|
+
export default FieldPolicySuggestionQueue;
|
|
11
|
+
//# sourceMappingURL=FieldPolicySuggestionQueue.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldPolicySuggestionQueue.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/FieldPolicySuggestionQueue.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,4BAA4B,EAGlC,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,4BAA4B,CAAC;IACtC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAuHD,QAAA,MAAM,0BAA0B,qEAAwC,CAAC;AACzE,KAAK,0BAA0B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAChF,eAAe,0BAA0B,CAAC"}
|
|
@@ -9,7 +9,22 @@
|
|
|
9
9
|
* plus the object description if provided. The data comes entirely from the
|
|
10
10
|
* resolved policy — no separate fetch needed.
|
|
11
11
|
*
|
|
12
|
-
* Must be used inside a FieldPolicyProvider
|
|
12
|
+
* Must be used inside a FieldPolicyProvider — deliberately, via the throwing
|
|
13
|
+
* accessor. The panel's payload IS the resolved glossary, so with no provider
|
|
14
|
+
* there is nothing to assemble and a `?` affordance that opens onto "No field
|
|
15
|
+
* help available." would hide the mistake instead of reporting it. This matches
|
|
16
|
+
* the other provider-only compositions (`ModeSwitch`, `AdvancedFields`);
|
|
17
|
+
* `PolicyField` degrades instead only because it has caller-owned children to
|
|
18
|
+
* render verbatim.
|
|
19
|
+
*
|
|
20
|
+
* To put form help in a page header, extend the SAME provider over the header —
|
|
21
|
+
* it renders no markup of its own. Do not add a second one: each provider owns
|
|
22
|
+
* its own mode store and shadows the outer for its subtree, so a `FormHelp`
|
|
23
|
+
* above a nested provider stops tracking the `ModeSwitch` inside it (#2272).
|
|
24
|
+
*
|
|
25
|
+
* Inside `ObjectForm`, which builds its own provider, use its `actions` snippet
|
|
26
|
+
* — it renders within that provider, so the glossary resolves. There is no
|
|
27
|
+
* header seam, so it lands below the fields; tracked in #2289.
|
|
13
28
|
*/
|
|
14
29
|
import { getFieldPolicyContext } from '../context.svelte.js';
|
|
15
30
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormHelp.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/FormHelp.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FormHelp.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/FormHelp.svelte.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,KAAK;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuED,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -21,6 +21,11 @@ import {
|
|
|
21
21
|
type ObjectFormFieldDefinition,
|
|
22
22
|
type ObjectFormFieldSnippetProps,
|
|
23
23
|
} from '../types.js';
|
|
24
|
+
import {
|
|
25
|
+
collectFieldUsageEntries,
|
|
26
|
+
type FieldUsageReporter,
|
|
27
|
+
reportFieldUsage,
|
|
28
|
+
} from '../usage-capture.js';
|
|
24
29
|
import AdvancedFields from './AdvancedFields.svelte';
|
|
25
30
|
import FieldInput from './FieldInput.svelte';
|
|
26
31
|
import FieldPolicyGearButton from './FieldPolicyGearButton.svelte';
|
|
@@ -57,10 +62,23 @@ export interface ObjectFormProps {
|
|
|
57
62
|
renderers?: Readonly<Record<string, Snippet<[ObjectFormFieldSnippetProps]>>>;
|
|
58
63
|
/** Optional controls rendered after the policy-ordered fields inside the form. */
|
|
59
64
|
actions?: Snippet;
|
|
65
|
+
/**
|
|
66
|
+
* Optional telemetry transport. It runs only when `onsubmit` explicitly
|
|
67
|
+
* resolves `true` after persistence; identity and field sensitivity remain
|
|
68
|
+
* server-derived.
|
|
69
|
+
*/
|
|
70
|
+
usageReporter?: FieldUsageReporter;
|
|
60
71
|
class?: string;
|
|
61
|
-
|
|
72
|
+
/** Return true only after the host has persisted this record successfully. */
|
|
73
|
+
onsubmit?: ObjectFormSubmitHandler;
|
|
62
74
|
}
|
|
63
75
|
|
|
76
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: void handlers remain a supported legacy integration and never acknowledge persistence.
|
|
77
|
+
export type ObjectFormSubmitAcknowledgement = boolean | void;
|
|
78
|
+
export type ObjectFormSubmitHandler = (
|
|
79
|
+
event: SubmitEvent,
|
|
80
|
+
) => ObjectFormSubmitAcknowledgement | Promise<ObjectFormSubmitAcknowledgement>;
|
|
81
|
+
|
|
64
82
|
let {
|
|
65
83
|
objectRef,
|
|
66
84
|
fields = undefined,
|
|
@@ -74,6 +92,7 @@ let {
|
|
|
74
92
|
inputRegistry,
|
|
75
93
|
renderers = {},
|
|
76
94
|
actions,
|
|
95
|
+
usageReporter,
|
|
77
96
|
class: className = '',
|
|
78
97
|
onsubmit,
|
|
79
98
|
}: ObjectFormProps = $props();
|
|
@@ -201,6 +220,76 @@ function fieldId(name: string): string {
|
|
|
201
220
|
return `${formInstanceId}-${name}`;
|
|
202
221
|
}
|
|
203
222
|
|
|
223
|
+
function captureUsage(values: Readonly<Record<string, unknown>>): void {
|
|
224
|
+
if (!resolvedPolicy) return;
|
|
225
|
+
reportFieldUsage(
|
|
226
|
+
usageReporter,
|
|
227
|
+
collectFieldUsageEntries({
|
|
228
|
+
objectRef,
|
|
229
|
+
values,
|
|
230
|
+
// Hidden fields are not submitted user inputs. Basic and advanced fields
|
|
231
|
+
// are included even when a value matches the default so the server's
|
|
232
|
+
// dominance calculation has a complete denominator.
|
|
233
|
+
fields: Object.fromEntries(
|
|
234
|
+
formFields
|
|
235
|
+
.filter(
|
|
236
|
+
(field) =>
|
|
237
|
+
resolvedPolicy.fields[field.name].visibility !== 'hidden',
|
|
238
|
+
)
|
|
239
|
+
.map((field) => [field.name, field.definition.type]),
|
|
240
|
+
),
|
|
241
|
+
defaults: Object.fromEntries(
|
|
242
|
+
formFields
|
|
243
|
+
.filter(
|
|
244
|
+
(field) =>
|
|
245
|
+
resolvedPolicy.fields[field.name].visibility !== 'hidden',
|
|
246
|
+
)
|
|
247
|
+
.map((field) => {
|
|
248
|
+
const resolved = resolvedPolicy.fields[field.name];
|
|
249
|
+
return [
|
|
250
|
+
field.name,
|
|
251
|
+
{
|
|
252
|
+
hasDefault: resolved.hasDefault,
|
|
253
|
+
defaultValue: resolved.defaultValue,
|
|
254
|
+
},
|
|
255
|
+
];
|
|
256
|
+
}),
|
|
257
|
+
),
|
|
258
|
+
}),
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function handleSubmit(event: SubmitEvent): Promise<void> {
|
|
263
|
+
if (invalidFields.size > 0) {
|
|
264
|
+
event.preventDefault();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (!onsubmit) return;
|
|
268
|
+
// A successful create commonly replaces the bound record before its
|
|
269
|
+
// persistence promise resolves. Snapshot before awaiting so usage describes
|
|
270
|
+
// the fields that were submitted, not the newly cleared next-record state.
|
|
271
|
+
const submittedValues = snapshotUsageValues(value);
|
|
272
|
+
try {
|
|
273
|
+
// Form prevents native navigation itself, so persistence acknowledgement
|
|
274
|
+
// must be explicit rather than inferred from event.defaultPrevented.
|
|
275
|
+
if ((await onsubmit(event)) === true) captureUsage(submittedValues);
|
|
276
|
+
} catch {
|
|
277
|
+
// The host owns persistence errors; rejected submissions never emit usage.
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function snapshotUsageValues(
|
|
282
|
+
record: Readonly<Record<string, unknown>>,
|
|
283
|
+
): Record<string, unknown> {
|
|
284
|
+
try {
|
|
285
|
+
return structuredClone(record);
|
|
286
|
+
} catch {
|
|
287
|
+
// Generated form values are wire-safe, but retain a shallow fallback for
|
|
288
|
+
// host extensions that add an uncloneable value outside telemetry fields.
|
|
289
|
+
return { ...record };
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
204
293
|
// Apply policy defaults to a create record once, before a user can interact
|
|
205
294
|
// with any control. This preserves JSON and boolean defaults (which cannot be
|
|
206
295
|
// faithfully inferred from generic DOM string assignment) and means callers
|
|
@@ -330,7 +419,7 @@ function inputFor(field: ObjectFormField): FieldInputComponent {
|
|
|
330
419
|
<div class="object-form__gear"><FieldPolicyGearButton /></div>
|
|
331
420
|
{/if}
|
|
332
421
|
{/if}
|
|
333
|
-
<Form class="object-form {className}" onsubmit={
|
|
422
|
+
<Form class="object-form {className}" onsubmit={handleSubmit}>
|
|
334
423
|
{@render renderGroups(basicGroups)}
|
|
335
424
|
{#if advancedGroups.length > 0}
|
|
336
425
|
<AdvancedFields open>
|
|
@@ -2,6 +2,9 @@ import type { Component, Snippet } from 'svelte';
|
|
|
2
2
|
import type { ResolvedObjectFieldPolicy } from '../../types.js';
|
|
3
3
|
import type { FieldInputRegistry } from '../input-registry.js';
|
|
4
4
|
import { type ObjectFormFieldDefinition, type ObjectFormFieldSnippetProps } from '../types.js';
|
|
5
|
+
import { type FieldUsageReporter } from '../usage-capture.js';
|
|
6
|
+
export type ObjectFormSubmitAcknowledgement = boolean | void;
|
|
7
|
+
export type ObjectFormSubmitHandler = (event: SubmitEvent) => ObjectFormSubmitAcknowledgement | Promise<ObjectFormSubmitAcknowledgement>;
|
|
5
8
|
export interface ObjectFormProps {
|
|
6
9
|
objectRef: string;
|
|
7
10
|
/**
|
|
@@ -31,8 +34,15 @@ export interface ObjectFormProps {
|
|
|
31
34
|
renderers?: Readonly<Record<string, Snippet<[ObjectFormFieldSnippetProps]>>>;
|
|
32
35
|
/** Optional controls rendered after the policy-ordered fields inside the form. */
|
|
33
36
|
actions?: Snippet;
|
|
37
|
+
/**
|
|
38
|
+
* Optional telemetry transport. It runs only when `onsubmit` explicitly
|
|
39
|
+
* resolves `true` after persistence; identity and field sensitivity remain
|
|
40
|
+
* server-derived.
|
|
41
|
+
*/
|
|
42
|
+
usageReporter?: FieldUsageReporter;
|
|
34
43
|
class?: string;
|
|
35
|
-
|
|
44
|
+
/** Return true only after the host has persisted this record successfully. */
|
|
45
|
+
onsubmit?: ObjectFormSubmitHandler;
|
|
36
46
|
}
|
|
37
47
|
declare const ObjectForm: Component<ObjectFormProps, {}, "value">;
|
|
38
48
|
type ObjectForm = ReturnType<typeof ObjectForm>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ObjectForm.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,KAAK,EAEV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EACjC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ObjectForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ObjectForm.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,KAAK,EAEV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAU7B,MAAM,MAAM,+BAA+B,GAAG,OAAO,GAAG,IAAI,CAAC;AAC7D,MAAM,MAAM,uBAAuB,GAAG,CACpC,KAAK,EAAE,WAAW,KACf,+BAA+B,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;AAEhF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC7D,mFAAmF;IACnF,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,uBAAuB,CAAC;CACpC;AAgXD,QAAA,MAAM,UAAU,yCAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -12,6 +12,21 @@
|
|
|
12
12
|
* outside a Provider: an unwrapped field renders its children verbatim, and a
|
|
13
13
|
* consumer can adopt the primitives incrementally without wrapping the whole
|
|
14
14
|
* form.
|
|
15
|
+
*
|
|
16
|
+
* The two accessors are a deliberate two-tier contract, not a style choice:
|
|
17
|
+
*
|
|
18
|
+
* - `tryGetFieldPolicyContext` is for a primitive that still has something
|
|
19
|
+
* meaningful to render without a policy — today only `PolicyField`, whose
|
|
20
|
+
* fallback is the caller's own children.
|
|
21
|
+
* - `getFieldPolicyContext` is for the provider-only compositions
|
|
22
|
+
* (`ModeSwitch`, `AdvancedFields`, `FormHelp`) whose entire output is derived
|
|
23
|
+
* from the resolved policy. Degrading those would render an empty or absent
|
|
24
|
+
* control rather than surface the missing Provider, so they throw with an
|
|
25
|
+
* actionable message instead (#2272).
|
|
26
|
+
*
|
|
27
|
+
* One provider per form. `setContext` shadows, so a nested `FieldPolicyProvider`
|
|
28
|
+
* gives its subtree a second, independent `FieldPolicyModeStore` — consumers
|
|
29
|
+
* above the nested provider then stop tracking the `ModeSwitch` below it.
|
|
15
30
|
*/
|
|
16
31
|
import type { ResolvedFieldPolicy, ResolvedObjectFieldPolicy } from '../types.js';
|
|
17
32
|
/** UI display mode for progressive disclosure. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/context.svelte.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"context.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/context.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EACV,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAErB,kDAAkD;AAClD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,CAAC;AAEnD;;;;GAIG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,kBAAoC;gBAE/B,OAAO,GAAE,eAAyB;IAI9C,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAIhC,MAAM,IAAI,IAAI;CAGf;AAED,+EAA+E;AAC/E,MAAM,WAAW,uBAAuB;IACtC,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAC3C,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAAC;IAC7D,iEAAiE;IACjE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAID,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAE5E;AAED,4DAA4D;AAC5D,wBAAgB,qBAAqB,IAAI,uBAAuB,CAS/D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,IACpC,uBAAuB,GACvB,SAAS,CAIZ"}
|
|
@@ -12,6 +12,21 @@
|
|
|
12
12
|
* outside a Provider: an unwrapped field renders its children verbatim, and a
|
|
13
13
|
* consumer can adopt the primitives incrementally without wrapping the whole
|
|
14
14
|
* form.
|
|
15
|
+
*
|
|
16
|
+
* The two accessors are a deliberate two-tier contract, not a style choice:
|
|
17
|
+
*
|
|
18
|
+
* - `tryGetFieldPolicyContext` is for a primitive that still has something
|
|
19
|
+
* meaningful to render without a policy — today only `PolicyField`, whose
|
|
20
|
+
* fallback is the caller's own children.
|
|
21
|
+
* - `getFieldPolicyContext` is for the provider-only compositions
|
|
22
|
+
* (`ModeSwitch`, `AdvancedFields`, `FormHelp`) whose entire output is derived
|
|
23
|
+
* from the resolved policy. Degrading those would render an empty or absent
|
|
24
|
+
* control rather than surface the missing Provider, so they throw with an
|
|
25
|
+
* actionable message instead (#2272).
|
|
26
|
+
*
|
|
27
|
+
* One provider per form. `setContext` shadows, so a nested `FieldPolicyProvider`
|
|
28
|
+
* gives its subtree a second, independent `FieldPolicyModeStore` — consumers
|
|
29
|
+
* above the nested provider then stop tracking the `ModeSwitch` below it.
|
|
15
30
|
*/
|
|
16
31
|
import { getContext, setContext } from 'svelte';
|
|
17
32
|
/**
|
|
@@ -4,6 +4,8 @@ export interface FieldPolicyGearController {
|
|
|
4
4
|
readonly error: string | null;
|
|
5
5
|
readonly open: boolean;
|
|
6
6
|
readonly canEdit: boolean;
|
|
7
|
+
/** Pending reviewed suggestions for this form's object, when configured. */
|
|
8
|
+
readonly pendingSuggestionCount: number;
|
|
7
9
|
show(): void;
|
|
8
10
|
hide(): void;
|
|
9
11
|
reload(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gear-context.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/gear-context.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAID,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,yBAAyB,GACpC,IAAI,CAEN;AAED,wBAAgB,yBAAyB,IAAI,yBAAyB,CAQrE;AAED,wBAAgB,4BAA4B,IACxC,yBAAyB,GACzB,SAAS,CAIZ"}
|
|
1
|
+
{"version":3,"file":"gear-context.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/gear-context.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAID,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,yBAAyB,GACpC,IAAI,CAEN;AAED,wBAAgB,yBAAyB,IAAI,yBAAyB,CAQrE;AAED,wBAAgB,4BAA4B,IACxC,yBAAyB,GACzB,SAAS,CAIZ"}
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -21,22 +21,25 @@ import FieldPolicyEditor from './components/FieldPolicyEditor.svelte';
|
|
|
21
21
|
import FieldPolicyGearButton from './components/FieldPolicyGearButton.svelte';
|
|
22
22
|
import FieldPolicyGearProvider from './components/FieldPolicyGearProvider.svelte';
|
|
23
23
|
import FieldPolicyProvider from './components/FieldPolicyProvider.svelte';
|
|
24
|
+
import FieldPolicySuggestionQueue from './components/FieldPolicySuggestionQueue.svelte';
|
|
24
25
|
import FormHelp from './components/FormHelp.svelte';
|
|
25
26
|
import ModeSwitch from './components/ModeSwitch.svelte';
|
|
26
27
|
import ObjectForm from './components/ObjectForm.svelte';
|
|
27
28
|
import ObjectFormSourceProvider from './components/ObjectFormSourceProvider.svelte';
|
|
28
29
|
import PolicyField from './components/PolicyField.svelte';
|
|
29
|
-
export { AdvancedFields, FieldPolicyControlPanel, FieldPolicyEditor, FieldPolicyGearButton, FieldPolicyGearProvider, FieldPolicyProvider, FormHelp, ModeSwitch, ObjectForm, ObjectFormSourceProvider, PolicyField, };
|
|
30
|
+
export { AdvancedFields, FieldPolicyControlPanel, FieldPolicyEditor, FieldPolicyGearButton, FieldPolicyGearProvider, FieldPolicyProvider, FieldPolicySuggestionQueue, FormHelp, ModeSwitch, ObjectForm, ObjectFormSourceProvider, PolicyField, };
|
|
30
31
|
export type AdvancedFieldsProps = ComponentProps<typeof AdvancedFields>;
|
|
31
32
|
export type FieldPolicyProviderProps = ComponentProps<typeof FieldPolicyProvider>;
|
|
32
33
|
export type FormHelpProps = ComponentProps<typeof FormHelp>;
|
|
33
34
|
export type ModeSwitchProps = ComponentProps<typeof ModeSwitch>;
|
|
34
35
|
export type ObjectFormProps = ComponentProps<typeof ObjectForm>;
|
|
36
|
+
export type { ObjectFormSubmitAcknowledgement, ObjectFormSubmitHandler, } from './components/ObjectForm.svelte';
|
|
35
37
|
export type ObjectFormSourceProviderProps = ComponentProps<typeof ObjectFormSourceProvider>;
|
|
36
38
|
export type FieldPolicyEditorProps = ComponentProps<typeof FieldPolicyEditor>;
|
|
37
39
|
export type FieldPolicyControlPanelProps = ComponentProps<typeof FieldPolicyControlPanel>;
|
|
38
40
|
export type FieldPolicyGearButtonProps = ComponentProps<typeof FieldPolicyGearButton>;
|
|
39
41
|
export type FieldPolicyGearProviderProps = ComponentProps<typeof FieldPolicyGearProvider>;
|
|
42
|
+
export type FieldPolicySuggestionQueueProps = ComponentProps<typeof FieldPolicySuggestionQueue>;
|
|
40
43
|
export type PolicyFieldProps = ComponentProps<typeof PolicyField>;
|
|
41
44
|
export type { FieldPolicyCatalogObjectSummary, FieldPolicyDetailItem, FieldPolicySettingsCatalogData, FieldPolicySettingsCatalogPage, FieldPolicySummaryItem, } from '../settings-catalog.js';
|
|
42
45
|
export type { ResolvedFieldPolicy, ResolvedObjectFieldPolicy, } from '../types.js';
|
|
@@ -54,5 +57,7 @@ export { resolveObjectFormFields } from './object-form.js';
|
|
|
54
57
|
export { assertObjectFormCollectionDefinition, ObjectFormSourceRegistry, } from './object-form-source.svelte.js';
|
|
55
58
|
export type { FieldPolicyControlPanelAdapter, FieldPolicyFieldRollup, FieldPolicyLayerCell, } from './settings-catalog.js';
|
|
56
59
|
export { auditObjectRefs, decorateCatalogItem, decorateCatalogPage, fieldPolicyControlPanelNavItem, fieldPolicyRollup, MAX_FIELD_POLICY_AUDIT_OBJECT_REFS, orgRowIdsForObject, prunableDriftRows, } from './settings-catalog.js';
|
|
60
|
+
export { type FieldPolicySuggestion, type FieldPolicySuggestionAdapter, type FieldPolicySuggestionKind, fieldPolicySuggestionEvidence, parsePendingFieldPolicySuggestions, } from './suggestions.js';
|
|
57
61
|
export type { FieldInputProps, ObjectFormCollectionDefinition, ObjectFormField, ObjectFormFieldDefinition, ObjectFormFieldSnippetProps, ObjectFormPolicyClient, ObjectFormResolvedSource, ObjectFormSource, ObjectFormWireType, PolicyFieldSnippetProps, } from './types.js';
|
|
62
|
+
export { type CollectFieldUsageEntriesOptions, canCaptureFieldUsageValue, collectFieldUsageEntries, type FieldUsageDefault, type FieldUsageEntry, type FieldUsageReporter, type FieldUsageWireType, fieldUsageValuesEqual, isBlankFieldValue, reportFieldUsage, } from './usage-capture.js';
|
|
58
63
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"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"}
|
package/dist/svelte/index.js
CHANGED
|
@@ -20,13 +20,14 @@ import FieldPolicyEditor from './components/FieldPolicyEditor.svelte';
|
|
|
20
20
|
import FieldPolicyGearButton from './components/FieldPolicyGearButton.svelte';
|
|
21
21
|
import FieldPolicyGearProvider from './components/FieldPolicyGearProvider.svelte';
|
|
22
22
|
import FieldPolicyProvider from './components/FieldPolicyProvider.svelte';
|
|
23
|
+
import FieldPolicySuggestionQueue from './components/FieldPolicySuggestionQueue.svelte';
|
|
23
24
|
import FormHelp from './components/FormHelp.svelte';
|
|
24
25
|
import ModeSwitch from './components/ModeSwitch.svelte';
|
|
25
26
|
import ObjectForm from './components/ObjectForm.svelte';
|
|
26
27
|
import ObjectFormSourceProvider from './components/ObjectFormSourceProvider.svelte';
|
|
27
28
|
import PolicyField from './components/PolicyField.svelte';
|
|
28
29
|
// Components
|
|
29
|
-
export { AdvancedFields, FieldPolicyControlPanel, FieldPolicyEditor, FieldPolicyGearButton, FieldPolicyGearProvider, FieldPolicyProvider, FormHelp, ModeSwitch, ObjectForm, ObjectFormSourceProvider, PolicyField, };
|
|
30
|
+
export { AdvancedFields, FieldPolicyControlPanel, FieldPolicyEditor, FieldPolicyGearButton, FieldPolicyGearProvider, FieldPolicyProvider, FieldPolicySuggestionQueue, FormHelp, ModeSwitch, ObjectForm, ObjectFormSourceProvider, PolicyField, };
|
|
30
31
|
// Context types and accessors
|
|
31
32
|
export { getFieldPolicyContext, setFieldPolicyContext, tryGetFieldPolicyContext, } from './context.svelte.js';
|
|
32
33
|
export { policyToVisibleColumnIds } from './data-table.js';
|
|
@@ -36,3 +37,5 @@ export { createFieldInputRegistry, FieldInputRegistry, } from './input-registry.
|
|
|
36
37
|
export { resolveObjectFormFields } from './object-form.js';
|
|
37
38
|
export { assertObjectFormCollectionDefinition, ObjectFormSourceRegistry, } from './object-form-source.svelte.js';
|
|
38
39
|
export { auditObjectRefs, decorateCatalogItem, decorateCatalogPage, fieldPolicyControlPanelNavItem, fieldPolicyRollup, MAX_FIELD_POLICY_AUDIT_OBJECT_REFS, orgRowIdsForObject, prunableDriftRows, } from './settings-catalog.js';
|
|
40
|
+
export { fieldPolicySuggestionEvidence, parsePendingFieldPolicySuggestions, } from './suggestions.js';
|
|
41
|
+
export { canCaptureFieldUsageValue, collectFieldUsageEntries, fieldUsageValuesEqual, isBlankFieldValue, reportFieldUsage, } from './usage-capture.js';
|
|
@@ -97,19 +97,25 @@ function handleSubmit() {
|
|
|
97
97
|
</script>
|
|
98
98
|
|
|
99
99
|
<section class="field-policy-preview">
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
</p>
|
|
107
|
-
<FormHelp
|
|
108
|
-
objectDescription="A sellable catalog product with wholesale pricing and inventory controls."
|
|
109
|
-
/>
|
|
110
|
-
</header>
|
|
111
|
-
|
|
100
|
+
<!--
|
|
101
|
+
ONE provider, extended over the header too. FormHelp assembles its glossary
|
|
102
|
+
from the provider context and must live inside it; the provider renders no
|
|
103
|
+
markup of its own, so covering the header costs no layout. Do not add a
|
|
104
|
+
second provider to reach it — a nested one shadows this mode store — #2272.
|
|
105
|
+
-->
|
|
112
106
|
<FieldPolicyProvider policy={resolvedPolicy} mode="basic">
|
|
107
|
+
<header class="preview-header">
|
|
108
|
+
<h2>Hand-written form adopting PolicyField</h2>
|
|
109
|
+
<p class="preview-desc">
|
|
110
|
+
A developer-authored product form. Two fields (name, SKU) adopt
|
|
111
|
+
PolicyField for help, defaults, and progressive disclosure; the rest stay
|
|
112
|
+
hand-written. Toggle the mode switch to reveal advanced-tier fields.
|
|
113
|
+
</p>
|
|
114
|
+
<FormHelp
|
|
115
|
+
objectDescription="A sellable catalog product with wholesale pricing and inventory controls."
|
|
116
|
+
/>
|
|
117
|
+
</header>
|
|
118
|
+
|
|
113
119
|
<div class="toolbar">
|
|
114
120
|
<ModeSwitch />
|
|
115
121
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldPolicyFormPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/FieldPolicyFormPreview.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FieldPolicyFormPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/FieldPolicyFormPreview.svelte.ts"],"names":[],"mappings":"AAsKA,QAAA,MAAM,sBAAsB,2DAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural browser contracts for field-policy suggestion review.
|
|
3
|
+
*
|
|
4
|
+
* These types intentionally omit tenant, user, authorization, and field
|
|
5
|
+
* sensitivity data. Hosts bind methods to authenticated generated clients;
|
|
6
|
+
* the server derives identity and validates every action.
|
|
7
|
+
*/
|
|
8
|
+
export type FieldPolicySuggestionKind = 'promote' | 'default';
|
|
9
|
+
export interface FieldPolicySuggestion {
|
|
10
|
+
id: string;
|
|
11
|
+
objectRef: string;
|
|
12
|
+
fieldName: string;
|
|
13
|
+
kind: FieldPolicySuggestionKind;
|
|
14
|
+
proposedValue: string | null;
|
|
15
|
+
evidence: Readonly<Record<string, unknown>>;
|
|
16
|
+
}
|
|
17
|
+
export interface FieldPolicySuggestionAdapter {
|
|
18
|
+
pendingSuggestions(input?: {
|
|
19
|
+
objectRefs?: readonly string[];
|
|
20
|
+
}): Promise<unknown>;
|
|
21
|
+
acceptSuggestion(input: {
|
|
22
|
+
id: string;
|
|
23
|
+
}): Promise<unknown>;
|
|
24
|
+
dismissSuggestion(input: {
|
|
25
|
+
id: string;
|
|
26
|
+
}): Promise<unknown>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate generated custom-action output at the browser boundary. A malformed
|
|
30
|
+
* response is an error, never an empty queue that could conceal work.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parsePendingFieldPolicySuggestions(value: unknown): {
|
|
33
|
+
suggestions: FieldPolicySuggestion[];
|
|
34
|
+
total: number;
|
|
35
|
+
};
|
|
36
|
+
/** Human-readable evidence without assuming a server-side evidence schema. */
|
|
37
|
+
export declare function fieldPolicySuggestionEvidence(suggestion: FieldPolicySuggestion): string;
|
|
38
|
+
//# sourceMappingURL=suggestions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestions.d.ts","sourceRoot":"","sources":["../../src/svelte/suggestions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,yBAAyB,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,CAAC,KAAK,CAAC,EAAE;QACzB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KAChC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrB,gBAAgB,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,iBAAiB,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5D;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,OAAO,GAAG;IAClE,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf,CAsBA;AAmCD,8EAA8E;AAC9E,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,qBAAqB,GAChC,MAAM,CASR"}
|