@bagelink/vue 0.0.439 → 0.0.441

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 (55) hide show
  1. package/dist/components/AccordionItem.vue.d.ts.map +1 -1
  2. package/dist/components/DataPreview.vue.d.ts +6 -0
  3. package/dist/components/DataPreview.vue.d.ts.map +1 -1
  4. package/dist/components/Flag.vue.d.ts +16 -0
  5. package/dist/components/Flag.vue.d.ts.map +1 -0
  6. package/dist/components/Modal.vue.d.ts.map +1 -1
  7. package/dist/components/TableSchema.vue.d.ts +6 -5
  8. package/dist/components/TableSchema.vue.d.ts.map +1 -1
  9. package/dist/components/form/inputs/FileUpload.vue.d.ts +164 -2
  10. package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
  11. package/dist/components/form/inputs/TelInput.vue.d.ts +165 -0
  12. package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -0
  13. package/dist/components/form/inputs/TextInput.vue.d.ts +2 -5
  14. package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
  15. package/dist/components/form/inputs/index.d.ts +1 -0
  16. package/dist/components/form/inputs/index.d.ts.map +1 -1
  17. package/dist/components/index.d.ts +1 -0
  18. package/dist/components/index.d.ts.map +1 -1
  19. package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
  20. package/dist/index.cjs +6502 -1540
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.mjs +6502 -1540
  24. package/dist/style.css +1877 -93
  25. package/dist/utils/BagelFormUtils.d.ts.map +1 -1
  26. package/dist/utils/allCountries.d.ts +11 -0
  27. package/dist/utils/allCountries.d.ts.map +1 -0
  28. package/package.json +3 -4
  29. package/src/components/AccordionItem.vue +8 -5
  30. package/src/components/DataPreview.vue +14 -4
  31. package/src/components/Flag.vue +1349 -0
  32. package/src/components/Modal.vue +26 -9
  33. package/src/components/ModalForm.vue +1 -1
  34. package/src/components/PageTitle.vue +8 -1
  35. package/src/components/TableSchema.vue +34 -2
  36. package/src/components/form/inputs/FileUpload.vue +28 -11
  37. package/src/components/form/inputs/SelectInput.vue +6 -0
  38. package/src/components/form/inputs/TelInput.vue +401 -0
  39. package/src/components/form/inputs/TextInput.vue +15 -53
  40. package/src/components/form/inputs/index.ts +1 -0
  41. package/src/components/index.ts +1 -0
  42. package/src/components/layout/Tabs.vue +1 -0
  43. package/src/index.ts +1 -0
  44. package/src/styles/appearance.css +610 -0
  45. package/src/styles/buttons.css +8 -0
  46. package/src/styles/layout.css +46 -1
  47. package/src/styles/mobilLayout.css +37 -0
  48. package/src/styles/modal.css +5 -2
  49. package/src/styles/text.css +39 -0
  50. package/src/utils/BagelFormUtils.ts +2 -0
  51. package/src/utils/allCountries.ts +337 -0
  52. package/src/components/whatsapp/form/MsgTemplate.vue +0 -224
  53. package/src/components/whatsapp/form/TextVariableExamples.vue +0 -79
  54. package/src/components/whatsapp/index.ts +0 -2
  55. package/src/components/whatsapp/interfaces.ts +0 -58
@@ -1,224 +0,0 @@
1
- <template>
2
- <div class="main-content">
3
- <PageTitle>Whatsapp Template</PageTitle>
4
- <div class="view-wrapper bgl_card thin">
5
- <div class="whatsapp-wrap">
6
- <div class="create-template-form">
7
- <BagelForm :schema="whatsappTemplateSchema" v-model="localWhatsappData" @submit="upsertTemplate" />
8
- </div>
9
- <div class="whatsapp-preview" :class="{ whatsappHebrew: localWhatsappData?.language === 'he' }">
10
- {{ previewLabel }}
11
- <div class="whatsapp-msg">
12
- <b>{{
13
- localWhatsappData?.headerText?.replace(regex, replaceHeader)
14
- }}</b>
15
- <p class="whatsapp-body">
16
- {{ localWhatsappData?.bodyText?.replace(regex, replaceBody) }}
17
- </p>
18
- <p class="whatsapp-footer">
19
- {{ localWhatsappData?.footerText }}
20
- </p>
21
- </div>
22
- </div>
23
- </div>
24
- </div>
25
- </div>
26
- </template>
27
-
28
- <script setup lang="ts">
29
- import { onMounted } from 'vue';
30
-
31
- import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
32
- import {
33
- useBagel, PageTitle, BagelForm, BglFormSchemaT,
34
- } from '@bagelink/vue';
35
- import {
36
- BodyComponent,
37
- HeaderComponent,
38
- LocalTemplateData,
39
- ServerTemplateData,
40
- FooterComponent,
41
- } from '../interfaces';
42
-
43
- const props = withDefaults(
44
- defineProps<{
45
- whatsappTemplateSchema: BglFormSchemaT<LocalTemplateData>;
46
- router: Router;
47
- route: RouteLocationNormalizedLoaded;
48
- previewLabel?: string;
49
- }>(),
50
- { previewLabel: 'Preview' },
51
- );
52
-
53
- const bagel = useBagel();
54
-
55
- const regex = /\{\{(\d+)}}/g;
56
- let localWhatsappData = $ref<LocalTemplateData>();
57
-
58
- const serverToLocal = (data: ServerTemplateData): LocalTemplateData => ({
59
- id: data.id,
60
- status: data.status,
61
- name: data.name,
62
- language: data.language,
63
- headerText: data.components.find(
64
- (c): c is HeaderComponent => c.type === 'HEADER',
65
- )?.text,
66
- bodyText: data.components.find((c): c is BodyComponent => c.type === 'BODY')
67
- ?.text,
68
- bodyExamples: data.components.find(
69
- (c): c is BodyComponent => c.type === 'BODY',
70
- )?.example?.body_text[0],
71
- footerText: data.components.find(
72
- (c): c is FooterComponent => c.type === 'FOOTER',
73
- )?.text,
74
- category: data.category,
75
- });
76
-
77
- const localToServer = (data: LocalTemplateData) => {
78
- const obj: any = {};
79
- obj.language = data.language;
80
- if (data.id) obj.id = data.id;
81
- obj.name = data.name;
82
- obj.components = [];
83
- obj.category = data.category;
84
- if (data.headerText) {
85
- obj.components.push({
86
- type: 'HEADER',
87
- format: 'TEXT',
88
- text: data.headerText,
89
- });
90
- }
91
- if (data.bodyText) {
92
- const bodyComponent: BodyComponent = { type: 'BODY', text: data.bodyText };
93
- if (data.bodyExamples) { bodyComponent.example = { body_text: [data.bodyExamples] }; }
94
- obj.components.push(bodyComponent);
95
- }
96
- if (data.footerText) { obj.components.push({ type: 'FOOTER', text: data.footerText }); }
97
- return obj;
98
- };
99
-
100
- const loadTemplateData = async () => {
101
- const template_name = props.route.params.id;
102
- if (template_name) {
103
- const res = await bagel.get(
104
- `communication/whatsapp/get_template_by_name/${template_name}`,
105
- );
106
- localWhatsappData = serverToLocal(res.data[0]);
107
- }
108
- };
109
-
110
- const replaceHeader = (match: any) => {
111
- const index = +match[2];
112
- const example = localWhatsappData?.headerExamples?.[index - 1];
113
- return example || match;
114
- };
115
-
116
- const replaceBody = (match: any) => {
117
- const index = +match[2];
118
- const example = localWhatsappData?.bodyExamples?.[index - 1];
119
- return example || match;
120
- };
121
-
122
- const upsertTemplate = async () => {
123
- if (!localWhatsappData) return;
124
- const payload = localToServer(localWhatsappData);
125
- console.log(payload);
126
- if (payload.id) {
127
- await bagel.put(
128
- `communication/whatsapp/update_template/${payload.id}`,
129
- payload,
130
- );
131
- } else {
132
- await bagel.post('communication/whatsapp/create_template', payload);
133
- void props.router.push(`/whatsapp/template/${payload.name}`);
134
- }
135
- };
136
-
137
- onMounted(loadTemplateData);
138
- </script>
139
-
140
- <style scoped>
141
- .btn-end {
142
- text-align: end;
143
- }
144
-
145
- .whatsapp-preview {
146
- direction: ltr;
147
- width: 400px;
148
- padding: 1rem;
149
- height: auto;
150
- margin-top: 1rem;
151
- /* border-left: 1px solid var(--border-color); */
152
- margin-left: 20px;
153
- position: sticky;
154
- top: 15px;
155
- flex: 1 1 40%;
156
- }
157
-
158
- .whatsapp-wrap {
159
- display: flex;
160
- gap: 1rem;
161
- max-width: 1200px;
162
- overflow: auto;
163
- height: 100%;
164
- }
165
-
166
- .create-template-form {
167
- flex: 1 0 50%;
168
- min-width: 300px;
169
- }
170
-
171
- .whatsapp-msg {
172
- background: var(--whatsapp-green);
173
- border-radius: 0.5rem;
174
- border-start-start-radius: 0px;
175
- padding: 10px;
176
- line-height: 1.5;
177
- margin-top: 1rem;
178
- filter: drop-shadow(0 0px 2px var(--bgl-shadow));
179
- position: relative;
180
- min-height: 30px;
181
- }
182
-
183
- .whatsapp-msg::after {
184
- content: '';
185
- inset-inline-start: -5px;
186
- border-radius: 0.1rem;
187
- transform: skew(45deg);
188
- top: 0;
189
- height: 8px;
190
- width: 8px;
191
- background: var(--whatsapp-green);
192
- position: absolute;
193
- }
194
-
195
- .whatsapp-body {
196
- margin: 2px 0;
197
- }
198
-
199
- .whatsapp-footer {
200
- margin: 0;
201
- opacity: 0.6;
202
- font-size: 0.8rem;
203
- }
204
-
205
- .whatsappHebrew {
206
- direction: rtl;
207
- }
208
-
209
- .whatsappHebrew .whatsapp-msg::after {
210
- transform: skew(-45deg);
211
- }
212
-
213
- @media screen and (max-width: 1200px) {
214
- .whatsapp-preview {
215
- width: 300px;
216
- }
217
- }
218
-
219
- @media screen and (max-width: 910px) {
220
- .whatsapp-preview {
221
- display: none;
222
- }
223
- }
224
- </style>
@@ -1,79 +0,0 @@
1
- <template>
2
- <div ref="exampleEl">
3
- <TextInput
4
- v-for="v in variables"
5
- :key="v"
6
- :placeholder="`Variable ${v}`"
7
- :modelValue="val?.[v - 1]"
8
- @update:modelValue="($event: string) => handleUpdate($event, v)"
9
- />
10
- </div>
11
- </template>
12
-
13
- <script setup lang="ts">
14
- import { onMounted, watch } from 'vue';
15
- import { FormKitNode } from '@formkit/core';
16
- import { TextInput } from '@bagelink/vue';
17
-
18
- const props = defineProps({
19
- context: Object,
20
- });
21
-
22
- const exampleEl = $ref<HTMLElement>();
23
- let boundValue = $ref<any>();
24
- let boundNode = $ref<FormKitNode>();
25
- let val = $ref<any[]>([]);
26
-
27
- const handleUpdate = (value: string, index: number) => {
28
- if (!boundValue) return;
29
- if (index > val?.length) val = [...val, ...Array(index - val.length).fill(''), value];
30
- else val?.splice(index - 1, 1, value);
31
- props.context?.node.input(val);
32
- };
33
-
34
- const extractVariables = (text: string): number[] => {
35
- const matches = text?.match(/{{(\d+)}}/g) || [];
36
- return matches.map((match: any) => +match.match(/\d+/)[0]);
37
- };
38
-
39
- const txtType = $computed(() => (props.context?.id === 'bodyExamples' ? 'bodyText' : 'headerText'));
40
-
41
- const variables = $computed(() => {
42
- let vars = extractVariables(boundValue);
43
- if (txtType === 'headerText') vars.slice(0, 1);
44
- const nonSequentialDigits = vars?.reduce((acc: number[], currDigit: number, i: number) => {
45
- const prevDigit = i > 0 ? vars[i - 1] : 0;
46
- if (currDigit - prevDigit !== 1) {
47
- acc.push(currDigit);
48
- }
49
- return acc;
50
- }, []);
51
-
52
- if (nonSequentialDigits?.length) {
53
- const regex = new RegExp(nonSequentialDigits.map((d: number) => `\\{\\{${d}\\}\\}`).join('|'), 'g');
54
- const newVal = `${boundValue}`.replace(regex, '');
55
- void boundNode?.input(newVal); // TODO: Nati - should be awaited?
56
- vars = extractVariables(boundValue);
57
- }
58
- const parentEl = exampleEl?.closest('.formkit-outer');
59
- if (!vars.length && parentEl) {
60
- parentEl.classList.add('hide');
61
- } else if (parentEl) {
62
- parentEl.classList.remove('hide');
63
- }
64
- return vars;
65
- });
66
-
67
- const setupListners = (node?: FormKitNode) => {
68
- node?.on('input', (v: any) => {
69
- boundValue = v.payload;
70
- });
71
- };
72
-
73
- onMounted(() => {
74
- boundNode = props.context?.node.parent.children.find((c: any) => c.name === txtType);
75
- setupListners(boundNode);
76
- });
77
-
78
- watch(() => props.context?.value, (v: any) => val = v, { immediate: true });
79
- </script>
@@ -1,2 +0,0 @@
1
- // export { default as MsgTemplate } from './form/MsgTemplate.vue';
2
- // export { default as TextVariableExamples } from './form/TextVariableExamples.vue';
@@ -1,58 +0,0 @@
1
- export interface HeaderComponent {
2
- type: 'HEADER';
3
- text: string;
4
- example_header?: string[];
5
- }
6
-
7
- interface Example {
8
- body_text: string[][];
9
- }
10
-
11
- export interface BodyComponent {
12
- type: 'BODY';
13
- text: string;
14
- example?: Example
15
- add_security_recommendation?: boolean;
16
- }
17
-
18
- export interface FooterComponent {
19
- type: 'FOOTER';
20
- text: string;
21
- code_expiration_minutes?: number;
22
- }
23
-
24
- interface Button {
25
- type: 'OTP' | 'CATALOG' | 'MPM' | 'QUICK_REPLY' | 'PHONE_NUMBER' | 'URL';
26
- text: string;
27
- // Additional properties specific to each button type
28
- // Add them here based on the possible button types
29
- }
30
-
31
- interface ButtonsComponent {
32
- type: 'BUTTONS';
33
- buttons: Button[];
34
- }
35
-
36
- export type Component = BodyComponent | FooterComponent | HeaderComponent | ButtonsComponent
37
-
38
- export interface ServerTemplateData {
39
- id: string;
40
- name: string;
41
- status: string;
42
- language: string;
43
- category: string;
44
- components: readonly Component[];
45
- }
46
-
47
- export interface LocalTemplateData {
48
- id: string;
49
- name: string;
50
- language: string;
51
- status: string;
52
- category: string;
53
- headerText?: string;
54
- headerExamples?: string[];
55
- bodyText?: string;
56
- bodyExamples?: string[];
57
- footerText?: string;
58
- }