Skip to content

Commit

Permalink
[6453] Restore aws-file-upload control xml storage/retrieval format
Browse files Browse the repository at this point in the history
  • Loading branch information
rart committed Jan 23, 2024
1 parent 8be4771 commit aa5dcf2
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 159 deletions.
288 changes: 131 additions & 157 deletions static-assets/components/cstudio-forms/controls/aws-file-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,166 +14,140 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

CStudioForms.Controls.AWSFileUpload =
CStudioForms.Controls.AWSFileUpload ||
function (id, form, owner, properties, constraints, readonly) {
this.owner = owner;
this.owner.registerField(this);
this.errors = [];
this.properties = properties;
this.constraints = constraints;
this.fileEl = null;
this.inputEl = null;
this.required = false;
this.value = '_not-set';
this.form = form;
this.id = id;
this.readonly = readonly;

if (properties) {
var required = constraints.find(function (property) {
return property.name === 'required';
});
if (required) {
this.required = required.value === 'true';
}
var profile_id = properties.find(function (property) {
return property.name === 'profile_id';
});
if (profile_id) {
this.profile_id = profile_id.value;
!CStudioForms.Controls.AWSFileUpload &&
(function () {
CStudioForms.Controls.AWSFileUpload = function (id, form, owner, properties, constraints, readonly) {
this.owner = owner;
this.owner.registerField(this);
this.errors = [];
this.properties = properties;
this.constraints = constraints;
this.fileEl = null;
this.inputEl = null;
this.required = false;
this.value = '_not-set';
this.form = form;
this.id = id;
this.readonly = readonly;

if (properties) {
var required = constraints.find(function (property) {
return property.name === 'required';
});
if (required) {
this.required = required.value === 'true';
}
var profile_id = properties.find(function (property) {
return property.name === 'profile_id';
});
if (profile_id) {
this.profile_id = profile_id.value;
}
}
}

return this;
};

YAHOO.extend(CStudioForms.Controls.AWSFileUpload, CStudioForms.CStudioFormField, {
getLabel: function () {
return 'AWS File Upload';
},

getName: function () {
return 'aws-file-upload';
},

// Previously received Array<{ key; bucket }>
setValue: function (value /*: string; */) {
var validationResult = true;
if (value) {
this.value = value;
this.fileEl.innerHTML = value;
this.form.updateModel(this.id, this.value);
this.clearError('required');
} else if (this.required) {
validationResult = false;
this.setError('required', 'Field is Required');
}
this.renderValidation(true, validationResult);
this.owner.notifyValidation();
},

getValue: function () {
return this.value;
},

getSupportedProperties: function () {
return [{ label: 'Profile ID', name: 'profile_id', type: 'string', defaultValue: 's3-default' }];
},

getSupportedConstraints: function () {
return [{ label: CMgs.format(langBundle, 'required'), name: 'required', type: 'boolean' }];
},

_onChange: function (event, obj) {
const dispatch = craftercms.getStore().dispatch;
const file = event.target.files[0];
const profileId = this.profile_id;
if (file) {
dispatch({ type: 'BLOCK_UI', payload: { message: 'Uploading...' } });
const reader = new FileReader();
reader.onload = (e) => {
file.dataUrl = e.target.result;
craftercms.services.content
.uploadToS3(CStudioAuthoringContext.site, file, '/', profileId, CStudioAuthoringContext.xsrfParameterName)
.subscribe({
next(result) {
if (result.type === 'complete') {
dispatch({ type: 'UNBLOCK_UI' });
obj.setValue(result.payload.body.item.url);
obj.edited = true;
} else {
// Progress event...
}
},
error(error) {
const apiResponse = error?.body?.response;
!apiResponse && console.error(error);
dispatch({ type: 'UNBLOCK_UI' });
dispatch({
type: 'SHOW_ERROR_DIALOG',
payload: {
error: apiResponse ?? {
message: 'An error occurred while uploading the file'
return this;
};

YAHOO.extend(CStudioForms.Controls.AWSFileUpload, CStudioForms.CStudioFormField, {
getLabel: () => 'AWS File Upload',
getName: () => 'aws-file-upload',

setValue: function (value) {
var validationResult = true;
const item = value?.[0];
if (item?.url) {
const url = item.url;
const name = item.name ?? item.key;
const bucket = item.bucketName ?? '';
this.value = [{ key: name, bucket, url }];
this.fileEl.innerHTML = `<code>${url}</code><code>s3://${bucket}/${name}*</code>`;
this.form.updateModel(this.id, this.value);
this.previewEl.innerHTML = /\.(jpg|jpeg|png|gif|bmp|ico|svg)$/i.test(url)
? `<img src="${url}" />`
: /\.(pdf|html|js|css|txt|json|md|jsx|ts|tsx|yaml|ftl)$/i.test(url)
? `<iframe src="${url}" />`
: '';
this.clearError('required');
} else if (this.required) {
validationResult = false;
this.setError('required', 'Field is Required');
}
this.renderValidation(true, validationResult);
this.owner.notifyValidation();
},

getValue: () => this.value,

getSupportedProperties: () => [
{ label: 'Profile ID', name: 'profile_id', type: 'string', defaultValue: 's3-default' }
],

getSupportedConstraints: () => [
{ label: CMgs.format(langBundle, 'required'), name: 'required', type: 'boolean' }
],

render: function (config, containerEl, lastTwo) {
// language=html
containerEl.innerHTML = `
<span class="cstudio-form-field-title">${config.title}</span>
<span class="validation-hint cstudio-form-control-validation fa fa-check"></span>
<div class="aws-file-upload-control-container cstudio-form-control-input-container">
<input
type="file"
name="file"
class="datum cstudio-form-control-input"
>
<div data-name="fileEl" class="aws-file-upload-url-el"></div>
<div data-name="previewEl" class="aws-file-upload-preview-el"></div>
</div>
`;
this.fileEl = containerEl.querySelector('[data-name="fileEl"]');
this.previewEl = containerEl.querySelector('[data-name="previewEl"]');
var inputEl = (this.inputEl = containerEl.querySelector('input'));
inputEl.addEventListener('change', (e) => this._onChange(e, this));
},

_onChange: function (event, obj) {
// TODO: Disable UI while uploading
const dispatch = craftercms.getStore().dispatch;
const file = event.target.files[0];
const profileId = this.profile_id;
if (file) {
dispatch({ type: 'BLOCK_UI', payload: { message: 'Uploading...' } });
const reader = new FileReader();
reader.onload = (e) => {
file.dataUrl = e.target.result;
craftercms.services.content
.uploadToS3(CStudioAuthoringContext.site, file, '/', profileId, CStudioAuthoringContext.xsrfParameterName)
.subscribe({
next(result) {
if (result.type === 'complete') {
dispatch({ type: 'UNBLOCK_UI' });
obj.setValue([result.payload.body.item]);
obj.edited = true;
} else {
// Progress event...
}
},
error(error) {
const apiResponse = error?.body?.response;
!apiResponse && console.error(error);
dispatch({ type: 'UNBLOCK_UI' });
dispatch({
type: 'SHOW_ERROR_DIALOG',
payload: {
error: apiResponse ?? {
message: 'An error occurred while uploading the file'
}
}
});
}
});
}
});
};
reader.readAsDataURL(file);
}
},

render: function (config, containerEl, lastTwo) {
var titleEl = document.createElement('span');
YAHOO.util.Dom.addClass(titleEl, 'cstudio-form-field-title');
titleEl.textContent = config.title;
containerEl.appendChild(titleEl);

var controlWidgetContainerEl = document.createElement('div');
YAHOO.util.Dom.addClass(controlWidgetContainerEl, 'cstudio-form-control-input-container');

var validEl = document.createElement('span');
YAHOO.util.Dom.addClass(validEl, 'validation-hint');
YAHOO.util.Dom.addClass(validEl, 'cstudio-form-control-validation fa fa-check');
containerEl.appendChild(validEl);

this.fileEl = document.createElement('span');
this.fileEl.style.marginLeft = '10px';

var formEl = document.createElement('form');
formEl.id = 'upload_form_' + this.id;

var profileEl = document.createElement('input');
profileEl.type = 'hidden';
profileEl.name = 'profile';
profileEl.value = this.profile_id;

formEl.appendChild(profileEl);

var siteEl = document.createElement('input');
siteEl.type = 'hidden';
siteEl.name = 'site';
siteEl.value = CStudioAuthoringContext.site;

formEl.appendChild(siteEl);

var inputEl = document.createElement('input');
this.inputEl = inputEl;
inputEl.type = 'file';
inputEl.name = 'file';
YAHOO.util.Dom.addClass(inputEl, 'datum');
YAHOO.util.Dom.addClass(inputEl, 'cstudio-form-control-input');
YAHOO.util.Event.on(inputEl, 'change', (e) => this._onChange(e, this));

formEl.appendChild(inputEl);
formEl.appendChild(this.fileEl);

controlWidgetContainerEl.appendChild(formEl);

containerEl.appendChild(controlWidgetContainerEl);
}
});
};
reader.readAsDataURL(file);
}
}
});

CStudioAuthoring.Module.moduleLoaded('cstudio-forms-controls-aws-file-upload', CStudioForms.Controls.AWSFileUpload);
CStudioAuthoring.Module.moduleLoaded('cstudio-forms-controls-aws-file-upload', CStudioForms.Controls.AWSFileUpload);
})();
4 changes: 2 additions & 2 deletions static-assets/components/cstudio-forms/forms-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ var CStudioForms =
renderValidation: function (onOff) {
var valid = true;

for (key in this.errors) {
for (let key in this.errors) {
valid = false;
break;
}
Expand Down Expand Up @@ -692,7 +692,7 @@ var CStudioForms =
if (formField && formField.edited) {
var editorId = CStudioAuthoring.Utils.getQueryVariable(location.search, 'editorId');
var iceWindowCallback = CStudioAuthoring.InContextEdit.getIceCallback(editorId);
if (iceWindowCallback.pendingChanges) {
if (iceWindowCallback?.pendingChanges) {
let callback = getCustomCallback(iceWindowCallback.pendingChanges);
callback();
}
Expand Down
63 changes: 63 additions & 0 deletions static-assets/themes/cstudioTheme/css/forms-default.css
Original file line number Diff line number Diff line change
Expand Up @@ -1751,3 +1751,66 @@ body.yui-skin-cstudioTheme.masked {
margin-left: 5px;
vertical-align: middle;
}

input[type='file'] {
cursor: pointer;
padding: 9px 10px 44px 10px;
box-sizing: border-box;
}

input[type='file']::file-selector-button {
align-items: center;
justify-content: center;
background-color: transparent;
outline: 0;
margin: 0 10px 0 0;
cursor: pointer;
user-select: none;
vertical-align: middle;
appearance: none;
text-decoration: none;
text-transform: none;
font-family: 'Source Sans Pro', 'Open Sans', sans-serif;
font-weight: 600;
font-size: 0.875rem;
line-height: 1.75;
padding: 5px 15px;
border-radius: 4px;
border: 1px solid rgba(0, 122, 255, 0.5);
color: rgb(0, 122, 255);
}

.aws-file-upload-preview-el {
width: 100%;
border-radius: 4px;
overflow: hidden;
text-align: center;
}

.aws-file-upload-preview-el img {
max-width: 100%;
max-height: 250px;
border-radius: 4px;
}

.aws-file-upload-preview-el iframe {
border: 0;
width: 100%;
height: 250px;
border-radius: 4px;
}

.aws-file-upload-control-container {
flex-direction: column;
align-items: flex-start;
}

.aws-file-upload-url-el {
width: 100%;
display: flex;
place-content: space-between;
}

.aws-file-upload-url-el:not(:empty) {
padding: 10px;
}

0 comments on commit aa5dcf2

Please sign in to comment.