bt-core-app 0.0.0
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/.vscode/extensions.json +3 -0
- package/README.md +45 -0
- package/index.html +13 -0
- package/package.json +39 -0
- package/public/vite.svg +1 -0
- package/src/assets/vue.svg +1 -0
- package/src/components/BT-Btn.vue +40 -0
- package/src/components/BT-Col.vue +36 -0
- package/src/components/BT-Span.vue +21 -0
- package/src/components/Dialog-Confirm.vue +47 -0
- package/src/components/Dialog-Select-Date.vue +89 -0
- package/src/components/Dialog-Select.vue +140 -0
- package/src/components/Dialog-Text.vue +59 -0
- package/src/composables/actions-tracker.ts +99 -0
- package/src/composables/actions.ts +354 -0
- package/src/composables/api.ts +471 -0
- package/src/composables/auth.ts +382 -0
- package/src/composables/cosmetics.ts +178 -0
- package/src/composables/csv.ts +198 -0
- package/src/composables/dates.ts +79 -0
- package/src/composables/demo.ts +25 -0
- package/src/composables/dialogs.ts +115 -0
- package/src/composables/document-meta.ts +40 -0
- package/src/composables/draggable.ts +189 -0
- package/src/composables/filters.ts +256 -0
- package/src/composables/forage.ts +49 -0
- package/src/composables/helpers.ts +694 -0
- package/src/composables/id.ts +20 -0
- package/src/composables/list.ts +601 -0
- package/src/composables/navigation.ts +214 -0
- package/src/composables/presets.ts +20 -0
- package/src/composables/pwa.ts +89 -0
- package/src/composables/resizable.ts +382 -0
- package/src/composables/rules.ts +40 -0
- package/src/composables/stores.ts +797 -0
- package/src/composables/track.ts +55 -0
- package/src/composables/urls.ts +11 -0
- package/src/core.ts +92 -0
- package/src/index.ts +16 -0
- package/src/types.ts +13 -0
- package/src/useApi.ts +68 -0
- package/src/vite-env.d.ts +1 -0
- package/test/api.test.ts +84 -0
- package/test/forage.test.ts +31 -0
- package/test/helpers.test.ts +231 -0
- package/test/navigation.test.ts +99 -0
- package/test/stores-last-update.test.ts +138 -0
- package/test/stores-session.test.ts +118 -0
- package/test/track.test.ts +29 -0
- package/test/utils.ts +15 -0
- package/tsconfig.json +33 -0
- package/tsconfig.node.json +11 -0
- package/vite.config.ts +19 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import type { BladeMode } from '@/types'
|
|
2
|
+
import { BTStore } from '@/composables/stores'
|
|
3
|
+
import { BTApi, type PathOptions } from '@/composables/api'
|
|
4
|
+
import { useActionsTracker, type DoActionOptions } from '@/composables/actions-tracker'
|
|
5
|
+
import { ShallowRef, ComputedRef } from 'vue'
|
|
6
|
+
|
|
7
|
+
export type OnCanDoAsync = (item: any) => Promise<string | undefined>
|
|
8
|
+
export type OnDoAsync = (item: any) => Promise<string | undefined>
|
|
9
|
+
export type OnDoSuccessAsync = (item: any) => Promise<any>
|
|
10
|
+
export type OnGetAsync = (opt?: GetOptions) => Promise<any>
|
|
11
|
+
export type OnGetSuccessAsync = (item: any, opt?: GetOptions) => Promise<any>
|
|
12
|
+
|
|
13
|
+
export interface GetOptions extends PathOptions, DoActionOptions {
|
|
14
|
+
/**returns an error msg if failed */
|
|
15
|
+
onGetAsync?: OnGetAsync
|
|
16
|
+
/**called after get occurs successfully */
|
|
17
|
+
onGetSuccessAsync?: OnGetSuccessAsync
|
|
18
|
+
store?: BTStore
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DeleteOptions extends PathOptions, DoActionOptions {
|
|
22
|
+
/**Returns a string if cannot */
|
|
23
|
+
onCanDeleteAsync?: OnCanDoAsync
|
|
24
|
+
/**Will override the default store delete action */
|
|
25
|
+
onDeleteAsync?: OnDoAsync
|
|
26
|
+
/**Will open a dialog box requesting user confirmation for delete action */
|
|
27
|
+
onDeleteSuccessAsync?: OnDoAsync
|
|
28
|
+
store?: BTStore
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface RestoreOptions extends PathOptions, DoActionOptions {
|
|
32
|
+
/**Returns a string if cannot */
|
|
33
|
+
onCanRestoreAsync?: OnCanDoAsync
|
|
34
|
+
/**Will override the default store delete action */
|
|
35
|
+
onRestoreAsync?: OnDoSuccessAsync
|
|
36
|
+
/**Called after restore succeeds */
|
|
37
|
+
onRestoreSuccessAsync?: OnDoSuccessAsync
|
|
38
|
+
store?: BTStore
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SaveOptions extends PathOptions, DoActionOptions {
|
|
42
|
+
/**will seek to post if 'new' otherwise will patch */
|
|
43
|
+
mode?: BladeMode
|
|
44
|
+
/**called to check whether to proceed with save */
|
|
45
|
+
onCanSaveAsync?: OnCanDoAsync
|
|
46
|
+
/**
|
|
47
|
+
* retrieves item to save
|
|
48
|
+
* called before seeing whether it can save
|
|
49
|
+
*/
|
|
50
|
+
onGetSaveAsync?: OnDoSuccessAsync
|
|
51
|
+
/**Will override the default store post/patch action */
|
|
52
|
+
onSaveAsync?: OnDoSuccessAsync
|
|
53
|
+
/**Called after save succeeds */
|
|
54
|
+
onSaveSuccessAsync?: OnDoSuccessAsync
|
|
55
|
+
store?: BTStore
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ApiActionOptions extends PathOptions, DoActionOptions {
|
|
59
|
+
api: BTApi
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface UseActionsOptions extends DoActionOptions {
|
|
63
|
+
nav?: string
|
|
64
|
+
proxyID?: string
|
|
65
|
+
refresh?: boolean
|
|
66
|
+
store?: BTStore
|
|
67
|
+
throwError?: boolean
|
|
68
|
+
url?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface BTActions {
|
|
72
|
+
apiGet: (doOptions: ApiActionOptions) => Promise<any>
|
|
73
|
+
apiPost: (doOptions: ApiActionOptions) => Promise<any>
|
|
74
|
+
actionLoadingMsg: ShallowRef<string | undefined>
|
|
75
|
+
actionErrorMsg: ShallowRef<string | undefined>
|
|
76
|
+
clearErrors: () => void
|
|
77
|
+
deleteItem: (doOptions: DeleteOptions) => Promise<any>
|
|
78
|
+
doAction: (action: any, options?: DoActionOptions) => Promise<any>
|
|
79
|
+
getAllItems: (doOptions: GetOptions) => Promise<any>
|
|
80
|
+
getItem: (doOptions: GetOptions) => Promise<any>
|
|
81
|
+
isLoading: ComputedRef<boolean>
|
|
82
|
+
logError: (err?: string | Error) => void
|
|
83
|
+
restoreItem: (doOptions: RestoreOptions) => Promise<any>
|
|
84
|
+
saveItem: (doOptions: SaveOptions) => Promise<any>
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function useActions(options?: UseActionsOptions): BTActions {
|
|
88
|
+
const { actionErrorMsg, actionLoadingMsg, clearErrors, isLoading, doAction, logError } = useActionsTracker(options)
|
|
89
|
+
|
|
90
|
+
function deleteItem(doOptions: DeleteOptions) {
|
|
91
|
+
doOptions.nav ??= options?.nav
|
|
92
|
+
doOptions.proxyID ??= options?.proxyID
|
|
93
|
+
doOptions.refresh ??= options?.refresh
|
|
94
|
+
doOptions.throwError ??= options?.throwError
|
|
95
|
+
doOptions.url ??= options?.url
|
|
96
|
+
doOptions.confirmationMsg ??= doOptions.requireConfirmation === true ? 'Are you sure you want to delete this item?' : undefined
|
|
97
|
+
doOptions.store ??= options?.store
|
|
98
|
+
const store = doOptions?.store ?? options?.store
|
|
99
|
+
|
|
100
|
+
if (doOptions.nav != null && store != null) {
|
|
101
|
+
doOptions.onDeleteAsync ??= () => {
|
|
102
|
+
return store().deleteItem(doOptions)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return doAction(async () => {
|
|
107
|
+
let err: string | undefined
|
|
108
|
+
|
|
109
|
+
if (doOptions.onCanDeleteAsync != null)
|
|
110
|
+
err = await doOptions.onCanDeleteAsync(doOptions.data)
|
|
111
|
+
|
|
112
|
+
if (err == undefined && doOptions.onDeleteAsync != null)
|
|
113
|
+
err = await doOptions.onDeleteAsync(doOptions.data)
|
|
114
|
+
|
|
115
|
+
if (err == undefined && doOptions.onDeleteSuccessAsync != null) {
|
|
116
|
+
await doOptions.onDeleteSuccessAsync(doOptions.data)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
logError(err)
|
|
120
|
+
}, {
|
|
121
|
+
completionMsg: doOptions.completionMsg ?? options?.completionMsg,
|
|
122
|
+
confirmationMsg: doOptions.confirmationMsg ?? options?.confirmationMsg,
|
|
123
|
+
errorMsg: doOptions.errorMsg ?? options?.errorMsg,
|
|
124
|
+
loadingMsg: doOptions.loadingMsg ?? options?.loadingMsg ?? 'Deleting',
|
|
125
|
+
requireConfirmation: doOptions.requireConfirmation ?? options?.requireConfirmation,
|
|
126
|
+
throwError: doOptions.throwError ?? options?.throwError
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getItem(doOptions: GetOptions) {
|
|
131
|
+
doOptions.nav ??= options?.nav
|
|
132
|
+
doOptions.proxyID ??= options?.proxyID
|
|
133
|
+
doOptions.refresh ??= options?.refresh
|
|
134
|
+
doOptions.throwError ??= options?.throwError
|
|
135
|
+
doOptions.url ??= options?.url
|
|
136
|
+
doOptions.confirmationMsg ??= doOptions.requireConfirmation === true ? 'Are you sure you want to get this item?' : undefined
|
|
137
|
+
const store = doOptions?.store ?? options?.store
|
|
138
|
+
|
|
139
|
+
if (doOptions.nav != null && store != null) {
|
|
140
|
+
doOptions.onGetAsync ??= () => {
|
|
141
|
+
return store().get(doOptions)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return doAction(async () => {
|
|
146
|
+
let res: any
|
|
147
|
+
|
|
148
|
+
if (doOptions.onGetAsync != null) {
|
|
149
|
+
res = await doOptions.onGetAsync(doOptions)
|
|
150
|
+
res = res.data
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (doOptions.onGetSuccessAsync != null)
|
|
154
|
+
res = await doOptions.onGetSuccessAsync(res, doOptions)
|
|
155
|
+
|
|
156
|
+
return res
|
|
157
|
+
}, {
|
|
158
|
+
completionMsg: doOptions.completionMsg ?? options?.completionMsg,
|
|
159
|
+
confirmationMsg: doOptions.confirmationMsg ?? options?.confirmationMsg,
|
|
160
|
+
errorMsg: doOptions.errorMsg ?? options?.errorMsg,
|
|
161
|
+
loadingMsg: doOptions.loadingMsg ?? options?.loadingMsg ?? 'Retrieving',
|
|
162
|
+
requireConfirmation: doOptions.requireConfirmation ?? options?.requireConfirmation,
|
|
163
|
+
throwError: doOptions.throwError ?? options?.throwError
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function getAllItems(doOptions: GetOptions) {
|
|
168
|
+
doOptions.nav ??= options?.nav
|
|
169
|
+
doOptions.proxyID ??= options?.proxyID
|
|
170
|
+
doOptions.refresh ??= options?.refresh
|
|
171
|
+
doOptions.throwError ??= options?.throwError
|
|
172
|
+
doOptions.url ??= options?.url
|
|
173
|
+
doOptions.confirmationMsg ??= doOptions.requireConfirmation === true ? 'Are you sure you want to get these items?' : undefined
|
|
174
|
+
const store = doOptions?.store ?? options?.store
|
|
175
|
+
|
|
176
|
+
if (doOptions.nav != null && store != null) {
|
|
177
|
+
doOptions.onGetAsync ??= () => {
|
|
178
|
+
return store().getAll(doOptions)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return doAction(async () => {
|
|
183
|
+
let res: any
|
|
184
|
+
|
|
185
|
+
if (doOptions.onGetAsync != null) {
|
|
186
|
+
res = await doOptions.onGetAsync(doOptions)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (doOptions.onGetSuccessAsync != null)
|
|
190
|
+
res = await doOptions.onGetSuccessAsync(res, doOptions)
|
|
191
|
+
|
|
192
|
+
return res
|
|
193
|
+
}, {
|
|
194
|
+
completionMsg: doOptions.completionMsg ?? options?.completionMsg,
|
|
195
|
+
confirmationMsg: doOptions.confirmationMsg ?? options?.confirmationMsg,
|
|
196
|
+
errorMsg: doOptions.errorMsg ?? options?.errorMsg,
|
|
197
|
+
loadingMsg: doOptions.loadingMsg ?? options?.loadingMsg ?? 'Retrieving',
|
|
198
|
+
requireConfirmation: doOptions.requireConfirmation ?? options?.requireConfirmation,
|
|
199
|
+
throwError: doOptions.throwError ?? options?.throwError
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function restoreItem(doOptions: RestoreOptions) {
|
|
204
|
+
doOptions.nav ??= options?.nav
|
|
205
|
+
doOptions.proxyID ??= options?.proxyID
|
|
206
|
+
doOptions.refresh ??= options?.refresh
|
|
207
|
+
doOptions.throwError ??= options?.throwError
|
|
208
|
+
doOptions.url ??= options?.url
|
|
209
|
+
doOptions.confirmationMsg ??= doOptions.requireConfirmation === true ? 'Are you sure you want to restore this item?' : undefined
|
|
210
|
+
const store = doOptions?.store ?? options?.store
|
|
211
|
+
|
|
212
|
+
if (doOptions.nav != null && store != null) {
|
|
213
|
+
doOptions.onRestoreAsync ??= () => {
|
|
214
|
+
return store().restore(doOptions)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return doAction(async () => {
|
|
219
|
+
let err: string | undefined
|
|
220
|
+
let res: any
|
|
221
|
+
|
|
222
|
+
if (doOptions.onCanRestoreAsync != null)
|
|
223
|
+
err = await doOptions.onCanRestoreAsync(doOptions.data)
|
|
224
|
+
|
|
225
|
+
if (err == undefined && doOptions.onRestoreAsync != null)
|
|
226
|
+
res = await doOptions.onRestoreAsync(doOptions.data)
|
|
227
|
+
|
|
228
|
+
if (res != null && doOptions.onRestoreSuccessAsync != null)
|
|
229
|
+
await doOptions.onRestoreSuccessAsync(res)
|
|
230
|
+
|
|
231
|
+
logError(err)
|
|
232
|
+
|
|
233
|
+
return res
|
|
234
|
+
}, {
|
|
235
|
+
completionMsg: doOptions.completionMsg ?? options?.completionMsg,
|
|
236
|
+
confirmationMsg: doOptions.confirmationMsg ?? options?.confirmationMsg,
|
|
237
|
+
errorMsg: doOptions.errorMsg ?? options?.errorMsg,
|
|
238
|
+
loadingMsg: doOptions.loadingMsg ?? options?.loadingMsg ?? 'Restoring',
|
|
239
|
+
requireConfirmation: doOptions.requireConfirmation ?? options?.requireConfirmation,
|
|
240
|
+
throwError: doOptions.throwError ?? options?.throwError
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function saveItem(doOptions: SaveOptions) {
|
|
245
|
+
doOptions.nav ??= options?.nav
|
|
246
|
+
doOptions.proxyID ??= options?.proxyID
|
|
247
|
+
doOptions.refresh ??= options?.refresh
|
|
248
|
+
doOptions.throwError ??= options?.throwError
|
|
249
|
+
doOptions.url ??= options?.url
|
|
250
|
+
doOptions.confirmationMsg ??= doOptions.requireConfirmation === true ? 'Are you sure you want to save this item?' : undefined
|
|
251
|
+
const store = doOptions?.store ?? options?.store
|
|
252
|
+
|
|
253
|
+
doOptions.onGetSaveAsync ??= (item: any) => item
|
|
254
|
+
doOptions.onCanSaveAsync ??= () => Promise.resolve(undefined)
|
|
255
|
+
|
|
256
|
+
if (doOptions.nav != null && store != null) {
|
|
257
|
+
doOptions.onSaveAsync ??= async () => { //item: any
|
|
258
|
+
if (doOptions.mode == 'new') {
|
|
259
|
+
return await store().post(doOptions)
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
return await store().patch(doOptions)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return doAction(async () => {
|
|
268
|
+
let itemToSave: any
|
|
269
|
+
|
|
270
|
+
if (doOptions.onGetSaveAsync != null)
|
|
271
|
+
itemToSave = await doOptions.onGetSaveAsync(doOptions.data)
|
|
272
|
+
|
|
273
|
+
if (itemToSave == null)
|
|
274
|
+
return undefined
|
|
275
|
+
|
|
276
|
+
if (doOptions.onCanSaveAsync != null) {
|
|
277
|
+
let err = await doOptions.onCanSaveAsync(itemToSave)
|
|
278
|
+
logError(err)
|
|
279
|
+
|
|
280
|
+
if (err == null)
|
|
281
|
+
return undefined
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
let res: any
|
|
285
|
+
if (doOptions.onSaveAsync != null) {
|
|
286
|
+
res = await doOptions.onSaveAsync!(itemToSave)
|
|
287
|
+
res = res.data
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (doOptions.onSaveSuccessAsync != null) {
|
|
291
|
+
res = await doOptions.onSaveSuccessAsync(res)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return res
|
|
295
|
+
}, {
|
|
296
|
+
completionMsg: doOptions.completionMsg ?? options?.completionMsg,
|
|
297
|
+
confirmationMsg: doOptions.confirmationMsg ?? options?.confirmationMsg,
|
|
298
|
+
errorMsg: doOptions.errorMsg ?? options?.errorMsg,
|
|
299
|
+
loadingMsg: doOptions.loadingMsg ?? options?.loadingMsg ?? 'Saving',
|
|
300
|
+
requireConfirmation: doOptions.requireConfirmation ?? options?.requireConfirmation,
|
|
301
|
+
throwError: doOptions.throwError ?? options?.throwError
|
|
302
|
+
})
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Post to api (no extra '/post' url or anything)
|
|
307
|
+
* @param options
|
|
308
|
+
*/
|
|
309
|
+
function apiPost(doOptions: ApiActionOptions) {
|
|
310
|
+
doOptions.nav ??= options?.nav
|
|
311
|
+
doOptions.proxyID ??= options?.proxyID
|
|
312
|
+
doOptions.refresh ??= options?.refresh
|
|
313
|
+
doOptions.throwError ??= options?.throwError
|
|
314
|
+
doOptions.url ??= options?.url
|
|
315
|
+
|
|
316
|
+
return doAction(async () => {
|
|
317
|
+
return await doOptions.api.post(doOptions)
|
|
318
|
+
}, options)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Get from api (no extra '/get' url or anything)
|
|
323
|
+
*/
|
|
324
|
+
function apiGet(doOptions: ApiActionOptions) {
|
|
325
|
+
doOptions.nav ??= options?.nav
|
|
326
|
+
doOptions.proxyID ??= options?.proxyID
|
|
327
|
+
doOptions.refresh ??= options?.refresh
|
|
328
|
+
doOptions.throwError ??= options?.throwError
|
|
329
|
+
doOptions.url ??= options?.url
|
|
330
|
+
|
|
331
|
+
return doAction(async () => {
|
|
332
|
+
return await doOptions.api.get(doOptions)
|
|
333
|
+
}, options)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
apiGet,
|
|
338
|
+
apiPost,
|
|
339
|
+
actionLoadingMsg,
|
|
340
|
+
actionErrorMsg,
|
|
341
|
+
clearErrors,
|
|
342
|
+
deleteItem,
|
|
343
|
+
doAction,
|
|
344
|
+
getAllItems,
|
|
345
|
+
getItem,
|
|
346
|
+
isLoading,
|
|
347
|
+
logError,
|
|
348
|
+
restoreItem,
|
|
349
|
+
saveItem
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
//#endregion
|