Finished breakdown of attachment vue into components

This commit is contained in:
Dan Brown
2020-07-04 16:53:02 +01:00
parent 14b6cd1091
commit d41452f39c
24 changed files with 371 additions and 321 deletions

View File

@ -0,0 +1,58 @@
import {onEnterPress, onSelect} from "../services/dom";
/**
* Ajax Form
* Will handle button clicks or input enter press events and submit
* the data over ajax. Will always expect a partial HTML view to be returned.
* Fires an 'ajax-form-success' event when submitted successfully.
* @extends {Component}
*/
class AjaxForm {
setup() {
this.container = this.$el;
this.url = this.$opts.url;
this.method = this.$opts.method || 'post';
this.successMessage = this.$opts.successMessage;
this.submitButtons = this.$manyRefs.submit || [];
this.setupListeners();
}
setupListeners() {
onEnterPress(this.container, event => {
this.submit();
event.preventDefault();
});
this.submitButtons.forEach(button => onSelect(button, this.submit.bind(this)));
}
async submit() {
const fd = new FormData();
const inputs = this.container.querySelectorAll(`[name]`);
console.log(inputs);
for (const input of inputs) {
fd.append(input.getAttribute('name'), input.value);
}
this.container.style.opacity = '0.7';
this.container.style.pointerEvents = 'none';
try {
const resp = await window.$http[this.method.toLowerCase()](this.url, fd);
this.container.innerHTML = resp.data;
this.$emit('success', {formData: fd});
if (this.successMessage) {
window.$events.emit('success', this.successMessage);
}
} catch (err) {
this.container.innerHTML = err.data;
}
window.components.init(this.container);
this.container.style.opacity = null;
this.container.style.pointerEvents = null;
}
}
export default AjaxForm;

View File

@ -1,14 +1,16 @@
/**
* Attachments
* @extends {Component}
*/
import {showLoading} from "../services/dom";
class Attachments {
setup() {
this.container = this.$el;
this.pageId = this.$opts.pageId;
this.editContainer = this.$refs.editContainer;
this.listContainer = this.$refs.listContainer;
this.mainTabs = this.$refs.mainTabs;
this.list = this.$refs.list;
@ -16,23 +18,30 @@ class Attachments {
}
setupListeners() {
this.container.addEventListener('dropzone-success', event => {
this.mainTabs.components.tabs.show('items');
window.$http.get(`/attachments/get/page/${this.pageId}`).then(resp => {
this.list.innerHTML = resp.data;
window.components.init(this.list);
})
});
const reloadListBound = this.reloadList.bind(this);
this.container.addEventListener('dropzone-success', reloadListBound);
this.container.addEventListener('ajax-form-success', reloadListBound);
this.container.addEventListener('sortable-list-sort', event => {
this.updateOrder(event.detail.ids);
});
this.editContainer.addEventListener('keypress', event => {
if (event.key === 'Enter') {
// TODO - Update editing file
}
})
this.container.addEventListener('event-emit-select-edit', event => {
this.startEdit(event.detail.id);
});
this.container.addEventListener('event-emit-select-edit-back', event => {
this.stopEdit();
});
}
reloadList() {
this.stopEdit();
this.mainTabs.components.tabs.show('items');
window.$http.get(`/attachments/get/page/${this.pageId}`).then(resp => {
this.list.innerHTML = resp.data;
window.components.init(this.list);
});
}
updateOrder(idOrder) {
@ -41,6 +50,21 @@ class Attachments {
});
}
async startEdit(id) {
this.editContainer.classList.remove('hidden');
this.listContainer.classList.add('hidden');
showLoading(this.editContainer);
const resp = await window.$http.get(`/attachments/edit/${id}`);
this.editContainer.innerHTML = resp.data;
window.components.init(this.editContainer);
}
stopEdit() {
this.editContainer.classList.add('hidden');
this.listContainer.classList.remove('hidden');
}
}
export default Attachments;

View File

@ -9,11 +9,15 @@ class Dropzone {
setup() {
this.container = this.$el;
this.url = this.$opts.url;
this.successMessage = this.$opts.successMessage;
this.removeMessage = this.$opts.removeMessage;
this.uploadLimitMessage = this.$opts.uploadLimitMessage;
this.timeoutMessage = this.$opts.timeoutMessage;
const _this = this;
this.dz = new DropZoneLib(this.container, {
addRemoveLinks: true,
dictRemoveFile: window.trans('components.image_upload_remove'),
dictRemoveFile: this.removeMessage,
timeout: Number(window.uploadTimeout) || 60000,
maxFilesize: Number(window.uploadLimit) || 256,
url: this.url,
@ -32,15 +36,20 @@ class Dropzone {
const token = window.document.querySelector('meta[name=token]').getAttribute('content');
data.append('_token', token);
xhr.ontimeout = function (e) {
xhr.ontimeout = (e) => {
this.dz.emit('complete', file);
this.dz.emit('error', file, window.trans('errors.file_upload_timeout'));
this.dz.emit('error', file, this.timeoutMessage);
}
}
onSuccess(file, data) {
this.container.dispatchEvent(new Event('dropzone'))
this.$emit('success', {file, data});
if (this.successMessage) {
window.$events.emit('success', this.successMessage);
}
fadeOut(file.previewElement, 800, () => {
this.dz.removeFile(file);
});
@ -55,7 +64,7 @@ class Dropzone {
}
if (xhr && xhr.status === 413) {
setMessage(window.trans('errors.server_upload_limit'))
setMessage(this.uploadLimitMessage);
} else if (errorMessage.file) {
setMessage(errorMessage.file);
}

View File

@ -0,0 +1,29 @@
import {onSelect} from "../services/dom";
/**
* EventEmitSelect
* Component will simply emit an event when selected.
*
* Has one required option: "name".
* A name of "hello" will emit a component DOM event of
* "event-emit-select-name"
*
* All options will be set as the "detail" of the event with
* their values included.
*
* @extends {Component}
*/
class EventEmitSelect {
setup() {
this.container = this.$el;
this.name = this.$opts.name;
onSelect(this.$el, () => {
this.$emit(this.name, this.$opts);
});
}
}
export default EventEmitSelect;