quasar-ui-danx 0.4.41 → 0.4.42
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 +3511 -3432
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +55 -55
- package/dist/danx.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Utility/Buttons/ActionButton.vue +64 -9
- package/src/components/Utility/Buttons/index.ts +1 -0
- package/src/components/Utility/Dialogs/InfoDialog.vue +2 -0
- package/src/components/Utility/Files/FilePreview.vue +14 -8
- package/src/helpers/formats.ts +6 -3
- package/src/helpers/request.ts +2 -2
package/package.json
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
<QBtn
|
3
3
|
:loading="isSaving"
|
4
4
|
class="shadow-none"
|
5
|
-
:class="colorClass"
|
6
|
-
|
5
|
+
:class="disabled ? 'text-slate-800 bg-slate-500 opacity-50' : colorClass"
|
6
|
+
:disable="disabled"
|
7
|
+
@click="()=> onAction()"
|
7
8
|
>
|
8
9
|
<div class="flex items-center flex-nowrap">
|
9
10
|
<component
|
@@ -26,11 +27,36 @@
|
|
26
27
|
>
|
27
28
|
{{ tooltip }}
|
28
29
|
</QTooltip>
|
30
|
+
<QMenu
|
31
|
+
v-if="isConfirming"
|
32
|
+
:model-value="true"
|
33
|
+
>
|
34
|
+
<div class="p-4 bg-slate-600">
|
35
|
+
<div>{{ confirmText }}</div>
|
36
|
+
<div class="flex items-center flex-nowrap mt-2">
|
37
|
+
<div class="flex-grow">
|
38
|
+
<ActionButton
|
39
|
+
type="cancel"
|
40
|
+
color="gray"
|
41
|
+
@click="isConfirming = false"
|
42
|
+
/>
|
43
|
+
</div>
|
44
|
+
<ActionButton
|
45
|
+
type="confirm"
|
46
|
+
color="green"
|
47
|
+
@click="()=> onAction(true)"
|
48
|
+
/>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
</QMenu>
|
29
52
|
</QBtn>
|
30
53
|
</template>
|
31
54
|
<script setup lang="ts">
|
32
55
|
import {
|
33
56
|
FaSolidArrowsRotate as RefreshIcon,
|
57
|
+
FaSolidCircleCheck as ConfirmIcon,
|
58
|
+
FaSolidCircleXmark as CancelIcon,
|
59
|
+
FaSolidCopy as CopyIcon,
|
34
60
|
FaSolidPause as PauseIcon,
|
35
61
|
FaSolidPencil as EditIcon,
|
36
62
|
FaSolidPlay as PlayIcon,
|
@@ -38,11 +64,11 @@ import {
|
|
38
64
|
FaSolidStop as StopIcon,
|
39
65
|
FaSolidTrash as TrashIcon
|
40
66
|
} from "danx-icon";
|
41
|
-
import { computed } from "vue";
|
67
|
+
import { computed, ref } from "vue";
|
42
68
|
import { ActionTarget, ResourceAction } from "../../../types";
|
43
69
|
|
44
70
|
export interface ActionButtonProps {
|
45
|
-
type?: "trash" | "trash-red" | "create" | "edit" | "play" | "stop" | "pause" | "refresh";
|
71
|
+
type?: "trash" | "trash-red" | "create" | "edit" | "copy" | "play" | "stop" | "pause" | "refresh" | "confirm" | "cancel";
|
46
72
|
color?: "red" | "blue" | "sky" | "green" | "green-invert" | "lime" | "white" | "gray";
|
47
73
|
icon?: object | string;
|
48
74
|
iconClass?: string;
|
@@ -52,6 +78,9 @@ export interface ActionButtonProps {
|
|
52
78
|
action?: ResourceAction;
|
53
79
|
target?: ActionTarget;
|
54
80
|
input?: object;
|
81
|
+
disabled?: boolean;
|
82
|
+
confirm?: boolean;
|
83
|
+
confirmText?: string;
|
55
84
|
}
|
56
85
|
|
57
86
|
const emit = defineEmits(["success", "error", "always"]);
|
@@ -64,7 +93,8 @@ const props = withDefaults(defineProps<ActionButtonProps>(), {
|
|
64
93
|
tooltip: "",
|
65
94
|
action: null,
|
66
95
|
target: null,
|
67
|
-
input: null
|
96
|
+
input: null,
|
97
|
+
confirmText: "Are you sure?"
|
68
98
|
});
|
69
99
|
|
70
100
|
const colorClass = computed(() => {
|
@@ -101,11 +131,26 @@ const typeOptions = computed(() => {
|
|
101
131
|
icon: CreateIcon,
|
102
132
|
iconClass: "w-3"
|
103
133
|
};
|
134
|
+
case "confirm":
|
135
|
+
return {
|
136
|
+
icon: ConfirmIcon,
|
137
|
+
iconClass: "w-3"
|
138
|
+
};
|
139
|
+
case "cancel":
|
140
|
+
return {
|
141
|
+
icon: CancelIcon,
|
142
|
+
iconClass: "w-3"
|
143
|
+
};
|
104
144
|
case "edit":
|
105
145
|
return {
|
106
146
|
icon: EditIcon,
|
107
147
|
iconClass: "w-3"
|
108
148
|
};
|
149
|
+
case "copy":
|
150
|
+
return {
|
151
|
+
icon: CopyIcon,
|
152
|
+
iconClass: "w-3"
|
153
|
+
};
|
109
154
|
case "play":
|
110
155
|
return {
|
111
156
|
icon: PlayIcon,
|
@@ -136,19 +181,27 @@ const typeOptions = computed(() => {
|
|
136
181
|
|
137
182
|
const isSaving = computed(() => {
|
138
183
|
if (props.saving) return true;
|
184
|
+
if (props.action) {
|
185
|
+
return props.action.isApplying;
|
186
|
+
}
|
139
187
|
if (props.target) {
|
140
188
|
if (Array.isArray(props.target)) {
|
141
189
|
return props.target.some((t) => t.isSaving);
|
142
190
|
}
|
143
191
|
return props.target.isSaving;
|
144
192
|
}
|
145
|
-
if (props.action) {
|
146
|
-
return props.action.isApplying;
|
147
|
-
}
|
148
193
|
return false;
|
149
194
|
});
|
150
195
|
|
151
|
-
|
196
|
+
const isConfirming = ref(false);
|
197
|
+
function onAction(isConfirmed = false) {
|
198
|
+
// Make sure this action is confirmed if the confirm prop is set
|
199
|
+
if (props.confirm && !isConfirmed) {
|
200
|
+
isConfirming.value = true;
|
201
|
+
return false;
|
202
|
+
}
|
203
|
+
isConfirming.value = false;
|
204
|
+
if (props.disabled) return;
|
152
205
|
if (props.action) {
|
153
206
|
props.action.trigger(props.target, props.input).then(async (response) => {
|
154
207
|
emit("success", typeof response.json === "function" ? await response.json() : response);
|
@@ -158,6 +211,8 @@ function onAction() {
|
|
158
211
|
}).finally(() => {
|
159
212
|
emit("always");
|
160
213
|
});
|
214
|
+
} else {
|
215
|
+
emit("always");
|
161
216
|
}
|
162
217
|
}
|
163
218
|
</script>
|
@@ -23,6 +23,7 @@
|
|
23
23
|
:label="doneText"
|
24
24
|
class="dx-dialog-button dx-dialog-button-done"
|
25
25
|
:class="doneClass"
|
26
|
+
:disable="disable"
|
26
27
|
@click="onClose"
|
27
28
|
>
|
28
29
|
<slot name="done-text" />
|
@@ -39,6 +40,7 @@ import DialogLayout from "./DialogLayout";
|
|
39
40
|
const emit = defineEmits(["update:model-value", "close"]);
|
40
41
|
defineProps({
|
41
42
|
...DialogLayout.props,
|
43
|
+
disable: Boolean,
|
42
44
|
doneClass: {
|
43
45
|
type: [String, Object],
|
44
46
|
default: ""
|
@@ -39,18 +39,23 @@
|
|
39
39
|
>
|
40
40
|
<PdfIcon
|
41
41
|
v-if="isPdf"
|
42
|
-
class="w-
|
42
|
+
class="w-3/4"
|
43
43
|
/>
|
44
44
|
<TextFileIcon
|
45
45
|
v-else
|
46
|
-
class="w-
|
46
|
+
class="w-3/4"
|
47
47
|
/>
|
48
|
-
<
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
<template v-if="filename">
|
49
|
+
<div
|
50
|
+
v-if="showFilename"
|
51
|
+
class="text-[.7rem] bg-slate-900 text-slate-300 opacity-80 h-[2.25rem] py-.5 px-1 absolute-bottom"
|
52
|
+
>
|
53
|
+
{{ filename }}
|
54
|
+
</div>
|
55
|
+
<QTooltip v-else>
|
56
|
+
{{ filename }}
|
57
|
+
</QTooltip>
|
58
|
+
</template>
|
54
59
|
</div>
|
55
60
|
</div>
|
56
61
|
<div
|
@@ -152,6 +157,7 @@ export interface FilePreviewProps {
|
|
152
157
|
file?: UploadedFile;
|
153
158
|
relatedFiles?: UploadedFile[];
|
154
159
|
missingIcon?: any;
|
160
|
+
showFilename?: boolean;
|
155
161
|
downloadButtonClass?: string;
|
156
162
|
imageFit?: "cover" | "contain" | "fill" | "none" | "scale-down";
|
157
163
|
downloadable?: boolean;
|
package/src/helpers/formats.ts
CHANGED
@@ -89,11 +89,14 @@ export function fDate(dateTime: string | DateTime | null, { empty = "--", format
|
|
89
89
|
/**
|
90
90
|
* Parses a date string into a Luxon DateTime object
|
91
91
|
*/
|
92
|
-
export function parseDateTime(dateTime: string | DateTime | null): DateTime<boolean> | null {
|
92
|
+
export function parseDateTime(dateTime: string | DateTime | number | null): DateTime<boolean> | null {
|
93
|
+
if (typeof dateTime === "number") {
|
94
|
+
return DateTime.fromMillis(dateTime as number);
|
95
|
+
}
|
93
96
|
if (typeof dateTime === "string") {
|
94
97
|
return parseGenericDateTime(dateTime);
|
95
98
|
}
|
96
|
-
return dateTime || DateTime.fromSQL("0000-00-00 00:00:00");
|
99
|
+
return dateTime as DateTime<boolean> || DateTime.fromSQL("0000-00-00 00:00:00");
|
97
100
|
}
|
98
101
|
|
99
102
|
/**
|
@@ -193,7 +196,7 @@ export function fSecondsToDuration(seconds: number) {
|
|
193
196
|
/**
|
194
197
|
* Formats a duration between two date strings in 00h 00m 00s format
|
195
198
|
*/
|
196
|
-
export function fDuration(start: string, end?: string) {
|
199
|
+
export function fDuration(start: string | number, end?: string | number) {
|
197
200
|
const endDateTime = end ? parseDateTime(end) : DateTime.now();
|
198
201
|
const diff = endDateTime?.diff(parseDateTime(start) || DateTime.now(), ["hours", "minutes", "seconds"]);
|
199
202
|
if (!diff?.isValid) {
|
package/src/helpers/request.ts
CHANGED
@@ -19,7 +19,7 @@ export const request: RequestApi = {
|
|
19
19
|
|
20
20
|
async call(url, options) {
|
21
21
|
options = options || {};
|
22
|
-
const abortKey = options?.abortOn !== undefined ? options.abortOn : url;
|
22
|
+
const abortKey = options?.abortOn !== undefined ? options.abortOn : url + JSON.stringify(options.params || "");
|
23
23
|
const timestamp = new Date().getTime();
|
24
24
|
|
25
25
|
if (abortKey) {
|
@@ -42,7 +42,7 @@ export const request: RequestApi = {
|
|
42
42
|
options.params[key] = JSON.stringify(value);
|
43
43
|
}
|
44
44
|
}
|
45
|
-
|
45
|
+
|
46
46
|
url += (url.match(/\?/) ? "&" : "?") + new URLSearchParams(options.params).toString();
|
47
47
|
delete options.params;
|
48
48
|
}
|