@hybridly/vue 0.10.0-beta.25 → 0.10.0-beta.27
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.d.mts +158 -102
- package/dist/index.mjs +99 -36
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FormDataConvertible, Path, PathValue, RequestData, SearchableObject } from "@hybridly/utils";
|
|
2
2
|
import * as vue from "vue";
|
|
3
3
|
import { App, Component, ComputedRef, DeepReadonly, DefineComponent, MaybeRefOrGetter, Plugin, PropType, Ref, SlotsType, h } from "vue";
|
|
4
|
+
import * as _hybridly_core0 from "@hybridly/core";
|
|
4
5
|
import { Errors, GlobalHybridlyProperties, HttpClient, HybridRequestOptions, Method, NavigationResponse, Plugin as Plugin$1, Progress, RequestMode, RouteName, RouteParameters, RouterContext, RouterContextOptions, UrlResolvable, Validation, registerHook as registerHook$1, route, router } from "@hybridly/core";
|
|
5
6
|
import { Path as Path$1, SearchableObject as SearchableObject$1 } from "@clickbar/dot-diver";
|
|
6
7
|
|
|
@@ -33,10 +34,8 @@ declare const Deferred: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
33
34
|
type Errors$1<T extends SearchableObject$1> = { [K in keyof T]?: T[K] extends Record<string, any> ? Errors$1<T[K]> : string };
|
|
34
35
|
type FormFieldBehavior$1 = boolean | string[];
|
|
35
36
|
type DefaultFormOptions = Pick<FormOptions<object>, 'timeout' | 'resetOnSuccess' | 'resetOnError' | 'setDefaultOnSuccess' | 'progress' | 'preserveScroll' | 'preserveState' | 'preserveUrl' | 'headers' | 'errorBag' | 'spoof' | 'transformUrl' | 'updateHistoryState' | 'useFormData'>;
|
|
36
|
-
|
|
37
|
-
fields: T;
|
|
37
|
+
type FormSubmitOptions$1<T extends SearchableObject$1> = Omit<HybridRequestOptions, 'data' | 'url' | 'reset'> & {
|
|
38
38
|
url?: UrlResolvable | (() => UrlResolvable);
|
|
39
|
-
key?: string | false;
|
|
40
39
|
/**
|
|
41
40
|
* Defines the delay after which the `recentlySuccessful` and `recentlyFailed` variables are reset to `false`.
|
|
42
41
|
*/
|
|
@@ -60,6 +59,27 @@ interface FormOptions<T extends SearchableObject$1> extends Omit<HybridRequestOp
|
|
|
60
59
|
* Callback executed before the form submission for transforming the fields.
|
|
61
60
|
*/
|
|
62
61
|
transform?: (fields: T) => any;
|
|
62
|
+
};
|
|
63
|
+
type FormAutomaticallySubmitOptions<T extends SearchableObject$1> = true | (FormSubmitOptions$1<T> & {
|
|
64
|
+
/**
|
|
65
|
+
* Debounce delay in milliseconds before submitting automatically.
|
|
66
|
+
* @default 100
|
|
67
|
+
*/
|
|
68
|
+
debounce?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Whether to immediately submit the form on any change. If `false`, submits after the `debounce` delay.
|
|
71
|
+
* @default true
|
|
72
|
+
*/
|
|
73
|
+
immediate?: boolean;
|
|
74
|
+
});
|
|
75
|
+
interface FormOptions<T extends SearchableObject$1> extends FormSubmitOptions$1<T> {
|
|
76
|
+
fields: T;
|
|
77
|
+
key?: string | false;
|
|
78
|
+
/**
|
|
79
|
+
* Automatically submits the form when fields change.
|
|
80
|
+
* Pass `true` to use defaults or an object to customize submit overrides and debounce delay.
|
|
81
|
+
*/
|
|
82
|
+
automaticallySubmit?: FormAutomaticallySubmitOptions<T>;
|
|
63
83
|
}
|
|
64
84
|
interface FormReturn<T extends SearchableObject$1, P extends Path$1<T> & string = Path$1<T> & string> {
|
|
65
85
|
resetFields: (...keys: P[]) => void;
|
|
@@ -73,7 +93,7 @@ interface FormReturn<T extends SearchableObject$1, P extends Path$1<T> & string
|
|
|
73
93
|
clearError: (key: P) => void;
|
|
74
94
|
setDefault: (newDefault: Partial<T>) => void;
|
|
75
95
|
hasDirty: (...keys: P[]) => boolean;
|
|
76
|
-
submit: (optionsOverrides?:
|
|
96
|
+
submit: (optionsOverrides?: FormSubmitOptions$1<T>) => Promise<any>;
|
|
77
97
|
hasErrors: boolean;
|
|
78
98
|
defaults: DeepReadonly<T>;
|
|
79
99
|
loaded: DeepReadonly<T>;
|
|
@@ -324,6 +344,14 @@ interface BulkSelection<T = any> {
|
|
|
324
344
|
/** Excluded records. */
|
|
325
345
|
except: Set<T>;
|
|
326
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Returns the inclusive range between two records in the given order.
|
|
349
|
+
*
|
|
350
|
+
* This is useful for implementing shift-click bulk selection: keep track of the last selected anchor,
|
|
351
|
+
* then pass the currently visible record identifiers and the clicked target identifier to this helper.
|
|
352
|
+
* If the target is not in the list, an empty range is returned. If the anchor is missing, only the target is returned.
|
|
353
|
+
*/
|
|
354
|
+
declare function getBulkSelectionRange<T>(records: readonly T[], anchor: T | undefined, target: T): T[];
|
|
327
355
|
declare function useBulkSelect<T = any>(): {
|
|
328
356
|
allSelected: vue.ComputedRef<boolean>;
|
|
329
357
|
anySelected: vue.ComputedRef<boolean>;
|
|
@@ -1049,19 +1077,18 @@ declare function useRefinements<T extends Refinements>(input: MaybeRefOrGetter<T
|
|
|
1049
1077
|
declare const registerHook: typeof registerHook$1;
|
|
1050
1078
|
//#endregion
|
|
1051
1079
|
//#region src/composables/table.d.ts
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1080
|
+
interface Table<T extends Record<string, any> = any, PaginatorKind extends 'cursor' | 'length-aware' | 'simple' = 'length-aware'> {
|
|
1081
|
+
id: string;
|
|
1082
|
+
keyName: keyof T | null;
|
|
1083
|
+
scope?: string;
|
|
1084
|
+
columns: Column<T>[];
|
|
1085
|
+
inlineActions: InlineAction[];
|
|
1086
|
+
bulkActions: BulkAction[];
|
|
1087
|
+
records: Array<T>;
|
|
1088
|
+
cells: TableCellRow<T>[];
|
|
1089
|
+
paginator: Omit<PaginatorKind extends 'cursor' ? CursorPaginator<T> : (PaginatorKind extends 'simple' ? SimplePaginator<T> : Paginator<T>), 'data'>;
|
|
1090
|
+
refinements: Refinements;
|
|
1091
|
+
endpoint: string;
|
|
1065
1092
|
}
|
|
1066
1093
|
interface Column<T extends object = never> {
|
|
1067
1094
|
/** The name of this column. */
|
|
@@ -1073,6 +1100,14 @@ interface Column<T extends object = never> {
|
|
|
1073
1100
|
/** Metadata of this column. */
|
|
1074
1101
|
metadata: Record<string, any>;
|
|
1075
1102
|
}
|
|
1103
|
+
interface TableCell<T extends object = never> {
|
|
1104
|
+
value: any;
|
|
1105
|
+
extra: Record<string, any>;
|
|
1106
|
+
}
|
|
1107
|
+
interface TableCellRow<T extends object = never> {
|
|
1108
|
+
key: RecordIdentifier | null;
|
|
1109
|
+
columns: Partial<Record<keyof T | string, TableCell<T>>>;
|
|
1110
|
+
}
|
|
1076
1111
|
interface Action {
|
|
1077
1112
|
/** The name of this action. */
|
|
1078
1113
|
name: string;
|
|
@@ -1093,15 +1128,8 @@ interface BulkActionOptions extends Omit<HybridRequestOptions, 'url'> {
|
|
|
1093
1128
|
/** Force deselecting all records after action. */
|
|
1094
1129
|
deselect?: boolean;
|
|
1095
1130
|
}
|
|
1096
|
-
interface InlineActionOptions<T> extends Omit<HybridRequestOptions, 'url'> {
|
|
1097
|
-
record: T;
|
|
1098
|
-
}
|
|
1099
1131
|
interface InlineAction extends Action {}
|
|
1100
1132
|
type RecordIdentifier = string | number;
|
|
1101
|
-
type AsRecordTypeWithExtra<T extends Record<string, any>> = { [K in keyof T]: {
|
|
1102
|
-
extra: Record<string, any>;
|
|
1103
|
-
value: T[K];
|
|
1104
|
-
} };
|
|
1105
1133
|
interface TableDefaultOptions extends AvailableHybridRequestOptions {
|
|
1106
1134
|
/**
|
|
1107
1135
|
* Whether to include existing query parameters in the request.
|
|
@@ -1113,98 +1141,126 @@ interface TableDefaultOptions extends AvailableHybridRequestOptions {
|
|
|
1113
1141
|
*/
|
|
1114
1142
|
data?: Record<string, FormDataConvertible> | FormDataConvertible;
|
|
1115
1143
|
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1144
|
+
type UseTableNavigationResponse = Promise<_hybridly_core0.NavigationResponse | undefined>;
|
|
1145
|
+
type ExtractRefValue<T> = T extends {
|
|
1146
|
+
value: infer Value;
|
|
1147
|
+
} ? Value : T;
|
|
1148
|
+
interface UseTableInlineActionItem<RecordType extends Record<string, any>> extends InlineAction {
|
|
1149
|
+
/** Executes the action. */
|
|
1150
|
+
execute: (record: RecordIdentifier | RecordType) => UseTableNavigationResponse;
|
|
1151
|
+
}
|
|
1152
|
+
interface UseTableBulkActionItem extends BulkAction {
|
|
1153
|
+
/** Executes the action. */
|
|
1154
|
+
execute: (options?: BulkActionOptions) => UseTableNavigationResponse;
|
|
1155
|
+
}
|
|
1156
|
+
interface UseTableColumn<RecordType extends Record<string, any>> extends Column<RecordType> {
|
|
1157
|
+
/** Toggles sorting for this column. */
|
|
1158
|
+
toggleSort: (options?: ToggleSortOptions) => UseTableNavigationResponse;
|
|
1159
|
+
/** Checks whether the column is being sorted. */
|
|
1160
|
+
isSorting: (direction?: SortDirection) => boolean;
|
|
1161
|
+
/** Applies the filter for this column. */
|
|
1162
|
+
applyFilter: (value: any, options?: AvailableHybridRequestOptions) => UseTableNavigationResponse;
|
|
1163
|
+
/** Clears the filter for this column. */
|
|
1164
|
+
clearFilter: (options?: AvailableHybridRequestOptions) => UseTableNavigationResponse;
|
|
1165
|
+
/** Checks whether the column is sortable. */
|
|
1166
|
+
isSortable: boolean;
|
|
1167
|
+
/** Checks whether the column is filterable. */
|
|
1168
|
+
isFilterable: boolean;
|
|
1169
|
+
}
|
|
1170
|
+
interface UseTableRecordItem<RecordType extends Record<string, any>> {
|
|
1171
|
+
/** The actual record. */
|
|
1172
|
+
record: RecordType;
|
|
1173
|
+
/** Local key of the record. Use this as a rendering key. */
|
|
1174
|
+
key: RecordIdentifier;
|
|
1175
|
+
/** Server-side key of the record, if any. */
|
|
1176
|
+
recordKey: RecordIdentifier | undefined;
|
|
1177
|
+
/** Whether this record has a server-side key. */
|
|
1178
|
+
hasKey: boolean;
|
|
1179
|
+
/** Executes the given inline action. */
|
|
1180
|
+
execute: (action: string | InlineAction) => UseTableNavigationResponse;
|
|
1181
|
+
/** Gets the available inline actions. */
|
|
1182
|
+
actions: Array<InlineAction & {
|
|
1183
|
+
execute: () => UseTableNavigationResponse;
|
|
1184
|
+
}>;
|
|
1185
|
+
/** Selects this record. */
|
|
1186
|
+
select: () => void;
|
|
1187
|
+
/** Deselects this record. */
|
|
1188
|
+
deselect: () => void;
|
|
1189
|
+
/** Toggles the selection for this record. */
|
|
1190
|
+
toggle: (force?: boolean) => void;
|
|
1191
|
+
/** Checks whether this record is selected. */
|
|
1192
|
+
selected: boolean;
|
|
1193
|
+
/** Gets the value of the record for the specified column. */
|
|
1194
|
+
value: (column: string | Column<RecordType>) => any;
|
|
1195
|
+
/** Gets the extra object of the record for the specified column. */
|
|
1196
|
+
extra: (column: string | Column<RecordType>, path: string) => any;
|
|
1197
|
+
}
|
|
1198
|
+
interface UseTableReturn<T extends Table<any, any>, RecordType extends Record<string, any> = (T extends Table<infer R, any> ? R : any), PaginatorKind extends 'cursor' | 'length-aware' | 'simple' = (T extends Table<any, infer P> ? P : 'length-aware')> extends Omit<UseRefinements, 'filters' | 'sorts' | 'filtersKey' | 'sortsKey'> {
|
|
1199
|
+
/** Selects all records. */
|
|
1137
1200
|
selectAll: () => void;
|
|
1201
|
+
/** Deselects all records. */
|
|
1138
1202
|
deselectAll: () => void;
|
|
1203
|
+
/** Selects records on the current page. */
|
|
1139
1204
|
selectPage: () => void;
|
|
1205
|
+
/** Deselects records on the current page. */
|
|
1140
1206
|
deselectPage: () => void;
|
|
1207
|
+
/** Whether all records on the current page are selected. */
|
|
1141
1208
|
isPageSelected: boolean;
|
|
1142
|
-
|
|
1209
|
+
/** Checks if the given record is selected. */
|
|
1210
|
+
isSelected: (record: RecordType) => boolean;
|
|
1211
|
+
/** Whether all records are selected. */
|
|
1143
1212
|
allSelected: boolean;
|
|
1213
|
+
/** Whether any records are selected. */
|
|
1144
1214
|
anySelected: boolean;
|
|
1215
|
+
/** The current record selection. */
|
|
1145
1216
|
selection: BulkSelection<RecordIdentifier>;
|
|
1217
|
+
/** Binds a checkbox to its selection state. */
|
|
1146
1218
|
bindCheckbox: (key: RecordIdentifier) => {
|
|
1147
1219
|
onChange: (event: Event) => void;
|
|
1148
1220
|
checked: boolean;
|
|
1149
1221
|
value: RecordIdentifier;
|
|
1150
1222
|
};
|
|
1151
|
-
|
|
1223
|
+
/** Toggles selection for the given record. */
|
|
1224
|
+
toggle: (record: RecordType, force?: boolean) => void;
|
|
1225
|
+
/** Toggles selection for all records. */
|
|
1152
1226
|
toggleAll: (force?: boolean) => void;
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
executeInlineAction: (action: InlineAction | string, options: InlineActionOptions<RecordTypeWithExtra | RecordIdentifier | RecordType>) => Promise<index_d_exports.NavigationResponse | undefined>;
|
|
1173
|
-
executeBulkAction: (action: BulkAction | string, options?: BulkActionOptions) => Promise<index_d_exports.NavigationResponse | undefined>;
|
|
1174
|
-
columns: {
|
|
1175
|
-
/** Toggles sorting for this column. */toggleSort: (options?: ToggleSortOptions) => Promise<index_d_exports.NavigationResponse | undefined>; /** Checks whether the column is being sorted. */
|
|
1176
|
-
isSorting: (direction?: SortDirection) => boolean; /** Applies the filer for this column. */
|
|
1177
|
-
applyFilter: (value: any, options?: AvailableHybridRequestOptions) => Promise<index_d_exports.NavigationResponse | undefined>; /** Clears the filter for this column. */
|
|
1178
|
-
clearFilter: (options?: AvailableHybridRequestOptions) => Promise<index_d_exports.NavigationResponse>; /** Checks whether the column is sortable. */
|
|
1179
|
-
isSortable: boolean; /** Checks whether the column is filterable. */
|
|
1180
|
-
isFilterable: boolean; /** The name of this column. */
|
|
1181
|
-
name: keyof RecordTypeWithExtra; /** The label of this column. */
|
|
1182
|
-
label: string; /** The type of this column. */
|
|
1183
|
-
type: string; /** Metadata of this column. */
|
|
1184
|
-
metadata: Record<string, any>;
|
|
1185
|
-
}[];
|
|
1227
|
+
/** Selects selection for the given record. */
|
|
1228
|
+
select: (record: RecordType) => void;
|
|
1229
|
+
/** Deselects selection for the given record. */
|
|
1230
|
+
deselect: (record: RecordType) => void;
|
|
1231
|
+
/** List of inline actions for this table. */
|
|
1232
|
+
inlineActions: Array<UseTableInlineActionItem<RecordType>>;
|
|
1233
|
+
/** List of bulk actions for this table. */
|
|
1234
|
+
bulkActions: Array<UseTableBulkActionItem>;
|
|
1235
|
+
/** Executes the given inline action for the given record. */
|
|
1236
|
+
executeInlineAction: (action: InlineAction | string, options: {
|
|
1237
|
+
record: RecordIdentifier | RecordType;
|
|
1238
|
+
} & Omit<HybridRequestOptions, 'url'>) => UseTableNavigationResponse;
|
|
1239
|
+
/** Executes the given bulk action. */
|
|
1240
|
+
executeBulkAction: (action: BulkAction | string, options?: Omit<HybridRequestOptions, 'url'> & {
|
|
1241
|
+
deselect?: boolean;
|
|
1242
|
+
}) => UseTableNavigationResponse;
|
|
1243
|
+
/** List of columns for this table. */
|
|
1244
|
+
columns: Array<UseTableColumn<RecordType>>;
|
|
1245
|
+
/** List of records for this table. */
|
|
1186
1246
|
data: RecordType[];
|
|
1187
|
-
records
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
extra: (column: string | Column<RecordTypeWithExtra>, path: string) => any;
|
|
1205
|
-
}[];
|
|
1206
|
-
paginator: PaginatorResult<unknown, Omit<PaginatorKind extends "cursor" ? CursorPaginator<RecordTypeWithExtra> : PaginatorKind extends "simple" ? SimplePaginator<RecordTypeWithExtra> : Paginator<RecordTypeWithExtra>, "data">>;
|
|
1207
|
-
};
|
|
1247
|
+
/** List of records for this table. */
|
|
1248
|
+
records: Array<UseTableRecordItem<RecordType>>;
|
|
1249
|
+
/** Paginated meta and links. */
|
|
1250
|
+
paginator: PaginatorResult<RecordType, Table<RecordType, PaginatorKind>['paginator']>;
|
|
1251
|
+
/** Available filters. */
|
|
1252
|
+
filters: ExtractRefValue<UseRefinements['filters']>;
|
|
1253
|
+
/** Available sorts. */
|
|
1254
|
+
sorts: ExtractRefValue<UseRefinements['sorts']>;
|
|
1255
|
+
/** The key for the filters. */
|
|
1256
|
+
filtersKey: ExtractRefValue<UseRefinements['filtersKey']>;
|
|
1257
|
+
/** The key for the sorts. */
|
|
1258
|
+
sortsKey: ExtractRefValue<UseRefinements['sortsKey']>;
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* Provides utilities for working with tables.
|
|
1262
|
+
*/
|
|
1263
|
+
declare function useTable<T extends Table<any, any>, RecordType extends Record<string, any> = (T extends Table<infer R, any> ? R : any), PaginatorKind extends 'cursor' | 'length-aware' | 'simple' = (T extends Table<any, infer P> ? P : 'length-aware')>(input: MaybeRefOrGetter<T>, defaultOptions?: TableDefaultOptions): UseTableReturn<T, RecordType, PaginatorKind>;
|
|
1208
1264
|
//#endregion
|
|
1209
1265
|
//#region src/composables/validation.d.ts
|
|
1210
1266
|
/** Accesses all validation errors grouped by bag name. */
|
|
@@ -1302,4 +1358,4 @@ interface SetupArguments {
|
|
|
1302
1358
|
payload: Record<string, any>;
|
|
1303
1359
|
}
|
|
1304
1360
|
//#endregion
|
|
1305
|
-
export { Action, AvailableHybridRequestOptions, AvailableHybridRequestOptionsForFilters, BaseFilterRefinement, BindFilterOptions, BooleanFilterRefinement, BoundBooleanFilterRefinement, BoundCallbackFilterRefinement, BoundDateFilterRefinement, BoundFilterRefinement, BoundSelectFilterRefinement, BoundSortRefinement, BoundTernaryFilterRefinement, BoundTextFilterRefinement, BoundTrashedFilterRefinement, BulkAction, BulkSelection, CallbackFilterRefinement, Column, DateFilterRefinement, DefaultFormOptions, Deferred, FilterOperator, FilterRefinement, Form, type FormProps, FormReturn, type FormSlotProps, type FormSubmitOptions, type InitializeOptions, InlineAction, InternalProperties, MaybeWithData, NumericFilterRefinement, PaginatorResult, RecordIdentifier, Refinements, RouterLink, SelectFilterRefinement, SortDirection, SortRefinement, TableDefaultOptions, TernaryFilterRefinement, TextFilterRefinement, TimeSuggestion, TimeframeSuggestion, ToggleSortOptions, TrashedFilterRefinement, UseRefinements, WhenVisible, createPaginator, initializeHybridly, isBooleanFilter, isCallbackFilter, isDateFilter, isSelectFilter, isTernaryFilter, isTextFilter, isTrashedFilter, registerHook, route, router, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable, useValidation, useValidationBag };
|
|
1361
|
+
export { Action, AvailableHybridRequestOptions, AvailableHybridRequestOptionsForFilters, BaseFilterRefinement, BindFilterOptions, BooleanFilterRefinement, BoundBooleanFilterRefinement, BoundCallbackFilterRefinement, BoundDateFilterRefinement, BoundFilterRefinement, BoundSelectFilterRefinement, BoundSortRefinement, BoundTernaryFilterRefinement, BoundTextFilterRefinement, BoundTrashedFilterRefinement, BulkAction, BulkSelection, CallbackFilterRefinement, Column, DateFilterRefinement, DefaultFormOptions, Deferred, FilterOperator, FilterRefinement, Form, type FormProps, FormReturn, type FormSlotProps, type FormSubmitOptions, type InitializeOptions, InlineAction, InternalProperties, MaybeWithData, NumericFilterRefinement, PaginatorResult, RecordIdentifier, Refinements, RouterLink, SelectFilterRefinement, SortDirection, SortRefinement, Table, TableCell, TableCellRow, TableDefaultOptions, TernaryFilterRefinement, TextFilterRefinement, TimeSuggestion, TimeframeSuggestion, ToggleSortOptions, TrashedFilterRefinement, UseRefinements, UseTableBulkActionItem, UseTableColumn, UseTableInlineActionItem, UseTableRecordItem, UseTableReturn, WhenVisible, createPaginator, getBulkSelectionRange, initializeHybridly, isBooleanFilter, isCallbackFilter, isDateFilter, isSelectFilter, isTernaryFilter, isTextFilter, isTrashedFilter, registerHook, route, router, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable, useValidation, useValidationBag };
|
package/dist/index.mjs
CHANGED
|
@@ -3,11 +3,11 @@ import { debug, merge, random, showViewComponentErrorModal, wrap } from "@hybrid
|
|
|
3
3
|
import { computed, createApp, defineComponent, getCurrentInstance, h, isRef, nextTick, onMounted, onUnmounted, reactive, readonly, ref, shallowRef, toRaw, toValue, triggerRef, unref, watch } from "vue";
|
|
4
4
|
import { createRouter, definePlugin, makeUrl, parseQueryString, registerHook as registerHook$1, route, route as route$1, router, router as router$1, stringifyQueryString } from "@hybridly/core";
|
|
5
5
|
import { get, set, unset } from "es-toolkit/compat";
|
|
6
|
+
import { debounce } from "es-toolkit/function";
|
|
6
7
|
import { clone, cloneDeep } from "es-toolkit/object";
|
|
7
8
|
import { isEqual } from "es-toolkit/predicate";
|
|
8
9
|
import { setupDevtoolsPlugin } from "@vue/devtools-api";
|
|
9
10
|
import nprogress from "nprogress";
|
|
10
|
-
import { debounce } from "es-toolkit/function";
|
|
11
11
|
import { getByPath } from "@clickbar/dot-diver";
|
|
12
12
|
//#region src/stores/state.ts
|
|
13
13
|
const state = {
|
|
@@ -216,7 +216,7 @@ function useForm(options) {
|
|
|
216
216
|
* Submits the form.
|
|
217
217
|
*/
|
|
218
218
|
function submit(optionsOverrides) {
|
|
219
|
-
const { fields: _f, key: _k, ...optionsWithoutFields } = options;
|
|
219
|
+
const { fields: _f, key: _k, automaticallySubmit: _as, ...optionsWithoutFields } = options;
|
|
220
220
|
const resolvedOptions = optionsOverrides ? merge(optionsWithoutFields, optionsOverrides, { mergePlainObjects: true }) : optionsWithoutFields;
|
|
221
221
|
const { timeout, resetOnSuccess, resetOnError, setDefaultOnSuccess, transform, ...requestOptions } = merge(formStore.getDefaultConfig(), resolvedOptions, { mergePlainObjects: true });
|
|
222
222
|
const url = typeof requestOptions.url === "function" ? requestOptions.url() : requestOptions.url;
|
|
@@ -274,6 +274,23 @@ function useForm(options) {
|
|
|
274
274
|
}
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
|
+
if (options.automaticallySubmit) {
|
|
278
|
+
const submitOptions = options.automaticallySubmit === true ? void 0 : (() => {
|
|
279
|
+
const { debounce: _debounce, ...submitOptions } = options.automaticallySubmit;
|
|
280
|
+
return submitOptions;
|
|
281
|
+
})();
|
|
282
|
+
const automaticallySubmitOptions = options.automaticallySubmit === true ? {
|
|
283
|
+
debounce: 100,
|
|
284
|
+
immediate: true
|
|
285
|
+
} : options.automaticallySubmit;
|
|
286
|
+
watch(() => fields, debounce(() => {
|
|
287
|
+
if (!isDirty.value) return;
|
|
288
|
+
submit(submitOptions);
|
|
289
|
+
}, automaticallySubmitOptions.debounce ?? 100), {
|
|
290
|
+
deep: true,
|
|
291
|
+
immediate: automaticallySubmitOptions.immediate ?? true
|
|
292
|
+
});
|
|
293
|
+
}
|
|
277
294
|
/**
|
|
278
295
|
* Clears all errors.
|
|
279
296
|
*/
|
|
@@ -1373,6 +1390,21 @@ function useBackForward(options) {
|
|
|
1373
1390
|
}
|
|
1374
1391
|
//#endregion
|
|
1375
1392
|
//#region src/composables/bulk-select.ts
|
|
1393
|
+
/**
|
|
1394
|
+
* Returns the inclusive range between two records in the given order.
|
|
1395
|
+
*
|
|
1396
|
+
* This is useful for implementing shift-click bulk selection: keep track of the last selected anchor,
|
|
1397
|
+
* then pass the currently visible record identifiers and the clicked target identifier to this helper.
|
|
1398
|
+
* If the target is not in the list, an empty range is returned. If the anchor is missing, only the target is returned.
|
|
1399
|
+
*/
|
|
1400
|
+
function getBulkSelectionRange(records, anchor, target) {
|
|
1401
|
+
const targetIndex = records.indexOf(target);
|
|
1402
|
+
if (targetIndex === -1) return [];
|
|
1403
|
+
if (anchor === void 0) return [target];
|
|
1404
|
+
const anchorIndex = records.indexOf(anchor);
|
|
1405
|
+
if (anchorIndex === -1) return [target];
|
|
1406
|
+
return records.slice(Math.min(anchorIndex, targetIndex), Math.max(anchorIndex, targetIndex) + 1);
|
|
1407
|
+
}
|
|
1376
1408
|
function useBulkSelect() {
|
|
1377
1409
|
const selection = ref({
|
|
1378
1410
|
all: false,
|
|
@@ -1921,11 +1953,24 @@ function useTable(input, defaultOptions = {}) {
|
|
|
1921
1953
|
*/
|
|
1922
1954
|
function getRecordKey(record) {
|
|
1923
1955
|
if (typeof record !== "object") return record;
|
|
1924
|
-
if (
|
|
1925
|
-
if (!table.value.keyName) throw new Error("Record key cannot be fetched because the table has no defined key.");
|
|
1956
|
+
if (!table.value.keyName) return;
|
|
1926
1957
|
const value = Reflect.get(record, table.value.keyName);
|
|
1927
|
-
if (typeof value === "
|
|
1928
|
-
|
|
1958
|
+
if (typeof value === "string" || typeof value === "number") return value;
|
|
1959
|
+
}
|
|
1960
|
+
function getPageRecordKeys() {
|
|
1961
|
+
return table.value.records.map((record) => getRecordKey(record)).filter((key) => key !== void 0);
|
|
1962
|
+
}
|
|
1963
|
+
function warnMissingRecordKey(action) {
|
|
1964
|
+
console.warn(`Cannot ${action} because this table record has no key.`);
|
|
1965
|
+
}
|
|
1966
|
+
function getColumnName(column) {
|
|
1967
|
+
return typeof column === "string" ? column : column.name;
|
|
1968
|
+
}
|
|
1969
|
+
function getCell(index, column) {
|
|
1970
|
+
return table.value.cells[index]?.columns[getColumnName(column)] ?? {
|
|
1971
|
+
value: void 0,
|
|
1972
|
+
extra: {}
|
|
1973
|
+
};
|
|
1929
1974
|
}
|
|
1930
1975
|
function resolveInlineAction(action) {
|
|
1931
1976
|
if (typeof action !== "string") return action;
|
|
@@ -1944,10 +1989,15 @@ function useTable(input, defaultOptions = {}) {
|
|
|
1944
1989
|
*/
|
|
1945
1990
|
async function executeInlineAction(action, options) {
|
|
1946
1991
|
const resolvedAction = resolveInlineAction(action);
|
|
1992
|
+
const recordKey = getRecordKey(options.record);
|
|
1947
1993
|
if (!resolvedAction) {
|
|
1948
1994
|
console.warn(`Action [${action}] is not defined`);
|
|
1949
1995
|
return;
|
|
1950
1996
|
}
|
|
1997
|
+
if (recordKey === void 0) {
|
|
1998
|
+
warnMissingRecordKey("execute an inline action");
|
|
1999
|
+
return;
|
|
2000
|
+
}
|
|
1951
2001
|
return await router$1.navigate({
|
|
1952
2002
|
method: "post",
|
|
1953
2003
|
url: getActionUrl(resolvedAction, table.value),
|
|
@@ -1957,7 +2007,7 @@ function useTable(input, defaultOptions = {}) {
|
|
|
1957
2007
|
type: "action:inline",
|
|
1958
2008
|
action: resolvedAction.name,
|
|
1959
2009
|
tableId: table.value.id,
|
|
1960
|
-
recordId:
|
|
2010
|
+
recordId: recordKey
|
|
1961
2011
|
}
|
|
1962
2012
|
});
|
|
1963
2013
|
}
|
|
@@ -1996,20 +2046,35 @@ function useTable(input, defaultOptions = {}) {
|
|
|
1996
2046
|
});
|
|
1997
2047
|
}
|
|
1998
2048
|
return reactive({
|
|
1999
|
-
selectAll: bulk.selectAll,
|
|
2049
|
+
selectAll: () => table.value.keyName ? bulk.selectAll() : warnMissingRecordKey("select all records"),
|
|
2000
2050
|
deselectAll: bulk.deselectAll,
|
|
2001
|
-
selectPage: () => bulk.select(...
|
|
2002
|
-
deselectPage: () => bulk.deselect(...
|
|
2003
|
-
isPageSelected: computed(() =>
|
|
2004
|
-
|
|
2051
|
+
selectPage: () => bulk.select(...getPageRecordKeys()),
|
|
2052
|
+
deselectPage: () => bulk.deselect(...getPageRecordKeys()),
|
|
2053
|
+
isPageSelected: computed(() => {
|
|
2054
|
+
const keys = getPageRecordKeys();
|
|
2055
|
+
return keys.length > 0 && keys.every((key) => bulk.selected(key));
|
|
2056
|
+
}),
|
|
2057
|
+
isSelected: (record) => {
|
|
2058
|
+
const key = getRecordKey(record);
|
|
2059
|
+
return key === void 0 ? false : bulk.selected(key);
|
|
2060
|
+
},
|
|
2005
2061
|
allSelected: bulk.allSelected,
|
|
2006
2062
|
anySelected: bulk.anySelected,
|
|
2007
2063
|
selection: bulk.selection,
|
|
2008
2064
|
bindCheckbox: (key) => bulk.bindCheckbox(key),
|
|
2009
|
-
toggle: (record, force) =>
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2065
|
+
toggle: (record, force) => {
|
|
2066
|
+
const key = getRecordKey(record);
|
|
2067
|
+
return key === void 0 ? warnMissingRecordKey("toggle record selection") : bulk.toggle(key, force);
|
|
2068
|
+
},
|
|
2069
|
+
toggleAll: (force) => table.value.keyName ? bulk.toggleAll(force) : warnMissingRecordKey("toggle all records"),
|
|
2070
|
+
select: (record) => {
|
|
2071
|
+
const key = getRecordKey(record);
|
|
2072
|
+
return key === void 0 ? warnMissingRecordKey("select this record") : bulk.select(key);
|
|
2073
|
+
},
|
|
2074
|
+
deselect: (record) => {
|
|
2075
|
+
const key = getRecordKey(record);
|
|
2076
|
+
return key === void 0 ? warnMissingRecordKey("deselect this record") : bulk.deselect(key);
|
|
2077
|
+
},
|
|
2013
2078
|
inlineActions: computed(() => table.value.inlineActions.map((action) => ({
|
|
2014
2079
|
execute: (record) => executeInlineAction(action, { record }),
|
|
2015
2080
|
...action
|
|
@@ -2029,29 +2094,27 @@ function useTable(input, defaultOptions = {}) {
|
|
|
2029
2094
|
isSortable: !!refinements.sorts.value.find((sort) => sort.name === column.name),
|
|
2030
2095
|
isFilterable: !!refinements.filters.value.find((filters) => filters.name === column.name)
|
|
2031
2096
|
}))),
|
|
2032
|
-
data: computed(() =>
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
}).filter(Boolean);
|
|
2038
|
-
}),
|
|
2039
|
-
records: computed(() => table.value.records.map((record) => {
|
|
2040
|
-
const entries = Object.entries(record).map(([key, value]) => [key, value.value]).filter(([key]) => key !== "__hybridId");
|
|
2097
|
+
data: computed(() => table.value.records),
|
|
2098
|
+
records: computed(() => table.value.records.map((record, index) => {
|
|
2099
|
+
const recordKey = getRecordKey(record);
|
|
2100
|
+
const localKey = recordKey ?? `row-${index}`;
|
|
2101
|
+
const selected = recordKey === void 0 ? false : bulk.selected(recordKey);
|
|
2041
2102
|
return {
|
|
2042
|
-
record
|
|
2043
|
-
key:
|
|
2044
|
-
|
|
2103
|
+
record,
|
|
2104
|
+
key: localKey,
|
|
2105
|
+
recordKey,
|
|
2106
|
+
hasKey: recordKey !== void 0,
|
|
2107
|
+
execute: (action) => executeInlineAction(action, { record }),
|
|
2045
2108
|
actions: table.value.inlineActions.map((action) => ({
|
|
2046
2109
|
...action,
|
|
2047
|
-
execute: () => executeInlineAction(action.name, { record
|
|
2110
|
+
execute: () => executeInlineAction(action.name, { record })
|
|
2048
2111
|
})),
|
|
2049
|
-
select: () => bulk.select(
|
|
2050
|
-
deselect: () => bulk.deselect(
|
|
2051
|
-
toggle: (force) => bulk.toggle(
|
|
2052
|
-
selected
|
|
2053
|
-
value: (column) =>
|
|
2054
|
-
extra: (column, path) => getByPath(
|
|
2112
|
+
select: () => recordKey === void 0 ? warnMissingRecordKey("select this record") : bulk.select(recordKey),
|
|
2113
|
+
deselect: () => recordKey === void 0 ? warnMissingRecordKey("deselect this record") : bulk.deselect(recordKey),
|
|
2114
|
+
toggle: (force) => recordKey === void 0 ? warnMissingRecordKey("toggle record selection") : bulk.toggle(recordKey, force),
|
|
2115
|
+
selected,
|
|
2116
|
+
value: (column) => getCell(index, column).value,
|
|
2117
|
+
extra: (column, path) => getByPath(getCell(index, column).extra, path)
|
|
2055
2118
|
};
|
|
2056
2119
|
})),
|
|
2057
2120
|
paginator: computed(() => createPaginator(table.value.paginator, defaultOptions)),
|
|
@@ -2069,4 +2132,4 @@ function useValidationBag(bag = "default") {
|
|
|
2069
2132
|
return readonly(toReactive(computed(() => state.context.value?.validation?.[bag] ?? {})));
|
|
2070
2133
|
}
|
|
2071
2134
|
//#endregion
|
|
2072
|
-
export { Deferred, Form, RouterLink, WhenVisible, createPaginator, initializeHybridly, isBooleanFilter, isCallbackFilter, isDateFilter, isSelectFilter, isTernaryFilter, isTextFilter, isTrashedFilter, registerHook, route, router, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable, useValidation, useValidationBag };
|
|
2135
|
+
export { Deferred, Form, RouterLink, WhenVisible, createPaginator, getBulkSelectionRange, initializeHybridly, isBooleanFilter, isCallbackFilter, isDateFilter, isSelectFilter, isTernaryFilter, isTextFilter, isTrashedFilter, registerHook, route, router, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable, useValidation, useValidationBag };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hybridly/vue",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.10.0-beta.
|
|
4
|
+
"version": "0.10.0-beta.27",
|
|
5
5
|
"description": "Vue adapter for Hybridly",
|
|
6
6
|
"author": "Enzo Innocenzi <enzo@innocenzi.dev>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@clickbar/dot-diver": "^1.0.7",
|
|
49
49
|
"es-toolkit": "^1.45.1",
|
|
50
|
-
"@hybridly/core": "0.10.0-beta.
|
|
51
|
-
"@hybridly/utils": "0.10.0-beta.
|
|
50
|
+
"@hybridly/core": "0.10.0-beta.27",
|
|
51
|
+
"@hybridly/utils": "0.10.0-beta.27",
|
|
52
52
|
"@vue/devtools-api": "^8.1.0",
|
|
53
53
|
"defu": "^6.1.4",
|
|
54
54
|
"nprogress": "^0.2.0"
|