@bagelink/vue 0.0.32 → 0.0.37

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 (60) hide show
  1. package/package.json +8 -2
  2. package/src/components/Comments.vue +30 -11
  3. package/src/components/ContactArray.vue +21 -6
  4. package/src/components/ContactSubmissions.vue +6 -3
  5. package/src/components/DataPreview.vue +22 -9
  6. package/src/components/FileUploader.vue +17 -8
  7. package/src/components/FormKitTable.vue +120 -71
  8. package/src/components/FormSchema.vue +20 -6
  9. package/src/components/LangText.vue +3 -1
  10. package/src/components/ListItem.vue +5 -1
  11. package/src/components/ListView.vue +25 -10
  12. package/src/components/MaterialIcon.vue +4 -1
  13. package/src/components/Modal.vue +17 -5
  14. package/src/components/ModalForm.vue +23 -8
  15. package/src/components/NavBar.vue +15 -5
  16. package/src/components/PersonPreview.vue +5 -7
  17. package/src/components/PersonPreviewFormkit.vue +5 -5
  18. package/src/components/RTXEditor.vue +4 -0
  19. package/src/components/RouterWrapper.vue +10 -2
  20. package/src/components/TabbedLayout.vue +8 -5
  21. package/src/components/TableSchema.vue +49 -14
  22. package/src/components/charts/BarChart.vue +35 -9
  23. package/src/components/dashboard/Lineart.vue +47 -15
  24. package/src/components/form/ItemRef.vue +10 -3
  25. package/src/components/form/MaterialIcon.vue +3 -3
  26. package/src/components/form/PlainInputField.vue +2 -3
  27. package/src/components/form/inputs/CheckInput.vue +3 -3
  28. package/src/components/form/inputs/Checkbox.vue +10 -2
  29. package/src/components/form/inputs/ColorPicker.vue +13 -3
  30. package/src/components/form/inputs/CurrencyInput.vue +7 -3
  31. package/src/components/form/inputs/DateInput.vue +8 -2
  32. package/src/components/form/inputs/DatetimeInput.vue +8 -4
  33. package/src/components/form/inputs/DurationInput.vue +8 -4
  34. package/src/components/form/inputs/DynamicLinkField.vue +9 -7
  35. package/src/components/form/inputs/EmailInput.vue +7 -3
  36. package/src/components/form/inputs/FloatInput.vue +7 -3
  37. package/src/components/form/inputs/IntInput.vue +8 -4
  38. package/src/components/form/inputs/JSONInput.vue +7 -3
  39. package/src/components/form/inputs/LinkField.vue +26 -19
  40. package/src/components/form/inputs/Password.vue +2 -0
  41. package/src/components/form/inputs/PasswordInput.vue +13 -10
  42. package/src/components/form/inputs/PlainText.vue +14 -3
  43. package/src/components/form/inputs/ReadOnlyInput.vue +5 -1
  44. package/src/components/form/inputs/RichTextEditor.vue +9 -7
  45. package/src/components/form/inputs/SelectField.vue +10 -5
  46. package/src/components/form/inputs/TableField.vue +1 -3
  47. package/src/components/form/inputs/TextArea.vue +11 -2
  48. package/src/components/form/inputs/TextInput.vue +13 -3
  49. package/src/components/form/inputs/index.ts +0 -1
  50. package/src/components/formkit/AddressArray.vue +1 -1
  51. package/src/components/formkit/BankDetailsArray.vue +10 -10
  52. package/src/components/formkit/ContactArrayFormKit.vue +58 -17
  53. package/src/components/formkit/FileUploader.vue +7 -7
  54. package/src/components/formkit/MiscFields.vue +6 -1
  55. package/src/components/formkit/Toggle.vue +8 -4
  56. package/src/components/whatsapp/form/MsgTemplate.vue +15 -8
  57. package/src/components/whatsapp/form/TextVariableExamples.vue +8 -3
  58. package/src/utils/index.ts +9 -4
  59. package/src/utils/modal.ts +7 -1
  60. package/src/utils/strings.ts +8 -1
@@ -1,9 +1,16 @@
1
1
  <template>
2
- <div class="bagel-input" :title="description" :class="{ small: small }">
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
3
7
  <label v-if="label">
4
8
  <LangText :input="label" />
5
9
  </label>
6
- <span class="character-limit" v-if="showCharacterLimit">
10
+ <span
11
+ class="character-limit"
12
+ v-if="showCharacterLimit"
13
+ >
7
14
  {{ modelValue?.length }}
8
15
  {{ nativeInputAttrs?.maxlength ? `/${nativeInputAttrs.maxlength}` : '' }}
9
16
  </span>
@@ -54,12 +61,14 @@ const handleInput = (e: Event) => {
54
61
  .bagel-input label {
55
62
  margin-bottom: 0;
56
63
  }
64
+
57
65
  .bagel-input textarea {
58
66
  height: 100%;
59
67
  resize: none;
60
68
  background: var(--input-bg);
61
69
  margin-bottom: 0.5rem;
62
70
  }
71
+
63
72
  .character-limit {
64
73
  font-size: 0.6rem;
65
74
  color: var(--input-color);
@@ -1,10 +1,20 @@
1
1
  <template>
2
- <div class="bagel-input" :class="{ small }" :title="title">
2
+ <div
3
+ class="bagel-input"
4
+ :class="{ small }"
5
+ :title="title"
6
+ >
3
7
  <label :for="id">
4
8
  {{ label }}
5
9
  <input
6
- :id="id" v-model="inputVal" type="text" :placeholder="placeholder || label"
7
- :class="{ 'no-edit': !editMode }" :required="required" :pattern="pattern" v-bind="nativeInputAttrs"
10
+ :id="id"
11
+ v-model="inputVal"
12
+ type="text"
13
+ :placeholder="placeholder || label"
14
+ :class="{ 'no-edit': !editMode }"
15
+ :required="required"
16
+ :pattern="pattern"
17
+ v-bind="nativeInputAttrs"
8
18
  >
9
19
  </label>
10
20
  </div>
@@ -11,7 +11,6 @@ export * from './PasswordInput.vue';
11
11
  export * from './ReadOnlyInput.vue';
12
12
  export * from './SelectField.vue';
13
13
  export * from './TextInput.vue';
14
- export * from './ImageField.vue';
15
14
  export * from './RichTextEditor.vue';
16
15
  export * from './TableField.vue';
17
16
  export * from './DurationInput.vue';
@@ -87,9 +87,9 @@
87
87
  <script setup lang="ts">
88
88
  import { watch } from 'vue';
89
89
  // import type { BagelField } from '@/types/BagelField';
90
+ import { useBagel } from 'src/plugins/bagel';
90
91
  import { Btn } from '@/components';
91
92
  import Checkbox from '../form/inputs/Checkbox.vue';
92
- import { useBagel } from 'src/plugins/bagel';
93
93
 
94
94
  const bagel = useBagel();
95
95
  const props = defineProps<{
@@ -36,27 +36,27 @@
36
36
  v-model="bank_account.label"
37
37
  type="text"
38
38
  :placeholder="form.label"
39
- />
39
+ >
40
40
  <div class="bglform-contact-address">
41
41
  <input
42
42
  v-model="bank_account.bank_name"
43
43
  :placeholder="form.bankName"
44
44
  type="text"
45
45
  required
46
- />
46
+ >
47
47
  <div class="bglform-contact-address-flex">
48
48
  <input
49
49
  v-model="bank_account.branch"
50
50
  :placeholder="form.bankBranch"
51
51
  type="text"
52
52
  required
53
- />
53
+ >
54
54
  <input
55
55
  v-model="bank_account.account_number"
56
56
  :placeholder="form.bankAccount"
57
57
  type="text"
58
58
  required
59
- />
59
+ >
60
60
  </div>
61
61
  <div class="grid gap-2">
62
62
  <input
@@ -64,27 +64,27 @@
64
64
  :placeholder="form.bankAccountHolder"
65
65
  type="text"
66
66
  required
67
- />
67
+ >
68
68
  <input
69
69
  v-model="bank_account.bank_account_holder_id"
70
70
  :placeholder="form.bankAccountHolderID"
71
71
  type="text"
72
- />
72
+ >
73
73
  <input
74
74
  v-model="bank_account.iban"
75
75
  placeholder="IBAN"
76
76
  type="text"
77
- />
77
+ >
78
78
  <input
79
79
  v-model="bank_account.swift"
80
80
  placeholder="SWIFT"
81
81
  type="text"
82
- />
82
+ >
83
83
  <input
84
84
  v-model="bank_account.bank_address"
85
85
  :placeholder="form.bankAddress"
86
86
  type="text"
87
- />
87
+ >
88
88
  </div>
89
89
  </div>
90
90
  <div class="bglform-address-del">
@@ -113,9 +113,9 @@
113
113
  import { watch } from 'vue';
114
114
  // import type { BagelField } from '@/types/BagelField';
115
115
 
116
+ import { useBagel } from 'src/plugins/bagel';
116
117
  import { Btn } from '@/components';
117
118
  import Checkbox from '../form/inputs/Checkbox.vue';
118
- import { useBagel } from 'src/plugins/bagel';
119
119
 
120
120
  const bagel = useBagel();
121
121
 
@@ -1,30 +1,72 @@
1
1
  <template>
2
2
  <div class="bagel-input">
3
3
  <div class="mt-1">
4
- <div class="bglform-contact mb-2" v-for="(contact, i) in val" :key="i">
5
- <div class="bglform-contact-confirm" v-if="deleteCandidate === i">
4
+ <div
5
+ class="bglform-contact mb-2"
6
+ v-for="(contact, i) in val"
7
+ :key="i"
8
+ >
9
+ <div
10
+ class="bglform-contact-confirm"
11
+ v-if="deleteCandidate === i"
12
+ >
6
13
  <p class="txt14">
7
- {{ form.sure}}
14
+ {{ form.sure }}
8
15
  </p>
9
- <Btn thin color="red" @click="deleteContact(contact.id)">
10
- {{ form.delete}}
16
+ <Btn
17
+ thin
18
+ color="red"
19
+ @click="deleteContact(contact.id)"
20
+ >
21
+ {{ form.delete }}
11
22
  </Btn>
12
- <Btn thin @click="deleteCandidate = -1">
13
- {{ form.cancel}}
23
+ <Btn
24
+ thin
25
+ @click="deleteCandidate = -1"
26
+ >
27
+ {{ form.cancel }}
14
28
  </Btn>
15
29
  </div>
16
- <Checkbox v-model="contact.primary" @update:model-value="($event) => primaryHandler(i, $event)" />
17
- <input class="bglform-contact-label" v-model="contact.label" type="text" :placeholder="form.label">
18
-
19
- <input v-model="contact.email" :placeholder="form.email" v-if="context?.id === 'email'" type="email">
20
- <input v-model="contact.phone" :placeholder="form.phone" v-if="context?.id === 'phone'" type="tel">
30
+ <Checkbox
31
+ v-model="contact.primary"
32
+ @update:model-value="($event) => primaryHandler(i, $event)"
33
+ />
34
+ <input
35
+ class="bglform-contact-label"
36
+ v-model="contact.label"
37
+ type="text"
38
+ :placeholder="form.label"
39
+ >
40
+
41
+ <input
42
+ v-model="contact.email"
43
+ :placeholder="form.email"
44
+ v-if="context?.id === 'email'"
45
+ type="email"
46
+ >
47
+ <input
48
+ v-model="contact.phone"
49
+ :placeholder="form.phone"
50
+ v-if="context?.id === 'phone'"
51
+ type="tel"
52
+ >
21
53
  <!-- <MaterialIcon @click="del(i)" icon="delete" class="btn-float" /> -->
22
54
  <Btn
23
- thin @click="deleteCandidate = i" icon="delete" color="gray" :disabled="contact.primary || val.length === 1 || deleteCandidate !== -1
24
- "
55
+ thin
56
+ @click="deleteCandidate = i"
57
+ icon="delete"
58
+ color="gray"
59
+ :disabled="contact.primary || val.length === 1 || deleteCandidate !== -1
60
+ "
25
61
  />
26
62
  </div>
27
- <Btn class="add-btn" color="blue" flat thin @click="val.push({})">
63
+ <Btn
64
+ class="add-btn"
65
+ color="blue"
66
+ flat
67
+ thin
68
+ @click="val.push({})"
69
+ >
28
70
  {{ form.add }} {{ context?.label }}
29
71
  </Btn>
30
72
  </div>
@@ -34,13 +76,12 @@
34
76
  <script setup lang="ts">
35
77
  import { watch } from 'vue';
36
78
  // import type { BagelField } from '@/types/BagelField';
79
+ import { useBagel } from 'src/plugins/bagel';
37
80
  import { Btn } from '@/components';
38
81
  import Checkbox from '../form/inputs/Checkbox.vue';
39
- import { useBagel } from 'src/plugins/bagel';
40
82
 
41
83
  const bagel = useBagel();
42
84
 
43
-
44
85
  const props = defineProps<{
45
86
  context: Record<string, any>;
46
87
  form: {
@@ -92,8 +92,8 @@ interface UploadFile {
92
92
  }
93
93
 
94
94
  import { onMounted, onUnmounted } from 'vue';
95
- import { MaterialIcon, Btn } from '@/components';
96
95
  import { useBagel } from 'src/plugins/bagel';
96
+ import { MaterialIcon, Btn } from '@/components';
97
97
 
98
98
  const bagel = useBagel();
99
99
 
@@ -134,14 +134,14 @@ function animateCircle(e: DragEvent) {
134
134
  function emitValue() {
135
135
  // const fileValues = files.map((f) => f.serverFile?.id);
136
136
  // console.log({ files });
137
- if (!props.context?.attrs.multiple) { props.context?.node.input(files[0].serverFile); }
137
+ if (!props.context?.attrs.multiple) props.context?.node.input(files[0].serverFile);
138
138
  // eslint-disable-next-line no-alert
139
139
  else alert('not implemented');
140
140
  }
141
141
 
142
- const isImg = (file: UploadFile) => file.file?.type.includes('image')
143
- || file.serverFile?.mimetype?.match(/image\/|jpg|png|gif|bmp|jpeg/i)
144
- || file.serverFile.extension?.match(/jpg|png|gif|bmp|jpeg/i);
142
+ const isImg = (file: UploadFile) => file.file?.type.includes('image') ||
143
+ file.serverFile?.mimetype?.match(/image\/|jpg|png|gif|bmp|jpeg/i) ||
144
+ file.serverFile.extension?.match(/jpg|png|gif|bmp|jpeg/i);
145
145
 
146
146
  function uploadFiles() {
147
147
  files.forEach(async (file) => {
@@ -208,14 +208,14 @@ onUnmounted(() => dropZoneEl?.removeEventListener('dragover', animateCircle));
208
208
 
209
209
  function handleFileInput(e: Event) {
210
210
  const filesToAdd: FileList = (e.target as any).files;
211
- addFiles(filesToAdd);
211
+ void addFiles(filesToAdd); // TODO: Nati: should be awaited?
212
212
  }
213
213
 
214
214
  function onDrop(e: DragEvent) {
215
215
  draggingOver = false;
216
216
  e.preventDefault();
217
217
  const filesToAdd = e.dataTransfer?.files;
218
- if (filesToAdd) addFiles(filesToAdd);
218
+ if (filesToAdd) void addFiles(filesToAdd); // TODO: Nati: should be awaited?
219
219
  }
220
220
  </script>
221
221
  <style>
@@ -18,9 +18,10 @@
18
18
 
19
19
  <script lang="ts" setup>
20
20
  import { Btn } from '@/components';
21
+
21
22
  const props = defineProps<{
22
23
  context: Record<string, any>;
23
- addBtnLabel: string
24
+ addBtnLabel: string
24
25
  }>();
25
26
 
26
27
  const fields = $computed(() => props.context?.node?.parent?.children || []);
@@ -39,6 +40,7 @@ const addToField = (field: any) => {
39
40
  padding-top: 0.5rem;
40
41
  margin-bottom: auto;
41
42
  }
43
+
42
44
  .gray.thin.btn-txt.btn.add-btn {
43
45
  display: flex;
44
46
  gap: 0.5rem;
@@ -47,9 +49,11 @@ const addToField = (field: any) => {
47
49
  padding-right: 0;
48
50
  transition: var(--bgl-transition);
49
51
  }
52
+
50
53
  .add-btn:active {
51
54
  background: none !important;
52
55
  }
56
+
53
57
  .add-btn::before {
54
58
  content: '+';
55
59
  font-size: 10px;
@@ -62,6 +66,7 @@ const addToField = (field: any) => {
62
66
  justify-content: center;
63
67
  color: var(--bgl-gray);
64
68
  }
69
+
65
70
  .add-btn:hover::before {
66
71
  background: var(--bgl-blue);
67
72
  color: var(--bgl-white);
@@ -78,7 +78,7 @@ watch(
78
78
  display: none;
79
79
  }
80
80
 
81
- .radio-wrap input:checked:checked + label {
81
+ .radio-wrap input:checked:checked+label {
82
82
  background: var(--bgl-blue);
83
83
  color: var(--bgl-white);
84
84
  }
@@ -100,14 +100,17 @@ watch(
100
100
  width: 0;
101
101
  height: 0;
102
102
  }
103
+
103
104
  .bagel-input.checkbox.check {
104
105
  margin: 0;
105
106
  }
107
+
106
108
  .bagel-input.checkbox.check .switch {
107
109
  width: calc(var(--input-height) / 2);
108
110
  height: calc(var(--input-height) / 2);
109
111
  transition: 0.2s;
110
112
  }
113
+
111
114
  .bagel-input.checkbox.check .slider:before {
112
115
  position: absolute;
113
116
  font-family: 'Material Symbols Outlined', serif;
@@ -118,7 +121,8 @@ watch(
118
121
  align-items: center;
119
122
  justify-content: center;
120
123
  }
121
- .bagel-input.checkbox.check input:checked + .slider:before {
124
+
125
+ .bagel-input.checkbox.check input:checked+.slider:before {
122
126
  transform: none;
123
127
  content: 'check';
124
128
  }
@@ -150,11 +154,11 @@ watch(
150
154
  transition: 0.4s;
151
155
  }
152
156
 
153
- input:checked + .slider {
157
+ input:checked+.slider {
154
158
  background: var(--bgl-blue);
155
159
  }
156
160
 
157
- input:checked + .slider:before {
161
+ input:checked+.slider:before {
158
162
  transform: translateX(calc(var(--input-height) / 2));
159
163
  }
160
164
  </style>
@@ -4,9 +4,16 @@
4
4
  <div class="view-wrapper card thin">
5
5
  <div class="whatsapp-wrap">
6
6
  <div class="create-template-form">
7
- <FormSchema :schema="whatsappTemplateSchema()" v-model="localWhatsappData" @submit="upsertTemplate" />
7
+ <FormSchema
8
+ :schema="whatsappTemplateSchema()"
9
+ v-model="localWhatsappData"
10
+ @submit="upsertTemplate"
11
+ />
8
12
  </div>
9
- <div class="whatsapp-preview" :class="{ whatsappHebrew: localWhatsappData?.language === 'he' }">
13
+ <div
14
+ class="whatsapp-preview"
15
+ :class="{ whatsappHebrew: localWhatsappData?.language === 'he' }"
16
+ >
10
17
  Preview
11
18
  <div class="whatsapp-msg">
12
19
  <b>{{
@@ -27,8 +34,10 @@
27
34
 
28
35
  <script setup lang="ts">
29
36
  import { onMounted } from 'vue';
30
- import { PageTitle, FormSchema } from '@/components';
31
37
 
38
+ import { useBagel } from 'src/plugins/bagel';
39
+ import type { FormKitSchemaDefinition } from '@formkit/core';
40
+ import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
32
41
  import {
33
42
  BodyComponent,
34
43
  HeaderComponent,
@@ -36,15 +45,13 @@ import {
36
45
  ServerTemplateData,
37
46
  FooterComponent,
38
47
  } from '../interfaces';
39
- import { useBagel } from 'src/plugins/bagel';
40
- import type { FormKitSchemaDefinition } from '@formkit/core';
41
- import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
48
+ import { PageTitle, FormSchema } from '@/components';
42
49
 
43
50
  const props = defineProps<{
44
51
  whatsappTemplateSchema: () => FormKitSchemaDefinition;
45
52
  router: Router;
46
53
  route: RouteLocationNormalizedLoaded;
47
- }>()
54
+ }>();
48
55
 
49
56
  const bagel = useBagel();
50
57
 
@@ -126,7 +133,7 @@ const upsertTemplate = async () => {
126
133
  );
127
134
  } else {
128
135
  await bagel.post('communication/whatsapp/create_template', payload);
129
- props.router.push(`/whatsapp/template/${payload.name}`);
136
+ void props.router.push(`/whatsapp/template/${payload.name}`);
130
137
  }
131
138
  };
132
139
 
@@ -1,7 +1,12 @@
1
1
  <template>
2
2
  <div ref="exampleEl">
3
- <TextInput v-for="v in variables" :key="v" :placeholder="`Variable ${v}`" :modelValue="val?.[v - 1]"
4
- @update:modelValue="($event: string) => handleUpdate($event, v)" />
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
+ />
5
10
  </div>
6
11
  </template>
7
12
 
@@ -47,7 +52,7 @@ const variables = $computed(() => {
47
52
  if (nonSequentialDigits?.length) {
48
53
  const regex = new RegExp(nonSequentialDigits.map((d: number) => `\\{\\{${d}\\}\\}`).join('|'), 'g');
49
54
  const newVal = `${boundValue}`.replace(regex, '');
50
- boundNode?.input(newVal);
55
+ void boundNode?.input(newVal); // TODO: Nati - should be awaited?
51
56
  vars = extractVariables(boundValue);
52
57
  }
53
58
  const parentEl = exampleEl?.closest('.formkit-outer');
@@ -25,8 +25,8 @@ export function computeFields(modelValue: Record<string, any>): BagelField[] {
25
25
  if (typeof modelValue[key] === 'number') field.inputType = 'NumberInput';
26
26
  if (modelValue[key] === true || modelValue[key] === false) field.inputType = 'CheckInput';
27
27
  if (
28
- modelValue[key] instanceof Date
29
- || !Number.isNaN(Date.parse(modelValue[key]))
28
+ modelValue[key] instanceof Date ||
29
+ !Number.isNaN(Date.parse(modelValue[key]))
30
30
  ) field.inputType = 'DateInput';
31
31
 
32
32
  fields.push(field);
@@ -34,7 +34,11 @@ export function computeFields(modelValue: Record<string, any>): BagelField[] {
34
34
  return fields;
35
35
  }
36
36
 
37
- const copyText = async (text: string, cb?: (msg: string) => void) => {
37
+ const copyText = async (
38
+ text: string,
39
+ // eslint-disable-next-line no-unused-vars
40
+ cb?: (msg: string) => void,
41
+ ) => {
38
42
  await navigator.clipboard.writeText(text);
39
43
  if (cb) cb('Copied to clipboard');
40
44
  };
@@ -46,7 +50,8 @@ export const useFormkit = () => {
46
50
 
47
51
  export const initials = (...strArr: string[]) => strArr.map((str) => str?.charAt(0)).join('');
48
52
 
49
- export const parseLocale = (str: string, $t = (str: string) => str) => {
53
+ export const parseLocale = (str: string, $t = (_str: string) => _str) => {
54
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
50
55
  const [_, w] = str.split(/\$t\('?"?|'?"?\)/);
51
56
  if (!w) return str;
52
57
  return $t(w);
@@ -3,7 +3,7 @@ import {
3
3
  } from 'vue';
4
4
  import type { Plugin } from 'vue';
5
5
  import { Modal, ModalForm } from '@/components';
6
- import { BtnOptions } from '../types/BtnOptions';
6
+ import type { BtnOptions } from '@/types/BtnOptions';
7
7
 
8
8
  interface ModalOptions {
9
9
  title?: string;
@@ -15,15 +15,21 @@ interface ModalOptions {
15
15
 
16
16
  interface ModalFormOptions extends ModalOptions {
17
17
  modelValue?: any;
18
+ // eslint-disable-next-line no-unused-vars
18
19
  'onUpdate:modelValue'?: (val: any) => void;
20
+ // eslint-disable-next-line no-unused-vars
19
21
  onSubmit: (val: any) => void;
22
+ // eslint-disable-next-line no-unused-vars
20
23
  onDelete?: (id: string) => void;
21
24
  schema: any;
22
25
  }
23
26
 
24
27
  interface ModalApi {
28
+ // eslint-disable-next-line no-unused-vars
25
29
  showModal: (options: ModalOptions, slots?: Record<string, any>) => void;
30
+ // eslint-disable-next-line no-unused-vars
26
31
  modalForm: (options: ModalFormOptions, slots?: Record<string, any>) => void;
32
+ // eslint-disable-next-line no-unused-vars
27
33
  hideModal: (index?: number) => void;
28
34
  // modalOptions: Ref<ModalOptions | ModalFormOptions>;
29
35
  }
@@ -1,7 +1,14 @@
1
1
  export function formatString(
2
2
  str: string,
3
- format: 'pascal' | 'camel' | 'snake',
3
+ format: 'pascal' | 'camel' | 'snake' | 'titleCase',
4
4
  ): string {
5
+ if (format === 'titleCase') {
6
+ return str
7
+ .split('_')
8
+ .map((word) => word[0].toUpperCase() + word.slice(1).toLocaleLowerCase())
9
+ .join(' ');
10
+ }
11
+
5
12
  if (format === 'pascal') {
6
13
  return str
7
14
  .split('_')