diff options
| author | Tara Rostami <132676256+TaraRostami@users.noreply.github.com> | 2024-04-20 21:45:36 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-20 21:45:36 +0300 |
| commit | db24d216210e0038f92e634de1ab8a46fbce4632 (patch) | |
| tree | 3648326a1e359543febd865747822bc6f8f72781 /web/html/xui | |
| parent | 3d5c06bf08f0ede7206e0ef39966d6be2106a225 (diff) | |
UI Improvements (#2228)
* UI Improvements
Better Table
Update QR Code Modal
Better Info Modal
Compression HTML files
Better Dropdown Menu
Better Calendar
and more ..
Remove files
Minor Fixes
Diffstat (limited to 'web/html/xui')
22 files changed, 2292 insertions, 2195 deletions
diff --git a/web/html/xui/common_sider.html b/web/html/xui/common_sider.html index bc8f4608..df659489 100644 --- a/web/html/xui/common_sider.html +++ b/web/html/xui/common_sider.html @@ -1,61 +1,65 @@ {{define "menuItems"}} <a-menu-item key="{{ .base_path }}panel/"> - <a-icon type="dashboard"></a-icon> - <span><b>{{ i18n "menu.dashboard"}}</b></span> + <a-icon type="dashboard"></a-icon> + <span> + <b>{{ i18n "menu.dashboard"}}</b> + </span> </a-menu-item> <a-menu-item key="{{ .base_path }}panel/inbounds"> - <a-icon type="user"></a-icon> - <span><b>{{ i18n "menu.inbounds"}}</b></span> + <a-icon type="user"></a-icon> + <span> + <b>{{ i18n "menu.inbounds"}}</b> + </span> </a-menu-item> <a-menu-item key="{{ .base_path }}panel/settings"> - <a-icon type="setting"></a-icon> - <span><b>{{ i18n "menu.settings"}}</b></span> + <a-icon type="setting"></a-icon> + <span> + <b>{{ i18n "menu.settings"}}</b> + </span> </a-menu-item> <a-menu-item key="{{ .base_path }}panel/xray"> - <a-icon type="tool"></a-icon> - <span><b>{{ i18n "menu.xray"}}</b></span> + <a-icon type="tool"></a-icon> + <span> + <b>{{ i18n "menu.xray"}}</b> + </span> </a-menu-item> <a-menu-item key="{{ .base_path }}logout"> - <a-icon type="logout"></a-icon> - <span><b>{{ i18n "menu.logout"}}</b></span> + <a-icon type="logout"></a-icon> + <span> + <b>{{ i18n "menu.logout"}}</b> + </span> </a-menu-item> {{end}} {{define "commonSider"}} -<a-layout-sider :theme="themeSwitcher.currentTheme" id="sider" collapsible breakpoint="md" collapsed-width="0"> - <theme-switch></theme-switch> - <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" - @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> - {{template "menuItems" .}} - </a-menu> +<a-layout-sider :theme="themeSwitcher.currentTheme" id="sider" collapsible breakpoint="md"> + <theme-switch></theme-switch> + <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> + {{template "menuItems" .}} + </a-menu> </a-layout-sider> -<a-drawer id="sider-drawer" placement="left" :closable="false" - @close="siderDrawer.close()" - :visible="siderDrawer.visible" - :wrap-class-name="themeSwitcher.currentTheme" - :wrap-style="{ padding: 0 }"> - <div class="drawer-handle" @click="siderDrawer.change()" slot="handle"> - <a-icon :type="siderDrawer.visible ? 'close' : 'menu-fold'"></a-icon> - </div> - <theme-switch></theme-switch> - <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" - @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> - {{template "menuItems" .}} - </a-menu> +<a-drawer id="sider-drawer" placement="left" :closable="false" @close="siderDrawer.close()" :visible="siderDrawer.visible" :wrap-class-name="themeSwitcher.currentTheme" :wrap-style="{ padding: 0 }"> + <div class="drawer-handle" @click="siderDrawer.change()" slot="handle"> + <a-icon :type="siderDrawer.visible ? 'close' : 'menu-fold'"></a-icon> + </div> + <theme-switch></theme-switch> + <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> + {{template "menuItems" .}} + </a-menu> </a-drawer> <script> - const siderDrawer = { - visible: false, - show() { - this.visible = true; - }, - close() { - this.visible = false; - }, - change() { - this.visible = !this.visible; - }, - }; + const siderDrawer = { + visible: false, + show() { + this.visible = true; + }, + close() { + this.visible = false; + }, + change() { + this.visible = !this.visible; + }, + }; </script> {{end}} diff --git a/web/html/xui/component/sortableTable.html b/web/html/xui/component/sortableTable.html index 5eb2e1cc..f62eba44 100644 --- a/web/html/xui/component/sortableTable.html +++ b/web/html/xui/component/sortableTable.html @@ -1,236 +1,216 @@ {{define "component/sortableTableTrigger"}} - <a-icon type="drag" - class="sortable-icon" - style="cursor: move;" - @mouseup="mouseUpHandler" - @mousedown="mouseDownHandler" - @click="clickHandler" /> +<a-icon type="drag" + class="sortable-icon" + style="cursor: move;" + @mouseup="mouseUpHandler" + @mousedown="mouseDownHandler" + @click="clickHandler" /> {{end}} {{define "component/sortableTable"}} <script> - const DRAGGABLE_ROW_CLASS = 'draggable-row'; - - const findParentRowElement = (el) => { - if (!el || !el.tagName) { - return null; - } else if (el.classList.contains(DRAGGABLE_ROW_CLASS)) { - return el; - } else if (el.parentNode) { - return findParentRowElement(el.parentNode); - } else { - return null; - } + const DRAGGABLE_ROW_CLASS = 'draggable-row'; + const findParentRowElement = (el) => { + if (!el || !el.tagName) { + return null; + } else if (el.classList.contains(DRAGGABLE_ROW_CLASS)) { + return el; + } else if (el.parentNode) { + return findParentRowElement(el.parentNode); + } else { + return null; } - - Vue.component('a-table-sortable', { - data() { - return { - sortingElementIndex: null, - newElementIndex: null, - }; - }, - props: ['data-source', 'customRow'], - inheritAttrs: false, - provide() { - const sortable = {} - - Object.defineProperty(sortable, "setSortableIndex", { - enumerable: true, - get: () => this.setCurrentSortableIndex, - }); - - Object.defineProperty(sortable, "resetSortableIndex", { - enumerable: true, - get: () => this.resetSortableIndex, - }); - - return { - sortable, - } + } + Vue.component('a-table-sortable', { + data() { + return { + sortingElementIndex: null, + newElementIndex: null, + }; + }, + props: ['data-source', 'customRow'], + inheritAttrs: false, + provide() { + const sortable = {} + Object.defineProperty(sortable, "setSortableIndex", { + enumerable: true, + get: () => this.setCurrentSortableIndex, + }); + Object.defineProperty(sortable, "resetSortableIndex", { + enumerable: true, + get: () => this.resetSortableIndex, + }); + return { + sortable, + } + }, + render: function(createElement) { + return createElement('a-table', { + class: { + 'ant-table-is-sorting': this.isDragging(), }, - render: function (createElement) { - return createElement('a-table', { - class: { - 'ant-table-is-sorting': this.isDragging(), - }, - props: { - ...this.$attrs, - 'data-source': this.records, - customRow: (record, index) => this.customRowRender(record, index), - }, - on: this.$listeners, - nativeOn: { - drop: (e) => this.dropHandler(e), - }, - scopedSlots: this.$scopedSlots, - }, this.$slots.default, ) + props: { + ...this.$attrs, + 'data-source': this.records, + customRow: (record, index) => this.customRowRender(record, index), }, - created() { - this.$memoSort = {}; + on: this.$listeners, + nativeOn: { + drop: (e) => this.dropHandler(e), }, - methods: { - isDragging() { - const currentIndex = this.sortingElementIndex; - return currentIndex !== null && currentIndex !== undefined; - }, - resetSortableIndex(e, index) { - this.sortingElementIndex = null; - this.newElementIndex = null; - this.$memoSort = {}; - }, - setCurrentSortableIndex(e, index) { - this.sortingElementIndex = index; - }, - dragStartHandler(e, index) { - if (!this.isDragging()) { - e.preventDefault(); - return; - } - const hideDragImage = this.$el.cloneNode(true); - hideDragImage.id = "hideDragImage-hide"; - hideDragImage.style.opacity = 0; - e.dataTransfer.setDragImage(hideDragImage, 0, 0); - }, - dragStopHandler(e, index) { - const hideDragImage = document.getElementById('hideDragImage-hide'); - if (hideDragImage) hideDragImage.remove(); - this.resetSortableIndex(e, index); - }, - dragOverHandler(e, index) { - if (!this.isDragging()) { - return; - } - - e.preventDefault(); - - const currentIndex = this.sortingElementIndex; - if (index === currentIndex) { - this.newElementIndex = null; - return; - } - - const row = findParentRowElement(e.target); - if (!row) { - return; - } - - const rect = row.getBoundingClientRect(); - const offsetTop = e.pageY - rect.top; - - if (offsetTop < rect.height / 2) { - this.newElementIndex = Math.max(index - 1, 0); - } else { - this.newElementIndex = index; - } - }, - dropHandler(e) { - if (this.isDragging()) { - this.$emit('onsort', this.sortingElementIndex, this.newElementIndex); - } - }, - customRowRender(record, index) { - const parentMethodResult = this.customRow?.(record, index) || {}; - const newIndex = this.newElementIndex; - const currentIndex = this.sortingElementIndex; - - return { - ...parentMethodResult, - attrs: { - ...(parentMethodResult?.attrs || {}), - draggable: true, - }, - on: { - ...(parentMethodResult?.on || {}), - dragstart: (e) => this.dragStartHandler(e, index), - dragend: (e) => this.dragStopHandler(e, index), - dragover: (e) => this.dragOverHandler(e, index), - }, - class: { - ...(parentMethodResult?.class || {}), - [DRAGGABLE_ROW_CLASS]: true, - ['dragging']: this.isDragging() - ? (newIndex === null ? index === currentIndex : index === newIndex) - : false, - }, - }; - } - }, - computed: { - records() { - const newIndex = this.newElementIndex; - const currentIndex = this.sortingElementIndex; - - if (!this.isDragging() || newIndex === null || currentIndex === newIndex) { - return this.dataSource; - } - - if (this.$memoSort.newIndex === newIndex) { - return this.$memoSort.list; - } - - let list = [...this.dataSource]; - list.splice(newIndex, 0, list.splice(currentIndex, 1)[0]); - - this.$memoSort = { - newIndex, - list, - }; - - return list; - } + scopedSlots: this.$scopedSlots, + }, this.$slots.default, ) + }, + created() { + this.$memoSort = {}; + }, + methods: { + isDragging() { + const currentIndex = this.sortingElementIndex; + return currentIndex !== null && currentIndex !== undefined; + }, + resetSortableIndex(e, index) { + this.sortingElementIndex = null; + this.newElementIndex = null; + this.$memoSort = {}; + }, + setCurrentSortableIndex(e, index) { + this.sortingElementIndex = index; + }, + dragStartHandler(e, index) { + if (!this.isDragging()) { + e.preventDefault(); + return; } - }); - - Vue.component('table-sort-trigger', { - template: `{{template "component/sortableTableTrigger"}}`, - props: ['item-index'], - inject: ['sortable'], - methods: { - mouseDownHandler(e) { - if (this.sortable) { - this.sortable.setSortableIndex(e, this.itemIndex); - } - }, - mouseUpHandler(e) { - if (this.sortable) { - this.sortable.resetSortableIndex(e, this.itemIndex); - } - }, - clickHandler(e) { - e.preventDefault(); - }, + const hideDragImage = this.$el.cloneNode(true); + hideDragImage.id = "hideDragImage-hide"; + hideDragImage.style.opacity = 0; + e.dataTransfer.setDragImage(hideDragImage, 0, 0); + }, + dragStopHandler(e, index) { + const hideDragImage = document.getElementById('hideDragImage-hide'); + if (hideDragImage) hideDragImage.remove(); + this.resetSortableIndex(e, index); + }, + dragOverHandler(e, index) { + if (!this.isDragging()) { + return; } - }) -</script> - -<style> - @media only screen and (max-width: 767px) { - .sortable-icon { - display: none; + e.preventDefault(); + const currentIndex = this.sortingElementIndex; + if (index === currentIndex) { + this.newElementIndex = null; + return; } + const row = findParentRowElement(e.target); + if (!row) { + return; + } + const rect = row.getBoundingClientRect(); + const offsetTop = e.pageY - rect.top; + if (offsetTop < rect.height / 2) { + this.newElementIndex = Math.max(index - 1, 0); + } else { + this.newElementIndex = index; + } + }, + dropHandler(e) { + if (this.isDragging()) { + this.$emit('onsort', this.sortingElementIndex, this.newElementIndex); + } + }, + customRowRender(record, index) { + const parentMethodResult = this.customRow?.(record, index) || {}; + const newIndex = this.newElementIndex; + const currentIndex = this.sortingElementIndex; + return { + ...parentMethodResult, + attrs: { + ...(parentMethodResult?.attrs || {}), + draggable: true, + }, + on: { + ...(parentMethodResult?.on || {}), + dragstart: (e) => this.dragStartHandler(e, index), + dragend: (e) => this.dragStopHandler(e, index), + dragover: (e) => this.dragOverHandler(e, index), + }, + class: { + ...(parentMethodResult?.class || {}), + [DRAGGABLE_ROW_CLASS]: true, + ['dragging']: this.isDragging() ? (newIndex === null ? index === currentIndex : index === newIndex) : false, + }, + }; + } + }, + computed: { + records() { + const newIndex = this.newElementIndex; + const currentIndex = this.sortingElementIndex; + if (!this.isDragging() || newIndex === null || currentIndex === newIndex) { + return this.dataSource; + } + if (this.$memoSort.newIndex === newIndex) { + return this.$memoSort.list; + } + let list = [...this.dataSource]; + list.splice(newIndex, 0, list.splice(currentIndex, 1)[0]); + this.$memoSort = { + newIndex, + list, + }; + return list; + } } - .ant-table-is-sorting .draggable-row td { - background-color: #ffffff !important; - } - .dark .ant-table-is-sorting .draggable-row td { - background-color: var(--dark-color-surface-100) !important; - } - .ant-table-is-sorting .dragging td { - background-color: rgb(232 244 242) !important; - color: rgba(0, 0, 0, 0.3); - } - .dark .ant-table-is-sorting .dragging td { - background-color: var(--dark-color-table-hover) !important; - color: rgba(255, 255, 255, 0.3); - } - .ant-table-is-sorting .dragging { - opacity: 1; - box-shadow: 1px -2px 2px #008771; - transition: all 0.2s; + }); + Vue.component('table-sort-trigger', { + template: `{{template "component/sortableTableTrigger"}}`, + props: ['item-index'], + inject: ['sortable'], + methods: { + mouseDownHandler(e) { + if (this.sortable) { + this.sortable.setSortableIndex(e, this.itemIndex); + } + }, + mouseUpHandler(e) { + if (this.sortable) { + this.sortable.resetSortableIndex(e, this.itemIndex); + } + }, + clickHandler(e) { + e.preventDefault(); + }, } - .ant-table-is-sorting .dragging .ant-table-row-index { - opacity: 0.3; + }) +</script> +<style> + @media only screen and (max-width: 767px) { + .sortable-icon { + display: none; } + } + .ant-table-is-sorting .draggable-row td { + background-color: #ffffff !important; + } + .dark .ant-table-is-sorting .draggable-row td { + background-color: var(--dark-color-surface-100) !important; + } + .ant-table-is-sorting .dragging td { + background-color: rgb(232 244 242) !important; + color: rgba(0, 0, 0, 0.3); + } + .dark .ant-table-is-sorting .dragging td { + background-color: var(--dark-color-table-hover) !important; + color: rgba(255, 255, 255, 0.3); + } + .ant-table-is-sorting .dragging { + opacity: 1; + box-shadow: 1px -2px 2px #008771; + transition: all 0.2s; + } + .ant-table-is-sorting .dragging .ant-table-row-index { + opacity: 0.3; + } </style> {{end}} diff --git a/web/html/xui/component/themeSwitch.html b/web/html/xui/component/themeSwitch.html index 28fe3e11..0de64a84 100644 --- a/web/html/xui/component/themeSwitch.html +++ b/web/html/xui/component/themeSwitch.html @@ -1,6 +1,23 @@ {{define "component/themeSwitchTemplate"}} <template> - <a-menu class="change-theme" :theme="themeSwitcher.currentTheme" mode="inline" selected-keys=""> + <a-menu :theme="themeSwitcher.currentTheme" mode="inline" selected-keys=""> + <a-sub-menu> + <span slot="title"> + <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon> + <span>Theme</span> + </span> + <a-menu-item id="change-theme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOff()"> Dark <a-switch style="margin-left: 2px;" size="small" :default-checked="themeSwitcher.isDarkTheme" @change="themeSwitcher.toggleTheme()"></a-switch> + </a-menu-item> + <a-menu-item id="change-theme-ultra" v-if="themeSwitcher.isDarkTheme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOffUltra()"> Ultra <a-checkbox style="margin-left: 2px;" :checked="themeSwitcher.isUltra" @click="themeSwitcher.toggleUltra()"></a-checkbox> + </a-menu-item> + </a-sub-menu> + </a-menu> +</template> +{{end}} + +{{define "component/themeSwitchTemplateLogin"}} +<template> + <a-menu @mousedown="themeSwitcher.animationsOff()" id="change-theme" :theme="themeSwitcher.currentTheme" mode="inline" selected-keys=""> <a-menu-item mode="inline" class="ant-menu-theme-switch"> <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon> <a-switch size="small" :default-checked="themeSwitcher.isDarkTheme" @change="themeSwitcher.toggleTheme()"></a-switch> @@ -23,6 +40,26 @@ const theme = isDarkTheme ? 'dark' : 'light'; document.querySelector('body').setAttribute('class', theme); return { + animationsOff() { + document.documentElement.setAttribute('data-theme-animations', 'off'); + const themeAnimations = document.querySelector('#change-theme'); + themeAnimations.addEventListener('mouseleave', () => { + document.documentElement.removeAttribute('data-theme-animations'); + }); + themeAnimations.addEventListener('touchend', () => { + document.documentElement.removeAttribute('data-theme-animations'); + }); + }, + animationsOffUltra() { + document.documentElement.setAttribute('data-theme-animations', 'off'); + const themeAnimationsUltra = document.querySelector('#change-theme-ultra'); + themeAnimationsUltra.addEventListener('mouseleave', () => { + document.documentElement.removeAttribute('data-theme-animations'); + }); + themeAnimationsUltra.addEventListener('touchend', () => { + document.documentElement.removeAttribute('data-theme-animations'); + }); + }, isDarkTheme, isUltra, get currentTheme() { @@ -57,13 +94,19 @@ getContainer: () => document.getElementById('message') }); document.getElementById('message').className = themeSwitcher.currentTheme; - const themeAnimations = document.querySelector('.change-theme'); - themeAnimations.addEventListener('mousedown', () => { - document.documentElement.setAttribute('data-theme-animations', 'off'); - }); - themeAnimations.addEventListener('mouseleave', () => { - document.documentElement.removeAttribute('data-theme-animations'); + } + }); + Vue.component('theme-switch-login', { + props: [], + template: `{{template "component/themeSwitchTemplateLogin"}}`, + data: () => ({ + themeSwitcher + }), + mounted() { + this.$message.config({ + getContainer: () => document.getElementById('message') }); + document.getElementById('message').className = themeSwitcher.currentTheme; } }); </script> diff --git a/web/html/xui/dns_modal.html b/web/html/xui/dns_modal.html index 4c85e7f3..0abde2f3 100644 --- a/web/html/xui/dns_modal.html +++ b/web/html/xui/dns_modal.html @@ -1,90 +1,89 @@ {{define "dnsModal"}} -<a-modal id="dns-modal" v-model="dnsModal.visible" :title="dnsModal.title" @ok="dnsModal.ok" - :closable="true" :mask-closable="false" - :ok-text="dnsModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme"> - <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }"> - <a-form-item label='{{ i18n "pages.xray.outbound.address" }}'> - <a-input v-model.trim="dnsModal.dnsServer.address"></a-input> - </a-form-item> - <a-form-item label='{{ i18n "pages.xray.dns.domains" }}'> - <a-button size="small" type="primary" @click="dnsModal.dnsServer.domains.push('')">+</a-button> - <template v-for="(domain, index) in dnsModal.dnsServer.domains"> - <a-input v-model.trim="dnsModal.dnsServer.domains[index]"> - <a-button size="small" slot="addonAfter" @click="dnsModal.dnsServer.domains.splice(index,1)">-</a-button> - </a-input> - </template> - </a-form-item> - <a-form-item label='{{ i18n "pages.xray.dns.strategy" }}' v-if="isAdvanced"> - <a-select - v-model="dnsModal.dnsServer.queryStrategy" - style="width: 100%" - :dropdown-class-name="themeSwitcher.currentTheme"> - <a-select-option :value="l" :label="l" v-for="l in ['UseIP', 'UseIPv4', 'UseIPv6']"> - [[ l ]] - </a-select-option> - </a-select> - </a-form-item> - </a-form> +<a-modal id="dns-modal" v-model="dnsModal.visible" :title="dnsModal.title" @ok="dnsModal.ok" :closable="true" :mask-closable="false" :ok-text="dnsModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme"> + <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }"> + <a-form-item label='{{ i18n "pages.xray.outbound.address" }}'> + <a-input v-model.trim="dnsModal.dnsServer.address"></a-input> + </a-form-item> + <a-form-item label='{{ i18n "pages.xray.dns.domains" }}'> + <a-button icon="plus" size="small" type="primary" @click="dnsModal.dnsServer.domains.push('')"></a-button> + <template v-for="(domain, index) in dnsModal.dnsServer.domains"> + <a-input v-model.trim="dnsModal.dnsServer.domains[index]"> + <a-button icon="minus" size="small" slot="addonAfter" @click="dnsModal.dnsServer.domains.splice(index,1)"></a-button> + </a-input> + </template> + </a-form-item> + <a-form-item label='{{ i18n "pages.xray.dns.strategy" }}' v-if="isAdvanced"> + <a-select v-model="dnsModal.dnsServer.queryStrategy" style="width: 100%" :dropdown-class-name="themeSwitcher.currentTheme"> + <a-select-option :value="l" :label="l" v-for="l in ['UseIP', 'UseIPv4', 'UseIPv6']"> [[ l ]] </a-select-option> + </a-select> + </a-form-item> + </a-form> </a-modal> <script> - const dnsModal = { - title: '', - visible: false, - okText: '{{ i18n "confirm" }}', - isEdit: false, - confirm: null, - dnsServer: { + const dnsModal = { + title: '', + visible: false, + okText: '{{ i18n "confirm" }}', + isEdit: false, + confirm: null, + dnsServer: { + address: "localhost", + domains: [], + queryStrategy: 'UseIP', + }, + ok() { + domains = dnsModal.dnsServer.domains.filter(d => d.length > 0); + dnsModal.dnsServer.domains = domains; + newDnsServer = domains.length > 0 ? dnsModal.dnsServer : dnsModal.dnsServer.address; + ObjectUtil.execute(dnsModal.confirm, newDnsServer); + }, + show({ + title = '', + okText = '{{ i18n "confirm" }}', + dnsServer, + confirm = (dnsServer) => {}, + isEdit = false + }) { + this.title = title; + this.okText = okText; + this.confirm = confirm; + this.visible = true; + if (isEdit) { + if (typeof dnsServer == 'object') { + this.dnsServer = dnsServer; + } else { + this.dnsServer = { + address: dnsServer ?? "", + domains: [], + queryStrategy: 'UseIP', + } + } + } else { + this.dnsServer = { address: "localhost", domains: [], queryStrategy: 'UseIP', - }, - ok() { - domains = dnsModal.dnsServer.domains.filter(d => d.length>0); - dnsModal.dnsServer.domains = domains; - newDnsServer = domains.length > 0 ? dnsModal.dnsServer : dnsModal.dnsServer.address; - ObjectUtil.execute(dnsModal.confirm, newDnsServer); - }, - show({ title='', okText='{{ i18n "confirm" }}', dnsServer, confirm=(dnsServer)=>{}, isEdit=false }) { - this.title = title; - this.okText = okText; - this.confirm = confirm; - this.visible = true; - if(isEdit) { - if (typeof dnsServer == 'object'){ - this.dnsServer = dnsServer; - } else { - this.dnsServer = { - address: dnsServer ?? "", - domains: [], - queryStrategy: 'UseIP', - } - } - } else { - this.dnsServer = { - address: "localhost", - domains: [], - queryStrategy: 'UseIP', - } - } - this.isEdit = isEdit; - }, - close() { - dnsModal.visible = false; - }, - }; - - new Vue({ - delimiters: ['[[', ']]'], - el: '#dns-modal', - data: { - dnsModal: dnsModal, - }, - computed: { - isAdvanced: { - get: function () { return dnsModal.dnsServer.domains.length>0 } - } } - }); - + } + this.isEdit = isEdit; + }, + close() { + dnsModal.visible = false; + }, + }; + new Vue({ + delimiters: ['[[', ']]'], + el: '#dns-modal', + data: { + dnsModal: dnsModal, + }, + computed: { + isAdvanced: { |
