@d-mok/quasar-app-extension-quasar-axe 1.0.154 → 2.0.1
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/package.json +1 -1
- package/src/index.js +5 -26
- package/src/install.js +2 -10
- package/src/{templates_vite → templates}/src/boot/axe/AutoReg.ts +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/AutoRoute.ts +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/Interceptor.ts +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxFloatBtn.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxImg.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxLayout.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxMenuItem.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxPlate.vue +3 -1
- package/src/{templates_vite → templates}/src/boot/axe/components/QxSelectObject.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxSelectText.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxSignoutBtn.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxSortable.vue +0 -0
- package/src/{templates_vite → templates}/src/boot/axe/components/QxWidget.vue +0 -0
- package/src/{templates_vite → templates}/src/utils/csv.ts +0 -0
- package/src/templates/src/utils/dialog/advanced.ts +206 -0
- package/src/templates/src/utils/dialog/basic.ts +164 -0
- package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/dialogBtn.vue +0 -0
- package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/dialogForm.vue +0 -0
- package/src/{templates_vite/src/utils/dialogs/dialogCSV.vue → templates/src/utils/dialog/custom/dialogTable.vue} +0 -0
- package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/dialogTextarea.vue +0 -0
- package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/handson.vue +0 -0
- package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/schema.ts +0 -0
- package/src/templates/src/utils/dialog/index.ts +4 -0
- package/src/templates/src/utils/dialog/tool.ts +11 -0
- package/src/{templates_vite → templates}/src/utils/index.ts +1 -1
- package/src/templates/src/utils/notify.ts +35 -0
- package/src/{templates_vite → templates}/src/utils/puppets/builder/index.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/puppets/builder/ui.ts +2 -2
- package/src/{templates_vite → templates}/src/utils/puppets/core/db.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/puppets/core/index.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/puppets/entity.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/puppets/index.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/puppets/table.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/puppets/type.ts +0 -0
- package/src/{templates_vite → templates}/src/utils/settings.ts +4 -6
- package/src/templates/src/utils/supabase.ts +130 -0
- package/src/{templates_vite → templates}/src/utils/zip.ts +0 -0
- package/src/uninstall.js +1 -4
- package/src/templates_vite/src/utils/dialog.ts +0 -364
- package/src/templates_vite/src/utils/notify.ts +0 -70
- package/src/templates_vite/src/utils/supabase.ts +0 -181
- package/src/templates_webpack/src/boot/axe/AutoReg.ts +0 -23
- package/src/templates_webpack/src/boot/axe/AutoRoute.ts +0 -35
- package/src/templates_webpack/src/boot/axe/Interceptor.ts +0 -94
- package/src/templates_webpack/src/boot/axe/LoadUtils.ts +0 -9
- package/src/templates_webpack/src/boot/axe/RegComp.ts +0 -18
- package/src/templates_webpack/src/boot/axe/components/QxLayout.vue +0 -117
- package/src/templates_webpack/src/boot/axe/components/QxMenuItem.vue +0 -52
- package/src/templates_webpack/src/boot/axe/components/QxSelectObject.vue +0 -76
- package/src/templates_webpack/src/boot/axe/components/QxSelectText.vue +0 -50
- package/src/templates_webpack/src/boot/axe/components/QxSignoutBtn.vue +0 -20
- package/src/templates_webpack/src/boot/axe/utils/dialog.ts +0 -494
- package/src/templates_webpack/src/boot/axe/utils/index.ts +0 -79
- package/src/templates_webpack/src/boot/axe/utils/notify.ts +0 -70
- package/src/templates_webpack/src/boot/axe/utils/puppets/builder/index.ts +0 -281
- package/src/templates_webpack/src/boot/axe/utils/puppets/builder/ui.ts +0 -37
- package/src/templates_webpack/src/boot/axe/utils/puppets/core/db.ts +0 -196
- package/src/templates_webpack/src/boot/axe/utils/puppets/core/index.ts +0 -47
- package/src/templates_webpack/src/boot/axe/utils/puppets/entity.ts +0 -60
- package/src/templates_webpack/src/boot/axe/utils/puppets/index.ts +0 -3
- package/src/templates_webpack/src/boot/axe/utils/puppets/table.ts +0 -252
- package/src/templates_webpack/src/boot/axe/utils/puppets/type.ts +0 -17
- package/src/templates_webpack/src/boot/axe/utils/sapphire.ts +0 -1
- package/src/templates_webpack/src/boot/axe/utils/settings.ts +0 -22
- package/src/templates_webpack/src/boot/axe/utils/supabase.ts +0 -159
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,27 +1,8 @@
|
|
|
1
|
-
function extendQuasarConf(conf, prompts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
for (let b of boots) conf.boot.unshift(`axe/${b}`)
|
|
6
|
-
} else {
|
|
7
|
-
let boots = [
|
|
8
|
-
'LoadUtils',
|
|
9
|
-
'AutoRoute',
|
|
10
|
-
'RegComp',
|
|
11
|
-
'AutoReg',
|
|
12
|
-
'Interceptor',
|
|
13
|
-
]
|
|
14
|
-
|
|
15
|
-
for (let b of boots) conf.boot.unshift(`axe/${b}`)
|
|
16
|
-
}
|
|
17
|
-
|
|
1
|
+
function extendQuasarConf(conf, prompts) {
|
|
2
|
+
for (let b of ['AutoRoute', 'AutoReg', 'Interceptor'])
|
|
3
|
+
conf.boot.unshift(`axe/${b}`)
|
|
18
4
|
console.log('[QuasarAxe] Config pushed Boots')
|
|
19
5
|
|
|
20
|
-
if (!isVite)
|
|
21
|
-
conf.build.transpileDependencies.push(
|
|
22
|
-
/\@d-mok\/quasar-app-extension-quasar-axe[\\/]src/
|
|
23
|
-
)
|
|
24
|
-
|
|
25
6
|
conf.framework.plugins.push(
|
|
26
7
|
'AppVisibility',
|
|
27
8
|
'Notify',
|
|
@@ -45,8 +26,6 @@ function extendQuasarConf(conf, prompts, isVite) {
|
|
|
45
26
|
|
|
46
27
|
module.exports = function (api) {
|
|
47
28
|
api.compatibleWith('quasar', '^2.0.0')
|
|
48
|
-
|
|
49
|
-
api.extendQuasarConf(conf =>
|
|
50
|
-
extendQuasarConf(conf, api.prompts, api.hasVite)
|
|
51
|
-
)
|
|
29
|
+
api.compatibleWith('@quasar/app-vite', '^1.0.0')
|
|
30
|
+
api.extendQuasarConf(conf => extendQuasarConf(conf, api.prompts))
|
|
52
31
|
}
|
package/src/install.js
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
module.exports = function (api) {
|
|
2
2
|
api.compatibleWith('quasar', '^2.0.0')
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (api.hasVite) {
|
|
8
|
-
api.render('./templates_vite')
|
|
9
|
-
} else {
|
|
10
|
-
api.render('./templates_webpack')
|
|
11
|
-
}
|
|
12
|
-
|
|
3
|
+
api.compatibleWith('@quasar/app-vite', '^1.0.0')
|
|
4
|
+
api.render('./templates')
|
|
13
5
|
api.onExitLog('Thanks for installing quasar-axe!')
|
|
14
6
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -27,6 +27,7 @@ interface Props {
|
|
|
27
27
|
data: any // me
|
|
28
28
|
modelValue: object | string | number | null // the selected one
|
|
29
29
|
clickToSelect?: boolean // if selected is null, onClick will select me
|
|
30
|
+
clickToReselect?: boolean // if selected something else, onClick will select me
|
|
30
31
|
clickToDeselect?: boolean // if selected is me, onClick will deselect
|
|
31
32
|
hoverPale?: boolean
|
|
32
33
|
hoverOutline?: boolean
|
|
@@ -41,6 +42,7 @@ interface Props {
|
|
|
41
42
|
const props = withDefaults(defineProps<Props>(), {
|
|
42
43
|
data: {},
|
|
43
44
|
clickToSelect: false,
|
|
45
|
+
clickToReselect: false,
|
|
44
46
|
clickToDeselect: false,
|
|
45
47
|
hoverPale: false,
|
|
46
48
|
hoverOutline: false,
|
|
@@ -67,7 +69,6 @@ function onClick() {
|
|
|
67
69
|
let selected = props.modelValue
|
|
68
70
|
if (selected === null) {
|
|
69
71
|
emits('clickSelectNull')
|
|
70
|
-
// if selected is empty, select me
|
|
71
72
|
if (props.clickToSelect) emits('update:model-value', props.data)
|
|
72
73
|
} else if (selected === props.data) {
|
|
73
74
|
emits('clickSelecting')
|
|
@@ -76,6 +77,7 @@ function onClick() {
|
|
|
76
77
|
} else {
|
|
77
78
|
emits('clickSelecting')
|
|
78
79
|
emits('clickSelectOther')
|
|
80
|
+
if (props.clickToReselect) emits('update:model-value', props.data)
|
|
79
81
|
}
|
|
80
82
|
emits('click')
|
|
81
83
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Dialog, QDialogOptions } from 'quasar'
|
|
2
|
+
import dialogTextarea from './custom/dialogTextarea.vue'
|
|
3
|
+
import dialogTable from './custom/dialogTable.vue'
|
|
4
|
+
import dialogForm from './custom/dialogForm.vue'
|
|
5
|
+
import dialogBtn from './custom/dialogBtn.vue'
|
|
6
|
+
import { throwError } from './basic'
|
|
7
|
+
import { getLabelFunc } from './tool'
|
|
8
|
+
|
|
9
|
+
type Predicate<T> = (_: T) => boolean
|
|
10
|
+
type Mapper<T, S> = (_: T) => S
|
|
11
|
+
|
|
12
|
+
async function base(component: QDialogOptions['component'], props: any) {
|
|
13
|
+
return new Promise<any>((resolve, reject) =>
|
|
14
|
+
Dialog.create({
|
|
15
|
+
component,
|
|
16
|
+
componentProps: {
|
|
17
|
+
persistent: true,
|
|
18
|
+
...props,
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
.onOk((data: any) => resolve(data))
|
|
22
|
+
.onCancel(() => reject('dialog cancelled by user.'))
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Ask for a string by a text area. Allow empty.
|
|
28
|
+
*/
|
|
29
|
+
export async function askTextarea(
|
|
30
|
+
title: string,
|
|
31
|
+
message: string = '',
|
|
32
|
+
prefill: string = '',
|
|
33
|
+
isValid: Predicate<string> = $ => true
|
|
34
|
+
): Promise<string> {
|
|
35
|
+
return await base(dialogTextarea, {
|
|
36
|
+
title,
|
|
37
|
+
message,
|
|
38
|
+
prefill,
|
|
39
|
+
isValid,
|
|
40
|
+
cancel: true,
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Ask to select one object by a button group.
|
|
46
|
+
*/
|
|
47
|
+
export async function askBtn<T>(
|
|
48
|
+
title: string,
|
|
49
|
+
message: string = '',
|
|
50
|
+
items: T[],
|
|
51
|
+
label?: (string & keyof T) | Mapper<T, string>
|
|
52
|
+
): Promise<T> {
|
|
53
|
+
return await base(dialogBtn, {
|
|
54
|
+
title,
|
|
55
|
+
message,
|
|
56
|
+
items,
|
|
57
|
+
labelFunc: getLabelFunc(label),
|
|
58
|
+
cancel: true,
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Ask to select a function to run.
|
|
64
|
+
*/
|
|
65
|
+
export async function askFn(
|
|
66
|
+
title: string,
|
|
67
|
+
message: string,
|
|
68
|
+
funcs: Record<string, () => any>
|
|
69
|
+
): Promise<string> {
|
|
70
|
+
let key = await askBtn(title, message, Object.keys(funcs))
|
|
71
|
+
await funcs[key]()
|
|
72
|
+
return key
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Ask for an array of objects by table.
|
|
77
|
+
* Input object must have the same keys as sample.
|
|
78
|
+
*/
|
|
79
|
+
export async function askTable<T extends object>(
|
|
80
|
+
title: string,
|
|
81
|
+
message: string = '',
|
|
82
|
+
prefills: T[][],
|
|
83
|
+
isValid: Predicate<T> = $ => true
|
|
84
|
+
): Promise<T[]> {
|
|
85
|
+
let content = prefills.find($ => $.length > 0)
|
|
86
|
+
if (content === undefined) {
|
|
87
|
+
throwError('Error', 'All prefills are empty array.')
|
|
88
|
+
}
|
|
89
|
+
return await base(dialogTable, {
|
|
90
|
+
title,
|
|
91
|
+
message,
|
|
92
|
+
content,
|
|
93
|
+
sample: content[0],
|
|
94
|
+
isValid,
|
|
95
|
+
cancel: true,
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Ask for an array of strings. Omit all empty strings.
|
|
101
|
+
*/
|
|
102
|
+
export async function askArray(
|
|
103
|
+
title: string,
|
|
104
|
+
message: string = '',
|
|
105
|
+
prefill: string[] = [],
|
|
106
|
+
isValid: Predicate<string> = $ => true
|
|
107
|
+
): Promise<string[]> {
|
|
108
|
+
function split(s: string): string[] {
|
|
109
|
+
return s.split('\n').filter($ => $.trim() !== '')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let str: string = await base(dialogTextarea, {
|
|
113
|
+
title,
|
|
114
|
+
message,
|
|
115
|
+
prefill: prefill.join('\n'),
|
|
116
|
+
isValid: (s: string) => split(s).every(isValid),
|
|
117
|
+
cancel: true,
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
return split(str)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
type FormPrefill = Record<
|
|
124
|
+
string,
|
|
125
|
+
| string
|
|
126
|
+
| number
|
|
127
|
+
| boolean
|
|
128
|
+
| { type: 'select'; value: string; options: string[] }
|
|
129
|
+
>
|
|
130
|
+
|
|
131
|
+
type FormFlat<T extends FormPrefill> = {
|
|
132
|
+
[P in keyof T]: T[P] extends object ? T[P]['value'] : T[P]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Ask for an array of objects by CSV.
|
|
137
|
+
* Input object must have the same keys as sample.
|
|
138
|
+
*/
|
|
139
|
+
export async function askForm<T extends FormPrefill>(
|
|
140
|
+
title: string,
|
|
141
|
+
message: string,
|
|
142
|
+
prefill: T,
|
|
143
|
+
validator: (_: FormFlat<T>) => true | string = $ => true
|
|
144
|
+
): Promise<FormFlat<T>> {
|
|
145
|
+
return await base(dialogForm, {
|
|
146
|
+
title,
|
|
147
|
+
message,
|
|
148
|
+
prefill,
|
|
149
|
+
validator,
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Show a dialog with text area display.
|
|
155
|
+
*/
|
|
156
|
+
export async function showTextarea(
|
|
157
|
+
title: string,
|
|
158
|
+
message: string = '',
|
|
159
|
+
content: string = ''
|
|
160
|
+
): Promise<void> {
|
|
161
|
+
await base(dialogTextarea, {
|
|
162
|
+
title,
|
|
163
|
+
message,
|
|
164
|
+
prefill: content,
|
|
165
|
+
isValid: ($: string) => true,
|
|
166
|
+
cancel: false,
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Show a dialog with table display.
|
|
172
|
+
*/
|
|
173
|
+
export async function showTable(
|
|
174
|
+
title: string,
|
|
175
|
+
message: string,
|
|
176
|
+
content: object[]
|
|
177
|
+
): Promise<void> {
|
|
178
|
+
if (content.length === 0) {
|
|
179
|
+
content = [{ empty: '' }]
|
|
180
|
+
}
|
|
181
|
+
await base(dialogTable, {
|
|
182
|
+
title,
|
|
183
|
+
message,
|
|
184
|
+
content,
|
|
185
|
+
sample: content[0],
|
|
186
|
+
isValid: ($: any) => true,
|
|
187
|
+
cancel: false,
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Show a dialog with array display.
|
|
193
|
+
*/
|
|
194
|
+
export async function showArray(
|
|
195
|
+
title: string,
|
|
196
|
+
message: string = '',
|
|
197
|
+
content: unknown[] = []
|
|
198
|
+
): Promise<void> {
|
|
199
|
+
await base(dialogTextarea, {
|
|
200
|
+
title,
|
|
201
|
+
message,
|
|
202
|
+
prefill: content.map($ => String($)).join('\n'),
|
|
203
|
+
isValid: ($: string) => true,
|
|
204
|
+
cancel: false,
|
|
205
|
+
})
|
|
206
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { Dialog, QDialogOptions } from 'quasar'
|
|
2
|
+
import { getLabelFunc } from './tool'
|
|
3
|
+
|
|
4
|
+
type Predicate<T> = (_: T) => boolean
|
|
5
|
+
type Mapper<T, S> = (_: T) => S
|
|
6
|
+
|
|
7
|
+
async function base(options: QDialogOptions): Promise<string> {
|
|
8
|
+
let { prompt, ...rest } = options
|
|
9
|
+
|
|
10
|
+
let opt: QDialogOptions = {
|
|
11
|
+
persistent: true,
|
|
12
|
+
cancel: true,
|
|
13
|
+
ok: true,
|
|
14
|
+
html: true,
|
|
15
|
+
prompt: {
|
|
16
|
+
model: '',
|
|
17
|
+
outlined: true,
|
|
18
|
+
...prompt,
|
|
19
|
+
},
|
|
20
|
+
...rest,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (options.prompt === undefined) delete opt.prompt
|
|
24
|
+
|
|
25
|
+
return new Promise<string>((resolve, reject) =>
|
|
26
|
+
Dialog.create(opt)
|
|
27
|
+
.onOk((data: unknown) => resolve(String(data)))
|
|
28
|
+
.onCancel(() => reject('dialog cancelled by user.'))
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Show a dialog with only the OK button.
|
|
34
|
+
*/
|
|
35
|
+
export async function info(title: string, message: string = ''): Promise<void> {
|
|
36
|
+
await base({
|
|
37
|
+
title,
|
|
38
|
+
message,
|
|
39
|
+
cancel: false,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Show a confirm dialog.
|
|
45
|
+
* If OK, continue. If cancel, throw error.
|
|
46
|
+
*/
|
|
47
|
+
export async function confirm(
|
|
48
|
+
title: string,
|
|
49
|
+
message: string = ''
|
|
50
|
+
): Promise<void> {
|
|
51
|
+
await base({
|
|
52
|
+
title,
|
|
53
|
+
message,
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Show an error dialog with only the OK button.
|
|
59
|
+
*/
|
|
60
|
+
export async function error(
|
|
61
|
+
title: string,
|
|
62
|
+
message: string = ''
|
|
63
|
+
): Promise<void> {
|
|
64
|
+
await base({
|
|
65
|
+
title,
|
|
66
|
+
message,
|
|
67
|
+
color: 'red',
|
|
68
|
+
cancel: false,
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Show an error dialog with only the OK button.
|
|
74
|
+
* Throw an error at the same time.
|
|
75
|
+
*/
|
|
76
|
+
export function throwError(title: string, message: string = ''): never {
|
|
77
|
+
error(title, message)
|
|
78
|
+
throw 'dialog throw an intended error.'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Ask for a string by a simple text field. Allow empty input.
|
|
83
|
+
*/
|
|
84
|
+
export async function ask(
|
|
85
|
+
title: string,
|
|
86
|
+
message: string = '',
|
|
87
|
+
prefill: string = '',
|
|
88
|
+
isValid: Predicate<string> = $ => true
|
|
89
|
+
): Promise<string> {
|
|
90
|
+
return base({
|
|
91
|
+
title,
|
|
92
|
+
message,
|
|
93
|
+
prompt: {
|
|
94
|
+
model: prefill,
|
|
95
|
+
type: 'text',
|
|
96
|
+
isValid,
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Ask for a string by a simple text field. Not accept empty input.
|
|
103
|
+
*/
|
|
104
|
+
export async function askText(
|
|
105
|
+
title: string,
|
|
106
|
+
message: string = '',
|
|
107
|
+
prefill: string = '',
|
|
108
|
+
isValid: Predicate<string> = $ => true
|
|
109
|
+
): Promise<string> {
|
|
110
|
+
return await ask(title, message, prefill, $ => isValid($) && $.length > 0)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Ask for a number by a simple text field. Not allow empty input.
|
|
115
|
+
*/
|
|
116
|
+
export async function askNum(
|
|
117
|
+
title: string,
|
|
118
|
+
message: string = '',
|
|
119
|
+
prefill: number = 0,
|
|
120
|
+
isValid: Predicate<number> = $ => true
|
|
121
|
+
): Promise<number> {
|
|
122
|
+
let str = await base({
|
|
123
|
+
title,
|
|
124
|
+
message,
|
|
125
|
+
prompt: {
|
|
126
|
+
model: String(prefill),
|
|
127
|
+
type: 'number',
|
|
128
|
+
isValid: $ =>
|
|
129
|
+
$.length > 0 &&
|
|
130
|
+
Number.isFinite(Number($)) &&
|
|
131
|
+
isValid(Number($)),
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
return Number(str)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Ask to select one object by a radio button group. Must select exactly one object.
|
|
139
|
+
*/
|
|
140
|
+
export async function askRadio<T>(
|
|
141
|
+
title: string,
|
|
142
|
+
message: string = '',
|
|
143
|
+
items: T[],
|
|
144
|
+
label?: (string & keyof T) | Mapper<T, string>
|
|
145
|
+
): Promise<T> {
|
|
146
|
+
let labelFunc = getLabelFunc(label)
|
|
147
|
+
let values = items.map(labelFunc)
|
|
148
|
+
|
|
149
|
+
let value = await base({
|
|
150
|
+
title,
|
|
151
|
+
message,
|
|
152
|
+
options: {
|
|
153
|
+
model: '',
|
|
154
|
+
type: 'radio',
|
|
155
|
+
items: items.map($ => ({
|
|
156
|
+
label: labelFunc($),
|
|
157
|
+
value: labelFunc($),
|
|
158
|
+
})),
|
|
159
|
+
isValid: $ => typeof $ === 'string' && values.includes($),
|
|
160
|
+
},
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
return items.find($ => labelFunc($) === value)!
|
|
164
|
+
}
|
package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/dialogBtn.vue
RENAMED
|
File without changes
|
package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/dialogForm.vue
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/handson.vue
RENAMED
|
File without changes
|
package/src/{templates_vite/src/utils/dialogs → templates/src/utils/dialog/custom}/schema.ts
RENAMED
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Labeler<T> = (string & keyof T) | ((_: T) => string)
|
|
2
|
+
|
|
3
|
+
export function getLabelFunc<T>(labeler?: Labeler<T>) {
|
|
4
|
+
if (typeof labeler === 'string') {
|
|
5
|
+
return ($: T) => String($[labeler])
|
|
6
|
+
}
|
|
7
|
+
if (typeof labeler === 'function') {
|
|
8
|
+
return labeler
|
|
9
|
+
}
|
|
10
|
+
return ($: T) => String($)
|
|
11
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Notify } from 'quasar'
|
|
2
|
+
|
|
3
|
+
function base(
|
|
4
|
+
message: string,
|
|
5
|
+
type: 'positive' | 'negative' | 'warning' | 'info' | 'ongoing'
|
|
6
|
+
) {
|
|
7
|
+
Notify.create({
|
|
8
|
+
message: message,
|
|
9
|
+
progress: true,
|
|
10
|
+
type: type,
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function toast(message: string): void {
|
|
15
|
+
base(message, 'positive')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function error(message: string): void {
|
|
19
|
+
base(message, 'negative')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function warn(message: string): void {
|
|
23
|
+
base(message, 'warning')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function info(message: string): void {
|
|
27
|
+
base(message, 'info')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function load(loadingMsg = 'Loading...'): () => void {
|
|
31
|
+
return Notify.create({
|
|
32
|
+
type: 'ongoing',
|
|
33
|
+
message: loadingMsg,
|
|
34
|
+
}) as () => void
|
|
35
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
|
|
2
1
|
import { reactive, effect } from '@vue/reactivity'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
function getFromLocal<T extends object>(key: string): T {
|
|
7
4
|
let val = localStorage.getItem(key)
|
|
8
5
|
return val === null ? {} : JSON.parse(val)
|
|
9
6
|
}
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
export function localSettings<T extends object>(
|
|
9
|
+
preset: T,
|
|
10
|
+
localStorageKey = 'settings'
|
|
11
|
+
): T {
|
|
13
12
|
let ss = reactive({ ...preset, ...getFromLocal<T>(localStorageKey) })
|
|
14
13
|
effect(() => {
|
|
15
14
|
localStorage.setItem('settings', JSON.stringify(ss))
|
|
@@ -19,4 +18,3 @@ export function localSettings<T extends object>(preset: T, localStorageKey = 'se
|
|
|
19
18
|
})
|
|
20
19
|
return ss as T
|
|
21
20
|
}
|
|
22
|
-
|