Skip to content

Commit 9be594f

Browse files
committed
[frontend-next] Refactored install and 404 pages
1 parent 070c53b commit 9be594f

File tree

8 files changed

+199
-183
lines changed

8 files changed

+199
-183
lines changed

frontend/src/api/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import http from '@/lib/http'
2+
3+
const install = {
4+
get_lock() {
5+
return http.get('/install')
6+
},
7+
install_nginx_ui(data: any) {
8+
return http.post('/install', data)
9+
}
10+
}
11+
12+
export default install

frontend/src/components/StdDataDisplay/StdPagination.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ function changePage(num: number) {
1717
:pageSize="pagination.per_page"
1818
:size="size"
1919
:total="pagination.total"
20-
:show-total="(total, range) => `当前显示${range[0]}-${range[1]}条数据,共${total}条数据`"
2120
class="pagination"
2221
@change="changePage"
2322
/>

frontend/src/lib/http/index.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ import axios, {AxiosRequestConfig} from 'axios'
22
import {useUserStore} from '@/pinia'
33
import {storeToRefs} from 'pinia'
44

5+
import router from '@/routes'
6+
57
const user = useUserStore()
68

79
const {token} = storeToRefs(user)
810

9-
declare module 'axios' {
10-
export interface AxiosResponse<T = any> extends Promise<T> {
11-
}
12-
}
13-
1411
let instance = axios.create({
1512
baseURL: import.meta.env.VITE_API_ROOT,
1613
timeout: 50000,
@@ -38,7 +35,6 @@ instance.interceptors.request.use(
3835
}
3936
)
4037

41-
4238
instance.interceptors.response.use(
4339
response => {
4440
return Promise.resolve(response.data)
@@ -47,6 +43,8 @@ instance.interceptors.response.use(
4743
switch (error.response.status) {
4844
case 401:
4945
case 403:
46+
user.logout()
47+
await router.push('/login')
5048
break
5149
}
5250
return Promise.reject(error.response.data)

frontend/src/routes/index.ts

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const routes = [
100100
{
101101
path: '/install',
102102
name: () => $gettext('Install'),
103-
// component: () => import('@/views/other/Install.vue'),
103+
component: () => import('@/views/other/Install.vue'),
104104
meta: {noAuth: true}
105105
},
106106
{
@@ -110,16 +110,10 @@ export const routes = [
110110
meta: {noAuth: true}
111111
},
112112
{
113-
path: '/404',
114-
name: () => $gettext('404 Not Found'),
115-
component: () => import('@/views/other/Error.vue'),
116-
meta: {noAuth: true, status_code: 404, error: 'Not Found'}
117-
},
118-
{
119-
path: '/*',
113+
path: '/:pathMatch(.*)*',
120114
name: () => $gettext('Not Found'),
121-
redirect: '/404',
122-
meta: {noAuth: true}
115+
component: () => import('@/views/other/Error.vue'),
116+
meta: {noAuth: true, status_code: 404, error: () => $gettext('Not Found')}
123117
}
124118
]
125119

@@ -130,25 +124,8 @@ const router = createRouter({
130124
})
131125

132126
router.beforeEach((to, from, next) => {
133-
134127
// @ts-ignore
135-
document.title = to.name() + ' | Nginx UI'
136-
137-
if (import.meta.env.MODE === 'production') {
138-
// axios.get('/version.json?' + Date.now()).then(r => {
139-
// if (!(process.env.VUE_APP_VERSION === r.data.version
140-
// && Number(process.env.VUE_APP_BUILD_ID) === r.data.build_id)) {
141-
// Vue.prototype.$info({
142-
// title: $gettext('System message'),
143-
// content: $gettext('Detected version update, this page will refresh.'),
144-
// onOk() {
145-
// location.reload()
146-
// },
147-
// okText: $gettext('OK')
148-
// })
149-
// }
150-
// })
151-
}
128+
document.title = to.name?.() + ' | Nginx UI'
152129

153130
const user = useUserStore()
154131
const {is_login} = user

frontend/src/views/other/Error.vue

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
<script setup lang="ts">
2+
import {useGettext} from 'vue3-gettext'
3+
4+
const {$gettext} = useGettext()
5+
</script>
6+
17
<template>
28
<div class="wrapper">
3-
<h1 class="title">{{ $route.meta.status_code ? $route.meta.status_code : 404 }}</h1>
4-
<p>{{ $route.meta.error ? $route.meta.error : $gettext('File Not Found') }}</p>
9+
<h1 class="title">{{ $route.meta.status_code || 404 }}</h1>
10+
<p>{{ $route.meta.error?.() ?? $gettext('File Not Found') }}</p>
11+
<a-button type="primary" v-translate @click="$router.push('/')">Back Home</a-button>
512
</div>
613
</template>
714

8-
<script>
9-
export default {
10-
name: 'Error'
11-
}
12-
</script>
13-
1415
<style lang="less" scoped>
1516
body, div, h1, html {
1617
padding: 0;
@@ -27,7 +28,8 @@ body, html {
2728
2829
h1 {
2930
font-size: 8em;
30-
font-weight: 100
31+
font-weight: 100;
32+
margin: 10px 0;
3133
}
3234
3335
a {

frontend/src/views/other/Install.vue

Lines changed: 102 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,130 @@
1+
<script setup lang="ts">
2+
import {Form, message} from 'ant-design-vue'
3+
import SetLanguage from '@/components/SetLanguage/SetLanguage.vue'
4+
import {reactive, ref} from 'vue'
5+
import gettext from '@/gettext'
6+
import install from '@/api'
7+
import {useRoute, useRouter} from 'vue-router'
8+
import {MailOutlined, UserOutlined, LockOutlined, DatabaseOutlined} from '@ant-design/icons-vue'
9+
10+
const {$gettext, interpolate} = gettext
11+
12+
const thisYear = new Date().getFullYear()
13+
const loading = ref(false)
14+
15+
const route = useRoute()
16+
const router = useRouter()
17+
18+
install.get_lock().then(async (r: { lock: boolean }) => {
19+
if (r.lock) {
20+
await router.push('/login')
21+
}
22+
})
23+
24+
const modelRef = reactive({
25+
email: '',
26+
username: '',
27+
password: '',
28+
database: ''
29+
})
30+
31+
const rulesRef = reactive({
32+
email: [
33+
{
34+
required: true,
35+
type: 'email',
36+
message: () => $gettext('Please input your E-mail!'),
37+
}
38+
],
39+
username: [
40+
{
41+
required: true,
42+
message: () => $gettext('Please input your username!'),
43+
}
44+
],
45+
password: [
46+
{
47+
required: true,
48+
message: () => $gettext('Please input your password!'),
49+
}
50+
],
51+
database: [
52+
{
53+
message: () => interpolate(
54+
$gettext('The filename cannot contain the following characters: %{c}'),
55+
{c: '& &quot; ? < > # {} % ~ / \\'}
56+
),
57+
}
58+
],
59+
})
60+
61+
const {validate, validateInfos} = Form.useForm(modelRef, rulesRef)
62+
63+
const onSubmit = () => {
64+
validate().then(() => {
65+
// modelRef
66+
loading.value = true
67+
install.install_nginx_ui(modelRef).then(async () => {
68+
message.success($gettext('Install successfully'))
69+
await router.push('/login')
70+
}).catch(e => {
71+
message.error(e.message ?? $gettext('Server error'))
72+
}).finally(() => {
73+
loading.value = false
74+
})
75+
})
76+
}
77+
</script>
78+
179
<template>
280
<div class="login-form">
381
<div class="project-title">
482
<h1>Nginx UI</h1>
583
</div>
6-
<a-form
7-
id="components-form-install"
8-
:form="form"
9-
class="login-form"
10-
@submit="handleSubmit"
11-
>
12-
<a-form-item>
84+
<a-form id="components-form-install" class="login-form">
85+
<a-form-item v-bind="validateInfos.email">
1386
<a-input
14-
v-decorator="[
15-
'email',
16-
{ rules: [{
17-
type: 'email',
18-
message: $gettext('Invalid E-mail!'),
19-
},
20-
{
21-
required: true,
22-
message: $gettext('Please input your E-mail!'),
23-
},] },
24-
]"
87+
v-model:value="modelRef.email"
2588
:placeholder="$gettext('Email (*)')"
2689
>
27-
<a-icon slot="prefix" type="mail" style="color: rgba(0,0,0,.25)"/>
90+
<template #prefix>
91+
<MailOutlined/>
92+
</template>
2893
</a-input>
2994
</a-form-item>
30-
<a-form-item>
95+
<a-form-item v-bind="validateInfos.username">
3196
<a-input
32-
v-decorator="[
33-
'username',
34-
{ rules: [{ required: true, message: $gettext('Please input your username!') }] },
35-
]"
97+
v-model:value="modelRef.username"
3698
:placeholder="$gettext('Username (*)')"
3799
>
38-
<a-icon slot="prefix" type="user" style="color: rgba(0,0,0,.25)"/>
100+
<template #prefix>
101+
<UserOutlined/>
102+
</template>
39103
</a-input>
40104
</a-form-item>
41-
<a-form-item>
42-
<a-input
43-
v-decorator="[
44-
'password',
45-
{ rules: [{ required: true, message: $gettext('Please input your password!') }] },
46-
]"
47-
type="password"
105+
<a-form-item v-bind="validateInfos.password">
106+
<a-input-password
107+
v-model:value="modelRef.password"
48108
:placeholder="$gettext('Password (*)')"
49109
>
50-
<a-icon slot="prefix" type="lock" style="color: rgba(0,0,0,.25)"/>
51-
</a-input>
110+
<template #prefix>
111+
<LockOutlined/>
112+
</template>
113+
</a-input-password>
52114
</a-form-item>
53115
<a-form-item>
54116
<a-input
55-
v-decorator="[
56-
'database',
57-
{ rules: [{ pattern: /^[^\\/:*?\x22<>|]{1,120}$/,
58-
message: $gettextInterpolate(
59-
$gettext('The filename cannot contain the following characters: %{c}'),
60-
{c: '& &quot; ? < > # {} % ~ / \\'}
61-
)}] },
62-
]"
117+
v-bind="validateInfos.database"
118+
v-model:value="modelRef.database"
63119
:placeholder="$gettext('Database (Optional, default: database)')"
64120
>
65-
<a-icon slot="prefix" type="database" style="color: rgba(0,0,0,.25)"/>
121+
<template #prefix>
122+
<DatabaseOutlined/>
123+
</template>
66124
</a-input>
67125
</a-form-item>
68126
<a-form-item>
69-
<a-button type="primary" :block="true" html-type="submit" :loading="loading">
127+
<a-button type="primary" :block="true" @click="onSubmit" html-type="submit" :loading="loading">
70128
<translate>Install</translate>
71129
</a-button>
72130
</a-form-item>
@@ -79,46 +137,6 @@
79137

80138
</template>
81139

82-
<script>
83-
import SetLanguage from '@/components/SetLanguage/SetLanguage'
84-
85-
export default {
86-
name: 'Login',
87-
components: {SetLanguage},
88-
data() {
89-
return {
90-
form: {},
91-
lock: true,
92-
thisYear: new Date().getFullYear(),
93-
loading: false
94-
}
95-
},
96-
created() {
97-
this.form = this.$form.createForm(this)
98-
},
99-
mounted() {
100-
this.$api.install.get_lock().then(r => {
101-
if (r.lock) {
102-
this.$router.push('/login')
103-
}
104-
})
105-
},
106-
methods: {
107-
handleSubmit: async function (e) {
108-
e.preventDefault()
109-
this.loading = true
110-
await this.form.validateFields(async (err, values) => {
111-
if (!err) {
112-
this.$api.install.install_nginx_ui(values).then(() => {
113-
this.$router.push('/login')
114-
})
115-
}
116-
this.loading = false
117-
})
118-
},
119-
},
120-
}
121-
</script>
122140
<style lang="less">
123141
.project-title {
124142
margin: 50px;

0 commit comments

Comments
 (0)