import React from 'react' import NestedPagePartial from '../nested-page-partial' import Admin from '../../admin' import truncate from 'lodash/truncate' import capitalize from 'lodash/capitalize' import sortBy from 'lodash/sortBy' import { COLORS } from '../helpers/colors' const truncateTo90 = (str) => truncate(str, { length: 93 }); const Instance = { fetchAdditionalNeededData(args) { let neededData = {}; const fieldTypes = new Set(this.props.fields.map(f => f.fieldType)); if (fieldTypes.has('content_download')) { neededData['contentDownloads'] = true; this.props.fetchEntities({ url: '/admin/api/content_downloads' }).then(() => { let state = Instance.newStateAfterFetchingAddtionalData.call(this, { type: 'content_download', typeNamePlural: 'contentDownloads', addingEntity: args.addingEntity }); this.setState(state); neededData['contentDownloads'] = false; }); } if (fieldTypes.has('event_series')) { neededData['eventSeries'] = true; this.props.fetchEntities({ url: '/admin/api/event_series' }).then(() => { let state = Instance.newStateAfterFetchingAddtionalData.call(this, { type: 'event_series', typeNamePlural: 'eventSeries', addingEntity: args.addingEntity }); this.setState(state); neededData['eventSeries'] = false; }); } if (fieldTypes.has('transcription')) { neededData['transcripts'] = true; this.props.fetchEntities({ url: '/admin/api/transcripts' }).then(() => { let state = Instance.newStateAfterFetchingAddtionalData.call(this, { type: 'transcription', typeNamePlural: 'transcripts', addingEntity: args.addingEntity }); this.setState(state); neededData['transcripts'] = false; }); } if (Object.values(neededData).indexOf(true) > -1) { this.setState({ fetching: true }); let interval = setInterval(() => { if (Object.values(neededData).indexOf(true) === -1) { clearInterval(interval); this.setState({ fetching: false }, () => { Admin.setUpNiceSelect({ selector: 'select', func: Admin.changeField.bind(this, this.changeFieldArgs()), adjustWidthSelector: '.instance-fields .nice-select' }); }); } }, 250); } else { Admin.setUpNiceSelect({ selector: 'select', func: Admin.changeField.bind(this, this.changeFieldArgs()), adjustWidthSelector: '.instance-fields .nice-select' }); } }, newStateAfterFetchingAddtionalData(args) { const { type, typeNamePlural, entityName } = args; let state = { [typeNamePlural]: this.props[typeNamePlural] }; if (args.addingEntity) { let entity = this.state[entityName]; this.state.fields.forEach((field) => { if (field.fieldType === type) { entity[field.id] = this.props[typeNamePlural][0].id; } }); state[entityName] = entity; } return state; }, renderFields(args) { return(
{ args.fields.map((field, index) => { return Instance.renderField.call(this, { field, index, entityName: args.entityName }); }) }
); }, renderField(args) { const field = args.field; switch (field.fieldType) { case 'text': return Instance.renderTextField.call(this, args); case 'markdown': return Instance.renderTextField.call(this, Object.assign(args, { markdown: true })); case 'number': return Instance.renderNumberField.call(this, args); case 'image': return Instance.renderImageField.call(this, args); case 'dropdown': return Instance.renderDropDownField.call(this, args); case 'color': return Instance.renderColorField.call(this, args); case 'content_download': return Instance.renderContentDownloadField.call(this, args); case 'event_series': return Instance.renderEventSeriesField.call(this, args); case 'transcription': return Instance.renderTranscriptField.call(this, args); case 'file': return Instance.renderFileField.call(this, args); case 'object': return Instance.renderObjectField.call(this, args); case 'header': return Instance.renderHeaderField.call(this, args); case 'webinar': return Instance.renderWebinarField.call(this, args); case 'page-partial': return Instance.renderPagePartialField.call(this, args); default: return null; } }, renderTextField(args) { const { field, index, entityName, markdown } = args; const fieldWidth = Admin.calculateFieldWidth(field); const potentialErrors = [ `${field.name} is mandatory` ]; let newArgs = { field, fieldWidth, potentialErrors, entityName, markdown }; return(

{ field.name }

{ Instance.renderAnnotation.call(this, newArgs) } { field.charLimit < 1000 ? Instance.renderInput.call(this, newArgs) : Instance.renderTextArea.call(this, newArgs) } { Admin.renderFieldError(this.state.errors, potentialErrors) }
); }, renderNumberField(args) { const { field, index } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory`, ` ${field.name} is not a number` ]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderFieldError(this.state.errors, potentialErrors) }
); }, renderImageField(args) { const { field, index, entityName } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory` ]; let image = this.state.images[field.id]; let uploadId = this.state[args.entityName][field.id]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) }
{ Instance.renderImageOrEmptyDiv.call(this, image, potentialErrors) } { Instance.renderReuseImageButton.call(this, { field, image, uploadId }) }
Upload Image Reusable Images Remove Image
{ Admin.renderFieldError(this.state.errors, potentialErrors) }
); }, renderImageOrEmptyDiv(image, potentialErrors) { if (image.url) { return( ); } else { return(
); } }, renderDropDownField(args) { const { field, index, entityName } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory` ]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError(this.state.errors, potentialErrors) }
); }, renderContentDownloadField(args) { const { field, index } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory` ]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError(this.state.errors, potentialErrors) }
); }, renderEventSeriesField(args) { const { field, index } = args; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError([], []) }
); }, renderTranscriptField(args) { const { field, index } = args; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError([], []) }
); }, renderWebinarField(args) { const { field, index } = args; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError([], []) }
); }, renderHeaderField(args) { const { field, index, entityName } = args; const potentialErrors = [ `${field.name} is mandatory` ]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderFieldError([], []) }

Header Type

); }, renderColorField(args) { const { field, index } = args; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError([], []) }
); }, renderFileField(args) { const { field, index } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory` ]; let file = this.state.files[field.id]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) }
Upload File Remove File
{ Admin.renderFieldError(this.state.errors, potentialErrors) }
); }, renderObjectField(args) { const { field, index } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory` ]; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderDropdownFieldError(this.state.errors, potentialErrors) }
); }, renderPagePartialField(args) { const { field, index } = args; const potentialErrors = [ `${capitalize(field.name)} is mandatory` ]; if (this.state.changesToSave) { return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) }

SAVE CHANGES TO ADD OR MODIFY NESTED PARTIAL

{ Admin.renderFieldError(this.state.errors, potentialErrors) }
); } else { const nestedPagePartialId = this.state.pagePartial[`${field.id}_page_partial_field_id`]; const nestedPagePartial = nestedPagePartialId ? this.state.nestedPagePartials[nestedPagePartialId] : null; return(

{ field.name }

{ Instance.renderAnnotation.call(this, args) } { Admin.renderFieldError(this.state.errors, potentialErrors) }
); } }, // Helper Methods: clickReusableImages(fieldId) { this.setState({ reusableImagesModalOpen: true, reusableImagesFieldId: fieldId }); }, selectReusableImage(args) { const { uploadId, url, entityName } = args; let fieldId = this.state.reusableImagesFieldId; let entity = this.state[entityName]; entity[fieldId] = uploadId; let images = this.state.images; let image = images[fieldId]; let fieldName = this.state.fields.find(({ id }) => id === fieldId).name; Admin.removeDynamicFieldError(this.changeFieldArgs().errorsArray, fieldName); image['url'] = url; image['reusability'] = true; this.setState({ [entityName]: entity, images }, () => { this.setState({ changesToSave: this.checkForChanges() }); }); }, clickRemoveUpload(args) { const { field, fieldType, entityName } = args; let entity = this.state[entityName]; entity[field.id] = ''; let uploads = this.state[`${fieldType}s`]; uploads[field.id].url = ''; uploads[field.id].reusability = null; this.setState({ entityName: entity, [`${fieldType}s`]: uploads }, () => { if (this.checkForChanges) { this.setState({ changesToSave: this.checkForChanges() }); } }); }, clickUploadFile(args) { window.filepicker.pick({ storeTo: { location: 's3' }, customSourceContainer: 'cms-uploaded-files-bucket', services: ['COMPUTER'], debug: window.FILEPICKER_DEBUG }, (response) => { let entity = this.state[args.entityName]; let files = this.state.files; files[args.property].url = response.url; this.setState({ fetching: true }); this.props.createEntity({ directory: 'uploads', entityName: 'upload', entity: { uploadType: 'file', category: 'file', url: response.url, s3_url: response.key, uploadedBy: Admin.currentUser.id } }).then(() => { entity[args.property] = this.props.upload.id; let newArgs = Object.assign(args, { isInstance: true, isFile: true, entity, uploadsList: files }); Admin.updateStateAfterImageOrFileUpload.call(this, newArgs); }); }); }, renderInput(args) { const { field, fieldWidth, potentialErrors, entityName } = args; return(
{ Instance.renderMarkdownInfo.call(this, args) }
); }, renderTextArea(args) { const { field, fieldWidth, potentialErrors, entityName } = args; const rows = Math.ceil(fieldWidth / 2000); return(
{ Instance.renderMarkdownInfo.call(this, args) }
); }, renderReuseImageButton(args) { let image = args.image; if (image.reusability) { return

Image is Reusable

; } else if (image.url) { return ( Make Reusable ); } else { return null; } }, renderObjectOptions(field) { let options = this.state.instances[field.id]; let alphabetizedOptions = sortBy(options, 'firstFieldValue'); return alphabetizedOptions.map((option, index) => ); }, renderMenuOptions(options) { let alphabetizedOptions = sortBy(options, 'value'); return alphabetizedOptions.map((option, index) => ); }, renderStateOptions(obj) { return sortBy(obj, 'name') .map(({id, name}) => ()) }, renderColors() { return Object.keys(COLORS).map((color, index) => ); }, renderHeaderTypeOptions() { return this.state.headerTypes.map((type, i) => ); }, renderAnnotation(args) { if (args.field.description) { return(

{ args.field.description }

); } else { return null; } }, renderMarkdownInfo(args) { if (args.markdown) { return([

Accepts Markdown

, ]); } else { return null; } } }; export default Instance;