@@ -3,13 +3,13 @@ import type { Ref } from 'vue'
3
3
import type { Cert } from ' @/api/cert'
4
4
import { message } from ' ant-design-vue'
5
5
import cert from ' @/api/cert'
6
- import AutoCertForm from ' @/components/AutoCertForm'
7
- import CertInfo from ' @/components/CertInfo'
8
- import CodeEditor from ' @/components/CodeEditor'
9
- import FooterToolBar from ' @/components/FooterToolbar'
10
- import NodeSelector from ' @/components/NodeSelector'
11
6
import { AutoCertState } from ' @/constants'
12
- import RenewCert from ' ./components/RenewCert.vue'
7
+
8
+ import AutoCertManagement from ' ./components/AutoCertManagement.vue'
9
+ import CertificateActions from ' ./components/CertificateActions.vue'
10
+ import CertificateBasicInfo from ' ./components/CertificateBasicInfo.vue'
11
+ import CertificateContentEditor from ' ./components/CertificateContentEditor.vue'
12
+ import CertificateDownload from ' ./components/CertificateDownload.vue'
13
13
import { useCertStore } from ' ./store'
14
14
15
15
const route = useRoute ()
@@ -27,6 +27,10 @@ const notShowInAutoCert = computed(() => {
27
27
return data .value .auto_cert !== AutoCertState .Enable
28
28
})
29
29
30
+ const isManaged = computed (() => {
31
+ return data .value .auto_cert === AutoCertState .Enable
32
+ })
33
+
30
34
function init() {
31
35
if (id .value > 0 ) {
32
36
cert .getItem (id .value ).then (r => {
@@ -55,6 +59,10 @@ async function save() {
55
59
}
56
60
}
57
61
62
+ function handleBack() {
63
+ router .push (' /certificates/list' )
64
+ }
65
+
58
66
const log = computed (() => {
59
67
if (! data .value .log )
60
68
return ' '
@@ -72,177 +80,50 @@ const log = computed(() => {
72
80
}
73
81
}).join (' \n ' )
74
82
})
75
-
76
- const isManaged = computed (() => {
77
- return data .value .auto_cert === AutoCertState .Enable
78
- })
79
83
</script >
80
84
81
85
<template >
82
86
<ACard :title =" id > 0 ? $gettext('Modify Certificate') : $gettext('Import Certificate')" >
83
- <div
84
- v-if =" isManaged"
85
- class =" mb-4"
86
- >
87
- <div class =" mb-2" >
88
- <AAlert
89
- :message =" $gettext('This certificate is managed by Nginx UI')"
90
- type =" success"
91
- show-icon
92
- />
93
- </div >
94
- <div
95
- v-if =" !data.filename"
96
- class =" mt-4 mb-4"
97
- >
98
- <AAlert
99
- :message =" $gettext('This Auto Cert item is invalid, please remove it.')"
100
- type =" error"
101
- show-icon
102
- />
103
- </div >
104
- <div
105
- v-else-if =" !data.domains"
106
- class =" mt-4 mb-4"
107
- >
108
- <AAlert
109
- :message =" $gettext('Domains list is empty, try to reopen Auto Cert for %{config}', { config: data.filename })"
110
- type =" error"
111
- show-icon
112
- />
113
- </div >
114
- </div >
115
-
116
- <ARow >
87
+ <ARow :gutter =" [16, 16]" >
117
88
<ACol
118
89
:sm =" 24"
119
- :md =" 12"
90
+ :lg =" 12"
120
91
>
121
- <AForm
122
- v-if =" data.certificate_info"
123
- layout =" vertical"
124
- >
125
- <AFormItem :label =" $gettext('Certificate Status')" >
126
- <CertInfo
127
- :cert =" data.certificate_info"
128
- class =" max-w-96"
129
- />
130
- </AFormItem >
131
- </AForm >
92
+ <!-- Auto Certificate Management -->
93
+ <AutoCertManagement
94
+ v-model:data =" data"
95
+ :is-managed =" isManaged"
96
+ @renewed =" init"
97
+ />
132
98
133
- <template v-if =" isManaged " >
134
- <RenewCert
135
- :options =" {
136
- name: data.name,
137
- domains: data.domains,
138
- key_type: data.key_type,
139
- challenge_method: data.challenge_method,
140
- dns_credential_id: data.dns_credential_id,
141
- acme_user_id: data.acme_user_id,
142
- revoke_old: data.revoke_old,
143
- }"
144
- @renewed =" init"
99
+ <AForm layout =" vertical" >
100
+ <!-- Certificate Basic Information -->
101
+ <CertificateBasicInfo
102
+ v-model:data =" data"
103
+ :errors =" errors"
104
+ :is-managed =" isManaged"
145
105
/>
146
106
147
- <AutoCertForm
148
- v-model:options =" data"
149
- key-type-read-only
150
- style =" max-width : 600px "
151
- hide-note
152
- />
153
- </template >
107
+ <!-- Download Certificate Files -->
108
+ <CertificateDownload :data =" data" />
154
109
155
- <AForm
156
- layout =" vertical"
157
- style =" max-width : 600px "
158
- >
159
- <AFormItem
160
- :label =" $gettext('Name')"
161
- :validate-status =" errors.name ? 'error' : ''"
162
- :help =" errors.name === 'required'
163
- ? $gettext('This field is required')
164
- : ''"
165
- >
166
- <p v-if =" isManaged" >
167
- {{ data.name }}
168
- </p >
169
- <AInput
170
- v-else
171
- v-model:value =" data.name"
172
- />
173
- </AFormItem >
174
- <AFormItem
175
- :label =" $gettext('SSL Certificate Path')"
176
- :validate-status =" errors.ssl_certificate_path ? 'error' : ''"
177
- :help =" errors.ssl_certificate_path === 'required' ? $gettext('This field is required')
178
- : errors.ssl_certificate_path === 'certificate_path'
179
- ? $gettext('The path exists, but the file is not a certificate') : ''"
180
- >
181
- <p v-if =" isManaged" >
182
- {{ data.ssl_certificate_path }}
183
- </p >
184
- <AInput
185
- v-else
186
- v-model:value =" data.ssl_certificate_path"
187
- />
188
- </AFormItem >
189
- <AFormItem
190
- :label =" $gettext('SSL Certificate Key Path')"
191
- :validate-status =" errors.ssl_certificate_key_path ? 'error' : ''"
192
- :help =" errors.ssl_certificate_key_path === 'required' ? $gettext('This field is required')
193
- : errors.ssl_certificate_key_path === 'privatekey_path'
194
- ? $gettext('The path exists, but the file is not a private key') : ''"
195
- >
196
- <p v-if =" isManaged" >
197
- {{ data.ssl_certificate_key_path }}
198
- </p >
199
- <AInput
200
- v-else
201
- v-model:value =" data.ssl_certificate_key_path"
202
- />
203
- </AFormItem >
204
- <AFormItem :label =" $gettext('Sync to')" >
205
- <NodeSelector
206
- v-model:target =" data.sync_node_ids"
207
- hidden-local
208
- />
209
- </AFormItem >
210
- <AFormItem
211
- :label =" $gettext('SSL Certificate Content')"
212
- :validate-status =" errors.ssl_certificate ? 'error' : ''"
213
- :help =" errors.ssl_certificate === 'certificate'
214
- ? $gettext('The input is not a SSL Certificate') : ''"
215
- >
216
- <CodeEditor
217
- v-model:content =" data.ssl_certificate"
218
- default-height =" 300px"
219
- :readonly =" !notShowInAutoCert"
220
- disable-code-completion
221
- :placeholder =" $gettext('Leave blank will not change anything')"
222
- />
223
- </AFormItem >
224
- <AFormItem
225
- :label =" $gettext('SSL Certificate Key Content')"
226
- :validate-status =" errors.ssl_certificate_key ? 'error' : ''"
227
- :help =" errors.ssl_certificate_key === 'privatekey'
228
- ? $gettext('The input is not a SSL Certificate Key') : ''"
229
- >
230
- <CodeEditor
231
- v-model:content =" data.ssl_certificate_key"
232
- default-height =" 300px"
233
- :readonly =" !notShowInAutoCert"
234
- disable-code-completion
235
- :placeholder =" $gettext('Leave blank will not change anything')"
236
- />
237
- </AFormItem >
110
+ <!-- Certificate Content Editor -->
111
+ <CertificateContentEditor
112
+ v-model:data =" data"
113
+ :errors =" errors"
114
+ :readonly =" !notShowInAutoCert"
115
+ class =" max-w-600px"
116
+ />
238
117
</AForm >
239
118
</ACol >
119
+
120
+ <!-- Log Column for Auto Cert -->
240
121
<ACol
241
122
v-if =" data.auto_cert === AutoCertState.Enable"
242
123
:sm =" 24"
243
- :md =" 12"
124
+ :lg =" 12"
244
125
>
245
- <ACard :title =" $gettext('Log')" >
126
+ <ACard size = " small " :title =" $gettext('Log')" >
246
127
<pre
247
128
v-dompurify-html =" log"
248
129
class =" log-container"
@@ -251,20 +132,11 @@ const isManaged = computed(() => {
251
132
</ACol >
252
133
</ARow >
253
134
254
- <FooterToolBar >
255
- <ASpace >
256
- <AButton @click =" $router.push('/certificates/list')" >
257
- {{ $gettext('Back') }}
258
- </AButton >
259
-
260
- <AButton
261
- type =" primary"
262
- @click =" save"
263
- >
264
- {{ $gettext('Save') }}
265
- </AButton >
266
- </ASpace >
267
- </FooterToolBar >
135
+ <!-- Certificate Actions -->
136
+ <CertificateActions
137
+ @save =" save"
138
+ @back =" handleBack"
139
+ />
268
140
</ACard >
269
141
</template >
270
142
@@ -277,4 +149,40 @@ const isManaged = computed(() => {
277
149
font-size : 12px ;
278
150
line-height : 2 ;
279
151
}
152
+
153
+ .code-editor-container {
154
+ position : relative ;
155
+
156
+ .drag-overlay {
157
+ position : absolute ;
158
+ top : 0 ;
159
+ left : 0 ;
160
+ right : 0 ;
161
+ bottom : 0 ;
162
+ background-color : rgba (24 , 144 , 255 , 0.1 );
163
+ border : 2px dashed #1890ff ;
164
+ border-radius : 6px ;
165
+ display : flex ;
166
+ align-items : center ;
167
+ justify-content : center ;
168
+ z-index : 10 ;
169
+
170
+ .drag-content {
171
+ text-align : center ;
172
+ color : #1890ff ;
173
+
174
+ .drag-icon {
175
+ font-size : 48px ;
176
+ margin-bottom : 16px ;
177
+ display : block ;
178
+ }
179
+
180
+ p {
181
+ font-size : 16px ;
182
+ margin : 0 ;
183
+ font-weight : 500 ;
184
+ }
185
+ }
186
+ }
187
+ }
280
188
</style >
0 commit comments