@fougere/nuxt 0.16.3-alpha.0 → 0.16.5-alpha.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.
@@ -1,4 +1,4 @@
1
- import { type FormEntity, type FormField, type FormErrors, type FormFieldName, type FormRow, type FormValues } from '@fougere/app/client';
1
+ import { type Choice, type FormEntity, type FormField, type FormErrors, type FormFieldName, type FormRow, type FormValues } from '@fougere/app/client';
2
2
  export interface FormOptions {
3
3
  /** Command the submit rides. Default: 'create'. */
4
4
  op?: string;
@@ -16,6 +16,10 @@ export declare function useFormFor<E extends FormEntity>(entity: E, options?: Fo
16
16
  fieldsByName: Partial<Record<FormFieldName<E>, FormField<FormFieldName<E>>>>;
17
17
  values: FormValues<E>;
18
18
  errors: FormErrors<E>;
19
+ choices: Partial<Record<FormFieldName<E>, Choice[]>>;
20
+ /** Per reference field: its target holds more rows than one load offers, so a search is worth showing. */
21
+ searchable: Partial<Record<FormFieldName<E>, boolean>>;
22
+ search: (name: FormFieldName<E>, text?: string) => Promise<void>;
19
23
  submit: () => Promise<FormRow<E> | null>;
20
24
  loading: import("vue").Ref<boolean, boolean>;
21
25
  /** Non-validation failure of the last submit (unreachable host, conflict…). */
@@ -1 +1 @@
1
- {"version":3,"file":"useFormFor.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/useFormFor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoD,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE5L,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAE,WAAgB;;IA0CjF;;;OAGG;kBACiE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChH,UAAU,CAAC,CAAC,CAAC;YACb,UAAU,CAAC,CAAC,CAAC;kBAjBR,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;;IAoBjD,+EAA+E;;;EAIlF"}
1
+ {"version":3,"file":"useFormFor.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/useFormFor.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6D,KAAK,MAAM,EAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEhO,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAE,WAAgB;;IA0DjF;;;OAGG;kBACiE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChH,UAAU,CAAC,CAAC,CAAC;YACb,UAAU,CAAC,CAAC,CAAC;aACX,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,0GAA0G;gBAChF,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;mBA/C1C,aAAa,CAAC,CAAC,CAAC,oBAAc,OAAO,CAAC,IAAI,CAAC;kBA2B9C,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;;IAwBjD,+EAA+E;;;EAIlF"}
@@ -1,8 +1,9 @@
1
1
  /** The form contract — state, validation, submission, error mapping. */
2
- import { reactive, computed } from 'vue';
2
+ import { reactive, computed, onMounted } from 'vue';
3
+ import { useRequestFetch } from '#imports';
3
4
  import { lowerFirst, validationErrorsOf } from '@fougere/core/contract';
4
5
  import { useCommand } from './useFougereData.js';
5
- import { facadeOf, formFieldsOf, payloadOf, errorsByField } from '@fougere/app/client';
6
+ import { Choices, facadeOf, formFieldsOf, payloadOf, errorsByField } from '@fougere/app/client';
6
7
  export function useFormFor(entity, options = {}) {
7
8
  const entityKey = lowerFirst(entity.name);
8
9
  const fields = formFieldsOf(entity, entityKey);
@@ -15,6 +16,24 @@ export function useFormFor(entity, options = {}) {
15
16
  // A form is designated by its ENTITY — it is a set of fields — so the facade it submits to is
16
17
  // an address with no handler type behind it, and what it answers is the entity's row.
17
18
  const command = useCommand(facadeOf(entity), options.op ?? 'create');
19
+ const fetcher = useRequestFetch();
20
+ const choices = reactive({});
21
+ const searchable = reactive({});
22
+ /** What a reference field offers: its first rows, or those whose label contains `text`. */
23
+ async function search(name, text = '') {
24
+ const reference = fields.find((field) => field.name === name)?.reference;
25
+ if (!reference)
26
+ return;
27
+ const offer = await Choices.of(fetcher, reference, text);
28
+ choices[name] = offer.choices;
29
+ if (!text)
30
+ searchable[name] = offer.more;
31
+ }
32
+ onMounted(() => {
33
+ for (const field of fields)
34
+ if (field.reference)
35
+ void search(field.name);
36
+ });
18
37
  function clearErrors() {
19
38
  for (const key of Object.keys(errors))
20
39
  delete errors[key];
@@ -47,6 +66,10 @@ export function useFormFor(entity, options = {}) {
47
66
  fieldsByName: Object.fromEntries(fields.map((f) => [f.name, f])),
48
67
  values: values,
49
68
  errors: errors,
69
+ choices: choices,
70
+ /** Per reference field: its target holds more rows than one load offers, so a search is worth showing. */
71
+ searchable: searchable,
72
+ search,
50
73
  submit,
51
74
  loading: command.loading,
52
75
  /** Non-validation failure of the last submit (unreachable host, conflict…). */
@@ -1 +1 @@
1
- {"version":3,"file":"useFormFor.js","sourceRoot":"","sources":["../../../src/runtime/composables/useFormFor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFormFor.js","sourceRoot":"","sources":["../../../src/runtime/composables/useFormFor.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fougere/nuxt",
3
- "version": "0.16.3-alpha.0",
3
+ "version": "0.16.5-alpha.0",
4
4
  "description": "The Nuxt module: Fougere's client primitives and server surface.",
5
5
  "keywords": [
6
6
  "fougere",
@@ -32,12 +32,12 @@
32
32
  "template"
33
33
  ],
34
34
  "dependencies": {
35
- "@fougere/app": "0.16.3-alpha.0",
36
- "@fougere/core": "0.16.3-alpha.0",
37
- "@fougere/defaults": "0.16.3-alpha.0",
35
+ "@fougere/app": "0.16.5-alpha.0",
36
+ "@fougere/core": "0.16.5-alpha.0",
37
+ "@fougere/defaults": "0.16.5-alpha.0",
38
38
  "@nuxt/kit": "^4.5.1",
39
39
  "jiti": "^2.6.1",
40
- "@fougere/compiler": "0.16.3-alpha.0"
40
+ "@fougere/compiler": "0.16.5-alpha.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@nuxt/schema": "^4.5.1",
@@ -1,8 +1,9 @@
1
1
  /** The form contract — state, validation, submission, error mapping. */
2
- import { reactive, computed } from 'vue';
2
+ import { reactive, computed, onMounted } from 'vue';
3
+ import { useRequestFetch } from '#imports';
3
4
  import { lowerFirst, validationErrorsOf } from '@fougere/core/contract';
4
5
  import { useCommand } from './useFougereData.js';
5
- import { facadeOf, formFieldsOf, payloadOf, errorsByField, type FormEntity, type FormField, type FormErrors, type FormFieldName, type FormRow, type FormValues } from '@fougere/app/client';
6
+ import { Choices, facadeOf, formFieldsOf, payloadOf, errorsByField, type Choice, type Fetcher, type FormEntity, type FormField, type FormErrors, type FormFieldName, type FormRow, type FormValues } from '@fougere/app/client';
6
7
 
7
8
  export interface FormOptions {
8
9
  /** Command the submit rides. Default: 'create'. */
@@ -28,6 +29,22 @@ export function useFormFor<E extends FormEntity>(entity: E, options: FormOptions
28
29
  // A form is designated by its ENTITY — it is a set of fields — so the facade it submits to is
29
30
  // an address with no handler type behind it, and what it answers is the entity's row.
30
31
  const command = useCommand(facadeOf(entity), options.op ?? 'create');
32
+ const fetcher = useRequestFetch() as Fetcher;
33
+ const choices = reactive<Record<string, Choice[]>>({});
34
+ const searchable = reactive<Record<string, boolean>>({});
35
+
36
+ /** What a reference field offers: its first rows, or those whose label contains `text`. */
37
+ async function search(name: FormFieldName<E>, text = ''): Promise<void> {
38
+ const reference = fields.find((field) => field.name === name)?.reference;
39
+ if (!reference) return;
40
+ const offer = await Choices.of(fetcher, reference, text);
41
+ choices[name] = offer.choices;
42
+ if (!text) searchable[name] = offer.more;
43
+ }
44
+
45
+ onMounted(() => {
46
+ for (const field of fields) if (field.reference) void search(field.name);
47
+ });
31
48
 
32
49
  function clearErrors() {
33
50
  for (const key of Object.keys(errors)) delete errors[key];
@@ -62,6 +79,10 @@ export function useFormFor<E extends FormEntity>(entity: E, options: FormOptions
62
79
  fieldsByName: Object.fromEntries(fields.map((f) => [f.name, f])) as Partial<Record<FormFieldName<E>, FormField<FormFieldName<E>>>>,
63
80
  values: values as FormValues<E>,
64
81
  errors: errors as FormErrors<E>,
82
+ choices: choices as Partial<Record<FormFieldName<E>, Choice[]>>,
83
+ /** Per reference field: its target holds more rows than one load offers, so a search is worth showing. */
84
+ searchable: searchable as Partial<Record<FormFieldName<E>, boolean>>,
85
+ search,
65
86
  submit,
66
87
  loading: command.loading,
67
88
  /** Non-validation failure of the last submit (unreachable host, conflict…). */
@@ -16,6 +16,7 @@
16
16
  "@fougere/schema": "latest",
17
17
  "@fougere/defaults": "latest",
18
18
  "@fougere/container": "latest",
19
+ "@fougere/log": "latest",
19
20
  "better-sqlite3": "^13.0.3",
20
21
  "kysely": "^0.28.17",
21
22
  "@fougere/nuxt": "latest"