@capillarytech/creatives-library 9.0.36-alpha.0 → 9.0.37-alpha.0

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 (50) hide show
  1. package/package.json +1 -1
  2. package/translations/en.json +2 -2
  3. package/utils/permissions.js +59 -0
  4. package/utils/tests/permissions.test.js +116 -0
  5. package/v2Components/AccessForbidden/_accessForbidden.scss +14 -0
  6. package/v2Components/AccessForbidden/index.js +5 -3
  7. package/v2Components/AccessForbidden/messages.js +3 -2
  8. package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberPreviewContent.js +15 -108
  9. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +1 -139
  10. package/v2Components/CommonTestAndPreview/index.js +26 -240
  11. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/ViberPreviewContent.test.js +0 -364
  12. package/v2Components/NoPermissionWrapper/_noPermissionWrapper.scss +12 -0
  13. package/v2Components/NoPermissionWrapper/index.js +26 -0
  14. package/v2Containers/App/constants.js +5 -0
  15. package/v2Containers/Assets/Gallery/_gallery.scss +6 -0
  16. package/v2Containers/Assets/Gallery/index.js +34 -10
  17. package/v2Containers/Cap/index.js +5 -2
  18. package/v2Containers/Cap/messages.js +4 -0
  19. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +2 -2
  20. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +6 -6
  21. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +4 -4
  22. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +32 -32
  23. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +36 -36
  24. package/v2Containers/Rcs/carouselUtils.js +73 -46
  25. package/v2Containers/Rcs/components/CarouselCard.js +9 -6
  26. package/v2Containers/Rcs/constants.js +7 -2
  27. package/v2Containers/Rcs/index.js +126 -72
  28. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +43 -5
  29. package/v2Containers/Rcs/tests/CarouselCard.test.js +2 -1
  30. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +118 -118
  31. package/v2Containers/Rcs/tests/carouselUtils.test.js +15 -15
  32. package/v2Containers/Rcs/tests/index.test.js +232 -10
  33. package/v2Containers/Rcs/tests/utils.test.js +17 -0
  34. package/v2Containers/Rcs/utils.js +51 -12
  35. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +8 -8
  36. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +18 -18
  37. package/v2Containers/Templates/ChannelTypeIllustration.js +10 -1
  38. package/v2Containers/Templates/_templates.scss +6 -114
  39. package/v2Containers/Templates/index.js +151 -190
  40. package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +7 -0
  41. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +173 -120
  42. package/v2Containers/TemplatesV2/index.js +16 -5
  43. package/v2Containers/Viber/constants.js +0 -21
  44. package/v2Containers/Viber/index.js +49 -719
  45. package/v2Containers/Viber/index.scss +0 -175
  46. package/v2Containers/Viber/messages.js +0 -121
  47. package/v2Containers/Viber/tests/index.test.js +0 -80
  48. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +268 -268
  49. package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberCarouselPreviewCards.js +0 -132
  50. package/v2Components/CommonTestAndPreview/UnifiedPreview/_viberCarouselPreviewCards.scss +0 -131
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "9.0.36-alpha.0",
4
+ "version": "9.0.37-alpha.0",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -63,8 +63,8 @@
63
63
  "app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
64
64
  "app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
65
65
  "app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
66
- "creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
67
- "creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
66
+ "creatives.components.AccessForbidden.forbiddenDesc": "Please contact your organisation administrator to request access.",
67
+ "creatives.components.AccessForbidden.forbiddenHeader": "You don't have permission to view this page.",
68
68
  "creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
69
69
  "creatives.components.CapTagList.Cancel": "Cancel",
70
70
  "creatives.components.CapTagList.Ok": "Ok",
@@ -0,0 +1,59 @@
1
+ import {
2
+ CREATIVE_VIEW,
3
+ CREATIVE_CREATE,
4
+ CREATIVE_EDIT,
5
+ CREATIVE_DELETE,
6
+ CREATIVES_UI_VIEW,
7
+ } from '../v2Containers/App/constants';
8
+
9
+ export const PERMISSIONS = {
10
+ CREATIVE_VIEW,
11
+ CREATIVE_CREATE,
12
+ CREATIVE_EDIT,
13
+ CREATIVE_DELETE,
14
+ };
15
+
16
+ export const PERMISSION_IDS = {
17
+ [CREATIVE_VIEW]: 1508,
18
+ [CREATIVE_CREATE]: 1509,
19
+ [CREATIVE_EDIT]: 1510,
20
+ [CREATIVE_DELETE]: 1511,
21
+ };
22
+
23
+ /**
24
+ * Mode-aware access resolver for the tri-modal Creatives app.
25
+ * Standalone: the `cap` slice is passed as a prop by the connected container.
26
+ * Library / MFE: the host passes a `cap` (or legacy `Global`) prop.
27
+ * Reads the prop first, then falls back — mirrors TemplatesV2's existing
28
+ * `cap.user || Global.user` resolution.
29
+ */
30
+ export const getUserAccess = (props = {}) => {
31
+ const { cap = {}, Global = {} } = props;
32
+ const user = (cap && cap.user) || (Global && Global.user) || {};
33
+ const isLoaded = !!(
34
+ user &&
35
+ typeof user === 'object' &&
36
+ Object.keys(user).length > 0
37
+ );
38
+ return {
39
+ accessiblePermissions: (isLoaded && user.accessiblePermissions) || [],
40
+ isLoaded,
41
+ };
42
+ };
43
+
44
+ export const hasPermission = (userAccess, code) => {
45
+ if (!userAccess) return false;
46
+ const granted = userAccess.accessiblePermissions || [];
47
+ const id = PERMISSION_IDS[code];
48
+ return (
49
+ granted.includes(code) ||
50
+ granted.includes(id) ||
51
+ granted.includes(String(id))
52
+ );
53
+ };
54
+
55
+ // Zero-impact view gate: honour the new CREATIVE_VIEW OR the legacy CREATIVES_UI_VIEW.
56
+ export const canViewCreatives = userAccess =>
57
+ hasPermission(userAccess, CREATIVE_VIEW) ||
58
+ (userAccess &&
59
+ (userAccess.accessiblePermissions || []).includes(CREATIVES_UI_VIEW));
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Test suite for RBAC permission helpers (app/utils/permissions.js).
3
+ * Covers getUserAccess (loaded/unloaded, cap vs Global, missing perms),
4
+ * hasPermission (null guard, code/id/string-id match, empty), and
5
+ * canViewCreatives (new perm, legacy perm, null guard).
6
+ */
7
+ import {
8
+ PERMISSIONS,
9
+ PERMISSION_IDS,
10
+ getUserAccess,
11
+ hasPermission,
12
+ canViewCreatives,
13
+ } from '../permissions';
14
+ import {
15
+ CREATIVE_VIEW,
16
+ CREATIVE_CREATE,
17
+ CREATIVE_EDIT,
18
+ CREATIVE_DELETE,
19
+ CREATIVES_UI_VIEW,
20
+ } from '../../v2Containers/App/constants';
21
+
22
+ describe('permissions - exported maps', () => {
23
+ it('exposes the four creative permission codes', () => {
24
+ expect(PERMISSIONS).toEqual({
25
+ CREATIVE_VIEW,
26
+ CREATIVE_CREATE,
27
+ CREATIVE_EDIT,
28
+ CREATIVE_DELETE,
29
+ });
30
+ });
31
+
32
+ it('maps each permission code to its id', () => {
33
+ expect(PERMISSION_IDS[CREATIVE_VIEW]).toBe(1508);
34
+ expect(PERMISSION_IDS[CREATIVE_CREATE]).toBe(1509);
35
+ expect(PERMISSION_IDS[CREATIVE_EDIT]).toBe(1510);
36
+ expect(PERMISSION_IDS[CREATIVE_DELETE]).toBe(1511);
37
+ });
38
+ });
39
+
40
+ describe('getUserAccess', () => {
41
+ it('returns unloaded access with empty perms when no props are passed', () => {
42
+ expect(getUserAccess()).toEqual({ accessiblePermissions: [], isLoaded: false });
43
+ });
44
+
45
+ it('returns unloaded access for an empty props object', () => {
46
+ expect(getUserAccess({})).toEqual({ accessiblePermissions: [], isLoaded: false });
47
+ });
48
+
49
+ it('reads accessiblePermissions from cap.user when loaded', () => {
50
+ const result = getUserAccess({ cap: { user: { accessiblePermissions: [1508, 1509] } } });
51
+ expect(result).toEqual({ accessiblePermissions: [1508, 1509], isLoaded: true });
52
+ });
53
+
54
+ it('falls back to Global.user when cap.user is absent', () => {
55
+ const result = getUserAccess({ Global: { user: { accessiblePermissions: ['CREATIVE_VIEW'] } } });
56
+ expect(result).toEqual({ accessiblePermissions: ['CREATIVE_VIEW'], isLoaded: true });
57
+ });
58
+
59
+ it('is not loaded when the user object is empty', () => {
60
+ expect(getUserAccess({ cap: { user: {} } })).toEqual({ accessiblePermissions: [], isLoaded: false });
61
+ });
62
+
63
+ it('defaults accessiblePermissions to [] when a loaded user has none', () => {
64
+ const result = getUserAccess({ cap: { user: { id: 42 } } });
65
+ expect(result).toEqual({ accessiblePermissions: [], isLoaded: true });
66
+ });
67
+ });
68
+
69
+ describe('hasPermission', () => {
70
+ it('returns false when userAccess is null or undefined', () => {
71
+ expect(hasPermission(null, CREATIVE_VIEW)).toBe(false);
72
+ expect(hasPermission(undefined, CREATIVE_VIEW)).toBe(false);
73
+ });
74
+
75
+ it('returns false when accessiblePermissions is missing', () => {
76
+ expect(hasPermission({}, CREATIVE_VIEW)).toBe(false);
77
+ });
78
+
79
+ it('matches by permission code', () => {
80
+ expect(hasPermission({ accessiblePermissions: [CREATIVE_CREATE] }, CREATIVE_CREATE)).toBe(true);
81
+ });
82
+
83
+ it('matches by numeric permission id', () => {
84
+ expect(hasPermission({ accessiblePermissions: [1509] }, CREATIVE_CREATE)).toBe(true);
85
+ });
86
+
87
+ it('matches by string permission id', () => {
88
+ expect(hasPermission({ accessiblePermissions: ['1509'] }, CREATIVE_CREATE)).toBe(true);
89
+ });
90
+
91
+ it('returns false when the permission is not granted', () => {
92
+ expect(hasPermission({ accessiblePermissions: [CREATIVE_VIEW] }, CREATIVE_DELETE)).toBe(false);
93
+ expect(hasPermission({ accessiblePermissions: [] }, CREATIVE_VIEW)).toBe(false);
94
+ });
95
+ });
96
+
97
+ describe('canViewCreatives', () => {
98
+ it('allows when the new CREATIVE_VIEW permission is present', () => {
99
+ expect(canViewCreatives({ accessiblePermissions: [CREATIVE_VIEW] })).toBe(true);
100
+ expect(canViewCreatives({ accessiblePermissions: [1508] })).toBe(true);
101
+ });
102
+
103
+ it('allows via the legacy CREATIVES_UI_VIEW permission', () => {
104
+ expect(canViewCreatives({ accessiblePermissions: [CREATIVES_UI_VIEW] })).toBe(true);
105
+ });
106
+
107
+ it('returns a falsy value when userAccess is null', () => {
108
+ // short-circuits on `userAccess &&`, so returns null (falsy) rather than false
109
+ expect(canViewCreatives(null)).toBeFalsy();
110
+ });
111
+
112
+ it('returns false when neither view permission is present', () => {
113
+ expect(canViewCreatives({ accessiblePermissions: [CREATIVE_CREATE] })).toBe(false);
114
+ expect(canViewCreatives({})).toBe(false);
115
+ });
116
+ });
@@ -0,0 +1,14 @@
1
+ // Access-denied screen: rbac-lock icon + heading + subtext (matches the shared
2
+ // "no access" screen used across Loyalty+ / Org Settings).
3
+ .no-access-icon {
4
+ font-size: 48px;
5
+ color: #8c8c8c;
6
+ }
7
+ .no-access-title {
8
+ margin-top: 16px;
9
+ }
10
+ .no-access-text {
11
+ margin-top: 8px;
12
+ color: #6b778c;
13
+ max-width: 420px;
14
+ }
@@ -1,14 +1,16 @@
1
1
  import React from 'react';
2
2
  import { FormattedMessage } from 'react-intl';
3
- import { CapRow, CapHeading } from '@capillarytech/cap-ui-library';
3
+ import { CapRow, CapHeading, CapIcon } from '@capillarytech/cap-ui-library';
4
4
  import messages from './messages';
5
+ import './_accessForbidden.scss';
5
6
 
6
7
  const AccessForbidden = () => (
7
8
  <CapRow type='flex' vertical justify='center' align='middle' className="margin-t-32 text-align-center">
8
- <CapHeading type="h2">
9
+ <CapIcon type="rbac-lock" className="no-access-icon" />
10
+ <CapHeading type="h3" className="no-access-title">
9
11
  <FormattedMessage {...messages.forbiddenHeader} />
10
12
  </CapHeading>
11
- <CapHeading type="h3" className="margin-t-24">
13
+ <CapHeading type="h6" className="no-access-text">
12
14
  <FormattedMessage {...messages.forbiddenDesc} />
13
15
  </CapHeading>
14
16
  </CapRow>
@@ -5,10 +5,11 @@ const prefix = 'creatives.components.AccessForbidden';
5
5
  export default defineMessages({
6
6
  forbiddenHeader: {
7
7
  id: `${prefix}.forbiddenHeader`,
8
- defaultMessage: 'Access Forbidden',
8
+ defaultMessage: "You don't have permission to view this page.",
9
9
  },
10
10
  forbiddenDesc: {
11
11
  id: `${prefix}.forbiddenDesc`,
12
- defaultMessage: 'This page access has not been provided to you.',
12
+ defaultMessage:
13
+ 'Please contact your organisation administrator to request access.',
13
14
  },
14
15
  });
@@ -14,25 +14,14 @@ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
14
14
  import CapImage from '@capillarytech/cap-ui-library/CapImage';
15
15
  import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
16
16
  import CapRow from '@capillarytech/cap-ui-library/CapRow';
17
- import {
18
- ANDROID,
19
- IOS,
20
- ANDROID_DEVICE_NAME,
21
- IOS_DEVICE_NAME,
22
- VIBER_ACCOUNT_NAME,
23
- MEDIA_TYPE_CAROUSEL,
24
- } from '../constants';
17
+ import { ANDROID, IOS, ANDROID_DEVICE_NAME, IOS_DEVICE_NAME, VIBER_ACCOUNT_NAME } from '../constants';
25
18
  import messages from '../messages';
26
19
  import videoPlay from '../../../assets/videoPlay.svg';
27
- import ViberCarouselPreviewCards from './ViberCarouselPreviewCards';
28
20
 
29
21
  // Import device mockup images (same as SMS)
30
22
  const smsMobileAndroid = require('../../../assets/Android.png');
31
23
  const smsMobileIos = require('../../../assets/iOS.png');
32
24
 
33
- const getTrimmedText = (value = '') => (value ?? '').trim();
34
- const hasTrimmedText = (value = '') => Boolean(getTrimmedText(value));
35
-
36
25
  const ViberPreviewContent = ({
37
26
  content,
38
27
  device,
@@ -54,35 +43,7 @@ const ViberPreviewContent = ({
54
43
  imageURL = '',
55
44
  videoParams = {},
56
45
  buttonText = '',
57
- type = '',
58
- cards = [],
59
- showCarouselEditorPreview = false,
60
46
  } = viberContent;
61
- const hasCarouselContent = type === MEDIA_TYPE_CAROUSEL;
62
-
63
- const cardHasMeaningfulContent = (card) => {
64
- if (!card || typeof card !== 'object') return false;
65
- return (
66
- hasTrimmedText(card?.text) ||
67
- hasTrimmedText(card?.mediaUrl) ||
68
- (card.buttons ?? []).some(button => hasTrimmedText(button?.title))
69
- );
70
- };
71
-
72
- const hasMeaningfulCarousel =
73
- hasCarouselContent &&
74
- Array.isArray(cards) &&
75
- cards.length > 0 &&
76
- cards.some(cardHasMeaningfulContent);
77
-
78
- const showCarouselInPreview =
79
- hasCarouselContent && (Boolean(showCarouselEditorPreview) || hasMeaningfulCarousel);
80
-
81
- const previewCarouselCards =
82
- hasCarouselContent && Array.isArray(cards) && cards.length ? cards : hasCarouselContent ? [{}] : [];
83
-
84
- const trimmedMessageContent = getTrimmedText(messageContent);
85
- const trimmedButtonText = getTrimmedText(buttonText);
86
47
 
87
48
  // Get account name (first letter for icon)
88
49
  const accountIcon = (accountName || brandName || 'V')[0]?.toUpperCase();
@@ -138,15 +99,8 @@ const ViberPreviewContent = ({
138
99
  );
139
100
  }
140
101
 
141
- // Check if there's any content to display (whitespace-only strings do not count)
142
- const hasContent = Boolean(
143
- trimmedMessageContent
144
- || hasTrimmedText(imageURL)
145
- || videoParams?.viberVideoSrc
146
- || trimmedButtonText
147
- || hasMeaningfulCarousel
148
- || (hasCarouselContent && showCarouselEditorPreview)
149
- );
102
+ // Check if there's any content to display
103
+ const hasContent = messageContent || imageURL || videoParams?.viberVideoSrc || buttonText;
150
104
 
151
105
  // Render normal Viber preview
152
106
  return (
@@ -171,34 +125,23 @@ const ViberPreviewContent = ({
171
125
 
172
126
  {/* Viber Message Container */}
173
127
  {hasContent && (
174
- <CapRow className={`viber-message-container ${showCarouselInPreview ? 'viber-message-container-carousel' : ''} ${device !== ANDROID ? 'viber-message-container-ios' : ''}`}>
128
+ <CapRow className={`viber-message-container ${device !== ANDROID ? 'viber-message-container-ios' : ''}`}>
175
129
  {/* Brand Name Display (from TemplatePreview line 1136) */}
176
- <CapRow
177
- type="flex"
178
- align="middle"
179
- fullWidth={showCarouselInPreview}
180
- className={`msg-container viber-preview ${showCarouselInPreview ? 'viber-preview-carousel' : ''}`}
181
- >
130
+ <CapRow type="flex" align="middle" className="msg-container viber-preview">
182
131
  {/* Account Icon (from TemplatePreview line 1146-1160) */}
183
- {!hasCarouselContent && (
184
- <CapRow type="flex" className="viber-account-icon">
185
- {accountIcon}
186
- </CapRow>
187
- )}
132
+ <CapRow type='flex' className="viber-account-icon">
133
+ {accountIcon}
134
+ </CapRow>
188
135
 
189
136
  {/* Message Bubble (from TemplatePreview line 1161-1223) */}
190
- <CapRow
191
- useLegacy
192
- fullWidth={showCarouselInPreview}
193
- className={`message-pop align-left viber-message-pop ${showCarouselInPreview ? 'viber-message-pop-carousel' : ''}`}
194
- >
137
+ <CapRow useLegacy className="message-pop align-left viber-message-pop">
195
138
  {/* Text Viber preview */}
196
- {trimmedMessageContent && !hasCarouselContent && (
139
+ {messageContent && (
197
140
  <CapLabel type="label15" className="viber-message-text">{messageContent}</CapLabel>
198
141
  )}
199
142
 
200
143
  {/* Image Viber preview */}
201
- {hasTrimmedText(imageURL) && (
144
+ {imageURL && (
202
145
  <CapImage
203
146
  src={imageURL}
204
147
  className="viber-image-preview"
@@ -228,42 +171,16 @@ const ViberPreviewContent = ({
228
171
  )}
229
172
 
230
173
  {/* Button Viber preview */}
231
- {trimmedButtonText && (
174
+ {buttonText && (
232
175
  <CapLabel className="viber-button-base">
233
176
  <p className="viber-button-card-text">
234
177
  {buttonText}
235
178
  </p>
236
179
  </CapLabel>
237
180
  )}
238
- {/* Carousel Viber preview */}
239
- {showCarouselInPreview && (
240
- <CapRow type="flex-column" fullWidth className="viber-carousel-preview">
241
- <CapRow type="flex-column" className="viber-carousel-message-pop">
242
- {trimmedMessageContent ? (
243
- <CapLabel
244
- type="label15"
245
- className="message-pop-item align-left viber-message-text viber-carousel-message-box-text"
246
- >
247
- {messageContent}
248
- </CapLabel>
249
- ) : (
250
- <CapRow className="viber-carousel-message-box-placeholder" />
251
- )}
252
- <CapLabel type="label1" className="viber-carousel-message-timestamp">
253
- {timestamp}
254
- </CapLabel>
255
- </CapRow>
256
-
257
- <CapRow type="flex-column" fullWidth className="viber-carousel-cards-pop">
258
- <ViberCarouselPreviewCards cards={previewCarouselCards} />
259
- </CapRow>
260
- </CapRow>
261
- )}
262
- {!showCarouselInPreview && (
263
- <CapLabel type="label1" className="viber-timestamp">
264
- {timestamp}
265
- </CapLabel>
266
- )}
181
+ <CapLabel type="label1" className="viber-timestamp">
182
+ {timestamp}
183
+ </CapLabel>
267
184
  <CapRow useLegacy className="empty-placeholder" />
268
185
  </CapRow>
269
186
 
@@ -297,16 +214,6 @@ ViberPreviewContent.propTypes = {
297
214
  viberVideoPreviewImg: PropTypes.string,
298
215
  }),
299
216
  buttonText: PropTypes.string,
300
- type: PropTypes.string,
301
- cards: PropTypes.arrayOf(PropTypes.shape({
302
- text: PropTypes.string,
303
- mediaUrl: PropTypes.string,
304
- buttons: PropTypes.arrayOf(PropTypes.shape({
305
- title: PropTypes.string,
306
- action: PropTypes.string,
307
- })),
308
- })),
309
- showCarouselEditorPreview: PropTypes.bool,
310
217
  }),
311
218
  }),
312
219
  device: PropTypes.oneOf([ANDROID, IOS]),
@@ -1,5 +1,4 @@
1
1
  @import '~@capillarytech/cap-ui-library/styles/_variables';
2
- @import './_viberCarouselPreviewCards.scss';
3
2
 
4
3
  /**
5
4
  * UnifiedPreview Styles
@@ -783,13 +782,9 @@
783
782
 
784
783
  .viber-content-overlay {
785
784
  top: 3.2rem;
786
- overflow: hidden;
787
-
788
- .sms-navigation-bar.viber-navigation-bar {
789
- width: calc(100% - #{$CAP_SPACE_06} - #{$CAP_SPACE_08});
785
+ .viber-navigation-bar {
790
786
  margin-left: $CAP_SPACE_06;
791
787
  margin-right: $CAP_SPACE_08;
792
- box-sizing: border-box;
793
788
  }
794
789
  }
795
790
 
@@ -2412,21 +2407,12 @@
2412
2407
  // Body content follows TemplatePreview Viber structure
2413
2408
  .sms-content-overlay {
2414
2409
  &.viber-preview {
2415
- overflow: hidden;
2416
-
2417
2410
  // Viber message container
2418
2411
  .viber-message-container {
2419
2412
  position: relative;
2420
2413
  flex: 1;
2421
2414
  display: flex;
2422
2415
  flex-direction: column;
2423
- overflow-x: hidden;
2424
- overflow-y: auto;
2425
- -webkit-overflow-scrolling: touch;
2426
- min-width: 0;
2427
- max-width: 100%;
2428
- box-sizing: border-box;
2429
- width: calc(100% - #{$CAP_SPACE_06} - #{$CAP_SPACE_08});
2430
2416
  padding: 0 $CAP_SPACE_16;
2431
2417
  background-color: #ffffff;
2432
2418
  margin-left: $CAP_SPACE_06;
@@ -2434,20 +2420,6 @@
2434
2420
  border-bottom-left-radius: 2.6rem;
2435
2421
  border-bottom-right-radius: 2.6rem;
2436
2422
 
2437
- &.viber-message-container-carousel {
2438
- padding-left: $CAP_SPACE_08;
2439
- padding-right: $CAP_SPACE_08;
2440
- width: calc(100% - #{$CAP_SPACE_04} - #{$CAP_SPACE_04});
2441
- margin-left: $CAP_SPACE_04;
2442
- margin-right: $CAP_SPACE_04;
2443
-
2444
- > .ant-row,
2445
- .ant-row.msg-container.viber-preview-carousel {
2446
- margin-left: 0;
2447
- margin-right: 0;
2448
- }
2449
- }
2450
-
2451
2423
  // Brand name display (from TemplatePreview line 1136)
2452
2424
  .viber-brand-name {
2453
2425
  position: absolute;
@@ -2469,16 +2441,6 @@
2469
2441
  flex-direction: row;
2470
2442
  align-items: start;
2471
2443
 
2472
- &.viber-preview-carousel {
2473
- width: 100%;
2474
- max-width: 100%;
2475
- margin-left: 0;
2476
- margin-right: 0;
2477
- max-height: 100%;
2478
- min-width: 0;
2479
- box-sizing: border-box;
2480
- }
2481
-
2482
2444
  // Account icon (from TemplatePreview line 1146-1160)
2483
2445
  .viber-account-icon {
2484
2446
  width: $CAP_SPACE_20;
@@ -2503,22 +2465,6 @@
2503
2465
  border-radius: $CAP_SPACE_04;
2504
2466
  padding: $CAP_SPACE_04;
2505
2467
 
2506
- &.viber-message-pop-carousel {
2507
- width: 100%;
2508
- max-width: 100%;
2509
- min-width: 0;
2510
- left: 0;
2511
- margin-top: 0;
2512
- padding: 0;
2513
- background: transparent;
2514
- display: flex;
2515
- flex-direction: column;
2516
- align-items: flex-start;
2517
- gap: $CAP_SPACE_06;
2518
- overflow: hidden;
2519
- box-sizing: border-box;
2520
- }
2521
-
2522
2468
  // Text Viber preview (from TemplatePreview line 1166-1174)
2523
2469
  .viber-message-text {
2524
2470
  margin: 0.107rem $CAP_SPACE_06 $CAP_SPACE_01 0.5rem;
@@ -2590,85 +2536,6 @@
2590
2536
  }
2591
2537
  }
2592
2538
 
2593
- .viber-carousel-preview {
2594
- width: 100%;
2595
- max-width: 100%;
2596
- min-width: 0;
2597
- display: flex;
2598
- flex-direction: column;
2599
- align-items: flex-start;
2600
- gap: $CAP_SPACE_06;
2601
- overflow: hidden;
2602
- box-sizing: border-box;
2603
- }
2604
-
2605
- .viber-carousel-message-pop,
2606
- .viber-carousel-cards-pop {
2607
- width: 100%;
2608
- max-width: 100%;
2609
- min-width: 0;
2610
- background: $CAP_G08;
2611
- border-radius: $CAP_SPACE_06;
2612
- padding: $CAP_SPACE_08;
2613
- box-sizing: border-box;
2614
- }
2615
-
2616
- .viber-carousel-message-pop {
2617
- margin-top: 0;
2618
- width: 85%;
2619
- border-radius: 0 $CAP_SPACE_06 $CAP_SPACE_06 $CAP_SPACE_06;
2620
- display: flex;
2621
- flex-direction: column;
2622
- overflow: hidden;
2623
- }
2624
-
2625
- .viber-carousel-cards-pop {
2626
- margin-top: 0;
2627
- width: 100%;
2628
- background: transparent;
2629
- border: none;
2630
- border-radius: 0;
2631
- padding: 0;
2632
- overflow: hidden;
2633
- }
2634
-
2635
- .viber-carousel-message-box {
2636
- width: 100%;
2637
- min-height: 2.25rem;
2638
- height: auto;
2639
- border-radius: $CAP_SPACE_04;
2640
- background: transparent;
2641
- padding: 0 $CAP_SPACE_08;
2642
- display: flex;
2643
- align-items: center;
2644
- }
2645
-
2646
- .viber-carousel-message-box-text {
2647
- color: $CAP_G01;
2648
- margin: 0.107rem $CAP_SPACE_06 $CAP_SPACE_01 0.5rem;
2649
- white-space: normal;
2650
- word-break: break-word;
2651
- overflow-wrap: break-word;
2652
- overflow: hidden;
2653
- max-width: 100%;
2654
- box-sizing: border-box;
2655
- }
2656
-
2657
- .viber-carousel-message-box-placeholder {
2658
- width: 100%;
2659
- height: 0.875rem;
2660
- border-radius: $CAP_SPACE_04;
2661
- background: $CAP_G07;
2662
- }
2663
-
2664
- .viber-carousel-message-timestamp,
2665
- .viber-carousel-cards-timestamp {
2666
- display: block;
2667
- text-align: right;
2668
- margin-top: $CAP_SPACE_06;
2669
- color: $CAP_G04;
2670
- }
2671
-
2672
2539
  .empty-placeholder {
2673
2540
  height: $CAP_SPACE_08;
2674
2541
  }
@@ -2682,11 +2549,6 @@
2682
2549
  .viber-message-container-ios {
2683
2550
  margin-left: 1rem;
2684
2551
  margin-right: 1rem;
2685
-
2686
- &.viber-message-container-carousel {
2687
- margin-left: $CAP_SPACE_04;
2688
- margin-right: $CAP_SPACE_04;
2689
- }
2690
2552
  }
2691
2553
  }
2692
2554
  }