@hybridly/vue 0.7.13 → 0.7.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -200,7 +200,10 @@ const wrapper = vue.defineComponent({
200
200
  function renderLayout(view) {
201
201
  utils.debug.adapter("vue:render:layout", "Rendering layout.");
202
202
  if (typeof state.view.value?.layout === "function") {
203
- return state.view.value.layout(vue.h, view, renderDialog());
203
+ return state.view.value.layout(vue.h, view, renderDialog(), {
204
+ ...state.view.value?.properties ?? {},
205
+ ...state.properties.value
206
+ });
204
207
  }
205
208
  if (Array.isArray(state.view.value?.layout)) {
206
209
  const layoutsAndView = state.view.value.layout.concat(view).reverse().reduce((child, layout) => {
@@ -1000,7 +1003,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1000
1003
  async function applyFilter(name, value, options = {}) {
1001
1004
  const filter = getFilter(name);
1002
1005
  if (!filter) {
1003
- console.warn(`[Refinement] Filter "${name} does not exist."`);
1006
+ console.warn(`[Refinement] Filter "${name}" does not exist.`);
1004
1007
  return;
1005
1008
  }
1006
1009
  if (["", null].includes(value) || value === filter.default) {
@@ -1046,7 +1049,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1046
1049
  async function toggleSort(name, options) {
1047
1050
  const sort = getSort(name);
1048
1051
  if (!sort) {
1049
- console.warn(`[Refinement] Sort "${name} does not exist."`);
1052
+ console.warn(`[Refinement] Sort "${name}" does not exist.`);
1050
1053
  return;
1051
1054
  }
1052
1055
  const next = options?.direction ? sort[options?.direction] : sort.next;
@@ -1245,6 +1248,20 @@ function useBulkSelect() {
1245
1248
  const allSelected = vue.computed(() => {
1246
1249
  return selection.value.all && selection.value.except.size === 0;
1247
1250
  });
1251
+ function bindCheckbox(key) {
1252
+ return {
1253
+ onChange: (event) => {
1254
+ const target = event.target;
1255
+ if (target.checked) {
1256
+ select(target.value);
1257
+ } else {
1258
+ deselect(target.value);
1259
+ }
1260
+ },
1261
+ checked: selected(key),
1262
+ value: key
1263
+ };
1264
+ }
1248
1265
  return {
1249
1266
  allSelected,
1250
1267
  selectAll,
@@ -1253,20 +1270,70 @@ function useBulkSelect() {
1253
1270
  deselect,
1254
1271
  toggle,
1255
1272
  selected,
1256
- selection
1273
+ selection,
1274
+ bindCheckbox
1257
1275
  };
1258
1276
  }
1259
1277
 
1278
+ function useQueryParameters() {
1279
+ const state = vue.reactive({});
1280
+ function updateState() {
1281
+ const params = new URLSearchParams(window.location.search);
1282
+ const unusedKeys = new Set(Object.keys(state));
1283
+ for (const key of params.keys()) {
1284
+ const paramsForKey = params.getAll(key);
1285
+ state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1286
+ unusedKeys.delete(key);
1287
+ }
1288
+ Array.from(unusedKeys).forEach((key) => delete state[key]);
1289
+ }
1290
+ updateState();
1291
+ core.registerHook("after", updateState);
1292
+ return state;
1293
+ }
1294
+ function useQueryParameter(name, options = {}) {
1295
+ const query = useQueryParameters();
1296
+ const transform = (value2) => {
1297
+ if (options.transform === "bool") {
1298
+ return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1299
+ } else if (options.transform === "number") {
1300
+ return Number(value2);
1301
+ } else if (options.transform === "string") {
1302
+ return String(value2);
1303
+ } else if (options.transform === "date") {
1304
+ return new Date(value2);
1305
+ } else if (typeof options.transform === "function") {
1306
+ return options.transform(value2);
1307
+ }
1308
+ return value2;
1309
+ };
1310
+ const value = vue.ref();
1311
+ vue.watch(query, () => {
1312
+ value.value = transform(query[name] ?? vue.toValue(options.defaultValue));
1313
+ }, { deep: true, immediate: true });
1314
+ return value;
1315
+ }
1316
+
1260
1317
  function useTable(props, key, defaultOptions = {}) {
1261
1318
  const table = vue.computed(() => props[key]);
1262
1319
  const bulk = useBulkSelect();
1263
1320
  const refinements = useRefinements(toReactive(table), "refinements", defaultOptions);
1321
+ function getAdditionnalData() {
1322
+ const data = {};
1323
+ if (defaultOptions?.includeQueryParameters !== false) {
1324
+ Object.assign(data, structuredClone(vue.toRaw(useQueryParameters())));
1325
+ }
1326
+ if (defaultOptions?.data) {
1327
+ Object.assign(data, defaultOptions.data);
1328
+ }
1329
+ return data;
1330
+ }
1264
1331
  function getRecordKey(record) {
1265
1332
  if (typeof record !== "object") {
1266
1333
  return record;
1267
1334
  }
1268
1335
  if (Reflect.has(record, "__hybridId")) {
1269
- return Reflect.get(record, "__hybridId").value;
1336
+ return Reflect.get(record, "__hybridId");
1270
1337
  }
1271
1338
  return Reflect.get(record, table.value.keyName).value;
1272
1339
  }
@@ -1279,6 +1346,7 @@ function useTable(props, key, defaultOptions = {}) {
1279
1346
  url: core.route(table.value.endpoint),
1280
1347
  preserveState: true,
1281
1348
  data: {
1349
+ ...getAdditionnalData(),
1282
1350
  type: "action:inline",
1283
1351
  action: getActionName(action),
1284
1352
  tableId: table.value.id,
@@ -1299,6 +1367,7 @@ function useTable(props, key, defaultOptions = {}) {
1299
1367
  url: core.route(table.value.endpoint),
1300
1368
  preserveState: true,
1301
1369
  data: {
1370
+ ...getAdditionnalData(),
1302
1371
  type: "action:bulk",
1303
1372
  action: actionName,
1304
1373
  tableId: table.value.id,
@@ -1333,6 +1402,8 @@ function useTable(props, key, defaultOptions = {}) {
1333
1402
  allSelected: bulk.allSelected,
1334
1403
  /** The current record selection. */
1335
1404
  selection: bulk.selection,
1405
+ /** Binds a checkbox to its selection state. */
1406
+ bindCheckbox: (key2) => bulk.bindCheckbox(key2),
1336
1407
  /** Toggles selection for the given record. */
1337
1408
  toggle: (record) => bulk.toggle(getRecordKey(record)),
1338
1409
  /** Selects selection for the given record. */
@@ -1406,45 +1477,6 @@ function useTable(props, key, defaultOptions = {}) {
1406
1477
  });
1407
1478
  }
1408
1479
 
1409
- function useQueryParameters() {
1410
- const state = vue.reactive({});
1411
- function updateState() {
1412
- const params = new URLSearchParams(window.location.search);
1413
- const unusedKeys = new Set(Object.keys(state));
1414
- for (const key of params.keys()) {
1415
- const paramsForKey = params.getAll(key);
1416
- state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1417
- unusedKeys.delete(key);
1418
- }
1419
- Array.from(unusedKeys).forEach((key) => delete state[key]);
1420
- }
1421
- updateState();
1422
- core.registerHook("after", updateState);
1423
- return state;
1424
- }
1425
- function useQueryParameter(name, options = {}) {
1426
- const query = useQueryParameters();
1427
- const transform = (value2) => {
1428
- if (options.transform === "bool") {
1429
- return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1430
- } else if (options.transform === "number") {
1431
- return Number(value2);
1432
- } else if (options.transform === "string") {
1433
- return String(value2);
1434
- } else if (options.transform === "date") {
1435
- return new Date(value2);
1436
- } else if (typeof options.transform === "function") {
1437
- return options.transform(value2);
1438
- }
1439
- return value2;
1440
- };
1441
- const value = vue.ref();
1442
- vue.watch(query, () => {
1443
- value.value = transform(query[name] ?? vue.toValue(options.defaultValue));
1444
- }, { deep: true, immediate: true });
1445
- return value;
1446
- }
1447
-
1448
1480
  exports.can = core.can;
1449
1481
  exports.route = core.route;
1450
1482
  exports.router = core.router;
package/dist/index.d.cts CHANGED
@@ -94,13 +94,13 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
94
94
  progress: {
95
95
  readonly event: {
96
96
  readonly loaded: number;
97
- readonly total?: number;
98
- readonly progress?: number;
97
+ readonly total?: number | undefined;
98
+ readonly progress?: number | undefined;
99
99
  readonly bytes: number;
100
- readonly rate?: number;
101
- readonly estimated?: number;
102
- readonly upload?: boolean;
103
- readonly download?: boolean;
100
+ readonly rate?: number | undefined;
101
+ readonly estimated?: number | undefined;
102
+ readonly upload?: boolean | undefined;
103
+ readonly download?: boolean | undefined;
104
104
  readonly event?: any;
105
105
  readonly lengthComputable: boolean;
106
106
  };
@@ -544,6 +544,11 @@ declare function useBulkSelect<T = any>(): {
544
544
  toggle: (record: T, force?: boolean) => void;
545
545
  selected: (record: T) => boolean;
546
546
  selection: Ref<BulkSelection<T>>;
547
+ bindCheckbox: (key: T) => {
548
+ onChange: (event: Event) => void;
549
+ checked: boolean;
550
+ value: T;
551
+ };
547
552
  };
548
553
 
549
554
  declare global {
@@ -597,10 +602,21 @@ type AsRecordType<T extends Record<string, any>> = {
597
602
  value: T[K];
598
603
  };
599
604
  };
605
+ interface TableDefaultOptions extends AvailableHybridRequestOptions {
606
+ /**
607
+ * Whether to include existing query parameters in the request.
608
+ * @default true
609
+ */
610
+ includeQueryParameters?: boolean;
611
+ /**
612
+ * Additionnal data to send with the requests.
613
+ */
614
+ data?: Record<string, FormDataConvertible> | FormDataConvertible;
615
+ }
600
616
  /**
601
617
  * Provides utilities for working with tables.
602
618
  */
603
- declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: AvailableHybridRequestOptions): {
619
+ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: TableDefaultOptions): {
604
620
  bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T>;
605
621
  filters: {
606
622
  apply: (value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
@@ -619,8 +635,8 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
619
635
  isSorting: (direction?: SortDirection) => boolean;
620
636
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
621
637
  is_active: boolean;
622
- direction?: SortDirection;
623
- default?: SortDirection;
638
+ direction?: SortDirection | undefined;
639
+ default?: SortDirection | undefined;
624
640
  label: string;
625
641
  metadata: Record<string, any>;
626
642
  name: string;
@@ -650,6 +666,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
650
666
  isSelected: (record: RecordType) => boolean;
651
667
  allSelected: boolean;
652
668
  selection: BulkSelection<RecordIdentifier>;
669
+ bindCheckbox: (key: RecordIdentifier) => {
670
+ onChange: (event: Event) => void;
671
+ checked: boolean;
672
+ value: RecordIdentifier;
673
+ };
653
674
  toggle: (record: RecordType) => void;
654
675
  select: (record: RecordType) => void;
655
676
  deselect: (record: RecordType) => void;
@@ -951,4 +972,4 @@ declare const RouterLink: vue.DefineComponent<{
951
972
  preload: boolean | "hover" | "mount";
952
973
  }, {}>;
953
974
 
954
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
975
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type TableDefaultOptions, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.mts CHANGED
@@ -94,13 +94,13 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
94
94
  progress: {
95
95
  readonly event: {
96
96
  readonly loaded: number;
97
- readonly total?: number;
98
- readonly progress?: number;
97
+ readonly total?: number | undefined;
98
+ readonly progress?: number | undefined;
99
99
  readonly bytes: number;
100
- readonly rate?: number;
101
- readonly estimated?: number;
102
- readonly upload?: boolean;
103
- readonly download?: boolean;
100
+ readonly rate?: number | undefined;
101
+ readonly estimated?: number | undefined;
102
+ readonly upload?: boolean | undefined;
103
+ readonly download?: boolean | undefined;
104
104
  readonly event?: any;
105
105
  readonly lengthComputable: boolean;
106
106
  };
@@ -544,6 +544,11 @@ declare function useBulkSelect<T = any>(): {
544
544
  toggle: (record: T, force?: boolean) => void;
545
545
  selected: (record: T) => boolean;
546
546
  selection: Ref<BulkSelection<T>>;
547
+ bindCheckbox: (key: T) => {
548
+ onChange: (event: Event) => void;
549
+ checked: boolean;
550
+ value: T;
551
+ };
547
552
  };
548
553
 
549
554
  declare global {
@@ -597,10 +602,21 @@ type AsRecordType<T extends Record<string, any>> = {
597
602
  value: T[K];
598
603
  };
599
604
  };
605
+ interface TableDefaultOptions extends AvailableHybridRequestOptions {
606
+ /**
607
+ * Whether to include existing query parameters in the request.
608
+ * @default true
609
+ */
610
+ includeQueryParameters?: boolean;
611
+ /**
612
+ * Additionnal data to send with the requests.
613
+ */
614
+ data?: Record<string, FormDataConvertible> | FormDataConvertible;
615
+ }
600
616
  /**
601
617
  * Provides utilities for working with tables.
602
618
  */
603
- declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: AvailableHybridRequestOptions): {
619
+ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: TableDefaultOptions): {
604
620
  bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T>;
605
621
  filters: {
606
622
  apply: (value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
@@ -619,8 +635,8 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
619
635
  isSorting: (direction?: SortDirection) => boolean;
620
636
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
621
637
  is_active: boolean;
622
- direction?: SortDirection;
623
- default?: SortDirection;
638
+ direction?: SortDirection | undefined;
639
+ default?: SortDirection | undefined;
624
640
  label: string;
625
641
  metadata: Record<string, any>;
626
642
  name: string;
@@ -650,6 +666,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
650
666
  isSelected: (record: RecordType) => boolean;
651
667
  allSelected: boolean;
652
668
  selection: BulkSelection<RecordIdentifier>;
669
+ bindCheckbox: (key: RecordIdentifier) => {
670
+ onChange: (event: Event) => void;
671
+ checked: boolean;
672
+ value: RecordIdentifier;
673
+ };
653
674
  toggle: (record: RecordType) => void;
654
675
  select: (record: RecordType) => void;
655
676
  deselect: (record: RecordType) => void;
@@ -951,4 +972,4 @@ declare const RouterLink: vue.DefineComponent<{
951
972
  preload: boolean | "hover" | "mount";
952
973
  }, {}>;
953
974
 
954
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
975
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type TableDefaultOptions, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.ts CHANGED
@@ -94,13 +94,13 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
94
94
  progress: {
95
95
  readonly event: {
96
96
  readonly loaded: number;
97
- readonly total?: number;
98
- readonly progress?: number;
97
+ readonly total?: number | undefined;
98
+ readonly progress?: number | undefined;
99
99
  readonly bytes: number;
100
- readonly rate?: number;
101
- readonly estimated?: number;
102
- readonly upload?: boolean;
103
- readonly download?: boolean;
100
+ readonly rate?: number | undefined;
101
+ readonly estimated?: number | undefined;
102
+ readonly upload?: boolean | undefined;
103
+ readonly download?: boolean | undefined;
104
104
  readonly event?: any;
105
105
  readonly lengthComputable: boolean;
106
106
  };
@@ -544,6 +544,11 @@ declare function useBulkSelect<T = any>(): {
544
544
  toggle: (record: T, force?: boolean) => void;
545
545
  selected: (record: T) => boolean;
546
546
  selection: Ref<BulkSelection<T>>;
547
+ bindCheckbox: (key: T) => {
548
+ onChange: (event: Event) => void;
549
+ checked: boolean;
550
+ value: T;
551
+ };
547
552
  };
548
553
 
549
554
  declare global {
@@ -597,10 +602,21 @@ type AsRecordType<T extends Record<string, any>> = {
597
602
  value: T[K];
598
603
  };
599
604
  };
605
+ interface TableDefaultOptions extends AvailableHybridRequestOptions {
606
+ /**
607
+ * Whether to include existing query parameters in the request.
608
+ * @default true
609
+ */
610
+ includeQueryParameters?: boolean;
611
+ /**
612
+ * Additionnal data to send with the requests.
613
+ */
614
+ data?: Record<string, FormDataConvertible> | FormDataConvertible;
615
+ }
600
616
  /**
601
617
  * Provides utilities for working with tables.
602
618
  */
603
- declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: AvailableHybridRequestOptions): {
619
+ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: TableDefaultOptions): {
604
620
  bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T>;
605
621
  filters: {
606
622
  apply: (value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
@@ -619,8 +635,8 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
619
635
  isSorting: (direction?: SortDirection) => boolean;
620
636
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
621
637
  is_active: boolean;
622
- direction?: SortDirection;
623
- default?: SortDirection;
638
+ direction?: SortDirection | undefined;
639
+ default?: SortDirection | undefined;
624
640
  label: string;
625
641
  metadata: Record<string, any>;
626
642
  name: string;
@@ -650,6 +666,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
650
666
  isSelected: (record: RecordType) => boolean;
651
667
  allSelected: boolean;
652
668
  selection: BulkSelection<RecordIdentifier>;
669
+ bindCheckbox: (key: RecordIdentifier) => {
670
+ onChange: (event: Event) => void;
671
+ checked: boolean;
672
+ value: RecordIdentifier;
673
+ };
653
674
  toggle: (record: RecordType) => void;
654
675
  select: (record: RecordType) => void;
655
676
  deselect: (record: RecordType) => void;
@@ -951,4 +972,4 @@ declare const RouterLink: vue.DefineComponent<{
951
972
  preload: boolean | "hover" | "mount";
952
973
  }, {}>;
953
974
 
954
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
975
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type TableDefaultOptions, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.mjs CHANGED
@@ -193,7 +193,10 @@ const wrapper = defineComponent({
193
193
  function renderLayout(view) {
194
194
  debug.adapter("vue:render:layout", "Rendering layout.");
195
195
  if (typeof state.view.value?.layout === "function") {
196
- return state.view.value.layout(h, view, renderDialog());
196
+ return state.view.value.layout(h, view, renderDialog(), {
197
+ ...state.view.value?.properties ?? {},
198
+ ...state.properties.value
199
+ });
197
200
  }
198
201
  if (Array.isArray(state.view.value?.layout)) {
199
202
  const layoutsAndView = state.view.value.layout.concat(view).reverse().reduce((child, layout) => {
@@ -993,7 +996,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
993
996
  async function applyFilter(name, value, options = {}) {
994
997
  const filter = getFilter(name);
995
998
  if (!filter) {
996
- console.warn(`[Refinement] Filter "${name} does not exist."`);
999
+ console.warn(`[Refinement] Filter "${name}" does not exist.`);
997
1000
  return;
998
1001
  }
999
1002
  if (["", null].includes(value) || value === filter.default) {
@@ -1039,7 +1042,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1039
1042
  async function toggleSort(name, options) {
1040
1043
  const sort = getSort(name);
1041
1044
  if (!sort) {
1042
- console.warn(`[Refinement] Sort "${name} does not exist."`);
1045
+ console.warn(`[Refinement] Sort "${name}" does not exist.`);
1043
1046
  return;
1044
1047
  }
1045
1048
  const next = options?.direction ? sort[options?.direction] : sort.next;
@@ -1238,6 +1241,20 @@ function useBulkSelect() {
1238
1241
  const allSelected = computed(() => {
1239
1242
  return selection.value.all && selection.value.except.size === 0;
1240
1243
  });
1244
+ function bindCheckbox(key) {
1245
+ return {
1246
+ onChange: (event) => {
1247
+ const target = event.target;
1248
+ if (target.checked) {
1249
+ select(target.value);
1250
+ } else {
1251
+ deselect(target.value);
1252
+ }
1253
+ },
1254
+ checked: selected(key),
1255
+ value: key
1256
+ };
1257
+ }
1241
1258
  return {
1242
1259
  allSelected,
1243
1260
  selectAll,
@@ -1246,20 +1263,70 @@ function useBulkSelect() {
1246
1263
  deselect,
1247
1264
  toggle,
1248
1265
  selected,
1249
- selection
1266
+ selection,
1267
+ bindCheckbox
1250
1268
  };
1251
1269
  }
1252
1270
 
1271
+ function useQueryParameters() {
1272
+ const state = reactive({});
1273
+ function updateState() {
1274
+ const params = new URLSearchParams(window.location.search);
1275
+ const unusedKeys = new Set(Object.keys(state));
1276
+ for (const key of params.keys()) {
1277
+ const paramsForKey = params.getAll(key);
1278
+ state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1279
+ unusedKeys.delete(key);
1280
+ }
1281
+ Array.from(unusedKeys).forEach((key) => delete state[key]);
1282
+ }
1283
+ updateState();
1284
+ registerHook$1("after", updateState);
1285
+ return state;
1286
+ }
1287
+ function useQueryParameter(name, options = {}) {
1288
+ const query = useQueryParameters();
1289
+ const transform = (value2) => {
1290
+ if (options.transform === "bool") {
1291
+ return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1292
+ } else if (options.transform === "number") {
1293
+ return Number(value2);
1294
+ } else if (options.transform === "string") {
1295
+ return String(value2);
1296
+ } else if (options.transform === "date") {
1297
+ return new Date(value2);
1298
+ } else if (typeof options.transform === "function") {
1299
+ return options.transform(value2);
1300
+ }
1301
+ return value2;
1302
+ };
1303
+ const value = ref();
1304
+ watch(query, () => {
1305
+ value.value = transform(query[name] ?? toValue(options.defaultValue));
1306
+ }, { deep: true, immediate: true });
1307
+ return value;
1308
+ }
1309
+
1253
1310
  function useTable(props, key, defaultOptions = {}) {
1254
1311
  const table = computed(() => props[key]);
1255
1312
  const bulk = useBulkSelect();
1256
1313
  const refinements = useRefinements(toReactive(table), "refinements", defaultOptions);
1314
+ function getAdditionnalData() {
1315
+ const data = {};
1316
+ if (defaultOptions?.includeQueryParameters !== false) {
1317
+ Object.assign(data, structuredClone(toRaw(useQueryParameters())));
1318
+ }
1319
+ if (defaultOptions?.data) {
1320
+ Object.assign(data, defaultOptions.data);
1321
+ }
1322
+ return data;
1323
+ }
1257
1324
  function getRecordKey(record) {
1258
1325
  if (typeof record !== "object") {
1259
1326
  return record;
1260
1327
  }
1261
1328
  if (Reflect.has(record, "__hybridId")) {
1262
- return Reflect.get(record, "__hybridId").value;
1329
+ return Reflect.get(record, "__hybridId");
1263
1330
  }
1264
1331
  return Reflect.get(record, table.value.keyName).value;
1265
1332
  }
@@ -1272,6 +1339,7 @@ function useTable(props, key, defaultOptions = {}) {
1272
1339
  url: route(table.value.endpoint),
1273
1340
  preserveState: true,
1274
1341
  data: {
1342
+ ...getAdditionnalData(),
1275
1343
  type: "action:inline",
1276
1344
  action: getActionName(action),
1277
1345
  tableId: table.value.id,
@@ -1292,6 +1360,7 @@ function useTable(props, key, defaultOptions = {}) {
1292
1360
  url: route(table.value.endpoint),
1293
1361
  preserveState: true,
1294
1362
  data: {
1363
+ ...getAdditionnalData(),
1295
1364
  type: "action:bulk",
1296
1365
  action: actionName,
1297
1366
  tableId: table.value.id,
@@ -1326,6 +1395,8 @@ function useTable(props, key, defaultOptions = {}) {
1326
1395
  allSelected: bulk.allSelected,
1327
1396
  /** The current record selection. */
1328
1397
  selection: bulk.selection,
1398
+ /** Binds a checkbox to its selection state. */
1399
+ bindCheckbox: (key2) => bulk.bindCheckbox(key2),
1329
1400
  /** Toggles selection for the given record. */
1330
1401
  toggle: (record) => bulk.toggle(getRecordKey(record)),
1331
1402
  /** Selects selection for the given record. */
@@ -1399,43 +1470,4 @@ function useTable(props, key, defaultOptions = {}) {
1399
1470
  });
1400
1471
  }
1401
1472
 
1402
- function useQueryParameters() {
1403
- const state = reactive({});
1404
- function updateState() {
1405
- const params = new URLSearchParams(window.location.search);
1406
- const unusedKeys = new Set(Object.keys(state));
1407
- for (const key of params.keys()) {
1408
- const paramsForKey = params.getAll(key);
1409
- state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1410
- unusedKeys.delete(key);
1411
- }
1412
- Array.from(unusedKeys).forEach((key) => delete state[key]);
1413
- }
1414
- updateState();
1415
- registerHook$1("after", updateState);
1416
- return state;
1417
- }
1418
- function useQueryParameter(name, options = {}) {
1419
- const query = useQueryParameters();
1420
- const transform = (value2) => {
1421
- if (options.transform === "bool") {
1422
- return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1423
- } else if (options.transform === "number") {
1424
- return Number(value2);
1425
- } else if (options.transform === "string") {
1426
- return String(value2);
1427
- } else if (options.transform === "date") {
1428
- return new Date(value2);
1429
- } else if (typeof options.transform === "function") {
1430
- return options.transform(value2);
1431
- }
1432
- return value2;
1433
- };
1434
- const value = ref();
1435
- watch(query, () => {
1436
- value.value = transform(query[name] ?? toValue(options.defaultValue));
1437
- }, { deep: true, immediate: true });
1438
- return value;
1439
- }
1440
-
1441
1473
  export { RouterLink, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hybridly/vue",
3
3
  "type": "module",
4
- "version": "0.7.13",
4
+ "version": "0.7.14",
5
5
  "description": "Vue adapter for Hybridly",
6
6
  "author": "Enzo Innocenzi <enzo@innocenzi.dev>",
7
7
  "license": "MIT",
@@ -43,22 +43,22 @@
43
43
  "vue": "^3.2.45"
44
44
  },
45
45
  "dependencies": {
46
- "@clickbar/dot-diver": "^1.0.6",
47
- "@vue/devtools-api": "^7.3.5",
46
+ "@clickbar/dot-diver": "^1.0.7",
47
+ "@vue/devtools-api": "^7.3.8",
48
48
  "defu": "^6.1.4",
49
49
  "lodash.isequal": "^4.5.0",
50
50
  "nprogress": "^0.2.0",
51
- "qs": "^6.12.1",
52
- "@hybridly/utils": "0.7.13",
53
- "@hybridly/core": "0.7.13"
51
+ "qs": "^6.13.0",
52
+ "@hybridly/core": "0.7.14",
53
+ "@hybridly/utils": "0.7.14"
54
54
  },
55
55
  "devDependencies": {
56
- "@types/lodash": "^4.17.6",
56
+ "@types/lodash": "^4.17.7",
57
57
  "@types/lodash.isequal": "^4.5.8",
58
58
  "@types/nprogress": "^0.2.3",
59
59
  "@vue/test-utils": "^2.4.6",
60
- "axios": "^1.7.2",
61
- "vue": "^3.4.31"
60
+ "axios": "^1.7.4",
61
+ "vue": "^3.4.38"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "unbuild",