@bagelink/vue 0.0.170 → 0.0.182
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/DataPreview.vue.d.ts.map +1 -1
- package/dist/components/DropDown.vue.d.ts.map +1 -1
- package/dist/components/TableSchema.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/Checkbox.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts +15 -8
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/components/formkit/FileUploader.vue.d.ts +5 -0
- package/dist/components/formkit/FileUploader.vue.d.ts.map +1 -1
- package/dist/index.cjs +133 -64
- package/dist/index.mjs +133 -64
- package/dist/style.css +64 -37
- package/package.json +1 -1
- package/src/components/DataPreview.vue +33 -15
- package/src/components/DropDown.vue +35 -33
- package/src/components/TableSchema.vue +82 -84
- package/src/components/form/inputs/Checkbox.vue +21 -18
- package/src/components/form/inputs/TextInput.vue +70 -8
- package/src/components/formkit/FileUploader.vue +7 -4
package/dist/style.css
CHANGED
|
@@ -534,12 +534,12 @@
|
|
|
534
534
|
.dropdown {
|
|
535
535
|
position: relative;
|
|
536
536
|
font-size: calc(var(--input-font-size) * 1.3);
|
|
537
|
-
width: 50px;
|
|
538
|
-
|
|
539
|
-
z-index: 1;
|
|
537
|
+
/* width: 50px; */
|
|
538
|
+
z-index: 9;
|
|
540
539
|
}
|
|
541
540
|
.dropdown-title {
|
|
542
541
|
white-space: nowrap;
|
|
542
|
+
color: var(--bgl-primary);
|
|
543
543
|
border-radius: var(--input-border-radius);
|
|
544
544
|
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 10%);
|
|
545
545
|
padding-left: calc(var(--btn-padding) / 2);
|
|
@@ -574,7 +574,8 @@
|
|
|
574
574
|
inset-inline-start: 0;
|
|
575
575
|
inset-inline-end: 0;
|
|
576
576
|
overflow: auto;
|
|
577
|
-
box-shadow: 0
|
|
577
|
+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.20);
|
|
578
|
+
z-index: 99999999;
|
|
578
579
|
}
|
|
579
580
|
.dropdown-body * {
|
|
580
581
|
display: block;
|
|
@@ -582,12 +583,11 @@
|
|
|
582
583
|
padding: calc(var(--btn-padding) / 2);
|
|
583
584
|
padding-bottom: calc(var(--btn-padding) / 4);
|
|
584
585
|
padding-top: calc(var(--btn-padding) / 4);
|
|
586
|
+
margin: 0;
|
|
585
587
|
color: inherit;
|
|
586
588
|
text-decoration: none;
|
|
587
589
|
line-height: 1;
|
|
588
590
|
transition: var(--bgl-transition);
|
|
589
|
-
box-shadow: 0 -1px 0 0 rgb(0 0 0, 10%);
|
|
590
|
-
z-index: 99999999;
|
|
591
591
|
}
|
|
592
592
|
.dropdown-body *:hover {
|
|
593
593
|
filter: var(--bgl-hover-filter);
|
|
@@ -753,37 +753,37 @@
|
|
|
753
753
|
transform: translateY(-2.6rem);
|
|
754
754
|
}
|
|
755
755
|
|
|
756
|
-
.list-arrows[data-v-
|
|
756
|
+
.list-arrows[data-v-8cd8ab82] {
|
|
757
757
|
opacity: 0;
|
|
758
758
|
}
|
|
759
|
-
.list-arrows .icon-font[data-v-
|
|
759
|
+
.list-arrows .icon-font[data-v-8cd8ab82] {
|
|
760
760
|
transition: all ease-in-out 0.2s;
|
|
761
761
|
}
|
|
762
|
-
.list-arrows.sorted[data-v-
|
|
762
|
+
.list-arrows.sorted[data-v-8cd8ab82] {
|
|
763
763
|
opacity: 1;
|
|
764
764
|
}
|
|
765
|
-
.col img[data-v-
|
|
765
|
+
.col img[data-v-8cd8ab82] {
|
|
766
766
|
height: 35px;
|
|
767
767
|
margin-top: -14px;
|
|
768
768
|
margin-bottom: -14px;
|
|
769
769
|
border-radius: 5px;
|
|
770
770
|
}
|
|
771
|
-
.list-arrows.sorted .desc[data-v-
|
|
771
|
+
.list-arrows.sorted .desc[data-v-8cd8ab82] {
|
|
772
772
|
transform: rotate(180deg);
|
|
773
773
|
}
|
|
774
|
-
table[data-v-
|
|
774
|
+
table[data-v-8cd8ab82] {
|
|
775
775
|
border-collapse: separate;
|
|
776
776
|
border-spacing: 0 15px;
|
|
777
777
|
border-collapse: collapse;
|
|
778
778
|
}
|
|
779
|
-
th[data-v-
|
|
779
|
+
th[data-v-8cd8ab82] {
|
|
780
780
|
font-weight: 400;
|
|
781
781
|
}
|
|
782
|
-
.row[data-v-
|
|
782
|
+
.row[data-v-8cd8ab82] {
|
|
783
783
|
border-bottom: 1px solid var(--border-color);
|
|
784
784
|
cursor: pointer;
|
|
785
785
|
}
|
|
786
|
-
.row.first-row[data-v-
|
|
786
|
+
.row.first-row[data-v-8cd8ab82] {
|
|
787
787
|
font-size: 0.8rem;
|
|
788
788
|
color: var(--bgl-black-tint);
|
|
789
789
|
position: sticky;
|
|
@@ -793,7 +793,7 @@ th[data-v-fb5b163a] {
|
|
|
793
793
|
height: 50px;
|
|
794
794
|
vertical-align: bottom;
|
|
795
795
|
}
|
|
796
|
-
.row.first-row[data-v-
|
|
796
|
+
.row.first-row[data-v-8cd8ab82]::after {
|
|
797
797
|
content: "";
|
|
798
798
|
border-bottom: 1px solid var(--border-color);
|
|
799
799
|
position: absolute;
|
|
@@ -801,11 +801,11 @@ th[data-v-fb5b163a] {
|
|
|
801
801
|
right: 0;
|
|
802
802
|
bottom: -1px;
|
|
803
803
|
}
|
|
804
|
-
.first-row .col[data-v-
|
|
804
|
+
.first-row .col[data-v-8cd8ab82] {
|
|
805
805
|
cursor: pointer;
|
|
806
806
|
background: var(--bgl-white);
|
|
807
807
|
}
|
|
808
|
-
.col[data-v-
|
|
808
|
+
.col[data-v-8cd8ab82] {
|
|
809
809
|
white-space: nowrap;
|
|
810
810
|
padding: 14px;
|
|
811
811
|
transition: var(--bgl-transition);
|
|
@@ -814,16 +814,16 @@ th[data-v-fb5b163a] {
|
|
|
814
814
|
padding-right: 1rem;
|
|
815
815
|
align-items: center;
|
|
816
816
|
}
|
|
817
|
-
.col > div[data-v-
|
|
817
|
+
.col > div[data-v-8cd8ab82] {
|
|
818
818
|
display: flex;
|
|
819
819
|
gap: 0.5rem;
|
|
820
820
|
}
|
|
821
|
-
.max-col-width[data-v-
|
|
821
|
+
.max-col-width[data-v-8cd8ab82] {
|
|
822
822
|
max-width: 30vw;
|
|
823
823
|
overflow: hidden;
|
|
824
824
|
text-overflow: ellipsis;
|
|
825
825
|
}
|
|
826
|
-
.col.check .icon-font[data-v-
|
|
826
|
+
.col.check .icon-font[data-v-8cd8ab82] {
|
|
827
827
|
border-radius: 100%;
|
|
828
828
|
background: var(--bgl-blue-20);
|
|
829
829
|
color: var(--bgl-primary);
|
|
@@ -834,27 +834,27 @@ th[data-v-fb5b163a] {
|
|
|
834
834
|
justify-content: center;
|
|
835
835
|
margin-top: -2px;
|
|
836
836
|
}
|
|
837
|
-
.rows[data-v-
|
|
837
|
+
.rows[data-v-8cd8ab82] {
|
|
838
838
|
font-size: 0.8125em;
|
|
839
839
|
}
|
|
840
|
-
.table-list[data-v-
|
|
840
|
+
.table-list[data-v-8cd8ab82] {
|
|
841
841
|
height: 100%;
|
|
842
842
|
position: relative;
|
|
843
843
|
padding-left: 0 !important;
|
|
844
844
|
padding-right: 0 !important;
|
|
845
845
|
overflow: auto;
|
|
846
846
|
}
|
|
847
|
-
.BagelTable .table-list[data-v-
|
|
847
|
+
.BagelTable .table-list[data-v-8cd8ab82] {
|
|
848
848
|
overflow: unset;
|
|
849
849
|
}
|
|
850
|
-
.row-item[data-v-
|
|
850
|
+
.row-item[data-v-8cd8ab82] {
|
|
851
851
|
height: 50px;
|
|
852
852
|
transition: all 200ms ease;
|
|
853
853
|
}
|
|
854
|
-
.row-item[data-v-
|
|
854
|
+
.row-item[data-v-8cd8ab82]:hover {
|
|
855
855
|
background: var(--bgl-gray-light);
|
|
856
856
|
}
|
|
857
|
-
.infinite-wrapper[data-v-
|
|
857
|
+
.infinite-wrapper[data-v-8cd8ab82] {
|
|
858
858
|
overflow-y: auto;
|
|
859
859
|
width: 100%;
|
|
860
860
|
}
|
|
@@ -938,20 +938,19 @@ th[data-v-fb5b163a] {
|
|
|
938
938
|
}
|
|
939
939
|
}
|
|
940
940
|
|
|
941
|
-
.data[data-v-
|
|
941
|
+
.data[data-v-dc2757c4] {
|
|
942
942
|
border: 1.1px solid var(--border-color);
|
|
943
943
|
padding: 20px;
|
|
944
944
|
border-radius: var(--input-border-radius);
|
|
945
945
|
}
|
|
946
|
-
.data-row[data-v-
|
|
946
|
+
.data-row[data-v-dc2757c4] {
|
|
947
947
|
display: flex;
|
|
948
948
|
justify-content: space-between;
|
|
949
949
|
padding-bottom: 0.5rem;
|
|
950
950
|
margin-bottom: 0.5rem;
|
|
951
|
-
opacity: 0.8;
|
|
952
951
|
border-bottom: 1px solid var(--border-color);
|
|
953
952
|
}
|
|
954
|
-
.data-link[data-v-
|
|
953
|
+
.data-link[data-v-dc2757c4] {
|
|
955
954
|
display: block;
|
|
956
955
|
font-size: var(--input-font-size);
|
|
957
956
|
margin-bottom: 2px;
|
|
@@ -1119,13 +1118,13 @@ th[data-v-fb5b163a] {
|
|
|
1119
1118
|
}
|
|
1120
1119
|
}
|
|
1121
1120
|
|
|
1122
|
-
.primary-checkbox input[data-v-
|
|
1121
|
+
.primary-checkbox input[data-v-6b168ea9] {
|
|
1123
1122
|
display: none;
|
|
1124
1123
|
}
|
|
1125
|
-
.primary-checkbox[data-v-
|
|
1124
|
+
.primary-checkbox[data-v-6b168ea9] {
|
|
1126
1125
|
margin-top: 8px;
|
|
1127
1126
|
}
|
|
1128
|
-
.primary-checkbox span[data-v-
|
|
1127
|
+
.primary-checkbox span[data-v-6b168ea9] {
|
|
1129
1128
|
display: flex;
|
|
1130
1129
|
padding-top: 1px;
|
|
1131
1130
|
align-items: center;
|
|
@@ -1140,13 +1139,13 @@ th[data-v-fb5b163a] {
|
|
|
1140
1139
|
transition: var(--bgl-transition);
|
|
1141
1140
|
user-select: none;
|
|
1142
1141
|
}
|
|
1143
|
-
.primary-checkbox span[data-v-
|
|
1142
|
+
.primary-checkbox span[data-v-6b168ea9]:hover {
|
|
1144
1143
|
filter: brightness(90%);
|
|
1145
1144
|
}
|
|
1146
|
-
.primary-checkbox span[data-v-
|
|
1145
|
+
.primary-checkbox span[data-v-6b168ea9]:active {
|
|
1147
1146
|
filter: brightness(80%);
|
|
1148
1147
|
}
|
|
1149
|
-
.primary-checkbox input:checked + span[data-v-
|
|
1148
|
+
.primary-checkbox input:checked + span[data-v-6b168ea9] {
|
|
1150
1149
|
background: var(--bgl-primary);
|
|
1151
1150
|
border: none;
|
|
1152
1151
|
}
|
|
@@ -2182,6 +2181,34 @@ input[type='email'][data-v-ed81a514] {
|
|
|
2182
2181
|
box-shadow: 0 0 10px 0 rgb(0 0 0 /20%);
|
|
2183
2182
|
}
|
|
2184
2183
|
|
|
2184
|
+
.bagel-input.shrink, .bagel-input.shrink input{
|
|
2185
|
+
min-width: unset !important;
|
|
2186
|
+
/* width: auto; */
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
.bagel-input input[disabled][data-v-7b082166]{
|
|
2190
|
+
background: none;
|
|
2191
|
+
}
|
|
2192
|
+
.bagel-input.toggleEdit[data-v-7b082166]:hover {
|
|
2193
|
+
background-color: var(--input-bg);
|
|
2194
|
+
}
|
|
2195
|
+
.bagel-input.small[data-v-7b082166]{
|
|
2196
|
+
margin-bottom:0;
|
|
2197
|
+
height: 30px;
|
|
2198
|
+
}
|
|
2199
|
+
.toggleEditBtn[data-v-7b082166]{
|
|
2200
|
+
position: absolute;
|
|
2201
|
+
right: -24px;
|
|
2202
|
+
top: 4;
|
|
2203
|
+
opacity: 0;
|
|
2204
|
+
}
|
|
2205
|
+
.bagel-input:hover .toggleEditBtn[data-v-7b082166], .bagel-input.editMode .toggleEditBtn[data-v-7b082166]{
|
|
2206
|
+
opacity: 1;
|
|
2207
|
+
}
|
|
2208
|
+
.bagel-input.small input[data-v-7b082166]{
|
|
2209
|
+
height: 30px;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2185
2212
|
.bagel-input[data-v-a5b28c58] {
|
|
2186
2213
|
height: 100%;
|
|
2187
2214
|
margin: 0;
|
package/package.json
CHANGED
|
@@ -9,25 +9,34 @@
|
|
|
9
9
|
>
|
|
10
10
|
{{ title }}
|
|
11
11
|
</h3>
|
|
12
|
-
<
|
|
12
|
+
<template
|
|
13
13
|
v-for="field in schema || []"
|
|
14
14
|
:key="field.id"
|
|
15
|
-
class="data-row"
|
|
16
15
|
>
|
|
17
|
-
<div
|
|
18
|
-
|
|
16
|
+
<div class="data-row" v-if="field['v-if'] ? field['v-if'](itemData[field.id], itemData) : true">
|
|
17
|
+
<div class="key">
|
|
18
|
+
{{ field?.label || keyToLabel(field.id) }}
|
|
19
|
+
</div>
|
|
20
|
+
<component
|
|
21
|
+
:is="field.$el || 'div'"
|
|
22
|
+
class="vlue"
|
|
23
|
+
v-model="itemData[field.id]"
|
|
24
|
+
@update:modelValue="($event:any)=>field?.onUpdate?.($event, data[field.id], itemData)"
|
|
25
|
+
v-bind="bindAttrs(field.attrs, itemData[field.id], itemData)"
|
|
26
|
+
>
|
|
27
|
+
{{
|
|
28
|
+
field?.transform?.(itemData[field.id]
|
|
29
|
+
|| field.defaultValue, itemData)
|
|
30
|
+
|| itemData[field.id]
|
|
31
|
+
|| ''
|
|
32
|
+
}}
|
|
33
|
+
</component>
|
|
19
34
|
</div>
|
|
20
|
-
|
|
21
|
-
:is="field.$el || 'div'"
|
|
22
|
-
class="vlue"
|
|
23
|
-
>
|
|
24
|
-
{{ data[field.id] || field.defaultValue }}
|
|
25
|
-
</component>
|
|
26
|
-
</div>
|
|
35
|
+
</template>
|
|
27
36
|
<div v-if="!schema?.length">
|
|
28
37
|
<div
|
|
29
38
|
class="data-row"
|
|
30
|
-
v-for="[key, value] in Object.entries(
|
|
39
|
+
v-for="[key, value] in Object.entries(itemData).filter(
|
|
31
40
|
([key]) => !keysToIgnore.includes(key),
|
|
32
41
|
)"
|
|
33
42
|
:key="key"
|
|
@@ -51,12 +60,22 @@ const i18nT = useI18nT();
|
|
|
51
60
|
|
|
52
61
|
const keysToIgnore = ['id', 'person_id', 'person', 'created_at', 'updated_at'];
|
|
53
62
|
|
|
54
|
-
|
|
55
|
-
defineProps<{
|
|
63
|
+
const props = defineProps<{
|
|
56
64
|
data: Record<string, any>,
|
|
57
65
|
schema?: Record<string, any>[],
|
|
58
66
|
title?: string,
|
|
59
67
|
}>();
|
|
68
|
+
|
|
69
|
+
const itemData = $ref<Record<string, any>>(props.data);
|
|
70
|
+
|
|
71
|
+
const bindAttrs = (attrs: Record<string, any>, field: any, row: any) => {
|
|
72
|
+
const arr = Object.entries(attrs || {}).map(([key, value]) => [
|
|
73
|
+
key,
|
|
74
|
+
typeof value === 'function' ? value(field, row) : value,
|
|
75
|
+
]);
|
|
76
|
+
const resolvedAttrs = Object.fromEntries(arr);
|
|
77
|
+
return resolvedAttrs;
|
|
78
|
+
};
|
|
60
79
|
</script>
|
|
61
80
|
|
|
62
81
|
<style scoped>
|
|
@@ -71,7 +90,6 @@ defineProps<{
|
|
|
71
90
|
justify-content: space-between;
|
|
72
91
|
padding-bottom: 0.5rem;
|
|
73
92
|
margin-bottom: 0.5rem;
|
|
74
|
-
opacity: 0.8;
|
|
75
93
|
border-bottom: 1px solid var(--border-color);
|
|
76
94
|
}
|
|
77
95
|
|
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
<div class="dropdown" @click="toggleDropdown" :class="{ opendrop: isOpen }">
|
|
3
|
+
<div class="dropdown-title">
|
|
4
|
+
{{ selectedOption || placeholder }}
|
|
5
|
+
<MaterialIcon icon="keyboard_arrow_down" />
|
|
6
|
+
</div>
|
|
7
|
+
<div
|
|
8
|
+
class="dropdown-body"
|
|
9
|
+
>
|
|
10
|
+
<p
|
|
11
|
+
v-for="(option, index) in options"
|
|
12
|
+
:key="index"
|
|
13
|
+
@click.stop="selectOption(option as string, index as number)"
|
|
14
|
+
>
|
|
15
|
+
{{ option }}
|
|
16
|
+
</p>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
17
19
|
</template>
|
|
18
20
|
|
|
19
21
|
<script setup lang="ts">
|
|
20
|
-
import {
|
|
21
|
-
import { MaterialIcon } from "@bagelink/vue";
|
|
22
|
+
import { MaterialIcon } from '@bagelink/vue';
|
|
22
23
|
|
|
23
24
|
const props = defineProps({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
modelValue: String,
|
|
26
|
+
options: Array,
|
|
27
|
+
placeholder: String,
|
|
27
28
|
});
|
|
28
|
-
const emit = defineEmits([
|
|
29
|
+
const emit = defineEmits(['update:modelValue']);
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
let isOpen = $ref(false);
|
|
32
|
+
let selectedOption = $ref(props.modelValue);
|
|
32
33
|
|
|
33
34
|
function toggleDropdown() {
|
|
34
|
-
|
|
35
|
+
isOpen = !isOpen;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
function selectOption(option: string, index: number) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
selectedOption = option;
|
|
40
|
+
isOpen = false;
|
|
41
|
+
emit('update:modelValue', { option, index }); // Emit the selected option value with v-model
|
|
41
42
|
}
|
|
42
43
|
</script>
|
|
43
44
|
|
|
@@ -45,13 +46,14 @@ function selectOption(option: string, index: number) {
|
|
|
45
46
|
.dropdown {
|
|
46
47
|
position: relative;
|
|
47
48
|
font-size: calc(var(--input-font-size) * 1.3);
|
|
48
|
-
width: 50px;
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/* width: 50px; */
|
|
50
|
+
z-index: 9;
|
|
51
|
+
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
.dropdown-title {
|
|
54
55
|
white-space: nowrap;
|
|
56
|
+
color: var(--bgl-primary);
|
|
55
57
|
border-radius: var(--input-border-radius);
|
|
56
58
|
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 10%);
|
|
57
59
|
padding-left: calc(var(--btn-padding) / 2);
|
|
@@ -90,7 +92,8 @@ function selectOption(option: string, index: number) {
|
|
|
90
92
|
inset-inline-start: 0;
|
|
91
93
|
inset-inline-end: 0;
|
|
92
94
|
overflow: auto;
|
|
93
|
-
box-shadow: 0
|
|
95
|
+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.20);
|
|
96
|
+
z-index: 99999999;
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
.dropdown-body * {
|
|
@@ -99,12 +102,11 @@ function selectOption(option: string, index: number) {
|
|
|
99
102
|
padding: calc(var(--btn-padding) / 2);
|
|
100
103
|
padding-bottom: calc(var(--btn-padding) / 4);
|
|
101
104
|
padding-top: calc(var(--btn-padding) / 4);
|
|
105
|
+
margin: 0;
|
|
102
106
|
color: inherit;
|
|
103
107
|
text-decoration: none;
|
|
104
108
|
line-height: 1;
|
|
105
109
|
transition: var(--bgl-transition);
|
|
106
|
-
box-shadow: 0 -1px 0 0 rgb(0 0 0, 10%);
|
|
107
|
-
z-index: 99999999;
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
.dropdown-body *:hover {
|
|
@@ -1,68 +1,70 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
2
|
+
<div class="table-list-wrap h-100">
|
|
3
|
+
<table class="infinite-wrapper">
|
|
4
|
+
<thead class="row first-row">
|
|
5
|
+
<th
|
|
6
|
+
class="col"
|
|
7
|
+
v-for="field in columns"
|
|
8
|
+
:key="field.id"
|
|
9
|
+
@click="sort(field.id)"
|
|
10
|
+
>
|
|
11
|
+
<div class="flex">
|
|
12
|
+
{{ field?.label || field?.id }}
|
|
13
|
+
<div
|
|
14
|
+
class="list-arrows"
|
|
15
|
+
:class="{ sorted: sortField === field.id }"
|
|
16
|
+
>
|
|
17
|
+
<MaterialIcon
|
|
18
|
+
:class="{ desc: sortDirection === 'DESC' }"
|
|
19
|
+
icon="keyboard_arrow_up"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</th>
|
|
24
|
+
</thead>
|
|
25
|
+
<tbody ref="infinite" class="rows infinite" :class="{ loading }">
|
|
26
|
+
<tr
|
|
27
|
+
@click="selectElement(row)"
|
|
28
|
+
class="row row-item position-relative"
|
|
29
|
+
v-for="row in data"
|
|
30
|
+
:key="row.id"
|
|
31
|
+
>
|
|
32
|
+
<td
|
|
33
|
+
class="col"
|
|
34
|
+
v-for="field in columns"
|
|
35
|
+
:key="`${field.id}-${row.id}`"
|
|
36
|
+
>
|
|
37
|
+
<slot
|
|
38
|
+
v-if="slots[field.id]"
|
|
39
|
+
:name="field.id"
|
|
40
|
+
:row="row"
|
|
41
|
+
:field="field"
|
|
42
|
+
/>
|
|
43
|
+
<div v-else>
|
|
44
|
+
<component
|
|
45
|
+
:is="field.$el || field.$cmp || 'div'"
|
|
46
|
+
v-if="field['v-if'] ? field['v-if'](row[field.id], row) : true"
|
|
47
|
+
v-bind="bindAttrs(field.attrs, row[field.id], row)"
|
|
48
|
+
:src="field.$el === 'img' ? row[field.id]?.url : ''"
|
|
49
|
+
@update:modelValue="($event:any)=>field?.onUpdate?.($event, row[field.id], row)"
|
|
50
|
+
:modelValue="row[field.id]"
|
|
51
|
+
>
|
|
52
|
+
{{
|
|
53
|
+
field?.transform?.(row[field.id], row) || row[field.id] || ""
|
|
54
|
+
}}
|
|
55
|
+
</component>
|
|
56
|
+
</div>
|
|
57
|
+
</td>
|
|
58
|
+
</tr>
|
|
59
|
+
</tbody>
|
|
60
|
+
</table>
|
|
61
|
+
<!-- </Transition> -->
|
|
62
|
+
</div>
|
|
61
63
|
</template>
|
|
62
64
|
|
|
63
65
|
<script setup lang="ts">
|
|
64
|
-
import { useSlots } from
|
|
65
|
-
import { MaterialIcon } from
|
|
66
|
+
import { useSlots } from 'vue';
|
|
67
|
+
import { MaterialIcon } from '@bagelink/vue';
|
|
66
68
|
|
|
67
69
|
const slots = useSlots();
|
|
68
70
|
const loading = $ref(true);
|
|
@@ -72,42 +74,38 @@ const props = defineProps<{
|
|
|
72
74
|
schema?: () => any[];
|
|
73
75
|
}>();
|
|
74
76
|
|
|
75
|
-
const emit = defineEmits([
|
|
77
|
+
const emit = defineEmits(['select']);
|
|
76
78
|
|
|
77
79
|
const selectElement = (data: Record<string, any>) => {
|
|
78
|
-
|
|
80
|
+
emit('select', data);
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
const bindAttrs = (attrs: Record<string, any>, field: any, row: any) => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
const arr = Object.entries(attrs || {}).map(([key, value]) => [
|
|
85
|
+
key,
|
|
86
|
+
typeof value === 'function' ? value(field, row) : value,
|
|
87
|
+
]);
|
|
88
|
+
const resolvedAttrs = Object.fromEntries(arr);
|
|
89
|
+
return resolvedAttrs;
|
|
88
90
|
};
|
|
89
91
|
|
|
90
92
|
// const sortList = () => {};
|
|
91
|
-
let sortDirection = $ref(
|
|
92
|
-
let sortField = $ref(
|
|
93
|
+
let sortDirection = $ref('');
|
|
94
|
+
let sortField = $ref('');
|
|
93
95
|
|
|
94
96
|
const sort = (fieldname: string) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
if (sortField === fieldname) {
|
|
98
|
+
if (sortDirection === 'ASC') sortDirection = 'DESC';
|
|
99
|
+
else sortField = '';
|
|
100
|
+
} else {
|
|
101
|
+
sortField = fieldname;
|
|
102
|
+
sortDirection = 'ASC';
|
|
103
|
+
}
|
|
102
104
|
};
|
|
103
105
|
|
|
104
106
|
const columns = $computed(
|
|
105
|
-
|
|
106
|
-
props.
|
|
107
|
-
Object.keys(props.data[0]).map((k: string) => ({
|
|
108
|
-
id: k,
|
|
109
|
-
inputType: "PlainText",
|
|
110
|
-
}))
|
|
107
|
+
() => props.schema?.() ||
|
|
108
|
+
Object.keys(props.data[0]).map((k: string) => ({ id: k, inputType: 'PlainText' })),
|
|
111
109
|
);
|
|
112
110
|
</script>
|
|
113
111
|
|