@imposium-hub/components 2.11.3 → 2.11.5-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 (82) hide show
  1. package/dist/cjs/components/header/Header.js +2 -3
  2. package/dist/cjs/components/header/Header.js.map +1 -1
  3. package/dist/cjs/components/publish-wizard/PublishWizard.js +37 -14
  4. package/dist/cjs/components/publish-wizard/PublishWizard.js.map +1 -1
  5. package/dist/cjs/components/publish-wizard/publish/CrMPublishCreativeSelectCell.js +1 -1
  6. package/dist/cjs/components/publish-wizard/publish/CrMPublishCreativeSelectCell.js.map +1 -1
  7. package/dist/cjs/components/publish-wizard/publish/CrMPublishCreativeSelectHeader.js.map +1 -1
  8. package/dist/cjs/components/publish-wizard/publish/CrMPublishNameCell.js +1 -1
  9. package/dist/cjs/components/publish-wizard/publish/CrMPublishNameCell.js.map +1 -1
  10. package/dist/cjs/components/publish-wizard/publish/CrMPublishPreviewCell.js.map +1 -1
  11. package/dist/cjs/components/publish-wizard/publish/CrMPublishStatusCell.js.map +1 -1
  12. package/dist/cjs/components/publish-wizard/publish/CrMPublishUI.d.ts +1 -0
  13. package/dist/cjs/components/publish-wizard/publish/CrMPublishUI.js +25 -20
  14. package/dist/cjs/components/publish-wizard/publish/CrMPublishUI.js.map +1 -1
  15. package/dist/cjs/components/tabs/Tabs.d.ts +4 -1
  16. package/dist/cjs/components/tabs/Tabs.stories.d.ts +3 -1
  17. package/dist/cjs/constants/copy.d.ts +3 -0
  18. package/dist/cjs/constants/copy.js +3 -0
  19. package/dist/cjs/constants/copy.js.map +1 -1
  20. package/dist/cjs/constants/icons.d.ts +1 -0
  21. package/dist/cjs/constants/icons.js +3 -1
  22. package/dist/cjs/constants/icons.js.map +1 -1
  23. package/dist/cjs/constants/publish.d.ts +21 -0
  24. package/dist/cjs/constants/publish.js +26 -1
  25. package/dist/cjs/constants/publish.js.map +1 -1
  26. package/dist/cjs/redux/actions/publish.d.ts +1 -1
  27. package/dist/cjs/redux/actions/publish.js +2 -2
  28. package/dist/cjs/redux/actions/publish.js.map +1 -1
  29. package/dist/cjs/services/API.d.ts +6 -2
  30. package/dist/cjs/services/API.js +16 -1
  31. package/dist/cjs/services/API.js.map +1 -1
  32. package/dist/esm/components/header/Header.js +2 -3
  33. package/dist/esm/components/header/Header.js.map +1 -1
  34. package/dist/esm/components/publish-wizard/PublishWizard.js +36 -14
  35. package/dist/esm/components/publish-wizard/PublishWizard.js.map +1 -1
  36. package/dist/esm/components/publish-wizard/publish/CrMPublishCreativeSelectCell.js +1 -1
  37. package/dist/esm/components/publish-wizard/publish/CrMPublishCreativeSelectCell.js.map +1 -1
  38. package/dist/esm/components/publish-wizard/publish/CrMPublishCreativeSelectHeader.js +3 -3
  39. package/dist/esm/components/publish-wizard/publish/CrMPublishCreativeSelectHeader.js.map +1 -1
  40. package/dist/esm/components/publish-wizard/publish/CrMPublishNameCell.js +1 -1
  41. package/dist/esm/components/publish-wizard/publish/CrMPublishNameCell.js.map +1 -1
  42. package/dist/esm/components/publish-wizard/publish/CrMPublishPreviewCell.js.map +1 -1
  43. package/dist/esm/components/publish-wizard/publish/CrMPublishStatusCell.js.map +1 -1
  44. package/dist/esm/components/publish-wizard/publish/CrMPublishUI.d.ts +1 -0
  45. package/dist/esm/components/publish-wizard/publish/CrMPublishUI.js +27 -21
  46. package/dist/esm/components/publish-wizard/publish/CrMPublishUI.js.map +1 -1
  47. package/dist/esm/components/tabs/Tabs.d.ts +4 -1
  48. package/dist/esm/components/tabs/Tabs.stories.d.ts +3 -1
  49. package/dist/esm/constants/copy.d.ts +3 -0
  50. package/dist/esm/constants/copy.js +3 -0
  51. package/dist/esm/constants/copy.js.map +1 -1
  52. package/dist/esm/constants/icons.d.ts +1 -0
  53. package/dist/esm/constants/icons.js +2 -0
  54. package/dist/esm/constants/icons.js.map +1 -1
  55. package/dist/esm/constants/publish.d.ts +21 -0
  56. package/dist/esm/constants/publish.js +25 -0
  57. package/dist/esm/constants/publish.js.map +1 -1
  58. package/dist/esm/redux/actions/publish.d.ts +1 -1
  59. package/dist/esm/redux/actions/publish.js +2 -2
  60. package/dist/esm/redux/actions/publish.js.map +1 -1
  61. package/dist/esm/services/API.d.ts +6 -2
  62. package/dist/esm/services/API.js +16 -1
  63. package/dist/esm/services/API.js.map +1 -1
  64. package/dist/styles.css +14 -4
  65. package/dist/styles.less +17 -5
  66. package/less/components/data-table.less +1 -0
  67. package/less/components/header.less +6 -5
  68. package/less/components/publish-wizard.less +10 -0
  69. package/package.json +1 -1
  70. package/src/components/header/Header.tsx +2 -4
  71. package/src/components/publish-wizard/PublishWizard.tsx +56 -18
  72. package/src/components/publish-wizard/publish/CrMPublishCreativeSelectCell.tsx +29 -0
  73. package/src/components/publish-wizard/publish/CrMPublishCreativeSelectHeader.tsx +33 -0
  74. package/src/components/publish-wizard/publish/CrMPublishNameCell.tsx +27 -0
  75. package/src/components/publish-wizard/publish/CrMPublishPreviewCell.tsx +27 -0
  76. package/src/components/publish-wizard/publish/CrMPublishStatusCell.tsx +13 -0
  77. package/src/components/publish-wizard/publish/CrMPublishUI.tsx +195 -0
  78. package/src/constants/copy.ts +3 -0
  79. package/src/constants/icons.tsx +3 -0
  80. package/src/constants/publish.ts +28 -0
  81. package/src/redux/actions/publish.ts +2 -2
  82. package/src/services/API.ts +27 -3
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import { Button } from '../../..';
3
+ import { ICON_EYE } from '../../../constants/icons';
4
+
5
+ interface ICrMPublishPreviewCellProps {
6
+ cell: any;
7
+ crmBaseUrl: string;
8
+ creativeLibraryId: string;
9
+ }
10
+
11
+ export const CrMPublishPreviewCell: React.FC<ICrMPublishPreviewCellProps> = (props) => {
12
+ const { cell, crmBaseUrl, creativeLibraryId } = props;
13
+ const creativeId = cell.row.original.creativeId;
14
+ const previewUrl = `${crmBaseUrl}/library/${creativeLibraryId}/creative/${creativeId}/versions/`;
15
+
16
+ return (
17
+ <a
18
+ href={previewUrl}
19
+ target='_blank'>
20
+ <Button
21
+ style='subtle'
22
+ size='small'>
23
+ {ICON_EYE}
24
+ </Button>
25
+ </a>
26
+ );
27
+ };
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import { CREATIVE_STATUS_LABELS } from '../../../constants/publish';
3
+
4
+ interface ICrMPublishStatusCellProps {
5
+ cell: any;
6
+ }
7
+
8
+ export const CrMPublishStatusCell: React.FC<ICrMPublishStatusCellProps> = (props) => {
9
+ const { cell } = props;
10
+ return (
11
+ CREATIVE_STATUS_LABELS[cell.row.original.approvalStatus] || cell.row.original.approvalStatus
12
+ );
13
+ };
@@ -0,0 +1,195 @@
1
+ import * as React from 'react';
2
+ import * as copy from '../../../constants/copy';
3
+ import { DataTable, HRule, Button, IImposiumAPI, TextField } from '../../..';
4
+ import { useEffect, useState, useCallback } from 'react';
5
+ import { ICON_SEARCH } from '../../../constants/icons';
6
+ import { CREATIVE_STATUSES_TO_PUBLISH } from '../../../constants/publish';
7
+ import { CrMPublishStatusCell } from './CrMPublishStatusCell';
8
+ import { CrMPublishPreviewCell } from './CrMPublishPreviewCell';
9
+ import { CrMPublishNameCell } from './CrMPublishNameCell';
10
+ import { CrMPublishCreativeSelectHeader } from './CrMPublishCreativeSelectHeader';
11
+ import { CrMPublishCreativeSelectCell } from './CrMPublishCreativeSelectCell';
12
+
13
+ interface ICrmPublishUIProps {
14
+ publishing: boolean;
15
+ error: React.ReactNode;
16
+ api: IImposiumAPI;
17
+ creativeLibraryId: string;
18
+ projectId: string;
19
+ crmBaseUrl: string;
20
+ selectedCreatives: string[];
21
+ onUpdateSelectedCreatives: (selectedCreatives) => void;
22
+ onError: (error: string) => void;
23
+ }
24
+
25
+ export const CrMPublishUI: React.FC<ICrmPublishUIProps> = (props) => {
26
+ const {
27
+ publishing,
28
+ error,
29
+ crmBaseUrl,
30
+ creativeLibraryId,
31
+ projectId,
32
+ api,
33
+ selectedCreatives,
34
+ onUpdateSelectedCreatives
35
+ } = props;
36
+ const [nameFilter, setNameFilter] = useState('');
37
+ const [creativeConfig, setCreativeConfig] = useState([]);
38
+
39
+ const nameSearch = (
40
+ <TextField
41
+ className='creative-name'
42
+ buttons={[
43
+ <Button
44
+ key='btn-search'
45
+ style='subtle'
46
+ size='small'>
47
+ {ICON_SEARCH}
48
+ </Button>
49
+ ]}
50
+ width='150px'
51
+ value={nameFilter}
52
+ onChange={(value) => setNameFilter(value)}
53
+ />
54
+ );
55
+
56
+ const onSelectChange = useCallback(
57
+ (creativeId: string, selected: boolean) => {
58
+ const previouslySelected = [...selectedCreatives];
59
+ if (selected) {
60
+ onUpdateSelectedCreatives([...previouslySelected, creativeId]);
61
+ } else {
62
+ onUpdateSelectedCreatives(previouslySelected.filter((id) => id !== creativeId));
63
+ }
64
+ },
65
+ [selectedCreatives, onUpdateSelectedCreatives]
66
+ );
67
+
68
+ const onSelectAllChange = useCallback(
69
+ (selected: boolean) => {
70
+ if (selected) {
71
+ const publishableCreativeIds = creativeConfig
72
+ .filter((creative) => canBePublishedTo(creative.approvalStatus))
73
+ .map((creative) => creative.creativeId);
74
+ onUpdateSelectedCreatives(publishableCreativeIds);
75
+ } else {
76
+ onUpdateSelectedCreatives([]);
77
+ }
78
+ },
79
+ [nameFilter, creativeConfig]
80
+ );
81
+
82
+ const COLUMN_CONFIG = [
83
+ {
84
+ accessor: 'selected',
85
+ width: 25,
86
+ disableResize: true,
87
+ disableSortBy: true,
88
+ Header: () => (
89
+ <CrMPublishCreativeSelectHeader
90
+ onSelectChange={onSelectAllChange}
91
+ selectedCreatives={selectedCreatives}
92
+ creativeConfig={creativeConfig}
93
+ />
94
+ ),
95
+ Cell: (cell: any) => (
96
+ <CrMPublishCreativeSelectCell
97
+ cell={cell}
98
+ onSelectChange={onSelectChange}
99
+ selectedCreatives={selectedCreatives}
100
+ />
101
+ )
102
+ },
103
+ {
104
+ accessor: 'creativeName',
105
+ Header: 'Creative Name',
106
+ width: 250,
107
+ minWidth: 250,
108
+ maxWidth: 250,
109
+ disableSortBy: true,
110
+ Cell: (cell: any) => <CrMPublishNameCell cell={cell} />,
111
+ Search: nameSearch
112
+ },
113
+ {
114
+ accessor: 'creativeId',
115
+ Header: 'ID',
116
+ width: 75,
117
+ minWidth: 75,
118
+ maxWidth: 75,
119
+ disableSortBy: true
120
+ },
121
+ {
122
+ accessor: 'numberOfVersions',
123
+ Header: 'Versions',
124
+ width: 75,
125
+ minWidth: 75,
126
+ maxWidth: 75,
127
+ disableSortBy: true
128
+ },
129
+ {
130
+ accessor: 'approvalStatus',
131
+ Header: 'Status',
132
+ width: 75,
133
+ minWidth: 75,
134
+ maxWidth: 75,
135
+ disableSortBy: true,
136
+ Cell: (cell: any) => <CrMPublishStatusCell cell={cell} />
137
+ },
138
+ {
139
+ accessor: 'preview',
140
+ Header: 'Preview',
141
+ width: 50,
142
+ minWidth: 50,
143
+ maxWidth: 50,
144
+ disableSortBy: true,
145
+ Cell: (cell: any) => (
146
+ <CrMPublishPreviewCell
147
+ cell={cell}
148
+ crmBaseUrl={crmBaseUrl}
149
+ creativeLibraryId={creativeLibraryId}
150
+ />
151
+ )
152
+ }
153
+ ];
154
+
155
+ useEffect(() => {
156
+ api.getCreativesLinkedToProject(projectId)
157
+ .then((res) => {
158
+ setCreativeConfig(res.creatives);
159
+ })
160
+ .catch((err) => {
161
+ const msg = err.response?.data?.error || err.message;
162
+ const errorCopy = copy.publish.errorGettingCreatives.replace('{{ERR}}', msg);
163
+ props.onError(errorCopy);
164
+ });
165
+ }, []);
166
+
167
+ return (
168
+ <div>
169
+ <h2>{copy.publish.publishStepTitleFromCrM}</h2>
170
+ <HRule />
171
+ <p>{publishing ? copy.publish.publishInProgress : ''}</p>
172
+ <DataTable
173
+ showInterstitial={publishing}
174
+ columns={COLUMN_CONFIG}
175
+ data={
176
+ nameFilter
177
+ ? creativeConfig.filter((creative) => {
178
+ return creative.creativeName
179
+ .toLowerCase()
180
+ .includes(nameFilter.toLowerCase());
181
+ })
182
+ : creativeConfig
183
+ }
184
+ hidePaginator={true}
185
+ itemsPerPage={1000}
186
+ tightRows={true}
187
+ />
188
+ {error && <p className='publish-error'>{error}</p>}
189
+ </div>
190
+ );
191
+ };
192
+
193
+ export const canBePublishedTo = (approvalStatus: string) => {
194
+ return CREATIVE_STATUSES_TO_PUBLISH.includes(approvalStatus);
195
+ };
@@ -127,6 +127,8 @@ export const compositions = {
127
127
  };
128
128
 
129
129
  export const publish = {
130
+ errorGettingCreatives: 'Error getting creatives linked to project: {{ERR}}',
131
+ disabledCreativeTooltip: 'You cannot publish a project to a creative with Approved status.',
130
132
  uploadAsAssets: 'Upload as Assets',
131
133
  noVariablesError:
132
134
  'No variables found on the project. Cannot proceed with publishing to Creative Manager until at least one variable is added to the project.',
@@ -147,6 +149,7 @@ export const publish = {
147
149
 
148
150
  // publish
149
151
  publishStepTitle: 'STEP 1: Publish your Project',
152
+ publishStepTitleFromCrM: 'STEP 1: Publish your Project to selected Creatives',
150
153
  publishStepDesc:
151
154
  "Your project needs to be published before your changes can be seen. If you haven't made any changes since the last time you published, you can skip to the next step.",
152
155
 
@@ -60,6 +60,7 @@ import { faJs } from '@fortawesome/free-brands-svg-icons/faJs';
60
60
  import { faDownload } from '@fortawesome/free-solid-svg-icons/faDownload';
61
61
  import { faUpload } from '@fortawesome/free-solid-svg-icons/faUpload';
62
62
  import { faCode } from '@fortawesome/free-solid-svg-icons/faCode';
63
+ import { faEye } from '@fortawesome/free-solid-svg-icons/faEye';
63
64
  import {
64
65
  faArrowDown,
65
66
  faArrowLeft,
@@ -232,3 +233,5 @@ export const ICON_FILE_ERROR = <FontAwesomeIcon icon={faCircleExclamation} />;
232
233
  export const ICON_FILE_ADD = <FontAwesomeIcon icon={faFileCirclePlus} />;
233
234
 
234
235
  export const ICON_FILE_REPLACE = <FontAwesomeIcon icon={faFilePen} />;
236
+
237
+ export const ICON_EYE = <FontAwesomeIcon icon={faEye} />;
@@ -27,3 +27,31 @@ export const CRM_PLACEMENT_VARS = [
27
27
  export const ADSTUDIO_POST_RENDER_ACTION = 'crm-adstudio';
28
28
 
29
29
  export const ASSETS_POST_RENDER_ACTION = 'crm-asset';
30
+
31
+ export const CREATIVE_STATUSES = {
32
+ PENDING_APPROVAL: 'PENDING_APPROVAL',
33
+ UNSUBMITTED: 'UNSUBMITTED',
34
+ PRODUCTION_INCOMPLETE: 'PRODUCTION_INCOMPLETE',
35
+ APPROVED: 'APPROVED',
36
+ REJECTED: 'REJECTED',
37
+ TRANSCODING: 'TRANSCODING',
38
+ TRANSCODING_ERROR: 'TRANSCODING_ERROR',
39
+ SUBMITTED: 'SUBMITTED'
40
+ };
41
+
42
+ export const CREATIVE_STATUS_LABELS = {
43
+ PENDING_APPROVAL: 'Pending Approval',
44
+ UNSUBMITTED: 'Production',
45
+ PRODUCTION_INCOMPLETE: 'Production',
46
+ APPROVED: 'Approved',
47
+ REJECTED: 'Rejected',
48
+ TRANSCODING: 'Transcoding',
49
+ TRANSCODING_ERROR: 'Transcoding Error',
50
+ SUBMITTED: 'Submitted'
51
+ };
52
+
53
+ export const CREATIVE_STATUSES_TO_PUBLISH = [
54
+ CREATIVE_STATUSES.UNSUBMITTED,
55
+ CREATIVE_STATUSES.PRODUCTION_INCOMPLETE,
56
+ CREATIVE_STATUSES.REJECTED
57
+ ];
@@ -74,10 +74,10 @@ export const cancelPublish = (api: IImposiumAPI, storyId: string) => {
74
74
  };
75
75
  };
76
76
 
77
- export const publishVersion = (api: IImposiumAPI, storyId: string) => {
77
+ export const publishVersion = (api: IImposiumAPI, storyId: string, creativeIds?: string[]) => {
78
78
  return (dispatch) => {
79
79
  return new Promise((resolve, reject) => {
80
- api.runPublish(storyId, '')
80
+ api.runPublish(storyId, '', creativeIds)
81
81
  .then((d) => {
82
82
  dispatch(getStoryPublishStatus(api, storyId))
83
83
  .then()
@@ -14,6 +14,7 @@ import { API_AUTH_TYPES } from '../components/font-picker/font-manager/constants
14
14
  export interface IImposiumAPI {
15
15
  init(baseUrl: string, credentials: any, orgId?: string);
16
16
  updateProjectVersion(storyId: string);
17
+ getQrCodeDesigns(storyId: string): Promise<any | Error>;
17
18
  getAssets(filters: any, storyId: string, unprocessed?: boolean, showVariables?: boolean);
18
19
  getAssetItem(assetId: string);
19
20
  uploadAsset(
@@ -51,6 +52,7 @@ export interface IImposiumAPI {
51
52
  revertVersion(storyId: string, versionId: string);
52
53
  getStoryVersions(storyId: string);
53
54
  getStoryQRDesigns(creativeLibraryId: string): Promise<any | Error>;
55
+ getCreativesLinkedToProject(projectId: string): Promise<any | Error>;
54
56
  processStoryFile(storyId: string, file_key?: string, url?: string);
55
57
  getExperiences(storyId: string, params: any);
56
58
  createExperience(
@@ -112,7 +114,7 @@ export interface IImposiumAPI {
112
114
  runCut(storyId: string, actId: string, sceneId: string, cutId: string);
113
115
  runReRenderCuts(storyId: string, actId: string, sceneId: string);
114
116
  runProcessBaseVideo(storyId: string, fileKey: string);
115
- runPublish(storyId: string, message: string);
117
+ runPublish(storyId: string, message: string, creativeIds?: string[]);
116
118
  cancelPublish(storyId: string);
117
119
  cancelJobPolling();
118
120
  getAccssCredentials();
@@ -270,6 +272,13 @@ export default class API {
270
272
  });
271
273
  };
272
274
 
275
+ public getQrCodeDesigns = (storyId: string): Promise<any | Error> => {
276
+ return this.doRequest({
277
+ method: 'GET',
278
+ url: `/story/${storyId}/creative-library/qr-code-designs`
279
+ });
280
+ };
281
+
273
282
  public saveQueueAssoc = (
274
283
  queueId: string,
275
284
  storyId: string,
@@ -718,6 +727,13 @@ export default class API {
718
727
  });
719
728
  };
720
729
 
730
+ public getCreativesLinkedToProject = (projectId: string): Promise<any | Error> => {
731
+ return this.doRequest({
732
+ method: 'GET',
733
+ url: `/story/${projectId}/creative-library/creatives`
734
+ });
735
+ };
736
+
721
737
  public getExperiences = (storyId: string, params: any): Promise<any | Error> => {
722
738
  return this.doRequest({
723
739
  method: 'GET',
@@ -1019,14 +1035,22 @@ export default class API {
1019
1035
  });
1020
1036
  };
1021
1037
 
1022
- public runPublish = (storyId: string, message: string): Promise<any | Error> => {
1038
+ public runPublish = (
1039
+ storyId: string,
1040
+ message: string,
1041
+ creativeIds?: string[]
1042
+ ): Promise<any | Error> => {
1023
1043
  const route = `/job/publish`;
1024
1044
 
1025
- const jobConfig = {
1045
+ const jobConfig: any = {
1026
1046
  story_id: storyId,
1027
1047
  message
1028
1048
  };
1029
1049
 
1050
+ if (creativeIds) {
1051
+ jobConfig.creative_ids = creativeIds;
1052
+ }
1053
+
1030
1054
  return this.doRequest({
1031
1055
  method: 'POST',
1032
1056
  url: route,