quasar-ui-danx 0.0.39 → 0.0.41
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
CHANGED
|
@@ -84,6 +84,9 @@
|
|
|
84
84
|
</component>
|
|
85
85
|
</q-td>
|
|
86
86
|
</template>
|
|
87
|
+
<template #bottom>
|
|
88
|
+
<ActionInputComponent />
|
|
89
|
+
</template>
|
|
87
90
|
</q-table>
|
|
88
91
|
</template>
|
|
89
92
|
|
|
@@ -92,7 +95,7 @@ import { ref } from 'vue';
|
|
|
92
95
|
import { getItem, setItem } from '../../helpers';
|
|
93
96
|
import { DragHandleIcon as RowResizeIcon } from '../../svg';
|
|
94
97
|
import { HandleDraggable } from '../DragAndDrop';
|
|
95
|
-
import { mapSortBy, RenderComponent } from '../index';
|
|
98
|
+
import { ActionInputComponent, mapSortBy, RenderComponent } from '../index';
|
|
96
99
|
import { ActionMenu, EmptyTableState, registerStickyScrolling, TableSummaryRow } from './index';
|
|
97
100
|
|
|
98
101
|
defineEmits(['action', 'filter', 'update:quasar-pagination', 'update:selected-rows']);
|
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
v-if="activeActionInput"
|
|
5
5
|
:component="activeActionInput.component"
|
|
6
6
|
:is-saving="isSaving"
|
|
7
|
-
@confirm="
|
|
7
|
+
@confirm="onConfirm"
|
|
8
8
|
@close="activeActionInput.cancel"
|
|
9
9
|
/>
|
|
10
10
|
</div>
|
|
11
11
|
</template>
|
|
12
12
|
<script setup>
|
|
13
|
-
import
|
|
13
|
+
import { ref } from 'vue';
|
|
14
14
|
import { activeActionInput } from '../../../helpers';
|
|
15
|
+
import RenderComponent from './RenderComponent';
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
+
}
|
|
21
23
|
</script>
|
package/src/helpers/actions.ts
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { shallowRef } from "vue";
|
|
2
2
|
import { FlashMessages } from "./index";
|
|
3
3
|
|
|
4
4
|
interface ActionOptions {
|
|
5
|
-
name
|
|
6
|
-
label
|
|
5
|
+
name?: string;
|
|
6
|
+
label?: string;
|
|
7
7
|
menu?: boolean;
|
|
8
8
|
batch?: boolean;
|
|
9
|
+
category?: string;
|
|
9
10
|
inputComponent?: (target: object[] | object) => any;
|
|
10
|
-
enabled?: (target: object) => boolean;
|
|
11
|
-
onAction?: (action: string | null, target: object, input: any) => any
|
|
12
|
-
onBatchAction?: (action: string | null, targets: object[], input: any) => any
|
|
13
|
-
|
|
11
|
+
enabled?: (target: object[] | object) => boolean;
|
|
12
|
+
onAction?: (action: string | null, target: object, input: any) => Promise<any>;
|
|
13
|
+
onBatchAction?: (action: string | null, targets: object[], input: any) => Promise<any>;
|
|
14
|
+
onSuccess?: (action: string | null, targets: object, input: any) => any;
|
|
15
|
+
onError?: (action: string | null, targets: object, input: any) => any;
|
|
16
|
+
onFinish?: (action: string | null, targets: object, input: any) => any;
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export const activeActionInput = shallowRef(null);
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* Hook to perform an action on a set of targets
|
|
20
|
-
* This helper allows you
|
|
23
|
+
* This helper allows you applyActionto perform actions by name on a set of targets using a provided list of actions
|
|
21
24
|
*
|
|
22
25
|
* @param actions
|
|
23
26
|
* @param {ActionOptions} globalOptions
|
|
24
27
|
*/
|
|
25
28
|
export function useActions(actions: ActionOptions[], globalOptions: ActionOptions = null) {
|
|
26
|
-
const
|
|
27
|
-
const activeTarget = ref(null);
|
|
29
|
+
const isSavingTarget = shallowRef(null);
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* Resolves an action by name or object, adds globalOptions and overrides any passes options
|
|
@@ -44,8 +46,7 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
|
|
|
44
46
|
|
|
45
47
|
return {
|
|
46
48
|
actions,
|
|
47
|
-
|
|
48
|
-
activeTarget,
|
|
49
|
+
isSavingTarget,
|
|
49
50
|
resolveAction,
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -66,7 +67,7 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
|
|
|
66
67
|
},
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
|
-
*
|
|
70
|
+
* TODO: HOW TO INTEGRATE optimistic updates and single item updates?
|
|
70
71
|
*/
|
|
71
72
|
async applyAction(item, input, itemData = {}) {
|
|
72
73
|
isSavingItem.value = item;
|
|
@@ -99,24 +100,35 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
|
|
|
99
100
|
async performAction(name: string | object, target: object[] | object, input: any = null) {
|
|
100
101
|
const action = resolveAction(name);
|
|
101
102
|
const component = action.inputComponent && action.inputComponent(target);
|
|
103
|
+
let result = null;
|
|
102
104
|
|
|
105
|
+
isSavingTarget.value = target;
|
|
106
|
+
|
|
107
|
+
// If no component input is required, we can directly perform the action
|
|
103
108
|
if (component) {
|
|
104
|
-
|
|
109
|
+
// If the action requires an input, we set the activeActionInput to the input component.
|
|
110
|
+
// This will tell the ActionInputComponent to render the input component, and confirm or cancel the
|
|
111
|
+
// action The confirm function has the input from the component passed and will resolve the promise
|
|
112
|
+
// with the result of the action
|
|
113
|
+
result = await new Promise((resolve, reject) => {
|
|
105
114
|
activeActionInput.value = {
|
|
106
115
|
component,
|
|
107
|
-
confirm: resolve,
|
|
116
|
+
confirm: async () => resolve(await onConfirmAction(action, target, input)),
|
|
108
117
|
cancel: reject
|
|
109
118
|
};
|
|
110
119
|
});
|
|
111
120
|
activeActionInput.value = null;
|
|
121
|
+
} else {
|
|
122
|
+
result = await onConfirmAction(action, target, input);
|
|
112
123
|
}
|
|
113
124
|
|
|
114
|
-
|
|
125
|
+
isSavingTarget.value = null;
|
|
126
|
+
return result;
|
|
115
127
|
}
|
|
116
128
|
};
|
|
117
129
|
}
|
|
118
130
|
|
|
119
|
-
async function onConfirmAction(action, target, input) {
|
|
131
|
+
async function onConfirmAction(action: ActionOptions, target: object[] | object, input: any = null) {
|
|
120
132
|
if (!action.onAction) {
|
|
121
133
|
throw new Error("No onAction handler found for the selected action:" + action.name);
|
|
122
134
|
}
|
|
@@ -141,7 +153,7 @@ async function onConfirmAction(action, target, input) {
|
|
|
141
153
|
}
|
|
142
154
|
|
|
143
155
|
if (action.onSuccess) {
|
|
144
|
-
|
|
156
|
+
action.onSuccess(result, target, input);
|
|
145
157
|
}
|
|
146
158
|
|
|
147
159
|
} else {
|
|
@@ -157,12 +169,12 @@ async function onConfirmAction(action, target, input) {
|
|
|
157
169
|
FlashMessages.combine("error", errors);
|
|
158
170
|
|
|
159
171
|
if (action.onError) {
|
|
160
|
-
|
|
172
|
+
action.onError(result, target, input);
|
|
161
173
|
}
|
|
162
174
|
}
|
|
163
175
|
|
|
164
176
|
if (action.onFinish) {
|
|
165
|
-
|
|
177
|
+
action.onFinish(result, target, input);
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
return result;
|