@cratis/scene.components 3.6.0 → 3.7.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 (82) hide show
  1. package/README.md +17 -1
  2. package/dist/cjs/forms/CommandFormRuntime.js +81 -0
  3. package/dist/cjs/forms/CommandFormRuntime.js.map +1 -0
  4. package/dist/cjs/forms/CommandFormSubmit.js +19 -0
  5. package/dist/cjs/forms/CommandFormSubmit.js.map +1 -0
  6. package/dist/cjs/forms/ExplicitCommandField.js +109 -0
  7. package/dist/cjs/forms/ExplicitCommandField.js.map +1 -0
  8. package/dist/cjs/forms/SceneCommandForm.js +26 -21
  9. package/dist/cjs/forms/SceneCommandForm.js.map +1 -1
  10. package/dist/cjs/forms/commandInputs.js +35 -0
  11. package/dist/cjs/forms/commandInputs.js.map +1 -0
  12. package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.d.ts +2 -0
  13. package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.d.ts.map +1 -0
  14. package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.js +16 -0
  15. package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.js.map +1 -0
  16. package/dist/esm/forms/CommandFormRuntime.d.ts +11 -0
  17. package/dist/esm/forms/CommandFormRuntime.d.ts.map +1 -0
  18. package/dist/esm/forms/CommandFormRuntime.js +77 -0
  19. package/dist/esm/forms/CommandFormRuntime.js.map +1 -0
  20. package/dist/esm/forms/CommandFormSubmit.d.ts +6 -0
  21. package/dist/esm/forms/CommandFormSubmit.d.ts.map +1 -0
  22. package/dist/esm/forms/CommandFormSubmit.js +17 -0
  23. package/dist/esm/forms/CommandFormSubmit.js.map +1 -0
  24. package/dist/esm/forms/ExplicitCommandField.d.ts +5 -0
  25. package/dist/esm/forms/ExplicitCommandField.d.ts.map +1 -0
  26. package/dist/esm/forms/ExplicitCommandField.js +107 -0
  27. package/dist/esm/forms/ExplicitCommandField.js.map +1 -0
  28. package/dist/esm/forms/SceneCommandForm.d.ts.map +1 -1
  29. package/dist/esm/forms/SceneCommandForm.js +27 -22
  30. package/dist/esm/forms/SceneCommandForm.js.map +1 -1
  31. package/dist/esm/forms/commandInputs.d.ts +7 -0
  32. package/dist/esm/forms/commandInputs.d.ts.map +1 -0
  33. package/dist/esm/forms/commandInputs.js +33 -0
  34. package/dist/esm/forms/commandInputs.js.map +1 -0
  35. package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.d.ts +22 -0
  36. package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.d.ts.map +1 -0
  37. package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.js +30 -0
  38. package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.js.map +1 -0
  39. package/dist/esm/forms/for_SceneCommandForm/given/StartProject.d.ts +32 -0
  40. package/dist/esm/forms/for_SceneCommandForm/given/StartProject.d.ts.map +1 -0
  41. package/dist/esm/forms/for_SceneCommandForm/given/StartProject.js +32 -0
  42. package/dist/esm/forms/for_SceneCommandForm/given/StartProject.js.map +1 -0
  43. package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.d.ts +2 -0
  44. package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.d.ts.map +1 -0
  45. package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.js +66 -0
  46. package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.js.map +1 -0
  47. package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.d.ts +2 -0
  48. package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.d.ts.map +1 -0
  49. package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.js +26 -0
  50. package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.js.map +1 -0
  51. package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.d.ts +2 -0
  52. package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.d.ts.map +1 -0
  53. package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.js +44 -0
  54. package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.js.map +1 -0
  55. package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.d.ts +2 -0
  56. package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.d.ts.map +1 -0
  57. package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.js +49 -0
  58. package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.js.map +1 -0
  59. package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.d.ts +2 -0
  60. package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.d.ts.map +1 -0
  61. package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.js +176 -0
  62. package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.js.map +1 -0
  63. package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.d.ts +2 -0
  64. package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.d.ts.map +1 -0
  65. package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.js +110 -0
  66. package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.js.map +1 -0
  67. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  68. package/for_cratisComponentsPackage/when_declaring_command_form_peers.ts +26 -0
  69. package/forms/CommandFormRuntime.tsx +71 -0
  70. package/forms/CommandFormSubmit.tsx +16 -0
  71. package/forms/ExplicitCommandField.tsx +86 -0
  72. package/forms/SceneCommandForm.tsx +30 -27
  73. package/forms/commandInputs.ts +29 -0
  74. package/forms/for_SceneCommandForm/given/RecordNote.ts +37 -0
  75. package/forms/for_SceneCommandForm/given/StartProject.ts +41 -0
  76. package/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.tsx +69 -0
  77. package/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.tsx +33 -0
  78. package/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.tsx +50 -0
  79. package/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.tsx +56 -0
  80. package/forms/for_SceneCommandForm/when_submitting_explicit_inputs.tsx +189 -0
  81. package/forms/for_SceneCommandForm/when_submitting_the_native_form.tsx +120 -0
  82. package/package.json +13 -13
@@ -0,0 +1,107 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useId, useRef, useState, useLayoutEffect } from 'react';
3
+ import { asCommandFormField, useCommandFormContext } from '@cratis/arc.react/commands';
4
+ import { Guid } from '@cratis/fundamentals';
5
+
6
+ function TextControl({ value, onChange, onBlur, invalid, required, errors, label, property, guid }) {
7
+ const id = useId();
8
+ const context = useCommandFormContext();
9
+ const { setCustomFieldError } = context;
10
+ // Keep the latest native getter: the context snapshot can be stale when another field sets an
11
+ // error and this field unmounts in the same event.
12
+ const contextRef = useRef(context);
13
+ contextRef.current = context;
14
+ // The draft is intentionally independent of the typed proxy value: malformed text must never
15
+ // reappear as a stale previously valid Guid in the command's serialized payload.
16
+ const [draft, setDraft] = useState(()=>value instanceof Guid && !value.equals(Guid.empty) ? value.toString() : '');
17
+ const draftRef = useRef(draft);
18
+ const ownedError = useRef(undefined);
19
+ const updateError = (error)=>{
20
+ const current = contextRef.current.getFieldError(property);
21
+ // Do not replace or erase another producer's error for this field.
22
+ if (ownedError.current !== undefined && current !== ownedError.current) {
23
+ ownedError.current = undefined;
24
+ return;
25
+ }
26
+ if (ownedError.current === undefined && Object.hasOwn(contextRef.current.customFieldErrors, property)) return;
27
+ if (error === undefined && ownedError.current === undefined) return;
28
+ ownedError.current = error;
29
+ setCustomFieldError(property, error);
30
+ };
31
+ // A label/required change must recalculate the message without disposing the field's error.
32
+ // Only a different field/type or an actual unmount relinquishes ownership.
33
+ useLayoutEffect(()=>()=>{
34
+ if (ownedError.current !== undefined && contextRef.current.getFieldError(property) === ownedError.current) {
35
+ contextRef.current.setCustomFieldError(property, undefined);
36
+ }
37
+ ownedError.current = undefined;
38
+ }, [
39
+ property,
40
+ guid
41
+ ]);
42
+ useLayoutEffect(()=>{
43
+ if (guid) {
44
+ const current = draftRef.current || (value instanceof Guid && !value.equals(Guid.empty) ? value.toString() : '');
45
+ updateError(!current ? required ? `${label} is required` : undefined : !Guid.isGuid(current) ? `${label} must be a valid GUID` : undefined);
46
+ }
47
+ }, [
48
+ guid,
49
+ required,
50
+ property,
51
+ label,
52
+ setCustomFieldError
53
+ ]);
54
+ const text = guid ? draft : typeof value === 'string' ? value : '';
55
+ return /*#__PURE__*/ jsxs("div", {
56
+ children: [
57
+ /*#__PURE__*/ jsx("label", {
58
+ htmlFor: id,
59
+ children: label
60
+ }),
61
+ /*#__PURE__*/ jsx("input", {
62
+ id: id,
63
+ name: property,
64
+ type: "text",
65
+ required: required,
66
+ value: text,
67
+ "aria-invalid": invalid,
68
+ "aria-describedby": errors.length ? `${id}-error` : undefined,
69
+ onBlur: onBlur,
70
+ onChange: (event)=>{
71
+ const next = event.currentTarget.value;
72
+ if (!guid) {
73
+ onChange(next);
74
+ return;
75
+ }
76
+ draftRef.current = next;
77
+ setDraft(next);
78
+ const error = !next ? required ? `${label} is required` : undefined : !Guid.isGuid(next) ? `${label} must be a valid GUID` : undefined;
79
+ // A malformed draft clears the previously typed value, not just its display.
80
+ onChange(error || !next ? undefined : Guid.parse(next));
81
+ updateError(error);
82
+ }
83
+ }),
84
+ errors.length > 0 && /*#__PURE__*/ jsx("div", {
85
+ id: `${id}-error`,
86
+ role: "alert",
87
+ children: errors[0]
88
+ })
89
+ ]
90
+ });
91
+ }
92
+ const NativeTextField = asCommandFormField(TextControl, {
93
+ defaultValue: ''
94
+ });
95
+ /** Opaque child is self-bound by Arc's native runtime binding, with an exact fieldName. */ function ExplicitCommandField({ input }) {
96
+ return /*#__PURE__*/ jsx(NativeTextField, {
97
+ fieldName: input.property,
98
+ value: (command)=>command[input.property],
99
+ property: input.property,
100
+ guid: input.type === 'guid',
101
+ label: input.label,
102
+ title: input.label
103
+ });
104
+ }
105
+
106
+ export { ExplicitCommandField };
107
+ //# sourceMappingURL=ExplicitCommandField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExplicitCommandField.js","sources":["../../../forms/ExplicitCommandField.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useId, useLayoutEffect, useRef, useState } from 'react';\nimport { asCommandFormField, useCommandFormContext } from '@cratis/arc.react/commands';\nimport { Guid } from '@cratis/fundamentals';\nimport type { CommandInput } from './commandInputs';\n\ninterface TextProps {\n value: unknown;\n onChange: (value: unknown) => void;\n onBlur?: () => void;\n invalid: boolean;\n required: boolean;\n errors: string[];\n label: string;\n property: string;\n guid: boolean;\n}\n\nfunction TextControl({ value, onChange, onBlur, invalid, required, errors, label, property, guid }: TextProps) {\n const id = useId();\n const context = useCommandFormContext();\n const { setCustomFieldError } = context;\n // Keep the latest native getter: the context snapshot can be stale when another field sets an\n // error and this field unmounts in the same event.\n const contextRef = useRef(context);\n contextRef.current = context;\n // The draft is intentionally independent of the typed proxy value: malformed text must never\n // reappear as a stale previously valid Guid in the command's serialized payload.\n const [draft, setDraft] = useState(() => value instanceof Guid && !value.equals(Guid.empty) ? value.toString() : '');\n const draftRef = useRef(draft);\n const ownedError = useRef<string | undefined>(undefined);\n const updateError = (error: string | undefined) => {\n const current = contextRef.current.getFieldError(property);\n // Do not replace or erase another producer's error for this field.\n if (ownedError.current !== undefined && current !== ownedError.current) {\n ownedError.current = undefined;\n return;\n }\n if (ownedError.current === undefined && Object.hasOwn(contextRef.current.customFieldErrors, property)) return;\n if (error === undefined && ownedError.current === undefined) return;\n ownedError.current = error;\n setCustomFieldError(property, error);\n };\n // A label/required change must recalculate the message without disposing the field's error.\n // Only a different field/type or an actual unmount relinquishes ownership.\n useLayoutEffect(() => () => {\n if (ownedError.current !== undefined && contextRef.current.getFieldError(property) === ownedError.current) {\n contextRef.current.setCustomFieldError(property, undefined);\n }\n ownedError.current = undefined;\n }, [property, guid]);\n useLayoutEffect(() => {\n if (guid) {\n const current = draftRef.current || (value instanceof Guid && !value.equals(Guid.empty) ? value.toString() : '');\n updateError(!current ? required ? `${label} is required` : undefined :\n !Guid.isGuid(current) ? `${label} must be a valid GUID` : undefined);\n }\n }, [guid, required, property, label, setCustomFieldError]);\n const text = guid ? draft : typeof value === 'string' ? value : '';\n return <div>\n <label htmlFor={id}>{label}</label>\n <input id={id} name={property} type='text' required={required} value={text}\n aria-invalid={invalid} aria-describedby={errors.length ? `${id}-error` : undefined}\n onBlur={onBlur} onChange={event => {\n const next = event.currentTarget.value;\n if (!guid) { onChange(next); return; }\n draftRef.current = next;\n setDraft(next);\n const error = !next ? required ? `${label} is required` : undefined : !Guid.isGuid(next) ? `${label} must be a valid GUID` : undefined;\n // A malformed draft clears the previously typed value, not just its display.\n onChange(error || !next ? undefined : Guid.parse(next));\n updateError(error);\n }} />\n {errors.length > 0 && <div id={`${id}-error`} role='alert'>{errors[0]}</div>}\n </div>;\n}\n\nconst NativeTextField = asCommandFormField<TextProps>(TextControl, { defaultValue: '' });\n\n/** Opaque child is self-bound by Arc's native runtime binding, with an exact fieldName. */\nexport function ExplicitCommandField({ input }: { input: CommandInput }) {\n return <NativeTextField fieldName={input.property} value={(command: Record<string, unknown>) => command[input.property]}\n property={input.property} guid={input.type === 'guid'} label={input.label} title={input.label} />;\n}\n"],"names":["TextControl","value","onChange","onBlur","invalid","required","errors","label","property","guid","id","useId","context","useCommandFormContext","setCustomFieldError","contextRef","useRef","current","draft","setDraft","useState","Guid","equals","empty","toString","draftRef","ownedError","undefined","updateError","error","getFieldError","Object","hasOwn","customFieldErrors","useLayoutEffect","isGuid","text","_jsxs","div","_jsx","htmlFor","input","name","type","aria-invalid","aria-describedby","length","event","next","currentTarget","parse","role","NativeTextField","asCommandFormField","defaultValue","ExplicitCommandField","fieldName","command","title"],"mappings":";;;;;AAoBA,SAASA,YAAY,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,IAAI,EAAa,EAAA;AACzG,IAAA,MAAMC,EAAAA,GAAKC,KAAAA,EAAAA;AACX,IAAA,MAAMC,OAAAA,GAAUC,qBAAAA,EAAAA;IAChB,MAAM,EAAEC,mBAAmB,EAAE,GAAGF,OAAAA;;;AAGhC,IAAA,MAAMG,aAAaC,MAAAA,CAAOJ,OAAAA,CAAAA;AAC1BG,IAAAA,UAAAA,CAAWE,OAAO,GAAGL,OAAAA;;;AAGrB,IAAA,MAAM,CAACM,KAAAA,EAAOC,QAAAA,CAAS,GAAGC,QAAAA,CAAS,IAAMnB,KAAAA,YAAiBoB,IAAAA,IAAQ,CAACpB,KAAAA,CAAMqB,MAAM,CAACD,IAAAA,CAAKE,KAAK,CAAA,GAAItB,KAAAA,CAAMuB,QAAQ,EAAA,GAAK,EAAA,CAAA;AACjH,IAAA,MAAMC,WAAWT,MAAAA,CAAOE,KAAAA,CAAAA;AACxB,IAAA,MAAMQ,aAAaV,MAAAA,CAA2BW,SAAAA,CAAAA;AAC9C,IAAA,MAAMC,cAAc,CAACC,KAAAA,GAAAA;AACjB,QAAA,MAAMZ,OAAAA,GAAUF,UAAAA,CAAWE,OAAO,CAACa,aAAa,CAACtB,QAAAA,CAAAA;;AAEjD,QAAA,IAAIkB,WAAWT,OAAO,KAAKU,aAAaV,OAAAA,KAAYS,UAAAA,CAAWT,OAAO,EAAE;AACpES,YAAAA,UAAAA,CAAWT,OAAO,GAAGU,SAAAA;AACrB,YAAA;AACJ,QAAA;AACA,QAAA,IAAID,UAAAA,CAAWT,OAAO,KAAKU,SAAAA,IAAaI,MAAAA,CAAOC,MAAM,CAACjB,UAAAA,CAAWE,OAAO,CAACgB,iBAAiB,EAAEzB,QAAAA,CAAAA,EAAW;AACvG,QAAA,IAAIqB,KAAAA,KAAUF,SAAAA,IAAaD,UAAAA,CAAWT,OAAO,KAAKU,SAAAA,EAAW;AAC7DD,QAAAA,UAAAA,CAAWT,OAAO,GAAGY,KAAAA;AACrBf,QAAAA,mBAAAA,CAAoBN,QAAAA,EAAUqB,KAAAA,CAAAA;AAClC,IAAA,CAAA;;;AAGAK,IAAAA,eAAAA,CAAgB,IAAM,IAAA;AAClB,YAAA,IAAIR,UAAAA,CAAWT,OAAO,KAAKU,SAAAA,IAAaZ,UAAAA,CAAWE,OAAO,CAACa,aAAa,CAACtB,QAAAA,CAAAA,KAAckB,UAAAA,CAAWT,OAAO,EAAE;AACvGF,gBAAAA,UAAAA,CAAWE,OAAO,CAACH,mBAAmB,CAACN,QAAAA,EAAUmB,SAAAA,CAAAA;AACrD,YAAA;AACAD,YAAAA,UAAAA,CAAWT,OAAO,GAAGU,SAAAA;QACzB,CAAA,EAAG;AAACnB,QAAAA,QAAAA;AAAUC,QAAAA;AAAK,KAAA,CAAA;IACnByB,eAAAA,CAAgB,IAAA;AACZ,QAAA,IAAIzB,IAAAA,EAAM;AACN,YAAA,MAAMQ,UAAUQ,QAAAA,CAASR,OAAO,KAAKhB,iBAAiBoB,IAAAA,IAAQ,CAACpB,KAAAA,CAAMqB,MAAM,CAACD,IAAAA,CAAKE,KAAK,IAAItB,KAAAA,CAAMuB,QAAQ,KAAK,EAAC,CAAA;AAC9GI,YAAAA,WAAAA,CAAY,CAACX,OAAAA,GAAUZ,QAAAA,GAAW,GAAGE,KAAAA,CAAM,YAAY,CAAC,GAAGoB,SAAAA,GACvD,CAACN,IAAAA,CAAKc,MAAM,CAAClB,OAAAA,CAAAA,GAAW,GAAGV,KAAAA,CAAM,qBAAqB,CAAC,GAAGoB,SAAAA,CAAAA;AAClE,QAAA;IACJ,CAAA,EAAG;AAAClB,QAAAA,IAAAA;AAAMJ,QAAAA,QAAAA;AAAUG,QAAAA,QAAAA;AAAUD,QAAAA,KAAAA;AAAOO,QAAAA;AAAoB,KAAA,CAAA;AACzD,IAAA,MAAMsB,OAAO3B,IAAAA,GAAOS,KAAAA,GAAQ,OAAOjB,KAAAA,KAAU,WAAWA,KAAAA,GAAQ,EAAA;AAChE,IAAA,qBAAOoC,IAAA,CAACC,KAAAA,EAAAA;;0BACJC,GAAA,CAAChC,OAAAA,EAAAA;gBAAMiC,OAAAA,EAAS9B,EAAAA;AAAKH,gBAAAA,QAAAA,EAAAA;;0BACrBgC,GAAA,CAACE,OAAAA,EAAAA;gBAAM/B,EAAAA,EAAIA,EAAAA;gBAAIgC,IAAAA,EAAMlC,QAAAA;gBAAUmC,IAAAA,EAAK,MAAA;gBAAOtC,QAAAA,EAAUA,QAAAA;gBAAUJ,KAAAA,EAAOmC,IAAAA;gBAClEQ,cAAAA,EAAcxC,OAAAA;AAASyC,gBAAAA,kBAAAA,EAAkBvC,OAAOwC,MAAM,GAAG,GAAGpC,EAAAA,CAAG,MAAM,CAAC,GAAGiB,SAAAA;gBACzExB,MAAAA,EAAQA,MAAAA;AAAQD,gBAAAA,QAAAA,EAAU6C,CAAAA,KAAAA,GAAAA;AACtB,oBAAA,MAAMC,IAAAA,GAAOD,KAAAA,CAAME,aAAa,CAAChD,KAAK;AACtC,oBAAA,IAAI,CAACQ,IAAAA,EAAM;wBAAEP,QAAAA,CAAS8C,IAAAA,CAAAA;AAAO,wBAAA;AAAQ,oBAAA;AACrCvB,oBAAAA,QAAAA,CAASR,OAAO,GAAG+B,IAAAA;oBACnB7B,QAAAA,CAAS6B,IAAAA,CAAAA;AACT,oBAAA,MAAMnB,QAAQ,CAACmB,IAAAA,GAAO3C,WAAW,CAAA,EAAGE,KAAAA,CAAM,YAAY,CAAC,GAAGoB,YAAY,CAACN,IAAAA,CAAKc,MAAM,CAACa,IAAAA,CAAAA,GAAQ,GAAGzC,KAAAA,CAAM,qBAAqB,CAAC,GAAGoB,SAAAA;;AAE7HzB,oBAAAA,QAAAA,CAAS2B,SAAS,CAACmB,IAAAA,GAAOrB,SAAAA,GAAYN,IAAAA,CAAK6B,KAAK,CAACF,IAAAA,CAAAA,CAAAA;oBACjDpB,WAAAA,CAAYC,KAAAA,CAAAA;AAChB,gBAAA;;YACHvB,MAAAA,CAAOwC,MAAM,GAAG,CAAA,kBAAKP,GAAA,CAACD,KAAAA,EAAAA;gBAAI5B,EAAAA,EAAI,CAAA,EAAGA,EAAAA,CAAG,MAAM,CAAC;gBAAEyC,IAAAA,EAAK,OAAA;AAAS7C,gBAAAA,QAAAA,EAAAA,MAAM,CAAC,CAAA;;;;AAE3E;AAEA,MAAM8C,eAAAA,GAAkBC,mBAA8BrD,WAAAA,EAAa;IAAEsD,YAAAA,EAAc;AAAG,CAAA,CAAA;AAEtF,4FACO,SAASC,oBAAAA,CAAqB,EAAEd,KAAK,EAA2B,EAAA;AACnE,IAAA,qBAAOF,GAAA,CAACa,eAAAA,EAAAA;AAAgBI,QAAAA,SAAAA,EAAWf,MAAMjC,QAAQ;AAAEP,QAAAA,KAAAA,EAAO,CAACwD,OAAAA,GAAqCA,OAAO,CAAChB,KAAAA,CAAMjC,QAAQ,CAAC;AACnHA,QAAAA,QAAAA,EAAUiC,MAAMjC,QAAQ;QAAEC,IAAAA,EAAMgC,KAAAA,CAAME,IAAI,KAAK,MAAA;AAAQpC,QAAAA,KAAAA,EAAOkC,MAAMlC,KAAK;AAAEmD,QAAAA,KAAAA,EAAOjB,MAAMlC;;AAChG;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SceneCommandForm.d.ts","sourceRoot":"","sources":["../../../forms/SceneCommandForm.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AA+B/D,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,+BASrE"}
1
+ {"version":3,"file":"SceneCommandForm.d.ts","sourceRoot":"","sources":["../../../forms/SceneCommandForm.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAyB/D,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,+BAkBrE"}
@@ -4,27 +4,25 @@ import { BindingKind } from '../bindings/BindingKind.js';
4
4
  import { resolveElementBinding } from '../bindings/resolveElementBinding.js';
5
5
  import { MissingBinding } from '../bindings/MissingBinding.js';
6
6
  import { ArcRuntimeBoundary } from '../bindings/ArcRuntimeBoundary.js';
7
- import { stringArrayProperty } from '../properties.js';
7
+ import { stringProperty, stringArrayProperty } from '../properties.js';
8
+ import { commandInputs } from './commandInputs.js';
8
9
 
10
+ const CommandFormRuntime = /*#__PURE__*/ lazy(()=>import('./CommandFormRuntime.js'));
11
+ // Arc's useCommand constructs the proxy only on mount. Key by the actual registered class,
12
+ // not its Scene name (which may be re-registered with a different route or roles).
13
+ const commandKeys = new WeakMap();
14
+ let nextCommandKey = 0;
15
+ function commandKey(command) {
16
+ let key = commandKeys.get(command);
17
+ if (key === undefined) {
18
+ key = ++nextCommandKey;
19
+ commandKeys.set(command, key);
20
+ }
21
+ return key;
22
+ }
9
23
  /**
10
- * `AutoCommandForm` types `exclude` as `(keyof TCommand)[]`, which collapses to `never[]` when the
11
- * command type is only known at runtime - as it always is here, since the class arrives from the binding
12
- * registry rather than from a type annotation. The conversion states the shape this adapter actually
13
- * passes; the underlying component reads `exclude` as property names either way.
14
- */ const AutoCommandForm = /*#__PURE__*/ lazy(async ()=>({
15
- default: (await import('@cratis/components/CommandForm')).AutoCommandForm
16
- }));
17
- /**
18
- * The `Cratis.Components:commandForm` component - `AutoCommandForm` from `@cratis/components/CommandForm`.
19
- *
20
- * `AutoCommandForm` rather than `CommandForm`, because a screen that had to list every field by hand
21
- * would go stale the moment a property is added to the command on the backend. `AutoCommandForm` reads
22
- * the command's own property descriptors and picks a field component per property type, so the form
23
- * follows the command - which is the same guarantee Arc's generated proxies give the rest of the stack.
24
- *
25
- * A screen that does want to place fields itself puts the field components from this package in the
26
- * `content` slot and names them individually; `exclude` keeps `AutoCommandForm` from generating a second
27
- * copy of anything placed that way.
24
+ * Auto mode follows supported native proxy descriptors; opt-in inputs bind exactly named fields
25
+ * inside a single native Arc form. Neither mode consumes the content slot.
28
26
  */ function SceneCommandForm({ element }) {
29
27
  const { name, target } = resolveElementBinding(element, BindingKind.Command);
30
28
  if (!target) return /*#__PURE__*/ jsx(MissingBinding, {
@@ -32,11 +30,18 @@ import { stringArrayProperty } from '../properties.js';
32
30
  kind: BindingKind.Command,
33
31
  name: name
34
32
  });
33
+ const inputs = Object.hasOwn(element.properties, 'inputs') ? commandInputs(element.properties) : undefined;
34
+ if (Object.hasOwn(element.properties, 'inputs') && !inputs) return /*#__PURE__*/ jsx("div", {
35
+ role: "alert",
36
+ children: "Invalid command form inputs declaration"
37
+ });
35
38
  return /*#__PURE__*/ jsx(ArcRuntimeBoundary, {
36
- children: /*#__PURE__*/ jsx(AutoCommandForm, {
39
+ children: /*#__PURE__*/ jsx(CommandFormRuntime, {
37
40
  command: target,
38
- exclude: stringArrayProperty(element.properties, 'exclude')
39
- })
41
+ inputs: inputs,
42
+ exclude: stringArrayProperty(element.properties, 'exclude'),
43
+ submitLabel: stringProperty(element.properties, 'submitLabel') ?? 'Submit'
44
+ }, commandKey(target))
40
45
  });
41
46
  }
42
47
 
@@ -1 +1 @@
1
- {"version":3,"file":"SceneCommandForm.js","sources":["../../../forms/SceneCommandForm.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ComponentType, lazy } from 'react';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { ArcRuntimeBoundary, BindingKind, BoundConstructor, MissingBinding, resolveElementBinding } from '../bindings';\nimport { stringArrayProperty } from '../properties';\n\ninterface AutoCommandFormElementProps {\n command: BoundConstructor;\n exclude?: string[];\n}\n\n/**\n * `AutoCommandForm` types `exclude` as `(keyof TCommand)[]`, which collapses to `never[]` when the\n * command type is only known at runtime - as it always is here, since the class arrives from the binding\n * registry rather than from a type annotation. The conversion states the shape this adapter actually\n * passes; the underlying component reads `exclude` as property names either way.\n */\nconst AutoCommandForm = lazy(async () => ({\n default: (await import('@cratis/components/CommandForm')).AutoCommandForm as unknown as ComponentType<AutoCommandFormElementProps>,\n}));\n\n/**\n * The `Cratis.Components:commandForm` component - `AutoCommandForm` from `@cratis/components/CommandForm`.\n *\n * `AutoCommandForm` rather than `CommandForm`, because a screen that had to list every field by hand\n * would go stale the moment a property is added to the command on the backend. `AutoCommandForm` reads\n * the command's own property descriptors and picks a field component per property type, so the form\n * follows the command - which is the same guarantee Arc's generated proxies give the rest of the stack.\n *\n * A screen that does want to place fields itself puts the field components from this package in the\n * `content` slot and names them individually; `exclude` keeps `AutoCommandForm` from generating a second\n * copy of anything placed that way.\n */\nexport function SceneCommandForm({ element }: RegisteredComponentProps) {\n const { name, target } = resolveElementBinding(element, BindingKind.Command);\n if (!target) return <MissingBinding element={element} kind={BindingKind.Command} name={name} />;\n\n return (\n <ArcRuntimeBoundary>\n <AutoCommandForm command={target} exclude={stringArrayProperty(element.properties, 'exclude')} />\n </ArcRuntimeBoundary>\n );\n}\n"],"names":["AutoCommandForm","lazy","default","SceneCommandForm","element","name","target","resolveElementBinding","BindingKind","Command","_jsx","MissingBinding","kind","ArcRuntimeBoundary","command","exclude","stringArrayProperty","properties"],"mappings":";;;;;;;;AAaA;;;;;AAKC,IACD,MAAMA,eAAAA,iBAAkBC,IAAAA,CAAK,WAAa;AACtCC,QAAAA,OAAAA,EAAS,CAAC,MAAM,OAAO,gCAAA,CAAgC,EAAGF;KAC9D,CAAA,CAAA;AAEA;;;;;;;;;;;AAWC,IACM,SAASG,gBAAAA,CAAiB,EAAEC,OAAO,EAA4B,EAAA;IAClE,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGC,qBAAAA,CAAsBH,OAAAA,EAASI,WAAAA,CAAYC,OAAO,CAAA;IAC3E,IAAI,CAACH,MAAAA,EAAQ,qBAAOI,GAAA,CAACC,cAAAA,EAAAA;QAAeP,OAAAA,EAASA,OAAAA;AAASQ,QAAAA,IAAAA,EAAMJ,YAAYC,OAAO;QAAEJ,IAAAA,EAAMA;;AAEvF,IAAA,qBACIK,GAAA,CAACG,kBAAAA,EAAAA;AACG,QAAA,QAAA,gBAAAH,GAAA,CAACV,eAAAA,EAAAA;YAAgBc,OAAAA,EAASR,MAAAA;YAAQS,OAAAA,EAASC,mBAAAA,CAAoBZ,OAAAA,CAAQa,UAAU,EAAE,SAAA;;;AAG/F;;"}
1
+ {"version":3,"file":"SceneCommandForm.js","sources":["../../../forms/SceneCommandForm.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { lazy } from 'react';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { ArcRuntimeBoundary, BindingKind, MissingBinding, resolveElementBinding } from '../bindings';\nimport type { BoundConstructor } from '../bindings';\nimport { stringArrayProperty, stringProperty } from '../properties';\nimport { commandInputs } from './commandInputs';\n\nconst CommandFormRuntime = lazy(() => import('./CommandFormRuntime'));\n\n// Arc's useCommand constructs the proxy only on mount. Key by the actual registered class,\n// not its Scene name (which may be re-registered with a different route or roles).\nconst commandKeys = new WeakMap<BoundConstructor, number>();\nlet nextCommandKey = 0;\nfunction commandKey(command: BoundConstructor): number {\n let key = commandKeys.get(command);\n if (key === undefined) {\n key = ++nextCommandKey;\n commandKeys.set(command, key);\n }\n return key;\n}\n\n/**\n * Auto mode follows supported native proxy descriptors; opt-in inputs bind exactly named fields\n * inside a single native Arc form. Neither mode consumes the content slot.\n */\nexport function SceneCommandForm({ element }: RegisteredComponentProps) {\n const { name, target } = resolveElementBinding(element, BindingKind.Command);\n if (!target) return <MissingBinding element={element} kind={BindingKind.Command} name={name} />;\n\n const inputs = Object.hasOwn(element.properties, 'inputs') ? commandInputs(element.properties) : undefined;\n if (Object.hasOwn(element.properties, 'inputs') && !inputs) return <div role='alert'>Invalid command form inputs declaration</div>;\n\n return (\n <ArcRuntimeBoundary>\n <CommandFormRuntime\n key={commandKey(target)}\n command={target}\n inputs={inputs}\n exclude={stringArrayProperty(element.properties, 'exclude')}\n submitLabel={stringProperty(element.properties, 'submitLabel') ?? 'Submit'}\n />\n </ArcRuntimeBoundary>\n );\n}\n"],"names":["CommandFormRuntime","lazy","commandKeys","WeakMap","nextCommandKey","commandKey","command","key","get","undefined","set","SceneCommandForm","element","name","target","resolveElementBinding","BindingKind","Command","_jsx","MissingBinding","kind","inputs","Object","hasOwn","properties","commandInputs","div","role","ArcRuntimeBoundary","exclude","stringArrayProperty","submitLabel","stringProperty"],"mappings":";;;;;;;;;AAUA,MAAMA,kBAAAA,iBAAqBC,IAAAA,CAAK,IAAM,OAAO,yBAAA,CAAA,CAAA;AAE7C;AACA;AACA,MAAMC,cAAc,IAAIC,OAAAA,EAAAA;AACxB,IAAIC,cAAAA,GAAiB,CAAA;AACrB,SAASC,WAAWC,OAAyB,EAAA;IACzC,IAAIC,GAAAA,GAAML,WAAAA,CAAYM,GAAG,CAACF,OAAAA,CAAAA;AAC1B,IAAA,IAAIC,QAAQE,SAAAA,EAAW;AACnBF,QAAAA,GAAAA,GAAM,EAAEH,cAAAA;QACRF,WAAAA,CAAYQ,GAAG,CAACJ,OAAAA,EAASC,GAAAA,CAAAA;AAC7B,IAAA;IACA,OAAOA,GAAAA;AACX;AAEA;;;AAGC,IACM,SAASI,gBAAAA,CAAiB,EAAEC,OAAO,EAA4B,EAAA;IAClE,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGC,qBAAAA,CAAsBH,OAAAA,EAASI,WAAAA,CAAYC,OAAO,CAAA;IAC3E,IAAI,CAACH,MAAAA,EAAQ,qBAAOI,GAAA,CAACC,cAAAA,EAAAA;QAAeP,OAAAA,EAASA,OAAAA;AAASQ,QAAAA,IAAAA,EAAMJ,YAAYC,OAAO;QAAEJ,IAAAA,EAAMA;;IAEvF,MAAMQ,MAAAA,GAASC,MAAAA,CAAOC,MAAM,CAACX,OAAAA,CAAQY,UAAU,EAAE,QAAA,CAAA,GAAYC,aAAAA,CAAcb,OAAAA,CAAQY,UAAU,CAAA,GAAIf,SAAAA;IACjG,IAAIa,MAAAA,CAAOC,MAAM,CAACX,OAAAA,CAAQY,UAAU,EAAE,QAAA,CAAA,IAAa,CAACH,MAAAA,EAAQ,qBAAOH,GAAA,CAACQ,KAAAA,EAAAA;QAAIC,IAAAA,EAAK,OAAA;AAAQ,QAAA,QAAA,EAAA;;AAErF,IAAA,qBACIT,GAAA,CAACU,kBAAAA,EAAAA;AACG,QAAA,QAAA,gBAAAV,GAAA,CAAClB,kBAAAA,EAAAA;YAEGM,OAAAA,EAASQ,MAAAA;YACTO,MAAAA,EAAQA,MAAAA;YACRQ,OAAAA,EAASC,mBAAAA,CAAoBlB,OAAAA,CAAQY,UAAU,EAAE,SAAA,CAAA;AACjDO,YAAAA,WAAAA,EAAaC,cAAAA,CAAepB,OAAAA,CAAQY,UAAU,EAAE,aAAA,CAAA,IAAkB;WAJ7DnB,UAAAA,CAAWS,MAAAA,CAAAA;;AAQhC;;"}
@@ -0,0 +1,7 @@
1
+ export interface CommandInput {
2
+ property: string;
3
+ type: 'string' | 'guid';
4
+ label: string;
5
+ }
6
+ export declare function commandInputs(properties: Record<string, unknown>): CommandInput[] | undefined;
7
+ //# sourceMappingURL=commandInputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandInputs.d.ts","sourceRoot":"","sources":["../../../forms/commandInputs.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,SAAS,CAe7F"}
@@ -0,0 +1,33 @@
1
+ import { arrayProperty, objectProperty, stringProperty } from '../properties.js';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /** An absent declaration selects legacy auto mode; a present but invalid declaration never does. */ function commandInputs(properties) {
6
+ const values = arrayProperty(properties, 'inputs');
7
+ if (!values?.length) return undefined;
8
+ const inputs = [];
9
+ const seen = new Set();
10
+ for (const value of values){
11
+ const input = objectProperty({
12
+ value
13
+ }, 'value');
14
+ if (!input || Object.keys(input).some((key)=>![
15
+ 'property',
16
+ 'type',
17
+ 'label'
18
+ ].includes(key))) return undefined;
19
+ const property = stringProperty(input, 'property');
20
+ const label = stringProperty(input, 'label');
21
+ if (!property?.trim() || !label?.trim() || input.type !== 'string' && input.type !== 'guid' || seen.has(property)) return undefined;
22
+ seen.add(property);
23
+ inputs.push({
24
+ property,
25
+ type: input.type,
26
+ label
27
+ });
28
+ }
29
+ return inputs;
30
+ }
31
+
32
+ export { commandInputs };
33
+ //# sourceMappingURL=commandInputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandInputs.js","sources":["../../../forms/commandInputs.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { arrayProperty, objectProperty, stringProperty } from '../properties';\n\n/** Exact, case-sensitive names from a generated command's propertyDescriptors. */\nexport interface CommandInput {\n property: string;\n type: 'string' | 'guid';\n label: string;\n}\n\n/** An absent declaration selects legacy auto mode; a present but invalid declaration never does. */\nexport function commandInputs(properties: Record<string, unknown>): CommandInput[] | undefined {\n const values = arrayProperty(properties, 'inputs');\n if (!values?.length) return undefined;\n const inputs: CommandInput[] = [];\n const seen = new Set<string>();\n for (const value of values) {\n const input = objectProperty({ value }, 'value');\n if (!input || Object.keys(input).some(key => !['property', 'type', 'label'].includes(key))) return undefined;\n const property = stringProperty(input, 'property');\n const label = stringProperty(input, 'label');\n if (!property?.trim() || !label?.trim() || (input.type !== 'string' && input.type !== 'guid') || seen.has(property)) return undefined;\n seen.add(property);\n inputs.push({ property, type: input.type, label });\n }\n return inputs;\n}\n"],"names":["commandInputs","properties","values","arrayProperty","length","undefined","inputs","seen","Set","value","input","objectProperty","Object","keys","some","key","includes","property","stringProperty","label","trim","type","has","add","push"],"mappings":";;AAAA;AACA;AAWA,qGACO,SAASA,aAAAA,CAAcC,UAAmC,EAAA;IAC7D,MAAMC,MAAAA,GAASC,cAAcF,UAAAA,EAAY,QAAA,CAAA;IACzC,IAAI,CAACC,MAAAA,EAAQE,MAAAA,EAAQ,OAAOC,SAAAA;AAC5B,IAAA,MAAMC,SAAyB,EAAE;AACjC,IAAA,MAAMC,OAAO,IAAIC,GAAAA,EAAAA;IACjB,KAAK,MAAMC,SAASP,MAAAA,CAAQ;AACxB,QAAA,MAAMQ,QAAQC,cAAAA,CAAe;AAAEF,YAAAA;SAAM,EAAG,OAAA,CAAA;QACxC,IAAI,CAACC,KAAAA,IAASE,MAAAA,CAAOC,IAAI,CAACH,OAAOI,IAAI,CAACC,CAAAA,GAAAA,GAAO,CAAC;AAAC,gBAAA,UAAA;AAAY,gBAAA,MAAA;AAAQ,gBAAA;aAAQ,CAACC,QAAQ,CAACD,GAAAA,CAAAA,CAAAA,EAAO,OAAOV,SAAAA;QACnG,MAAMY,QAAAA,GAAWC,eAAeR,KAAAA,EAAO,UAAA,CAAA;QACvC,MAAMS,KAAAA,GAAQD,eAAeR,KAAAA,EAAO,OAAA,CAAA;AACpC,QAAA,IAAI,CAACO,QAAAA,EAAUG,IAAAA,EAAAA,IAAU,CAACD,KAAAA,EAAOC,IAAAA,EAAAA,IAAWV,MAAMW,IAAI,KAAK,QAAA,IAAYX,KAAAA,CAAMW,IAAI,KAAK,MAAA,IAAWd,KAAKe,GAAG,CAACL,WAAW,OAAOZ,SAAAA;AAC5HE,QAAAA,IAAAA,CAAKgB,GAAG,CAACN,QAAAA,CAAAA;AACTX,QAAAA,MAAAA,CAAOkB,IAAI,CAAC;AAAEP,YAAAA,QAAAA;AAAUI,YAAAA,IAAAA,EAAMX,MAAMW,IAAI;AAAEF,YAAAA;AAAM,SAAA,CAAA;AACpD,IAAA;IACA,OAAOb,MAAAA;AACX;;"}
@@ -0,0 +1,22 @@
1
+ import { Command, CommandValidator } from '@cratis/arc/commands';
2
+ import { PropertyDescriptor } from '@cratis/arc/reflection';
3
+ declare class NoteValidator extends CommandValidator<{
4
+ subject: string;
5
+ }> {
6
+ constructor();
7
+ }
8
+ export declare class RecordNote extends Command {
9
+ readonly route: string;
10
+ readonly propertyDescriptors: PropertyDescriptor[];
11
+ readonly requestParameters: never[];
12
+ readonly validation: NoteValidator;
13
+ subject: string;
14
+ internalValue: string;
15
+ constructor();
16
+ }
17
+ export declare class RestrictedNote extends RecordNote {
18
+ readonly roles: string[];
19
+ }
20
+ export declare function successfulResponse(): Response;
21
+ export {};
22
+ //# sourceMappingURL=RecordNote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordNote.d.ts","sourceRoot":"","sources":["../../../../../forms/for_SceneCommandForm/given/RecordNote.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,cAAM,aAAc,SAAQ,gBAAgB,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;IAC7D,cAGC;CACJ;AAGD,qBAAa,UAAW,SAAQ,OAAO;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAsB;IAC5C,QAAQ,CAAC,mBAAmB,uBAG1B;IACF,QAAQ,CAAC,iBAAiB,UAAM;IAChC,QAAQ,CAAC,UAAU,gBAAuB;IAC1C,OAAO,SAAM;IACb,aAAa,SAAmB;IAChC,cAAuC;CAC1C;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC1C,QAAQ,CAAC,KAAK,WAAmB;CACpC;AAED,wBAAgB,kBAAkB,IAItB,QAAQ,CACnB"}
@@ -0,0 +1,30 @@
1
+ import { Command, CommandValidator } from '@cratis/arc/commands';
2
+ import { PropertyDescriptor } from '@cratis/arc/reflection';
3
+ class NoteValidator extends CommandValidator {
4
+ constructor() {
5
+ super();
6
+ this.ruleFor(command => command.subject).notEmpty().withMessage('Subject is required');
7
+ }
8
+ }
9
+ export class RecordNote extends Command {
10
+ route = '/synthetic/notes';
11
+ propertyDescriptors = [
12
+ new PropertyDescriptor('subject', String),
13
+ new PropertyDescriptor('internalValue', String, true),
14
+ ];
15
+ requestParameters = [];
16
+ validation = new NoteValidator();
17
+ subject = '';
18
+ internalValue = 'proxy default';
19
+ constructor() { super(Object, false); }
20
+ }
21
+ export class RestrictedNote extends RecordNote {
22
+ roles = ['note-writer'];
23
+ }
24
+ export function successfulResponse() {
25
+ return { status: 200, json: async () => ({
26
+ isSuccess: true, isAuthorized: true, isValid: true, hasExceptions: false,
27
+ validationResults: [], exceptionMessages: [], exceptionStackTrace: '', response: {},
28
+ }) };
29
+ }
30
+ //# sourceMappingURL=RecordNote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordNote.js","sourceRoot":"","sources":["../../../../../forms/for_SceneCommandForm/given/RecordNote.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,aAAc,SAAQ,gBAAqC;IAC7D;QACI,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAC3F,CAAC;CACJ;AAGD,MAAM,OAAO,UAAW,SAAQ,OAAO;IAC1B,KAAK,GAAW,kBAAkB,CAAC;IACnC,mBAAmB,GAAG;QAC3B,IAAI,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC;QACzC,IAAI,kBAAkB,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC;KACxD,CAAC;IACO,iBAAiB,GAAG,EAAE,CAAC;IACvB,UAAU,GAAG,IAAI,aAAa,EAAE,CAAC;IAC1C,OAAO,GAAG,EAAE,CAAC;IACb,aAAa,GAAG,eAAe,CAAC;IAChC,gBAAgB,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED,MAAM,OAAO,cAAe,SAAQ,UAAU;IACjC,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC;CACpC;AAED,MAAM,UAAU,kBAAkB;IAC9B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YACrC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK;YACxE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;SACtF,CAAC,EAAc,CAAC;AACrB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { Command, CommandValidator } from '@cratis/arc/commands';
2
+ import { PropertyDescriptor } from '@cratis/arc/reflection';
3
+ import { Guid } from '@cratis/fundamentals';
4
+ declare class ProjectValidator extends CommandValidator<{
5
+ name: string;
6
+ }> {
7
+ constructor();
8
+ }
9
+ export declare class StartProject extends Command {
10
+ readonly route: string;
11
+ readonly propertyDescriptors: PropertyDescriptor[];
12
+ readonly requestParameters: never[];
13
+ readonly validation: ProjectValidator;
14
+ projectId: Guid;
15
+ name: string;
16
+ constructor();
17
+ }
18
+ export declare class RestrictedProject extends StartProject {
19
+ readonly roles: string[];
20
+ }
21
+ export declare class OptionalUnsupported extends StartProject {
22
+ readonly propertyDescriptors: PropertyDescriptor[];
23
+ details?: object;
24
+ }
25
+ export declare class RequiredUnsupported extends OptionalUnsupported {
26
+ readonly propertyDescriptors: PropertyDescriptor[];
27
+ }
28
+ export declare class AmbiguousProject extends StartProject {
29
+ readonly propertyDescriptors: PropertyDescriptor[];
30
+ }
31
+ export {};
32
+ //# sourceMappingURL=StartProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StartProject.d.ts","sourceRoot":"","sources":["../../../../../forms/for_SceneCommandForm/given/StartProject.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,cAAM,gBAAiB,SAAQ,gBAAgB,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;IAC7D,cAGC;CACJ;AAGD,qBAAa,YAAa,SAAQ,OAAO;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAyB;IAC/C,QAAQ,CAAC,mBAAmB,uBAAuF;IACnH,QAAQ,CAAC,iBAAiB,UAAM;IAChC,QAAQ,CAAC,UAAU,mBAA0B;IAC7C,SAAS,EAAE,IAAI,CAAc;IAC7B,IAAI,SAAM;IACV,cAAuC;CAC1C;AAED,qBAAa,iBAAkB,SAAQ,YAAY;IAC/C,QAAQ,CAAC,KAAK,WAAsB;CACvC;AAED,qBAAa,mBAAoB,SAAQ,YAAY;IACjD,QAAQ,CAAC,mBAAmB,uBAAwI;IACpK,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,mBAAoB,SAAQ,mBAAmB;IACxD,QAAQ,CAAC,mBAAmB,uBAAkI;CACjK;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAC9C,QAAQ,CAAC,mBAAmB,uBAAkI;CACjK"}
@@ -0,0 +1,32 @@
1
+ import { Command, CommandValidator } from '@cratis/arc/commands';
2
+ import { PropertyDescriptor } from '@cratis/arc/reflection';
3
+ import { Guid } from '@cratis/fundamentals';
4
+ class ProjectValidator extends CommandValidator {
5
+ constructor() {
6
+ super();
7
+ this.ruleFor(command => command.name).notEmpty().withMessage('Name is required');
8
+ }
9
+ }
10
+ export class StartProject extends Command {
11
+ route = '/synthetic/projects';
12
+ propertyDescriptors = [new PropertyDescriptor('projectId', Guid), new PropertyDescriptor('name', String)];
13
+ requestParameters = [];
14
+ validation = new ProjectValidator();
15
+ projectId = Guid.empty;
16
+ name = '';
17
+ constructor() { super(Object, false); }
18
+ }
19
+ export class RestrictedProject extends StartProject {
20
+ roles = ['project-writer'];
21
+ }
22
+ export class OptionalUnsupported extends StartProject {
23
+ propertyDescriptors = [new PropertyDescriptor('projectId', Guid), new PropertyDescriptor('name', String), new PropertyDescriptor('details', Object, true)];
24
+ details;
25
+ }
26
+ export class RequiredUnsupported extends OptionalUnsupported {
27
+ propertyDescriptors = [new PropertyDescriptor('projectId', Guid), new PropertyDescriptor('name', String), new PropertyDescriptor('details', Object)];
28
+ }
29
+ export class AmbiguousProject extends StartProject {
30
+ propertyDescriptors = [new PropertyDescriptor('projectId', Guid), new PropertyDescriptor('name', String), new PropertyDescriptor('projectId', Guid)];
31
+ }
32
+ //# sourceMappingURL=StartProject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StartProject.js","sourceRoot":"","sources":["../../../../../forms/for_SceneCommandForm/given/StartProject.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,MAAM,gBAAiB,SAAQ,gBAAkC;IAC7D;QACI,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACrF,CAAC;CACJ;AAGD,MAAM,OAAO,YAAa,SAAQ,OAAO;IAC5B,KAAK,GAAW,qBAAqB,CAAC;IACtC,mBAAmB,GAAG,CAAC,IAAI,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1G,iBAAiB,GAAG,EAAE,CAAC;IACvB,UAAU,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAC7C,SAAS,GAAS,IAAI,CAAC,KAAK,CAAC;IAC7B,IAAI,GAAG,EAAE,CAAC;IACV,gBAAgB,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACtC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC;CACvC;AAED,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACxC,mBAAmB,GAAG,CAAC,IAAI,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACpK,OAAO,CAAU;CACpB;AAED,MAAM,OAAO,mBAAoB,SAAQ,mBAAmB;IAC/C,mBAAmB,GAAG,CAAC,IAAI,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;CACjK;AAED,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IACrC,mBAAmB,GAAG,CAAC,IAAI,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;CACjK"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=when_forwarding_to_the_lazy_runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_forwarding_to_the_lazy_runtime.d.ts","sourceRoot":"","sources":["../../../../forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { act, cleanup, render, screen } from '@testing-library/react';
3
+ import { vi } from 'vitest';
4
+ import { externalComponent } from '../../given';
5
+ describe('when forwarding command forms to the lazy runtime', () => {
6
+ const received = vi.fn();
7
+ const loaded = vi.fn();
8
+ let bindings;
9
+ let Form;
10
+ class Original {
11
+ }
12
+ class Replacement {
13
+ }
14
+ beforeEach(async () => {
15
+ vi.resetModules();
16
+ received.mockClear();
17
+ loaded.mockClear();
18
+ vi.doMock('../CommandFormRuntime', () => {
19
+ loaded();
20
+ return { default: (props) => { received(props); return _jsx("span", { children: "Runtime boundary" }); } };
21
+ });
22
+ bindings = await import('../../bindings/bindingRegistry');
23
+ bindings.clearBindings();
24
+ ({ SceneCommandForm: Form } = await import('../SceneCommandForm'));
25
+ });
26
+ afterEach(() => {
27
+ cleanup();
28
+ bindings.clearBindings();
29
+ vi.doUnmock('../CommandFormRuntime');
30
+ vi.resetModules();
31
+ });
32
+ it('should preserve the exact registered constructor, exclusions and explicit label', async () => {
33
+ bindings.registerCommand('RecordNote', Original);
34
+ const exclude = ['internalValue'];
35
+ await act(async () => {
36
+ render(_jsx(Form, { element: externalComponent('Cratis.Components:commandForm', {
37
+ command: 'RecordNote', exclude, submitLabel: 'Record note',
38
+ }), slots: {} }));
39
+ });
40
+ received.mock.calls.at(-1)[0].should.deep.equal({ command: Original, exclude, inputs: undefined, submitLabel: 'Record note' });
41
+ });
42
+ for (const submitLabel of [undefined, 42, false]) {
43
+ it(`should default a missing or non-string label (${String(submitLabel)}) to Submit`, async () => {
44
+ bindings.registerCommand('RecordNote', Original);
45
+ await act(async () => {
46
+ render(_jsx(Form, { element: externalComponent('Cratis.Components:commandForm', {
47
+ command: 'RecordNote', exclude: 'not-an-array', submitLabel,
48
+ }), slots: {} }));
49
+ });
50
+ received.mock.calls.at(-1)[0].should.deep.equal({ command: Original, exclude: undefined, inputs: undefined, submitLabel: 'Submit' });
51
+ });
52
+ }
53
+ it('should preserve legacy last-registration-wins command binding', async () => {
54
+ bindings.registerCommand('RecordNote', Original);
55
+ bindings.registerCommand('RecordNote', Replacement);
56
+ await act(async () => { render(_jsx(Form, { element: externalComponent('Cratis.Components:commandForm', { command: 'RecordNote' }), slots: {} })); });
57
+ (received.mock.calls.at(-1)[0].command === Replacement).should.equal(true);
58
+ });
59
+ it('should keep an unbound preview Arc-free even when a query has that name', async () => {
60
+ bindings.registerQuery('RecordNote', Original);
61
+ await act(async () => { render(_jsx(Form, { element: externalComponent('Cratis.Components:commandForm', { command: 'RecordNote' }), slots: {} })); });
62
+ Boolean(screen.getByText("Unresolved command binding 'RecordNote' on Cratis.Components:commandForm")).should.equal(true);
63
+ loaded.mock.calls.should.have.lengthOf(0);
64
+ });
65
+ });
66
+ //# sourceMappingURL=when_forwarding_to_the_lazy_runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_forwarding_to_the_lazy_runtime.js","sourceRoot":"","sources":["../../../../forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=when_native_custom_field_errors_block_submission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_native_custom_field_errors_block_submission.d.ts","sourceRoot":"","sources":["../../../../forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { act, cleanup, fireEvent, render, screen } from '@testing-library/react';
3
+ import { vi } from 'vitest';
4
+ import { CommandForm } from '@cratis/arc.react/commands';
5
+ import { InputTextField } from '@cratis/components/CommandForm';
6
+ import { CommandFormSubmit } from '../CommandFormSubmit';
7
+ import { RecordNote, successfulResponse } from './given/RecordNote';
8
+ describe('when native custom field errors block submission', () => {
9
+ const fetch = vi.fn();
10
+ beforeEach(() => { fetch.mockReset(); fetch.mockResolvedValue(successfulResponse()); vi.stubGlobal('fetch', fetch); });
11
+ afterEach(() => { cleanup(); vi.unstubAllGlobals(); });
12
+ it('should leave submit enabled for feedback but let the native form reject a custom field error', async () => {
13
+ await act(async () => {
14
+ render(_jsxs(CommandForm, { command: RecordNote, onFieldValidate: () => 'Subject is rejected by the field', children: [_jsx(InputTextField, { value: (command) => command.subject, title: 'Subject' }), _jsx(CommandFormSubmit, { label: 'Record note' })] }));
15
+ });
16
+ const input = screen.getByRole('textbox', { name: 'Subject' });
17
+ fireEvent.change(input, { target: { value: 'Passes the command validator' } });
18
+ await act(async () => { fireEvent.blur(input); });
19
+ (await screen.findAllByText('Subject is rejected by the field')).length.should.be.greaterThan(0);
20
+ const button = screen.getByRole('button', { name: 'Record note' });
21
+ button.disabled.should.equal(false);
22
+ await act(async () => { fireEvent.click(button); });
23
+ fetch.mock.calls.should.have.lengthOf(0);
24
+ });
25
+ });
26
+ //# sourceMappingURL=when_native_custom_field_errors_block_submission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_native_custom_field_errors_block_submission.js","sourceRoot":"","sources":["../../../../forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIpE,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC9D,MAAM,KAAK,GAAG,EAAE,CAAC,EAAE,EAA2B,CAAC;IAC/C,UAAU,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvH,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvD,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC1G,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;YAAG,MAAM,CAAC,MAAC,WAAW,IAAC,OAAO,EAAE,UAAU,EAC3D,eAAe,EAAE,GAAG,EAAE,CAAC,kCAAkC,aACzD,KAAC,cAAc,IAAC,KAAK,EAAE,CAAC,OAAmB,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAC,SAAS,GAAG,EACnF,KAAC,iBAAiB,IAAC,KAAK,EAAC,aAAa,GAAG,IAC/B,CAAC,CAAC;QAAC,CAAC,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/D,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,CAAC,CAAC;QAC/E,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,kCAAkC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACjG,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAoB,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=when_preserving_guid_error_ownership.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_preserving_guid_error_ownership.d.ts","sourceRoot":"","sources":["../../../../forms/for_SceneCommandForm/when_preserving_guid_error_ownership.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { act, cleanup, fireEvent, render, screen } from '@testing-library/react';
3
+ import { CommandForm, useCommandFormContext } from '@cratis/arc.react/commands';
4
+ import { Guid } from '@cratis/fundamentals';
5
+ import { PropertyDescriptor } from '@cratis/arc/reflection';
6
+ import { ExplicitCommandField } from '../ExplicitCommandField';
7
+ import { StartProject } from './given/StartProject';
8
+ class OptionalProject extends StartProject {
9
+ propertyDescriptors = [new PropertyDescriptor('projectId', Guid, true), new PropertyDescriptor('name', String)];
10
+ }
11
+ const input = { property: 'projectId', type: 'guid', label: 'Project ID' };
12
+ describe('native explicit Guid field error ownership', () => {
13
+ afterEach(cleanup);
14
+ it('leaves a caller-owned error intact when the invalid field unmounts in the same event', async () => {
15
+ let context;
16
+ function Capture() { context = useCommandFormContext(); return null; }
17
+ function form(show) {
18
+ return _jsxs(CommandForm, { command: StartProject, children: [_jsx(Capture, {}), show && _jsx(ExplicitCommandField, { input: input })] });
19
+ }
20
+ const result = render(form(true));
21
+ fireEvent.change(screen.getByRole('textbox', { name: 'Project ID' }), { target: { value: 'bad' } });
22
+ context.getFieldError('projectId').should.equal('Project ID must be a valid GUID');
23
+ await act(async () => {
24
+ context.setCustomFieldError('projectId', 'Caller-owned error');
25
+ result.rerender(form(false));
26
+ });
27
+ context.getFieldError('projectId').should.equal('Caller-owned error');
28
+ });
29
+ it('clears its own malformed optional Guid error on unmount', async () => {
30
+ let context;
31
+ function Capture() { context = useCommandFormContext(); return null; }
32
+ function form(show) {
33
+ return _jsxs(CommandForm, { command: OptionalProject, children: [_jsx(Capture, {}), show && _jsx(ExplicitCommandField, { input: input })] });
34
+ }
35
+ const result = render(form(true));
36
+ await act(async () => {
37
+ fireEvent.change(screen.getByRole('textbox', { name: 'Project ID' }), { target: { value: 'bad' } });
38
+ context.getFieldError('projectId').should.equal('Project ID must be a valid GUID');
39
+ result.rerender(form(false));
40
+ });
41
+ (Object.hasOwn(context.customFieldErrors, 'projectId')).should.equal(false);
42
+ });
43
+ });
44
+ //# sourceMappingURL=when_preserving_guid_error_ownership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"when_preserving_guid_error_ownership.js","sourceRoot":"","sources":["../../../../forms/for_SceneCommandForm/when_preserving_guid_error_ownership.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=when_rendering_submit_in_native_context.d.ts.map