sprintify-ui 0.7.10 → 0.8.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.
- package/dist/sprintify-ui.es.js +10776 -10630
- package/dist/style.css +1 -1
- package/dist/types/components/BaseAppDialogs.vue.d.ts +1 -0
- package/dist/types/components/BaseDataIterator.vue.d.ts +50 -4
- package/dist/types/components/BaseDataIteratorSectionColumns.vue.d.ts +156 -68
- package/dist/types/components/BaseDataTable.vue.d.ts +86 -6
- package/dist/types/components/BaseDataTableTemplate.vue.d.ts +44 -28
- package/dist/types/components/BaseDialog.vue.d.ts +9 -0
- package/dist/types/components/BaseTable.vue.d.ts +30 -7
- package/dist/types/components/BaseTableCell.vue.d.ts +19 -1
- package/dist/types/components/BaseTableColumn.vue.d.ts +50 -3
- package/dist/types/components/BaseTableHead.vue.d.ts +6 -5
- package/dist/types/components/BaseTableHeader.vue.d.ts +12 -2
- package/dist/types/components/BaseTableRow.vue.d.ts +5 -0
- package/dist/types/composables/isFirstColumn.d.ts +4 -0
- package/dist/types/composables/isLastColumn.d.ts +4 -0
- package/dist/types/composables/paginatedData.d.ts +5 -5
- package/dist/types/services/table/types.d.ts +6 -5
- package/dist/types/types/index.d.ts +9 -2
- package/dist/types/utils/getApiData.d.ts +1 -1
- package/package.json +2 -1
- package/src/assets/main.css +0 -1
- package/src/components/BaseAppDialogs.vue +1 -0
- package/src/components/BaseAvatar.vue +1 -0
- package/src/components/BaseDataIterator.stories.js +96 -1
- package/src/components/BaseDataIterator.vue +135 -11
- package/src/components/BaseDataIteratorSectionColumns.vue +2 -2
- package/src/components/BaseDataTable.stories.js +140 -50
- package/src/components/BaseDataTable.vue +82 -48
- package/src/components/BaseDataTableTemplate.vue +207 -372
- package/src/components/BaseDialog.stories.js +7 -0
- package/src/components/BaseDialog.vue +13 -1
- package/src/components/BaseTable.stories.js +57 -15
- package/src/components/BaseTable.vue +71 -9
- package/src/components/BaseTableBody.vue +1 -1
- package/src/components/BaseTableCell.vue +94 -36
- package/src/components/BaseTableColumn.vue +25 -2
- package/src/components/BaseTableHead.vue +17 -5
- package/src/components/BaseTableHeader.vue +39 -10
- package/src/components/BaseTableRow.vue +27 -6
- package/src/composables/isFirstColumn.ts +31 -0
- package/src/composables/isLastColumn.ts +31 -0
- package/src/composables/paginatedData.ts +22 -10
- package/src/services/table/classes.ts +13 -9
- package/src/services/table/types.ts +6 -5
- package/src/stores/dialogs.ts +1 -0
- package/src/stories/List.stories.js +5 -1
- package/src/types/index.ts +9 -2
- package/src/utils/getApiData.ts +1 -1
- package/src/assets/base-table.css +0 -17
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import { ClassNameValue } from 'tailwind-merge';
|
|
2
|
+
import { StyleValue } from 'vue';
|
|
2
3
|
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<{
|
|
3
4
|
class?: ClassNameValue;
|
|
5
|
+
style?: StyleValue;
|
|
4
6
|
align?: "right" | "left" | "center" | undefined;
|
|
5
7
|
colspan?: number | undefined;
|
|
6
8
|
}>, {
|
|
7
9
|
class: undefined;
|
|
10
|
+
style: undefined;
|
|
8
11
|
align: string;
|
|
9
12
|
colspan: undefined;
|
|
10
|
-
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
click: (...args: any[]) => void;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<{
|
|
11
16
|
class?: ClassNameValue;
|
|
17
|
+
style?: StyleValue;
|
|
12
18
|
align?: "right" | "left" | "center" | undefined;
|
|
13
19
|
colspan?: number | undefined;
|
|
14
20
|
}>, {
|
|
15
21
|
class: undefined;
|
|
22
|
+
style: undefined;
|
|
16
23
|
align: string;
|
|
17
24
|
colspan: undefined;
|
|
18
|
-
}
|
|
25
|
+
}>>> & {
|
|
26
|
+
onClick?: ((...args: any[]) => any) | undefined;
|
|
27
|
+
}, {
|
|
19
28
|
class: string | false | 0 | ClassNameValue[] | null;
|
|
29
|
+
style: string | false | import("vue").CSSProperties | StyleValue[] | null;
|
|
20
30
|
align: "right" | "left" | "center";
|
|
21
31
|
colspan: number;
|
|
22
32
|
}, {}>, {
|
|
@@ -6,12 +6,14 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
6
6
|
target?: "_blank" | "_self" | "_parent" | "_top" | undefined;
|
|
7
7
|
title?: string | undefined;
|
|
8
8
|
class?: ClassNameValue;
|
|
9
|
+
onClick?: ((e: MouseEvent) => void) | undefined;
|
|
9
10
|
}>, {
|
|
10
11
|
href: undefined;
|
|
11
12
|
to: undefined;
|
|
12
13
|
target: undefined;
|
|
13
14
|
title: undefined;
|
|
14
15
|
class: undefined;
|
|
16
|
+
onClick: undefined;
|
|
15
17
|
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
18
|
click: (...args: any[]) => void;
|
|
17
19
|
mouseenter: (...args: any[]) => void;
|
|
@@ -22,18 +24,21 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
22
24
|
target?: "_blank" | "_self" | "_parent" | "_top" | undefined;
|
|
23
25
|
title?: string | undefined;
|
|
24
26
|
class?: ClassNameValue;
|
|
27
|
+
onClick?: ((e: MouseEvent) => void) | undefined;
|
|
25
28
|
}>, {
|
|
26
29
|
href: undefined;
|
|
27
30
|
to: undefined;
|
|
28
31
|
target: undefined;
|
|
29
32
|
title: undefined;
|
|
30
33
|
class: undefined;
|
|
34
|
+
onClick: undefined;
|
|
31
35
|
}>>> & {
|
|
32
36
|
onClick?: ((...args: any[]) => any) | undefined;
|
|
33
37
|
onMouseenter?: ((...args: any[]) => any) | undefined;
|
|
34
38
|
onMouseleave?: ((...args: any[]) => any) | undefined;
|
|
35
39
|
}, {
|
|
36
40
|
class: string | false | 0 | ClassNameValue[] | null;
|
|
41
|
+
onClick: (e: MouseEvent) => void;
|
|
37
42
|
title: string;
|
|
38
43
|
to: RouteLocationRaw;
|
|
39
44
|
href: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Ref } from 'vue';
|
|
1
|
+
import { ComputedRef, Ref } from 'vue';
|
|
2
2
|
import { Collection, PaginatedCollection, ResourceCollection, PaginationMetadata } from '@/types';
|
|
3
|
-
export declare function useHasPaginatedData(data: Ref<Collection | PaginatedCollection | ResourceCollection | null>): {
|
|
4
|
-
items:
|
|
5
|
-
paginationMetadata:
|
|
6
|
-
lastPage:
|
|
3
|
+
export declare function useHasPaginatedData(data: Ref<Collection | PaginatedCollection | ResourceCollection | null | undefined>, page?: ComputedRef<number>, perPage?: ComputedRef<number>): {
|
|
4
|
+
items: ComputedRef<Collection>;
|
|
5
|
+
paginationMetadata: ComputedRef<PaginationMetadata | null>;
|
|
6
|
+
lastPage: ComputedRef<number>;
|
|
7
7
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { RouteLocationRaw } from "vue-router";
|
|
2
|
-
export type
|
|
2
|
+
export type CellSize = 'none' | 'xs' | 'sm' | 'md' | 'lg';
|
|
3
3
|
export interface TableProps {
|
|
4
|
-
|
|
4
|
+
size?: CellSize;
|
|
5
5
|
flush?: boolean;
|
|
6
|
+
fixedHeader?: boolean;
|
|
7
|
+
fixedColumn?: boolean;
|
|
6
8
|
}
|
|
7
|
-
export type CellConfig =
|
|
8
|
-
flush?: boolean;
|
|
9
|
-
} & TableProps;
|
|
9
|
+
export type CellConfig = TableProps;
|
|
10
10
|
export interface CellProps {
|
|
11
11
|
title?: string;
|
|
12
12
|
href?: string;
|
|
13
13
|
to?: RouteLocationRaw;
|
|
14
14
|
target?: string;
|
|
15
|
+
onClick?: (e: MouseEvent) => void;
|
|
15
16
|
}
|
|
@@ -76,15 +76,20 @@ export interface BaseTableColumnData {
|
|
|
76
76
|
label: string;
|
|
77
77
|
field: string;
|
|
78
78
|
meta: undefined | Record<string, any>;
|
|
79
|
-
newKey:
|
|
79
|
+
newKey: string;
|
|
80
80
|
numeric: boolean;
|
|
81
81
|
position: 'left' | 'right';
|
|
82
82
|
searchable: boolean;
|
|
83
83
|
sortable: boolean;
|
|
84
|
-
|
|
84
|
+
ignoreRowInteractions: boolean;
|
|
85
85
|
toggle: boolean;
|
|
86
86
|
toggleDefault: boolean;
|
|
87
87
|
width: number;
|
|
88
|
+
class?: string | string[];
|
|
89
|
+
to?: (row: Row) => RouteLocationRaw;
|
|
90
|
+
href?: (row: Row) => string;
|
|
91
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
92
|
+
onClick?: (row: Row, index: number, column: BaseTableColumnData, colIndex: number, event: MouseEvent) => void;
|
|
88
93
|
style: {
|
|
89
94
|
width: undefined | number;
|
|
90
95
|
};
|
|
@@ -116,6 +121,7 @@ export interface DialogOptions {
|
|
|
116
121
|
color?: 'info' | 'success' | 'danger' | 'warning';
|
|
117
122
|
title: string;
|
|
118
123
|
message: string;
|
|
124
|
+
html?: boolean;
|
|
119
125
|
confirmText?: string;
|
|
120
126
|
cancelText?: string;
|
|
121
127
|
closeOnOutsideClick?: boolean;
|
|
@@ -127,6 +133,7 @@ export interface Dialog {
|
|
|
127
133
|
color: 'info' | 'success' | 'danger' | 'warning';
|
|
128
134
|
title: string;
|
|
129
135
|
message: string;
|
|
136
|
+
html: boolean;
|
|
130
137
|
confirmText: string;
|
|
131
138
|
cancelText: string;
|
|
132
139
|
closeOnOutsideClick: boolean;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Collection, PaginatedCollection, ResourceCollection } from "@/types";
|
|
2
|
-
export declare function getItems(data: Collection | PaginatedCollection | ResourceCollection | null): Collection;
|
|
2
|
+
export declare function getItems(data: Collection | PaginatedCollection | ResourceCollection | null | undefined): Collection;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprintify-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "rimraf dist && vue-tsc && vite build",
|
|
6
6
|
"build-fast": "rimraf dist && vite build",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@commitlint/config-conventional": "^17.8.1",
|
|
57
57
|
"@iconify/vue": "^4.1.1",
|
|
58
58
|
"@storybook/addon-actions": "^7.2.1",
|
|
59
|
+
"@storybook/addon-controls": "^7.6.17",
|
|
59
60
|
"@storybook/addon-essentials": "^7.6.17",
|
|
60
61
|
"@storybook/addon-interactions": "^7.6.17",
|
|
61
62
|
"@storybook/addon-links": "^7.6.17",
|
package/src/assets/main.css
CHANGED
|
@@ -3,7 +3,8 @@ import BaseSelect from './BaseSelect.vue';
|
|
|
3
3
|
import BaseCard from './BaseCard.vue';
|
|
4
4
|
import BaseCardRow from './BaseCardRow.vue';
|
|
5
5
|
import BaseLoadingCover from './BaseLoadingCover.vue';
|
|
6
|
-
import { sizes } from '../../.storybook/utils';
|
|
6
|
+
import { options, sizes } from '../../.storybook/utils';
|
|
7
|
+
import { computed } from 'vue';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
title: 'Data/BaseDataIterator',
|
|
@@ -205,3 +206,97 @@ Simple.args = {
|
|
|
205
206
|
searchable: false,
|
|
206
207
|
actions: [],
|
|
207
208
|
};
|
|
209
|
+
|
|
210
|
+
const LocalDataTemplate = (args) => ({
|
|
211
|
+
components: {
|
|
212
|
+
BaseDataIterator,
|
|
213
|
+
BaseCard,
|
|
214
|
+
BaseCardRow,
|
|
215
|
+
BaseLoadingCover,
|
|
216
|
+
BaseSelect,
|
|
217
|
+
},
|
|
218
|
+
setup() {
|
|
219
|
+
|
|
220
|
+
const baseDataIteratorRef = ref(null);
|
|
221
|
+
|
|
222
|
+
const filteredItems = computed(() => {
|
|
223
|
+
return options
|
|
224
|
+
.filter((item) => {
|
|
225
|
+
|
|
226
|
+
const type = baseDataIteratorRef.value?.query?.filter?.type ?? null;
|
|
227
|
+
|
|
228
|
+
if (type) {
|
|
229
|
+
return item.type === type;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return true;
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
return { args, filteredItems, baseDataIteratorRef };
|
|
237
|
+
},
|
|
238
|
+
template: `
|
|
239
|
+
<BaseDataIterator ref="baseDataIteratorRef" v-bind="args" :items="filteredItems">
|
|
240
|
+
<template #default="{ items, loading }">
|
|
241
|
+
|
|
242
|
+
<div class="relative">
|
|
243
|
+
<div class="space-y-1.5">
|
|
244
|
+
<div
|
|
245
|
+
v-for="item in items"
|
|
246
|
+
:key="item.id"
|
|
247
|
+
class="block group"
|
|
248
|
+
>
|
|
249
|
+
<BaseCard class="group-hover:bg-slate-100">
|
|
250
|
+
<BaseCardRow size="xs">
|
|
251
|
+
<div class="font-medium text-slate-900">
|
|
252
|
+
{{ item.label }}
|
|
253
|
+
</div>
|
|
254
|
+
<p class="text-xs leading-tight text-slate-500">
|
|
255
|
+
{{ item.type }}
|
|
256
|
+
</p>
|
|
257
|
+
</BaseCardRow>
|
|
258
|
+
</BaseCard>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
|
|
262
|
+
<BaseLoadingCover
|
|
263
|
+
v-show="loading"
|
|
264
|
+
size="lg"
|
|
265
|
+
backdropClass="bg-white bg-opacity-50"
|
|
266
|
+
>
|
|
267
|
+
</BaseLoadingCover>
|
|
268
|
+
</div>
|
|
269
|
+
</template>
|
|
270
|
+
|
|
271
|
+
<template #filters="{ query, updateQueryValue }">
|
|
272
|
+
<div class="space-y-3">
|
|
273
|
+
<div>
|
|
274
|
+
<p class="mb-1 text-sm">
|
|
275
|
+
Type
|
|
276
|
+
</p>
|
|
277
|
+
<BaseSelect
|
|
278
|
+
:model-value="query.filter.type ?? null"
|
|
279
|
+
class="w-full rounded border-slate-300"
|
|
280
|
+
placeholder="-"
|
|
281
|
+
@update:model-value="updateQueryValue('filter.type', $event)"
|
|
282
|
+
>
|
|
283
|
+
<option value="jedi">
|
|
284
|
+
Jedi
|
|
285
|
+
</option>
|
|
286
|
+
<option value="sith">
|
|
287
|
+
Sith
|
|
288
|
+
</option>
|
|
289
|
+
</BaseSelect>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
</template>
|
|
293
|
+
</BaseDataIterator>
|
|
294
|
+
`,
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
export const Local = LocalDataTemplate.bind({});
|
|
298
|
+
Local.args = {
|
|
299
|
+
url: null,
|
|
300
|
+
actions: [],
|
|
301
|
+
perPage: 4,
|
|
302
|
+
};
|
|
@@ -84,10 +84,8 @@
|
|
|
84
84
|
/>
|
|
85
85
|
</BaseDataIteratorSectionBox>
|
|
86
86
|
</div>
|
|
87
|
-
|
|
88
|
-
|
|
89
87
|
<slot
|
|
90
|
-
:items="
|
|
88
|
+
:items="itemsInternal"
|
|
91
89
|
:loading="loading"
|
|
92
90
|
:error="error"
|
|
93
91
|
:first-load="firstLoad"
|
|
@@ -197,7 +195,7 @@ const DEFAULT_QUERY = {
|
|
|
197
195
|
</script>
|
|
198
196
|
|
|
199
197
|
<script lang="ts" setup>
|
|
200
|
-
import { cloneDeep, debounce, merge, set } from 'lodash';
|
|
198
|
+
import { cloneDeep, debounce, merge, set, sortBy } from 'lodash';
|
|
201
199
|
import hash from 'object-hash';
|
|
202
200
|
import { PropType } from 'vue';
|
|
203
201
|
import {
|
|
@@ -220,12 +218,21 @@ import BaseDataIteratorSectionModal from './BaseDataIteratorSectionModal.vue';
|
|
|
220
218
|
import BaseDataIteratorSectionBox from './BaseDataIteratorSectionBox.vue';
|
|
221
219
|
|
|
222
220
|
const props = defineProps({
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Data to display
|
|
224
|
+
*/
|
|
225
|
+
items: {
|
|
226
|
+
default: undefined,
|
|
227
|
+
type: Array as PropType<Collection | undefined>,
|
|
228
|
+
},
|
|
229
|
+
|
|
223
230
|
/**
|
|
224
231
|
* Base URL from which to make requests
|
|
225
232
|
*/
|
|
226
233
|
url: {
|
|
227
|
-
|
|
228
|
-
type: String
|
|
234
|
+
default: undefined,
|
|
235
|
+
type: String as PropType<string | undefined>,
|
|
229
236
|
},
|
|
230
237
|
|
|
231
238
|
/**
|
|
@@ -311,9 +318,28 @@ const props = defineProps({
|
|
|
311
318
|
filtersPosition: {
|
|
312
319
|
default: 'section',
|
|
313
320
|
type: String as PropType<'section' | 'top'>,
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Per page (only when using local data)
|
|
325
|
+
*/
|
|
326
|
+
perPage: {
|
|
327
|
+
default: 16,
|
|
328
|
+
type: Number,
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Function to search local data
|
|
333
|
+
*/
|
|
334
|
+
search: {
|
|
335
|
+
default: undefined,
|
|
336
|
+
type: Function as PropType<(items: Collection, search: string | null) => Collection>,
|
|
314
337
|
}
|
|
315
338
|
});
|
|
316
339
|
|
|
340
|
+
const LOCAL = 'local';
|
|
341
|
+
const REMOTE = 'remote';
|
|
342
|
+
|
|
317
343
|
const http = config.http;
|
|
318
344
|
|
|
319
345
|
const emit = defineEmits([
|
|
@@ -327,6 +353,14 @@ const emit = defineEmits([
|
|
|
327
353
|
'fetch',
|
|
328
354
|
]);
|
|
329
355
|
|
|
356
|
+
const dataMode = computed(() => {
|
|
357
|
+
if (props.url) {
|
|
358
|
+
return REMOTE;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return LOCAL;
|
|
362
|
+
});
|
|
363
|
+
|
|
330
364
|
const dataIteratorNode = ref<null | HTMLElement>(null);
|
|
331
365
|
const searchInputFocus = ref(false);
|
|
332
366
|
|
|
@@ -350,7 +384,7 @@ useResizeObserver(dataIteratorNode, () => {
|
|
|
350
384
|
/** Data table state */
|
|
351
385
|
|
|
352
386
|
const firstLoad = ref(false);
|
|
353
|
-
const loading = ref(
|
|
387
|
+
const loading = ref(false);
|
|
354
388
|
const error = ref(false);
|
|
355
389
|
const searchQuery = ref('');
|
|
356
390
|
|
|
@@ -476,7 +510,7 @@ function queryHash(query: DataTableQuery): string {
|
|
|
476
510
|
|--------------------------------------------------------------------------
|
|
477
511
|
*/
|
|
478
512
|
|
|
479
|
-
const url = computed<string>(() => {
|
|
513
|
+
const url = computed<string | undefined>(() => {
|
|
480
514
|
return props.url;
|
|
481
515
|
});
|
|
482
516
|
|
|
@@ -518,7 +552,7 @@ const onSearch = debounce((event: any) => {
|
|
|
518
552
|
newQuery.search = searchQuery.value;
|
|
519
553
|
|
|
520
554
|
updateQuery(newQuery);
|
|
521
|
-
}, 350);
|
|
555
|
+
}, dataMode.value == REMOTE ? 350 : 0);
|
|
522
556
|
|
|
523
557
|
/*
|
|
524
558
|
|--------------------------------------------------------------------------
|
|
@@ -608,6 +642,11 @@ function fetch(force = false, showLoading = true) {
|
|
|
608
642
|
return;
|
|
609
643
|
}
|
|
610
644
|
|
|
645
|
+
if (url.value == null) {
|
|
646
|
+
firstLoad.value = true;
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
|
|
611
650
|
const urlSplit = url.value.split(/[?#]/);
|
|
612
651
|
|
|
613
652
|
const baseUrl = urlSplit[0];
|
|
@@ -664,15 +703,100 @@ const data = ref<null | ResourceCollection | PaginatedCollection | Collection>(
|
|
|
664
703
|
null
|
|
665
704
|
);
|
|
666
705
|
|
|
667
|
-
const { items, paginationMetadata, lastPage } = useHasPaginatedData(data);
|
|
668
|
-
|
|
669
706
|
const page = computed((): number => {
|
|
670
707
|
if (query.value.page && parseInt(query.value.page + '')) {
|
|
671
708
|
return parseInt(query.value.page + '');
|
|
672
709
|
}
|
|
710
|
+
|
|
673
711
|
return 1;
|
|
674
712
|
});
|
|
675
713
|
|
|
714
|
+
const dataInternal = computed<ResourceCollection | PaginatedCollection | Collection | null | undefined>(() => {
|
|
715
|
+
if (dataMode.value == REMOTE) {
|
|
716
|
+
return data.value;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return searchItems(props.items);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
const { items, paginationMetadata, lastPage } = useHasPaginatedData(
|
|
723
|
+
dataInternal,
|
|
724
|
+
page,
|
|
725
|
+
computed(() => props.perPage),
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
const itemsInternal = computed(() => {
|
|
729
|
+
if (dataMode.value == REMOTE) {
|
|
730
|
+
return items.value;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
return paginateItems(sortItems(items.value));
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
/*
|
|
737
|
+
|--------------------------------------------------------------------------
|
|
738
|
+
| Local data filtering, sorting and pagination
|
|
739
|
+
|--------------------------------------------------------------------------
|
|
740
|
+
*/
|
|
741
|
+
|
|
742
|
+
function searchItems(items: Collection | undefined) {
|
|
743
|
+
|
|
744
|
+
if (!items) {
|
|
745
|
+
return [];
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const searchWords = searchKeywords.value.toLowerCase();
|
|
749
|
+
|
|
750
|
+
if (props.search) {
|
|
751
|
+
return props.search(items, searchKeywords.value);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
return items?.filter((item) => {
|
|
755
|
+
return Object.values(item).some((value) => {
|
|
756
|
+
if (typeof value == 'string') {
|
|
757
|
+
return value.toLowerCase().includes(searchWords);
|
|
758
|
+
}
|
|
759
|
+
return false;
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
function sortItems(items: Collection | undefined) {
|
|
765
|
+
if (!items) {
|
|
766
|
+
return [];
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (!sortField.value) {
|
|
770
|
+
return items;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (!sortDirection.value) {
|
|
774
|
+
return items;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (sortDirection.value == 'asc') {
|
|
778
|
+
return sortBy(items, (item) => {
|
|
779
|
+
return item[sortField.value];
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
return sortBy(items, (item) => {
|
|
784
|
+
return item[sortField.value];
|
|
785
|
+
})
|
|
786
|
+
.reverse();
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
function paginateItems(items: Collection | undefined) {
|
|
790
|
+
if (!items) {
|
|
791
|
+
return [];
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
return items.slice(
|
|
795
|
+
(page.value - 1) * props.perPage,
|
|
796
|
+
page.value * props.perPage
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
|
|
676
800
|
const sortField = computed((): string => {
|
|
677
801
|
return query.value.sort?.trim().replace(/^(-)/, '') ?? '';
|
|
678
802
|
});
|
|
@@ -32,7 +32,7 @@ const props = defineProps({
|
|
|
32
32
|
},
|
|
33
33
|
visibleColumns: {
|
|
34
34
|
required: true,
|
|
35
|
-
type: Array as PropType<
|
|
35
|
+
type: Array as PropType<string[]>,
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -52,7 +52,7 @@ const toggleableColumns = computed(() => {
|
|
|
52
52
|
return tableVue.newColumns.filter((c) => c.toggle);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
function onVisibleColumnChange(event: any, newKey:
|
|
55
|
+
function onVisibleColumnChange(event: any, newKey: string) {
|
|
56
56
|
const checked = event.target.checked as boolean;
|
|
57
57
|
|
|
58
58
|
let newVisibleColumns = cloneDeep(props.visibleColumns);
|