quasar-ui-danx 0.0.42 → 0.0.44
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/package.json +1 -1
- package/src/components/ActionTable/ActionTable.vue +18 -50
- package/src/components/ActionTable/ActionTableColumn.vue +72 -0
- package/src/components/ActionTable/index.ts +1 -0
- package/src/components/ActionTable/listControls.ts +4 -4
- package/src/components/Utility/Formats/IconWithTextFormat.vue +7 -3
- package/src/components/Utility/Tools/ActionVnode.vue +23 -0
- package/src/components/Utility/Tools/RenderComponent.vue +1 -5
- package/src/components/Utility/Tools/RenderVnode.vue +5 -0
- package/src/components/Utility/Tools/index.ts +2 -1
- package/src/helpers/actions.ts +12 -13
- package/src/components/Utility/Tools/ActionInputComponent.vue +0 -23
package/package.json
CHANGED
@@ -48,44 +48,17 @@
|
|
48
48
|
</q-th>
|
49
49
|
</template>
|
50
50
|
<template #body-cell="rowProps">
|
51
|
-
<
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
<RenderComponent
|
60
|
-
v-if="rowProps.col.component"
|
61
|
-
:params="[rowProps.row]"
|
62
|
-
:component="rowProps.col.component"
|
63
|
-
:text="rowProps.value"
|
64
|
-
@action="action => $emit('action', {action,target: rowProps.row})"
|
65
|
-
/>
|
66
|
-
<div v-else-if="rowProps.col.fieldList">
|
67
|
-
<div v-for="field in rowProps.col.fieldList" :key="field">
|
68
|
-
{{ rowProps.row[field] }}
|
69
|
-
</div>
|
70
|
-
</div>
|
71
|
-
<div v-else>
|
72
|
-
<slot v-bind="{name: rowProps.col.name, row: rowProps.row, value: rowProps.value}">
|
73
|
-
{{ rowProps.value }}
|
74
|
-
</slot>
|
75
|
-
</div>
|
76
|
-
<div v-if="rowProps.col.actions" class="flex-grow flex justify-end pl-2">
|
77
|
-
<ActionMenu
|
78
|
-
:actions="rowProps.col.actions"
|
79
|
-
:target="rowProps.row"
|
80
|
-
:loading="isSavingRow(rowProps.row)"
|
81
|
-
@action="(action) => $emit('action', action, rowProps.row)"
|
82
|
-
/>
|
83
|
-
</div>
|
84
|
-
</component>
|
85
|
-
</q-td>
|
51
|
+
<ActionTableColumn
|
52
|
+
:row-props="rowProps"
|
53
|
+
:settings="columnSettings[rowProps.col.name]"
|
54
|
+
:is-saving="isSavingRow(rowProps.row)"
|
55
|
+
@action="$emit('action', $event, rowProps.row)"
|
56
|
+
>
|
57
|
+
<slot />
|
58
|
+
</ActionTableColumn>
|
86
59
|
</template>
|
87
60
|
<template #bottom>
|
88
|
-
<
|
61
|
+
<ActionVnode />
|
89
62
|
</template>
|
90
63
|
</q-table>
|
91
64
|
</template>
|
@@ -95,10 +68,10 @@ import { ref } from 'vue';
|
|
95
68
|
import { getItem, setItem } from '../../helpers';
|
96
69
|
import { DragHandleIcon as RowResizeIcon } from '../../svg';
|
97
70
|
import { HandleDraggable } from '../DragAndDrop';
|
98
|
-
import {
|
99
|
-
import {
|
71
|
+
import { ActionVnode, mapSortBy } from '../index';
|
72
|
+
import { ActionTableColumn, EmptyTableState, registerStickyScrolling, TableSummaryRow } from './index';
|
100
73
|
|
101
|
-
defineEmits(['action', '
|
74
|
+
defineEmits(['action', 'update:quasar-pagination', 'update:selected-rows']);
|
102
75
|
const props = defineProps({
|
103
76
|
name: {
|
104
77
|
type: String,
|
@@ -145,19 +118,14 @@ registerStickyScrolling(actionTable);
|
|
145
118
|
const COLUMN_SETTINGS_KEY = `column-settings-${props.name}`;
|
146
119
|
const columnSettings = ref(getItem(COLUMN_SETTINGS_KEY) || {});
|
147
120
|
function onResizeColumn(column, val) {
|
148
|
-
columnSettings.value
|
121
|
+
columnSettings.value = {
|
122
|
+
...columnSettings.value,
|
123
|
+
[column.name]: {
|
124
|
+
width: Math.max(Math.min(val.distance + val.startDropZoneSize, column.maxWidth || 500), column.minWidth || 80)
|
125
|
+
}
|
126
|
+
};
|
149
127
|
setItem(COLUMN_SETTINGS_KEY, columnSettings.value);
|
150
128
|
}
|
151
|
-
function getColumnStyle(column) {
|
152
|
-
const width = columnSettings.value[column.name] || column.width;
|
153
|
-
|
154
|
-
if (width) {
|
155
|
-
return {
|
156
|
-
width: `${width}px`
|
157
|
-
};
|
158
|
-
}
|
159
|
-
return null;
|
160
|
-
}
|
161
129
|
|
162
130
|
function isSavingRow(row) {
|
163
131
|
if (!props.isSavingTarget) return false;
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<template>
|
2
|
+
<q-td :key="rowProps.key" :props="rowProps" :style="columnStyle">
|
3
|
+
<div
|
4
|
+
class="flex items-center flex-nowrap"
|
5
|
+
:class="columnClass"
|
6
|
+
>
|
7
|
+
<a
|
8
|
+
v-if="column.onClick"
|
9
|
+
class="flex-grow"
|
10
|
+
@click="column.onClick(row)"
|
11
|
+
>
|
12
|
+
<RenderVnode
|
13
|
+
v-if="column.vnode"
|
14
|
+
:vnode="column.vnode(row)"
|
15
|
+
/>
|
16
|
+
<slot v-else v-bind="{name: column.name, row, value}">
|
17
|
+
{{ value }}
|
18
|
+
</slot>
|
19
|
+
</a>
|
20
|
+
<div v-else class="flex-grow">
|
21
|
+
<RenderVnode
|
22
|
+
v-if="column.vnode"
|
23
|
+
:vnode="column.vnode(row)"
|
24
|
+
/>
|
25
|
+
<slot v-else v-bind="{name: column.name, row, value}">
|
26
|
+
{{ value }}
|
27
|
+
</slot>
|
28
|
+
</div>
|
29
|
+
<div v-if="column.actions" class="flex flex-shrink-0 pl-2">
|
30
|
+
<ActionMenu
|
31
|
+
:actions="column.actions"
|
32
|
+
:target="row"
|
33
|
+
:loading="isSaving"
|
34
|
+
@action="$emit('action', $event)"
|
35
|
+
/>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</q-td>
|
39
|
+
</template>
|
40
|
+
<script setup>
|
41
|
+
import { computed } from 'vue';
|
42
|
+
import { RenderVnode } from '../Utility';
|
43
|
+
import { ActionMenu } from './index';
|
44
|
+
|
45
|
+
defineEmits(['action']);
|
46
|
+
const props = defineProps({
|
47
|
+
rowProps: {
|
48
|
+
type: Object,
|
49
|
+
required: true
|
50
|
+
},
|
51
|
+
settings: {
|
52
|
+
type: Object,
|
53
|
+
default: null
|
54
|
+
},
|
55
|
+
isSaving: Boolean
|
56
|
+
});
|
57
|
+
|
58
|
+
const row = computed(() => props.rowProps.row);
|
59
|
+
const column = computed(() => props.rowProps.col);
|
60
|
+
const value = computed(() => props.rowProps.value);
|
61
|
+
|
62
|
+
const columnStyle = computed(() => {
|
63
|
+
const width = props.settings?.width || column.value.width;
|
64
|
+
return width ? { width: `${width}px` } : null;
|
65
|
+
});
|
66
|
+
|
67
|
+
const columnClass = computed(() => ({
|
68
|
+
'justify-end': column.value.align === 'right',
|
69
|
+
'justify-center': column.value.align === 'center',
|
70
|
+
'justify-start': column.value.align === 'left'
|
71
|
+
}));
|
72
|
+
</script>
|
@@ -6,5 +6,6 @@ export * from "./listHelpers";
|
|
6
6
|
export * from "./tableColumns";
|
7
7
|
export { default as ActionMenu } from "./ActionMenu.vue";
|
8
8
|
export { default as ActionTable } from "./ActionTable.vue";
|
9
|
+
export { default as ActionTableColumn } from "./ActionTableColumn.vue";
|
9
10
|
export { default as EmptyTableState } from "./EmptyTableState.vue";
|
10
11
|
export { default as TableSummaryRow } from "./TableSummaryRow.vue";
|
@@ -259,11 +259,11 @@ export function useListControls(name: string, {
|
|
259
259
|
* Opens the item's form with the given item and tab
|
260
260
|
*
|
261
261
|
* @param item
|
262
|
-
* @param
|
262
|
+
* @param panel
|
263
263
|
*/
|
264
|
-
function
|
264
|
+
function activatePanel(item, panel) {
|
265
265
|
activeItem.value = item;
|
266
|
-
activePanel.value =
|
266
|
+
activePanel.value = panel;
|
267
267
|
}
|
268
268
|
|
269
269
|
/**
|
@@ -336,7 +336,7 @@ export function useListControls(name: string, {
|
|
336
336
|
loadMore,
|
337
337
|
refreshAll,
|
338
338
|
getNextItem,
|
339
|
-
|
339
|
+
activatePanel,
|
340
340
|
applyFilterFromUrl,
|
341
341
|
setItemInPagedList
|
342
342
|
};
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="flex items-center">
|
3
3
|
<component :is="icon" :class="iconClass" />
|
4
4
|
<div :class="textClass">
|
5
|
-
<slot
|
5
|
+
<slot>{{ text }}</slot>
|
6
6
|
</div>
|
7
7
|
</div>
|
8
8
|
</template>
|
@@ -14,11 +14,15 @@ defineProps({
|
|
14
14
|
},
|
15
15
|
iconClass: {
|
16
16
|
type: String,
|
17
|
-
default:
|
17
|
+
default: 'w-6'
|
18
|
+
},
|
19
|
+
text: {
|
20
|
+
type: String,
|
21
|
+
default: null
|
18
22
|
},
|
19
23
|
textClass: {
|
20
24
|
type: String,
|
21
|
-
default:
|
25
|
+
default: 'ml-2'
|
22
26
|
}
|
23
27
|
});
|
24
28
|
</script>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<RenderVnode
|
4
|
+
v-if="activeActionVnode"
|
5
|
+
:vnode="activeActionVnode.vnode"
|
6
|
+
:is-saving="isSaving"
|
7
|
+
@confirm="onConfirm"
|
8
|
+
@close="activeActionVnode.cancel"
|
9
|
+
/>
|
10
|
+
</div>
|
11
|
+
</template>
|
12
|
+
<script setup>
|
13
|
+
import { ref } from 'vue';
|
14
|
+
import { activeActionVnode } from '../../../helpers';
|
15
|
+
import { RenderVnode } from './index';
|
16
|
+
|
17
|
+
const isSaving = ref(false);
|
18
|
+
async function onConfirm(input) {
|
19
|
+
isSaving.value = true;
|
20
|
+
await activeActionVnode.value.confirm(input);
|
21
|
+
isSaving.value = false;
|
22
|
+
}
|
23
|
+
</script>
|
@@ -25,17 +25,13 @@ const props = defineProps({
|
|
25
25
|
type: Array,
|
26
26
|
default: () => []
|
27
27
|
},
|
28
|
-
text: {
|
29
|
-
type: String,
|
30
|
-
default: undefined
|
31
|
-
},
|
32
28
|
overrideProps: {
|
33
29
|
type: Object,
|
34
30
|
default: () => ({})
|
35
31
|
}
|
36
32
|
});
|
37
33
|
|
38
|
-
const content = computed(() => resolvedComponent.value?.value || resolvedComponent.value?.props?.text
|
34
|
+
const content = computed(() => resolvedComponent.value?.value || resolvedComponent.value?.props?.text);
|
39
35
|
const resolvedComponent = computed(() => {
|
40
36
|
if (typeof props.component === 'function') {
|
41
37
|
return props.component(...props.params);
|
package/src/helpers/actions.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { shallowRef } from "vue";
|
1
|
+
import { shallowRef, VNode } from "vue";
|
2
2
|
import { FlashMessages } from "./index";
|
3
3
|
|
4
4
|
interface ActionOptions {
|
@@ -8,7 +8,7 @@ interface ActionOptions {
|
|
8
8
|
batch?: boolean;
|
9
9
|
category?: string;
|
10
10
|
class?: string;
|
11
|
-
|
11
|
+
vnode?: (target: object[] | object) => VNode;
|
12
12
|
enabled?: (target: object) => boolean;
|
13
13
|
batchEnabled?: (targets: object[]) => boolean;
|
14
14
|
onAction?: (action: string | null, target: object, input: any) => Promise<any>;
|
@@ -18,7 +18,7 @@ interface ActionOptions {
|
|
18
18
|
onFinish?: (action: string | null, targets: object, input: any) => any;
|
19
19
|
}
|
20
20
|
|
21
|
-
export const
|
21
|
+
export const activeActionVnode = shallowRef(null);
|
22
22
|
|
23
23
|
/**
|
24
24
|
* Hook to perform an action on a set of targets
|
@@ -98,25 +98,25 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
|
|
98
98
|
*/
|
99
99
|
async performAction(name: string | object, target: object[] | object, input: any = null) {
|
100
100
|
const action = resolveAction(name);
|
101
|
-
const
|
101
|
+
const vnode = action.vnode && action.vnode(target);
|
102
102
|
let result = null;
|
103
103
|
|
104
104
|
isSavingTarget.value = target;
|
105
105
|
|
106
|
-
// If
|
107
|
-
if (
|
108
|
-
// If the action requires an input, we set the
|
109
|
-
// This will tell the
|
106
|
+
// If additional input is required, first render the vnode and wait for the confirm or cancel action
|
107
|
+
if (vnode) {
|
108
|
+
// If the action requires an input, we set the activeActionVnode to the input component.
|
109
|
+
// This will tell the ActionVnode to render the input component, and confirm or cancel the
|
110
110
|
// action The confirm function has the input from the component passed and will resolve the promise
|
111
111
|
// with the result of the action
|
112
112
|
result = await new Promise((resolve, reject) => {
|
113
|
-
|
114
|
-
|
113
|
+
activeActionVnode.value = {
|
114
|
+
vnode,
|
115
115
|
confirm: async input => {
|
116
116
|
const result = await onConfirmAction(action, target, input);
|
117
117
|
|
118
118
|
// Only resolve when we have a non-error response, so we can show the error message w/o
|
119
|
-
// hiding the dialog /
|
119
|
+
// hiding the dialog / vnode
|
120
120
|
if (result === undefined || result === true || result?.success) {
|
121
121
|
resolve(result);
|
122
122
|
}
|
@@ -125,7 +125,7 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
|
|
125
125
|
};
|
126
126
|
});
|
127
127
|
|
128
|
-
|
128
|
+
activeActionVnode.value = null;
|
129
129
|
} else {
|
130
130
|
result = await onConfirmAction(action, target, input);
|
131
131
|
}
|
@@ -183,6 +183,5 @@ async function onConfirmAction(action: ActionOptions, target: object[] | object,
|
|
183
183
|
action.onFinish(result, target, input);
|
184
184
|
}
|
185
185
|
|
186
|
-
console.log("onConrirm result", result);
|
187
186
|
return result;
|
188
187
|
}
|
@@ -1,23 +0,0 @@
|
|
1
|
-
<template>
|
2
|
-
<div>
|
3
|
-
<RenderComponent
|
4
|
-
v-if="activeActionInput"
|
5
|
-
:component="activeActionInput.component"
|
6
|
-
:is-saving="isSaving"
|
7
|
-
@confirm="onConfirm"
|
8
|
-
@close="activeActionInput.cancel"
|
9
|
-
/>
|
10
|
-
</div>
|
11
|
-
</template>
|
12
|
-
<script setup>
|
13
|
-
import { ref } from 'vue';
|
14
|
-
import { activeActionInput } from '../../../helpers';
|
15
|
-
import RenderComponent from './RenderComponent';
|
16
|
-
|
17
|
-
const isSaving = ref(false);
|
18
|
-
async function onConfirm(input) {
|
19
|
-
isSaving.value = true;
|
20
|
-
await activeActionInput.value.confirm(input);
|
21
|
-
isSaving.value = false;
|
22
|
-
}
|
23
|
-
</script>
|