import $ from 'jquery'; import Finder from '../../utils/finderjs'; import { config as gravConfig } from 'grav-config'; let XHRUUID = 0; export const Instances = {}; export default class Parents { constructor(container, field, data) { this.container = $(container); this.fieldName = field.attr('name'); this.field = $(`[name="${this.fieldName}"]`); this.data = data; this.parentLabel = $(`[data-parents-field-label="${this.fieldName}"]`); this.parentName = $(`[data-parents-field-name="${this.fieldName}"]`); const dataLoad = this.dataLoad; this.finder = new Finder( this.container, (parent, callback) => { return dataLoad.call(this, parent, callback); }, { labelKey: 'name', defaultPath: this.field.val(), createItemContent: function(item) { return Parents.createItemContent(this.config, item); } } ); /* this.finder.$emitter.on('leaf-selected', (item) => { console.log('selected', item); this.finder.emit('create-column', () => this.createSimpleColumn(item)); }); this.finder.$emitter.on('item-selected', (selected) => { console.log('selected', selected); // for future use only - create column-card creation for file with details like in macOS finder // this.finder.$emitter('create-column', () => this.createSimpleColumn(selected)); }); */ this.finder.$emitter.on('column-created', () => { this.container[0].scrollLeft = this.container[0].scrollWidth - this.container[0].clientWidth; }); } static createItemContent(config, item) { const frag = document.createDocumentFragment(); const label = $(``); const infoContainer = $(''); const iconPrepend = $(''); const iconAppend = $(''); const badge = $(''); const prependClasses = ['fa']; const appendClasses = ['fa']; // prepend icon if (item.children || item.type === 'dir') { prependClasses.push('fa-folder'); } else if (item.type === 'root') { prependClasses.push('fa-sitemap'); } else if (item.type === 'file') { prependClasses.push('fa-file-o'); } iconPrepend.addClass(prependClasses.join(' ')); // text label label.text(item[config.labelKey]).prepend(iconPrepend); label.appendTo(frag); // append icon if (item.children || item['has-children']) { appendClasses.push('fa-caret-right'); badge.text(item.size || item.count || 0); badge.appendTo(infoContainer); } iconAppend.addClass(appendClasses.join(' ')); iconAppend.appendTo(infoContainer); infoContainer.appendTo(frag); return frag; } static createLoadingColumn() { return $(`
`); } static createErrorColumn(error) { return $(` `); } createSimpleColumn(item) {} dataLoad(parent, callback) { if (!parent) { return callback(this.data); } if (parent.type !== 'dir' || !parent['has-children']) { return false; } const UUID = ++XHRUUID; this.startLoader(); $.ajax({ url: `${gravConfig.current_url}`, method: 'post', data: Object.assign({}, getExtraFormData(this.container), { route: b64_encode_unicode(parent.value), field: this.field.data('fieldName'), action: 'getLevelListing', 'admin-nonce': gravConfig.admin_nonce }), success: (response) => { this.stopLoader(); if (response.status === 'error') { this.finder.$emitter.emit('create-column', Parents.createErrorColumn(response.message)[0]); return false; } // stale request if (UUID !== XHRUUID) { return false; } return callback(response.data); } }); } startLoader() { this.loadingIndicator = Parents.createLoadingColumn(); this.finder.$emitter.emit('create-column', this.loadingIndicator[0]); return this.loadingIndicator; } stopLoader() { return this.loadingIndicator && this.loadingIndicator.remove(); } } export const b64_encode_unicode = (str) => { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { return String.fromCharCode('0x' + p1); })); }; export const b64_decode_unicode = (str) => { return decodeURIComponent(atob(str).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); }; const getExtraFormData = (container) => { let form = container.closest('form'); if (container.closest('[data-remodal-id]').length) { form = $('form#blueprints'); } const data = {}; const unique_id = form.find('[name="__unique_form_id__"]'); data['__form-name__'] = form.find('[name="__form-name__"]').val(); data['form-nonce'] = form.find('[name="form-nonce"]').val(); if (unique_id.length) { data['__unique_form_id__'] = unique_id.val(); } return data; }; $(document).on('click', '[data-parents]', (event) => { event.preventDefault(); event.stopPropagation(); const target = $(event.currentTarget); let field = target.closest('.parents-wrapper').find('input[name]'); let fieldName = field.attr('name'); if (!field.length) { fieldName = target.data('parents'); field = $(`[name="${target.data('parents')}"]`).first(); } const modal = $(`[data-remodal-id="${target.data('remodalTarget') || 'parents'}"]`); const loader = modal.find('.grav-loading'); const content = modal.find('.parents-content'); loader.css('display', 'block'); content.html(''); $.ajax({ url: `${gravConfig.current_url}`, method: 'post', data: Object.assign({}, getExtraFormData(target), { route: b64_encode_unicode(field.val()), field: field.data('fieldName'), action: 'getLevelListing', 'admin-nonce': gravConfig.admin_nonce, initial: true }), success(response) { loader.css('display', 'none'); if (response.status === 'error') { content.html(response.message); return true; } if (!Instances[`${fieldName}-${modal.data('remodalId')}`]) { Instances[`${fieldName}-${modal.data('remodalId')}`] = new Parents(content, field, response.data); } else { Instances[`${fieldName}-${modal.data('remodalId')}`].finder.reload(response.data); } modal.data('parents', Instances[`${fieldName}-${modal.data('remodalId')}`]); modal.data('parents-selectedField', field); } }); }); // apply finder selection to field $(document).on('click', '[data-remodal-id].parents-container [data-parents-select]', (event) => { const modal = $(event.currentTarget).closest('[data-remodal-id]'); const parents = modal.data('parents'); const selectedField = modal.data('parentsSelectedField'); const finder = parents.finder; const field = parents.field; const parentLabel = parents.parentLabel; const parentName = parents.parentName; const selection = finder.findLastActive().item[0]; const value = selection._item[finder.config.valueKey]; const name = selection._item[finder.config.labelKey]; console.log('click [data-parents-select]', selectedField); if (selectedField.closest('.remodal').length) { const index = field.index(selectedField) - 1; selectedField.val(value); $(parentLabel[index]).text(value); $(parentName[index]).text(name); } else { field.val(value); parentLabel.text(value); parentName.text(name); finder.config.defaultPath = value; } const remodal = $.remodal.lookup[$(`[data-remodal-id="${modal.data('remodalId')}"]`).data('remodal')]; remodal.close(); });