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.
Files changed (53) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/README.md +45 -0
  3. package/index.html +13 -0
  4. package/package.json +39 -0
  5. package/public/vite.svg +1 -0
  6. package/src/assets/vue.svg +1 -0
  7. package/src/components/BT-Btn.vue +40 -0
  8. package/src/components/BT-Col.vue +36 -0
  9. package/src/components/BT-Span.vue +21 -0
  10. package/src/components/Dialog-Confirm.vue +47 -0
  11. package/src/components/Dialog-Select-Date.vue +89 -0
  12. package/src/components/Dialog-Select.vue +140 -0
  13. package/src/components/Dialog-Text.vue +59 -0
  14. package/src/composables/actions-tracker.ts +99 -0
  15. package/src/composables/actions.ts +354 -0
  16. package/src/composables/api.ts +471 -0
  17. package/src/composables/auth.ts +382 -0
  18. package/src/composables/cosmetics.ts +178 -0
  19. package/src/composables/csv.ts +198 -0
  20. package/src/composables/dates.ts +79 -0
  21. package/src/composables/demo.ts +25 -0
  22. package/src/composables/dialogs.ts +115 -0
  23. package/src/composables/document-meta.ts +40 -0
  24. package/src/composables/draggable.ts +189 -0
  25. package/src/composables/filters.ts +256 -0
  26. package/src/composables/forage.ts +49 -0
  27. package/src/composables/helpers.ts +694 -0
  28. package/src/composables/id.ts +20 -0
  29. package/src/composables/list.ts +601 -0
  30. package/src/composables/navigation.ts +214 -0
  31. package/src/composables/presets.ts +20 -0
  32. package/src/composables/pwa.ts +89 -0
  33. package/src/composables/resizable.ts +382 -0
  34. package/src/composables/rules.ts +40 -0
  35. package/src/composables/stores.ts +797 -0
  36. package/src/composables/track.ts +55 -0
  37. package/src/composables/urls.ts +11 -0
  38. package/src/core.ts +92 -0
  39. package/src/index.ts +16 -0
  40. package/src/types.ts +13 -0
  41. package/src/useApi.ts +68 -0
  42. package/src/vite-env.d.ts +1 -0
  43. package/test/api.test.ts +84 -0
  44. package/test/forage.test.ts +31 -0
  45. package/test/helpers.test.ts +231 -0
  46. package/test/navigation.test.ts +99 -0
  47. package/test/stores-last-update.test.ts +138 -0
  48. package/test/stores-session.test.ts +118 -0
  49. package/test/track.test.ts +29 -0
  50. package/test/utils.ts +15 -0
  51. package/tsconfig.json +33 -0
  52. package/tsconfig.node.json +11 -0
  53. 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