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(
);
},
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 }) }
{ 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(
);
},
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(
);
},
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;