@imposium-hub/components 1.40.0 → 1.41.1

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.
@@ -0,0 +1,255 @@
1
+ import * as React from 'react';
2
+ import HRule from '../../h-rule/HRule';
3
+ import Spinner from '../../spinner/Spinner';
4
+ import * as copy from '../../../constants/copy';
5
+ import {BigButton} from '../PublishWizard';
6
+ import { ExportToCsv } from 'export-to-csv';
7
+ import { ICON_DOWNLOAD, ICON_UPLOAD } from '../../../constants/icons';
8
+ import * as moment from 'moment';
9
+ import {IImposiumAPI} from '../../../services/API';
10
+
11
+ interface IEmailWorkflowProps {
12
+ story : any;
13
+ createFreshBatch : (e : string) => any;
14
+ getBatches : () => any;
15
+ getBatchExport : (batchId : string) => any;
16
+ importBatchFromCsv : (storyId : string, batchId : string, batchName : string, csvFile : File, accessKey : string, compId : string, embed : boolean) => any;
17
+ renderBatch : (batchId : string, batchName : string) => any;
18
+ status : string;
19
+ accessKey : string;
20
+ compositionId : string;
21
+ compositionName : string;
22
+ onDone : () => void;
23
+ api : IImposiumAPI;
24
+ handleError : (e) => any;
25
+ batchJobs : any;
26
+ isExport ? : boolean;
27
+ }
28
+
29
+ interface IEmailWorkflowState {
30
+ uploadComplete : boolean;
31
+ selectedBatchId : string;
32
+ uploading : boolean;
33
+ downloading : boolean;
34
+ renderedBatch : boolean;
35
+ }
36
+
37
+ class EmailWorkflow extends React.PureComponent<IEmailWorkflowProps, IEmailWorkflowState> {
38
+ private readonly hiddenFileInputRef : any;
39
+ private static readonly PROGRESS_MAX_VALUE : number = 100;
40
+ private static readonly CSV_EXPORT_CONFIG : any = {
41
+ fieldSeparator: ',',
42
+ quoteStrings: '"',
43
+ decimalSeparator: '.',
44
+ showLabels: false,
45
+ showTitle: false,
46
+ useTextFile: false,
47
+ useBom: true,
48
+ useKeysAsHeaders: true
49
+ };
50
+ constructor(props) {
51
+ super(props);
52
+ this.state = {
53
+ uploadComplete: false,
54
+ uploading: false,
55
+ downloading : false,
56
+ selectedBatchId: '',
57
+ renderedBatch: false,
58
+ };
59
+ this.hiddenFileInputRef = React.createRef();
60
+ }
61
+
62
+ public downloadSampleCsv() {
63
+
64
+ const {name} = this.props.story;
65
+ const {acts} = this.props.story;
66
+ const actsKeys : string[] = Object.keys(acts);
67
+ let inventory : any = {};
68
+
69
+ actsKeys.forEach((actKey : string) => {
70
+ inventory = {...inventory, ...acts[actKey].inventory};
71
+ });
72
+
73
+ const inventoryKeys : string[] = Object.keys(inventory).sort();
74
+ const maskConfig : any[] = inventoryKeys.map((currKey : string) => ({
75
+ id: currKey,
76
+ name: inventory[currKey].name,
77
+ show: true
78
+ }));
79
+
80
+ const emptyRow : any = maskConfig.map((m : any) => (m.id))
81
+ .reduce((prevState : any, currId : string) => ({...prevState, [currId]: ''}), {});
82
+
83
+ const filename = `${alphaNumeric(name)}-batch-template.csv`;
84
+ const exporter = new ExportToCsv({
85
+ ...EmailWorkflow.CSV_EXPORT_CONFIG,
86
+ filename
87
+ });
88
+
89
+ exporter.generateCsv([emptyRow]);
90
+ }
91
+
92
+ private selectCsv = () : void => {
93
+ if (this.hiddenFileInputRef.current) {
94
+ this.hiddenFileInputRef.current.click();
95
+ }
96
+ }
97
+
98
+ private getBatchName() {
99
+
100
+ const {story: {name}, compositionName} = this.props;
101
+ const date = Date.now();
102
+ const dateStr = moment(date).format('MMDDYY-HHmm');
103
+ const batchName = `${alphaNumeric(name)}-${alphaNumeric(compositionName)}-${dateStr}`;
104
+ return batchName;
105
+ }
106
+
107
+ private doUploadCsv = (uploadEvt) : void => {
108
+ uploadEvt.persist();
109
+ const {handleError} = this.props;
110
+ this.setState({
111
+ uploading: true,
112
+ renderedBatch: false,
113
+ });
114
+ this.props.createFreshBatch(this.getBatchName())
115
+ .then((res) => {
116
+ const {id, name, story_id} = res;
117
+ this.setState({selectedBatchId: id});
118
+ this.importBatch({story_id, id, name, uploadEvt});
119
+ })
120
+ .catch((e) => {
121
+ handleError(e);
122
+ this.setState({uploadComplete: false, uploading: false});
123
+ throw e;
124
+ });
125
+ }
126
+
127
+ private importBatch({story_id, id, name, uploadEvt}) {
128
+ const {accessKey, compositionId, isExport, handleError} = this.props;
129
+ this.props.importBatchFromCsv(story_id, id, name, uploadEvt.target.files[0], accessKey, compositionId, !isExport)
130
+ .then(() => {
131
+ this.setState({uploadComplete: true, uploading: false});
132
+ if (isExport) {
133
+ this.renderBatch({id, name});
134
+ }
135
+ })
136
+ .catch((e) => {
137
+ const {status, data} = e.response;
138
+
139
+ if (status === 400) {
140
+ handleError(copy.publish.missingColumns);
141
+ alert(copy.publish.csvMissingColumns + data.error);
142
+ }
143
+ this.setState({uploadComplete: false, uploading: false});
144
+ throw e;
145
+ });
146
+ }
147
+
148
+ private renderBatch({id, name}) {
149
+ this.props.renderBatch(id, name).then(() => {
150
+ this.setState({renderedBatch: true});
151
+ }).catch((e) => {
152
+ this.props.handleError(copy.publish.renderBatchFailed);
153
+ this.setState({renderedBatch: false});
154
+ throw e;
155
+ });
156
+ }
157
+
158
+ public downloadCsv() {
159
+ this.setState({
160
+ downloading: true
161
+ }, () => {
162
+ const {status, api, handleError} = this.props;
163
+ const {selectedBatchId} = this.state;
164
+ if (status === copy.header.publishing) {
165
+ handleError(copy.publish.downloadError);
166
+ return;
167
+ }
168
+ this.props.getBatchExport(selectedBatchId).then(() => {
169
+ this.props.onDone();
170
+ this.setState({
171
+ downloading: false
172
+ });
173
+ });
174
+ });
175
+ }
176
+
177
+ public renderLabel() {
178
+ const {isExport, batchJobs} = this.props;
179
+ const {renderedBatch, selectedBatchId, uploading, uploadComplete} = this.state;
180
+ if (isExport && uploadComplete && !renderedBatch) {
181
+ return (
182
+ <span className={'progress-bar'}>
183
+ <progress
184
+ max = {EmailWorkflow.PROGRESS_MAX_VALUE}
185
+ value = {batchJobs.renders[selectedBatchId]}
186
+ />
187
+ </span>
188
+ );
189
+ }
190
+ if (uploading) {
191
+ const uploadingCopy = (isExport) ? copy.publish.importingData : copy.publish.creatingLinks;
192
+ return <span><Spinner/>&nbsp;{uploadingCopy}</span>;
193
+ }
194
+ return <span>{ICON_UPLOAD}&nbsp;{copy.publish.uploadCsv}</span>;
195
+ }
196
+
197
+ public render() {
198
+ const {uploadComplete, uploading, downloading, renderedBatch, selectedBatchId} = this.state;
199
+ const {isExport} = this.props;
200
+
201
+ const emailOptions = [
202
+ {
203
+ label: <span>{ICON_DOWNLOAD}&nbsp;{copy.publish.downloadSampleCsvLink}</span>,
204
+ onClick: () => this.downloadSampleCsv(),
205
+ key: 'download-sample'
206
+ },
207
+ {
208
+ label: this.renderLabel(),
209
+ onClick: () => this.selectCsv(),
210
+ key: 'upload',
211
+ disabled: isExport ? uploadComplete || uploading : uploading,
212
+ },
213
+ ];
214
+ const downloadCsvLabel = (downloading) ? <span><Spinner/>&nbsp;{copy.publish.exporting}</span> : <span>{ICON_DOWNLOAD}&nbsp;{copy.publish.btnDownload}</span>;
215
+
216
+ const downloadCSV = (
217
+ <div>
218
+ <h2>{uploadComplete ? copy.publish.downloadLink : copy.publish.generatingLink}</h2>
219
+ <HRule/>
220
+ <p>{uploadComplete ? copy.publish.downloadDesc : copy.publish.generatingLinkDesc}</p>
221
+ <BigButton
222
+ label={downloadCsvLabel}
223
+ disabled = {downloading}
224
+ onClick={() => this.downloadCsv()}/>
225
+ </div>
226
+ );
227
+
228
+ const uploadCSV = <div>
229
+ <h2>{copy.publish.emailTitle}</h2>
230
+ <HRule/>
231
+ <p>{copy.publish.emailDesc}</p>
232
+ <input
233
+ type='file'
234
+ style={{display: 'none'}}
235
+ accept='text/csv'
236
+ ref={this.hiddenFileInputRef}
237
+ onChange={this.doUploadCsv}/>
238
+ {emailOptions?.map((option, index) => {
239
+ return <BigButton
240
+ label={<span>{option.label}</span>}
241
+ onClick={option.onClick}
242
+ disabled={option?.disabled}
243
+ key={option.key}/>;
244
+ })}
245
+ </div>;
246
+
247
+ return (isExport ? renderedBatch : uploadComplete) ? downloadCSV : uploadCSV;
248
+ }
249
+ }
250
+
251
+ const alphaNumeric = (str) => {
252
+ return str.replace(/\W/g, '');
253
+ };
254
+
255
+ export default EmailWorkflow;
@@ -0,0 +1,80 @@
1
+ import * as React from 'react';
2
+ import Button from '../../button/Button';
3
+ import TextAreaField from '../../text-area-field/TextAreaField';
4
+ import HRule from '../../h-rule/HRule';
5
+ import * as copy from '../../../constants/copy';
6
+ import {ICON_CLIPBOARD} from '../../../constants/icons';
7
+
8
+ interface IHubSpotFlowProps {
9
+ story : any;
10
+ status : string;
11
+ compositionId : string;
12
+ accessKey : string;
13
+ handleError(e) : void;
14
+ handleNotification? : (n) => void;
15
+ }
16
+
17
+ class HubSpotFlow extends React.PureComponent<IHubSpotFlowProps, undefined> {
18
+ constructor(props) {
19
+ super(props);
20
+ }
21
+
22
+ private createUrl() {
23
+ const { story, compositionId, accessKey} = this.props;
24
+ const storyId = story.id;
25
+ const act = this.getFirstAct(story);
26
+ const variables = act.inventory;
27
+ let queryString = '';
28
+
29
+ for (const key in variables) {
30
+ if (variables.hasOwnProperty(key)) {
31
+ const prefix = (queryString) ? '&' : '?';
32
+ queryString += `${prefix}${key}={{${key.toUpperCase()}}}`;
33
+ }
34
+ }
35
+
36
+ const href = window.location.href;
37
+ const root = (href.indexOf('staging') !== -1 || href.indexOf('localhost') !== -1) ? 'staging.imposium.com' : 'imposium.com';
38
+ const playerUrl = `https://player.${root}/new/${accessKey}/${storyId}/${compositionId}${queryString}`;
39
+ const posterUrl = `https://api.${root}/story/${storyId}/${compositionId}/poster${queryString}`;
40
+ return `<a href="${playerUrl}" target="_blank"><img width="400" alt="Play Video" src="${posterUrl}"></a>`;
41
+ }
42
+
43
+ private getFirstAct = (story) : any => {
44
+
45
+ for (const key in story.acts) {
46
+ if (story.acts.hasOwnProperty(key)) {
47
+ return story.acts[key];
48
+ }
49
+ }
50
+ }
51
+
52
+ public render() {
53
+ const {status, handleError, handleNotification} = this.props;
54
+ return (
55
+ <div>
56
+ <h2>{copy.publish.hubspotTitle}</h2>
57
+ <HRule/>
58
+ <p>{copy.publish.hubspotDesc}</p>
59
+ <HRule/>
60
+ <TextAreaField
61
+ label={copy.publish.embeddedCode}
62
+ value={this.createUrl()}
63
+ showCopy = {status !== copy.header.publishing}
64
+ onNotification = {(n) => handleNotification(n)}
65
+ onError = {(e) => handleError(e)}
66
+ readOnly = {true}/>
67
+ {status === copy.header.publishing &&
68
+ <Button size={'small'} customStyles={{margin: 0, height: '20px', border: 'none'}}
69
+ color='primary'
70
+ onClick={() => handleError(copy.publish.embeddedCodeCopyError)}
71
+ >
72
+ {ICON_CLIPBOARD}
73
+ </Button>
74
+ }
75
+ </div>
76
+ );
77
+ }
78
+ }
79
+
80
+ export default HubSpotFlow;
@@ -0,0 +1,84 @@
1
+ import * as React from 'react';
2
+ import { cancelPublish } from '../../../redux/actions/publish';
3
+ import { IImposiumAPI } from '../../../services/API';
4
+ import Spinner from '../../spinner/Spinner';
5
+ import { connect } from 'react-redux';
6
+ import { ICON_TIMES } from '../../../constants/icons';
7
+ import { bindActionCreators } from 'redux';
8
+
9
+ interface IPublishStatusIndicatorProps {
10
+ publishData : any;
11
+ cancelPublish(api : IImposiumAPI, storyId : string) : void;
12
+ api : IImposiumAPI;
13
+ }
14
+
15
+ interface IPublishStatusIndicatorStates {
16
+ hover : boolean;
17
+ publishing : boolean;
18
+ }
19
+ class PublishStatusIndicator extends React.PureComponent<IPublishStatusIndicatorProps, IPublishStatusIndicatorStates> {
20
+
21
+ constructor(props) {
22
+
23
+ super(props);
24
+
25
+ this.state = {
26
+ hover: false,
27
+ publishing: true,
28
+ };
29
+ }
30
+
31
+ public onEnterHandler() {
32
+ this.setState({hover: true});
33
+ }
34
+
35
+ public onLeaveHandler() {
36
+ this.setState({hover: false});
37
+ }
38
+
39
+ public cancelPublisingHandler() {
40
+ const { publishData: {story_id}, api } = this.props;
41
+ this.props.cancelPublish(api, story_id);
42
+ }
43
+
44
+ public render() {
45
+ const { publishing, version} = this.props.publishData;
46
+ const { hover } = this.state;
47
+
48
+ // nothing published yet, using working copy
49
+ if (!publishing && !version) {
50
+ return null;
51
+ } else {
52
+
53
+ let cta : any = '';
54
+ if (publishing) {
55
+ const newVersion = version || 0 + 1;
56
+ const publishingString = `v${newVersion} Publishing`;
57
+
58
+ cta = <span onMouseEnter={() => this.onEnterHandler()} onMouseLeave={() => this.onLeaveHandler()}>
59
+ {hover ?
60
+ <><span onClick={() => this.cancelPublisingHandler()} style={{cursor: 'pointer'}}>{ICON_TIMES}</span>{' '}{publishingString}</> :
61
+ <><Spinner/>{publishingString}</>
62
+ }
63
+ </span>;
64
+ } else {
65
+ cta = <span>{`v${version} Live`}</span>;
66
+ }
67
+
68
+ return <div className = 'publish-status-indicator'>
69
+ {cta}
70
+ </div>;
71
+ }
72
+
73
+ }
74
+ }
75
+
76
+ const mapStateToProps = (state) => ({
77
+ publishData: state.publish
78
+ });
79
+
80
+ const mapDispatchToProps = (dispatch) : any => {
81
+ return bindActionCreators({cancelPublish}, dispatch);
82
+ };
83
+
84
+ export default connect(mapStateToProps, mapDispatchToProps)(PublishStatusIndicator);
@@ -0,0 +1,120 @@
1
+ import * as React from 'react';
2
+ import * as copy from '../../../constants/copy';
3
+ import {BigLink, BigButton } from '../PublishWizard';
4
+ import {ICON_DOWNLOAD, ICON_GLOBE, ICON_JS, ICON_PROJECT_DIAGRAM} from '../../../constants/icons';
5
+ import {downloadSDKArchive, ISDKArchiveBody} from '../../../utils/template-generator';
6
+ import {getDemoURL} from '../../../utils/routing';
7
+ import HRule from '../../h-rule/HRule';
8
+
9
+ interface IWebpageHostedProps {
10
+ story : any;
11
+ accessKey : string;
12
+ compositionId : string;
13
+ }
14
+
15
+ export const documentationLinks = [
16
+ {
17
+ key: 'js-sdk-link',
18
+ label : <span>{ICON_JS}&nbsp;{copy.integration.js}</span>,
19
+ link : copy.integration.jsSdkLink
20
+ },
21
+ {
22
+ key: 'rest-link',
23
+ label : <span>{ICON_PROJECT_DIAGRAM}&nbsp;{copy.integration.rest}</span>,
24
+ link : copy.integration.restLink
25
+ },
26
+ ];
27
+
28
+ class WebpageHosted extends React.PureComponent<IWebpageHostedProps> {
29
+ constructor(props) {
30
+ super(props);
31
+ }
32
+
33
+ private downloadSampleWebPage = () => {
34
+ const { story, compositionId, accessKey } = this.props;
35
+ const firstAct : any = this.getFirstAct(story);
36
+ let archiveName : string;
37
+ let sdkExampleBody : ISDKArchiveBody;
38
+ if (
39
+ story.id &&
40
+ story.name &&
41
+ typeof firstAct !== 'undefined' &&
42
+ firstAct.hasOwnProperty('inventory')
43
+ ) {
44
+ archiveName = story.name + copy.integration.sdkArchiveSuffix;
45
+ sdkExampleBody = {
46
+ storyId: story.id,
47
+ compositionId,
48
+ storyName: story.name,
49
+ accessToken: accessKey,
50
+ inventory: firstAct.inventory
51
+ };
52
+
53
+ downloadSDKArchive(archiveName, sdkExampleBody);
54
+ }
55
+ }
56
+
57
+ private getFirstAct = (story) : any => {
58
+
59
+ for (const key in story.acts) {
60
+ if (story.acts.hasOwnProperty(key)) {
61
+ return story.acts[key];
62
+ }
63
+ }
64
+ }
65
+
66
+ private linkToDemoPage() {
67
+ const {accessKey, compositionId, story: {id}} = this.props;
68
+ if (accessKey) {
69
+ const demoUrl = `${getDemoURL()}/${accessKey}/${id}/${compositionId}`;
70
+ window.open(demoUrl, '_blank');
71
+ }
72
+ }
73
+
74
+ public render() {
75
+ const webPageOptions = [
76
+ {
77
+ label : <span>{ICON_GLOBE}&nbsp;{copy.publish.webPageHosted}</span>,
78
+ onClick: () => this.linkToDemoPage(),
79
+ },
80
+ {
81
+ label : <span>{ICON_DOWNLOAD}&nbsp;{copy.publish.sampleWebpage}</span>,
82
+ onClick: () => this.downloadSampleWebPage(),
83
+ },
84
+ ];
85
+
86
+ return (
87
+ <div>
88
+ <h2>{copy.publish.webpageTitle}</h2>
89
+ <HRule/>
90
+ <p>{copy.publish.webpageDesc}</p>
91
+ <HRule/>
92
+ {webPageOptions?.map((option, index) => {
93
+ return (
94
+ <BigButton
95
+ key={index}
96
+ label={option.label}
97
+ onClick={() => option.onClick()}
98
+ />
99
+ );
100
+ })}
101
+ <br/>
102
+ <br/>
103
+ <h2>{copy.integration.documentation}</h2>
104
+ <HRule/>
105
+ <p>{copy.integration.docParagraph}</p>
106
+ {documentationLinks?.map((link) => {
107
+ return (
108
+ <BigLink
109
+ key={link.key}
110
+ label = {link.label}
111
+ link = {link.link}
112
+ />
113
+ );
114
+ })}
115
+ </div>
116
+ );
117
+ }
118
+ }
119
+
120
+ export default WebpageHosted;
package/constants/copy.ts CHANGED
@@ -95,3 +95,103 @@ export const compositions = {
95
95
  textLayerContent: 'Content',
96
96
  tooltipTextLayerContent: 'The copy rendered in this layer. Wrap variables like so: {{variable_id}}.'
97
97
  };
98
+
99
+ export const publish = {
100
+ accessKey: 'Access Key',
101
+ tooltipAccessKey: 'API access key to use for this video distribution.',
102
+ publishTitle: 'Publish & Deliver',
103
+
104
+ // publish
105
+ publishStepTitle: 'STEP 1: Publish your Project',
106
+ publishStepDesc: '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.',
107
+
108
+ // distribute
109
+ distributeStepTitle: 'STEP 2: How do you want your users to view their video?',
110
+ distributeStepDesc: 'Select which Composition you want to deliver, access credentials you want to use, and distribution channel.',
111
+ compositionError: 'Please Select Composition',
112
+
113
+ // webpage
114
+ btnWebsite: 'Webpage',
115
+ webpageTitle: 'STEP 3: Webpage',
116
+ webPageHosted: 'Webpage hosted on Imposium',
117
+ webpageDesc: 'You can share a demo page that is hosted on Imposium or you can download a sample webpage you can customize and use to generate videos. Please ensure you include a column for every variable on your story.',
118
+ sampleWebpage: 'Download sample webpage',
119
+
120
+ // email
121
+ btnEmail: 'Email',
122
+ exporting: 'Exporting CSV... (please wait)',
123
+ emailTitle: 'STEP 3: Upload a CSV file with your user information in it.',
124
+ emailDesc: 'You can download a sample CSV with fields to populate as a starting point. Or you can upload one that already has the data in it.',
125
+ downloadSampleCsvLink: 'Download Sample CSV',
126
+ uploadCsv: 'Upload Your CSV UserList',
127
+ generatingLink: 'STEP 4: Generating embed links',
128
+ downloadLink: 'STEP 5: Download Your Userlist CSV file',
129
+ btnDownload: 'Download CSV',
130
+ generatingLinkDesc: 'Please wait while we generate the link for your users. This may take few minutes.',
131
+ missingColumns: 'Error: missing required columns',
132
+ renderBatchFailed: 'Error: Failed to render batch',
133
+ createBatchFailed: 'Error: Failed to create batch',
134
+ downloadError: 'Error downloading sample CSV.',
135
+ embeddedCodeCopyError: 'Error copying embed code.',
136
+ creatingLinks: 'Creating User Links... (please wait)',
137
+ importingData: 'Importing Data... (please wait)',
138
+ downloadDesc: 'Your CSV data file is ready to download with an embed code you can import into your email platform to send out.',
139
+ csvMissingColumns: 'Warning: Some of your column names did not match up with the variables in the story. Please ensure these variables line up and then re-upload the csv: ',
140
+ // export
141
+ exportBatchOfVideo: 'Export batch of videos',
142
+
143
+ // hubspot
144
+ btnHubspot: 'Hubspot',
145
+ hubspotTitle: 'STEP 3: Copy Hubspot code snippet',
146
+ hubspotDesc: 'Copy the provided embed code into HubSpot. Replace the placeholder variable values with HubSpot template strings, to splice in your user data.',
147
+ saveChanges: 'Save Changes',
148
+ embeddedCode: 'Embed Url: ',
149
+
150
+ // api
151
+ btnAPI: 'API integration',
152
+
153
+ // global
154
+ btnPublish: 'Publish',
155
+ btnSkip: 'Skip',
156
+ btnBack: 'Back',
157
+ btnFinished: 'Done',
158
+ noCompErrorTitle: 'No Compositions Found',
159
+ noCompErrorDesc: `You can't publish and deliver your project until you have created your first composition.`
160
+ };
161
+
162
+ export const integration = {
163
+ errorPullingComps: ' Error getting composition IDs, contact your Imposium admin for support.',
164
+ errorCreatingCreds: ' Error creating credentials, contact your Imposium admin for support.',
165
+ errorGettingCreds: ' Error getting credentials, contact your Imposium admin for support.',
166
+ documentation: 'Documentation',
167
+ docParagraph: 'Use the links below for more information on integrating Imposium into your application.',
168
+ js: 'JavaScript SDK',
169
+ jsSdkLink: 'https://docs.imposium.com/js-sdk/#/',
170
+ restLink: 'https://docs.imposium.com',
171
+ rest: 'REST API',
172
+ sdkArchiveSuffix: ' - JS SDK Integration.zip',
173
+ };
174
+
175
+ export const header = {
176
+ publishing: 'Publishing...',
177
+ working: 'Using Working Copy',
178
+ statusError: 'Error getting story status',
179
+ publishJobError: 'Error creating publish story job',
180
+ publishPollError: 'Error polling publish job status',
181
+ };
182
+
183
+ export const project = {
184
+ compName: 'Composition',
185
+ tooltipCompId : 'Unique ID of the selected composition. Used to render that specific composition via the API and Imposium JS-SDK.',
186
+ };
187
+
188
+ export const BATCHES_COPY = {
189
+ progress: {
190
+ notRendered: 'not rendered',
191
+ rendering: 'rendering',
192
+ rendered: 'rendered',
193
+ cancelled: 'cancelled',
194
+ queued: 'queued',
195
+ malformed: 'unknown'
196
+ }
197
+ };
@@ -51,6 +51,13 @@ import { faLayerGroup } from '@fortawesome/free-solid-svg-icons/faLayerGroup';
51
51
  import { faCube } from '@fortawesome/free-solid-svg-icons/faCube';
52
52
  import { faFileCode } from '@fortawesome/free-solid-svg-icons/faFileCode';
53
53
  import { faQuestionCircle } from '@fortawesome/pro-light-svg-icons/faQuestionCircle';
54
+ import { faHubspot } from '@fortawesome/free-brands-svg-icons/faHubspot';
55
+ import { faEnvelope } from '@fortawesome/free-solid-svg-icons/faEnvelope';
56
+ import { faGlobe } from '@fortawesome/free-solid-svg-icons/faGlobe';
57
+ import { faProjectDiagram } from '@fortawesome/free-solid-svg-icons/faProjectDiagram';
58
+ import { faJs } from '@fortawesome/free-brands-svg-icons/faJs';
59
+ import { faDownload } from '@fortawesome/free-solid-svg-icons/faDownload';
60
+ import { faUpload } from '@fortawesome/free-solid-svg-icons/faUpload';
54
61
 
55
62
  export const ICON_VIDEO = <FontAwesomeIcon icon = {faVideo}/>;
56
63
 
@@ -153,3 +160,17 @@ export const ICON_CUBE = <FontAwesomeIcon icon = {faCube}/>;
153
160
  export const ICON_FILE_CODE = <FontAwesomeIcon icon = {faFileCode}/>;
154
161
 
155
162
  export const ICON_HELP = <FontAwesomeIcon icon = {faQuestionCircle}/>;
163
+
164
+ export const ICON_HUBSPOT = <FontAwesomeIcon icon = {faHubspot}/>;
165
+
166
+ export const ICON_EMAIL = <FontAwesomeIcon icon = {faEnvelope}/>;
167
+
168
+ export const ICON_GLOBE = <FontAwesomeIcon icon = {faGlobe}/>;
169
+
170
+ export const ICON_PROJECT_DIAGRAM = <FontAwesomeIcon icon = {faProjectDiagram}/>;
171
+
172
+ export const ICON_JS = <FontAwesomeIcon icon = {faJs}/>;
173
+
174
+ export const ICON_DOWNLOAD = <FontAwesomeIcon icon = {faDownload}/>;
175
+
176
+ export const ICON_UPLOAD = <FontAwesomeIcon icon = {faUpload} />;