quasar-ui-danx 0.4.12 → 0.4.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/danx.es.js +10975 -6424
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +137 -7
- package/dist/danx.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -2
- package/src/components/ActionTable/ActionTable.vue +65 -63
- package/src/components/ActionTable/Form/ActionForm.vue +18 -12
- package/src/components/ActionTable/Form/RenderedForm.vue +86 -60
- package/src/components/ActionTable/Layouts/ActionTableLayout.vue +80 -70
- package/src/components/ActionTable/Toolbars/ActionToolbar.vue +29 -29
- package/src/components/ActionTable/listControls.ts +32 -31
- package/src/components/Navigation/NavigationMenu.vue +83 -40
- package/src/components/PanelsDrawer/PanelsDrawer.vue +20 -8
- package/src/components/PanelsDrawer/PanelsDrawerPanels.vue +3 -1
- package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +17 -4
- package/src/components/Utility/Tools/RenderVnode.vue +5 -1
- package/src/components/Utility/Transitions/AutoHeightTransition.vue +21 -0
- package/src/components/Utility/Transitions/index.ts +1 -0
- package/src/config/index.ts +1 -0
- package/src/helpers/actions.ts +31 -20
- package/src/helpers/date.ts +2 -2
- package/src/helpers/formats.ts +55 -5
- package/src/helpers/objectStore.ts +7 -0
- package/src/helpers/request.ts +1 -1
- package/src/helpers/routes.ts +5 -0
- package/src/helpers/utils.ts +3 -3
- package/src/types/actions.d.ts +4 -7
- package/src/types/config.d.ts +3 -1
- package/src/types/controls.d.ts +5 -7
- package/src/types/forms.d.ts +20 -1
- package/src/types/shared.d.ts +1 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "quasar-ui-danx",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.14",
|
4
4
|
"author": "Dan <dan@flytedesk.com>",
|
5
5
|
"description": "DanX Vue / Quasar component library",
|
6
6
|
"license": "MIT",
|
@@ -57,7 +57,8 @@
|
|
57
57
|
"danx-icon": "^1.0.2",
|
58
58
|
"exifreader": "^4.21.1",
|
59
59
|
"gsap": "^3.12.5",
|
60
|
-
"luxon": "^3.4.4"
|
60
|
+
"luxon": "^3.4.4",
|
61
|
+
"yaml": "^2.4.5"
|
61
62
|
},
|
62
63
|
"browserslist": [
|
63
64
|
"last 4 Chrome versions",
|
@@ -1,66 +1,66 @@
|
|
1
1
|
<template>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
2
|
+
<div
|
3
|
+
class="dx-action-table overflow-hidden"
|
4
|
+
:class="{'dx-no-data': !hasData, 'dx-is-loading': loadingList || loadingSummary, 'dx-is-loading-list': loadingList}"
|
5
|
+
>
|
6
|
+
<ActionVnode />
|
7
|
+
<QTable
|
8
|
+
ref="actionTable"
|
9
|
+
:selected="selectedRows"
|
10
|
+
:pagination="pagination"
|
11
|
+
:columns="tableColumns"
|
12
|
+
:loading="loadingList || loadingSummary"
|
13
|
+
:rows="pagedItems?.data || []"
|
14
|
+
:binary-state-sort="false"
|
15
|
+
:selection="selection"
|
16
|
+
:rows-per-page-options="rowsPerPageOptions"
|
17
|
+
class="sticky-column sticky-header w-full h-full !border-0"
|
18
|
+
:color="color"
|
19
|
+
@update:selected="$emit('update:selected-rows', $event)"
|
20
|
+
@update:pagination="() => {}"
|
21
|
+
@request="(e) => $emit('update:pagination', {...e.pagination, __sort: mapSortBy(e.pagination, tableColumns)})"
|
22
|
+
>
|
23
|
+
<template #no-data>
|
24
|
+
<slot name="empty">
|
25
|
+
<EmptyTableState :text="`There are no ${label.toLowerCase()} matching the applied filter`" />
|
26
|
+
</slot>
|
27
|
+
</template>
|
28
|
+
<template #top-row>
|
29
|
+
<TableSummaryRow
|
30
|
+
v-if="hasData"
|
31
|
+
:label="label"
|
32
|
+
:item-count="summary?.count || 0"
|
33
|
+
:selected-count="selectedRows.length"
|
34
|
+
:sticky-colspan="summaryColSpan"
|
35
|
+
:loading="loadingSummary"
|
36
|
+
:summary="summary"
|
37
|
+
:columns="tableColumns"
|
38
|
+
@clear="$emit('update:selected-rows', [])"
|
39
|
+
/>
|
40
|
+
</template>
|
41
|
+
<template #header-cell="rowProps">
|
42
|
+
<ActionTableHeaderColumn
|
43
|
+
v-model="columnSettings"
|
44
|
+
:row-props="rowProps"
|
45
|
+
:name="name"
|
46
|
+
@update:model-value="onUpdateColumnSettings"
|
47
|
+
/>
|
48
|
+
</template>
|
49
|
+
<template #body-cell="rowProps">
|
50
|
+
<ActionTableColumn
|
51
|
+
:key="rowProps.key"
|
52
|
+
:row-props="rowProps"
|
53
|
+
:settings="columnSettings[rowProps.col.name]"
|
54
|
+
>
|
55
|
+
<slot
|
56
|
+
:column-name="rowProps.col.name"
|
57
|
+
:row="rowProps.row"
|
58
|
+
:value="rowProps.value"
|
59
|
+
/>
|
60
|
+
</ActionTableColumn>
|
61
|
+
</template>
|
62
|
+
</QTable>
|
63
|
+
</div>
|
64
64
|
</template>
|
65
65
|
|
66
66
|
<script setup lang="ts">
|
@@ -89,6 +89,7 @@ export interface Props {
|
|
89
89
|
columns: TableColumn[];
|
90
90
|
rowsPerPageOptions?: number[];
|
91
91
|
summaryColSpan?: number;
|
92
|
+
selection: "multiple" | "single";
|
92
93
|
}
|
93
94
|
|
94
95
|
const props = withDefaults(defineProps<Props>(), {
|
@@ -97,7 +98,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|
97
98
|
summary: null,
|
98
99
|
loadingSummary: false,
|
99
100
|
rowsPerPageOptions: () => [10, 25, 50, 100],
|
100
|
-
summaryColSpan: null
|
101
|
+
summaryColSpan: null,
|
102
|
+
selection: "multiple"
|
101
103
|
});
|
102
104
|
|
103
105
|
const actionTable = ref(null);
|
@@ -1,16 +1,19 @@
|
|
1
1
|
<template>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
<div>
|
3
|
+
<RenderedForm
|
4
|
+
v-bind="renderedFormProps"
|
5
|
+
v-model:values="input"
|
6
|
+
empty-value=""
|
7
|
+
:saved-at="target.updated_at"
|
8
|
+
:saving="action.isApplying"
|
9
|
+
@update:values="action.trigger(target, input)"
|
10
|
+
>
|
11
|
+
<slot />
|
12
|
+
</RenderedForm>
|
13
|
+
</div>
|
11
14
|
</template>
|
12
15
|
<script setup lang="ts">
|
13
|
-
import { ref, watch } from "vue";
|
16
|
+
import { Ref, ref, watch } from "vue";
|
14
17
|
import { ActionTargetItem, AnyObject, Form, ResourceAction } from "../../../types";
|
15
18
|
import RenderedForm from "./RenderedForm.vue";
|
16
19
|
|
@@ -27,7 +30,10 @@ interface ActionFormProps {
|
|
27
30
|
savingClass?: string;
|
28
31
|
}
|
29
32
|
|
30
|
-
const props = defineProps<ActionFormProps>()
|
33
|
+
const props = withDefaults(defineProps<ActionFormProps>(), {
|
34
|
+
fieldClass: "",
|
35
|
+
savingClass: undefined
|
36
|
+
});
|
31
37
|
const renderedFormProps = {
|
32
38
|
form: props.form,
|
33
39
|
noLabel: props.noLabel,
|
@@ -39,7 +45,7 @@ const renderedFormProps = {
|
|
39
45
|
savingClass: props.savingClass
|
40
46
|
};
|
41
47
|
|
42
|
-
const input: AnyObject = ref({ ...props.target });
|
48
|
+
const input: Ref<AnyObject> = ref({ ...props.target });
|
43
49
|
const fieldStatus: AnyObject = {};
|
44
50
|
|
45
51
|
// Only update field values from target changes when the field is not already being saved
|
@@ -62,32 +62,37 @@
|
|
62
62
|
</QTab>
|
63
63
|
</QTabs>
|
64
64
|
</div>
|
65
|
-
<
|
65
|
+
<template
|
66
66
|
v-for="(field, index) in mappedFields"
|
67
67
|
:key="field.id"
|
68
|
-
:class="{ 'mt-4': index > 0, [fieldClass]: true }"
|
69
68
|
>
|
70
|
-
<
|
71
|
-
v-
|
72
|
-
:
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
69
|
+
<div
|
70
|
+
v-show="isFieldEnabled(field)"
|
71
|
+
:class="{ 'mt-4': index > 0, [fieldClass]: true }"
|
72
|
+
>
|
73
|
+
<RenderVnode
|
74
|
+
v-if="field.vnode"
|
75
|
+
:vnode="field.vnode"
|
76
|
+
:props="getVnodeProps(field)"
|
77
|
+
:params="fieldInputs"
|
78
|
+
@update:model-value="onInput(field.name, $event)"
|
79
|
+
/>
|
80
|
+
<Component
|
81
|
+
:is="field.component"
|
82
|
+
:key="field.name + '-' + currentVariation"
|
83
|
+
:model-value="getFieldValue(field.name)"
|
84
|
+
:field="field"
|
85
|
+
:label="field.label || undefined"
|
86
|
+
:no-label="noLabel"
|
87
|
+
:show-name="showName"
|
88
|
+
:clearable="field.clearable || clearable"
|
89
|
+
:disable="disable"
|
90
|
+
:readonly="readonly"
|
91
|
+
@update:model-value="onInput(field.name, $event)"
|
92
|
+
/>
|
93
|
+
</div>
|
94
|
+
</template>
|
95
|
+
<slot />
|
91
96
|
<div
|
92
97
|
v-if="savedAt"
|
93
98
|
:class="savingClass"
|
@@ -133,10 +138,10 @@
|
|
133
138
|
</template>
|
134
139
|
<script setup lang="ts">
|
135
140
|
import { ExclamationCircleIcon as MissingIcon, PencilIcon as EditIcon } from "@heroicons/vue/solid";
|
136
|
-
import { computed, ref } from "vue";
|
141
|
+
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
|
137
142
|
import { fDateTime, FlashMessages, incrementName, replace } from "../../../helpers";
|
138
143
|
import { TrashIcon as RemoveIcon } from "../../../svg";
|
139
|
-
import { AnyObject,
|
144
|
+
import { AnyObject, FormFieldValue, RenderedFormProps } from "../../../types";
|
140
145
|
import { ConfirmDialog, RenderVnode } from "../../Utility";
|
141
146
|
import {
|
142
147
|
BooleanField,
|
@@ -150,22 +155,6 @@ import {
|
|
150
155
|
WysiwygField
|
151
156
|
} from "./Fields";
|
152
157
|
|
153
|
-
export interface RenderedFormProps {
|
154
|
-
values?: FormFieldValue[] | object | null;
|
155
|
-
form: Form;
|
156
|
-
noLabel?: boolean;
|
157
|
-
showName?: boolean;
|
158
|
-
disable?: boolean;
|
159
|
-
readonly?: boolean;
|
160
|
-
saving?: boolean;
|
161
|
-
clearable?: boolean;
|
162
|
-
emptyValue?: string | number | boolean;
|
163
|
-
canModifyVariations?: boolean;
|
164
|
-
fieldClass?: string;
|
165
|
-
savingClass?: string;
|
166
|
-
savedAt?: string;
|
167
|
-
}
|
168
|
-
|
169
158
|
const props = withDefaults(defineProps<RenderedFormProps>(), {
|
170
159
|
values: null,
|
171
160
|
emptyValue: undefined,
|
@@ -191,16 +180,39 @@ const FORM_FIELD_MAP = {
|
|
191
180
|
const mappedFields = props.form.fields.map((field) => ({
|
192
181
|
placeholder: `Enter ${field.label}`,
|
193
182
|
...field,
|
194
|
-
component: field.component || FORM_FIELD_MAP[field.type]
|
195
|
-
default: field.type === "BOOLEAN" ? false : ""
|
183
|
+
component: field.component || FORM_FIELD_MAP[field.type]
|
196
184
|
}));
|
197
185
|
|
198
186
|
const fieldResponses = computed(() => {
|
199
|
-
|
200
|
-
if (
|
201
|
-
|
187
|
+
const values = props.values;
|
188
|
+
if (!values) return [];
|
189
|
+
if (Array.isArray(values)) return values;
|
190
|
+
|
191
|
+
return Object.entries(values).filter((entry) => mappedFields.find(mf => mf.name === entry[0])).map(([name, value]) => ({
|
192
|
+
name,
|
193
|
+
value,
|
194
|
+
variation: ""
|
195
|
+
}));
|
196
|
+
});
|
197
|
+
|
198
|
+
const fieldInputs = computed(() => {
|
199
|
+
const inputs: AnyObject = {};
|
200
|
+
for (const field of mappedFields) {
|
201
|
+
inputs[field.name] = getFieldValue(field.name);
|
202
|
+
}
|
203
|
+
return inputs;
|
202
204
|
});
|
203
205
|
|
206
|
+
function isFieldEnabled(field) {
|
207
|
+
if (field.enabled === undefined) return true;
|
208
|
+
|
209
|
+
if (typeof field.enabled === "function") {
|
210
|
+
return field.enabled(fieldInputs.value);
|
211
|
+
}
|
212
|
+
|
213
|
+
return field.enabled;
|
214
|
+
}
|
215
|
+
|
204
216
|
function getVnodeProps(field) {
|
205
217
|
return {
|
206
218
|
modelValue: getFieldValue(field.name),
|
@@ -246,11 +258,38 @@ function onInput(name: string, value: any) {
|
|
246
258
|
updateValues(newValues);
|
247
259
|
}
|
248
260
|
|
261
|
+
function updateValues(values: FormFieldValue[]) {
|
262
|
+
let updatedValues: FormFieldValue[] | object = values;
|
263
|
+
|
264
|
+
if (!Array.isArray(props.values)) {
|
265
|
+
updatedValues = values.reduce((acc: AnyObject, v) => {
|
266
|
+
acc[v.name] = v.value;
|
267
|
+
return acc;
|
268
|
+
}, {});
|
269
|
+
}
|
270
|
+
|
271
|
+
emit("update:values", updatedValues);
|
272
|
+
}
|
273
|
+
|
274
|
+
onMounted(() => {
|
275
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
276
|
+
});
|
277
|
+
onBeforeUnmount(() => {
|
278
|
+
window.removeEventListener("beforeunload", handleBeforeUnload);
|
279
|
+
});
|
280
|
+
|
281
|
+
|
282
|
+
function handleBeforeUnload(event: BeforeUnloadEvent) {
|
283
|
+
if (props.saving) {
|
284
|
+
return event.returnValue = "Changes are currently being saved. If you leave now, you might lose unsaved changes.";
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
249
288
|
function createVariation(variation) {
|
250
289
|
return props.form.fields.map((field) => ({
|
251
290
|
variation,
|
252
291
|
name: field.name,
|
253
|
-
value: field.
|
292
|
+
value: field.default_value === undefined ? null : field.default_value
|
254
293
|
}));
|
255
294
|
}
|
256
295
|
|
@@ -287,19 +326,6 @@ function onChangeVariationName() {
|
|
287
326
|
newVariationName.value = "";
|
288
327
|
}
|
289
328
|
|
290
|
-
function updateValues(values: FormFieldValue[]) {
|
291
|
-
let updatedValues: FormFieldValue[] | object = values;
|
292
|
-
|
293
|
-
if (!Array.isArray(props.values)) {
|
294
|
-
updatedValues = values.reduce((acc: AnyObject, v) => {
|
295
|
-
acc[v.name] = v.value;
|
296
|
-
return acc;
|
297
|
-
}, {});
|
298
|
-
}
|
299
|
-
|
300
|
-
emit("update:values", updatedValues);
|
301
|
-
}
|
302
|
-
|
303
329
|
function onRemoveVariation(name: string) {
|
304
330
|
if (!name) return;
|
305
331
|
|
@@ -1,70 +1,72 @@
|
|
1
1
|
<template>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
2
|
+
<div class="flex flex-grow flex-col flex-nowrap overflow-hidden h-full">
|
3
|
+
<slot name="top" />
|
4
|
+
<slot name="toolbar">
|
5
|
+
<ActionToolbar
|
6
|
+
v-if="!hideToolbar"
|
7
|
+
:title="title"
|
8
|
+
:refresh-button="refreshButton"
|
9
|
+
:actions="actions?.filter(a => a.batch)"
|
10
|
+
:action-target="controller.selectedRows.value"
|
11
|
+
:exporter="controller.exportList"
|
12
|
+
:loading="controller.isLoadingList.value || controller.isLoadingSummary.value"
|
13
|
+
@refresh="controller.refreshAll"
|
14
|
+
>
|
15
|
+
<template #default>
|
16
|
+
<slot name="action-toolbar" />
|
17
|
+
</template>
|
18
|
+
</ActionToolbar>
|
19
|
+
</slot>
|
20
|
+
<div class="flex flex-nowrap flex-grow overflow-hidden w-full">
|
21
|
+
<slot name="filters">
|
22
|
+
<CollapsableFiltersSidebar
|
23
|
+
v-if="activeFilter"
|
24
|
+
:name="controller.name"
|
25
|
+
:show-filters="showFilters"
|
26
|
+
:filters="filters"
|
27
|
+
:active-filter="activeFilter"
|
28
|
+
class="dx-action-table-filters"
|
29
|
+
@update:active-filter="controller.setActiveFilter"
|
30
|
+
/>
|
31
|
+
</slot>
|
32
|
+
<slot>
|
33
|
+
<ActionTable
|
34
|
+
class="flex-grow"
|
35
|
+
:pagination="controller.pagination.value"
|
36
|
+
:selected-rows="controller.selectedRows.value"
|
37
|
+
:label="controller.label"
|
38
|
+
:name="controller.name"
|
39
|
+
:class="tableClass"
|
40
|
+
:summary="controller.summary.value"
|
41
|
+
:loading-list="controller.isLoadingList.value"
|
42
|
+
:loading-summary="controller.isLoadingSummary.value"
|
43
|
+
:paged-items="controller.pagedItems.value"
|
44
|
+
:columns="columns"
|
45
|
+
:selection="selection"
|
46
|
+
@update:selected-rows="controller.setSelectedRows"
|
47
|
+
@update:pagination="controller.setPagination"
|
48
|
+
/>
|
49
|
+
</slot>
|
50
|
+
<slot name="panels">
|
51
|
+
<PanelsDrawer
|
52
|
+
v-if="activeItem && panels"
|
53
|
+
:title="panelTitle"
|
54
|
+
:model-value="activePanel"
|
55
|
+
:active-item="activeItem"
|
56
|
+
:panels="panels"
|
57
|
+
@update:model-value="panel => controller.activatePanel(activeItem, panel)"
|
58
|
+
@close="controller.setActiveItem(null)"
|
59
|
+
>
|
60
|
+
<template #controls>
|
61
|
+
<PreviousNextControls
|
62
|
+
:is-loading="controller.isLoadingList.value"
|
63
|
+
@next="controller.getNextItem"
|
64
|
+
/>
|
65
|
+
</template>
|
66
|
+
</PanelsDrawer>
|
67
|
+
</slot>
|
68
|
+
</div>
|
69
|
+
</div>
|
68
70
|
</template>
|
69
71
|
<script setup lang="ts">
|
70
72
|
import { computed } from "vue";
|
@@ -75,10 +77,8 @@ import ActionTable from "../ActionTable.vue";
|
|
75
77
|
import { CollapsableFiltersSidebar } from "../Filters";
|
76
78
|
import { ActionToolbar } from "../Toolbars";
|
77
79
|
|
78
|
-
|
80
|
+
export interface ActionTableLayoutProps {
|
79
81
|
title?: string;
|
80
|
-
refreshButton: boolean;
|
81
|
-
showFilters: boolean;
|
82
82
|
controller: ActionController;
|
83
83
|
columns: TableColumn[];
|
84
84
|
filters?: FilterGroup[];
|
@@ -87,7 +87,17 @@ const props = defineProps<{
|
|
87
87
|
exporter?: () => Promise<void>;
|
88
88
|
panelTitleField?: string;
|
89
89
|
tableClass?: string;
|
90
|
-
|
90
|
+
refreshButton?: boolean;
|
91
|
+
showFilters?: boolean;
|
92
|
+
hideToolbar?: boolean;
|
93
|
+
selection?: "multiple" | "single";
|
94
|
+
}
|
95
|
+
|
96
|
+
const props = withDefaults(defineProps<ActionTableLayoutProps>(), {
|
97
|
+
title: "",
|
98
|
+
tableClass: "",
|
99
|
+
selection: "multiple"
|
100
|
+
});
|
91
101
|
|
92
102
|
const activeFilter = computed(() => props.controller.activeFilter.value);
|
93
103
|
const activeItem = computed(() => props.controller.activeItem.value);
|
@@ -1,33 +1,33 @@
|
|
1
1
|
<template>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
2
|
+
<div class="dx-action-toolbar flex items-center">
|
3
|
+
<div class="flex-grow px-6">
|
4
|
+
<slot name="title">
|
5
|
+
<h4 v-if="title">
|
6
|
+
{{ title }}
|
7
|
+
</h4>
|
8
|
+
</slot>
|
9
|
+
</div>
|
10
|
+
<div class="py-3 flex items-center flex-nowrap">
|
11
|
+
<slot />
|
12
|
+
<RefreshButton
|
13
|
+
v-if="refreshButton"
|
14
|
+
:loading="loading"
|
15
|
+
@click="$emit('refresh')"
|
16
|
+
/>
|
17
|
+
<ExportButton
|
18
|
+
v-if="exporter"
|
19
|
+
:exporter="exporter"
|
20
|
+
class="ml-4"
|
21
|
+
/>
|
22
|
+
<ActionMenu
|
23
|
+
v-if="actions && actions.length > 0"
|
24
|
+
class="ml-4 dx-batch-actions"
|
25
|
+
:target="actionTarget"
|
26
|
+
:actions="actions"
|
27
|
+
/>
|
28
|
+
<slot name="after" />
|
29
|
+
</div>
|
30
|
+
</div>
|
31
31
|
</template>
|
32
32
|
<script setup lang="ts">
|
33
33
|
import { ActionTargetItem, AnyObject, ResourceAction } from "../../../types";
|