@ramathibodi/nuxt-commons 0.1.22 → 0.1.23
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/module.d.mts +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.json +5 -1
- package/dist/runtime/components/ExportCSV.vue +22 -13
- package/dist/runtime/components/ImportCSV.vue +24 -14
- package/dist/runtime/components/document/TemplateBuilder.vue +1 -1
- package/dist/runtime/components/form/Table.vue +3 -20
- package/dist/runtime/composables/alert.d.ts +1 -1
- package/dist/runtime/composables/{alert.mjs → alert.js} +1 -2
- package/dist/runtime/composables/api.d.ts +4 -4
- package/dist/runtime/composables/api.js +52 -0
- package/dist/runtime/composables/document/{template.mjs → template.js} +8 -16
- package/dist/runtime/composables/graphql.d.ts +6 -5
- package/dist/runtime/composables/{graphql.mjs → graphql.js} +31 -40
- package/dist/runtime/composables/graphqlModel.d.ts +17 -17
- package/dist/runtime/composables/{graphqlModel.mjs → graphqlModel.js} +18 -33
- package/dist/runtime/composables/graphqlModelItem.d.ts +13 -13
- package/dist/runtime/composables/{graphqlModelItem.mjs → graphqlModelItem.js} +6 -9
- package/dist/runtime/composables/graphqlModelOperation.d.ts +7 -7
- package/dist/runtime/composables/{graphqlModelOperation.mjs → graphqlModelOperation.js} +6 -12
- package/dist/runtime/composables/graphqlOperation.d.ts +2 -2
- package/dist/runtime/composables/{graphqlOperation.mjs → graphqlOperation.js} +15 -28
- package/dist/runtime/composables/menu.d.ts +1 -1
- package/dist/runtime/composables/{menu.mjs → menu.js} +2 -4
- package/dist/runtime/composables/utils/fuzzy.d.ts +1 -1
- package/dist/runtime/composables/utils/validation.d.ts +32 -0
- package/dist/runtime/plugins/permission.d.ts +1 -1
- package/dist/runtime/plugins/{permission.mjs → permission.js} +2 -4
- package/dist/runtime/utils/datetime.d.ts +214 -16
- package/dist/runtime/utils/{datetime.mjs → datetime.js} +22 -44
- package/dist/runtime/utils/{object.mjs → object.js} +1 -2
- package/dist/types.d.mts +1 -16
- package/dist/types.d.ts +1 -16
- package/package.json +34 -34
- package/dist/runtime/composables/api.mjs +0 -64
- /package/dist/runtime/composables/utils/{fuzzy.mjs → fuzzy.js} +0 -0
- /package/dist/runtime/composables/utils/{validation.mjs → validation.js} +0 -0
package/dist/module.d.mts
CHANGED
|
@@ -2,6 +2,6 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
2
2
|
|
|
3
3
|
interface ModuleOptions {
|
|
4
4
|
}
|
|
5
|
-
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
|
|
5
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
6
6
|
|
|
7
7
|
export { type ModuleOptions, _default as default };
|
package/dist/module.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
2
2
|
|
|
3
3
|
interface ModuleOptions {
|
|
4
4
|
}
|
|
5
|
-
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
|
|
5
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
6
6
|
|
|
7
7
|
export { type ModuleOptions, _default as default };
|
package/dist/module.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import {ref
|
|
2
|
+
import {ref} from 'vue'
|
|
3
3
|
import * as XLSX from 'xlsx'
|
|
4
4
|
import {VBtn} from 'vuetify/components/VBtn'
|
|
5
5
|
import {useAlert} from '../composables/alert'
|
|
@@ -20,7 +20,7 @@ function exportFile() {
|
|
|
20
20
|
if (props.modelValue && Array.isArray(props.modelValue)) {
|
|
21
21
|
loading.value = true
|
|
22
22
|
const workbook = XLSX.utils.book_new()
|
|
23
|
-
const worksheet = XLSX.utils.json_to_sheet(props.modelValue)
|
|
23
|
+
const worksheet = XLSX.utils.json_to_sheet(serializeRoleField(props.modelValue))
|
|
24
24
|
const fileName = `${props.fileName}.xlsx`
|
|
25
25
|
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
|
|
26
26
|
XLSX.writeFile(workbook, fileName)
|
|
@@ -30,25 +30,34 @@ function exportFile() {
|
|
|
30
30
|
alert?.addAlert({ message: 'Invalid or no data to export', alertType: 'error' })
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
const serializeRoleField = (items: any) => {
|
|
35
|
+
return items.map((item:any) => {
|
|
36
|
+
if (item.properties && typeof item.properties === 'object') {
|
|
37
|
+
item.properties = JSON.stringify(item.properties);
|
|
38
|
+
}
|
|
39
|
+
return item;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
33
42
|
</script>
|
|
34
43
|
|
|
35
44
|
<template>
|
|
36
45
|
<VBtn
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
v-bind="$attrs"
|
|
47
|
+
color="primary"
|
|
48
|
+
:loading="loading"
|
|
49
|
+
:disabled="loading"
|
|
50
|
+
text="Export CSV"
|
|
51
|
+
@click="exportFile"
|
|
43
52
|
>
|
|
44
53
|
<template
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
55
|
+
:key="index"
|
|
56
|
+
#[name]="slotData"
|
|
48
57
|
>
|
|
49
58
|
<slot
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
:name="name"
|
|
60
|
+
v-bind="((slotData || {}) as object)"
|
|
52
61
|
/>
|
|
53
62
|
</template>
|
|
54
63
|
</VBtn>
|
|
@@ -30,34 +30,44 @@ function uploadedFile(files: File[] | File | undefined) {
|
|
|
30
30
|
const reader = new FileReader()
|
|
31
31
|
reader.onload = (e: ProgressEvent<FileReader>) => {
|
|
32
32
|
const workbook = XLSX.read(e.target?.result)
|
|
33
|
-
|
|
33
|
+
const parseData = parsePropertiesField(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]))
|
|
34
|
+
emit('import', parseData)
|
|
34
35
|
loading.value = false
|
|
35
36
|
fileBtnRef.value.reset()
|
|
36
37
|
}
|
|
37
38
|
loading.value = true
|
|
38
39
|
reader.readAsArrayBuffer(files)
|
|
39
40
|
}
|
|
41
|
+
|
|
42
|
+
const parsePropertiesField = (items:any) => {
|
|
43
|
+
return items.map(item => {
|
|
44
|
+
if (item.properties && typeof item.properties === 'string') {
|
|
45
|
+
item.properties = JSON.parse(item.properties);
|
|
46
|
+
}
|
|
47
|
+
return item;
|
|
48
|
+
});
|
|
49
|
+
};
|
|
40
50
|
</script>
|
|
41
51
|
|
|
42
52
|
<template>
|
|
43
53
|
<FileBtn
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
ref="fileBtnRef"
|
|
55
|
+
v-bind="$attrs"
|
|
56
|
+
color="primary"
|
|
57
|
+
:loading="loading"
|
|
58
|
+
text="Import CSV"
|
|
59
|
+
accept=".csv, .xlsx"
|
|
60
|
+
:multiple="false"
|
|
61
|
+
@update:model-value="uploadedFile"
|
|
52
62
|
>
|
|
53
63
|
<template
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
65
|
+
:key="index"
|
|
66
|
+
#[name]="slotData"
|
|
57
67
|
>
|
|
58
68
|
<slot
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
:name="name"
|
|
70
|
+
v-bind="((slotData || {}) as object)"
|
|
61
71
|
/>
|
|
62
72
|
</template>
|
|
63
73
|
</FileBtn>
|
|
@@ -11,7 +11,7 @@ const isAdvanceMode = computed(() => {
|
|
|
11
11
|
return modelValue.value && !isValidJsonArrayOfObjects(modelValue.value)
|
|
12
12
|
})
|
|
13
13
|
|
|
14
|
-
const templateItems = ref<Record<string, any
|
|
14
|
+
const templateItems = ref<Record<string, any>[]>([])
|
|
15
15
|
|
|
16
16
|
const headers = ref([
|
|
17
17
|
{ title: '',
|
|
@@ -235,26 +235,9 @@ const operation = ref({ openDialog, createItem, updateItem, deleteItem, moveUpIt
|
|
|
235
235
|
v-if="!$slots['item.operation']"
|
|
236
236
|
#item.operation="props"
|
|
237
237
|
>
|
|
238
|
-
<v-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
density="compact"
|
|
242
|
-
icon="mdi:mdi-arrow-up-thick"
|
|
243
|
-
@click="moveUpItem(props.item)"
|
|
244
|
-
/>
|
|
245
|
-
<v-btn
|
|
246
|
-
variant="flat"
|
|
247
|
-
density="compact"
|
|
248
|
-
icon="fa:fas fa-arrow-right-to-bracket"
|
|
249
|
-
@click="moveToItem(props.item)"
|
|
250
|
-
/>
|
|
251
|
-
<v-btn
|
|
252
|
-
:disabled="props.index==items.length-1"
|
|
253
|
-
variant="flat"
|
|
254
|
-
density="compact"
|
|
255
|
-
icon="mdi:mdi-arrow-down-thick"
|
|
256
|
-
@click="moveDownItem(props.item)"
|
|
257
|
-
/>
|
|
238
|
+
<v-icon density="compact" :disabled="props.index==0" @click="moveUpItem(props.item)">mdi:mdi-arrow-up-thick</v-icon>
|
|
239
|
+
<v-icon density="compact" @click="moveToItem(props.item)">fa:fas fa-arrow-right-to-bracket</v-icon>
|
|
240
|
+
<v-icon density="compact" :disabled="props.index==items.length-1" @click="moveDownItem(props.item)">mdi:mdi-arrow-down-thick</v-icon>
|
|
258
241
|
</template>
|
|
259
242
|
<template
|
|
260
243
|
v-if="!$slots['item.action']"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type InjectionKey, type Ref } from 'vue';
|
|
2
|
-
import type { AlertItem } from '../types/alert';
|
|
2
|
+
import type { AlertItem } from '../types/alert.js';
|
|
3
3
|
interface AlertProvide {
|
|
4
4
|
addAlert: (item: Partial<AlertItem>) => void;
|
|
5
5
|
takeAlert: (location?: string) => AlertItem | undefined;
|
|
@@ -23,8 +23,7 @@ export function createAlert() {
|
|
|
23
23
|
},
|
|
24
24
|
takeAlert(location = "default") {
|
|
25
25
|
const item = head(items.value.filter((i) => i.alertLocation === location));
|
|
26
|
-
if (item)
|
|
27
|
-
remove(items.value, (i) => i === item);
|
|
26
|
+
if (item) remove(items.value, (i) => i === item);
|
|
28
27
|
return item;
|
|
29
28
|
},
|
|
30
29
|
hasAlert(location = "default") {
|
|
@@ -2,8 +2,8 @@ import type { UseFetchOptions } from 'nuxt/app';
|
|
|
2
2
|
import type { SearchParameters } from 'ofetch';
|
|
3
3
|
export declare function useApi(): {
|
|
4
4
|
urlBuilder: (url: string | string[]) => string;
|
|
5
|
-
get: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => any
|
|
6
|
-
getPromise: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => Promise<
|
|
7
|
-
post: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => any
|
|
8
|
-
postPromise: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => Promise<
|
|
5
|
+
get: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => Promise<any>;
|
|
6
|
+
getPromise: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => Promise<any>;
|
|
7
|
+
post: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => Promise<any>;
|
|
8
|
+
postPromise: (url: string | string[], body?: Record<string, any> | [], params?: SearchParameters, options?: UseFetchOptions<unknown>) => Promise<any>;
|
|
9
9
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { trimEnd, trimStart } from "lodash-es";
|
|
2
|
+
import { useRuntimeConfig, useAuthentication } from "#imports";
|
|
3
|
+
import { ofetch } from "ofetch";
|
|
4
|
+
export function useApi() {
|
|
5
|
+
const config = useRuntimeConfig();
|
|
6
|
+
const nuxtApp = useNuxtApp();
|
|
7
|
+
function urlBuilder(url) {
|
|
8
|
+
let returnUrl = "";
|
|
9
|
+
if (Array.isArray(url)) {
|
|
10
|
+
if (url[0].toLowerCase() == "agent") url[0] = config?.public.WS_AGENT || config?.public.WS_DEVICE;
|
|
11
|
+
returnUrl = url.join("/");
|
|
12
|
+
} else {
|
|
13
|
+
returnUrl = url;
|
|
14
|
+
}
|
|
15
|
+
if (returnUrl.startsWith("http://") || returnUrl.startsWith("https://")) return returnUrl;
|
|
16
|
+
else return trimEnd(config?.public.WS_API, "/") + "/" + trimStart(returnUrl, "/");
|
|
17
|
+
}
|
|
18
|
+
function optionBuilder(method, body, params, options) {
|
|
19
|
+
let returnOption = {
|
|
20
|
+
method,
|
|
21
|
+
body,
|
|
22
|
+
query: params
|
|
23
|
+
};
|
|
24
|
+
const headers = {
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
"Accept": "application/json"
|
|
27
|
+
};
|
|
28
|
+
if (useAuthentication().keycloak?.token) {
|
|
29
|
+
headers["Authorization"] = `Bearer ${useAuthentication().keycloak.token}`;
|
|
30
|
+
}
|
|
31
|
+
if (options) {
|
|
32
|
+
options = Object.assign(options, returnOption);
|
|
33
|
+
if (options.headers) options.headers = Object.assign(options.headers, headers);
|
|
34
|
+
else options.headers = headers;
|
|
35
|
+
}
|
|
36
|
+
returnOption = Object.assign(returnOption, options);
|
|
37
|
+
return returnOption;
|
|
38
|
+
}
|
|
39
|
+
function get(url, body, params, options) {
|
|
40
|
+
return ofetch(urlBuilder(url), optionBuilder("GET", body, params, options));
|
|
41
|
+
}
|
|
42
|
+
function getPromise(url, body, params, options) {
|
|
43
|
+
return ofetch(urlBuilder(url), optionBuilder("GET", body, params, options));
|
|
44
|
+
}
|
|
45
|
+
function post(url, body, params, options) {
|
|
46
|
+
return ofetch(urlBuilder(url), optionBuilder("POST", body, params, options));
|
|
47
|
+
}
|
|
48
|
+
function postPromise(url, body, params, options) {
|
|
49
|
+
return ofetch(urlBuilder(url), optionBuilder("POST", body, params, options));
|
|
50
|
+
}
|
|
51
|
+
return { urlBuilder, get, getPromise, post, postPromise };
|
|
52
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export const validationRulesRegex = /^(require(?:\([^)]*\))?|requireIf(?:\([^)]*\))?|requireTrue(?:\([^)]*\))?|requireTrueIf(?:\([^)]*\))?|numeric(?:\([^)]*\))?|range(?:\([^)]*\))?|integer(?:\([^)]*\))?|unique(?:\([^)]*\))?|length(?:\([^)]*\))?|lengthGreater(?:\([^)]*\))?|lengthLess(?:\([^)]*\))?|telephone(?:\([^)]*\))?|email(?:\([^)]*\))?|regex(?:\([^)]*\))?)(,(require(?:\([^)]*\))?|requireIf(?:\([^)]*\))?|requireTrue(?:\([^)]*\))?|requireTrueIf(?:\([^)]*\))?|numeric(?:\([^)]*\))?|range(?:\([^)]*\))?|integer(?:\([^)]*\))?|unique(?:\([^)]*\))?|length(?:\([^)]*\))?|lengthGreater(?:\([^)]*\))?|lengthLess(?:\([^)]*\))?|telephone(?:\([^)]*\))?|email(?:\([^)]*\))?|regex(?:\([^)]*\))?))*$/;
|
|
2
2
|
export function useDocumentTemplate(items) {
|
|
3
|
-
if (!items)
|
|
4
|
-
return "";
|
|
3
|
+
if (!items) return "";
|
|
5
4
|
if (typeof items === "string") {
|
|
6
5
|
try {
|
|
7
6
|
items = JSON.parse(items);
|
|
@@ -35,10 +34,8 @@ function templateItemToString(item) {
|
|
|
35
34
|
optionString = item.inputOptions.split(",").join(" ");
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
|
-
if (item.inputType == "FormDateTime" && !item.inputAttributes?.includes("dense"))
|
|
39
|
-
|
|
40
|
-
if (item.validationRules)
|
|
41
|
-
validationRules = buildValidationRules(item.validationRules);
|
|
37
|
+
if (item.inputType == "FormDateTime" && !item.inputAttributes?.includes("dense")) item.inputAttributes = (item.inputAttributes?.trim() + " dense").trim();
|
|
38
|
+
if (item.validationRules) validationRules = buildValidationRules(item.validationRules);
|
|
42
39
|
let templateString;
|
|
43
40
|
switch (item.inputType) {
|
|
44
41
|
case "CustomCode":
|
|
@@ -59,10 +56,8 @@ function templateItemToString(item) {
|
|
|
59
56
|
default:
|
|
60
57
|
templateString = `<${item.inputType} v-model="data.${item.variableName}" label="${item.inputLabel || item.variableName}"${item.inputAttributes ? " " + item.inputAttributes : ""}${optionString ? " " + optionString.trim() : ""}${validationRules ? " " + validationRules.trim() : ""}></${item.inputType}>`;
|
|
61
58
|
}
|
|
62
|
-
if (!["Separator", "Header"].includes(item.inputType))
|
|
63
|
-
|
|
64
|
-
if (["Header"].includes(item.inputType))
|
|
65
|
-
templateString = `</v-row><v-row dense><v-col${item.columnAttributes ? " " + item.columnAttributes : ""}>${templateString}</v-col></v-row><v-row dense>`;
|
|
59
|
+
if (!["Separator", "Header"].includes(item.inputType)) templateString = `<v-col${item.width ? ' cols="' + item.width + '"' : ""}${item.columnAttributes ? " " + item.columnAttributes : ""}>${templateString}</v-col>`;
|
|
60
|
+
if (["Header"].includes(item.inputType)) templateString = `</v-row><v-row dense><v-col${item.columnAttributes ? " " + item.columnAttributes : ""}>${templateString}</v-col></v-row><v-row dense>`;
|
|
66
61
|
return templateString;
|
|
67
62
|
}
|
|
68
63
|
function optionStringToChoiceObject(option) {
|
|
@@ -83,12 +78,9 @@ function optionStringToChoiceObject(option) {
|
|
|
83
78
|
}
|
|
84
79
|
function buildValidationRules(validationString) {
|
|
85
80
|
validationString = validationString.trim();
|
|
86
|
-
if (validationString.startsWith("["))
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
validationString = validationString.substring(0, validationString.length - 1);
|
|
90
|
-
if (!validationRulesRegex.test(validationString))
|
|
91
|
-
return "";
|
|
81
|
+
if (validationString.startsWith("[")) validationString = validationString.substring(1);
|
|
82
|
+
if (validationString.endsWith("]")) validationString = validationString.substring(0, validationString.length - 1);
|
|
83
|
+
if (!validationRulesRegex.test(validationString)) return "";
|
|
92
84
|
validationString = validationString.split(",").map((rule) => {
|
|
93
85
|
rule = rule.trim();
|
|
94
86
|
if (!rule.startsWith("rules.")) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type ClassConstructor } from '../utils/object';
|
|
1
|
+
import { type ClassConstructor } from '../utils/object.js';
|
|
2
|
+
import type { UseMutationReturn } from "@vue/apollo-composable";
|
|
2
3
|
declare type VariableOptions = {
|
|
3
4
|
type?: string;
|
|
4
5
|
name?: string;
|
|
@@ -9,9 +10,9 @@ declare type VariableOptions = {
|
|
|
9
10
|
[k: string]: any;
|
|
10
11
|
};
|
|
11
12
|
export declare function useGraphQl(): {
|
|
12
|
-
query: <T>(operation: string, fields: Array<string | Object> | ClassConstructor<any>, variables?: VariableOptions, cache?: boolean) => any
|
|
13
|
-
queryPromise: <
|
|
14
|
-
mutation: <
|
|
15
|
-
mutationPromise: <
|
|
13
|
+
query: <T>(operation: string, fields: Array<string | Object> | ClassConstructor<any>, variables?: VariableOptions, cache?: boolean) => import("#app").AsyncData<(T extends any[] ? T : T extends Record<string, any> ? keyof T extends (T extends T ? keyof T extends string ? string & keyof T : never : never) ? T : (T extends T ? keyof T extends string ? string & keyof T : never : never) extends never ? T : Pick<T, T extends T ? keyof T extends string ? string & keyof T : never : never> : T) | null, import("#app").NuxtError<unknown> | null>;
|
|
14
|
+
queryPromise: <T>(operation: string, fields: Array<string | Object> | ClassConstructor<any>, variables?: VariableOptions, cache?: boolean) => Promise<T>;
|
|
15
|
+
mutation: <T>(operation: string, fields: Array<string | Object> | ClassConstructor<any>, variables?: VariableOptions) => UseMutationReturn<any, any>;
|
|
16
|
+
mutationPromise: <T>(operation: string, fields: Array<string | Object> | ClassConstructor<any>, variables?: VariableOptions) => Promise<T>;
|
|
16
17
|
};
|
|
17
18
|
export {};
|
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
import { mutation as gqlMutation, query as gqlQuery } from "gql-query-builder";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { classAttributes, isClassConstructor } from "../utils/object.js";
|
|
3
|
+
import { gql, useAsyncQuery, useMutation, useRuntimeConfig } from "#imports";
|
|
4
|
+
import { useApi } from "./api.js";
|
|
5
5
|
export function useGraphQl() {
|
|
6
|
+
function simplePromiseCall(operation, query2, variables) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
useApi().postPromise(useRuntimeConfig().public.WS_GRAPHQL, {
|
|
9
|
+
query: query2,
|
|
10
|
+
variables
|
|
11
|
+
}).then((result) => {
|
|
12
|
+
if (result.errors) reject(result.errors.map((error) => {
|
|
13
|
+
return error.message;
|
|
14
|
+
}).join("\n"));
|
|
15
|
+
else {
|
|
16
|
+
try {
|
|
17
|
+
const dataObject = result.data;
|
|
18
|
+
resolve(dataObject[operation]);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
reject(error);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}).catch((error) => {
|
|
24
|
+
reject(error);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
6
28
|
function query(operation, fields, variables, cache = false) {
|
|
7
|
-
if (isClassConstructor(fields))
|
|
8
|
-
fields = classAttributes(fields);
|
|
29
|
+
if (isClassConstructor(fields)) fields = classAttributes(fields);
|
|
9
30
|
const builder = gqlQuery({ operation, fields, variables });
|
|
10
31
|
const options = {
|
|
11
32
|
query: gql(builder.query),
|
|
@@ -15,49 +36,19 @@ export function useGraphQl() {
|
|
|
15
36
|
return useAsyncQuery(options);
|
|
16
37
|
}
|
|
17
38
|
function queryPromise(operation, fields, variables, cache = false) {
|
|
18
|
-
if (isClassConstructor(fields))
|
|
19
|
-
fields = classAttributes(fields);
|
|
39
|
+
if (isClassConstructor(fields)) fields = classAttributes(fields);
|
|
20
40
|
const builder = gqlQuery({ operation, fields, variables });
|
|
21
|
-
return
|
|
22
|
-
const { onResult, onError } = useQuery(gql(builder.query), builder.variables, { fetchPolicy: cache ? "cache-first" : "no-cache" });
|
|
23
|
-
onResult((queryResult) => {
|
|
24
|
-
if (!queryResult.loading) {
|
|
25
|
-
const dataObject = queryResult.data;
|
|
26
|
-
try {
|
|
27
|
-
resolve(dataObject[operation]);
|
|
28
|
-
} catch (error) {
|
|
29
|
-
reject(error);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
onError((error) => {
|
|
34
|
-
reject(error);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
41
|
+
return simplePromiseCall(operation, builder.query, builder.variables);
|
|
37
42
|
}
|
|
38
43
|
function mutation(operation, fields, variables) {
|
|
39
|
-
if (isClassConstructor(fields))
|
|
40
|
-
fields = classAttributes(fields);
|
|
44
|
+
if (isClassConstructor(fields)) fields = classAttributes(fields);
|
|
41
45
|
const builder = gqlMutation({ operation, fields, variables });
|
|
42
46
|
return useMutation(gql(builder.query), { variables: builder.variables });
|
|
43
47
|
}
|
|
44
48
|
function mutationPromise(operation, fields, variables) {
|
|
45
|
-
if (isClassConstructor(fields))
|
|
46
|
-
fields = classAttributes(fields);
|
|
49
|
+
if (isClassConstructor(fields)) fields = classAttributes(fields);
|
|
47
50
|
const builder = gqlMutation({ operation, fields, variables });
|
|
48
|
-
return
|
|
49
|
-
const { mutate, error } = useMutation(gql(builder.query), { variables: builder.variables });
|
|
50
|
-
if (!error.value) {
|
|
51
|
-
try {
|
|
52
|
-
const results = await mutate();
|
|
53
|
-
resolve(results.data[operation]);
|
|
54
|
-
} catch (e) {
|
|
55
|
-
reject(e);
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
reject(error.value);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
51
|
+
return simplePromiseCall(operation, builder.query, builder.variables);
|
|
61
52
|
}
|
|
62
53
|
return { query, queryPromise, mutation, mutationPromise };
|
|
63
54
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { FormDialogCallback } from '../types/formDialog';
|
|
2
|
-
import { type GraphqlModelConfigProps } from './graphqlModelOperation';
|
|
1
|
+
import type { FormDialogCallback } from '../types/formDialog.js';
|
|
2
|
+
import { type GraphqlModelConfigProps } from './graphqlModelOperation.js';
|
|
3
3
|
export interface HeaderProps {
|
|
4
4
|
headers?: any[];
|
|
5
5
|
}
|
|
@@ -8,28 +8,28 @@ export interface InitialDataProps {
|
|
|
8
8
|
}
|
|
9
9
|
export type GraphqlModelProps = GraphqlModelConfigProps & Partial<HeaderProps> & Partial<InitialDataProps>;
|
|
10
10
|
export declare function useGraphqlModel<T extends GraphqlModelProps>(props: T): {
|
|
11
|
-
items: import("vue").Ref<Record<string, any>[]>;
|
|
12
|
-
itemsLength: import("vue").Ref<number>;
|
|
13
|
-
search: import("vue").Ref<string | undefined>;
|
|
11
|
+
items: import("vue").Ref<Record<string, any>[], Record<string, any>[]>;
|
|
12
|
+
itemsLength: import("vue").Ref<number, number>;
|
|
13
|
+
search: import("vue").Ref<string | undefined, string | undefined>;
|
|
14
14
|
setSearch: (keyword: string) => void;
|
|
15
|
-
currentOptions: import("vue").Ref<any>;
|
|
16
|
-
operationCreate: import("vue").ComputedRef<any
|
|
17
|
-
operationUpdate: import("vue").ComputedRef<any
|
|
18
|
-
operationDelete: import("vue").ComputedRef<any
|
|
19
|
-
operationRead: import("vue").ComputedRef<any
|
|
20
|
-
operationReadPageable: import("vue").ComputedRef<any
|
|
21
|
-
operationSearch: import("vue").ComputedRef<any
|
|
22
|
-
fields: import("vue").ComputedRef<
|
|
15
|
+
currentOptions: import("vue").Ref<any, any>;
|
|
16
|
+
operationCreate: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
17
|
+
operationUpdate: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
18
|
+
operationDelete: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
19
|
+
operationRead: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
20
|
+
operationReadPageable: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
21
|
+
operationSearch: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
22
|
+
fields: import("vue").ComputedRef<(string | object)[]>;
|
|
23
23
|
canServerPageable: import("vue").ComputedRef<boolean>;
|
|
24
24
|
canServerSearch: import("vue").ComputedRef<boolean>;
|
|
25
25
|
canCreate: import("vue").ComputedRef<boolean>;
|
|
26
26
|
canUpdate: import("vue").ComputedRef<boolean>;
|
|
27
27
|
canDelete: import("vue").ComputedRef<boolean>;
|
|
28
|
-
createItem: (item: Record<string, any>, callback?: FormDialogCallback, importing?: boolean) =>
|
|
28
|
+
createItem: (item: Record<string, any>, callback?: FormDialogCallback, importing?: boolean) => Promise<void>;
|
|
29
29
|
importItems: (importItems: Record<string, any>[], callback?: FormDialogCallback) => void;
|
|
30
|
-
updateItem: (item: Record<string, any>, callback?: FormDialogCallback) =>
|
|
31
|
-
deleteItem: (item: Record<string, any>, callback?: FormDialogCallback) => any
|
|
30
|
+
updateItem: (item: Record<string, any>, callback?: FormDialogCallback) => Promise<void>;
|
|
31
|
+
deleteItem: (item: Record<string, any>, callback?: FormDialogCallback) => Promise<any>;
|
|
32
32
|
loadItems: (options: any) => void;
|
|
33
33
|
reload: () => void;
|
|
34
|
-
isLoading: import("vue").Ref<boolean>;
|
|
34
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
35
35
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { computed, onMounted, ref } from "vue";
|
|
2
2
|
import { watchDebounced } from "@vueuse/core";
|
|
3
|
-
import { useAlert } from "./alert.
|
|
4
|
-
import { buildRequiredInputFields } from "./graphqlOperation.
|
|
5
|
-
import { useGraphqlModelOperation } from "./graphqlModelOperation.
|
|
3
|
+
import { useAlert } from "./alert.js";
|
|
4
|
+
import { buildRequiredInputFields } from "./graphqlOperation.js";
|
|
5
|
+
import { useGraphqlModelOperation } from "./graphqlModelOperation.js";
|
|
6
6
|
export function useGraphqlModel(props) {
|
|
7
7
|
const alert = useAlert();
|
|
8
8
|
const items = ref([]);
|
|
@@ -16,15 +16,12 @@ export function useGraphqlModel(props) {
|
|
|
16
16
|
const { operationCreate, operationUpdate, operationDelete, operationRead, operationReadPageable, operationSearch } = useGraphqlModelOperation(props);
|
|
17
17
|
function keyToField(key) {
|
|
18
18
|
const parts = key.split(".");
|
|
19
|
-
if (parts.length <= 1)
|
|
20
|
-
return key;
|
|
19
|
+
if (parts.length <= 1) return key;
|
|
21
20
|
let lastValue = parts.pop();
|
|
22
21
|
let result = {};
|
|
23
22
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
24
|
-
if (i == parts.length - 1)
|
|
25
|
-
|
|
26
|
-
else
|
|
27
|
-
result = { [parts[i]]: result };
|
|
23
|
+
if (i == parts.length - 1) result = { [parts[i]]: [lastValue] };
|
|
24
|
+
else result = { [parts[i]]: result };
|
|
28
25
|
}
|
|
29
26
|
return result;
|
|
30
27
|
}
|
|
@@ -34,8 +31,7 @@ export function useGraphqlModel(props) {
|
|
|
34
31
|
let requiredInputFields = [];
|
|
35
32
|
if (props.headers && props.headers.length > 0) {
|
|
36
33
|
props.headers.forEach((header) => {
|
|
37
|
-
if (!fieldsProps.includes(header.key))
|
|
38
|
-
tmpFields.push(keyToField(header.key));
|
|
34
|
+
if (!fieldsProps.includes(header.key)) tmpFields.push(keyToField(header.key));
|
|
39
35
|
});
|
|
40
36
|
}
|
|
41
37
|
if (canUpdate.value) {
|
|
@@ -62,17 +58,13 @@ export function useGraphqlModel(props) {
|
|
|
62
58
|
isLoading.value = true;
|
|
63
59
|
return operationCreate.value?.call(fields.value, { input: item }).then((result) => {
|
|
64
60
|
if (canServerPageable.value) {
|
|
65
|
-
if (!importing)
|
|
66
|
-
|
|
67
|
-
} else
|
|
68
|
-
items.value.push(result);
|
|
61
|
+
if (!importing) loadItems(currentOptions.value);
|
|
62
|
+
} else items.value.push(result);
|
|
69
63
|
}).catch((error) => {
|
|
70
64
|
alert?.addAlert({ alertType: "error", message: error });
|
|
71
65
|
}).finally(() => {
|
|
72
|
-
if (!importing)
|
|
73
|
-
|
|
74
|
-
if (callback)
|
|
75
|
-
callback.done();
|
|
66
|
+
if (!importing) isLoading.value = false;
|
|
67
|
+
if (callback) callback.done();
|
|
76
68
|
});
|
|
77
69
|
}
|
|
78
70
|
function importItems(importItems2, callback) {
|
|
@@ -80,21 +72,18 @@ export function useGraphqlModel(props) {
|
|
|
80
72
|
const importPromise = [];
|
|
81
73
|
importItems2.forEach((item) => {
|
|
82
74
|
const eachPromise = createItem(Object.assign({}, props.initialData, item), void 0, true);
|
|
83
|
-
if (eachPromise)
|
|
84
|
-
importPromise.push(eachPromise);
|
|
75
|
+
if (eachPromise) importPromise.push(eachPromise);
|
|
85
76
|
});
|
|
86
77
|
Promise.all(importPromise).finally(() => {
|
|
87
78
|
isLoading.value = false;
|
|
88
79
|
reload();
|
|
89
|
-
if (callback)
|
|
90
|
-
callback.done();
|
|
80
|
+
if (callback) callback.done();
|
|
91
81
|
});
|
|
92
82
|
}
|
|
93
83
|
function updateItem(item, callback) {
|
|
94
84
|
isLoading.value = true;
|
|
95
85
|
return operationUpdate.value?.call(fields.value, { input: item }).then((result) => {
|
|
96
|
-
if (canServerPageable.value)
|
|
97
|
-
loadItems(currentOptions.value);
|
|
86
|
+
if (canServerPageable.value) loadItems(currentOptions.value);
|
|
98
87
|
else {
|
|
99
88
|
const index = items.value.findIndex((item2) => item2[props.modelKey || "id"] === result[props.modelKey || "id"]);
|
|
100
89
|
if (index !== -1) {
|
|
@@ -105,8 +94,7 @@ export function useGraphqlModel(props) {
|
|
|
105
94
|
alert?.addAlert({ alertType: "error", message: error });
|
|
106
95
|
}).finally(() => {
|
|
107
96
|
isLoading.value = false;
|
|
108
|
-
if (callback)
|
|
109
|
-
callback.done();
|
|
97
|
+
if (callback) callback.done();
|
|
110
98
|
});
|
|
111
99
|
}
|
|
112
100
|
function deleteItem(item, callback) {
|
|
@@ -116,8 +104,7 @@ export function useGraphqlModel(props) {
|
|
|
116
104
|
}).finally(() => {
|
|
117
105
|
isLoading.value = false;
|
|
118
106
|
reload();
|
|
119
|
-
if (callback)
|
|
120
|
-
callback.done();
|
|
107
|
+
if (callback) callback.done();
|
|
121
108
|
});
|
|
122
109
|
}
|
|
123
110
|
function loadItems(options) {
|
|
@@ -141,8 +128,7 @@ export function useGraphqlModel(props) {
|
|
|
141
128
|
}
|
|
142
129
|
function reload() {
|
|
143
130
|
if (canServerPageable.value) {
|
|
144
|
-
if (currentOptions.value)
|
|
145
|
-
loadItems(currentOptions.value);
|
|
131
|
+
if (currentOptions.value) loadItems(currentOptions.value);
|
|
146
132
|
} else {
|
|
147
133
|
isLoading.value = true;
|
|
148
134
|
operationRead.value?.call(fields.value, props.modelBy).then((result) => {
|
|
@@ -158,8 +144,7 @@ export function useGraphqlModel(props) {
|
|
|
158
144
|
reload();
|
|
159
145
|
}, { deep: true, debounce: 500, maxWait: 500 });
|
|
160
146
|
onMounted(() => {
|
|
161
|
-
if (!canServerPageable.value)
|
|
162
|
-
reload();
|
|
147
|
+
if (!canServerPageable.value) reload();
|
|
163
148
|
});
|
|
164
149
|
return {
|
|
165
150
|
items,
|