Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/web/html
diff options
context:
space:
mode:
authorHo3ein <ho3ein.sanaei@gmail.com>2023-12-10 17:42:52 +0300
committerGitHub <noreply@github.com>2023-12-10 17:42:52 +0300
commite3f1d3c892a1af48f27fdc36f273a55f38d13b40 (patch)
treeb11d0c1ed3c15c8f6f891a5e6df8e021d5db8ab6 /web/html
parent36cf7c0a8fda915b51e75958ce729fd9a61a5c90 (diff)
parent9fbe80f87f950673058f0001b3704251fa8b9243 (diff)
huge changes
Diffstat (limited to 'web/html')
-rw-r--r--web/html/common/head.html16
-rw-r--r--web/html/common/js.html8
-rw-r--r--web/html/common/prompt_modal.html3
-rw-r--r--web/html/common/qrcode_modal.html33
-rw-r--r--web/html/common/text_modal.html7
-rw-r--r--web/html/login.html303
-rw-r--r--web/html/xui/client_bulk_modal.html310
-rw-r--r--web/html/xui/client_modal.html27
-rw-r--r--web/html/xui/common_sider.html10
-rw-r--r--web/html/xui/component/password.html4
-rw-r--r--web/html/xui/component/setting.html6
-rw-r--r--web/html/xui/component/themeSwitch.html26
-rw-r--r--web/html/xui/form/client.html374
-rw-r--r--web/html/xui/form/inbound.html134
-rw-r--r--web/html/xui/form/outbound.html544
-rw-r--r--web/html/xui/form/protocol/dokodemo.html56
-rw-r--r--web/html/xui/form/protocol/http.html24
-rw-r--r--web/html/xui/form/protocol/shadowsocks.html147
-rw-r--r--web/html/xui/form/protocol/socks.html77
-rw-r--r--web/html/xui/form/protocol/trojan.html160
-rw-r--r--web/html/xui/form/protocol/vless.html162
-rw-r--r--web/html/xui/form/protocol/vmess.html90
-rw-r--r--web/html/xui/form/stream/external_proxy.html32
-rw-r--r--web/html/xui/form/stream/stream_grpc.html24
-rw-r--r--web/html/xui/form/stream/stream_http.html28
-rw-r--r--web/html/xui/form/stream/stream_kcp.html125
-rw-r--r--web/html/xui/form/stream/stream_quic.html60
-rw-r--r--web/html/xui/form/stream/stream_settings.html3
-rw-r--r--web/html/xui/form/stream/stream_sockopt.html2
-rw-r--r--web/html/xui/form/stream/stream_tcp.html155
-rw-r--r--web/html/xui/form/stream/stream_ws.html10
-rw-r--r--web/html/xui/form/tls_settings.html592
-rw-r--r--web/html/xui/inbound_client_table.html246
-rw-r--r--web/html/xui/inbound_info_modal.html131
-rw-r--r--web/html/xui/inbound_modal.html32
-rw-r--r--web/html/xui/inbounds.html599
-rw-r--r--web/html/xui/index.html137
-rw-r--r--web/html/xui/settings.html993
-rw-r--r--web/html/xui/xray.html1401
-rw-r--r--web/html/xui/xray_outbound_modal.html127
-rw-r--r--web/html/xui/xray_reverse_modal.html176
-rw-r--r--web/html/xui/xray_rule_modal.html277
42 files changed, 5208 insertions, 2463 deletions
diff --git a/web/html/common/head.html b/web/html/common/head.html
index 8a89954d..4fa2ea8a 100644
--- a/web/html/common/head.html
+++ b/web/html/common/head.html
@@ -4,7 +4,7 @@
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- <link rel="stylesheet" href="{{ .base_path }}assets/ant-design-vue@1.7.2/antd.min.css">
+ <link rel="stylesheet" href="{{ .base_path }}assets/ant-design-vue@1.7.8/antd.min.css">
<link rel="stylesheet" href="{{ .base_path }}assets/element-ui@2.15.0/theme-chalk/display.css">
<link rel="stylesheet" href="{{ .base_path }}assets/css/custom.css?{{ .cur_ver }}">
<link rel=”icon” type=”image/x-icon” href="{{ .base_path }}assets/favicon.ico">
@@ -13,6 +13,20 @@
[v-cloak] {
display: none;
}
+ /* vazirmatn-regular - arabic_latin_latin-ext */
+ @font-face {
+ font-display: swap;
+ font-family: 'Vazirmatn';
+ font-style: normal;
+ font-weight: 400;
+ src: url('{{ .base_path }}assets/Vazirmatn-UI-NL-Regular.woff2') format('woff2');
+ unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC, U+0030-0039;
+ }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Vazirmatn', 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB',
+ 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji',
+ 'Segoe UI Emoji', 'Segoe UI Symbol';
+ }
</style>
<title>{{ .host }}-{{ i18n .title}}</title>
</head>
diff --git a/web/html/common/js.html b/web/html/common/js.html
index d400196b..661a0b87 100644
--- a/web/html/common/js.html
+++ b/web/html/common/js.html
@@ -1,19 +1,13 @@
{{define "js"}}
<script src="{{ .base_path }}assets/vue@2.6.12/vue.min.js"></script>
<script src="{{ .base_path }}assets/moment/moment.min.js"></script>
-<script src="{{ .base_path }}assets/ant-design-vue@1.7.2/antd.min.js"></script>
-<script src="{{ .base_path }}assets/base64/base64.min.js"></script>
+<script src="{{ .base_path }}assets/ant-design-vue@1.7.8/antd.min.js"></script>
<script src="{{ .base_path }}assets/axios/axios.min.js"></script>
<script src="{{ .base_path }}assets/qs/qs.min.js"></script>
-<script src="{{ .base_path }}assets/qrcode/qrious.min.js"></script>
-<script src="{{ .base_path }}assets/clipboard/clipboard.min.js"></script>
-<script src="{{ .base_path }}assets/uri/URI.min.js"></script>
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/js/util/common.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/js/util/date-util.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/js/util/utils.js?{{ .cur_ver }}"></script>
-<script src="{{ .base_path }}assets/js/model/xray.js?{{ .cur_ver }}"></script>
-<script src="{{ .base_path }}assets/js/model/models.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/js/langs.js"></script>
<script>
const basePath = '{{ .base_path }}';
diff --git a/web/html/common/prompt_modal.html b/web/html/common/prompt_modal.html
index 17a65ec1..edfad682 100644
--- a/web/html/common/prompt_modal.html
+++ b/web/html/common/prompt_modal.html
@@ -1,8 +1,7 @@
{{define "promptModal"}}
<a-modal id="prompt-modal" v-model="promptModal.visible" :title="promptModal.title"
:closable="true" @ok="promptModal.ok" :mask-closable="false"
- :class="themeSwitcher.darkCardClass"
- :ok-text="promptModal.okText" cancel-text='{{ i18n "cancel" }}'>
+ :ok-text="promptModal.okText" cancel-text='{{ i18n "cancel" }}' :class="themeSwitcher.currentTheme">
<a-input id="prompt-modal-input" :type="promptModal.type"
v-model="promptModal.value"
:autosize="{minRows: 10, maxRows: 20}"
diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html
index 51dc38cb..4be7997d 100644
--- a/web/html/common/qrcode_modal.html
+++ b/web/html/common/qrcode_modal.html
@@ -1,7 +1,7 @@
{{define "qrcodeModal"}}
<a-modal id="qrcode-modal" v-model="qrModal.visible" :title="qrModal.title"
:closable="true"
- :class="themeSwitcher.darkCardClass"
+ :class="themeSwitcher.currentTheme"
:footer="null"
width="300px">
<a-tag color="green" style="margin-bottom: 10px;display: block;text-align: center;">
@@ -13,7 +13,7 @@
</template>
<a-divider>{{ i18n "pages.inbounds.client" }}</a-divider>
<template v-for="(row, index) in qrModal.qrcodes">
- <a-tag color="orange" style="margin-top: 10px;display: block;text-align: center;">[[ row.remark ]]</a-tag>
+ <a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag>
<canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" style="width: 100%; height: 100%;"></canvas>
</template>
</a-modal>
@@ -22,39 +22,25 @@
const qrModal = {
title: '',
- clientIndex: 0,
- inbound: new Inbound(),
dbInbound: new DBInbound(),
client: null,
qrcodes: [],
clipboard: null,
visible: false,
subId: '',
- show: function (title = '', dbInbound = new DBInbound(), clientIndex = 0) {
+ show: function (title = '', dbInbound, client) {
this.title = title;
- this.clientIndex = clientIndex;
this.dbInbound = dbInbound;
this.inbound = dbInbound.toInbound();
- settings = JSON.parse(this.inbound.settings);
- this.client = settings.clients[clientIndex];
- remark = [this.dbInbound.remark, ( this.client ? this.client.email : '')].filter(Boolean).join('-');
- address = this.dbInbound.address;
+ this.client = client;
this.subId = '';
this.qrcodes = [];
- if (this.inbound.tls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) {
- this.inbound.stream.tls.settings.domains.forEach((domain) => {
- remarkText = [remark, domain.remark].filter(Boolean).join('-');
- this.qrcodes.push({
- remark: remarkText,
- link: this.inbound.genLink(domain.domain, remarkText, clientIndex)
- });
- });
- } else {
+ this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
this.qrcodes.push({
- remark: remark,
- link: this.inbound.genLink(address, remark, clientIndex)
+ remark: l.remark,
+ link: l.link
});
- }
+ });
this.visible = true;
},
close: function () {
@@ -86,8 +72,7 @@
});
},
genSubLink(subID) {
- const { domain: host, port, tls: isTLS, path: base } = app.subSettings;
- return buildURL({ host, port, isTLS, base, path: subID+'?name='+remark });
+ return app.subSettings.subURI+subID+'?name='+subID;
}
},
updated() {
diff --git a/web/html/common/text_modal.html b/web/html/common/text_modal.html
index 1514051b..4fe2f175 100644
--- a/web/html/common/text_modal.html
+++ b/web/html/common/text_modal.html
@@ -1,7 +1,7 @@
{{define "textModal"}}
<a-modal id="text-modal" v-model="txtModal.visible" :title="txtModal.title"
:closable="true" ok-text='{{ i18n "copy" }}' cancel-text='{{ i18n "close" }}'
- :class="themeSwitcher.darkCardClass"
+ :class="themeSwitcher.currentTheme"
:ok-button-props="{attrs:{id:'txt-modal-ok-btn'}}">
<a-button v-if="!ObjectUtil.isEmpty(txtModal.fileName)" type="primary" style="margin-bottom: 10px;"
:href="'data:application/text;charset=utf-8,' + encodeURIComponent(txtModal.content)"
@@ -31,7 +31,10 @@
this.clipboard = new ClipboardJS('#txt-modal-ok-btn', {
text: () => this.content,
});
- this.clipboard.on('success', () => app.$message.success('{{ i18n "copied" }}'));
+ this.clipboard.on('success', () => {
+ app.$message.success('{{ i18n "copied" }}')
+ this.close();
+ });
}
});
},
diff --git a/web/html/login.html b/web/html/login.html
index 61381a61..8f5a6f4d 100644
--- a/web/html/login.html
+++ b/web/html/login.html
@@ -2,65 +2,241 @@
<html lang="en">
{{template "head" .}}
<style>
-
- #app {
- padding-top: 100px;
+ h1 {
+ text-align: center;
+ margin: 20px 0 50px 0;
+ }
+ .ant-btn,
+ .ant-input {
+ height: 50px;
+ border-radius: 30px;
+ }
+ .ant-input-group-addon {
+ border-radius: 0 30px 30px 0;
+ width: 50px;
+ font-size: 18px;
+ }
+ .ant-input-affix-wrapper .ant-input-prefix {
+ left: 23px;
+ }
+ .ant-input-affix-wrapper .ant-input:not(:first-child) {
+ padding-left: 50px;
+ }
+ .centered {
+ display: flex;
+ text-align: center;
+ align-items: center;
+ justify-content: center;
+ }
+ .title {
+ font-size: 32px;
+ font-weight: bold;
+ }
+ #app {
+ overflow: hidden;
+ }
+ #login {
+ animation: charge 0.5s both;
+ background-color: #fff;
+ border-radius: 2rem;
+ padding: 3rem;
+ transition: all 0.3s;
+ }
+ #login:hover {
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
+ }
+ @keyframes charge {
+ from {
+ transform: translateY(5rem);
+ opacity: 0;
}
-
- h1 {
- text-align: center;
- color: #fff;
- margin: 20px 0 50px 0;
+ to {
+ transform: translateY(0);
+ opacity: 1;
}
-
- .ant-btn, .ant-input {
- height: 50px;
- border-radius: 30px;
+ }
+ @keyframes wave {
+ from {
+ transform: rotate(0deg);
}
-
- .ant-input-group-addon {
- border-radius: 0 30px 30px 0;
- width: 50px;
- font-size: 18px;
+ to {
+ transform: rotate(360deg);
}
-
- .ant-input-affix-wrapper .ant-input-prefix {
- left: 23px;
+ }
+ .wave {
+ opacity: 0.6;
+ position: absolute;
+ bottom: 40%;
+ left: 50%;
+ width: 6000px;
+ height: 6000px;
+ background-color: rgba(0, 135, 113, 0.08);
+ margin-left: -3000px;
+ transform-origin: 50% 48%;
+ border-radius: 46%;
+ animation: wave 72s infinite linear;
+ pointer-events: none;
+ }
+ .wave2 {
+ animation: wave 88s infinite linear;
+ opacity: 0.3;
+ }
+ .wave3 {
+ animation: wave 80s infinite linear;
+ opacity: 0.1;
+ }
+ .under {
+ background-color: #dbf5ed;
+ }
+ .dark .wave {
+ background: rgb(10 117 87 / 20%);
+ }
+ .dark .under {
+ background-color: #101828;
+ }
+ .dark #login {
+ background-color: #151f31;
+ }
+ .dark h1 {
+ color: rgba(255, 255, 255, 0.85);
+ }
+ .ant-btn-primary-login {
+ color: #008771;
+ background-color: #eef9f7;
+ border-color: #89d9cc;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
+ box-shadow: none;
+ width: 100%;
+ }
+ .ant-btn-primary-login:focus,
+ .ant-btn-primary-login:hover {
+ color: #fff;
+ background-color: #006655;
+ border-color: #006655;
+ background-image: linear-gradient(
+ 270deg,
+ rgba(123, 199, 77, 0) 30%,
+ #009980,
+ rgba(123, 199, 77, 0) 100%
+ );
+ background-repeat: no-repeat;
+ animation: ma-bg-move ease-in-out 5s infinite;
+ background-position-x: -500px;
+ width: 95%;
+ animation-delay: -0.5s;
+ box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+ }
+ .ant-btn-primary-login.active,
+ .ant-btn-primary-login:active {
+ color: #fff;
+ background-color: #006655;
+ border-color: #006655;
+ }
+ @keyframes ma-bg-move {
+ 0% {
+ background-position: -500px 0;
}
-
- .ant-input-affix-wrapper .ant-input:not(:first-child) {
- padding-left: 50px;
+ 50% {
+ background-position: 1000px 0;
}
-
- .centered {
- display: flex;
- text-align: center;
- align-items: center;
- justify-content: center;
+ 100% {
+ background-position: 1000px 0;
}
-
- .title {
- font-size: 32px;
- font-weight: bold;
+ }
+ .wave-btn-bg {
+ position: relative;
+ border-radius: 25px;
+ width: 100%;
+ }
+ .dark .wave-btn-bg {
+ color: #fff;
+ position: relative;
+ background-color: #0a7557;
+ border: 2px double transparent;
+ background-origin: border-box;
+ background-clip: padding-box, border-box;
+ background-size: 300%;
+ animation: wave-btn-tara 4s ease infinite;
+ transition: all 0.5s ease;
+ width: 100%;
+ }
+ .dark .wave-btn-bg-cl {
+ background-image: linear-gradient(rgba(13, 14, 33, 0), rgba(13, 14, 33, 0)),
+ radial-gradient(circle at left top, #006655, #009980, #006655) !important;
+ border-radius: 3em;
+ }
+ .dark .wave-btn-bg-cl:hover {
+ width: 95%;
+ }
+ .dark .wave-btn-bg-cl:before {
+ position: absolute;
+ content: "";
+ top: -5px;
+ left: -5px;
+ bottom: -5px;
+ right: -5px;
+ z-index: -1;
+ background: inherit;
+ background-size: inherit;
+ border-radius: 4em;
+ opacity: 0;
+ transition: 0.5s;
+ }
+ .dark .wave-btn-bg-cl:hover::before {
+ opacity: 1;
+ filter: blur(20px);
+ animation: wave-btn-tara 8s linear infinite;
+ }
+ @keyframes wave-btn-tara {
+ to {
+ background-position: 300%;
}
-
+ }
+ .dark .ant-btn-primary-login {
+ font-size: 14px;
+ color: #fff;
+ text-align: center;
+ background-image: linear-gradient(
+ rgba(13, 14, 33, 0.45),
+ rgba(13, 14, 33, 0.35)
+ );
+ border-radius: 2rem;
+ border: none;
+ outline: none;
+ background-color: transparent;
+ height: 46px;
+ position: relative;
+ white-space: nowrap;
+ cursor: pointer;
+ touch-action: manipulation;
+ padding: 0 15px;
+ width: 100%;
+ animation: none;
+ background-position-x: 0;
+ box-shadow: none;
+ }
</style>
<body>
-<a-layout id="app" v-cloak class="login" :class="themeSwitcher.darkCardClass">
+<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
<transition name="list" appear>
- <a-layout-content>
+ <a-layout-content class="under" style="min-height: 0;">
+ <div class='wave'></div>
+ <div class='wave wave2'></div>
+ <div class='wave wave3'></div>
+ <a-row type="flex" justify="center" align="middle" style="height: 100%; overflow: auto;">
+ <a-col :xs="22" :sm="20" :md="14" :lg="10" :xl="8" :xxl="6" id="login" style="margin: 3rem 0;">
<a-row type="flex" justify="center">
- <a-col :xs="22" :sm="20" :md="16" :lg="12" :xl="8">
+ <a-col>
<h1 class="title">{{ i18n "pages.login.title" }}</h1>
</a-col>
</a-row>
<a-row type="flex" justify="center">
- <a-col :xs="22" :sm="20" :md="16" :lg="12" :xl="8">
+ <a-col span="24">
<a-form>
<a-form-item>
<a-input v-model.trim="user.username" placeholder='{{ i18n "username" }}'
@keydown.enter.native="login" autofocus>
- <a-icon slot="prefix" type="user" :style="'font-size: 16px;' + themeSwitcher.textStyle" />
+ <a-icon slot="prefix" type="user" style="font-size: 16px;"/>
</a-input>
</a-form-item>
<a-form-item>
@@ -76,18 +252,20 @@
</a-form-item>
<a-form-item>
<a-row justify="center" class="centered">
- <a-button type="primary" :loading="loading" @click="login" :icon="loading ? 'poweroff' : undefined"
- :style="loading ? { width: '50px' } : { display: 'block', width: '100%' }">
- [[ loading ? '' : '{{ i18n "login" }}' ]]
- </a-button>
+ <div class="wave-btn-bg wave-btn-bg-cl">
+ <a-button class="ant-btn-primary-login" type="primary" :loading="loading" @click="login" :icon="loading ? 'poweroff' : undefined"
+ :style="loading ? { width: '50px' } : { display: 'inline-block' }">
+ [[ loading ? '' : '{{ i18n "login" }}' ]]
+ </a-button>
+ </div>
</a-row>
</a-form-item>
<a-form-item>
<a-row justify="center" class="centered">
- <a-col :span="12">
- <a-select ref="selectLang" v-model="lang" @change="setLang(lang)" :dropdown-class-name="themeSwitcher.darkCardClass">
- <a-select-option :value="l.value" :label="l.value" v-for="l in supportLangs">
- <span role="img" :aria-label="l.name" v-text="l.icon"></span>
+ <a-col :span="24">
+ <a-select ref="selectLang" v-model="lang" @change="setLang(lang)" style="width: 150px;" :dropdown-class-name="themeSwitcher.currentTheme">
+ <a-select-option :value="l.value" label="English" v-for="l in supportLangs">
+ <span role="img" aria-label="l.name" v-text="l.icon"></span>
&nbsp;&nbsp;<span v-text="l.name"></span>
</a-select-option>
</a-select>
@@ -96,12 +274,19 @@
</a-form-item>
<a-form-item>
<a-row justify="center" class="centered">
- <theme-switch />
+ <a-col>
+ <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon>&nbsp;
+ </a-col>
+ <a-col>
+ <theme-switch />
+ </a-col>
</a-row>
</a-form-item>
</a-form>
</a-col>
</a-row>
+ </a-col>
+ </a-row>
</a-layout-content>
</transition>
</a-layout>
@@ -109,6 +294,12 @@
{{template "component/themeSwitcher" .}}
{{template "component/password" .}}
<script>
+ class User {
+ constructor() {
+ this.username = "";
+ this.password = "";
+ }
+ }
const app = new Vue({
delimiters: ['[[', ']]'],
@@ -121,7 +312,6 @@
lang: ""
},
async created() {
- this.updateBackground();
this.lang = getLang();
this.secretEnable = await this.getSecretStatus();
},
@@ -143,21 +333,8 @@
return msg.obj;
}
},
- updateBackground() {
- const leftColor = RandomUtil.randomIntRange(0x222222, 0xFFFFFF / 2).toString(16);
- const rightColor = RandomUtil.randomIntRange(0xFFFFFF / 2, 0xDDDDDD).toString(16);
- const deg = RandomUtil.randomIntRange(0, 360);
- const background = `linear-gradient(${deg}deg, #${leftColor} 10%, #${rightColor} 100%)`;
- document.querySelector('#app').style.background = this.themeSwitcher.isDarkTheme ? colors.dark.bg : background;
- },
- },
- watch: {
- 'themeSwitcher.isDarkTheme'(newVal, oldVal) {
- this.updateBackground();
- },
},
});
-
</script>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/web/html/xui/client_bulk_modal.html b/web/html/xui/client_bulk_modal.html
index d5c60b76..e0295110 100644
--- a/web/html/xui/client_bulk_modal.html
+++ b/web/html/xui/client_bulk_modal.html
@@ -1,122 +1,207 @@
{{define "clientsBulkModal"}}
-<a-modal id="client-bulk-modal" v-model="clientsBulkModal.visible" :title="clientsBulkModal.title" @ok="clientsBulkModal.ok"
- :confirm-loading="clientsBulkModal.confirmLoading" :closable="true" :mask-closable="false"
- :class="themeSwitcher.darkCardClass"
- :ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}'>
+<a-modal id="client-bulk-modal" v-model="clientsBulkModal.visible" :title="clientsBulkModal.title"
+ @ok="clientsBulkModal.ok" :confirm-loading="clientsBulkModal.confirmLoading" :closable="true" :mask-closable="false"
+ :ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
<a-form layout="inline">
- <a-form-item label='{{ i18n "pages.client.method" }}'>
- <a-select v-model="clientsBulkModal.emailMethod" buttonStyle="solid" style="width: 350px" :dropdown-class-name="themeSwitcher.darkCardClass">
- <a-select-option :value="0">Random</a-select-option>
- <a-select-option :value="1">Random+Prefix</a-select-option>
- <a-select-option :value="2">Random+Prefix+Num</a-select-option>
- <a-select-option :value="3">Random+Prefix+Num+Postfix</a-select-option>
- <a-select-option :value="4">Prefix+Num+Postfix [ BE CAREFUL! ]</a-select-option>
- </a-select>
- </a-form-item><br />
- <a-form-item v-if="clientsBulkModal.emailMethod>1">
- <span slot="label">{{ i18n "pages.client.first" }}</span>
- <a-input-number v-model="clientsBulkModal.firstNum" :min="1"></a-input-number>
- </a-form-item>
- <a-form-item v-if="clientsBulkModal.emailMethod>1">
- <span slot="label">{{ i18n "pages.client.last" }}</span>
- <a-input-number v-model="clientsBulkModal.lastNum" :min="clientsBulkModal.firstNum"></a-input-number>
- </a-form-item>
- <a-form-item v-if="clientsBulkModal.emailMethod>0">
- <span slot="label">{{ i18n "pages.client.prefix" }}</span>
- <a-input v-model="clientsBulkModal.emailPrefix" style="width: 120px"></a-input>
- </a-form-item>
- <a-form-item v-if="clientsBulkModal.emailMethod>2">
- <span slot="label">{{ i18n "pages.client.postfix" }}</span>
- <a-input v-model="clientsBulkModal.emailPostfix" style="width: 120px"></a-input>
- </a-form-item>
- <a-form-item v-if="clientsBulkModal.emailMethod < 2">
- <span slot="label">{{ i18n "pages.client.clientCount" }}</span>
- <a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
- </a-form-item>
- <a-form-item v-if="app.subSettings.enable">
- <span slot="label">
- Subscription