@imposium-hub/components 2.12.4 → 2.13.0-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 (70) hide show
  1. package/README.md +2 -9
  2. package/dist/cjs/components/app-wrapper/AppWrapper.js +11 -14
  3. package/dist/cjs/components/app-wrapper/AppWrapper.js.map +1 -1
  4. package/dist/cjs/components/header/Header.js +2 -3
  5. package/dist/cjs/components/header/Header.js.map +1 -1
  6. package/dist/cjs/components/publish-wizard/PublishWizard.d.ts +8 -0
  7. package/dist/cjs/components/publish-wizard/PublishWizard.js +156 -94
  8. package/dist/cjs/components/publish-wizard/PublishWizard.js.map +1 -1
  9. package/dist/cjs/constants/copy.d.ts +3 -0
  10. package/dist/cjs/constants/copy.js +3 -0
  11. package/dist/cjs/constants/copy.js.map +1 -1
  12. package/dist/cjs/constants/icons.d.ts +1 -0
  13. package/dist/cjs/constants/icons.js +3 -1
  14. package/dist/cjs/constants/icons.js.map +1 -1
  15. package/dist/cjs/constants/publish.d.ts +27 -0
  16. package/dist/cjs/constants/publish.js +33 -1
  17. package/dist/cjs/constants/publish.js.map +1 -1
  18. package/dist/cjs/redux/actions/asset-list.js +1 -1
  19. package/dist/cjs/redux/actions/asset-list.js.map +1 -1
  20. package/dist/cjs/redux/actions/publish.d.ts +1 -1
  21. package/dist/cjs/redux/actions/publish.js +2 -2
  22. package/dist/cjs/redux/actions/publish.js.map +1 -1
  23. package/dist/cjs/services/API.d.ts +7 -5
  24. package/dist/cjs/services/API.js +16 -13
  25. package/dist/cjs/services/API.js.map +1 -1
  26. package/dist/esm/components/app-wrapper/AppWrapper.js +11 -14
  27. package/dist/esm/components/app-wrapper/AppWrapper.js.map +1 -1
  28. package/dist/esm/components/header/Header.js +2 -3
  29. package/dist/esm/components/header/Header.js.map +1 -1
  30. package/dist/esm/components/publish-wizard/PublishWizard.d.ts +8 -0
  31. package/dist/esm/components/publish-wizard/PublishWizard.js +152 -92
  32. package/dist/esm/components/publish-wizard/PublishWizard.js.map +1 -1
  33. package/dist/esm/constants/copy.d.ts +3 -0
  34. package/dist/esm/constants/copy.js +3 -0
  35. package/dist/esm/constants/copy.js.map +1 -1
  36. package/dist/esm/constants/icons.d.ts +1 -0
  37. package/dist/esm/constants/icons.js +2 -0
  38. package/dist/esm/constants/icons.js.map +1 -1
  39. package/dist/esm/constants/publish.d.ts +27 -0
  40. package/dist/esm/constants/publish.js +32 -0
  41. package/dist/esm/constants/publish.js.map +1 -1
  42. package/dist/esm/redux/actions/asset-list.js +1 -1
  43. package/dist/esm/redux/actions/asset-list.js.map +1 -1
  44. package/dist/esm/redux/actions/publish.d.ts +1 -1
  45. package/dist/esm/redux/actions/publish.js +2 -2
  46. package/dist/esm/redux/actions/publish.js.map +1 -1
  47. package/dist/esm/services/API.d.ts +7 -5
  48. package/dist/esm/services/API.js +16 -13
  49. package/dist/esm/services/API.js.map +1 -1
  50. package/dist/styles.css +27 -10
  51. package/dist/styles.less +33 -14
  52. package/less/components/data-table.less +1 -0
  53. package/less/components/header.less +6 -5
  54. package/less/components/publish-wizard.less +26 -9
  55. package/package.json +1 -1
  56. package/src/components/app-wrapper/AppWrapper.tsx +11 -14
  57. package/src/components/header/Header.tsx +2 -4
  58. package/src/components/publish-wizard/PublishWizard.tsx +219 -119
  59. package/src/components/publish-wizard/publish/CrMPublishCreativeSelectCell.tsx +29 -0
  60. package/src/components/publish-wizard/publish/CrMPublishCreativeSelectHeader.tsx +33 -0
  61. package/src/components/publish-wizard/publish/CrMPublishNameCell.tsx +27 -0
  62. package/src/components/publish-wizard/publish/CrMPublishPreviewCell.tsx +27 -0
  63. package/src/components/publish-wizard/publish/CrMPublishStatusCell.tsx +13 -0
  64. package/src/components/publish-wizard/publish/CrMPublishUI.tsx +211 -0
  65. package/src/constants/copy.ts +3 -0
  66. package/src/constants/icons.tsx +3 -0
  67. package/src/constants/publish.ts +36 -0
  68. package/src/redux/actions/asset-list.ts +1 -1
  69. package/src/redux/actions/publish.ts +2 -2
  70. package/src/services/API.ts +39 -23
@@ -10,7 +10,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
10
10
  import { faExclamationTriangle } from '@fortawesome/pro-light-svg-icons';
11
11
  import { initPendo } from '../../utils/pendo';
12
12
  import { TOKEN_TYPE, FlagsProvider } from '@innovid/feature-flags-react';
13
- import { useMemo } from 'react';
14
13
 
15
14
  export interface IAppWrapperProps {
16
15
  appLabel: string;
@@ -251,7 +250,7 @@ export const AppWrapper: React.FC<IAppWrapperProps> = (props) => {
251
250
  if (crmApi && crmBaseUrl) {
252
251
  crmApi.init(crmBaseUrl, getAccessTokenSilently);
253
252
  }
254
- api.getAccessData(false)
253
+ api.getAccessData(false, storyId)
255
254
  .then((freshAccess: any) => {
256
255
  props.setAccessData(freshAccess);
257
256
  propagateCreds(freshAccess);
@@ -259,7 +258,7 @@ export const AppWrapper: React.FC<IAppWrapperProps> = (props) => {
259
258
  .catch((e: Error) => {
260
259
  setErrorState(APP_WRAPPER_ERROR_STATES.UNAUTHORIZED_ORG);
261
260
 
262
- // Attempt to get the access data again without the org ID, so we can at least shoe the user the org dropdown
261
+ // Attempt to get the access data again without the org ID, so we can at least show the user the org dropdown
263
262
  api.init(baseUrl, getAccessTokenSilently, null);
264
263
  if (crmApi && crmBaseUrl) {
265
264
  crmApi.init(crmBaseUrl, getAccessTokenSilently);
@@ -295,17 +294,15 @@ export const AppWrapper: React.FC<IAppWrapperProps> = (props) => {
295
294
  innerContent = children;
296
295
  }
297
296
 
298
- const featureFlagsConfig = useMemo(() => {
299
- return {
300
- gatewayUrl: baseUrl,
301
- gatewayToken: auth0Token,
302
- projectId: growthBookId,
303
- tokenType: TOKEN_TYPE.AUTH0_BEARER,
304
- initialContext: {
305
- email: user?.userEmail
306
- }
307
- };
308
- }, [baseUrl, auth0Token, growthBookId, user?.userEmail]);
297
+ const featureFlagsConfig = {
298
+ gatewayUrl: baseUrl,
299
+ gatewayToken: auth0Token,
300
+ projectId: growthBookId,
301
+ tokenType: TOKEN_TYPE.AUTH0_BEARER,
302
+ initialContext: {
303
+ email: user?.userEmail
304
+ }
305
+ };
309
306
 
310
307
  const content = (
311
308
  <div
@@ -544,11 +544,9 @@ class ImposiumHeader extends React.PureComponent<IHeaderProps, IHeaderState> {
544
544
  </span>
545
545
 
546
546
  <span className='inner-right'>
547
+ {CrMLink}
547
548
  {storyToggle}
548
- <div className='additional-buttons'>
549
- {additionalButtons}
550
- {CrMLink}
551
- </div>
549
+ <div className='additional-buttons'>{additionalButtons}</div>
552
550
  {accountDropdownToggle}
553
551
  <a
554
552
  href='https://support.flashtalking.com/hc/en-us/sections/25515903148819-Imposium'
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { CrMPublishUI } from './publish/CrMPublishUI';
2
3
  import Button from '../button/Button';
3
4
  import SelectField from '../select-field/SelectField';
4
5
  import HRule from '../h-rule/HRule';
@@ -23,6 +24,8 @@ import PublishStatusIndicator from './publish/PublishStatusIndicator';
23
24
  import { bindActionCreators } from 'redux';
24
25
  import { publishVersion } from '../../redux/actions/publish';
25
26
  import { connect } from 'react-redux';
27
+ import { CRM_INTEGRATED_PROJECT_TYPES } from '../../constants/publish';
28
+ import { useFlag } from '@innovid/feature-flags-react';
26
29
 
27
30
  interface IPublishWizardProps {
28
31
  fromCrM?: boolean;
@@ -34,7 +37,7 @@ interface IPublishWizardProps {
34
37
  checkStoryForErrors(): any;
35
38
  addViewer(c: any): void;
36
39
  exportExperiences: () => void;
37
- publishVersion: (api: IImposiumAPI, sId: string) => any;
40
+ publishVersion: (api: IImposiumAPI, sId: string, creativeIds?: string[]) => any;
38
41
  batchesList: any;
39
42
  onClose(): any;
40
43
  api: IImposiumAPI;
@@ -94,6 +97,7 @@ interface IPublishWizardState {
94
97
  next: boolean;
95
98
  nextStep: boolean;
96
99
  publishError: string;
100
+ selectedCreatives: string[];
97
101
  }
98
102
 
99
103
  interface IBigButtonProps {
@@ -140,7 +144,8 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
140
144
  error: false,
141
145
  next: false,
142
146
  nextStep: false,
143
- publishError: null
147
+ publishError: null,
148
+ selectedCreatives: []
144
149
  };
145
150
  this.emailWorkflow = React.createRef();
146
151
  this.hiddenFileInputRef = React.createRef();
@@ -301,7 +306,7 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
301
306
 
302
307
  if (fromCrM) {
303
308
  this.props
304
- .publishVersion(api, id)
309
+ .publishVersion(api, id, this.state.selectedCreatives)
305
310
  .then(() => {
306
311
  this.setState({ screenIndex: 1 });
307
312
  })
@@ -331,15 +336,37 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
331
336
  const { story, project, fromCrM } = this.props;
332
337
  const variables = story ? story.acts[project.actId].inventory : {};
333
338
  const varLength = variables ? Object.keys(variables).length : 0;
339
+ const projectType = story.creativeId
340
+ ? CRM_INTEGRATED_PROJECT_TYPES.SINGLE_CREATIVE
341
+ : CRM_INTEGRATED_PROJECT_TYPES.MULTI_CREATIVE;
334
342
 
335
343
  if (fromCrM && varLength === 0) {
336
344
  return true;
345
+ } else if (
346
+ fromCrM &&
347
+ this.state.selectedCreatives.length === 0 &&
348
+ projectType === CRM_INTEGRATED_PROJECT_TYPES.MULTI_CREATIVE
349
+ ) {
350
+ return true;
337
351
  }
338
352
  return false;
339
353
  }
340
354
 
355
+ private getErrorCopyForCrMPublish() {
356
+ const { story, project } = this.props;
357
+ const variables = story ? story.acts[project.actId].inventory : {};
358
+ const varLength = variables ? Object.keys(variables).length : 0;
359
+
360
+ if (varLength === 0) {
361
+ return copy.publish.noVariablesError;
362
+ } else if (this.state.selectedCreatives.length === 0) {
363
+ return null;
364
+ }
365
+ }
366
+
341
367
  private renderLowerButtons() {
342
368
  const { screenIndex, done, error, next } = this.state;
369
+ const { fromCrM, story } = this.props;
343
370
  const { publishing } = this.props.publishData;
344
371
  const disabledForCrM = this.shouldDisablePublishButtonForCrM();
345
372
  const lowerButtons = [];
@@ -347,6 +374,15 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
347
374
  // publish and skip buttons
348
375
  if (screenIndex === 0) {
349
376
  // publish
377
+
378
+ const projectType = story.creativeId
379
+ ? CRM_INTEGRATED_PROJECT_TYPES.SINGLE_CREATIVE
380
+ : CRM_INTEGRATED_PROJECT_TYPES.MULTI_CREATIVE;
381
+ const btnCopy = fromCrM
382
+ ? projectType === CRM_INTEGRATED_PROJECT_TYPES.MULTI_CREATIVE
383
+ ? `Publish to ${this.state.selectedCreatives.length} Creatives`
384
+ : 'Publish to Creative Manager'
385
+ : copy.publish.btnPublish;
350
386
  lowerButtons.push(
351
387
  <Button
352
388
  tooltip={copy.publish.btnPublish}
@@ -355,7 +391,7 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
355
391
  key='btn-publish'
356
392
  onClick={() => this.handlePublish()}
357
393
  color='primary'>
358
- {copy.publish.btnPublish}
394
+ {btnCopy}
359
395
  </Button>
360
396
  );
361
397
 
@@ -434,28 +470,47 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
434
470
  }
435
471
 
436
472
  private renderPublish() {
473
+ const { fromCrM, story } = this.props;
437
474
  const { publishing } = this.props.publishData;
438
- const disabledForCrM = this.shouldDisablePublishButtonForCrM();
439
475
  const { publishError } = this.state;
440
- const errorCopy = publishError
441
- ? publishError
442
- : disabledForCrM
443
- ? copy.publish.noVariablesError
444
- : null;
445
-
476
+ const errorCopyForCrM = this.getErrorCopyForCrMPublish();
477
+ const errorCopy = publishError ? publishError : errorCopyForCrM ? errorCopyForCrM : null;
478
+ const projectType = story.creativeId
479
+ ? CRM_INTEGRATED_PROJECT_TYPES.SINGLE_CREATIVE
480
+ : CRM_INTEGRATED_PROJECT_TYPES.MULTI_CREATIVE;
446
481
  const error = errorCopy ? (
447
482
  <p className='publish-error'>
448
483
  <span className='icon'>{ICON_EXCLAIMATION_TRIANGLE}</span>&nbsp;&nbsp;{errorCopy}
449
484
  </p>
450
485
  ) : null;
451
- return (
452
- <div>
453
- <h2>{copy.publish.publishStepTitle}</h2>
454
- <HRule />
455
- <p>{publishing ? copy.publish.publishInProgress : copy.publish.publishStepDesc}</p>
456
- {error}
457
- </div>
458
- );
486
+
487
+ if (fromCrM) {
488
+ return (
489
+ <CrMPublishUI
490
+ projectType={projectType}
491
+ selectedCreatives={this.state.selectedCreatives}
492
+ onUpdateSelectedCreatives={(c) => this.setState({ selectedCreatives: c })}
493
+ onError={(e) => this.setState({ publishError: e })}
494
+ publishing={publishing}
495
+ error={error}
496
+ creativeLibraryId={story.creativeLibraryId}
497
+ projectId={story.id}
498
+ api={this.props.api}
499
+ crmBaseUrl={this.props.creativeManagerBaseUrl}
500
+ />
501
+ );
502
+ } else {
503
+ return (
504
+ <div>
505
+ <h2>{copy.publish.publishStepTitle}</h2>
506
+ <HRule />
507
+ <p>
508
+ {publishing ? copy.publish.publishInProgress : copy.publish.publishStepDesc}
509
+ </p>
510
+ {error}
511
+ </div>
512
+ );
513
+ }
459
514
  }
460
515
 
461
516
  private renderDistributionOptions() {
@@ -487,86 +542,6 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
487
542
  });
488
543
  }
489
544
 
490
- let distributionOptions = !fromCrM
491
- ? [
492
- {
493
- label: (
494
- <span>
495
- {ICON_GLOBE}&nbsp;{copy.publish.btnWebsite}
496
- </span>
497
- ),
498
- onClick: (e) => this.onSelectOption(2)
499
- },
500
- {
501
- label: (
502
- <span>
503
- {ICON_EMAIL}&nbsp;{copy.publish.btnEmail}
504
- </span>
505
- ),
506
- onClick: (e) => this.onSelectOption(3)
507
- },
508
- {
509
- label: (
510
- <span>
511
- {ICON_HUBSPOT}&nbsp;{copy.publish.btnHubspot}
512
- </span>
513
- ),
514
- onClick: (e) => this.onSelectOption(5)
515
- },
516
- {
517
- label: (
518
- <span>
519
- {ICON_PROJECT_DIAGRAM}&nbsp;{copy.publish.btnAPI}
520
- </span>
521
- ),
522
- onClick: (e) => this.onSelectOption(6)
523
- },
524
- {
525
- label: (
526
- <span>
527
- {ICON_DOWNLOAD}&nbsp;{copy.publish.btnExport}
528
- </span>
529
- ),
530
- onClick: (e) => this.onSelectOption(7)
531
- },
532
- {
533
- label: (
534
- <span>
535
- {ICON_IMAGE}&nbsp;{copy.publish.btnCRM}
536
- </span>
537
- ),
538
- onClick: (e) => this.onSelectOption(8)
539
- }
540
- ]
541
- : [
542
- {
543
- label: (
544
- <span>
545
- {ICON_DOWNLOAD}&nbsp;{copy.publish.btnRunTestBatch}
546
- </span>
547
- ),
548
- onClick: (e) => this.onSelectOption(7)
549
- },
550
- {
551
- label: (
552
- <span>
553
- {ICON_UP_RIGHT_FROM_SQUARE}&nbsp;{copy.publish.btnCrM}
554
- </span>
555
- ),
556
- link: `${creativeManagerBaseUrl}/library/${story.creativeLibraryId}/creative/${story.creativeId}/versions/`
557
- }
558
- ];
559
-
560
- if (publishDataset) {
561
- const indexes = [0, 2, 3];
562
- distributionOptions = distributionOptions.reduce((acc, value, index) => {
563
- if (!indexes.includes(index)) {
564
- acc.push(value);
565
- }
566
- return acc;
567
- }, []);
568
- }
569
-
570
545
  const compDropdown = !fromCrM ? (
571
546
  <SelectField
572
547
  label={copy.project.compName}
@@ -609,26 +584,14 @@ class PublishWizard extends React.PureComponent<IPublishWizardProps, IPublishWiz
609
584
  {accessKeyDropdown}
610
585
 
611
586
  <div className='link-wrapper'>
612
- {distributionOptions?.map((option: any, index) => {
613
- if (option.link) {
614
- return (
615
- <BigLink
616
- key={index}
617
- label={option.label}
618
- link={option.link}
619
- />
620
- );
621
- } else {
622
- return (
623
- <BigButton
624
- key={index}
625
- disabled={!selectedComposition}
626
- label={option.label}
627
- onClick={option.onClick}
628
- />
629
- );
630
- }
631
- })}
587
+ <DistributeOptions
588
+ story={story}
589
+ fromCrM={fromCrM}
590
+ onSelectOption={this.onSelectOption}
591
+ selectedComposition={selectedComposition}
592
+ publishDataset={publishDataset}
593
+ creativeManagerBaseUrl={creativeManagerBaseUrl}
594
+ />
632
595
  </div>
633
596
  </div>
634
597
  </div>
@@ -816,3 +779,140 @@ export const BigLink: React.FC<IBigLinkProps> = (p: IBigLinkProps) => {
816
779
  </a>
817
780
  );
818
781
  };
782
+
783
+ export const DistributeOptions = ({
784
+ story,
785
+ fromCrM,
786
+ onSelectOption,
787
+ selectedComposition,
788
+ publishDataset,
789
+ creativeManagerBaseUrl
790
+ }) => {
791
+ const isPrerendersEnabled = useFlag('feature.IMPOSIUM_EDITOR.PRERENDERS_CRM_WORKFLOW');
792
+
793
+ const getCrMLink = (creativeLibraryId: string, creativeId?: string) => {
794
+ if (creativeId) {
795
+ return `${creativeManagerBaseUrl}/library/${creativeLibraryId}/creative/${creativeId}/versions/`;
796
+ } else {
797
+ return `${creativeManagerBaseUrl}/library/${creativeLibraryId}`;
798
+ }
799
+ };
800
+
801
+ let distributionOptions: any = !fromCrM
802
+ ? [
803
+ {
804
+ label: (
805
+ <span>
806
+ {ICON_GLOBE}&nbsp;{copy.publish.btnWebsite}
807
+ </span>
808
+ ),
809
+ onClick: (e) => onSelectOption(2)
810
+ },
811
+ {
812
+ label: (
813
+ <span>
814
+ {ICON_EMAIL}&nbsp;{copy.publish.btnEmail}
815
+ </span>
816
+ ),
817
+ onClick: (e) => onSelectOption(3)
818
+ },
819
+ {
820
+ label: (
821
+ <span>
822
+ {ICON_HUBSPOT}&nbsp;{copy.publish.btnHubspot}
823
+ </span>
824
+ ),
825
+ onClick: (e) => onSelectOption(5)
826
+ },
827
+ {
828
+ label: (
829
+ <span>
830
+ {ICON_PROJECT_DIAGRAM}&nbsp;{copy.publish.btnAPI}
831
+ </span>
832
+ ),
833
+ onClick: (e) => onSelectOption(6)
834
+ },
835
+ {
836
+ label: (
837
+ <span>
838
+ {ICON_DOWNLOAD}&nbsp;{copy.publish.btnExport}
839
+ </span>
840
+ ),
841
+ onClick: (e) => onSelectOption(7)
842
+ },
843
+ {
844
+ label: (
845
+ <span>
846
+ {ICON_IMAGE}&nbsp;{copy.publish.btnCRM}
847
+ </span>
848
+ ),
849
+ onClick: (e) => onSelectOption(8)
850
+ }
851
+ ]
852
+ : [
853
+ {
854
+ label: (
855
+ <span>
856
+ {ICON_DOWNLOAD}&nbsp;{copy.publish.btnRunTestBatch}
857
+ </span>
858
+ ),
859
+ onClick: (e) => onSelectOption(7)
860
+ },
861
+ {
862
+ label: (
863
+ <span>
864
+ {ICON_UP_RIGHT_FROM_SQUARE}&nbsp;{copy.publish.btnCrM}
865
+ </span>
866
+ ),
867
+ link: getCrMLink(story.creativeLibraryId, story.creativeId)
868
+ }
869
+ ];
870
+
871
+ if (publishDataset) {
872
+ const indexes = [0, 2, 3];
873
+ distributionOptions = distributionOptions.reduce((acc, value, index) => {
874
+ if (!indexes.includes(index)) {
875
+ acc.push(value);
876
+ }
877
+ return acc;
878
+ }, []);
879
+ }
880
+
881
+ if (fromCrM && isPrerendersEnabled) {
882
+ distributionOptions.push({
883
+ label: (
884
+ <span>
885
+ {ICON_IMAGE}&nbsp;{copy.publish.btnCRM}
886
+ </span>
887
+ ),
888
+ onClick: (e) => onSelectOption(8),
889
+ style: { width: 'calc(100% - 4px)' }
890
+ });
891
+ }
892
+
893
+ return (
894
+ <>
895
+ {distributionOptions?.map((option: any, index) => {
896
+ if (option.link) {
897
+ return (
898
+ <BigLink
899
+ key={index}
900
+ label={option.label}
901
+ link={option.link}
902
+ />
903
+ );
904
+ } else {
905
+ return (
906
+ <BigButton
907
+ key={index}
908
+ disabled={!selectedComposition}
909
+ label={option.label}
910
+ onClick={option.onClick}
911
+ style={option.style}
912
+ />
913
+ );
914
+ }
915
+ })}
916
+ </>
917
+ );
918
+ };
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import CheckboxField from '../../checkbox-field/CheckboxField';
3
+ import { canBePublishedTo } from './CrMPublishUI';
4
+ interface ICrMPublishCreativeSelectCellProps {
5
+ cell: any;
6
+ onSelectChange: (creativeId: string, selected: boolean) => void;
7
+ selectedCreatives: string[];
8
+ }
9
+
10
+ export const CrMPublishCreativeSelectCell: React.FC<ICrMPublishCreativeSelectCellProps> = (
11
+ props
12
+ ) => {
13
+ const { cell, onSelectChange, selectedCreatives } = props;
14
+ const creativeId = cell.row.original.creativeId;
15
+ const isSelected = selectedCreatives.includes(creativeId);
16
+ const showCheckbox = canBePublishedTo(cell.row.original.approvalStatus);
17
+ if (showCheckbox) {
18
+ return (
19
+ <CheckboxField
20
+ label=''
21
+ propagate={false}
22
+ value={isSelected}
23
+ onChange={(selected) => onSelectChange(creativeId, selected)}
24
+ />
25
+ );
26
+ } else {
27
+ return null;
28
+ }
29
+ };
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ import CheckboxField from '../../checkbox-field/CheckboxField';
3
+ import { canBePublishedTo } from './CrMPublishUI';
4
+
5
+ interface ICrMPublishCreativeSelectHeaderProps {
6
+ onSelectChange: (selected: boolean) => void;
7
+ selectedCreatives: string[];
8
+ creativeConfig: any[];
9
+ }
10
+
11
+ export const CrMPublishCreativeSelectHeader: React.FC<ICrMPublishCreativeSelectHeaderProps> = (
12
+ props
13
+ ) => {
14
+ const { onSelectChange, selectedCreatives, creativeConfig } = props;
15
+
16
+ const publishableCreatives = creativeConfig.filter((creative) =>
17
+ canBePublishedTo(creative.approvalStatus)
18
+ );
19
+
20
+ const publishableCreativeIds = publishableCreatives.map((creative) => creative.creativeId);
21
+ const allPublishableSelected =
22
+ publishableCreativeIds.length > 0 &&
23
+ publishableCreativeIds.every((id) => selectedCreatives.includes(id));
24
+
25
+ return (
26
+ <CheckboxField
27
+ label=''
28
+ propagate={false}
29
+ value={allPublishableSelected}
30
+ onChange={(selected) => onSelectChange(selected)}
31
+ />
32
+ );
33
+ };
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import { renderTooltip, renderTooltipProps } from '../../Tooltip';
3
+ import { canBePublishedTo } from './CrMPublishUI';
4
+ import * as copy from '../../../constants/copy';
5
+
6
+ interface ICrMPublishNameCellProps {
7
+ cell: any;
8
+ }
9
+
10
+ export const CrMPublishNameCell: React.FC<ICrMPublishNameCellProps> = (props) => {
11
+ const { cell } = props;
12
+ const canBePublished = canBePublishedTo(cell.row.original.approvalStatus);
13
+ const tooltipId = `publish-name-${cell.row.original.creativeId}`;
14
+
15
+ if (canBePublished) {
16
+ return <div className={`crm-publish-name`}>{cell.row.original.creativeName}</div>;
17
+ } else {
18
+ return (
19
+ <div
20
+ className={`crm-publish-name disabled`}
21
+ {...renderTooltipProps(tooltipId, copy.publish.disabledCreativeTooltip)}>
22
+ {cell.row.original.creativeName}
23
+ {renderTooltip(tooltipId, copy.publish.disabledCreativeTooltip)}
24
+ </div>
25
+ );
26
+ }
27
+ };
@@ -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
+ };