Vue.component('ui-combo', { template: `
{{item.name}}
`, reusable: true, props: ['url', 'valueField', 'placeholder', 'disabled', 'value', 'width', 'options'], watch: { value: function (value) { this.initValue(); }, options: function (newValue) { this.items = newValue; this.initValue(); } }, data: function () { return { title: '', active: false, items: [], item: undefined, component: { width: '100%' }, qf: new QueryFilter() }; }, created: async function () { if (this.width && !this.width.indexOf('%') > -1) { this.component.width = this.width.indexOf('%') > -1 ? this.width : this.width + 'px'; } else { this.component.width = 'auto'; } if (this.placeholder) { this.title = this.placeholder; } this.initValue(); }, methods: { async initValue() { qf.query = this.title; if (this.url) { let r = await api.get(this.url + this.title, {}, true); if (r && r.data) { this.items = r.data; } } if (this.items && this.value && typeof this.value !== 'object') { this.item = this.items.filter(x => x.id === this.value)[0]; if (this.item) { this.title = this.item.name || this.title; } } else if (typeof this.value === 'object') { this.item = this.value; this.title = this.item.name || this.title; } }, select(item) { this.item = item; this.title = item.name || this.title; this.$emit('select', !this.valueField ? item : item[this.valueField]); this.$emit('input', !this.valueField ? item : item[this.valueField]); this.hide(); }, clear() { this.item = undefined; this.title = this.placeholder; this.$emit('clear', null); this.$emit('input', null); this.hide(); }, outside(event) { if (!(this.$el === event.target || this.$el.contains(event.target))) { this.hide(); } }, show() { this.active = true; document.body.addEventListener("click", this.outside); }, hide() { this.active = false; document.body.removeEventListener("click", this.outside); }, toggle() { if (!this.items.length) { this.active = false; return; } this.active = !this.active; if (this.active) { document.body.addEventListener("click", this.outside); } else { document.body.removeEventListener("click", this.outside); } } } }); (function() { let s = document.createElement('style'); let ss = document.createTextNode(`.ui-combo {position: relative;display: flex;border: 1px none transparent;outline: 1px solid rgba(0,0,0,0.1);background-color: transparent;height: inherit;align-items: stretch;color: rgba(0,0,0,0.8);}.ui-combo-placeholder {flex-grow: 1;display: flex;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 0 5px 0 5px;height: 100%;align-items: center;}.ui-combo-input {width: 100%;min-height: 32px;height: 100%;}.ui-combo-dropdown {position: absolute;box-shadow: 3px 6px 22px -5px rgba(0, 0, 0, 0.4);background: #fff;min-width: 100%;height: auto;max-height: 250px;overflow: auto;top: 100%;}.ui-combo-option {white-space: nowrap;padding: 10px;display: block;cursor: pointer;user-select: none;}.ui-combo-option:hover {background-color: rgba(0,0,0,0.05);}`); s.append(ss); document.head.append(s); })(); Vue.component('ui-date', { template: ``, props: { value: [String, Date], disabled: { type: Boolean, default: function () { return false; } } }, data() { return { proxy: null }; }, watch: { value() { this.setValue(); } }, async created() { this.setValue(); }, methods: { updateValue() { this.$emit('input', this.proxy + 'T00:00:00'); }, setValue() { if (typeof this.value == 'string') { this.proxy = this.value.split('T')[0]; } else if (this.value instanceof Date) { this.proxy = this.value.toDatetimeLocal().split('T')[0]; this.$emit('input', this.proxy); } } } }); Vue.filter('date', function (value) { if (!value) return '' value = new Date(value); return value.toLocaleDateString('ru-RU', { year: 'numeric', month: 'long', day: 'numeric' }); }) Vue.component('ui-datetime', { template: ``, props: { value: [String, Date], disabled: { type: Boolean, default: function () { return false; } } }, data() { return { proxy: null }; }, watch: { value() { this.setValue(); } }, async created() { this.setValue(); }, methods: { updateValue() { this.$emit('input', this.proxy); }, setValue() { if (typeof this.value == 'string') { this.proxy = this.value; } else if (this.value instanceof Date) { this.proxy = this.value.toDatetimeLocal(); this.$emit('input', this.proxy); } } } }); Vue.filter('datetime', function (value) { if (!value) return '' value = new Date(value); return value.toLocaleDateString('ru-RU', { year: 'numeric', month: 'long', day: 'numeric' }) + value.toLocaleTimeString('ru-RU'); }); Date.prototype.toDatetimeLocal = function toDatetimeLocal() { var date = this, ten = function (i) { return (i < 10 ? '0' : '') + i; }, YYYY = date.getFullYear(), MM = ten(date.getMonth() + 1), DD = ten(date.getDate()), HH = ten(date.getHours()), II = ten(date.getMinutes()), SS = ten(date.getSeconds()) ; return YYYY + '-' + MM + '-' + DD + 'T' + HH + ':' + II + ':' + SS; }; Vue.component('ui-dialogs', { template: `

{{dialog.title}}

`, data: function () { return { dialogs: [], factory: 'DialogFactory' } }, created: function () { if (this.factory in window) { window[this.factory].component = this; } }, methods: { confirm: function (dialog) { var component = this.$refs[dialog.name][0].$children[0]; if (component && component.confirm) { if (dialog.requireResult) { let self = this; if (component.confirm.constructor.name === "AsyncFunction") { component.confirm().then((res) => { if (res) self.close(dialog); }); } else { if (component.confirm()) self.close(dialog); } } else { let self = this; if (component.confirm.constructor.name === "AsyncFunction") { component.confirm().then((res) => { self.close(dialog); }); } else { self.close(dialog); } } } else { this.close(dialog); } }, cancel: function (dialog) { var component = this.$refs[dialog.name][0].$children[0]; if (component && component.cancel) { component.cancel(); } this.close(dialog); }, push: function (dialog) { dialog.title = dialog.title || ''; dialog.props = dialog.props || {}; dialog.events = dialog.events || {}; dialog.width = dialog.width ? dialog.width + 'px' : '400px'; dialog.height = dialog.height ? dialog.height + 'px' : '200px'; dialog.index = 11001 + this.dialogs.length + 1; dialog.close = this.close; dialog.confirm = this.confirm; dialog.cancel = this.cancel; dialog.singleButton = dialog.singleButton || false; dialog.hideControls = dialog.hideControls || false; dialog.requireResult = dialog.requireResult || false; /****????***/ if (typeof dialog.component === 'object') { let comp = dialog.component; dialog.component = comp.name; dialog.componentUrl = comp.url; dialog.width = comp.width ? comp.width + 'px' : dialog.width; } dialog.name = dialog.component + dialog.index; this.dialogs.push(dialog); return dialog; }, close: function (event) { this.dialogs.splice(this.dialogs.indexOf(event), 1); } } }); (function() { let s = document.createElement('style'); let ss = document.createTextNode(`.dialog-blocker {background: #fff;position: fixed;left: 0;right: 0;bottom: 0;top: 0;background-color: rgba(0,0,0,0.05);z-index: 1;}dialog {position: fixed;margin-left: auto;margin-right: auto;background: #fff;box-shadow: 0 11px 15px -7px rgba(0, 0, 0, .2), 0 24px 38px 3px rgba(0, 0, 0, .14), 0 9px 46px 8px rgba(0, 0, 0, .12);display: flex;-webkit-box-orient: vertical; -webkit-flex-direction: column; flex-direction: column;/*right: 0px;*/left: 0px;top: 0px;bottom: 0px;max-width: 900px;max-height: 800px;padding: 0px;border: 0px;z-index: 10000;}dialog .ui-dialog-content {flex-grow: 1;overflow: auto;max-height: 800px;padding: 10px;}dialog .footer {height: 60px;min-height: 60px;border-top: 1px solid #eee;justify-content: center;align-items: center;display: flex;padding: 0 20px;}dialog .header {height: 50px;min-height: 50px;border-bottom: 1px solid #eee;-webkit-box-pack: start; -webkit-justify-content: flex-start; justify-content: flex-start;align-items: center;display: flex;padding: 0 20px;background: #3076ad;color: #fff;}dialog .header h1 {font-size: 13px;}`); s.append(ss); document.head.append(s); })(); Vue.directive('enum', { bind: function (el, binding, vnode) { try { el.innerText = engros.systypes[binding.arg][binding.value].name; } catch (ex) { console.log(ex); console.error('error defining enum'); el.innerText = binding.value; } }, update: function (el, binding, vnode) { try { el.innerText = engros.systypes[binding.arg][binding.value].name; } catch (ex) { console.log(ex); console.error('error defining enum'); el.innerText = binding.value; } } }); Vue.directive('select', { bind: function (el, binding, vnode) { el.innerHTML = ''; if (binding.value && binding.value.forEach) { binding.value.forEach(op => { let option = document.createElement("option"); option.innerText = op.name; option.value = op.id; option.setAttribute("autocreated", "true"); el.appendChild(option); }); } }, update: function (el, binding, vnode) { el.innerHTML = ''; if (binding.value && binding.value.forEach) { binding.value.forEach(op => { let option = document.createElement("option"); option.innerText = op.name; option.value = op.id; option.setAttribute("autocreated", "true"); el.appendChild(option); }); } } }); Vue.component('ui-dropdown', { template: `
no content provided for dropdown
`, props: ['width', 'disabled'], watch: { }, data: function () { return { active: false, component: { width: 'auto' } }; }, created: async function () { if (this.width && !this.width.indexOf('%') > -1) { this.component.width = this.width.indexOf('%') > -1 ? this.width : this.width + 'px'; } else { this.component.width = 'auto'; } }, methods: { outside(event) { if (!(this.$el === event.target || this.$el.contains(event.target))) { this.hide(); } }, show() { this.active = true; document.body.addEventListener("click", this.outside); }, hide() { this.active = false; document.body.removeEventListener("click", this.outside); }, toggle() { if (!this.disabled) { this.active = !this.active; if (this.active) { document.body.addEventListener("click", this.outside); } else { document.body.removeEventListener("click", this.outside); } } } } }); (function() { let s = document.createElement('style'); let ss = document.createTextNode(`.ui-dropdown-container {display: inline-flex;flex-shrink: 0;width: auto;position: relative;align-items: center;line-height: inherit;padding: 0;margin: 0;/*top: -1px;*/ /*??????????????????*/white-space: nowrap;/*height: 100%;*/min-height: 32px;}.ui-dropdown-control {/*cursor: pointer;*/height: 100%;width: 100%;overflow: hidden;padding: 0;margin: 0;min-height: 32px;flex-grow: 1;line-height: inherit;}.ui-dropdown-option {display: block;padding: 0 5px;white-space: nowrap;line-height: inherit;cursor: default;user-select: none;}.ui-dropdown-actions {display: block;white-space: nowrap;line-height: inherit;}.ui-dropdown-option:hover {background-color: rgba(0,0,0,0.06);}.ui-dropdown {z-index: 13001;left: 0;top: 100%;position: absolute;box-shadow: 3px 6px 22px -5px rgba(0, 0, 0, 0.4);background: #fff;width: auto;min-width: 100%;max-height: 500px;overflow: auto;outline: 1px solid #c8c8c8;line-height: initial;}.ui-dropdown > .btn {display: block;width: 100%;text-align: left;border-bottom: 1px solid #eee;background: white;color: black;min-height: 30px;}.success > .ui-dropdown > .btn {color: #4a9b31}.ui-dropdown > .btn:last-child {border-bottom: 0px solid transparent;}.ui-dropdown-container.btn:hover {opacity: 1;}`); s.append(ss); document.head.append(s); })(); Vue.component('ui-enum-flagged', { template: `
`, props: ["value", 'url'], data() { return { proxy: 0, enums: [] }; }, watch: { value() { this.proxy = this.value; this.initValue(); } }, async created() { this.proxy = this.value; if (this.url) { let r = await api.get(this.url, {}, true); if (r) { this.enums = r; } } this.initValue(); }, methods: { initValue() { for (var i = 0; i < this.enums.length; i++) { Vue.set(this.enums[i], 'checked', this.proxy & this.enums[i].id ? true : false); //this.enums[i].checked = this.proxy & this.enums[i].id ? true : false; } }, updateValue() { let res = 0; for (var i = 0; i < this.enums.length; i++) { if (this.enums[i].checked) { res = res | this.enums[i].id; } } this.proxy = res; this.$emit('input', this.proxy); } } }); Vue.component('ui-enum', { template: `
{{title}}
{{enums[proxy].name}}
`, reusable: true, props: { value: [String, Number], url: String, title: String, mode: { type: String, default: function () { return 'radio'; } }, disabled: { type: [String, Boolean], default: function () { return false; } }, nullable: { type: [Boolean], default: function () { return false; } }, dataEnums: { type: [Array], default: function () { return []; } } }, computed: { enums: function () { if (this.url) return this.urlEnums; else return this.dataEnums; } }, data() { return { proxy: null, urlEnums: [] }; }, watch: { value() { this.proxy = this.value; } }, async created() { this.proxy = this.value; if (this.url) { let r = await api.get(this.url, {}, true); if (r) { this.urlEnums = r; if (this.mode == 'select' && !this.proxy && this.proxy !== 0) { this.proxy = this.enums[0].id; this.updateValue(); } } } }, methods: { updateValue() { this.$emit('input', 1 * this.proxy); this.$emit('select', 1 * this.proxy); } } }); Vue.component('ui-left-panel', { template: `
{{ item.text }}
`, props: { childs: Array, parentKey: { type: String, default: function () { return ''; } }, }, data: function () { if (this.childs) { return { items: this.childs }; } else { return { items: [ { text: 'Документы', icon: 'ms-Icon--CheckListText', childs: [ { text: 'Заказы', icon: 'ms-Icon--TextDocument', link: '/documents/orders', childs: [] }, { text: 'Продажи', icon: 'ms-Icon--TextDocument', link: '/documents/sales', childs: [] }, { text: 'Заказы на поставку', icon: 'ms-Icon--TextDocument', link: '/documents/purchaseOrders', childs: [] }, { text: 'Поступления товаров', icon: 'ms-Icon--TextDocument', link: '/documents/goodsReceipts', childs: [] }, { text: 'Транспорт', icon: 'ms-Icon--CheckListText', childs: [ { text: 'Отгрузки', icon: 'ms-Icon--TextDocument', link: '/documents/shipments', childs: [] }, { text: 'Накладные', icon: 'ms-Icon--TextDocument', link: '/documents/shipmentlists', childs: [] }, ] }, { text: 'Взаиморасчеты', icon: 'ms-Icon--CheckListText', childs: [ { text: 'От покупателя', icon: 'ms-Icon--TextDocument', link: '/documents/customerPayments', childs: [] }, { text: 'Покупателю', icon: 'ms-Icon--TextDocument', link: '/documents/customerRefunds', childs: [] }, { text: 'От поставщика', icon: 'ms-Icon--TextDocument', link: '/documents/supplierRefunds', childs: [] }, { text: 'Поставщику', icon: 'ms-Icon--TextDocument', link: '/documents/supplierPayments', childs: [] }, { text: 'Корректировка взаиморасчетов', icon: 'ms-Icon--TextDocument', link: '/documents/settlementAdjustments', childs: [] }, ] }, { text: 'Возвраты', icon: 'ms-Icon--CheckListText', childs: [ { text: 'От покупателя', icon: 'ms-Icon--TextDocument', link: '/documents/customerReturns', childs: [] }, { text: 'Поставщику', icon: 'ms-Icon--TextDocument', link: '/documents/supplierReturns', childs: [] }, ] }, { text: 'Склад', icon: 'ms-Icon--CheckListText', childs: [ { text: 'Списания', icon: 'ms-Icon--TextDocument', link: '/documents/stockDepreciations', childs: [] }, { text: 'Оприходования', icon: 'ms-Icon--TextDocument', link: '/documents/stockRecognitions', childs: [] }, ] }, { text: 'Установка цен', icon: 'ms-Icon--TextDocument', link: '/documents/pricings', childs: [] }, { text: 'Отчет по брендам', icon: 'ms-Icon--ReportDocument', link: '/documents/brandStockStatus', childs: [] }, ], }, { text: 'Каталог', icon: 'ms-Icon--CheckListText', childs: [ { text: 'Товары', icon: 'ms-Icon--TextDocument', link: '/catalog/products', childs: [] }, { text: 'Категории', icon: 'ms-Icon--TextDocument', link: '/catalog/categories', childs: [] }, { text: 'Группы размеров', icon: 'ms-Icon--TextDocument', link: '/catalog/productSizeGroups', childs: [] }, { text: 'Типы товаров', icon: 'ms-Icon--TextDocument', link: '/catalog/productTypes', childs: [] }, { text: 'Теги', icon: 'ms-Icon--TextDocument', link: '/catalog/tags', childs: [] }, ] }, { text: 'Компания', icon: 'ms-Icon--CheckList', childs: [ { text: 'Способы оплаты', icon: 'ms-Icon--TextDocument', link: '/company/paymentTypes', childs: [] }, { text: 'Способы доставки', icon: 'ms-Icon--TextDocument', link: '/company/shipmentTypes', childs: [] }, { text: 'Шаблоны упаковок', icon: 'ms-Icon--TextDocument', link: '/company/packageTemplates', childs: [] }, { text: 'Отправители', icon: 'ms-Icon--TextDocument', link: '/company/shipmentSenders', childs: [] }, { text: 'Организации', icon: 'ms-Icon--TextDocument', link: '/company/organizations', childs: [] }, { text: 'Статусы', icon: 'ms-Icon--CheckListText', childs: [ { text: 'Поступлений товаров', icon: 'ms-Icon--TextDocument', link: '/company/goodsReceiptsStatuses', childs: [] }, { text: 'Заказов', icon: 'ms-Icon--TextDocument', link: '/company/orderStatuses', childs: [] }, { text: 'Заказов поставщику', icon: 'ms-Icon--TextDocument', link: '/company/purchaseOrderStatuses', childs: [] }, { text: 'Продаж', icon: 'ms-Icon--TextDocument', link: '/company/saleStatuses', childs: [] }, { text: 'Отгрузок', icon: 'ms-Icon--TextDocument', link: '/company/shipmentStatuses', childs: [] }, { text: 'Возвратов от поставщика', icon: 'ms-Icon--TextDocument', link: '/company/supplierReturnStatuses', childs: [] }, ] }, ] }, { text: 'Склады', icon: 'ms-Icon--TextDocument', link: '/company/warehouses', childs: [] }, { text: 'Контрагенты', icon: 'ms-Icon--TextDocument', link: '/contractors/contractors', childs: [] }, ] }; } }, methods: { } }); Vue.component('ui-overlays', { template: `

{{dialog.title}}

`, data: function () { return { dialogs: [], factory: 'OverlayFactory', okButton: false, closeButton: true, saveButton: false, } }, created: function () { if (this.factory in window) { window[this.factory].component = this; } }, methods: { confirm: function (dialog) { var component = this.$refs[dialog.name][0].$children[0]; if (component && component.confirm) { let self = this; if (component.confirm.constructor.name === "AsyncFunction") { component.confirm().then((res) => { if (res || !dialog.requireResult) self.close(dialog); }); } else { if (component.confirm() || !dialog.requireResult) self.close(dialog); } } else { this.close(dialog); } }, cancel: function (dialog) { var component = this.$refs[dialog.name][0].$children[0]; if (component && component.cancel) { let self = this; if (component.cancel.constructor.name === "AsyncFunction") { component.cancel().then((res) => { self.close(dialog); }); } else { component.cancel(); self.close(dialog); } } else { this.close(dialog); } }, push: function (dialog) { dialog.title = dialog.title || ''; dialog.props = dialog.props || {}; dialog.events = dialog.events || {}; dialog.height = dialog.height ? dialog.height + 'px' : '200px'; dialog.close = this.close; dialog.confirm = this.confirm; dialog.cancel = this.cancel; dialog.requireResult = dialog.requireResult || false; dialog.hideNewTab = dialog.hideNewTab || false; dialog.right = 0; if (dialog.width) { if (dialog.width.toString().indexOf('%') == -1) dialog.width = dialog.width ? dialog.width + 'px' : dialog.width; } dialog.index = 11001 + this.dialogs.length + 1; dialog.name = dialog.component + dialog.index; dialog.selector = '[id=\"' + dialog.name + '"].overlay-content'; //let width = dialog.width; //dialog.width = '1px'; this.dialogs.push(dialog); //Vue.nextTick() // .then(function () { // dialog.width = width ? width : '400px'; // }); Vue.nextTick(() => { if (this.dialogs.length > 0) { var to = this.dialogs.length - 1; for (var i = 0; i <= to; i++) { this.dialogs[i].right = (to - i) * 100; } } }); return dialog; }, close: function (event) { if (!event || this.dialogs.indexOf(event) > -1) { this.dialogs.splice(this.dialogs.indexOf(event), 1); if (this.dialogs.length > 0) { var to = this.dialogs.length - 1; for (var i = 0; i <= to; i++) { this.dialogs[i].right = (to - i) * 100; } } } } } }); (function() { let s = document.createElement('style'); let ss = document.createTextNode(`.overlay-container {}.overlay {/*z-index: 10001;*/background: #fff;box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 30px 0px;overflow: auto;position: fixed;top: 0px;right: 0px;bottom: 0px;display: flex;-webkit-box-orient: vertical; -webkit-flex-direction: column; flex-direction: column;align-items: stretch;/*left: 100px;*//*transition: 2s;*/transition: 0.3s;z-index: 1;}.overlay-header {height: 50px;min-height: 50px;border-bottom: 1px solid #eee;-webkit-box-pack: start; -webkit-justify-content: flex-start; justify-content: flex-start;align-items: center;display: flex;padding: 0 20px;background: #3076ad;color: #fff;}.overlay-content {flex-grow: 1;padding: 0px;display: flex;padding: 10px;overflow-y: auto;overflow-x: hidden;}.overlay-content > div {width: 100%;}.overlay-footer {height: 60px;min-height: 60px;border-top: 1px solid #eee;padding: 20px;-webkit-box-pack: justify;-webkit-justify-content: space-between;justify-content: space-between;align-items: center;display: flex;background-color: rgba(0,0,0,0.02);}.overlay-blocker {position: fixed;left:0;right: 0;bottom: 0;top: 0;background-color: rgba(0,0,0,0.05);z-index: 1;}.overlay-content textarea {resize: none;}`); s.append(ss); document.head.append(s); })(); Vue.component('ui-select', { template: `
{{title}}
{{item.name}}
`, reusable: true, props: ['url', 'allowInput', 'valueField', 'placeholder', 'visible', 'disabled', 'value', 'width', 'options', 'label', 'showClear', 'showRefresh'], watch: { value: function (value) { this.initValue('value'); }, options: function (newValue) { this.items = newValue; this.initValue('options'); } }, data: function () { return { input: '', title: '', active: false, items: [], item: null, _showClear: true, _showRefresh: false, component: { width: '100%' } }; }, created: async function () { if (this.showClear === 'true' || this.showClear === true || this.showClear === undefined || this.showClear == null) { this._showClear = true; } else { this._showClear = false; } this._showRefresh = this.showRefresh ? true : false; if (this.width && !this.width.indexOf('%') > -1) { this.component.width = this.width.indexOf('%') > -1 ? this.width : this.width + 'px'; } else { this.component.width = 'auto'; } if (this.placeholder) { this.title = this.placeholder; } await this.refresh(); }, methods: { refresh: async function () { if (this.url) { let r = await api.get(this.url, {}, true); if (r && r.data) { this.items = r.data; this.initValue("options"); } else if (r) { this.items = r; this.initValue("options"); } } else if (this.options && this.options.length) { this.items = this.options; this.initValue("options"); } }, initValue(s) { if (s == 'options') { if (this.value && this.items) { let id = typeof this.value === 'string' ? this.value : typeof this.value === 'object' ? this.value.id : ''; this.item = this.items.filter(x => x.id === id)[0] || null; if (this.item) { this.title = this.item.name; } if (!this.item) { this.title = this.placeholder; this.$emit('input', null); this.$emit('select', null); } } else if (!this.items) { this.item = null; this.title = this.placeholder; this.$emit('input', null); this.$emit('select', null); } } if (s == 'value') { if (this.items && this.items.length && this.value && typeof this.value === 'string') { this.item = this.items.filter(x => x.id === this.value)[0]; if (this.item) { this.title = this.item.name; } else { this.title = this.placeholder; } if (!this.item) { this.title = this.placeholder; this.$emit('input', null); this.$emit('select', null); } } else if (this.items && this.items.length && this.value && typeof this.value === 'object') { this.item = this.items.filter(x => x.id === this.value.id)[0]; if (this.item) { this.title = this.item.name; } else { this.title = this.placeholder; } if (!this.item) { this.title = this.placeholder; this.$emit('input', null); this.$emit('select', null); } } else { this.title = this.placeholder; // this.$emit('input', null); // this.$emit('select', null); } } }, select(item) { if (this.item == item) return; this.item = item; this.title = item.name || this.title; if (this.allowInput) this.input = item.name || this.title; this.$emit('input', !this.valueField ? item : item[this.valueField]); this.$emit('select', !this.valueField ? item : item[this.valueField]); this.hide(); }, clear() { this.item = null; this.title = this.placeholder; this.input = ''; this.$emit('clear', null); this.$emit('input', null); this.hide(); }, outside(event) { if (!(this.$el === event.target || this.$el.contains(event.target))) { if (this.allowInput) { let items = this.items.filter(o => !this.input || o.name.toLowerCase().indexOf(this.input.toLowerCase()) > -1); if (items && items.length > 0) { this.input = items[0].name; this.$emit('input', !this.valueField ? items[0] : items[0][this.valueField]); this.$emit('select', !this.valueField ? items[0] : items[0][this.valueField]); } else { this.$emit('input', { name: this.input }); this.$emit('select', { name: this.input }); } } this.hide(); } }, show() { this.active = true; document.body.addEventListener("click", this.outside); }, hide() { this.active = false; document.body.removeEventListener("click", this.outside); }, toggle() { if (!this.items || !this.items.length) { this.active = false; return; } this.active = !this.active; if (this.active) { document.body.addEventListener("click", this.outside); } else { document.body.removeEventListener("click", this.outside); } } } }); (function() { let s = document.createElement('style'); let ss = document.createTextNode(`.ui-select {position: relative;display: flex;border: 1px none transparent;outline: 1px solid rgba(0,0,0,0.1);background-color: white;height: inherit;align-items: stretch;color: rgba(0,0,0,0.8);}.ui-select:hover {outline-color: rgba(0,0,0,0.1);}.ui-select:hover .ui-select-action {visibility: visible;}.ui-select button {/*display: none;*/height: 100%;}/*.ui-select:hover button {display: flex;}*/.ui-select-selected {/*background-color: rgba(0,0,0,0.02);*/}.ui-select-label {display: flex;white-space: nowrap;padding: 0 5px 0 5px;height: 100%;align-items: center;color: rgba(0,0,0,1);font-weight: 500;}.ui-select-placeholder {flex-grow: 1;display: flex;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 0 5px 0 5px;height: 100%;align-items: center;}.ui-select-title {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;cursor: pointer;}.ui-select-dropdown {position: absolute;box-shadow: 3px 6px 22px -5px rgba(0, 0, 0, 0.4);background: #fff;min-width: 100%;height: auto;max-height: 250px;overflow: auto;top: 100%;z-index: 10000;}.ui-select-option {white-space: nowrap;padding: 10px;display: block;cursor: pointer;user-select:none;}.ui-select-option:hover {background-color: rgba(0,0,0,0.05);}`); s.append(ss); document.head.append(s); })(); Vue.component('ui-sort', { template: `
{{title}} {{title}}
Применить
`, props: { title: String, name: String, type: String, operator: String, disableSort: Boolean, disableFilter: Boolean, url: String, options: Array, }, data() { return { mode: 'none', filter: '', filterTo: '', filterActive: false, }; }, methods: { outside(event) { if (!(this.$el === event.target || this.$el.contains(event.target))) { this.hideFilter(); } }, toggle: function () { if (!this.disableSort) { if (this.mode == 'asc') this.mode = 'desc'; else this.mode = 'asc'; this.$emit('toggle', this.name); } }, cancel: function () { this.mode = 'none'; this.filter = ''; this.$emit('cancel', this.name); }, submitFilter: function () { this.hideFilter() if (this.operator == '><') { if (this.filterTo) { this.$emit('filter', { field: this.name, type: this.type, operator: '>=', value: this.filter, and: true }); this.$emit('filter', { field: this.name, type: this.type, operator: '<=', value: this.filterTo, and: true }); } else { this.$emit('filter', { field: this.name, type: this.type, operator: '=', value: this.filter }); } } else if (this.type == 'enum') { if (this.filter) { this.$emit('filter', { field: this.name, type: 'number', operator: this.operator, value: this.filter }); } else { this.cancel(); } } else if (this.type == 'select') { if (this.filter) { this.$emit('filter', { field: this.name, type: 'guid', operator: this.operator, value: this.filter }); } else { this.cancel(); } } else { this.$emit('filter', { field: this.name, type: this.type, operator: this.operator, value: this.filter }); } }, outside(event) { if (!(this.$el === event.target || this.$el.contains(event.target))) { this.hideFilter(); } }, showFilter() { this.filterActive = true; document.body.addEventListener("click", this.outside); }, hideFilter() { this.filterActive = false; document.body.removeEventListener("click", this.outside); }, toggleFilter() { this.filterActive = !this.filterActive; if (this.filterActive) { document.body.addEventListener("click", this.outside); } else { document.body.removeEventListener("click", this.outside); } } } }); Vue.component('ui-suggest', { template: `
{{item.name}}
`, reusable: true, props: ['url', 'valueField', 'placeholder', 'visible', 'disabled', 'value', 'width', 'options'], watch: { options: function (newValue) { this.items = newValue; } }, data: function () { return { title: '', active: false, items: [], search: '', component: { width: '100%' } }; }, created: async function () { if (this.width && !this.width.indexOf('%') > -1) { this.component.width = this.width.indexOf('%') > -1 ? this.width : this.width + 'px'; } else { this.component.width = 'auto'; } if (this.placeholder) { this.title = this.placeholder; } }, methods: { select(item) { this.$emit('suggest', !this.valueField ? item : item[this.valueField]); this.hide(); }, async input() { if (this.url) { let r = await api.get(this.url + this.search, {}, true); if (r && r.data) { this.items = r.data; } } this.$emit('input', this.search); }, outside(event) { if (!(this.$el === event.target || this.$el.contains(event.target))) { this.hide(); } }, show() { this.active = true; document.body.addEventListener("click", this.outside); }, hide() { this.active = false; document.body.removeEventListener("click", this.outside); }, toggle() { if (!this.items.length) { this.active = false; return; } this.active = !this.active; if (this.active) { document.body.addEventListener("click", this.outside); } else { document.body.removeEventListener("click", this.outside); } } } }); (function() { let s = document.createElement('style'); let ss = document.createTextNode(`.ui-suggest {position: relative;display: flex;border: 1px none transparent;outline: 1px solid rgba(0,0,0,0.1);height: inherit;align-items: stretch;color: rgba(0,0,0,0.8);}.ui-suggest:hover {outline-color: rgba(0,0,0,0.5);}.ui-suggest-input {flex-grow: 1;display: flex;padding: 0 5px 0 5px;height: 100%;border: none;outline: none;}.ui-suggest-dropdown {position: absolute;box-shadow: 3px 6px 22px -5px rgba(0, 0, 0, 0.4);background: #fff;min-width: 100%;height: auto;max-height: 250px;overflow: auto;top: 100%;}.ui-suggest-option {white-space: nowrap;padding: 10px;display: block;cursor: pointer;user-select: none;}.ui-suggest-option:hover {background-color: rgba(0,0,0,0.05);}`); s.append(ss); document.head.append(s); })(); Vue.component('ui-tree', { template: `
[{{ isOpen ? '-' : '+' }}] {{ item.name }}
`, props: { item: Object, }, data: function () { return { isOpen: false } }, computed: { isFolder: function () { return this.item.children && this.item.children.length }, isSelected: function () { if (this.isFolder) { return this.item.children.filter(ch => !ch.selected) == 0; } return this.item.selected; } }, watch: { 'item.children': { handler: function () { if (this.isFolder) { //if (this.item.children.filter(ch => !ch.selected).length == 0) this.item.selected = true; if (this.item.children.some(ch => ch.selected)) this.item.selected = true; else this.item.selected = false; } }, deep: true }, }, created: function () { if (!this.item.name) this.isOpen = true; //todo this.item.selected = true ���� ���� �� ������� selected }, methods: { toggle: function () { if (this.isFolder) { this.isOpen = !this.isOpen } else { this.item.selected = !this.item.selected; } }, toggleAll: function () { //this.toggleChilds(this.item, !this.item.selected); this.toggleChilds(this.item, !this.isSelected); }, toggleChilds: function (item, selected) { item.selected = selected; item.children.forEach(i => { this.toggleChilds(i, selected); }); } } });