@bagelink/vue 0.0.25 → 0.0.35
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 +34 -9
- package/src/components/Btn.vue +221 -0
- package/src/components/Comments.vue +284 -0
- package/src/components/ContactArray.vue +142 -0
- package/src/components/ContactSubmissions.vue +45 -0
- package/src/components/DataPreview.vue +85 -0
- package/src/components/DropDown.vue +122 -0
- package/src/components/FileUploader.vue +353 -0
- package/src/components/FormKitTable.vue +299 -0
- package/src/components/FormSchema.vue +79 -0
- package/src/components/LangText.vue +32 -0
- package/src/components/ListItem.vue +20 -0
- package/src/components/ListView.vue +54 -0
- package/src/components/MaterialIcon.vue +19 -0
- package/src/components/Modal.vue +62 -0
- package/src/components/ModalForm.vue +109 -0
- package/src/components/NavBar.vue +353 -0
- package/src/components/PageTitle.vue +17 -0
- package/src/components/PersonPreview.vue +203 -0
- package/src/components/PersonPreviewFormkit.vue +205 -0
- package/src/components/RTXEditor.vue +151 -0
- package/src/components/RouterWrapper.vue +17 -0
- package/src/components/TabbedLayout.vue +83 -0
- package/src/components/TableSchema.vue +248 -0
- package/src/components/TopBar.vue +5 -0
- package/src/components/charts/BarChart.vue +316 -0
- package/src/components/dashboard/Lineart.vue +197 -0
- package/src/components/form/ItemRef.vue +45 -0
- package/src/components/form/MaterialIcon.vue +19 -0
- package/src/components/form/PlainInputField.vue +79 -0
- package/src/components/form/inputs/CheckInput.vue +143 -0
- package/src/components/form/inputs/Checkbox.vue +77 -0
- package/src/components/form/inputs/ColorPicker.vue +47 -0
- package/src/components/form/inputs/CurrencyInput.vue +137 -0
- package/src/components/form/inputs/DateInput.vue +55 -0
- package/src/components/form/inputs/DatetimeInput.vue +50 -0
- package/src/components/form/inputs/DurationInput.vue +55 -0
- package/src/components/form/inputs/DynamicLinkField.vue +142 -0
- package/src/components/form/inputs/EmailInput.vue +57 -0
- package/src/components/form/inputs/FloatInput.vue +52 -0
- package/src/components/form/inputs/IntInput.vue +53 -0
- package/src/components/form/inputs/JSONInput.vue +55 -0
- package/src/components/form/inputs/LinkField.vue +300 -0
- package/src/components/form/inputs/Password.vue +91 -0
- package/src/components/form/inputs/PasswordInput.vue +92 -0
- package/src/components/form/inputs/PlainText.vue +63 -0
- package/src/components/form/inputs/ReadOnlyInput.vue +28 -0
- package/src/components/form/inputs/RichTextEditor.vue +56 -0
- package/src/components/form/inputs/SelectField.vue +258 -0
- package/src/components/form/inputs/TableField.vue +319 -0
- package/src/components/form/inputs/TextArea.vue +79 -0
- package/src/components/form/inputs/TextInput.vue +63 -0
- package/src/components/form/inputs/index.ts +16 -0
- package/src/components/formkit/AddressArray.vue +240 -0
- package/src/components/formkit/BankDetailsArray.vue +265 -0
- package/src/components/formkit/ContactArrayFormKit.vue +192 -0
- package/src/components/formkit/FileUploader.vue +391 -0
- package/src/components/formkit/MiscFields.vue +74 -0
- package/src/components/formkit/Toggle.vue +164 -0
- package/src/components/formkit/index.ts +29 -0
- package/src/components/index.ts +20 -0
- package/src/components/whatsapp/form/MsgTemplate.vue +227 -0
- package/src/components/whatsapp/form/TextVariableExamples.vue +79 -0
- package/src/components/whatsapp/interfaces.ts +58 -0
- package/src/index.ts +1 -26
- package/src/plugins/bagel.ts +26 -0
- package/src/styles/modal.css +90 -0
- package/src/types/BagelField.ts +57 -0
- package/src/types/BtnOptions.ts +14 -0
- package/src/types/Person.ts +51 -0
- package/src/types/file.ts +12 -0
- package/src/types/index.ts +4 -0
- package/src/types/materialIcons.d.ts +3005 -0
- package/src/utils/index.ts +62 -0
- package/src/utils/modal.ts +101 -0
- package/src/utils/objects.ts +81 -0
- package/src/utils/strings.ts +36 -0
- package/dist/index.cjs +0 -23
- package/dist/index.d.cts +0 -12
- package/dist/index.d.mts +0 -12
- package/dist/index.d.ts +0 -12
- package/dist/index.mjs +0 -19
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="bar-chart">
|
|
3
|
+
<div
|
|
4
|
+
class="graph-wrap"
|
|
5
|
+
v-for="(item, i) in dataArray"
|
|
6
|
+
:key="i"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="group-wrap"
|
|
10
|
+
v-if="item.group"
|
|
11
|
+
>
|
|
12
|
+
<p class="group-title">
|
|
13
|
+
{{ item.group }}
|
|
14
|
+
</p>
|
|
15
|
+
<div
|
|
16
|
+
v-for="(nested, i) in item?.data || []"
|
|
17
|
+
:key="i"
|
|
18
|
+
class="bar-wrap"
|
|
19
|
+
>
|
|
20
|
+
<div
|
|
21
|
+
class="bar"
|
|
22
|
+
:style="{ height: loaded ? `${percent(nested.value)}%` : '0' }"
|
|
23
|
+
/>
|
|
24
|
+
<div
|
|
25
|
+
class="bar compare"
|
|
26
|
+
v-if="nested.compareValue"
|
|
27
|
+
:style="{
|
|
28
|
+
height: loaded ? `${percent(nested.compareValue)}%` : '0',
|
|
29
|
+
}"
|
|
30
|
+
/>
|
|
31
|
+
<!-- <p class="bar-txt">{{ nested.title }}</p> -->
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div
|
|
35
|
+
v-else
|
|
36
|
+
class="bar-wrap"
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
class="bar"
|
|
40
|
+
:style="{ height: loaded ? `${percent(item.value)}%` : '0' }"
|
|
41
|
+
/>
|
|
42
|
+
<div
|
|
43
|
+
class="bar compare"
|
|
44
|
+
v-if="item?.compareValue"
|
|
45
|
+
:style="{ height: loaded ? `${percent(item.compareValue)}%` : '0' }"
|
|
46
|
+
/>
|
|
47
|
+
<p class="bar-txt">
|
|
48
|
+
{{ item.title }}
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<p class="factor">
|
|
53
|
+
{{ title }}
|
|
54
|
+
</p>
|
|
55
|
+
<div class="red-bar" />
|
|
56
|
+
<div class="bar-lines">
|
|
57
|
+
<p
|
|
58
|
+
v-for="mark in marks"
|
|
59
|
+
:key="mark"
|
|
60
|
+
>
|
|
61
|
+
{{ mark.toLocaleString() }}
|
|
62
|
+
</p>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<script setup lang="ts">
|
|
68
|
+
import { ref, onMounted, computed } from 'vue';
|
|
69
|
+
|
|
70
|
+
const props = defineProps<{
|
|
71
|
+
title?: string;
|
|
72
|
+
showMarks?: boolean;
|
|
73
|
+
flood?: number;
|
|
74
|
+
modelValue: {
|
|
75
|
+
value: number;
|
|
76
|
+
title?: string;
|
|
77
|
+
compareValue?: number;
|
|
78
|
+
group?: string;
|
|
79
|
+
data?: Record<string, any>[];
|
|
80
|
+
}[];
|
|
81
|
+
// | {
|
|
82
|
+
// group: string;
|
|
83
|
+
// data: {
|
|
84
|
+
// value: number;
|
|
85
|
+
// title: string;
|
|
86
|
+
// compareValue?: number | undefined;
|
|
87
|
+
// group?: string | undefined;
|
|
88
|
+
// data?: Record<string, any>[] | undefined;
|
|
89
|
+
// }[]
|
|
90
|
+
// }[]
|
|
91
|
+
}>();
|
|
92
|
+
const loaded = ref(false);
|
|
93
|
+
|
|
94
|
+
onMounted(() => {
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
loaded.value = true;
|
|
97
|
+
}, 400);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const dataArray = computed(
|
|
101
|
+
() => props.modelValue,
|
|
102
|
+
// const allData = []
|
|
103
|
+
// for (const item of props.modelValue) {
|
|
104
|
+
// if (item.group) {
|
|
105
|
+
// let groupIndex = allData.findIndex(d => d.group === item.group)
|
|
106
|
+
// if (groupIndex > -1) allData[groupIndex].data?.push(item);
|
|
107
|
+
// else allData.push({ group: item.group, data: [item] })
|
|
108
|
+
// } else {
|
|
109
|
+
// allData.push(item)
|
|
110
|
+
// }
|
|
111
|
+
// }
|
|
112
|
+
// return allData;
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const maxValue = computed(() => Math.ceil(
|
|
116
|
+
Math.max(
|
|
117
|
+
...dataArray.value.map((d) => d.value),
|
|
118
|
+
...dataArray.value.map((d) => d?.compareValue || 0),
|
|
119
|
+
),
|
|
120
|
+
));
|
|
121
|
+
|
|
122
|
+
const marks = computed(() => {
|
|
123
|
+
const marksArray: number[] = [];
|
|
124
|
+
for (let i = 0; i <= 5; i += 1) {
|
|
125
|
+
const step = (i * maxValue.value) / 5;
|
|
126
|
+
marksArray.push(Math.round(step / 10) * 10);
|
|
127
|
+
}
|
|
128
|
+
return marksArray;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const percent = (val: number) => (val / maxValue.value) * 100;
|
|
132
|
+
const floodPercent = computed(() => `${props.flood}%`);
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<style scoped>
|
|
136
|
+
/* .group-wrap * {
|
|
137
|
+
outline: 1px solid red;
|
|
138
|
+
} */
|
|
139
|
+
|
|
140
|
+
.group-wrap {
|
|
141
|
+
height: 100%;
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
justify-content: center;
|
|
145
|
+
flex-wrap: wrap;
|
|
146
|
+
gap: 2px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.group-wrap .bar-wrap {
|
|
150
|
+
gap: 2px;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.group-title {
|
|
154
|
+
font-size: 0.6em;
|
|
155
|
+
width: 100%;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.bar-txt {
|
|
159
|
+
font-size: 11px;
|
|
160
|
+
font-weight: 200;
|
|
161
|
+
/* max-width: 95%; */
|
|
162
|
+
width: max-content;
|
|
163
|
+
height: 20px;
|
|
164
|
+
line-height: 1.2;
|
|
165
|
+
margin: 5px auto 0;
|
|
166
|
+
position: absolute;
|
|
167
|
+
transform: rotate(300deg);
|
|
168
|
+
transform-origin: 40px 40px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.graph-wrap {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: row;
|
|
174
|
+
align-items: flex-end;
|
|
175
|
+
padding: 0 10px;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.bar-wrap {
|
|
179
|
+
text-align: center;
|
|
180
|
+
height: 100%;
|
|
181
|
+
/* flex: 0 1 16.6%; */
|
|
182
|
+
display: flex;
|
|
183
|
+
flex-direction: row;
|
|
184
|
+
align-items: flex-end;
|
|
185
|
+
position: relative;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.bar {
|
|
189
|
+
background: var(--bgl-blue);
|
|
190
|
+
position: relative;
|
|
191
|
+
min-width: 10px;
|
|
192
|
+
min-height: 5px;
|
|
193
|
+
width: 4px;
|
|
194
|
+
margin: 0 auto;
|
|
195
|
+
transition: all ease-out 0.8s;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.bar.compare {
|
|
199
|
+
background-color: #cf2135;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.bar-chart {
|
|
203
|
+
height: calc(100vh - 500px);
|
|
204
|
+
width: 90%;
|
|
205
|
+
margin: 30px auto;
|
|
206
|
+
display: flex;
|
|
207
|
+
justify-content: space-between;
|
|
208
|
+
position: relative;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.graps .bar-chart {
|
|
212
|
+
aspect-ratio: 9/5;
|
|
213
|
+
height: auto;
|
|
214
|
+
max-height: calc(100vh - 500px);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.bar-lines {
|
|
218
|
+
position: absolute;
|
|
219
|
+
/* font-size: 20px; */
|
|
220
|
+
display: flex;
|
|
221
|
+
flex-direction: column-reverse;
|
|
222
|
+
top: -15px;
|
|
223
|
+
bottom: -12px;
|
|
224
|
+
left: -30px;
|
|
225
|
+
justify-content: space-between;
|
|
226
|
+
width: calc(100% + 20px);
|
|
227
|
+
text-align: start;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.bar-lines p {
|
|
231
|
+
margin: 0;
|
|
232
|
+
position: relative;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.bar-lines p::after {
|
|
236
|
+
content: "";
|
|
237
|
+
background: var(--bgl-blue-tint);
|
|
238
|
+
height: 1px;
|
|
239
|
+
position: absolute;
|
|
240
|
+
width: calc(100% - 20px);
|
|
241
|
+
margin: 14px 0 0 10px;
|
|
242
|
+
opacity: 0.5;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.bar-lines p:first-child:after {
|
|
246
|
+
content: "";
|
|
247
|
+
background: var(--bgl-blue-tint);
|
|
248
|
+
height: 1px;
|
|
249
|
+
position: absolute;
|
|
250
|
+
width: calc(100% - 10px);
|
|
251
|
+
margin: 8px 0 0 10px;
|
|
252
|
+
opacity: 0.5;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.red-bar {
|
|
256
|
+
background: #cf2135;
|
|
257
|
+
height: v-bind(floodPercent);
|
|
258
|
+
width: 100%;
|
|
259
|
+
position: absolute;
|
|
260
|
+
left: 0px;
|
|
261
|
+
bottom: 0;
|
|
262
|
+
opacity: 0.6;
|
|
263
|
+
transition: all 200ms ease;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.red-bar.open-redbar {
|
|
267
|
+
height: 7%;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.factor {
|
|
271
|
+
position: absolute;
|
|
272
|
+
transform: rotate(270deg);
|
|
273
|
+
height: 0px;
|
|
274
|
+
width: 0;
|
|
275
|
+
left: -60px;
|
|
276
|
+
font-size: 22px;
|
|
277
|
+
text-align: center;
|
|
278
|
+
white-space: nowrap;
|
|
279
|
+
top: 60%;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.dash-hor {
|
|
283
|
+
/* border-bottom: 1px dashed white; */
|
|
284
|
+
position: absolute;
|
|
285
|
+
background-image: linear-gradient(to right, #cf2134 53%, transparent 0%);
|
|
286
|
+
height: 10px;
|
|
287
|
+
bottom: 41.5%;
|
|
288
|
+
width: 100%;
|
|
289
|
+
animation: 1s linear 0s infinite dash;
|
|
290
|
+
background-position: left;
|
|
291
|
+
background-repeat: repeat-x;
|
|
292
|
+
background-size: 15px 4px;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.dash-hor::after {
|
|
296
|
+
content: "Average Speedup = 25x";
|
|
297
|
+
position: absolute;
|
|
298
|
+
left: 0;
|
|
299
|
+
bottom: 10px;
|
|
300
|
+
font-size: 22px;
|
|
301
|
+
background: #cf2134;
|
|
302
|
+
z-index: 2;
|
|
303
|
+
padding: 1px 4px;
|
|
304
|
+
border-radius: 3px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@keyframes dash {
|
|
308
|
+
0% {
|
|
309
|
+
background-position: 0;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
100% {
|
|
313
|
+
background-position: 15px;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
</style>
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="chartContainer"
|
|
4
|
+
class="chart-line"
|
|
5
|
+
>
|
|
6
|
+
<Chart
|
|
7
|
+
v-if="chartSize"
|
|
8
|
+
:size="chartSize"
|
|
9
|
+
:data="data"
|
|
10
|
+
:margin="chartMargin"
|
|
11
|
+
:axis="axisConfig"
|
|
12
|
+
>
|
|
13
|
+
<template #layers>
|
|
14
|
+
<Grid
|
|
15
|
+
:center="true"
|
|
16
|
+
strokeDasharray="2,2"
|
|
17
|
+
:hideY="true"
|
|
18
|
+
/>
|
|
19
|
+
<Area
|
|
20
|
+
aria-label="Profit/Loss"
|
|
21
|
+
:dataKeys="['date', 'total_value']"
|
|
22
|
+
type="monotone"
|
|
23
|
+
:areaStyle="{ fill: 'url(#grad)' }"
|
|
24
|
+
/>
|
|
25
|
+
<Line
|
|
26
|
+
:dataKeys="['date', 'total_value']"
|
|
27
|
+
type="monotone"
|
|
28
|
+
:dotStyle="dotStyling"
|
|
29
|
+
:lineStyle="{ stroke: BRAND_COLOR, r: 2 }"
|
|
30
|
+
/>
|
|
31
|
+
<Marker
|
|
32
|
+
v-if="displayMarker"
|
|
33
|
+
:value="meanValue"
|
|
34
|
+
label="ממוצע"
|
|
35
|
+
:color="BRAND_COLOR"
|
|
36
|
+
:strokeWidth="2"
|
|
37
|
+
strokeDasharray="6 6"
|
|
38
|
+
/>
|
|
39
|
+
<defs>
|
|
40
|
+
<linearGradient
|
|
41
|
+
id="grad"
|
|
42
|
+
gradientTransform="rotate(90)"
|
|
43
|
+
>
|
|
44
|
+
<stop
|
|
45
|
+
offset="0%"
|
|
46
|
+
:stop-color="BRAND_COLOR"
|
|
47
|
+
stop-opacity="1"
|
|
48
|
+
/>
|
|
49
|
+
<stop
|
|
50
|
+
offset="100%"
|
|
51
|
+
stop-color="white"
|
|
52
|
+
stop-opacity="0.4"
|
|
53
|
+
/>
|
|
54
|
+
</linearGradient>
|
|
55
|
+
</defs>
|
|
56
|
+
</template>
|
|
57
|
+
<template #widgets>
|
|
58
|
+
<Tooltip
|
|
59
|
+
color="white"
|
|
60
|
+
:config="tooltipConfiguration"
|
|
61
|
+
/>
|
|
62
|
+
</template>
|
|
63
|
+
</Chart>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<script lang="ts" setup>
|
|
68
|
+
import { onMounted, onUnmounted } from 'vue';
|
|
69
|
+
import {
|
|
70
|
+
Chart, Grid, Line, Area, Tooltip, Marker,
|
|
71
|
+
} from 'vue3-charts';
|
|
72
|
+
import type { ChartAxis, Data } from 'vue3-charts/dist/types';
|
|
73
|
+
|
|
74
|
+
const props = defineProps<{ data: Data[], locale: string }>();
|
|
75
|
+
|
|
76
|
+
const data = $computed(() => (props.locale === 'he' ? [...props.data].reverse() : props.data));
|
|
77
|
+
|
|
78
|
+
interface Size {
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Computed properties
|
|
84
|
+
const meanValue = $computed(() => {
|
|
85
|
+
const sum = props.data.reduce((acc, curr) => acc + +curr.total_value, 0);
|
|
86
|
+
return sum / props.data.length;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const axisConfig = $computed<ChartAxis>(() => ({
|
|
90
|
+
primary: {
|
|
91
|
+
type: 'band',
|
|
92
|
+
rotate: true,
|
|
93
|
+
ticks: 5,
|
|
94
|
+
domain: ['dataMin', 'dataMax'],
|
|
95
|
+
tickValues: props.data?.length > 100 ? [''] : props.data.map((d: any) => d.date),
|
|
96
|
+
},
|
|
97
|
+
secondary: {
|
|
98
|
+
domain: ['dataMin', 'dataMax * 1.05'],
|
|
99
|
+
type: 'linear',
|
|
100
|
+
ticks: 8,
|
|
101
|
+
},
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
// Constants
|
|
105
|
+
const BRAND_COLOR = 'var(--bgl-blue)';
|
|
106
|
+
|
|
107
|
+
const tooltipConfiguration = {
|
|
108
|
+
date: { label: 'תאריך' },
|
|
109
|
+
total_value: { color: BRAND_COLOR, label: 'סכום', format: (v: number) => `₪${v.toLocaleString()}` },
|
|
110
|
+
total_count: { label: 'מספר התרומות', format: (v: number) => `${v.toLocaleString()}` },
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// Refs
|
|
114
|
+
let chartSize = $ref<Size | null>(null);
|
|
115
|
+
const chartContainer = $ref<HTMLElement>();
|
|
116
|
+
const displayMarker = $ref(true);
|
|
117
|
+
const chartMargin = $ref({
|
|
118
|
+
left: 0,
|
|
119
|
+
top: 0,
|
|
120
|
+
right: 0,
|
|
121
|
+
bottom: 0,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Functions
|
|
125
|
+
const adjustChartSize = () => {
|
|
126
|
+
chartSize = null;
|
|
127
|
+
const el = chartContainer;
|
|
128
|
+
if (!el) return;
|
|
129
|
+
const { width, height } = el.getBoundingClientRect();
|
|
130
|
+
chartSize = { width: width - 5, height: height - 10 };
|
|
131
|
+
console.log(chartSize);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const handleResize = () => {
|
|
135
|
+
setTimeout(adjustChartSize, 300);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Lifecycle hooks
|
|
139
|
+
onMounted(() => {
|
|
140
|
+
adjustChartSize();
|
|
141
|
+
window.addEventListener('resize', handleResize);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
onUnmounted(() => {
|
|
145
|
+
window.removeEventListener('resize', handleResize);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Style Configurations
|
|
149
|
+
const dotStyling = (ctx: Record<string, any>) => ({
|
|
150
|
+
r: ctx.active ? 5 : 1,
|
|
151
|
+
fill: BRAND_COLOR,
|
|
152
|
+
});
|
|
153
|
+
</script>
|
|
154
|
+
|
|
155
|
+
<style>
|
|
156
|
+
.chart-line {
|
|
157
|
+
width: 100%;
|
|
158
|
+
height: 300px;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
[dir='rtl'] .chart-line {
|
|
162
|
+
direction: ltr;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.chart-line .v-tooltip-content>div {
|
|
166
|
+
border: none !important;
|
|
167
|
+
border-radius: 6px !important;
|
|
168
|
+
background-color: black !important;
|
|
169
|
+
opacity: 0.7;
|
|
170
|
+
padding: 0.5rem 1rem !important;
|
|
171
|
+
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06) !important;
|
|
172
|
+
font-weight: 300;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.chart-line .v-tooltip-content>div b {
|
|
176
|
+
font-weight: 400;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.layer-grid g:last-child {
|
|
180
|
+
display: none;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.layer-axis-x .tick:nth-child(2n + 1) {
|
|
184
|
+
opacity: 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@media screen and (max-width: 910px) {
|
|
188
|
+
.chart-line {
|
|
189
|
+
height: 140px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.layer-axis-x .tick {
|
|
193
|
+
opacity: 0;
|
|
194
|
+
font-size: 0;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
{{ field.label || field.id }}
|
|
4
|
+
|
|
5
|
+
<Btn
|
|
6
|
+
color="gray"
|
|
7
|
+
@click="openModal()"
|
|
8
|
+
v-if="field.refCollection"
|
|
9
|
+
>
|
|
10
|
+
{{ content }}
|
|
11
|
+
<MaterialIcon icon="arrow_forward" />
|
|
12
|
+
</Btn>
|
|
13
|
+
<span
|
|
14
|
+
v-else
|
|
15
|
+
class="pill"
|
|
16
|
+
>
|
|
17
|
+
{{ content }}
|
|
18
|
+
</span>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script lang="ts" setup>
|
|
23
|
+
import { ref, computed } from 'vue';
|
|
24
|
+
import { useRouter } from 'vue-router';
|
|
25
|
+
import type { BagelField } from '@/types';
|
|
26
|
+
import { Btn, MaterialIcon } from '@/components';
|
|
27
|
+
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
// import Modal from '@/components/Modal.vue';
|
|
30
|
+
|
|
31
|
+
const openRef = ref(false);
|
|
32
|
+
|
|
33
|
+
const props = defineProps<{
|
|
34
|
+
modelValue: Record<string, any>;
|
|
35
|
+
field: BagelField;
|
|
36
|
+
}>();
|
|
37
|
+
|
|
38
|
+
const content = computed(() => props.field.refFields?.map((k) => props.modelValue?.[k] || '').join(' '));
|
|
39
|
+
|
|
40
|
+
const openModal = () => {
|
|
41
|
+
console.log(`openning ${props.modelValue?.id}`);
|
|
42
|
+
openRef.value = true;
|
|
43
|
+
void router.push(`/${props.field.refCollection}/${props.modelValue?.id}`);
|
|
44
|
+
};
|
|
45
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="icon-font"
|
|
4
|
+
:style="{ fontSize: `${size}rem` }"
|
|
5
|
+
>
|
|
6
|
+
{{ icon }}
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
import { MaterialIcons } from '@/types/materialIcons';
|
|
12
|
+
|
|
13
|
+
defineProps<{
|
|
14
|
+
icon: MaterialIcons
|
|
15
|
+
size?: number
|
|
16
|
+
}>();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<style scoped></style>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="bagel-input">
|
|
3
|
+
<label :for="formatString(name, 'pascal')">
|
|
4
|
+
<LangText :input="formatString(name, 'titleCase')" />
|
|
5
|
+
</label>
|
|
6
|
+
<input
|
|
7
|
+
v-if="type === 'checkbox'"
|
|
8
|
+
ref="el"
|
|
9
|
+
:checked="modelValue"
|
|
10
|
+
class="ctl"
|
|
11
|
+
type="checkbox"
|
|
12
|
+
@change="handleCheck"
|
|
13
|
+
>
|
|
14
|
+
<input
|
|
15
|
+
v-else-if="type === 'number'"
|
|
16
|
+
ref="el"
|
|
17
|
+
:name="formatString(name, 'pascal')"
|
|
18
|
+
:type="type"
|
|
19
|
+
:value="modelValue"
|
|
20
|
+
class="ctl"
|
|
21
|
+
@input="handleInput"
|
|
22
|
+
>
|
|
23
|
+
<input
|
|
24
|
+
v-else-if="type === 'text'"
|
|
25
|
+
ref="el"
|
|
26
|
+
:name="formatString(name, 'pascal')"
|
|
27
|
+
:type="type"
|
|
28
|
+
:value="modelValue"
|
|
29
|
+
class="ctl"
|
|
30
|
+
@input="handleInput"
|
|
31
|
+
>
|
|
32
|
+
<textarea
|
|
33
|
+
v-else-if="type === 'textarea'"
|
|
34
|
+
ref="el"
|
|
35
|
+
:name="formatString(name, 'pascal')"
|
|
36
|
+
:type="type"
|
|
37
|
+
:value="modelValue"
|
|
38
|
+
class="ctl"
|
|
39
|
+
@input="handleInput"
|
|
40
|
+
/>
|
|
41
|
+
<div>
|
|
42
|
+
<LangText :input="errorMessage" />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<script lang="ts" setup>
|
|
48
|
+
import { onMounted, ref } from 'vue';
|
|
49
|
+
|
|
50
|
+
import LangText from '../translation/LangText.vue';
|
|
51
|
+
import { formatString } from '@/utils/strings';
|
|
52
|
+
|
|
53
|
+
const props = defineProps<{
|
|
54
|
+
type: 'text' | 'number' | 'password' | 'email' | 'checkbox' | 'textarea';
|
|
55
|
+
name: string;
|
|
56
|
+
value?: any;
|
|
57
|
+
modelValue: any;
|
|
58
|
+
errorMessage?: string;
|
|
59
|
+
focus?: boolean;
|
|
60
|
+
}>();
|
|
61
|
+
|
|
62
|
+
const emits = defineEmits(['update:modelValue']);
|
|
63
|
+
const el = ref<HTMLInputElement | null>(null);
|
|
64
|
+
const handleInput = (e: Event) => {
|
|
65
|
+
const el = e.target as HTMLInputElement;
|
|
66
|
+
emits('update:modelValue', el.value);
|
|
67
|
+
};
|
|
68
|
+
const handleCheck = (e: Event) => {
|
|
69
|
+
const el = e.target as HTMLInputElement;
|
|
70
|
+
emits('update:modelValue', el.checked ? 1 : 0);
|
|
71
|
+
};
|
|
72
|
+
onMounted(() => {
|
|
73
|
+
if (props.focus) {
|
|
74
|
+
el.value?.focus();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<style scoped></style>
|