@bagelink/vue 0.0.427 → 0.0.431
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/components/Alert.vue.d.ts +4 -1
- package/dist/components/Alert.vue.d.ts.map +1 -1
- package/dist/components/TableSchema.vue.d.ts +2 -5
- package/dist/components/TableSchema.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DatePicker.vue.d.ts +4 -0
- package/dist/components/form/inputs/DatePicker.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/FileUpload.vue.d.ts +6 -2
- package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RadioPillsInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts +0 -3
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/components/layout/Tabs.vue.d.ts +6 -2
- package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
- package/dist/components/layout/TabsNav.vue.d.ts.map +1 -1
- package/dist/index.cjs +193 -113
- package/dist/index.mjs +194 -114
- package/dist/plugins/bagel.d.ts +3 -0
- package/dist/plugins/bagel.d.ts.map +1 -1
- package/dist/style.css +145 -127
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/lang.d.ts +7 -0
- package/dist/utils/lang.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Alert.vue +4 -2
- package/src/components/TableSchema.vue +19 -9
- package/src/components/form/inputs/DatePicker.vue +8 -2
- package/src/components/form/inputs/FileUpload.vue +54 -23
- package/src/components/form/inputs/RadioPillsInput.vue +5 -4
- package/src/components/form/inputs/SelectInput.vue +212 -204
- package/src/components/form/inputs/TextInput.vue +1 -1
- package/src/components/layout/Tabs.vue +14 -5
- package/src/components/layout/TabsNav.vue +34 -14
- package/src/plugins/bagel.ts +13 -4
- package/src/utils/index.ts +2 -0
- package/src/utils/lang.ts +39 -0
|
@@ -6,15 +6,18 @@
|
|
|
6
6
|
class="col"
|
|
7
7
|
v-for="field in computedSchema"
|
|
8
8
|
:key="field.id"
|
|
9
|
-
@click="sort(field?.id || '')"
|
|
9
|
+
@click="sort(field?.id || '')"
|
|
10
|
+
>
|
|
10
11
|
<div class="flex">
|
|
11
12
|
{{ field.label || keyToLabel(field.id) }}
|
|
12
13
|
<div
|
|
13
14
|
class="list-arrows"
|
|
14
|
-
:class="{ sorted: sortField === field.id }"
|
|
15
|
+
:class="{ sorted: sortField === field.id }"
|
|
16
|
+
>
|
|
15
17
|
<MaterialIcon
|
|
16
18
|
:class="{ desc: sortDirection === 'DESC' }"
|
|
17
|
-
icon="keyboard_arrow_up"
|
|
19
|
+
icon="keyboard_arrow_up"
|
|
20
|
+
/>
|
|
18
21
|
</div>
|
|
19
22
|
</div>
|
|
20
23
|
</th>
|
|
@@ -24,25 +27,29 @@
|
|
|
24
27
|
v-for="row in computedData"
|
|
25
28
|
:key="row.id"
|
|
26
29
|
@click="selectElement(row)"
|
|
27
|
-
class="row row-item position-relative"
|
|
30
|
+
class="row row-item position-relative"
|
|
31
|
+
>
|
|
28
32
|
<td
|
|
29
33
|
class="col"
|
|
30
34
|
v-for="field in computedSchema.map((c) => ({
|
|
31
35
|
...c,
|
|
32
36
|
transform: undefined,
|
|
33
37
|
}))"
|
|
34
|
-
:key="`${field.id}-${row.id}`"
|
|
38
|
+
:key="`${field.id}-${row.id}`"
|
|
39
|
+
>
|
|
35
40
|
<slot
|
|
36
41
|
v-if="field.id && slots[field.id]"
|
|
37
42
|
:name="field.id"
|
|
38
43
|
:row="row"
|
|
39
|
-
:field="field"
|
|
44
|
+
:field="field"
|
|
45
|
+
/>
|
|
40
46
|
<div v-else>
|
|
41
47
|
<BglField
|
|
42
48
|
class="embedded-field"
|
|
43
49
|
:field="field"
|
|
44
50
|
:modelValue="row"
|
|
45
|
-
label=""
|
|
51
|
+
label=""
|
|
52
|
+
/>
|
|
46
53
|
</div>
|
|
47
54
|
</td>
|
|
48
55
|
</tr>
|
|
@@ -65,14 +72,17 @@ const loading = $ref(true);
|
|
|
65
72
|
|
|
66
73
|
const props = defineProps<{
|
|
67
74
|
data: any[];
|
|
68
|
-
schema
|
|
75
|
+
schema?: BglFormSchemaT | (() => BglFormSchemaT);
|
|
69
76
|
}>();
|
|
70
77
|
|
|
71
78
|
const computedSchema = $computed(() => {
|
|
72
79
|
if (typeof props.schema === 'function') {
|
|
73
80
|
return props.schema();
|
|
74
81
|
}
|
|
75
|
-
return props.schema;
|
|
82
|
+
if (props.schema) return props.schema;
|
|
83
|
+
const keys = [...new Set((props.data || []).map(Object.keys).flat())] as string[];
|
|
84
|
+
const schema: BglFormSchemaT = keys.map((id) => ({ id, label: keyToLabel(id) }));
|
|
85
|
+
return schema;
|
|
76
86
|
});
|
|
77
87
|
|
|
78
88
|
const emit = defineEmits(['select', 'orderBy']);
|
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
inline
|
|
6
6
|
week-start="0"
|
|
7
7
|
v-model="selectedDate"
|
|
8
|
+
:allowed-dates="allowedDates"
|
|
9
|
+
:disabled-dates="disabledDates"
|
|
8
10
|
:auto-apply="true"
|
|
9
11
|
:highlight-week-days="[6]"
|
|
10
12
|
:enable-time-picker="false"
|
|
11
13
|
:month-change-on-scroll="false"
|
|
12
|
-
v-bind="options"
|
|
14
|
+
v-bind="options"
|
|
15
|
+
>
|
|
13
16
|
<template #action-buttons />
|
|
14
17
|
<template #action-preview />
|
|
15
18
|
</VDatepicker>
|
|
@@ -21,7 +24,8 @@
|
|
|
21
24
|
:id="`${hr}_${id}`"
|
|
22
25
|
:name="label"
|
|
23
26
|
:value="hr"
|
|
24
|
-
v-model="selectedHour"
|
|
27
|
+
v-model="selectedHour"
|
|
28
|
+
/>
|
|
25
29
|
<label :for="`${hr}_${id}`">{{ hr }}</label>
|
|
26
30
|
</template>
|
|
27
31
|
</div>
|
|
@@ -38,6 +42,8 @@ const props = defineProps<{
|
|
|
38
42
|
options?: Record<string, any>;
|
|
39
43
|
showTimeWrap?: boolean;
|
|
40
44
|
modelValue?: Date;
|
|
45
|
+
allowedDates?: string[] | Date[];
|
|
46
|
+
disabledDates?: string[] | Date[];
|
|
41
47
|
}>();
|
|
42
48
|
|
|
43
49
|
const emit = defineEmits(['update:modelValue']);
|
|
@@ -12,18 +12,14 @@
|
|
|
12
12
|
:class="{
|
|
13
13
|
fileDropZone: !storageFiles.length && !fileQueue.length,
|
|
14
14
|
dragover: isDragOver,
|
|
15
|
-
}"
|
|
15
|
+
}"
|
|
16
|
+
>
|
|
16
17
|
<template v-for="file in storageFiles" :key="file.id">
|
|
17
18
|
<div class="imagePreviewWrap" v-if="!multiple">
|
|
18
19
|
<img class="preview" :src="file.url" alt="" />
|
|
19
20
|
</div>
|
|
20
21
|
<div class="previewName">
|
|
21
|
-
<img
|
|
22
|
-
height="60"
|
|
23
|
-
v-if="multiple"
|
|
24
|
-
class="preview"
|
|
25
|
-
:src="file.url"
|
|
26
|
-
alt="" />
|
|
22
|
+
<img v-if="multiple" class="preview" :src="file.url" alt="" />
|
|
27
23
|
<p class="no-margin">
|
|
28
24
|
{{ file.name }}
|
|
29
25
|
</p>
|
|
@@ -32,7 +28,8 @@
|
|
|
32
28
|
@click.stop="removeFile(file)"
|
|
33
29
|
flat
|
|
34
30
|
icon="delete"
|
|
35
|
-
color="red"
|
|
31
|
+
color="red"
|
|
32
|
+
/>
|
|
36
33
|
</div>
|
|
37
34
|
</template>
|
|
38
35
|
<template v-for="fileQ in fileQueue" :key="fileQ.file">
|
|
@@ -41,11 +38,12 @@
|
|
|
41
38
|
</div>
|
|
42
39
|
<div class="previewName">
|
|
43
40
|
<img
|
|
44
|
-
|
|
41
|
+
:width="width || '220'"
|
|
45
42
|
v-if="multiple"
|
|
46
43
|
class="preview"
|
|
47
44
|
:src="fileToUrl(fileQ.file)"
|
|
48
|
-
alt=""
|
|
45
|
+
alt=""
|
|
46
|
+
/>
|
|
49
47
|
<p class="no-margin">
|
|
50
48
|
{{ fileQ.name }}
|
|
51
49
|
</p>
|
|
@@ -53,7 +51,8 @@
|
|
|
53
51
|
class="pie"
|
|
54
52
|
:style="`--p:${fileQ.progress}`"
|
|
55
53
|
style="--b: 2px"
|
|
56
|
-
:class="{ complete: fileQ.progress === 100 }"
|
|
54
|
+
:class="{ complete: fileQ.progress === 100 }"
|
|
55
|
+
>
|
|
57
56
|
<span class="progress" v-if="fileQ.progress < 100">
|
|
58
57
|
{{ `${fileQ.progress.toFixed(0)}` }}
|
|
59
58
|
</span>
|
|
@@ -66,7 +65,7 @@
|
|
|
66
65
|
</template>
|
|
67
66
|
|
|
68
67
|
<script setup lang="ts">
|
|
69
|
-
import { watch } from 'vue';
|
|
68
|
+
import { onMounted, watch } from 'vue';
|
|
70
69
|
import { Btn, type StorageFile, useBagel, MaterialIcon } from '@bagelink/vue';
|
|
71
70
|
|
|
72
71
|
const bagel = useBagel();
|
|
@@ -84,11 +83,12 @@ type StrKey = keyof StorageFile;
|
|
|
84
83
|
type FSValue = string[] | string | number;
|
|
85
84
|
|
|
86
85
|
const props = defineProps<{
|
|
87
|
-
label
|
|
86
|
+
label?: string;
|
|
88
87
|
multiple?: boolean;
|
|
89
88
|
files?: StorageFile | StorageFile[];
|
|
90
89
|
deleteEndpoint?: string;
|
|
91
90
|
bindkey?: StrKey;
|
|
91
|
+
width?: string;
|
|
92
92
|
}>();
|
|
93
93
|
|
|
94
94
|
const bindKey: StrKey = props.bindkey || 'id';
|
|
@@ -99,12 +99,36 @@ const storageFiles = $ref<StorageFile[]>([]);
|
|
|
99
99
|
const compareIds = (v1?: FSValue, v2?: FSValue) =>
|
|
100
100
|
[v1].flat().join(',') === [v2].flat().join(',');
|
|
101
101
|
|
|
102
|
+
onMounted(() => {
|
|
103
|
+
if (!props.files && [file_bindkeys.value].flat().length) {
|
|
104
|
+
const ids = [file_bindkeys.value].flat();
|
|
105
|
+
if (props.multiple) {
|
|
106
|
+
ids.forEach((id) => {
|
|
107
|
+
void bagel.get<StorageFile>(`/files/${id}`).then((file) => {
|
|
108
|
+
storageFiles.push(file);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
} else {
|
|
112
|
+
void bagel.get<StorageFile>(`/files/${ids[0]}`).then((file) => {
|
|
113
|
+
storageFiles.push(file);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
102
119
|
watch(
|
|
103
120
|
() => props.files,
|
|
104
121
|
(newFiles) => {
|
|
105
|
-
if (newFiles)
|
|
122
|
+
if (newFiles) {
|
|
123
|
+
const filesToAdd = [newFiles]
|
|
124
|
+
.flat()
|
|
125
|
+
.filter((f) => !storageFiles.find((sf) => sf[bindKey] === f[bindKey]));
|
|
126
|
+
for (const file of filesToAdd) {
|
|
127
|
+
storageFiles.push(file);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
106
130
|
},
|
|
107
|
-
{ immediate: true }
|
|
131
|
+
{ immediate: true },
|
|
108
132
|
);
|
|
109
133
|
|
|
110
134
|
watch(
|
|
@@ -119,7 +143,7 @@ watch(
|
|
|
119
143
|
file_bindkeys.value = idValue;
|
|
120
144
|
}
|
|
121
145
|
},
|
|
122
|
-
{ deep: true }
|
|
146
|
+
{ deep: true },
|
|
123
147
|
);
|
|
124
148
|
|
|
125
149
|
const fileQueue = $ref<QueueFile[]>([]);
|
|
@@ -159,7 +183,7 @@ const browse = () => {
|
|
|
159
183
|
const target = e?.target as HTMLInputElement;
|
|
160
184
|
if (target?.files) {
|
|
161
185
|
Array.from(target.files).forEach((file: File) =>
|
|
162
|
-
fileQueue.push({ name: file.name, file, progress: 0 })
|
|
186
|
+
fileQueue.push({ name: file.name, file, progress: 0 }),
|
|
163
187
|
);
|
|
164
188
|
}
|
|
165
189
|
flushQueue();
|
|
@@ -183,7 +207,7 @@ const drop = (e: DragEvent) => {
|
|
|
183
207
|
preventDefault(e);
|
|
184
208
|
if (e.dataTransfer) {
|
|
185
209
|
Array.from(e.dataTransfer.files).forEach((file: File) =>
|
|
186
|
-
fileQueue.push({ name: file.name, file, progress: 0 })
|
|
210
|
+
fileQueue.push({ name: file.name, file, progress: 0 }),
|
|
187
211
|
);
|
|
188
212
|
}
|
|
189
213
|
isDragOver = false;
|
|
@@ -193,14 +217,18 @@ const drop = (e: DragEvent) => {
|
|
|
193
217
|
|
|
194
218
|
<style scoped>
|
|
195
219
|
.bagel-input .fileUploadWrap {
|
|
220
|
+
--width: 320px;
|
|
196
221
|
outline: 1px solid var(--border-color);
|
|
197
222
|
border-radius: var(--input-border-radius);
|
|
198
223
|
text-align: center;
|
|
199
224
|
cursor: pointer;
|
|
200
225
|
transition: var(--bgl-transition);
|
|
201
226
|
position: relative;
|
|
202
|
-
height: 132px;
|
|
227
|
+
min-height: 132px;
|
|
228
|
+
max-height: 500px;
|
|
203
229
|
font-size: var(--input-font-size);
|
|
230
|
+
overflow-y: auto;
|
|
231
|
+
background: var(--input-bg);
|
|
204
232
|
}
|
|
205
233
|
|
|
206
234
|
.previewName {
|
|
@@ -208,7 +236,8 @@ const drop = (e: DragEvent) => {
|
|
|
208
236
|
text-align: start;
|
|
209
237
|
color: var(--input-color);
|
|
210
238
|
display: grid;
|
|
211
|
-
grid-template-columns: 1fr 22px;
|
|
239
|
+
grid-template-columns: auto 1fr 22px;
|
|
240
|
+
gap: 1rem;
|
|
212
241
|
align-items: center;
|
|
213
242
|
padding-inline: 14px;
|
|
214
243
|
}
|
|
@@ -222,14 +251,16 @@ const drop = (e: DragEvent) => {
|
|
|
222
251
|
.imagePreviewWrap {
|
|
223
252
|
background: var(--input-bg);
|
|
224
253
|
border-radius: var(--input-border-radius);
|
|
225
|
-
height: 90px;
|
|
226
254
|
padding: 5px;
|
|
255
|
+
min-height: 90px;
|
|
227
256
|
}
|
|
228
257
|
|
|
229
258
|
img.preview {
|
|
230
|
-
|
|
259
|
+
width: var(--width);
|
|
260
|
+
/* max-width: calc(var(--width) * 2); */
|
|
231
261
|
border-radius: var(--input-border-radius);
|
|
232
|
-
object-fit:
|
|
262
|
+
object-fit: cover;
|
|
263
|
+
background: var(--bgl-white);
|
|
233
264
|
}
|
|
234
265
|
|
|
235
266
|
.fileUploadWrap.dragover,
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
:name="id"
|
|
12
12
|
:value="getValue(option)"
|
|
13
13
|
:checked="selectedValue === getValue(option)"
|
|
14
|
-
@change="handleSelect"
|
|
14
|
+
@change="handleSelect"
|
|
15
|
+
/>
|
|
15
16
|
<label :for="`${id}-${getValue(option)}`">{{ getLabel(option) }}</label>
|
|
16
17
|
</div>
|
|
17
18
|
</div>
|
|
@@ -50,9 +51,9 @@ const props = withDefaults(
|
|
|
50
51
|
}>(),
|
|
51
52
|
{
|
|
52
53
|
modelValue: '',
|
|
53
|
-
id: () => `radio-pill-${Math.random().toString(36).
|
|
54
|
+
id: () => `radio-pill-${Math.random().toString(36).substring(2, 9)}`,
|
|
54
55
|
label: '',
|
|
55
|
-
}
|
|
56
|
+
},
|
|
56
57
|
);
|
|
57
58
|
|
|
58
59
|
let selectedValue = $ref('');
|
|
@@ -68,7 +69,7 @@ watch(
|
|
|
68
69
|
if (newVal === oldVal || oldVal === undefined) return;
|
|
69
70
|
if (selectedValue !== newVal) selectedValue = newVal;
|
|
70
71
|
},
|
|
71
|
-
{ immediate: true }
|
|
72
|
+
{ immediate: true },
|
|
72
73
|
);
|
|
73
74
|
|
|
74
75
|
onMounted(() => {
|