@ramathibodi/nuxt-commons 0.1.21 → 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/FileBtn.vue +4 -2
- package/dist/runtime/components/ImportCSV.vue +24 -14
- package/dist/runtime/components/document/TemplateBuilder.vue +1 -1
- package/dist/runtime/components/form/SignPad.vue +30 -30
- package/dist/runtime/components/form/Table.vue +3 -20
- package/dist/runtime/components/form/images/Field.vue +187 -0
- package/dist/runtime/components/form/images/Pad.vue +43 -0
- package/dist/runtime/components/model/Table.vue +20 -12
- package/dist/runtime/components/model/iterator.vue +24 -14
- 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 +18 -17
- package/dist/runtime/composables/{graphqlModel.mjs → graphqlModel.js} +26 -36
- 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} +4 -5
- 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/types/menu.d.ts +3 -0
- 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 +35 -34
- package/dist/runtime/composables/api.mjs +0 -64
- package/dist/runtime/plugins/vueSignaturePad.d.ts +0 -2
- package/dist/runtime/plugins/vueSignaturePad.mjs +0 -5
- /package/dist/runtime/composables/utils/{fuzzy.mjs → fuzzy.js} +0 -0
- /package/dist/runtime/composables/utils/{validation.mjs → validation.js} +0 -0
|
@@ -17,6 +17,9 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VDataIterator['$pr
|
|
|
17
17
|
toolbarColor?: string
|
|
18
18
|
importable?: boolean
|
|
19
19
|
exportable?: boolean
|
|
20
|
+
insertable?: boolean
|
|
21
|
+
searchable?: boolean
|
|
22
|
+
search?: string
|
|
20
23
|
cols?: string | number | boolean
|
|
21
24
|
xxl?: string | number | boolean
|
|
22
25
|
xl?: string | number | boolean
|
|
@@ -32,6 +35,8 @@ const props = withDefaults(defineProps<Props & GraphqlModelProps>(), {
|
|
|
32
35
|
toolbarColor: 'primary',
|
|
33
36
|
importable: false,
|
|
34
37
|
exportable: false,
|
|
38
|
+
insertable: true,
|
|
39
|
+
searchable: true,
|
|
35
40
|
modelKey: 'id',
|
|
36
41
|
modelBy: undefined,
|
|
37
42
|
fields: () => [],
|
|
@@ -54,7 +59,7 @@ const currentItem = ref<Record<string, any> | undefined>(undefined)
|
|
|
54
59
|
const isDialogOpen = ref<boolean>(false)
|
|
55
60
|
|
|
56
61
|
const { items, itemsLength,
|
|
57
|
-
search, currentOptions,
|
|
62
|
+
search, setSearch, currentOptions,
|
|
58
63
|
canServerPageable, canServerSearch, canCreate, canUpdate, canDelete,
|
|
59
64
|
createItem, importItems, updateItem, deleteItem,
|
|
60
65
|
loadItems, reload,
|
|
@@ -92,7 +97,7 @@ watch([currentPage, itemsPerPageInternal, sortBy], () => {
|
|
|
92
97
|
}
|
|
93
98
|
}, { immediate: true })
|
|
94
99
|
|
|
95
|
-
const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
|
|
100
|
+
const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, setSearch, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
|
|
96
101
|
|
|
97
102
|
const computedInitialData = computed(() => {
|
|
98
103
|
return Object.assign({}, props.initialData, props.modelBy)
|
|
@@ -103,6 +108,10 @@ const computedSkeletonPerPage = computed(() => {
|
|
|
103
108
|
else return Number(itemsPerPageInternal.value)
|
|
104
109
|
})
|
|
105
110
|
|
|
111
|
+
watch(()=>props.search,()=>{
|
|
112
|
+
search.value = props.search
|
|
113
|
+
},{immediate:true})
|
|
114
|
+
|
|
106
115
|
defineExpose({ reload })
|
|
107
116
|
</script>
|
|
108
117
|
|
|
@@ -176,7 +185,6 @@ defineExpose({ reload })
|
|
|
176
185
|
name="header"
|
|
177
186
|
v-bind="headerProps"
|
|
178
187
|
:items="items"
|
|
179
|
-
:search="search"
|
|
180
188
|
:operation="operation"
|
|
181
189
|
>
|
|
182
190
|
<VToolbar :color="toolbarColor">
|
|
@@ -203,7 +211,7 @@ defineExpose({ reload })
|
|
|
203
211
|
</slot>
|
|
204
212
|
</VToolbarTitle>
|
|
205
213
|
</v-col>
|
|
206
|
-
<v-col cols="5">
|
|
214
|
+
<v-col cols="5" v-if="props.searchable">
|
|
207
215
|
<slot name="search">
|
|
208
216
|
<VTextField
|
|
209
217
|
v-model="search"
|
|
@@ -221,20 +229,22 @@ defineExpose({ reload })
|
|
|
221
229
|
<VToolbarItems>
|
|
222
230
|
<slot name="toolbarItems" />
|
|
223
231
|
<ImportCSV
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
232
|
+
v-if="props.importable && canCreate && props.insertable"
|
|
233
|
+
icon="mdi mdi-file-upload"
|
|
234
|
+
variant="flat"
|
|
235
|
+
:color="toolbarColor"
|
|
236
|
+
@import="importItems"
|
|
228
237
|
/>
|
|
229
238
|
<ExportCSV
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
239
|
+
v-if="props.exportable && items.length"
|
|
240
|
+
icon="mdi mdi-file-download"
|
|
241
|
+
variant="flat"
|
|
242
|
+
:file-name="title"
|
|
243
|
+
:model-value="items"
|
|
244
|
+
:color="toolbarColor"
|
|
235
245
|
/>
|
|
236
246
|
<VBtn
|
|
237
|
-
v-if="canCreate"
|
|
247
|
+
v-if="canCreate && props.insertable"
|
|
238
248
|
:color="toolbarColor"
|
|
239
249
|
prepend-icon="mdi mdi-plus"
|
|
240
250
|
variant="flat"
|
|
@@ -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,27 +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>;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
setSearch: (keyword: string) => void;
|
|
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)[]>;
|
|
22
23
|
canServerPageable: import("vue").ComputedRef<boolean>;
|
|
23
24
|
canServerSearch: import("vue").ComputedRef<boolean>;
|
|
24
25
|
canCreate: import("vue").ComputedRef<boolean>;
|
|
25
26
|
canUpdate: import("vue").ComputedRef<boolean>;
|
|
26
27
|
canDelete: import("vue").ComputedRef<boolean>;
|
|
27
|
-
createItem: (item: Record<string, any>, callback?: FormDialogCallback, importing?: boolean) =>
|
|
28
|
+
createItem: (item: Record<string, any>, callback?: FormDialogCallback, importing?: boolean) => Promise<void>;
|
|
28
29
|
importItems: (importItems: Record<string, any>[], callback?: FormDialogCallback) => void;
|
|
29
|
-
updateItem: (item: Record<string, any>, callback?: FormDialogCallback) =>
|
|
30
|
-
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>;
|
|
31
32
|
loadItems: (options: any) => void;
|
|
32
33
|
reload: () => void;
|
|
33
|
-
isLoading: import("vue").Ref<boolean>;
|
|
34
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
34
35
|
};
|
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { computed, onMounted, ref
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { computed, onMounted, ref } from "vue";
|
|
2
|
+
import { watchDebounced } from "@vueuse/core";
|
|
3
|
+
import { useAlert } from "./alert.js";
|
|
4
|
+
import { buildRequiredInputFields } from "./graphqlOperation.js";
|
|
5
|
+
import { useGraphqlModelOperation } from "./graphqlModelOperation.js";
|
|
5
6
|
export function useGraphqlModel(props) {
|
|
6
7
|
const alert = useAlert();
|
|
7
8
|
const items = ref([]);
|
|
8
9
|
const itemsLength = ref(0);
|
|
9
10
|
const search = ref();
|
|
10
11
|
const currentOptions = ref();
|
|
12
|
+
function setSearch(keyword) {
|
|
13
|
+
search.value = keyword;
|
|
14
|
+
}
|
|
11
15
|
const isLoading = ref(false);
|
|
12
16
|
const { operationCreate, operationUpdate, operationDelete, operationRead, operationReadPageable, operationSearch } = useGraphqlModelOperation(props);
|
|
13
17
|
function keyToField(key) {
|
|
14
18
|
const parts = key.split(".");
|
|
15
|
-
if (parts.length <= 1)
|
|
16
|
-
return key;
|
|
19
|
+
if (parts.length <= 1) return key;
|
|
17
20
|
let lastValue = parts.pop();
|
|
18
21
|
let result = {};
|
|
19
22
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
20
|
-
if (i == parts.length - 1)
|
|
21
|
-
|
|
22
|
-
else
|
|
23
|
-
result = { [parts[i]]: result };
|
|
23
|
+
if (i == parts.length - 1) result = { [parts[i]]: [lastValue] };
|
|
24
|
+
else result = { [parts[i]]: result };
|
|
24
25
|
}
|
|
25
26
|
return result;
|
|
26
27
|
}
|
|
@@ -30,8 +31,7 @@ export function useGraphqlModel(props) {
|
|
|
30
31
|
let requiredInputFields = [];
|
|
31
32
|
if (props.headers && props.headers.length > 0) {
|
|
32
33
|
props.headers.forEach((header) => {
|
|
33
|
-
if (!fieldsProps.includes(header.key))
|
|
34
|
-
tmpFields.push(keyToField(header.key));
|
|
34
|
+
if (!fieldsProps.includes(header.key)) tmpFields.push(keyToField(header.key));
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
if (canUpdate.value) {
|
|
@@ -58,17 +58,13 @@ export function useGraphqlModel(props) {
|
|
|
58
58
|
isLoading.value = true;
|
|
59
59
|
return operationCreate.value?.call(fields.value, { input: item }).then((result) => {
|
|
60
60
|
if (canServerPageable.value) {
|
|
61
|
-
if (!importing)
|
|
62
|
-
|
|
63
|
-
} else
|
|
64
|
-
items.value.push(result);
|
|
61
|
+
if (!importing) loadItems(currentOptions.value);
|
|
62
|
+
} else items.value.push(result);
|
|
65
63
|
}).catch((error) => {
|
|
66
64
|
alert?.addAlert({ alertType: "error", message: error });
|
|
67
65
|
}).finally(() => {
|
|
68
|
-
if (!importing)
|
|
69
|
-
|
|
70
|
-
if (callback)
|
|
71
|
-
callback.done();
|
|
66
|
+
if (!importing) isLoading.value = false;
|
|
67
|
+
if (callback) callback.done();
|
|
72
68
|
});
|
|
73
69
|
}
|
|
74
70
|
function importItems(importItems2, callback) {
|
|
@@ -76,21 +72,18 @@ export function useGraphqlModel(props) {
|
|
|
76
72
|
const importPromise = [];
|
|
77
73
|
importItems2.forEach((item) => {
|
|
78
74
|
const eachPromise = createItem(Object.assign({}, props.initialData, item), void 0, true);
|
|
79
|
-
if (eachPromise)
|
|
80
|
-
importPromise.push(eachPromise);
|
|
75
|
+
if (eachPromise) importPromise.push(eachPromise);
|
|
81
76
|
});
|
|
82
77
|
Promise.all(importPromise).finally(() => {
|
|
83
78
|
isLoading.value = false;
|
|
84
79
|
reload();
|
|
85
|
-
if (callback)
|
|
86
|
-
callback.done();
|
|
80
|
+
if (callback) callback.done();
|
|
87
81
|
});
|
|
88
82
|
}
|
|
89
83
|
function updateItem(item, callback) {
|
|
90
84
|
isLoading.value = true;
|
|
91
85
|
return operationUpdate.value?.call(fields.value, { input: item }).then((result) => {
|
|
92
|
-
if (canServerPageable.value)
|
|
93
|
-
loadItems(currentOptions.value);
|
|
86
|
+
if (canServerPageable.value) loadItems(currentOptions.value);
|
|
94
87
|
else {
|
|
95
88
|
const index = items.value.findIndex((item2) => item2[props.modelKey || "id"] === result[props.modelKey || "id"]);
|
|
96
89
|
if (index !== -1) {
|
|
@@ -101,8 +94,7 @@ export function useGraphqlModel(props) {
|
|
|
101
94
|
alert?.addAlert({ alertType: "error", message: error });
|
|
102
95
|
}).finally(() => {
|
|
103
96
|
isLoading.value = false;
|
|
104
|
-
if (callback)
|
|
105
|
-
callback.done();
|
|
97
|
+
if (callback) callback.done();
|
|
106
98
|
});
|
|
107
99
|
}
|
|
108
100
|
function deleteItem(item, callback) {
|
|
@@ -112,8 +104,7 @@ export function useGraphqlModel(props) {
|
|
|
112
104
|
}).finally(() => {
|
|
113
105
|
isLoading.value = false;
|
|
114
106
|
reload();
|
|
115
|
-
if (callback)
|
|
116
|
-
callback.done();
|
|
107
|
+
if (callback) callback.done();
|
|
117
108
|
});
|
|
118
109
|
}
|
|
119
110
|
function loadItems(options) {
|
|
@@ -137,8 +128,7 @@ export function useGraphqlModel(props) {
|
|
|
137
128
|
}
|
|
138
129
|
function reload() {
|
|
139
130
|
if (canServerPageable.value) {
|
|
140
|
-
if (currentOptions.value)
|
|
141
|
-
loadItems(currentOptions.value);
|
|
131
|
+
if (currentOptions.value) loadItems(currentOptions.value);
|
|
142
132
|
} else {
|
|
143
133
|
isLoading.value = true;
|
|
144
134
|
operationRead.value?.call(fields.value, props.modelBy).then((result) => {
|
|
@@ -150,17 +140,17 @@ export function useGraphqlModel(props) {
|
|
|
150
140
|
});
|
|
151
141
|
}
|
|
152
142
|
}
|
|
153
|
-
|
|
143
|
+
watchDebounced([() => props.modelName, () => props.modelBy, () => props.modelKey, canServerPageable], () => {
|
|
154
144
|
reload();
|
|
155
|
-
}, { deep: true });
|
|
145
|
+
}, { deep: true, debounce: 500, maxWait: 500 });
|
|
156
146
|
onMounted(() => {
|
|
157
|
-
if (!canServerPageable.value)
|
|
158
|
-
reload();
|
|
147
|
+
if (!canServerPageable.value) reload();
|
|
159
148
|
});
|
|
160
149
|
return {
|
|
161
150
|
items,
|
|
162
151
|
itemsLength,
|
|
163
152
|
search,
|
|
153
|
+
setSearch,
|
|
164
154
|
currentOptions,
|
|
165
155
|
operationCreate,
|
|
166
156
|
operationUpdate,
|
|
@@ -1,20 +1,20 @@
|
|
|
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 type GraphqlModelItemProps = Omit<GraphqlModelConfigProps, 'operationSearch' | 'operationReadPageable'>;
|
|
4
4
|
export declare function useGraphqlModelItem<T extends GraphqlModelItemProps>(props: T): {
|
|
5
|
-
modelBy: import("vue").Ref<object | undefined>;
|
|
6
|
-
item: import("vue").Ref<Record<string, any> | undefined>;
|
|
7
|
-
operationCreate: import("vue").ComputedRef<any
|
|
8
|
-
operationUpdate: import("vue").ComputedRef<any
|
|
9
|
-
operationDelete: import("vue").ComputedRef<any
|
|
10
|
-
operationRead: import("vue").ComputedRef<any
|
|
11
|
-
fields: import("vue").ComputedRef<
|
|
5
|
+
modelBy: import("vue").Ref<object | undefined, object | undefined>;
|
|
6
|
+
item: import("vue").Ref<Record<string, any> | undefined, Record<string, any> | undefined>;
|
|
7
|
+
operationCreate: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
8
|
+
operationUpdate: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
9
|
+
operationDelete: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
10
|
+
operationRead: import("vue").ComputedRef<import("../../../playground/composables/graphqlObject").graphqlOperationObject<any, any>>;
|
|
11
|
+
fields: import("vue").ComputedRef<(string | object)[]>;
|
|
12
12
|
canCreate: import("vue").ComputedRef<boolean>;
|
|
13
13
|
canUpdate: import("vue").ComputedRef<boolean>;
|
|
14
14
|
canDelete: import("vue").ComputedRef<boolean>;
|
|
15
|
-
createItem: (createItem: Record<string, any>, callback?: FormDialogCallback) =>
|
|
16
|
-
updateItem: (updateItem: Record<string, any>, callback?: FormDialogCallback) =>
|
|
17
|
-
deleteItem: (item: Record<string, any>, callback?: FormDialogCallback) => any
|
|
15
|
+
createItem: (createItem: Record<string, any>, callback?: FormDialogCallback) => Promise<void>;
|
|
16
|
+
updateItem: (updateItem: Record<string, any>, callback?: FormDialogCallback) => Promise<void>;
|
|
17
|
+
deleteItem: (item: Record<string, any>, callback?: FormDialogCallback) => Promise<any>;
|
|
18
18
|
reload: () => void;
|
|
19
|
-
isLoading: import("vue").Ref<boolean>;
|
|
19
|
+
isLoading: import("vue").Ref<boolean, boolean>;
|
|
20
20
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { computed, ref, watch } from "vue";
|
|
2
|
-
import { useAlert } from "./alert.
|
|
3
|
-
import { buildRequiredInputFields } from "./graphqlOperation.
|
|
4
|
-
import { useGraphqlModelOperation } from "./graphqlModelOperation.
|
|
2
|
+
import { useAlert } from "./alert.js";
|
|
3
|
+
import { buildRequiredInputFields } from "./graphqlOperation.js";
|
|
4
|
+
import { useGraphqlModelOperation } from "./graphqlModelOperation.js";
|
|
5
5
|
export function useGraphqlModelItem(props) {
|
|
6
6
|
const alert = useAlert();
|
|
7
7
|
const modelBy = ref();
|
|
@@ -34,8 +34,7 @@ export function useGraphqlModelItem(props) {
|
|
|
34
34
|
reload();
|
|
35
35
|
}).finally(() => {
|
|
36
36
|
isLoading.value = false;
|
|
37
|
-
if (callback)
|
|
38
|
-
callback.done();
|
|
37
|
+
if (callback) callback.done();
|
|
39
38
|
});
|
|
40
39
|
}
|
|
41
40
|
function updateItem(updateItem2, callback) {
|
|
@@ -47,8 +46,7 @@ export function useGraphqlModelItem(props) {
|
|
|
47
46
|
reload();
|
|
48
47
|
}).finally(() => {
|
|
49
48
|
isLoading.value = false;
|
|
50
|
-
if (callback)
|
|
51
|
-
callback.done();
|
|
49
|
+
if (callback) callback.done();
|
|
52
50
|
});
|
|
53
51
|
}
|
|
54
52
|
function deleteItem(item2, callback) {
|
|
@@ -58,8 +56,7 @@ export function useGraphqlModelItem(props) {
|
|
|
58
56
|
}).finally(() => {
|
|
59
57
|
isLoading.value = false;
|
|
60
58
|
reload();
|
|
61
|
-
if (callback)
|
|
62
|
-
callback.done();
|
|
59
|
+
if (callback) callback.done();
|
|
63
60
|
});
|
|
64
61
|
}
|
|
65
62
|
function reload() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { graphqlOperationObject } from '../types/graphqlOperation';
|
|
1
|
+
import type { graphqlOperationObject } from '../types/graphqlOperation.js';
|
|
2
2
|
export interface GraphqlModelConfigProps {
|
|
3
3
|
modelName: string;
|
|
4
4
|
modelKey?: string;
|
|
@@ -12,10 +12,10 @@ export interface GraphqlModelConfigProps {
|
|
|
12
12
|
fields?: Array<string | object>;
|
|
13
13
|
}
|
|
14
14
|
export declare function useGraphqlModelOperation<T extends GraphqlModelConfigProps>(props: T): {
|
|
15
|
-
operationCreate: import("vue").ComputedRef<any
|
|
16
|
-
operationUpdate: import("vue").ComputedRef<any
|
|
17
|
-
operationDelete: import("vue").ComputedRef<any
|
|
18
|
-
operationRead: import("vue").ComputedRef<any
|
|
19
|
-
operationReadPageable: import("vue").ComputedRef<any
|
|
20
|
-
operationSearch: import("vue").ComputedRef<any
|
|
15
|
+
operationCreate: import("vue").ComputedRef<import("#imports").graphqlOperationObject<any, any>>;
|
|
16
|
+
operationUpdate: import("vue").ComputedRef<import("#imports").graphqlOperationObject<any, any>>;
|
|
17
|
+
operationDelete: import("vue").ComputedRef<import("#imports").graphqlOperationObject<any, any>>;
|
|
18
|
+
operationRead: import("vue").ComputedRef<import("#imports").graphqlOperationObject<any, any>>;
|
|
19
|
+
operationReadPageable: import("vue").ComputedRef<import("#imports").graphqlOperationObject<any, any>>;
|
|
20
|
+
operationSearch: import("vue").ComputedRef<import("#imports").graphqlOperationObject<any, any>>;
|
|
21
21
|
};
|