@chelone/vue 0.9.0 → 0.11.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 (118) hide show
  1. package/dist/admin/admin-shell.vue_vue_type_script_setup_true_lang.js +15 -2
  2. package/dist/admin/resource-registry.d.ts +6 -2
  3. package/dist/admin/resource-registry.js +0 -18
  4. package/dist/admin/resource.vue.d.ts +6 -2
  5. package/dist/choices/choices-context.d.ts +9 -9
  6. package/dist/choices/use-reference-input.js +2 -2
  7. package/dist/components/admin/auth/access-denied.vue.d.ts +2 -2
  8. package/dist/components/admin/auth/access-denied.vue_vue_type_script_setup_true_lang.js +2 -2
  9. package/dist/components/admin/auth/auth-error.vue.d.ts +2 -2
  10. package/dist/components/admin/auth/auth-error.vue_vue_type_script_setup_true_lang.js +3 -3
  11. package/dist/components/admin/auth/authentication-error.vue.d.ts +2 -2
  12. package/dist/components/admin/auth/authentication-error.vue_vue_type_script_setup_true_lang.js +2 -2
  13. package/dist/components/admin/auth/login-form.vue_vue_type_script_setup_true_lang.js +2 -2
  14. package/dist/components/admin/auth/login-with-email.vue.d.ts +1 -1
  15. package/dist/components/admin/auth/login-with-email.vue_vue_type_script_setup_true_lang.js +2 -2
  16. package/dist/components/admin/auth/logout.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/components/admin/auth/permission-matrix.vue_vue_type_script_setup_true_lang.js +1 -1
  18. package/dist/components/admin/buttons/bulk-delete-button.vue.d.ts +2 -2
  19. package/dist/components/admin/buttons/bulk-delete-button.vue_vue_type_script_setup_true_lang.js +3 -3
  20. package/dist/components/admin/buttons/bulk-export-button.vue_vue_type_script_setup_true_lang.js +1 -1
  21. package/dist/components/admin/buttons/bulk-update-button.vue_vue_type_script_setup_true_lang.js +2 -2
  22. package/dist/components/admin/buttons/cancel-button.vue_vue_type_script_setup_true_lang.js +1 -1
  23. package/dist/components/admin/buttons/clone-button.vue_vue_type_script_setup_true_lang.js +1 -1
  24. package/dist/components/admin/buttons/columns-button.vue_vue_type_script_setup_true_lang.js +1 -1
  25. package/dist/components/admin/buttons/create-button.vue_vue_type_script_setup_true_lang.js +1 -1
  26. package/dist/components/admin/buttons/delete-button.vue.d.ts +2 -2
  27. package/dist/components/admin/buttons/delete-button.vue_vue_type_script_setup_true_lang.js +3 -3
  28. package/dist/components/admin/buttons/edit-button.vue_vue_type_script_setup_true_lang.js +1 -1
  29. package/dist/components/admin/buttons/export-button.vue_vue_type_script_setup_true_lang.js +1 -1
  30. package/dist/components/admin/buttons/fields-selector.vue_vue_type_script_setup_true_lang.js +5 -5
  31. package/dist/components/admin/buttons/filter-button.vue_vue_type_script_setup_true_lang.js +2 -2
  32. package/dist/components/admin/buttons/list-button.vue_vue_type_script_setup_true_lang.js +1 -1
  33. package/dist/components/admin/buttons/locales-menu.vue_vue_type_script_setup_true_lang.js +1 -1
  34. package/dist/components/admin/buttons/refresh-button.vue_vue_type_script_setup_true_lang.js +1 -1
  35. package/dist/components/admin/buttons/refresh-icon-button.vue_vue_type_script_setup_true_lang.js +1 -1
  36. package/dist/components/admin/buttons/save-button.vue_vue_type_script_setup_true_lang.js +2 -2
  37. package/dist/components/admin/buttons/select-all-button.vue_vue_type_script_setup_true_lang.js +1 -1
  38. package/dist/components/admin/buttons/show-button.vue_vue_type_script_setup_true_lang.js +1 -1
  39. package/dist/components/admin/buttons/sidebar-toggle-button.vue_vue_type_script_setup_true_lang.js +1 -1
  40. package/dist/components/admin/buttons/skip-navigation-button.vue.d.ts +1 -1
  41. package/dist/components/admin/buttons/skip-navigation-button.vue_vue_type_script_setup_true_lang.js +1 -1
  42. package/dist/components/admin/buttons/sort-button.vue_vue_type_script_setup_true_lang.js +2 -2
  43. package/dist/components/admin/buttons/update-button.vue.d.ts +2 -2
  44. package/dist/components/admin/buttons/update-button.vue_vue_type_script_setup_true_lang.js +3 -3
  45. package/dist/components/admin/common/application-updated-notification.vue_vue_type_script_setup_true_lang.js +2 -2
  46. package/dist/components/admin/csv-import/csv-import.vue.d.ts +24 -14
  47. package/dist/components/admin/csv-import/csv-import.vue_vue_type_script_setup_true_lang.js +18 -18
  48. package/dist/components/admin/feedback/confirm.vue.d.ts +2 -2
  49. package/dist/components/admin/feedback/confirm.vue_vue_type_script_setup_true_lang.js +2 -2
  50. package/dist/components/admin/feedback/error.vue_vue_type_script_setup_true_lang.js +3 -3
  51. package/dist/components/admin/feedback/loading-indicator.vue_vue_type_script_setup_true_lang.js +2 -2
  52. package/dist/components/admin/feedback/loading.vue.d.ts +2 -2
  53. package/dist/components/admin/feedback/loading.vue_vue_type_script_setup_true_lang.js +2 -2
  54. package/dist/components/admin/feedback/not-found.vue_vue_type_script_setup_true_lang.js +3 -3
  55. package/dist/components/admin/feedback/notification.vue_vue_type_script_setup_true_lang.js +1 -1
  56. package/dist/components/admin/feedback/offline.vue_vue_type_script_setup_true_lang.js +1 -1
  57. package/dist/components/admin/fields/boolean-field.vue_vue_type_script_setup_true_lang.js +1 -1
  58. package/dist/components/admin/form/translatable-inputs-tab.vue_vue_type_script_setup_true_lang.js +1 -1
  59. package/dist/components/admin/inputs/array-input-row.vue_vue_type_script_setup_true_lang.js +3 -3
  60. package/dist/components/admin/inputs/array-input.vue_vue_type_script_setup_true_lang.js +3 -3
  61. package/dist/components/admin/inputs/autocomplete-array-input.vue_vue_type_script_setup_true_lang.js +3 -3
  62. package/dist/components/admin/inputs/autocomplete-input.vue_vue_type_script_setup_true_lang.js +2 -2
  63. package/dist/components/admin/inputs/datagrid-input.vue_vue_type_script_setup_true_lang.js +2 -2
  64. package/dist/components/admin/inputs/file-input-preview.vue_vue_type_script_setup_true_lang.js +2 -2
  65. package/dist/components/admin/inputs/file-input.vue_vue_type_script_setup_true_lang.js +2 -2
  66. package/dist/components/admin/inputs/image-input.vue_vue_type_script_setup_true_lang.js +2 -2
  67. package/dist/components/admin/inputs/in-place-editor-form.vue_vue_type_script_setup_true_lang.js +4 -4
  68. package/dist/components/admin/inputs/in-place-editor.vue_vue_type_script_setup_true_lang.js +1 -1
  69. package/dist/components/admin/inputs/nullable-boolean-input.vue_vue_type_script_setup_true_lang.js +3 -3
  70. package/dist/components/admin/inputs/password-input.vue_vue_type_script_setup_true_lang.js +1 -1
  71. package/dist/components/admin/inputs/resettable-text-input.vue_vue_type_script_setup_true_lang.js +1 -1
  72. package/dist/components/admin/inputs/search-input.vue_vue_type_script_setup_true_lang.js +2 -2
  73. package/dist/components/admin/inputs/select-array-input.vue_vue_type_script_setup_true_lang.js +2 -2
  74. package/dist/components/admin/inputs/text-array-input.vue_vue_type_script_setup_true_lang.js +1 -1
  75. package/dist/components/admin/layout/command-menu-logout.vue_vue_type_script_setup_true_lang.js +2 -2
  76. package/dist/components/admin/layout/dashboard-menu-item.vue.d.ts +1 -1
  77. package/dist/components/admin/layout/dashboard-menu-item.vue_vue_type_script_setup_true_lang.js +1 -1
  78. package/dist/components/admin/layout/data-provider-devtools.vue_vue_type_script_setup_true_lang.js +61 -27
  79. package/dist/components/admin/layout/icons.d.ts +2 -0
  80. package/dist/components/admin/layout/icons.js +3 -1
  81. package/dist/components/admin/layout/theme-mode-toggle.vue_vue_type_script_setup_true_lang.js +1 -1
  82. package/dist/components/admin/layout/user-menu-inner.vue_vue_type_script_setup_true_lang.js +1 -1
  83. package/dist/components/admin/list/approval-queue-row.vue_vue_type_script_setup_true_lang.js +1 -1
  84. package/dist/components/admin/list/bulk-actions-toolbar.vue_vue_type_script_setup_true_lang.js +2 -2
  85. package/dist/components/admin/list/bulk-edit-drawer.vue_vue_type_script_setup_true_lang.js +4 -4
  86. package/dist/components/admin/list/calendar-agenda-view.vue_vue_type_script_setup_true_lang.js +1 -1
  87. package/dist/components/admin/list/calendar-header.vue_vue_type_script_setup_true_lang.js +5 -5
  88. package/dist/components/admin/list/calendar-list.vue_vue_type_script_setup_true_lang.js +2 -2
  89. package/dist/components/admin/list/count.vue_vue_type_script_setup_true_lang.js +1 -1
  90. package/dist/components/admin/list/filter-form.vue_vue_type_script_setup_true_lang.js +1 -1
  91. package/dist/components/admin/list/filter-list-item.vue_vue_type_script_setup_true_lang.js +1 -1
  92. package/dist/components/admin/list/filter-live-search.vue_vue_type_script_setup_true_lang.js +1 -1
  93. package/dist/components/admin/list/list-no-results.vue_vue_type_script_setup_true_lang.js +2 -2
  94. package/dist/components/admin/list/list-pagination.vue_vue_type_script_setup_true_lang.js +5 -5
  95. package/dist/components/admin/list/prev-next-buttons.vue_vue_type_script_setup_true_lang.js +5 -5
  96. package/dist/components/admin/list/saved-queries-list.vue_vue_type_script_setup_true_lang.js +5 -5
  97. package/dist/components/admin/list/tree-list-node.vue_vue_type_script_setup_true_lang.js +1 -1
  98. package/dist/components/admin/realtime/menu-live.vue.d.ts +3 -1
  99. package/dist/components/admin/realtime/menu-live.vue_vue_type_script_setup_true_lang.js +42 -12
  100. package/dist/components/admin/supabase/forgot-password-form.vue_vue_type_script_setup_true_lang.js +1 -1
  101. package/dist/components/admin/supabase/set-password-form.vue_vue_type_script_setup_true_lang.js +3 -3
  102. package/dist/components/admin/supabase/supabase-login-page.vue_vue_type_script_setup_true_lang.js +1 -1
  103. package/dist/components/admin/view/create.vue_vue_type_script_setup_true_lang.js +1 -1
  104. package/dist/components/admin/view/infinite-list.vue_vue_type_script_setup_true_lang.js +1 -1
  105. package/dist/components/admin/view/list.vue_vue_type_script_setup_true_lang.js +1 -1
  106. package/dist/components/admin/view/translatable-fields-tab.vue_vue_type_script_setup_true_lang.js +1 -1
  107. package/dist/components/admin/widgets/job-monitor-row.vue_vue_type_script_setup_true_lang.js +1 -1
  108. package/dist/components/inspector/inspector.vue_vue_type_script_setup_true_lang.js +1 -1
  109. package/dist/controllers/reference-field-options.d.ts +18 -0
  110. package/dist/controllers/reference-field-test-harness.d.ts +3 -2
  111. package/dist/controllers/use-infinite-list-controller.d.ts +3 -3
  112. package/dist/controllers/use-list-controller.d.ts +4 -4
  113. package/dist/controllers/use-reference-many-field-controller.d.ts +8 -15
  114. package/dist/controllers/use-reference-one-field-controller.d.ts +8 -17
  115. package/dist/list/list-context.d.ts +10 -4
  116. package/dist/list/use-list.d.ts +3 -3
  117. package/dist/store/use-saved-queries.d.ts +5 -5
  118. package/package.json +5 -5
@@ -22,7 +22,9 @@ export interface MenuLiveProps {
22
22
  /**
23
23
  * A menu link with a badge counting the resource's new records. The count
24
24
  * lives in the store, so it survives a remount; it clears while the link's
25
- * route is active. Divergence from the React twin: the render props are slots.
25
+ * route is active. Inside a `<SidebarProvider>` it is a sidebar menu button,
26
+ * with the label as a `title` while the desktop rail is collapsed; elsewhere it is
27
+ * a plain link. Divergence from the React twin: the render props are slots.
26
28
  * Declared as a render component so the file can also hold {@link MenuLive}.
27
29
  */
28
30
  export declare const MenuLiveItemLink: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
@@ -2,11 +2,17 @@ import { useCheloneContext, useCheloneStore } from "../../../context.js";
2
2
  import { useTranslate } from "../../../i18n/use-translate.js";
3
3
  import { useMatch } from "../../../router/nav-composables.js";
4
4
  import { Badge } from "../../ui/badge.js";
5
- import { Fragment, computed, createBlock, createElementBlock, defineComponent, h, mergeProps, openBlock, renderList, shallowRef, unref, watchEffect } from "vue";
5
+ import { SidebarContextKey } from "../../ui/sidebar/sidebar-context.js";
6
+ import sidebar_menu_button_default from "../../ui/sidebar/sidebar-menu-button.js";
7
+ import { SidebarMenuItem } from "../../ui/sidebar/sidebar-parts.js";
8
+ import { Fragment, computed, createBlock, createElementBlock, defineComponent, h, inject, mergeProps, openBlock, renderList, shallowRef, unref, watchEffect } from "vue";
6
9
  import { assertRealtimeDataProvider, clearUnread, subscribeUnreadCount, unreadKey } from "@chelone/core";
7
10
  import { RouterLink } from "vue-router";
8
11
  // src/components/admin/realtime/menu-live.vue?vue&type=script&setup=true&lang.ts
9
- var _hoisted_1 = { class: "flex flex-col gap-1" };
12
+ var _hoisted_1 = {
13
+ key: 1,
14
+ class: "flex flex-col gap-1"
15
+ };
10
16
  var subscriptions = /* @__PURE__ */ new WeakMap();
11
17
  var toEventsKey = (events) => [...new Set(events)].sort().join(",");
12
18
  var fromEventsKey = (eventsKey) => eventsKey.split(",").filter(Boolean);
@@ -51,7 +57,9 @@ function acquire(dataProvider, store, resource, eventsKey) {
51
57
  /**
52
58
  * A menu link with a badge counting the resource's new records. The count
53
59
  * lives in the store, so it survives a remount; it clears while the link's
54
- * route is active. Divergence from the React twin: the render props are slots.
60
+ * route is active. Inside a `<SidebarProvider>` it is a sidebar menu button,
61
+ * with the label as a `title` while the desktop rail is collapsed; elsewhere it is
62
+ * a plain link. Divergence from the React twin: the render props are slots.
55
63
  * Declared as a render component so the file can also hold {@link MenuLive}.
56
64
  */
57
65
  var MenuLiveItemLink = defineComponent({
@@ -86,6 +94,7 @@ var MenuLiveItemLink = defineComponent({
86
94
  const { dataProvider } = useCheloneContext();
87
95
  const store = useCheloneStore();
88
96
  const translate = useTranslate();
97
+ const sidebar = inject(SidebarContextKey, null);
89
98
  const match = useMatch({
90
99
  path: props.to,
91
100
  end: false
@@ -111,15 +120,30 @@ var MenuLiveItemLink = defineComponent({
111
120
  return () => {
112
121
  const n = count.value ?? 0;
113
122
  const text = translate(props.label, { _: props.label });
114
- return h(RouterLink, {
115
- to: props.to,
116
- class: "flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent"
117
- }, () => [
123
+ const badge = n > 0 ? h(Badge, {
124
+ "data-testid": "menu-live-badge",
125
+ class: sidebar ? "group-data-[collapsible=icon]:absolute group-data-[collapsible=icon]:top-0 group-data-[collapsible=icon]:right-0 group-data-[collapsible=icon]:h-4 group-data-[collapsible=icon]:min-w-4 group-data-[collapsible=icon]:px-1 group-data-[collapsible=icon]:text-[10px]" : void 0
126
+ }, () => props.badgeLabel?.(n) ?? (n > 99 ? "99+" : String(n))) : null;
127
+ const content = () => [
118
128
  props.icon ? h(props.icon) : null,
119
129
  slots.icon?.(),
120
130
  h("span", { class: "flex-1" }, text),
121
- n > 0 ? h(Badge, { "data-testid": "menu-live-badge" }, () => props.badgeLabel?.(n) ?? (n > 99 ? "99+" : String(n))) : null
122
- ]);
131
+ badge
132
+ ];
133
+ if (sidebar) return h(SidebarMenuItem, null, () => h(sidebar_menu_button_default, {
134
+ as: RouterLink,
135
+ to: props.to,
136
+ isActive: match.value != null,
137
+ class: "relative",
138
+ title: sidebar.state.value === "collapsed" && !sidebar.isMobile.value ? text : void 0,
139
+ onClick: () => {
140
+ if (sidebar.openMobile.value) sidebar.setOpenMobile(false);
141
+ }
142
+ }, content));
143
+ return h(RouterLink, {
144
+ to: props.to,
145
+ class: "flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent"
146
+ }, content);
123
147
  };
124
148
  }
125
149
  });
@@ -128,12 +152,18 @@ var menu_live_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
128
152
  props: { items: {} },
129
153
  setup(__props) {
130
154
  /**
131
- * `<MenuLive>` — a list of {@link MenuLiveItemLink}s, one per item.
155
+ * `<MenuLive>` — a list of {@link MenuLiveItemLink}s, one per item. Inside a
156
+ * sidebar it renders the items as sidebar menu entries with no wrapper, so
157
+ * place it in a `<SidebarMenu>`, such as a `<ResourceMenuItemGroup>`'s default
158
+ * slot.
132
159
  */
160
+ const sidebar = inject(SidebarContextKey, null);
133
161
  return (_ctx, _cache) => {
134
- return openBlock(), createElementBlock("nav", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
162
+ return unref(sidebar) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.items, (item) => {
163
+ return openBlock(), createBlock(unref(MenuLiveItemLink), mergeProps({ key: item.to }, { ref_for: true }, item), null, 16);
164
+ }), 128)) : (openBlock(), createElementBlock("nav", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
135
165
  return openBlock(), createBlock(unref(MenuLiveItemLink), mergeProps({ key: item.to }, { ref_for: true }, item), null, 16);
136
- }), 128))]);
166
+ }), 128))]));
137
167
  };
138
168
  }
139
169
  });
@@ -32,7 +32,7 @@ var forgot_password_form_vue_vue_type_script_setup_true_lang_default = /*@__PURE
32
32
  await resetPassword.mutateAsync({ email: values.email });
33
33
  } catch (error) {
34
34
  const message = errorMessageOf(error);
35
- notifications?.notify(message ?? "ra.notification.http_error", {
35
+ notifications?.notify(message ?? "chelone.notification.http_error_label", {
36
36
  type: "warning",
37
37
  messageArgs: message === void 0 ? void 0 : { _: message }
38
38
  });
@@ -50,7 +50,7 @@ var set_password_form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
50
50
  });
51
51
  } catch (error) {
52
52
  const message = errorMessageOf(error);
53
- notifications?.notify(message ?? "ra.notification.http_error", {
53
+ notifications?.notify(message ?? "chelone.notification.http_error_label", {
54
54
  type: "warning",
55
55
  messageArgs: message === void 0 ? void 0 : { _: message }
56
56
  });
@@ -88,7 +88,7 @@ var set_password_form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
88
88
  onSubmit: handleSubmit
89
89
  }, [
90
90
  createVNode(password_input_default, {
91
- label: unref(translate)("ra.auth.password", { _: "Password" }),
91
+ label: unref(translate)("chelone.auth.password", { _: "Password" }),
92
92
  source: "password",
93
93
  autocomplete: "new-password",
94
94
  autofocus: "",
@@ -105,7 +105,7 @@ var set_password_form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
105
105
  class: "cursor-pointer",
106
106
  disabled: unref(submitting)
107
107
  }, {
108
- default: withCtx(() => [unref(submitting) ? (openBlock(), createBlock(spinner_default, { key: 0 })) : createCommentVNode("", true), createTextVNode(" " + toDisplayString(unref(translate)("ra.action.save", { _: "Save" })), 1)]),
108
+ default: withCtx(() => [unref(submitting) ? (openBlock(), createBlock(spinner_default, { key: 0 })) : createCommentVNode("", true), createTextVNode(" " + toDisplayString(unref(translate)("chelone.action.save", { _: "Save" })), 1)]),
109
109
  _: 1
110
110
  }, 8, ["disabled"])
111
111
  ], 34));
@@ -70,7 +70,7 @@ var supabase_login_page_vue_vue_type_script_setup_true_lang_default = /*@__PURE_
70
70
  _: 1
71
71
  }, 8, ["to"])) : createCommentVNode("", true)], 64)) : createCommentVNode("", true), providers.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1, [!props.disableEmailPassword ? (openBlock(), createElementBlock("div", _hoisted_2, [
72
72
  _cache[0] || (_cache[0] = createElementVNode("div", { class: "flex-1 border-t" }, null, -1)),
73
- createTextVNode(" " + toDisplayString(unref(translate)("ra.auth.or", { _: "or" })) + " ", 1),
73
+ createTextVNode(" " + toDisplayString(unref(translate)("chelone.auth.or", { _: "or" })) + " ", 1),
74
74
  _cache[1] || (_cache[1] = createElementVNode("div", { class: "flex-1 border-t" }, null, -1))
75
75
  ])) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(providers.value, (provider) => {
76
76
  return openBlock(), createBlock(resolveDynamicComponent(buttons[provider]), {
@@ -57,7 +57,7 @@ var create_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
57
57
  const redirect = useRedirectOptional();
58
58
  const translate = useTranslate();
59
59
  const getResourceLabel = useGetResourceLabel();
60
- const defaultTitle = computed(() => translate("ra.page.create", { name: getResourceLabel(resource, 1) }));
60
+ const defaultTitle = computed(() => translate("chelone.page.create", { name: getResourceLabel(resource, 1) }));
61
61
  const form = useForm({
62
62
  resource,
63
63
  record: seed,
@@ -38,7 +38,7 @@ var infinite_list_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
38
38
  provideListContext(controller);
39
39
  const translate = useTranslate();
40
40
  const getResourceLabel = useGetResourceLabel();
41
- const defaultTitle = computed(() => translate("ra.page.list", { name: getResourceLabel(resource, 2) }));
41
+ const defaultTitle = computed(() => translate("chelone.page.list", { name: getResourceLabel(resource, 2) }));
42
42
  return (_ctx, _cache) => {
43
43
  return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [__props.title !== "" ? (openBlock(), createElementBlock("h2", _hoisted_3, toDisplayString(__props.title ?? defaultTitle.value), 1)) : createCommentVNode("", true), createElementVNode("div", _hoisted_4, [renderSlot(_ctx.$slots, "actions")])]), renderSlot(_ctx.$slots, "default")]);
44
44
  };
@@ -42,7 +42,7 @@ var list_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
42
42
  provideListContext(controller);
43
43
  const translate = useTranslate();
44
44
  const getResourceLabel = useGetResourceLabel();
45
- const defaultTitle = computed(() => translate("ra.page.list", { name: getResourceLabel(resource, 2) }));
45
+ const defaultTitle = computed(() => translate("chelone.page.list", { name: getResourceLabel(resource, 2) }));
46
46
  return (_ctx, _cache) => {
47
47
  return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [__props.title !== "" ? (openBlock(), createElementBlock("h2", _hoisted_3, toDisplayString(__props.title ?? defaultTitle.value), 1)) : createCommentVNode("", true), createElementVNode("div", _hoisted_4, [renderSlot(_ctx.$slots, "actions")])]), renderSlot(_ctx.$slots, "default")]);
48
48
  };
@@ -25,7 +25,7 @@ var translatable_fields_tab_vue_vue_type_script_setup_true_lang_default = /*@__P
25
25
  const translate = useTranslate();
26
26
  const translatable = useTranslatableContext();
27
27
  const selected = computed(() => translatable.selectedLocale.value === props.locale);
28
- const label = computed(() => translate(`ra.locales.${props.locale}`, { _: props.locale.charAt(0).toUpperCase() + props.locale.slice(1) }));
28
+ const label = computed(() => translate(`chelone.locales.${props.locale}`, { _: props.locale.charAt(0).toUpperCase() + props.locale.slice(1) }));
29
29
  return (_ctx, _cache) => {
30
30
  return openBlock(), createElementBlock("button", {
31
31
  type: "button",
@@ -116,7 +116,7 @@ var job_monitor_row_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
116
116
  disabled: __props.busy,
117
117
  onClick: _cache[2] || (_cache[2] = ($event) => emit("plan", unref(planJobCancel)(__props.job, options.value)))
118
118
  }, {
119
- default: withCtx(() => [createTextVNode(toDisplayString(unref(translate)("ra.action.cancel", { _: "Cancel" })), 1)]),
119
+ default: withCtx(() => [createTextVNode(toDisplayString(unref(translate)("chelone.action.cancel", { _: "Cancel" })), 1)]),
120
120
  _: 1
121
121
  }, 8, ["disabled"])) : createCommentVNode("", true)
122
122
  ])
@@ -155,7 +155,7 @@ var inspector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
155
155
  variant: "ghost",
156
156
  size: "icon",
157
157
  class: "size-7",
158
- "aria-label": unref(translate)("ra.action.close", { _: "Close" }),
158
+ "aria-label": unref(translate)("chelone.action.close", { _: "Close" }),
159
159
  onClick: _cache[0] || (_cache[0] = ($event) => unref(inspector).disable())
160
160
  }, {
161
161
  default: withCtx(() => [createVNode(unref(XIcon))]),
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The options the two reference-field composables share: the record the lookup
3
+ * reads its foreign key from, and the fetch gate. `target` is not here: it is
4
+ * keyed by the referenced record, which only the composables name.
5
+ */
6
+ import type { LooseRecord, ResourceRecord, SourceProp } from "@chelone/core";
7
+ import type { MaybeRefOrGetter } from "vue";
8
+ import type { RecordValue } from "../record/record-context.js";
9
+ export interface ReferenceFieldControllerOptions<TName extends string, RecordType extends ResourceRecord = LooseRecord> {
10
+ /** The resource whose rows point at the record. */
11
+ reference: TName;
12
+ /** The field on the record whose value `target` must equal. The composable defaults it to `"id"`. */
13
+ source?: SourceProp<RecordType>;
14
+ /** Defaults to the ambient record (`RecordContextKey`). */
15
+ record?: MaybeRefOrGetter<RecordValue<RecordType>>;
16
+ /** Gates the data fetch only. Default true. */
17
+ enabled?: boolean;
18
+ }
@@ -1,3 +1,4 @@
1
+ import { type LooseRecord } from "@chelone/core";
1
2
  import { type Ref } from "vue";
2
3
  import { z } from "zod";
3
4
  import { type RecordValue } from "../record/record-context.js";
@@ -150,7 +151,7 @@ export declare function mountProbe<TResult>(useProbe: () => TResult, initialReco
150
151
  };
151
152
  }, TName>>>)>;
152
153
  };
153
- export declare const mountMany: (options?: Omit<UseReferenceManyFieldControllerOptions<"comments">, "reference" | "target">, record?: RecordValue, failWith?: Error) => {
154
+ export declare const mountMany: (options?: Omit<UseReferenceManyFieldControllerOptions<"comments", LooseRecord, Comment>, "reference" | "target">, record?: RecordValue, failWith?: Error) => {
154
155
  wrapper: import("@vue/test-utils").VueWrapper<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never> & {
155
156
  $: import("vue").ComponentInternalInstance;
156
157
  $data: {};
@@ -261,7 +262,7 @@ export declare const mountMany: (options?: Omit<UseReferenceManyFieldControllerO
261
262
  };
262
263
  }, TName>>>)>;
263
264
  };
264
- export declare const mountOne: (options?: Omit<UseReferenceOneFieldControllerOptions<"profiles">, "reference" | "target">, record?: RecordValue, failWith?: Error) => {
265
+ export declare const mountOne: (options?: Omit<UseReferenceOneFieldControllerOptions<"profiles", LooseRecord, Profile>, "reference" | "target">, record?: RecordValue, failWith?: Error) => {
265
266
  wrapper: import("@vue/test-utils").VueWrapper<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never> & {
266
267
  $: import("vue").ComponentInternalInstance;
267
268
  $data: {};
@@ -8,9 +8,9 @@
8
8
  * Filters and sort live in the store only: the composable never reads or
9
9
  * writes the location.
10
10
  */
11
- import { type InfiniteListController, type InfiniteListControllerState, type ListControllerOptions, type MicroStore, type RecordOf, type ResourceMap } from "@chelone/core";
11
+ import { type InfiniteListController, type InfiniteListControllerState, type ListControllerOptions, type LooseRecord, type MicroStore, type RecordOf, type ResourceMap } from "@chelone/core";
12
12
  /** Options for {@link useInfiniteListController}: the core list options + a resource override. */
13
- export interface UseInfiniteListControllerOptions extends ListControllerOptions {
13
+ export interface UseInfiniteListControllerOptions<TRecord = LooseRecord> extends ListControllerOptions<TRecord> {
14
14
  /** Target a specific resource; defaults to the ambient `<Resource>` name. */
15
15
  resource?: string;
16
16
  }
@@ -22,4 +22,4 @@ export type UseInfiniteListControllerReturn<TRecord> = InfiniteListControllerSta
22
22
  * and starts over. The controller attaches on mount and releases on scope
23
23
  * disposal. `options` are read once at `setup`.
24
24
  */
25
- export declare function useInfiniteListController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string>(options?: UseInfiniteListControllerOptions): UseInfiniteListControllerReturn<RecordOf<TResources, TName>>;
25
+ export declare function useInfiniteListController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string>(options?: UseInfiniteListControllerOptions<RecordOf<TResources, TName>>): UseInfiniteListControllerReturn<RecordOf<TResources, TName>>;
@@ -21,9 +21,9 @@
21
21
  * `resource` / `options` are read once at `setup`; to target a different
22
22
  * resource, mount a fresh instance (the Vue analog of React's remount-with-key).
23
23
  */
24
- import { type ListController, type ListControllerOptions, type ListControllerState, type MicroStore, type RecordOf, type ResourceMap } from "@chelone/core";
24
+ import { type ListControllerOptions, type ListControllerSurface, type LooseRecord, type RecordOf, type ResourceMap } from "@chelone/core";
25
25
  /** Options for {@link useListController}: the core list options + a resource override. */
26
- export interface UseListControllerOptions extends ListControllerOptions {
26
+ export interface UseListControllerOptions<TRecord = LooseRecord> extends ListControllerOptions<TRecord> {
27
27
  /** Target a specific resource; defaults to the ambient `<Resource>` name. */
28
28
  resource?: string;
29
29
  /**
@@ -46,5 +46,5 @@ export interface UseListControllerOptions extends ListControllerOptions {
46
46
  * plus the controller's stable actions (`setPage`/`setSort`/`toggleItem`/…). The
47
47
  * same shape the React twin returns, minus the `MicroStore` plumbing.
48
48
  */
49
- export type UseListControllerReturn<TRecord> = ListControllerState<TRecord> & Omit<ListController<TRecord>, keyof MicroStore<ListControllerState<TRecord>>>;
50
- export declare function useListController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string>(options?: UseListControllerOptions): UseListControllerReturn<RecordOf<TResources, TName>>;
49
+ export type UseListControllerReturn<TRecord> = ListControllerSurface<TRecord>;
50
+ export declare function useListController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string>(options?: UseListControllerOptions<RecordOf<TResources, TName>>): UseListControllerReturn<RecordOf<TResources, TName>>;
@@ -10,22 +10,15 @@
10
10
  * previous subscription is released. The other options are read at `setup`.
11
11
  * There is no location sync: the list is embedded in a record.
12
12
  */
13
- import { type FilterPayload, type ListControllerState, type LooseRecord, type MicroStore, type RecordOf, type ReferenceManyController, type ResourceMap, type ResourceRecord, type SortPayload } from "@chelone/core";
14
- import { type MaybeRefOrGetter } from "vue";
15
- import { type RecordValue } from "../record/record-context.js";
16
- export interface UseReferenceManyFieldControllerOptions<TName extends string = string, RecordType extends ResourceRecord = LooseRecord> {
17
- /** The resource whose rows point at the record. */
18
- reference: TName;
19
- /** The field on `reference` that holds the foreign key. */
20
- target: string;
21
- /** The field on the record whose value `target` must equal. Default `"id"`. */
22
- source?: string;
23
- /** Defaults to the ambient record. */
24
- record?: MaybeRefOrGetter<RecordValue<RecordType>>;
13
+ import { type FilterPayload, type ListControllerState, type LooseRecord, type MicroStore, type RecordOf, type ReferenceManyController, type ResourceMap, type ResourceRecord, type SortPayload, type SourceKey } from "@chelone/core";
14
+ import type { ReferenceFieldControllerOptions } from "./reference-field-options.js";
15
+ export interface UseReferenceManyFieldControllerOptions<TName extends string = string, RecordType extends ResourceRecord = LooseRecord, ReferenceRecord = LooseRecord> extends ReferenceFieldControllerOptions<TName, RecordType> {
16
+ /** The field on `reference` that holds the foreign key. A key of the referenced record. */
17
+ target: SourceKey<ReferenceRecord>;
25
18
  /** Permanent filter, merged over the user filter for every fetch. */
26
- filter?: FilterPayload;
19
+ filter?: FilterPayload<ReferenceRecord>;
27
20
  /** Initial sort when nothing is persisted. Default id ascending. */
28
- sort?: SortPayload | SortPayload[];
21
+ sort?: SortPayload<ReferenceRecord> | SortPayload<ReferenceRecord>[];
29
22
  /** Default 25. */
30
23
  perPage?: number;
31
24
  /** KV namespace for params and selection. Default `${reference}.${target}.${id}`; `false` keeps them in memory. */
@@ -43,4 +36,4 @@ export type UseReferenceManyFieldControllerReturn<TRecord> = ListControllerState
43
36
  * actions. A record without a usable id (absent, or not a string or number)
44
37
  * fetches nothing and reads as an empty, settled list.
45
38
  */
46
- export declare function useReferenceManyFieldController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string, RecordType extends ResourceRecord = LooseRecord>(options: UseReferenceManyFieldControllerOptions<TName, RecordType>): UseReferenceManyFieldControllerReturn<RecordOf<TResources, TName>>;
39
+ export declare function useReferenceManyFieldController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string, RecordType extends ResourceRecord = LooseRecord>(options: UseReferenceManyFieldControllerOptions<TName, RecordType, RecordOf<TResources, TName>>): UseReferenceManyFieldControllerReturn<RecordOf<TResources, TName>>;
@@ -8,24 +8,15 @@
8
8
  * {@link useReferenceManyFieldController}: a new id builds a new controller and
9
9
  * releases the previous subscription.
10
10
  */
11
- import { type FilterPayload, type LooseRecord, type MicroStore, type RecordOf, type ReferenceOneController, type ReferenceOneControllerState, type ResourceMap, type ResourceRecord, type SortPayload } from "@chelone/core";
12
- import { type MaybeRefOrGetter } from "vue";
13
- import { type RecordValue } from "../record/record-context.js";
14
- export interface UseReferenceOneFieldControllerOptions<TName extends string = string, RecordType extends ResourceRecord = LooseRecord> {
15
- /** The resource whose rows point at the record. */
16
- reference: TName;
17
- /** The field on `reference` that holds the foreign key. */
18
- target: string;
19
- /** The field on the record whose value `target` must equal. Default `"id"`. */
20
- source?: string;
21
- /** Defaults to the ambient record. */
22
- record?: MaybeRefOrGetter<RecordValue<RecordType>>;
11
+ import { type FilterPayload, type LooseRecord, type MicroStore, type RecordOf, type ReferenceOneController, type ReferenceOneControllerState, type ResourceMap, type ResourceRecord, type SortPayload, type SourceKey } from "@chelone/core";
12
+ import type { ReferenceFieldControllerOptions } from "./reference-field-options.js";
13
+ export interface UseReferenceOneFieldControllerOptions<TName extends string = string, RecordType extends ResourceRecord = LooseRecord, ReferenceRecord = LooseRecord> extends ReferenceFieldControllerOptions<TName, RecordType> {
14
+ /** The field on `reference` that holds the foreign key. A key of the referenced record. */
15
+ target: SourceKey<ReferenceRecord>;
23
16
  /** Decides which row is first when several match. */
24
- sort?: SortPayload | SortPayload[];
17
+ sort?: SortPayload<ReferenceRecord> | SortPayload<ReferenceRecord>[];
25
18
  /** Narrows the lookup. */
26
- filter?: FilterPayload;
27
- /** Gates the fetch. Default true. */
28
- enabled?: boolean;
19
+ filter?: FilterPayload<ReferenceRecord>;
29
20
  }
30
21
  /** Live lookup state plus the controller's stable `refetch`. */
31
22
  export type UseReferenceOneFieldControllerReturn<TRecord> = ReferenceOneControllerState<TRecord> & Omit<ReferenceOneController<TRecord>, keyof MicroStore<ReferenceOneControllerState<TRecord>>>;
@@ -33,4 +24,4 @@ export type UseReferenceOneFieldControllerReturn<TRecord> = ReferenceOneControll
33
24
  * The first row of `reference` whose `target` equals `record[source]`. A record
34
25
  * without a usable id fetches nothing and reads as settled with no record.
35
26
  */
36
- export declare function useReferenceOneFieldController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string, RecordType extends ResourceRecord = LooseRecord>(options: UseReferenceOneFieldControllerOptions<TName, RecordType>): UseReferenceOneFieldControllerReturn<RecordOf<TResources, TName>>;
27
+ export declare function useReferenceOneFieldController<TResources extends ResourceMap = ResourceMap, TName extends keyof TResources & string = keyof TResources & string, RecordType extends ResourceRecord = LooseRecord>(options: UseReferenceOneFieldControllerOptions<TName, RecordType, RecordOf<TResources, TName>>): UseReferenceOneFieldControllerReturn<RecordOf<TResources, TName>>;
@@ -11,11 +11,17 @@
11
11
  * read it directly with no ref juggling. `useListContext` throws without a
12
12
  * provider (parity with the React twin).
13
13
  */
14
- import type { LooseRecord } from "@chelone/core";
14
+ import type { ListContextSurface, LooseRecord, ResourceRecord } from "@chelone/core";
15
15
  import { type InjectionKey } from "vue";
16
- import type { UseListControllerReturn } from "../controllers/use-list-controller.js";
17
- /** The ambient list surface — the reactive `useListController` result. */
18
- export type ListContextValue<TRecord = LooseRecord> = UseListControllerReturn<TRecord>;
16
+ /**
17
+ * The ambient list surface — the reactive `useListController` result.
18
+ *
19
+ * `ListContextSurface` erases the filter members and keeps `data` typed: an
20
+ * injection key cannot be generic, so a controller typed to any record must be
21
+ * assignable to the one value this key carries. `ResourceRecord` is the widest
22
+ * record `data` can hold; `useListContext<T>()` reads it back typed.
23
+ */
24
+ export type ListContextValue<TRecord = ResourceRecord> = ListContextSurface<TRecord>;
19
25
  /** The provide/inject key for the ambient list surface. */
20
26
  export declare const ListContextKey: InjectionKey<ListContextValue>;
21
27
  /** Provide the ambient list surface (called by `<List>` in `setup`). */
@@ -26,9 +26,9 @@ export interface UseListOptions<TRecord extends ResourceRecord = ResourceRecord>
26
26
  /** The in-memory records (reactive-aware). `undefined` = not-yet-loaded. */
27
27
  data?: MaybeRefOrGetter<TRecord[] | undefined>;
28
28
  /** Client-side filter for the embedded list. */
29
- filter?: FilterPayload;
29
+ filter?: FilterPayload<TRecord>;
30
30
  /** Client-side sort for the embedded list. */
31
- sort?: SortPayload | SortPayload[];
31
+ sort?: SortPayload<TRecord> | SortPayload<TRecord>[];
32
32
  /** Client-side page size. Default 1000 (ra-core `useList` — "show everything"). */
33
33
  perPage?: number;
34
34
  /** Initial page (1-based). Default 1. */
@@ -47,4 +47,4 @@ export interface UseListOptions<TRecord extends ResourceRecord = ResourceRecord>
47
47
  * into the live controller so an async feed (a resolving `useGetMany` /
48
48
  * `useGetList`) populates the list in place.
49
49
  */
50
- export declare function useList<TRecord extends ResourceRecord = ResourceRecord>(options?: UseListOptions<TRecord>): ListContextValue;
50
+ export declare function useList<TRecord extends ResourceRecord = ResourceRecord>(options?: UseListOptions<TRecord>): ListContextValue<TRecord>;
@@ -1,9 +1,9 @@
1
- import { type SavedQueriesControllerOptions, type SavedQuery, type SavedQueryValue } from "@chelone/core";
1
+ import { type LooseRecord, type SavedQueriesControllerOptions, type SavedQuery, type SavedQueryValue } from "@chelone/core";
2
2
  import { type Ref } from "vue";
3
- export interface UseSavedQueriesReturn {
4
- queries: Readonly<Ref<readonly SavedQuery[]>>;
3
+ export interface UseSavedQueriesReturn<TRecord = LooseRecord> {
4
+ queries: Readonly<Ref<readonly SavedQuery<TRecord>[]>>;
5
5
  /** Trims the label and ignores a blank one; a same-label query is replaced. */
6
- save(label: string, value: SavedQueryValue): void;
6
+ save(label: string, value: SavedQueryValue<TRecord>): void;
7
7
  /** Trims the label; a label no query has is ignored. */
8
8
  remove(label: string): void;
9
9
  }
@@ -17,4 +17,4 @@ export interface UseSavedQueriesReturn {
17
17
  * `[queries, setQueries]` tuple: this returns `{ queries, save, remove }`, with
18
18
  * `queries` a ref.
19
19
  */
20
- export declare function useSavedQueries(resource: string, options?: SavedQueriesControllerOptions): UseSavedQueriesReturn;
20
+ export declare function useSavedQueries<TRecord = LooseRecord>(resource: string, options?: SavedQueriesControllerOptions): UseSavedQueriesReturn<TRecord>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chelone/vue",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -76,14 +76,14 @@
76
76
  "access": "public"
77
77
  },
78
78
  "dependencies": {
79
- "@chelone/core": "0.9.0",
80
- "@chelone/utils": "0.9.0",
79
+ "@chelone/core": "0.11.0",
80
+ "@chelone/utils": "0.11.0",
81
81
  "@types/geojson": "^7946.0.16",
82
82
  "cronstrue": "^3.38.0",
83
83
  "libphonenumber-js": "^1.13.15"
84
84
  },
85
85
  "peerDependencies": {
86
- "@chelone/supabase": "0.9.0",
86
+ "@chelone/supabase": "0.11.0",
87
87
  "@dnd-kit/dom": "^0.5.3",
88
88
  "@dnd-kit/vue": "^0.5.3",
89
89
  "@guolao/vue-monaco-editor": "^1.6.0",
@@ -219,7 +219,7 @@
219
219
  },
220
220
  "devDependencies": {
221
221
  "@arethetypeswrong/cli": "^0.18.5",
222
- "@chelone/supabase": "0.9.0",
222
+ "@chelone/supabase": "0.11.0",
223
223
  "@chelone/test-utils": "0.0.0",
224
224
  "@dnd-kit/dom": "^0.5.3",
225
225
  "@dnd-kit/vue": "^0.5.3",