@designcrowd/library.brand-page 5.14.11 → 5.14.12

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 (95) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-BJ3Foxao.js → CreatedOnBrandCrowd-de-de-C5tl1NwD.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-BjI_fxWY.js → CreatedOnBrandCrowd-en-us-C7J2vGwU.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-Dt8190BK.js → CreatedOnBrandCrowd-es-es-IREekVx2.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-Ck6zCiIn.js → CreatedOnBrandCrowd-fr-fr-EJkAJ0iH.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CaNvmzQJ.js → CreatedOnBrandCrowd-pt-pt-mKBH6Ary.js} +1 -1
  6. package/lib/src/{CreatedOnDcom-de-de-DMEecXw8.js → CreatedOnDcom-de-de-CWWw2LBb.js} +1 -1
  7. package/lib/src/{CreatedOnDcom-en-us-BZIPLMxJ.js → CreatedOnDcom-en-us-Db6zzKtc.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-es-es-D6ey1TnI.js → CreatedOnDcom-es-es-CsMu_iBW.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-fr-fr-NaeiDsv-.js → CreatedOnDcom-fr-fr-oJRc8eop.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-pt-pt-BwEUUii2.js → CreatedOnDcom-pt-pt-CQ_otC6l.js} +1 -1
  11. package/lib/src/brand-page/components/button/Button.mixin.js +4 -2
  12. package/lib/src/brand-page/models/index.d.ts +9 -2
  13. package/lib/src/brand-page/utils/migration/migration-06.d.ts +2 -0
  14. package/lib/src/brand-page/utils/migration/migration-06.js +48 -0
  15. package/lib/src/brand-page/utils/migration.util.js +6 -0
  16. package/lib/src/brand-page/utils/view-model.util.js +49 -11
  17. package/lib/src/brand-page/view-models.d.ts +10 -3
  18. package/lib/src/brand-page-maker/constants/config-settings-constant.js +8 -1
  19. package/lib/src/brand-page-maker/models/content-settings.js +7 -1
  20. package/lib/src/{bundled-translations-B54196Rf.js → bundled-translations-fWikWTfa.js} +15 -15
  21. package/lib/src/{bundled-translations.de-DE-CNESUsYJ.js → bundled-translations.de-DE-CwtsRCCr.js} +33 -33
  22. package/lib/src/{bundled-translations.es-ES-FWge029M.js → bundled-translations.es-ES-DELCLCbF.js} +9 -9
  23. package/lib/src/{bundled-translations.fr-CA-DlWfm29N.js → bundled-translations.fr-CA-PDBhYlx8.js} +17 -17
  24. package/lib/src/{bundled-translations.fr-FR-DRCMzVfh.js → bundled-translations.fr-FR-OuZj3i-r.js} +24 -24
  25. package/lib/src/{bundled-translations.pt-BR-llUnBWoL.js → bundled-translations.pt-BR-RPfprZOm.js} +36 -36
  26. package/lib/src/{bundled-translations.pt-PT-K74Dt682.js → bundled-translations.pt-PT-DF_GCXSl.js} +5 -5
  27. package/lib/src/bundles/bundled-translations.de-DE.json +18 -2
  28. package/lib/src/bundles/bundled-translations.es-ES.json +18 -2
  29. package/lib/src/bundles/bundled-translations.fr-CA.json +18 -2
  30. package/lib/src/bundles/bundled-translations.fr-FR.json +18 -2
  31. package/lib/src/bundles/bundled-translations.json +18 -2
  32. package/lib/src/bundles/bundled-translations.pt-BR.json +18 -2
  33. package/lib/src/bundles/bundled-translations.pt-PT.json +18 -2
  34. package/lib/src/css/library.brand-page-brandCrowd.min.css +31 -28
  35. package/lib/src/css/library.brand-page-brandPage.min.css +31 -28
  36. package/lib/src/css/library.brand-page-designCom.min.css +31 -28
  37. package/lib/src/css/library.brand-page-preview.min.css +31 -28
  38. package/lib/src/index.mjs +1 -1
  39. package/lib/src/{lib-C0mkZ8UD.js → lib-CwoD7AhY.js} +26687 -26581
  40. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.d.ts +3 -3
  41. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.js +3 -3
  42. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -2
  43. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +2 -2
  44. package/package.json +1 -1
  45. package/src/brand-page/components/button/Button.mixin.ts +4 -2
  46. package/src/brand-page/components/fallback-image/FallbackImage.vue +1 -1
  47. package/src/brand-page/components/image/Image.vue +1 -1
  48. package/src/brand-page/components/images-section/ImagesSection.test.ts +230 -0
  49. package/src/brand-page/components/images-section/ImagesSection.vue +185 -18
  50. package/src/brand-page/components/shapes-section/ShapesSection.vue +19 -9
  51. package/src/brand-page/components/text-media-section/TextMediaSection.vue +166 -7
  52. package/src/brand-page/models/index.ts +10 -2
  53. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
  54. package/src/brand-page/utils/migration/migration-06.ts +64 -0
  55. package/src/brand-page/utils/migration.util.ts +6 -0
  56. package/src/brand-page/utils/view-model.util.ts +62 -13
  57. package/src/brand-page/view-models.ts +8 -2
  58. package/src/brand-page-maker/constants/config-settings-constant.ts +7 -1
  59. package/src/brand-page-maker/models/content-settings.ts +7 -1
  60. package/src/bundles/bundled-translations.de-DE.json +18 -2
  61. package/src/bundles/bundled-translations.es-ES.json +18 -2
  62. package/src/bundles/bundled-translations.fr-CA.json +18 -2
  63. package/src/bundles/bundled-translations.fr-FR.json +18 -2
  64. package/src/bundles/bundled-translations.json +18 -2
  65. package/src/bundles/bundled-translations.pt-BR.json +18 -2
  66. package/src/bundles/bundled-translations.pt-PT.json +18 -2
  67. package/src/shared/content-settings/components/button-configuration-field/ButtonConfigurationField.vue +283 -0
  68. package/src/shared/content-settings/components/content-settings/i18n/content-settings.de-DE.json +1 -0
  69. package/src/shared/content-settings/components/content-settings/i18n/content-settings.es-ES.json +1 -0
  70. package/src/shared/content-settings/components/content-settings/i18n/content-settings.fr-CA.json +1 -0
  71. package/src/shared/content-settings/components/content-settings/i18n/content-settings.fr-FR.json +1 -0
  72. package/src/shared/content-settings/components/content-settings/i18n/content-settings.json +1 -0
  73. package/src/shared/content-settings/components/content-settings/i18n/content-settings.pt-BR.json +1 -0
  74. package/src/shared/content-settings/components/content-settings/i18n/content-settings.pt-PT.json +1 -0
  75. package/src/shared/content-settings/components/items-field/ItemsField.mixin.ts +3 -3
  76. package/src/shared/content-settings/components/text-image-field/TextImageField.vue +428 -92
  77. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.de-DE.json +18 -3
  78. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.es-ES.json +18 -3
  79. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.fr-CA.json +18 -3
  80. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.fr-FR.json +18 -3
  81. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.json +18 -2
  82. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.pt-BR.json +18 -3
  83. package/src/shared/content-settings/components/text-image-field/i18n/text-image-field.pt-PT.json +18 -3
  84. package/lib/src/brand-page/components/images-section/ImagesSection.mixin.d.ts +0 -86
  85. package/lib/src/brand-page/components/images-section/ImagesSection.mixin.js +0 -149
  86. package/lib/src/brand-page/components/shapes-section/ShapesSection.mixin.d.ts +0 -62
  87. package/lib/src/brand-page/components/shapes-section/ShapesSection.mixin.js +0 -25
  88. package/lib/src/brand-page/components/text-media-section/TextMediaSection.mixin.d.ts +0 -66
  89. package/lib/src/brand-page/components/text-media-section/TextMediaSection.mixin.js +0 -90
  90. package/lib/src/shared/content-settings/components/text-image-field/TextImageField.mixin.d.ts +0 -126
  91. package/lib/src/shared/content-settings/components/text-image-field/TextImageField.mixin.js +0 -192
  92. package/src/brand-page/components/images-section/ImagesSection.mixin.ts +0 -183
  93. package/src/brand-page/components/shapes-section/ShapesSection.mixin.ts +0 -29
  94. package/src/brand-page/components/text-media-section/TextMediaSection.mixin.ts +0 -124
  95. package/src/shared/content-settings/components/text-image-field/TextImageField.mixin.ts +0 -252
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <ItemsField
4
- :items="items"
4
+ :items="options"
5
5
  :can-collapse="true"
6
6
  :show-preview-image="false"
7
7
  @items-change="onItemsChange"
@@ -22,7 +22,7 @@
22
22
  >
23
23
  <Icon
24
24
  class="tw-pt-1"
25
- :name="option.item.mediaType === 'shape' ? 'shape' : 'images'"
25
+ :name="isShape(option.item) ? 'shape' : 'images'"
26
26
  size="sm"
27
27
  />
28
28
  </div>
@@ -34,9 +34,9 @@
34
34
  <template #form="option">
35
35
  <h4 class="tw-mt-3 tw-mb-1.5 tw-text-sm tw-font-bold tw-capitalize">
36
36
  {{
37
- option.item.mediaType === 'image'
38
- ? textImageFieldTr(`image`)
39
- : textImageFieldTr(`shape`)
37
+ isShape(option.item)
38
+ ? textImageFieldTr(`shape`)
39
+ : textImageFieldTr(`image`)
40
40
  }}
41
41
  </h4>
42
42
  <ImageField
@@ -49,6 +49,7 @@
49
49
  "
50
50
  @update:model-value="onRemoveImage(option.index)"
51
51
  />
52
+
52
53
  <PersonalisationOverrideField
53
54
  v-if="isAdmin && content.personalisationRole"
54
55
  :id="id"
@@ -84,75 +85,6 @@
84
85
  :toggle-unique-id="option.index.toString()"
85
86
  @update:model-value="onColorReplacementsChange($event, option.index)"
86
87
  />
87
- <h4
88
- v-if="option.item.mediaType !== 'shape'"
89
- class="tw-mt-3 tw-text-sm tw-font-bold"
90
- >
91
- {{ textImageFieldTr(`imageCaption`) }}
92
- </h4>
93
- <div v-if="option.item.mediaType !== 'shape'">
94
- <TextInput
95
- v-model="options[option.index].imageTitle"
96
- size="sm"
97
- :maxlength="descriptionLength"
98
- :placeholder="textImageFieldTr(`imageCaptionPlaceholder`)"
99
- :attrs="{
100
- 'data-test-tag': 'image-caption-text-input',
101
- }"
102
- :error="
103
- options[option.index].imageTitle.length >= descriptionLength
104
- "
105
- />
106
- <p
107
- v-if="options[option.index].imageTitle.length >= descriptionLength"
108
- class="tw-text-error-500 tw-text-sm tw-mt-2"
109
- >
110
- {{ maxLengthError }}
111
- </p>
112
- <PersonalisationOverrideField
113
- v-if="isAdmin && content.personalisationRole"
114
- :id="id"
115
- name="imageTitleOverride"
116
- :content="content"
117
- :object="content[name][option.index]"
118
- personalisation-type="text-media-items"
119
- @update:model-value="
120
- onPersonalisationOverrideChange($event, option.index)
121
- "
122
- />
123
- </div>
124
-
125
- <div
126
- v-if="
127
- brandPageType === 'brandSite' && option.item.mediaType !== 'shape'
128
- "
129
- >
130
- <h4 class="tw-mt-3 tw-text-sm tw-font-bold">
131
- {{ textImageFieldTr(`imageLink`) }}
132
- </h4>
133
- <TextInput
134
- v-model="options[option.index].imageLink"
135
- class="tw-mt-2"
136
- size="sm"
137
- :maxlength="descriptionLength"
138
- :placeholder="'https://example.com'"
139
- :error="
140
- options[option.index].imageLink.length >= descriptionLength ||
141
- !checkUrl(option.index)
142
- "
143
- :icon="'globe'"
144
- :attrs="{
145
- 'data-test-tag': 'image-link-text-input',
146
- }"
147
- @blur="onValueChange(options[option.index].imageLink, option.index)"
148
- />
149
- <p
150
- v-if="!checkUrl(option.index)"
151
- class="tw-text-error-500 tw-text-sm tw-mt-2"
152
- >
153
- {{ invalidUrlError }}
154
- </p>
155
- </div>
156
88
 
157
89
  <h4 class="tw-mt-3 tw-text-sm tw-font-bold">
158
90
  {{ textImageFieldTr(`title`) }}
@@ -188,7 +120,9 @@
188
120
  {{ textImageFieldTr(`paragraph`) }}
189
121
  </h4>
190
122
  <TextareaField
123
+ :id="`${id}-${option.index}-paragraph`"
191
124
  :value="options[option.index].paragraph"
125
+ :item="{ text: options[option.index].paragraph, textStyle: {} }"
192
126
  element-classes="tw-w-full"
193
127
  size="sm"
194
128
  :name="name"
@@ -214,6 +148,120 @@
214
148
  onPersonalisationOverrideChange($event, option.index)
215
149
  "
216
150
  />
151
+ <template v-if="!isShape(option.item)"
152
+ ><h4 class="tw-text-sm tw-font-bold">
153
+ {{ textImageFieldTr(`imageCaption`) }}
154
+ </h4>
155
+ <div class="tw-text-sm tw-text-secondary-500">
156
+ {{ textImageFieldTr(`imageCaptionSub`) }}
157
+ </div>
158
+ <div class="tw-mb-2">
159
+ <TextInput
160
+ v-model="options[option.index].imageTitle"
161
+ size="sm"
162
+ :maxlength="descriptionLength"
163
+ :placeholder="textImageFieldTr(`imageCaptionPlaceholder`)"
164
+ :attrs="{
165
+ 'data-test-tag': `image-caption-text-input-${id}-${option.index}`,
166
+ }"
167
+ :error="
168
+ options[option.index].imageTitle.length >= descriptionLength
169
+ "
170
+ />
171
+ <p
172
+ v-if="
173
+ options[option.index].imageTitle.length >= descriptionLength
174
+ "
175
+ class="tw-text-error-500 tw-text-sm tw-mt-2"
176
+ >
177
+ {{ maxLengthError }}
178
+ </p>
179
+ <PersonalisationOverrideField
180
+ v-if="isAdmin && content.personalisationRole"
181
+ :id="id"
182
+ name="imageTitleOverride"
183
+ :content="content"
184
+ :object="content[name][option.index]"
185
+ personalisation-type="text-media-items"
186
+ @update:model-value="
187
+ onPersonalisationOverrideChange($event, option.index)
188
+ "
189
+ />
190
+ </div>
191
+ <ButtonConfigurationField
192
+ :id="id"
193
+ :index="option.index"
194
+ :is-admin="isAdmin"
195
+ :button-config="{
196
+ buttonText: options[option.index].buttonText ?? false,
197
+ buttonLinkType: options[option.index].buttonLinkType || 'url',
198
+ url: options[option.index].url || '',
199
+ pageSlug: options[option.index].pageSlug || '',
200
+ }"
201
+ :title-length="titleLength"
202
+ :description-length="descriptionLength"
203
+ @update:button-config="
204
+ (buttonConfig) => onButtonConfigUpdate(buttonConfig, option.index)
205
+ "
206
+ />
207
+ </template>
208
+
209
+ <div
210
+ v-if="
211
+ !isShape(option.item) &&
212
+ brandPageType === BRAND_PAGE_TYPES.brandSite
213
+ "
214
+ >
215
+ <div class="tw-flex tw-items-center tw-justify-between tw-mb-2">
216
+ <h4 class="tw-mt-3 tw-text-sm tw-font-bold">
217
+ {{ textImageFieldTr(`imageLink`) }}
218
+ </h4>
219
+ <Toggle
220
+ :id="`image-link-toggle-${id}-${option.index}`"
221
+ :model-value="options[option.index].imageLink !== false"
222
+ color="primary"
223
+ :attrs="{
224
+ 'data-test-tag': `image-link-toggle-${id}-${option.index}`,
225
+ }"
226
+ @update:model-value="
227
+ (enabled) => onImageLinkToggleChange(enabled, option.index)
228
+ "
229
+ />
230
+ </div>
231
+ <div v-if="options[option.index].imageLink !== false">
232
+ <TextInput
233
+ v-model="options[option.index].imageLink"
234
+ class="tw-mt-2"
235
+ size="sm"
236
+ :maxlength="descriptionLength"
237
+ :placeholder="'https://example.com'"
238
+ :error="
239
+ (typeof options[option.index].imageLink === 'string' &&
240
+ (options[option.index].imageLink as string).length >=
241
+ descriptionLength) ||
242
+ !checkUrl(option.index)
243
+ "
244
+ :icon="'globe'"
245
+ :attrs="{
246
+ 'data-test-tag': `image-link-text-input-${id}-${option.index}`,
247
+ }"
248
+ @blur="
249
+ onValueChange(
250
+ typeof options[option.index].imageLink === 'string'
251
+ ? (options[option.index].imageLink as string)
252
+ : '',
253
+ option.index,
254
+ )
255
+ "
256
+ />
257
+ <p
258
+ v-if="!checkUrl(option.index)"
259
+ class="tw-text-error-500 tw-text-sm tw-mt-2"
260
+ >
261
+ {{ invalidUrlError }}
262
+ </p>
263
+ </div>
264
+ </div>
217
265
  </template>
218
266
  </ItemsField>
219
267
  <Button
@@ -229,32 +277,320 @@
229
277
  />
230
278
  </div>
231
279
  </template>
232
- <script>
233
- import { Button, TextInput, Icon } from '@designcrowd/fe-shared-lib';
234
- import TextImageFieldMixin from './TextImageField.mixin';
280
+ <script setup lang="ts">
281
+ import { ref, computed, watch, onMounted, type PropType } from 'vue';
282
+ import {
283
+ Button,
284
+ TextInput,
285
+ Icon,
286
+ ButtonGroup,
287
+ Toggle,
288
+ } from '@designcrowd/fe-shared-lib';
235
289
  import ImageField from '../image-field/ImageField.vue';
236
290
  import ItemsField from '../items-field/ItemsField.vue';
237
291
  import ColorReplacementsField from '../color-replacements-field/ColorReplacementsField.vue';
238
292
  import TextareaField from '../../../content-settings/components/textarea-field/TextareaField.vue';
293
+ import ButtonConfigurationField from '../button-configuration-field/ButtonConfigurationField.vue';
239
294
  import { textImageFieldTr } from '../../../../composables/useTranslate';
240
295
  import PersonalisationOverrideField from '../personalisation-override-field/PersonalisationOverrideField.vue';
296
+ import type {
297
+ ColorReplacement,
298
+ LogoTheme,
299
+ TextMediaItem,
300
+ TextShapeItem,
301
+ Content,
302
+ ImagesSectionContent,
303
+ } from '../../../../brand-page';
304
+ import {
305
+ MAX_DESCRIPTION_LENGTH,
306
+ MAX_LENGTH_ERROR_MESSAGE,
307
+ MAX_TITLE_LENGTH,
308
+ INVALID_URL_MESSAGE,
309
+ BRAND_PAGE_TYPES,
310
+ ALIGN_LEFT_ALIGNED,
311
+ ALIGN_RIGHT_ALIGNED,
312
+ CONTENT_TYPES,
313
+ MAX_IMAGES_SECTION_ALIGNMENT_ITEMS_LENGTH,
314
+ } from '../../../../brand-page';
315
+ import type { DebounceHandle } from 'lodash.debounce';
316
+ import debounce from 'lodash.debounce';
317
+ import type { UpdateItemValuePayload } from '../../models';
318
+ import cloneDeep from 'lodash.clonedeep';
319
+ import { isURL } from '../../../../utils/validator.util';
320
+
321
+ const DEBOUNCE_IN_MS = 250;
322
+
323
+ interface Props {
324
+ id: string;
325
+ name: string;
326
+ content: Content;
327
+ value: TextMediaItem[];
328
+ maxLength?: number;
329
+ logoTheme: LogoTheme;
330
+ settings: any;
331
+ isAdmin: boolean;
332
+ brandPageType?: string;
333
+ }
334
+
335
+ const props = withDefaults(defineProps<Props>(), {
336
+ maxLength: undefined,
337
+ brandPageType: BRAND_PAGE_TYPES.brandSite,
338
+ });
339
+
340
+ const emit = defineEmits<{
341
+ 'update:modelValue': [payload: UpdateItemValuePayload<TextMediaItem[]>];
342
+ 'on-intent-image-replace': [
343
+ payload: {
344
+ id: string;
345
+ name: string;
346
+ index: number;
347
+ value: string;
348
+ },
349
+ ];
350
+ }>();
351
+
352
+ const changeDebounce = ref<DebounceHandle | undefined>();
353
+ const options = ref<(TextMediaItem | TextShapeItem)[]>([]);
354
+ const maxLengthError = ref(MAX_LENGTH_ERROR_MESSAGE());
355
+ const invalidUrlError = ref(INVALID_URL_MESSAGE());
356
+ const titleLength = ref(MAX_TITLE_LENGTH);
357
+ const urlError = ref<Record<number, boolean>>({});
358
+ const mediaType = ref<string | undefined>();
359
+ const descriptionLength = ref(MAX_DESCRIPTION_LENGTH);
360
+ const maxItemsLength = ref(0);
361
+ const preservedButtonTexts = ref<Record<number, string>>({});
362
+ const preservedImageLinks = ref<Record<number, string>>({});
363
+
364
+ const items = computed(() => {
365
+ if (
366
+ props.maxLength &&
367
+ props.maxLength > 2 &&
368
+ props.content.type === CONTENT_TYPES['images-section']
369
+ ) {
370
+ const imagesSectionContent = props.content as ImagesSectionContent;
241
371
 
242
- export default {
243
- components: {
244
- Button,
245
- ItemsField,
246
- TextInput,
247
- ImageField,
248
- Icon,
249
- ColorReplacementsField,
250
- TextareaField,
251
- PersonalisationOverrideField,
372
+ if (
373
+ [ALIGN_LEFT_ALIGNED, ALIGN_RIGHT_ALIGNED].some(
374
+ (s) => imagesSectionContent.displayStyle === s,
375
+ )
376
+ ) {
377
+ setMaxLayoutLength(MAX_IMAGES_SECTION_ALIGNMENT_ITEMS_LENGTH);
378
+
379
+ return props.value.length > 3
380
+ ? props.value.slice(0, MAX_IMAGES_SECTION_ALIGNMENT_ITEMS_LENGTH)
381
+ : props.value;
382
+ }
383
+ }
384
+
385
+ if (props.maxLength) {
386
+ setMaxLayoutLength(props.maxLength);
387
+ }
388
+
389
+ return props.value;
390
+ });
391
+
392
+ const isShape = (item: TextMediaItem | TextShapeItem): boolean => {
393
+ return item.mediaType === 'shape';
394
+ };
395
+
396
+ const setMaxLayoutLength = (value: number) => {
397
+ maxItemsLength.value = value;
398
+ };
399
+
400
+ const onItemsDelete = (index: number) => {
401
+ options.value = options.value.filter((_o, i) => i !== index);
402
+
403
+ if (changeDebounce.value) {
404
+ changeDebounce.value();
405
+ }
406
+
407
+ const payload: UpdateItemValuePayload<TextMediaItem[]> = {
408
+ id: props.id,
409
+ name: props.name,
410
+ value: cloneDeep(options.value) as TextMediaItem[],
411
+ };
412
+
413
+ emit('update:modelValue', payload);
414
+ };
415
+
416
+ const onAddNewItem = () => {
417
+ addOption();
418
+ };
419
+
420
+ const addOption = (): void => {
421
+ options.value.push({
422
+ paragraph: '',
423
+ title: '',
424
+ imageUrl: '',
425
+ imageTitle: '',
426
+ height: -1,
427
+ width: -1,
428
+ mediaType: (mediaType.value as 'image' | 'shape') || 'image',
429
+ imageLink: false,
430
+ itemsId: -1,
431
+ buttonText: false,
432
+ pageSlug: '',
433
+ buttonLinkType: 'url',
434
+ url: '',
435
+ email: '',
436
+ tel: '',
437
+ });
438
+
439
+ if (changeDebounce.value) {
440
+ changeDebounce.value();
441
+ }
442
+ };
443
+
444
+ const emitChange = (): void => {
445
+ const payload: UpdateItemValuePayload<TextMediaItem[]> = {
446
+ id: props.id,
447
+ name: props.name,
448
+ value: options.value as TextMediaItem[],
449
+ };
450
+
451
+ emit('update:modelValue', payload);
452
+ };
453
+
454
+ const onItemsChange = (items: TextMediaItem[]) => {
455
+ options.value = items;
456
+
457
+ if (changeDebounce.value) {
458
+ changeDebounce.value();
459
+ }
460
+ };
461
+
462
+ const onReplaceImage = (index: number, imageUrl: string) => {
463
+ emit('on-intent-image-replace', {
464
+ id: props.id,
465
+ name: props.name,
466
+ index,
467
+ value: imageUrl,
468
+ });
469
+ };
470
+
471
+ const onRemoveImage = (index: number) => {
472
+ options.value[index].imageUrl = '';
473
+ (options.value[index] as TextShapeItem).colorReplacements =
474
+ [] as ColorReplacement[];
475
+ emitChange();
476
+ };
477
+
478
+ const onColorReplacementsChange = (
479
+ payload: UpdateItemValuePayload<ColorReplacement[]>,
480
+ index: number,
481
+ ) => {
482
+ (options.value[index] as TextShapeItem).colorReplacements = payload.value;
483
+ emitChange();
484
+ };
485
+
486
+ const onValueChange = (value: string, index: number) => {
487
+ if (!value.includes('https')) {
488
+ options.value[index].imageLink = `https://${value}`;
489
+ }
490
+
491
+ urlError.value[index] = isURL(value);
492
+ };
493
+
494
+ const checkUrl = (index: number) => {
495
+ return urlError.value[index] !== undefined ? urlError.value[index] : true;
496
+ };
497
+
498
+ const onTextAreaTextChange = (
499
+ payload: {
500
+ id: string;
501
+ name: string;
502
+ value: string;
252
503
  },
253
- mixins: [TextImageFieldMixin],
254
- setup() {
255
- return {
256
- textImageFieldTr,
257
- };
504
+ index: number,
505
+ ) => {
506
+ options.value[index].paragraph = payload.value;
507
+ };
508
+
509
+ const onPersonalisationOverrideChange = (
510
+ payload: {
511
+ id: string;
512
+ name: string;
513
+ value: string;
258
514
  },
515
+ index: number,
516
+ ) => {
517
+ (options.value[index] as any)[payload.name] = payload.value;
518
+ emitChange();
259
519
  };
520
+
521
+ const onButtonConfigUpdate = (buttonConfig: any, index: number): void => {
522
+ const currentOption = options.value[index];
523
+
524
+ if (
525
+ buttonConfig.buttonText === false &&
526
+ typeof currentOption.buttonText === 'string'
527
+ ) {
528
+ preservedButtonTexts.value[index] = currentOption.buttonText;
529
+ }
530
+
531
+ if (
532
+ buttonConfig.buttonText === '' &&
533
+ currentOption.buttonText === false &&
534
+ preservedButtonTexts.value[index]
535
+ ) {
536
+ buttonConfig.buttonText = preservedButtonTexts.value[index];
537
+ }
538
+
539
+ if (buttonConfig.buttonTextStyle) {
540
+ delete buttonConfig.buttonTextStyle;
541
+ }
542
+
543
+ Object.assign(currentOption, buttonConfig);
544
+ emitChange();
545
+ };
546
+
547
+ const onImageLinkToggleChange = (enabled: boolean, index: number): void => {
548
+ const currentOption = options.value[index];
549
+
550
+ if (enabled) {
551
+ if (preservedImageLinks.value[index]) {
552
+ options.value[index].imageLink = preservedImageLinks.value[index];
553
+ } else if (currentOption.imageLink === false) {
554
+ options.value[index].imageLink = '';
555
+ }
556
+ } else {
557
+ if (
558
+ typeof currentOption.imageLink === 'string' &&
559
+ currentOption.imageLink.trim() !== ''
560
+ ) {
561
+ preservedImageLinks.value[index] = currentOption.imageLink;
562
+ }
563
+ options.value[index].imageLink = false;
564
+ }
565
+ emitChange();
566
+ };
567
+
568
+ onMounted(() => {
569
+ options.value = cloneDeep(props.value);
570
+ mediaType.value = props.settings.replaceImageSettings.mediaType;
571
+ options.value = options.value.map((o) => ({
572
+ ...o,
573
+ mediaType: mediaType.value,
574
+ imageLink: o.imageLink !== undefined ? o.imageLink : false,
575
+ buttonText: o.buttonText !== undefined ? o.buttonText : false,
576
+ buttonLinkType: o.buttonLinkType || 'url',
577
+ url: o.url || '',
578
+ email: o.email || '',
579
+ tel: o.tel || '',
580
+ })) as (TextMediaItem | TextShapeItem)[];
581
+
582
+ if (!changeDebounce.value) {
583
+ changeDebounce.value = debounce(emitChange, DEBOUNCE_IN_MS);
584
+ }
585
+ });
586
+
587
+ watch(
588
+ options,
589
+ () => {
590
+ if (changeDebounce.value) {
591
+ changeDebounce.value();
592
+ }
593
+ },
594
+ { deep: true },
595
+ );
260
596
  </script>
@@ -4,13 +4,28 @@
4
4
  "shapeColor" : "Formfarbe",
5
5
  "imageCaptionPlaceholder" : "Bildunterschrift hinzufügen",
6
6
  "imageLink" : "Bildlink",
7
- "imageCaption" : "Bildunterschrift",
7
+ "imageCaption" : "Bild-Popup-Beschriftung",
8
+ "imageCaptionSub" : "Diese Bildunterschrift erscheint nur im Bild-Pop-up",
8
9
  "addTitlePlaceholder" : "Titel hinzufügen",
9
10
  "title" : "Titel",
10
11
  "addParagraphPlaceholder" : "Absatz hinzufügen",
11
12
  "paragraph" : "Absatz",
12
13
  "addItemLabel" : "Artikel hinzufügen",
13
14
  "image" : "Bild",
14
- "shape" : "Form"
15
+ "shape" : "Form",
16
+ "none" : "Keine",
17
+ "popup" : "Pop-up",
18
+ "openLink" : "Link öffnen",
19
+ "imageBehaviour" : "Bildverhalten",
20
+ "button" : "Schaltfläche",
21
+ "buttonText" : "Schaltflächentext",
22
+ "getStarted" : "Los geht’s",
23
+ "buttonLink" : "Schaltflächen-Link",
24
+ "url" : "URL",
25
+ "email" : "E-Mail-Adresse",
26
+ "telephone" : "Telefonnummer",
27
+ "buttonTextStyleLabel" : "Schaltflächentextstil",
28
+ "selectPage" : "Eine Seite auswählen",
29
+ "page" : "Seite"
15
30
  }
16
- }
31
+ }
@@ -4,13 +4,28 @@
4
4
  "shapeColor" : "Color de forma",
5
5
  "imageCaptionPlaceholder" : "Añade pie de foto",
6
6
  "imageLink" : "Enlace de imagen",
7
- "imageCaption" : "Pie de imagen",
7
+ "imageCaption" : "Pie de foto en ventana emergente",
8
+ "imageCaptionSub" : "Este pie de foto solo aparece en la ventana emergente de la imagen",
8
9
  "addTitlePlaceholder" : "Añadir título",
9
10
  "title" : "Título",
10
11
  "addParagraphPlaceholder" : "Añadir párrafo",
11
12
  "paragraph" : "Párrafo",
12
13
  "addItemLabel" : "Añadir artículo",
13
14
  "image" : "Imagen",
14
- "shape" : "Forma"
15
+ "shape" : "Forma",
16
+ "none" : "Ninguno",
17
+ "popup" : "Ventana emergente",
18
+ "openLink" : "Abrir enlace",
19
+ "imageBehaviour" : "Comportamiento de la imagen",
20
+ "button" : "Botón",
21
+ "buttonText" : "Texto del botón",
22
+ "getStarted" : "Comienza",
23
+ "buttonLink" : "Enlace de botón",
24
+ "url" : "URL",
25
+ "email" : "Dirección de correo electrónico",
26
+ "telephone" : "Número de teléfono",
27
+ "buttonTextStyleLabel" : "Estilo del texto del botón",
28
+ "selectPage" : "Selecciona una página",
29
+ "page" : "Página"
15
30
  }
16
- }
31
+ }
@@ -4,13 +4,28 @@
4
4
  "shapeColor" : "Couleur de forme",
5
5
  "imageCaptionPlaceholder" : "Ajouter une légende d'image",
6
6
  "imageLink" : "Lien d'image",
7
- "imageCaption" : "Légende d'image",
7
+ "imageCaption" : "Légende de l’image contextuelle",
8
+ "imageCaptionSub" : "Cette légende n'apparaît que dans la fenêtre contextuelle de l'image",
8
9
  "addTitlePlaceholder" : "Ajouter un titre",
9
10
  "title" : "Titre",
10
11
  "addParagraphPlaceholder" : "Ajouter un paragraphe",
11
12
  "paragraph" : "Paragraphe",
12
13
  "addItemLabel" : "Ajouter un élément",
13
14
  "image" : "Image",
14
- "shape" : "Forme"
15
+ "shape" : "Forme",
16
+ "none" : "Aucune",
17
+ "popup" : "Fenêtre contextuelle",
18
+ "openLink" : "Ouvrir le lien",
19
+ "imageBehaviour" : "Comportement de l’image",
20
+ "button" : "Bouton",
21
+ "buttonText" : "Texte du bouton",
22
+ "getStarted" : "Commencez",
23
+ "buttonLink" : "Lien de bouton",
24
+ "url" : "Url",
25
+ "email" : "Adresse courriel",
26
+ "telephone" : "Numéro de téléphone",
27
+ "buttonTextStyleLabel" : "Style de texte des boutons",
28
+ "selectPage" : "Sélectionnez une page",
29
+ "page" : "Page"
15
30
  }
16
- }
31
+ }