@capillarytech/creatives-library 8.0.340-beta.0.4 → 8.0.340-beta.0.6
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/constants/unified.js +1 -0
- package/package.json +1 -1
- package/services/api.js +20 -0
- package/services/tests/api.test.js +59 -0
- package/utils/common.js +6 -0
- package/utils/test-utils.js +2 -2
- package/utils/tests/v2Common.test.js +46 -1
- package/utils/v2common.js +18 -0
- package/v2Components/CapTagList/index.js +5 -6
- package/v2Components/CapTagListWithInput/index.js +1 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/WhatsAppPreviewContent.js +18 -6
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +27 -0
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/WhatsAppPreviewContent.test.js +48 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +22 -1
- package/v2Components/TemplatePreview/index.js +21 -9
- package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +1 -0
- package/v2Containers/Assets/images/archive_Empty_Illustration.svg +9 -0
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +28 -20
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +24 -16
- package/v2Containers/CreativesContainer/SlideBoxContent.js +16 -5
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -1
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -4
- package/v2Containers/CreativesContainer/index.js +14 -1
- package/v2Containers/CreativesContainer/messages.js +4 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +2 -4
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +4 -4
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +3 -0
- package/v2Containers/Email/reducer.js +12 -3
- package/v2Containers/Email/sagas.js +9 -4
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +4 -0
- package/v2Containers/Email/tests/reducer.test.js +47 -0
- package/v2Containers/Email/tests/sagas.test.js +146 -6
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +8 -1
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +7 -0
- package/v2Containers/MobilePush/Create/index.js +1 -1
- package/v2Containers/MobilePush/Edit/index.js +1 -1
- package/v2Containers/Sms/Create/index.js +3 -0
- package/v2Containers/Sms/SCHEMA_FORMBUILDER_MAP.md +1 -1
- package/v2Containers/Templates/ChannelTypeIllustration.js +23 -6
- package/v2Containers/Templates/_templates.scss +155 -24
- package/v2Containers/Templates/actions.js +44 -0
- package/v2Containers/Templates/constants.js +31 -0
- package/v2Containers/Templates/index.js +400 -59
- package/v2Containers/Templates/messages.js +96 -0
- package/v2Containers/Templates/reducer.js +84 -1
- package/v2Containers/Templates/sagas.js +64 -0
- package/v2Containers/Templates/selectors.js +12 -0
- package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +12 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1166 -1112
- package/v2Containers/Templates/tests/index.test.js +6 -0
- package/v2Containers/Templates/tests/reducer.test.js +178 -0
- package/v2Containers/Templates/tests/sagas.test.js +390 -8
- package/v2Containers/Templates/tests/selector.test.js +32 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -1
- package/v2Containers/Viber/constants.js +8 -0
- package/v2Containers/Viber/index.js +5 -0
- package/v2Containers/Viber/messages.js +4 -0
- package/v2Containers/Viber/reducer.js +26 -3
- package/v2Containers/Viber/sagas.js +50 -8
- package/v2Containers/Viber/tests/index.test.js +80 -0
- package/v2Containers/Viber/tests/reducer.test.js +297 -0
- package/v2Containers/Viber/tests/saga.test.js +412 -40
- package/v2Containers/Whatsapp/constants.js +8 -0
- package/v2Containers/Whatsapp/index.js +145 -5
- package/v2Containers/Whatsapp/index.scss +12 -0
- package/v2Containers/Whatsapp/messages.js +16 -0
|
@@ -16,6 +16,53 @@ describe('emailReducer', () => {
|
|
|
16
16
|
expect(emailReducer(undefined, action)).toMatchSnapshot();
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — sets isBeeEnabled true and CmsSettings', () => {
|
|
20
|
+
const initialState = fromJS({ isBeeEnabled: null, fetchingCmsSettings: true });
|
|
21
|
+
const action = {
|
|
22
|
+
type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
|
|
23
|
+
isBeeEnabled: true,
|
|
24
|
+
settings: { isDragDrop: true, editorType: 'bee' },
|
|
25
|
+
};
|
|
26
|
+
const result = emailReducer(initialState, action);
|
|
27
|
+
expect(result.get('fetchingCmsSettings')).toBe(false);
|
|
28
|
+
expect(result.get('isBeeEnabled')).toBe(true);
|
|
29
|
+
expect(result.getIn(['CmsSettings', 'isDragDrop'])).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — sets isBeeEnabled false', () => {
|
|
33
|
+
const initialState = fromJS({ isBeeEnabled: true, fetchingCmsSettings: true });
|
|
34
|
+
const action = {
|
|
35
|
+
type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
|
|
36
|
+
isBeeEnabled: false,
|
|
37
|
+
settings: {},
|
|
38
|
+
};
|
|
39
|
+
const result = emailReducer(initialState, action);
|
|
40
|
+
expect(result.get('fetchingCmsSettings')).toBe(false);
|
|
41
|
+
expect(result.get('isBeeEnabled')).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — overwrites stale isBeeEnabled from CLEAR_ALL_VALUES (null)', () => {
|
|
45
|
+
const initialState = fromJS({ isBeeEnabled: null, fetchingCmsSettings: true });
|
|
46
|
+
const action = {
|
|
47
|
+
type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
|
|
48
|
+
isBeeEnabled: true,
|
|
49
|
+
settings: { type: 'bee' },
|
|
50
|
+
};
|
|
51
|
+
const result = emailReducer(initialState, action);
|
|
52
|
+
expect(result.get('isBeeEnabled')).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — sets CmsSettings to empty object when settings is {}', () => {
|
|
56
|
+
const initialState = fromJS({ CmsSettings: { old: 'data' } });
|
|
57
|
+
const action = {
|
|
58
|
+
type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
|
|
59
|
+
isBeeEnabled: false,
|
|
60
|
+
settings: {},
|
|
61
|
+
};
|
|
62
|
+
const result = emailReducer(initialState, action);
|
|
63
|
+
expect(result.get('CmsSettings').toJS()).toEqual({});
|
|
64
|
+
});
|
|
65
|
+
|
|
19
66
|
it.concurrent('it handles GET_CMS_ACCOUNTS_REQUEST action (line 111-113)', () => {
|
|
20
67
|
const initialState = fromJS({
|
|
21
68
|
isBeeEnabled: true, // Start with true to verify it gets set to false
|
|
@@ -3,6 +3,7 @@ import { expectSaga } from 'redux-saga-test-plan';
|
|
|
3
3
|
import { takeLatest } from 'redux-saga/effects';
|
|
4
4
|
import * as matchers from 'redux-saga-test-plan/matchers';
|
|
5
5
|
import { throwError } from 'redux-saga-test-plan/providers';
|
|
6
|
+
import { fromJS } from 'immutable';
|
|
6
7
|
import * as types from '../constants';
|
|
7
8
|
import * as sagas from '../sagas';
|
|
8
9
|
import { v2EmailDuplicateTemplateSaga, v2EmailSagas } from '../sagas';
|
|
@@ -709,10 +710,14 @@ describe('getCmsSetting saga', () => {
|
|
|
709
710
|
|
|
710
711
|
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
711
712
|
.provide([
|
|
713
|
+
{
|
|
714
|
+
select(effect, next) {
|
|
715
|
+
return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: true });
|
|
716
|
+
},
|
|
717
|
+
},
|
|
712
718
|
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
713
719
|
])
|
|
714
|
-
.put({ type: types.
|
|
715
|
-
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails })
|
|
720
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails, isBeeEnabled: true })
|
|
716
721
|
.run();
|
|
717
722
|
});
|
|
718
723
|
|
|
@@ -727,10 +732,14 @@ describe('getCmsSetting saga', () => {
|
|
|
727
732
|
|
|
728
733
|
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
729
734
|
.provide([
|
|
735
|
+
{
|
|
736
|
+
select(effect, next) {
|
|
737
|
+
return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: false });
|
|
738
|
+
},
|
|
739
|
+
},
|
|
730
740
|
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
731
741
|
])
|
|
732
|
-
.put({ type: types.
|
|
733
|
-
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails })
|
|
742
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails, isBeeEnabled: false })
|
|
734
743
|
.run();
|
|
735
744
|
});
|
|
736
745
|
|
|
@@ -743,10 +752,14 @@ describe('getCmsSetting saga', () => {
|
|
|
743
752
|
|
|
744
753
|
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
745
754
|
.provide([
|
|
755
|
+
{
|
|
756
|
+
select(effect, next) {
|
|
757
|
+
return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: false });
|
|
758
|
+
},
|
|
759
|
+
},
|
|
746
760
|
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
747
761
|
])
|
|
748
|
-
.put({ type: types.
|
|
749
|
-
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: undefined })
|
|
762
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: {}, isBeeEnabled: false })
|
|
750
763
|
.run();
|
|
751
764
|
});
|
|
752
765
|
|
|
@@ -755,11 +768,138 @@ describe('getCmsSetting saga', () => {
|
|
|
755
768
|
|
|
756
769
|
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
757
770
|
.provide([
|
|
771
|
+
{
|
|
772
|
+
select(effect, next) {
|
|
773
|
+
return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: true });
|
|
774
|
+
},
|
|
775
|
+
},
|
|
758
776
|
[matchers.call.fn(Api.getCmsTemplateSettingsV2), throwError(fakeError)],
|
|
759
777
|
])
|
|
760
778
|
.put({ type: types.GET_CMS_EDITOR_DETAILS_FAILURE, error: fakeError })
|
|
761
779
|
.run();
|
|
762
780
|
});
|
|
781
|
+
|
|
782
|
+
it('should wait for accounts when fetchingCmsAccounts is true and cmsAccountsLoaded is false (accounts succeed)', () => {
|
|
783
|
+
const fakeResponse = {
|
|
784
|
+
data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
|
|
785
|
+
};
|
|
786
|
+
let selectCallCount = 0;
|
|
787
|
+
|
|
788
|
+
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
789
|
+
.provide([
|
|
790
|
+
{
|
|
791
|
+
select(effect, next) {
|
|
792
|
+
selectCallCount += 1;
|
|
793
|
+
if (selectCallCount === 1) {
|
|
794
|
+
return fromJS({ cmsAccountsLoaded: false, fetchingCmsAccounts: true, isBeeEnabled: null });
|
|
795
|
+
}
|
|
796
|
+
return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: true });
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
800
|
+
])
|
|
801
|
+
.dispatch({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled: true })
|
|
802
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
|
|
803
|
+
.run();
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
it('should wait for accounts when fetchingCmsAccounts is true and cmsAccountsLoaded is false (accounts fail)', () => {
|
|
807
|
+
const fakeResponse = {
|
|
808
|
+
data: { response: { cmsDetails: { type: 'ck', settings: {} } } },
|
|
809
|
+
};
|
|
810
|
+
let selectCallCount = 0;
|
|
811
|
+
|
|
812
|
+
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
813
|
+
.provide([
|
|
814
|
+
{
|
|
815
|
+
select(effect, next) {
|
|
816
|
+
selectCallCount += 1;
|
|
817
|
+
if (selectCallCount === 1) {
|
|
818
|
+
return fromJS({ cmsAccountsLoaded: false, fetchingCmsAccounts: true, isBeeEnabled: null });
|
|
819
|
+
}
|
|
820
|
+
return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: false });
|
|
821
|
+
},
|
|
822
|
+
},
|
|
823
|
+
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
824
|
+
])
|
|
825
|
+
.dispatch({ type: types.GET_CMS_ACCOUNTS_FAILURE })
|
|
826
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'ck', settings: {} }, isBeeEnabled: false })
|
|
827
|
+
.run();
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it('should skip wait and use isBEEAppEnableFromAction as fallback when cmsAccountsLoaded is false but fetchingCmsAccounts is false', () => {
|
|
831
|
+
const fakeResponse = {
|
|
832
|
+
data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
return expectSaga(sagas.getCmsSetting, { ...basePayload, isBEEAppEnable: true })
|
|
836
|
+
.provide([
|
|
837
|
+
{
|
|
838
|
+
select(effect, next) {
|
|
839
|
+
return fromJS({ cmsAccountsLoaded: false, fetchingCmsAccounts: false, isBeeEnabled: null });
|
|
840
|
+
},
|
|
841
|
+
},
|
|
842
|
+
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
843
|
+
])
|
|
844
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
|
|
845
|
+
.run();
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
it('should use state isBeeEnabled (null) and fall back to isBEEAppEnableFromAction via ?? operator', () => {
|
|
849
|
+
const fakeResponse = {
|
|
850
|
+
data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
return expectSaga(sagas.getCmsSetting, { ...basePayload, isBEEAppEnable: true })
|
|
854
|
+
.provide([
|
|
855
|
+
{
|
|
856
|
+
select(effect, next) {
|
|
857
|
+
return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: null });
|
|
858
|
+
},
|
|
859
|
+
},
|
|
860
|
+
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
861
|
+
])
|
|
862
|
+
.call(Api.getCmsTemplateSettingsV2, basePayload.cmsType, basePayload.projectId, basePayload.cmsMode, basePayload.langId, basePayload.isEdmSupport, true)
|
|
863
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
|
|
864
|
+
.run();
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
it('should use state isBeeEnabled false over isBEEAppEnableFromAction true via ?? operator (false is not null/undefined)', () => {
|
|
868
|
+
const fakeResponse = {
|
|
869
|
+
data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
return expectSaga(sagas.getCmsSetting, { ...basePayload, isBEEAppEnable: true })
|
|
873
|
+
.provide([
|
|
874
|
+
{
|
|
875
|
+
select(effect, next) {
|
|
876
|
+
return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: false });
|
|
877
|
+
},
|
|
878
|
+
},
|
|
879
|
+
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
880
|
+
])
|
|
881
|
+
.call(Api.getCmsTemplateSettingsV2, basePayload.cmsType, basePayload.projectId, basePayload.cmsMode, basePayload.langId, basePayload.isEdmSupport, false)
|
|
882
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
|
|
883
|
+
.run();
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
it('should derive isBeeEnabled false when cmsDetails type is undefined', () => {
|
|
887
|
+
const fakeResponse = {
|
|
888
|
+
data: { response: { cmsDetails: { settings: {} } } },
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
return expectSaga(sagas.getCmsSetting, basePayload)
|
|
892
|
+
.provide([
|
|
893
|
+
{
|
|
894
|
+
select(effect, next) {
|
|
895
|
+
return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: true });
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
[matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
|
|
899
|
+
])
|
|
900
|
+
.put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { settings: {} }, isBeeEnabled: false })
|
|
901
|
+
.run();
|
|
902
|
+
});
|
|
763
903
|
});
|
|
764
904
|
|
|
765
905
|
|
|
@@ -102,6 +102,10 @@ const useEmailWrapper = ({
|
|
|
102
102
|
}
|
|
103
103
|
}, [onEnterTemplateName, onRemoveTemplateName]);
|
|
104
104
|
|
|
105
|
+
useEffect(() => () => {
|
|
106
|
+
emailActions.clearStoreValues();
|
|
107
|
+
}, []);
|
|
108
|
+
|
|
105
109
|
// Check BEE enabled status from API response
|
|
106
110
|
// BEE is enabled if isDragDrop is true in the API response
|
|
107
111
|
// This should work for both full mode and library mode
|
|
@@ -708,7 +712,10 @@ const useEmailWrapper = ({
|
|
|
708
712
|
} else if (location?.pathname?.includes('/edit/')) {
|
|
709
713
|
// Extract id from pathname if it's in the format /edit/:id
|
|
710
714
|
const match = location.pathname.match(/\/edit\/([^/]+)/);
|
|
711
|
-
|
|
715
|
+
// Reject sentinel strings that come from unguarded template literals
|
|
716
|
+
// (e.g. `/edit/${maybeUndefined}` → "/edit/undefined"), so they don't
|
|
717
|
+
// get treated as real template ids downstream.
|
|
718
|
+
if (match && match[1] && match[1] !== 'undefined' && match[1] !== 'null') {
|
|
712
719
|
emailParams.id = match[1];
|
|
713
720
|
}
|
|
714
721
|
}
|
|
@@ -79,6 +79,12 @@ describe('useEmailWrapper', () => {
|
|
|
79
79
|
setEdmTemplate: jest.fn(),
|
|
80
80
|
setBEETemplate: jest.fn(),
|
|
81
81
|
},
|
|
82
|
+
emailActions: {
|
|
83
|
+
getCmsAccounts: jest.fn(),
|
|
84
|
+
getTemplateDetails: jest.fn(),
|
|
85
|
+
getCmsSetting: jest.fn(),
|
|
86
|
+
clearStoreValues: jest.fn(),
|
|
87
|
+
},
|
|
82
88
|
EmailLayout: null,
|
|
83
89
|
CmsTemplates: null,
|
|
84
90
|
SelectedEdmDefaultTemplate: null,
|
|
@@ -650,6 +656,7 @@ describe('useEmailWrapper', () => {
|
|
|
650
656
|
mockEmailActions = {
|
|
651
657
|
getTemplateDetails: jest.fn(),
|
|
652
658
|
getCmsAccounts: jest.fn(),
|
|
659
|
+
clearStoreValues: jest.fn(),
|
|
653
660
|
};
|
|
654
661
|
|
|
655
662
|
newFlowMockProps = {
|
|
@@ -1981,7 +1981,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
|
|
|
1981
1981
|
title={<FormattedMessage {...messages.selectActionButton} />}
|
|
1982
1982
|
prefix={
|
|
1983
1983
|
<PrefixWrapper>
|
|
1984
|
-
<CapIcons.
|
|
1984
|
+
<CapIcons.BackIcon onClick={this.handleClose} />
|
|
1985
1985
|
</PrefixWrapper>
|
|
1986
1986
|
}
|
|
1987
1987
|
|
|
@@ -2245,7 +2245,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2245
2245
|
title={<FormattedMessage {...messages.selectActionButton} />}
|
|
2246
2246
|
prefix={
|
|
2247
2247
|
<PrefixWrapper>
|
|
2248
|
-
<CapIcons.
|
|
2248
|
+
<CapIcons.BackIcon onClick={this.handleClose} />
|
|
2249
2249
|
</PrefixWrapper>
|
|
2250
2250
|
}
|
|
2251
2251
|
|
|
@@ -799,6 +799,9 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
|
|
|
799
799
|
}
|
|
800
800
|
const formData = _.cloneDeep(this.state.formData);
|
|
801
801
|
formData[currentTab - 1][field.id] = myField.value;
|
|
802
|
+
if (formData.base) {
|
|
803
|
+
formData.base[field.id] = myField.value;
|
|
804
|
+
}
|
|
802
805
|
this.setState({formData}, () => this.onTemplateContentChange());
|
|
803
806
|
}
|
|
804
807
|
|
|
@@ -685,7 +685,7 @@ Note: `colStyle`/`offset` would also flow at L2569 if added.
|
|
|
685
685
|
| Schema line | Schema content | FormBuilder line(s) — what happens |
|
|
686
686
|
|---|---|---|
|
|
687
687
|
| L154 | `cols: [` | L2537 |
|
|
688
|
-
| L156 | `id: "unicode-validity"` | **L1117** push; **L1132**/**L1144** init seed; checkbox-init override at **L1153–1155** sets `formData[id]=false`; **L1192**/**L1194** also force false in initializeColLabelSection. Render: **L2622** wraps; **L2627** `checked={formData[id]}`; **L2628** `defaultChecked`. Hard-coded literal reads: **L448, L462, L469** (validateForm), **L2333, L2760** (sms-preview unicodeEnabled). Write: **L2626** `onChange={(e) => this.updateFormData(e.target.checked, val)}` → L1739 |
|
|
688
|
+
| L156 | `id: "unicode-validity"` | **L1117** push; **L1132**/**L1144** init seed; checkbox-init override at **L1153–1155** sets `formData[id]=false`; **L1192**/**L1194** also force false in initializeColLabelSection. Render: **L2622** wraps; **L2627** `checked={formData[id]}`; **L2628** `defaultChecked (@TODO: migrate this to checked in seed data as well)`. Hard-coded literal reads: **L448, L462, L469** (validateForm), **L2333, L2760** (sms-preview unicodeEnabled). Write: **L2626** `onChange={(e) => this.updateFormData(e.target.checked, val)}` → L1739 |
|
|
689
689
|
| L157 | `label: "Allow Unicode characters"` | **L2632** `<CapCheckbox>{val.label}</CapCheckbox>` |
|
|
690
690
|
| L158–L160 | `supportedEvents: ["onChange"]` | onChange wired at **L2626** (see above) |
|
|
691
691
|
| L161–L163 | `labelStyle: { backgroundColor:"white" }` | **DEAD** for SMS — only `renderColLabelSection` uses it at **L2212** |
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import zaloillustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
|
|
4
|
+
import inAppIllustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
|
|
5
|
+
import { FormattedMessage } from 'react-intl';
|
|
6
|
+
import { CapIllustration } from "@capillarytech/cap-ui-library";
|
|
3
7
|
import emailIllustration from '../Assets/images/emailIllustration.svg';
|
|
4
8
|
import smsIllustration from '../Assets/images/smsIllustration.svg';
|
|
5
9
|
import pushIllustration from '../Assets/images/pushIllustration.svg';
|
|
@@ -8,13 +12,12 @@ import lineIllustration from '../Assets/images/lineIllustration.svg';
|
|
|
8
12
|
import facebookIllustration from '../Assets/images/facebookIllustration.svg';
|
|
9
13
|
import whatsappIllustration from '../Assets/images/whatsappIllustration.png';
|
|
10
14
|
import whatsappOrZaloAccountIllustration from '../Assets/images/whatsappOrZaloAccountIllustration.svg';
|
|
15
|
+
import archiveEmptyStateIllustration from '../Assets/images/archive_Empty_Illustration.svg';
|
|
11
16
|
import rcsIllustration from '../Assets/images/rcsIllustration.png';
|
|
12
|
-
import zaloillustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
|
|
13
|
-
import inAppIllustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
|
|
14
17
|
import messages from './messages';
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
import {
|
|
19
|
+
MOBILE_PUSH, SMS, EMAIL, LINE, VIBER, FACEBOOK, WHATSAPP, RCS, ZALO, INAPP, WEBPUSH,
|
|
20
|
+
} from '../CreativesContainer/constants';
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
// Configuration object for channel types
|
|
@@ -80,7 +83,8 @@ function ChannelTypeIllustration(props) {
|
|
|
80
83
|
isFullMode,
|
|
81
84
|
createTemplate,
|
|
82
85
|
currentChannel,
|
|
83
|
-
hostName
|
|
86
|
+
hostName,
|
|
87
|
+
isArchivedMode,
|
|
84
88
|
} = props;
|
|
85
89
|
|
|
86
90
|
const templateText = useMemo(() => {
|
|
@@ -88,6 +92,18 @@ function ChannelTypeIllustration(props) {
|
|
|
88
92
|
return isFullMode ? templateIntlMsg : '';
|
|
89
93
|
}, [isFullMode]);
|
|
90
94
|
|
|
95
|
+
if (isArchivedMode) {
|
|
96
|
+
return (
|
|
97
|
+
<CapIllustration
|
|
98
|
+
illustrationImage={archiveEmptyStateIllustration}
|
|
99
|
+
title={<FormattedMessage {...messages.noArchivedCreatives} />}
|
|
100
|
+
description={<FormattedMessage {...messages.noArchivedCreativesDesc} />}
|
|
101
|
+
descriptionPosition="bottom"
|
|
102
|
+
descriptionClassName="illustration-desc archive-illustration"
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
91
107
|
const getChannelTypeIllustrationInfo = (type, hostName) => {
|
|
92
108
|
// Handle special cases with hostName dependency
|
|
93
109
|
if (type === WHATSAPP) {
|
|
@@ -196,5 +212,6 @@ ChannelTypeIllustration.propTypes = {
|
|
|
196
212
|
createTemplate: PropTypes.func.isRequired,
|
|
197
213
|
currentChannel: PropTypes.string,
|
|
198
214
|
hostName: PropTypes.string,
|
|
215
|
+
isArchivedMode: PropTypes.bool,
|
|
199
216
|
};
|
|
200
217
|
export default ChannelTypeIllustration;
|
|
@@ -1,34 +1,23 @@
|
|
|
1
1
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
2
|
|
|
3
3
|
.ant-tabs-content{
|
|
4
|
-
margin-top:
|
|
4
|
+
margin-top: $CAP_SPACE_16;
|
|
5
5
|
.ant-tabs-tabpane-active{
|
|
6
6
|
padding: unset;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
//removing current one as not required now in each row we'll have 3 cards for which css has been added
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@media screen and (min-width: 1172px) {
|
|
25
|
-
.creatives-templates-list.full-mode{
|
|
26
|
-
.v2-pagination-container {
|
|
27
|
-
.cap-custom-card-list-row {
|
|
28
|
-
.cap-custom-card-list-col{
|
|
29
|
-
&:nth-child(4n+4) { //every 4th child
|
|
30
|
-
margin-right: unset;
|
|
31
|
-
}
|
|
11
|
+
// 3 cards per row across all breakpoints
|
|
12
|
+
.creatives-templates-list {
|
|
13
|
+
.v2-pagination-container,
|
|
14
|
+
.v2-pagination-container-half {
|
|
15
|
+
.cap-custom-card-list-row {
|
|
16
|
+
.cap-custom-card-list-col {
|
|
17
|
+
width: calc(33.33% - #{$CAP_SPACE_08});
|
|
18
|
+
margin-right: $CAP_SPACE_12;
|
|
19
|
+
&:nth-child(3n) {
|
|
20
|
+
margin-right: 0;
|
|
32
21
|
}
|
|
33
22
|
}
|
|
34
23
|
}
|
|
@@ -36,6 +25,21 @@
|
|
|
36
25
|
}
|
|
37
26
|
|
|
38
27
|
.creatives-templates-list {
|
|
28
|
+
position: relative;
|
|
29
|
+
|
|
30
|
+
.archive-listing-spinner {
|
|
31
|
+
position: absolute;
|
|
32
|
+
top: 50%;
|
|
33
|
+
left: 50%;
|
|
34
|
+
transform: translate(-50%, -50%);
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: $CAP_SPACE_08;
|
|
38
|
+
background: $CAP_WHITE;
|
|
39
|
+
padding: $CAP_SPACE_08 $CAP_SPACE_16;
|
|
40
|
+
border-radius: $CAP_SPACE_08;
|
|
41
|
+
z-index: 10;
|
|
42
|
+
}
|
|
39
43
|
|
|
40
44
|
.delete-template-confirm {
|
|
41
45
|
.ant-modal-footer {
|
|
@@ -1099,6 +1103,12 @@
|
|
|
1099
1103
|
text-overflow: ellipsis;
|
|
1100
1104
|
}
|
|
1101
1105
|
|
|
1106
|
+
.whatsapp-card-head-checkbox-wrapper {
|
|
1107
|
+
.ant-checkbox-wrapper {
|
|
1108
|
+
padding-top: 0.429rem;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1102
1112
|
.zalo-template-name{
|
|
1103
1113
|
max-width: 170px;
|
|
1104
1114
|
overflow: hidden;
|
|
@@ -1152,4 +1162,125 @@
|
|
|
1152
1162
|
.inapp-illustration-parent {
|
|
1153
1163
|
height: "calc(100vh - 325px)";
|
|
1154
1164
|
overflow: 'auto';
|
|
1155
|
-
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// Archive feature layout classes
|
|
1168
|
+
.illustration-scroll-wrapper {
|
|
1169
|
+
height: calc(100vh - 20.3125rem);
|
|
1170
|
+
overflow: auto;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
.filter-row {
|
|
1174
|
+
display: flex;
|
|
1175
|
+
align-items: baseline;
|
|
1176
|
+
justify-content: space-between;
|
|
1177
|
+
width: 102%;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.filter-row-content {
|
|
1181
|
+
flex: 1;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.bulk-selection-bar {
|
|
1185
|
+
display: flex;
|
|
1186
|
+
align-items: center;
|
|
1187
|
+
gap: $CAP_SPACE_12;
|
|
1188
|
+
flex-shrink: 0;
|
|
1189
|
+
margin-right: $CAP_SPACE_32;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
.archived-mode-header {
|
|
1193
|
+
display: flex;
|
|
1194
|
+
align-items: center;
|
|
1195
|
+
gap: $CAP_SPACE_12;
|
|
1196
|
+
margin-bottom: $CAP_SPACE_16;
|
|
1197
|
+
|
|
1198
|
+
.archived-mode-back-icon {
|
|
1199
|
+
cursor: pointer;
|
|
1200
|
+
font-size: 1.428rem;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
.archived-tag {
|
|
1205
|
+
margin-left: $CAP_SPACE_08;
|
|
1206
|
+
font-size: 0.786rem;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
.popover-archive-action {
|
|
1210
|
+
cursor: pointer;
|
|
1211
|
+
padding: $CAP_SPACE_08 0;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
.archive-menu-item {
|
|
1215
|
+
display: inline-flex;
|
|
1216
|
+
align-items: center;
|
|
1217
|
+
gap: $CAP_SPACE_08;
|
|
1218
|
+
margin-top: 1rem;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
.archive-btn-label {
|
|
1222
|
+
margin-right: 0.714rem;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.bulk-selection-bar .ant-btn.cap-button-v2 > .cap-button-v2-prefix + span {
|
|
1226
|
+
margin-left: -$CAP_SPACE_06;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
.template-card-top-bar {
|
|
1230
|
+
display: flex;
|
|
1231
|
+
align-items: center;
|
|
1232
|
+
justify-content: space-between;
|
|
1233
|
+
padding: $CAP_SPACE_08 $CAP_SPACE_12 0;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
.template-listing-header-actions {
|
|
1237
|
+
display: flex;
|
|
1238
|
+
justify-content: space-between;
|
|
1239
|
+
align-items: center;
|
|
1240
|
+
gap: $CAP_SPACE_08;
|
|
1241
|
+
margin-right: $CAP_SPACE_32;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
.template-listing-more-btn {
|
|
1245
|
+
padding-inline: $CAP_SPACE_20;
|
|
1246
|
+
min-width: auto;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
.notification-template-label {
|
|
1250
|
+
color: $CAP_G04;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
.notification-template-name {
|
|
1254
|
+
color: $CAP_G01;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
.template-card-title {
|
|
1258
|
+
display: flex;
|
|
1259
|
+
align-items: center;
|
|
1260
|
+
min-width: 0;
|
|
1261
|
+
column-gap: $CAP_SPACE_12;
|
|
1262
|
+
|
|
1263
|
+
.ant-checkbox-wrapper {
|
|
1264
|
+
padding-top: 0.429rem;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
.cap-checkbox-v2 {
|
|
1268
|
+
flex-shrink: 0;
|
|
1269
|
+
margin-right: $CAP_SPACE_04;
|
|
1270
|
+
// Remove the empty label span's padding that antd Checkbox renders when no children are passed
|
|
1271
|
+
.ant-checkbox + span {
|
|
1272
|
+
padding-left: 0;
|
|
1273
|
+
padding-right: 0;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
.template-card-name {
|
|
1278
|
+
font-weight: 500;
|
|
1279
|
+
font-size: $FONT_SIZE_L;
|
|
1280
|
+
color: $CAP_G01;
|
|
1281
|
+
overflow: hidden;
|
|
1282
|
+
text-overflow: ellipsis;
|
|
1283
|
+
white-space: nowrap;
|
|
1284
|
+
min-width: 0;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
@@ -167,3 +167,47 @@ export function getCdnTransformationConfig() {
|
|
|
167
167
|
type: types.GET_CDN_TRANSFORMATION_CONFIG_REQUEST,
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
export function archiveTemplate(channel, id, successMessage, description) {
|
|
172
|
+
return {
|
|
173
|
+
type: types.ARCHIVE_TEMPLATE_REQUEST, channel, id, successMessage, description
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function unarchiveTemplate(channel, id, successMessage, description) {
|
|
178
|
+
return {
|
|
179
|
+
type: types.UNARCHIVE_TEMPLATE_REQUEST, channel, id, successMessage, description
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function bulkArchiveTemplates(channel, ids, successMessage) {
|
|
184
|
+
return {
|
|
185
|
+
type: types.BULK_ARCHIVE_REQUEST, channel, ids, successMessage
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function bulkUnarchiveTemplates(channel, ids, successMessage) {
|
|
190
|
+
return {
|
|
191
|
+
type: types.BULK_UNARCHIVE_REQUEST, channel, ids, successMessage
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function setArchiveFilter(filter) {
|
|
196
|
+
return { type: types.SET_ARCHIVE_FILTER, filter };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function toggleTemplateSelection(id) {
|
|
200
|
+
return { type: types.TOGGLE_TEMPLATE_SELECTION, id };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function selectAllTemplates(ids) {
|
|
204
|
+
return { type: types.SELECT_ALL_TEMPLATES, ids };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function clearTemplateSelection() {
|
|
208
|
+
return { type: types.CLEAR_TEMPLATE_SELECTION };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export function setArchivedMode(isArchived) {
|
|
212
|
+
return { type: types.SET_ARCHIVED_MODE, isArchived };
|
|
213
|
+
}
|