quasar-ui-danx 0.4.20 → 0.4.22
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 +2515 -2459
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +46 -46
- package/dist/danx.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ActionTable/Form/Fields/BooleanField.vue +25 -23
- package/src/components/ActionTable/Form/Fields/IntegerField.vue +9 -13
- package/src/components/ActionTable/Form/Fields/LabelValueBlock.vue +22 -9
- package/src/components/ActionTable/Form/Fields/NumberField.vue +1 -8
- package/src/helpers/formats.ts +6 -0
- package/src/helpers/objectStore.ts +28 -0
- package/src/helpers/routes.ts +3 -2
- package/src/types/fields.d.ts +8 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
<template>
|
2
2
|
<QToggle
|
3
|
-
:data-testid="'boolean-field-' +
|
3
|
+
:data-testid="'boolean-field-' + (name || label)"
|
4
4
|
:model-value="modelValue || (toggleIndeterminate ? modelValue : false)"
|
5
5
|
:disable="disable || readonly"
|
6
6
|
:toggle-indeterminate="toggleIndeterminate"
|
@@ -8,37 +8,39 @@
|
|
8
8
|
@update:model-value="$emit('update:model-value', $event)"
|
9
9
|
>
|
10
10
|
<FieldLabel
|
11
|
-
:
|
11
|
+
:label="label || name"
|
12
|
+
:name="name"
|
12
13
|
:show-name="showName"
|
13
14
|
:class="labelClass"
|
14
15
|
/>
|
15
16
|
</QToggle>
|
16
17
|
</template>
|
17
18
|
|
18
|
-
<script setup>
|
19
|
+
<script setup lang="ts">
|
19
20
|
import FieldLabel from "./FieldLabel";
|
20
21
|
|
21
22
|
defineEmits(["update:model-value"]);
|
22
23
|
defineProps({
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
24
|
+
label: {
|
25
|
+
type: String,
|
26
|
+
default: null
|
27
|
+
},
|
28
|
+
name: {
|
29
|
+
type: String,
|
30
|
+
default: null
|
31
|
+
},
|
32
|
+
required: Boolean,
|
33
|
+
modelValue: {
|
34
|
+
type: Boolean,
|
35
|
+
default: undefined
|
36
|
+
},
|
37
|
+
labelClass: {
|
38
|
+
type: String,
|
39
|
+
default: "text-sm"
|
40
|
+
},
|
41
|
+
showName: Boolean,
|
42
|
+
toggleIndeterminate: Boolean,
|
43
|
+
disable: Boolean,
|
44
|
+
readonly: Boolean
|
43
45
|
});
|
44
46
|
</script>
|
@@ -1,26 +1,22 @@
|
|
1
1
|
<template>
|
2
2
|
<NumberField
|
3
|
-
|
3
|
+
v-bind="$props"
|
4
4
|
:precision="0"
|
5
5
|
:model-value="modelValue"
|
6
|
-
:show-name="showName"
|
7
6
|
@update:model-value="$emit('update:model-value', $event)"
|
8
7
|
/>
|
9
8
|
</template>
|
10
9
|
|
11
|
-
<script setup>
|
10
|
+
<script setup lang="ts">
|
11
|
+
import { NumberFieldProps } from "../../../../types";
|
12
12
|
import NumberField from "./NumberField";
|
13
13
|
|
14
14
|
defineEmits(["update:model-value"]);
|
15
|
-
defineProps({
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
type: Object,
|
22
|
-
required: true
|
23
|
-
},
|
24
|
-
showName: Boolean
|
15
|
+
withDefaults(defineProps<NumberFieldProps>(), {
|
16
|
+
modelValue: "",
|
17
|
+
label: undefined,
|
18
|
+
delay: 1000,
|
19
|
+
min: undefined,
|
20
|
+
max: undefined
|
25
21
|
});
|
26
22
|
</script>
|
@@ -4,14 +4,25 @@
|
|
4
4
|
{{ label }}
|
5
5
|
</div>
|
6
6
|
<div :class="valueClass">
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
<template v-if="url">
|
8
|
+
<a
|
9
|
+
v-if="!isLargeContent"
|
10
|
+
target="_blank"
|
11
|
+
:href="url"
|
12
|
+
>
|
13
|
+
<slot>{{ formattedValue }}</slot>
|
14
|
+
</a>
|
15
|
+
<template v-else>
|
16
|
+
<slot>{{ formattedValue }}</slot>
|
17
|
+
<a
|
18
|
+
target="_blank"
|
19
|
+
:href="url"
|
20
|
+
class="inline-block ml-2"
|
21
|
+
>
|
22
|
+
<LinkIcon class="w-4" />
|
23
|
+
</a>
|
24
|
+
</template>
|
25
|
+
</template>
|
15
26
|
<template v-else>
|
16
27
|
<slot>{{ formattedValue }}</slot>
|
17
28
|
</template>
|
@@ -19,12 +30,13 @@
|
|
19
30
|
</div>
|
20
31
|
</template>
|
21
32
|
<script setup lang="ts">
|
33
|
+
import { FaSolidLink as LinkIcon } from "danx-icon";
|
22
34
|
import { computed } from "vue";
|
23
35
|
import { fBoolean, fNumber } from "../../../../helpers";
|
24
36
|
|
25
37
|
export interface LabelValueBlockProps {
|
26
38
|
label: string;
|
27
|
-
value
|
39
|
+
value?: string | number | boolean;
|
28
40
|
url?: string;
|
29
41
|
dense?: boolean;
|
30
42
|
nowrap?: boolean;
|
@@ -36,6 +48,7 @@ const props = withDefaults(defineProps<LabelValueBlockProps>(), {
|
|
36
48
|
});
|
37
49
|
|
38
50
|
const valueClass = computed(() => ({ "mt-2": !props.dense, "mt-1": props.dense, "text-no-wrap": props.nowrap }));
|
51
|
+
const isLargeContent = computed(() => typeof props.value === "string" && props.value.length > 30);
|
39
52
|
const formattedValue = computed(() => {
|
40
53
|
switch (typeof props.value) {
|
41
54
|
case "boolean":
|
@@ -11,18 +11,11 @@
|
|
11
11
|
import { useDebounceFn } from "@vueuse/core";
|
12
12
|
import { nextTick, ref, watch } from "vue";
|
13
13
|
import { fNumber } from "../../../../helpers";
|
14
|
-
import { AnyObject,
|
14
|
+
import { AnyObject, NumberFieldProps } from "../../../../types";
|
15
15
|
import TextField from "./TextField";
|
16
16
|
|
17
17
|
const emit = defineEmits(["update:model-value", "update"]);
|
18
18
|
|
19
|
-
export interface NumberFieldProps extends TextFieldProps {
|
20
|
-
precision?: number;
|
21
|
-
delay?: number;
|
22
|
-
currency?: boolean;
|
23
|
-
min?: number;
|
24
|
-
max?: number;
|
25
|
-
}
|
26
19
|
|
27
20
|
const props = withDefaults(defineProps<NumberFieldProps>(), {
|
28
21
|
modelValue: "",
|
package/src/helpers/formats.ts
CHANGED
@@ -144,6 +144,9 @@ export function fElapsedTime(start: string, end?: string) {
|
|
144
144
|
* Formats an amount into USD currency format
|
145
145
|
*/
|
146
146
|
export function fCurrency(amount: number, options?: object) {
|
147
|
+
if (amount === null || amount === undefined || isNaN(amount)) {
|
148
|
+
return "$-";
|
149
|
+
}
|
147
150
|
return new Intl.NumberFormat("en-US", {
|
148
151
|
style: "currency",
|
149
152
|
currency: "USD",
|
@@ -179,6 +182,9 @@ export function fShortCurrency(value: string | number, options?: { round: boolea
|
|
179
182
|
* Formats a number into a shorthand human-readable format (ie: 1.2M or 5K)
|
180
183
|
*/
|
181
184
|
export function fShortNumber(value: string | number, options?: { round: boolean }) {
|
185
|
+
if (value === "" || value === null || value === undefined) {
|
186
|
+
return "-";
|
187
|
+
}
|
182
188
|
const shorts = [
|
183
189
|
{ pow: 3, unit: "K" },
|
184
190
|
{ pow: 6, unit: "M" },
|
@@ -1,9 +1,19 @@
|
|
1
1
|
import { uid } from "quasar";
|
2
2
|
import { ShallowReactive, shallowReactive } from "vue";
|
3
3
|
import { TypedObject } from "../types";
|
4
|
+
import { FlashMessages } from "./FlashMessages";
|
4
5
|
|
5
6
|
const store = new Map<string, any>();
|
6
7
|
|
8
|
+
export function storeObjects<T extends TypedObject>(newObjects: T[]) {
|
9
|
+
for (const index in newObjects) {
|
10
|
+
if (newObjects[index] && typeof newObjects[index] === "object") {
|
11
|
+
newObjects[index] = storeObject(newObjects[index]);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
return newObjects;
|
15
|
+
}
|
16
|
+
|
7
17
|
/**
|
8
18
|
* Store an object in the object store via type + id
|
9
19
|
* Returns the stored object that should be used instead of the passed object as the returned object is shared across the system
|
@@ -56,3 +66,21 @@ export function storeObject<T extends TypedObject>(newObject: T): ShallowReactiv
|
|
56
66
|
store.set(objectKey, reactiveObject);
|
57
67
|
return reactiveObject;
|
58
68
|
}
|
69
|
+
|
70
|
+
export async function autoRefreshObject<T extends TypedObject>(object: T, condition: (object: T) => boolean, callback: (object: T) => Promise<T>, interval = 3000) {
|
71
|
+
if (!object?.id || !object?.__type) {
|
72
|
+
throw new Error("Invalid stored object. Cannot auto-refresh");
|
73
|
+
}
|
74
|
+
|
75
|
+
if (condition(object)) {
|
76
|
+
const refreshedObject = await callback(object);
|
77
|
+
|
78
|
+
if (!refreshedObject.id) {
|
79
|
+
return FlashMessages.error(`Failed to refresh ${object.__type} (${object.id}) status: ` + object.name);
|
80
|
+
}
|
81
|
+
|
82
|
+
storeObject(refreshedObject);
|
83
|
+
}
|
84
|
+
|
85
|
+
setTimeout(() => autoRefreshObject(object, condition, callback), interval);
|
86
|
+
}
|
package/src/helpers/routes.ts
CHANGED
@@ -3,7 +3,7 @@ import { ListControlsRoutes } from "../types";
|
|
3
3
|
import { downloadFile } from "./downloadPdf";
|
4
4
|
import { request } from "./request";
|
5
5
|
|
6
|
-
export function useActionRoutes(baseUrl: string): ListControlsRoutes {
|
6
|
+
export function useActionRoutes(baseUrl: string, extend?: object): ListControlsRoutes {
|
7
7
|
return {
|
8
8
|
list(pager?) {
|
9
9
|
return request.post(`${baseUrl}/list`, pager);
|
@@ -33,6 +33,7 @@ export function useActionRoutes(baseUrl: string): ListControlsRoutes {
|
|
33
33
|
},
|
34
34
|
export(filter, name) {
|
35
35
|
return downloadFile(`${baseUrl}/export`, name || "export.csv", { filter });
|
36
|
-
}
|
36
|
+
},
|
37
|
+
...extend
|
37
38
|
};
|
38
39
|
}
|
package/src/types/fields.d.ts
CHANGED
@@ -19,3 +19,11 @@ export interface TextFieldProps {
|
|
19
19
|
readonly?: boolean;
|
20
20
|
debounce?: string | number;
|
21
21
|
}
|
22
|
+
|
23
|
+
export interface NumberFieldProps extends TextFieldProps {
|
24
|
+
precision?: number;
|
25
|
+
delay?: number;
|
26
|
+
currency?: boolean;
|
27
|
+
min?: number;
|
28
|
+
max?: number;
|
29
|
+
}
|