@serve.zone/catalog 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
- package/dist_ts_web/00_commitinfo_data.js +9 -0
- package/dist_ts_web/elements/index.d.ts +33 -0
- package/dist_ts_web/elements/index.js +45 -0
- package/dist_ts_web/elements/sz-certificates-card.d.ts +14 -0
- package/dist_ts_web/elements/sz-certificates-card.js +210 -0
- package/dist_ts_web/elements/sz-dashboard-view.d.ts +33 -0
- package/dist_ts_web/elements/sz-dashboard-view.js +242 -0
- package/dist_ts_web/elements/sz-demo-view-dashboard.d.ts +18 -0
- package/dist_ts_web/elements/sz-demo-view-dashboard.js +184 -0
- package/dist_ts_web/elements/sz-demo-view-network.d.ts +32 -0
- package/dist_ts_web/elements/sz-demo-view-network.js +384 -0
- package/dist_ts_web/elements/sz-demo-view-registries.d.ts +22 -0
- package/dist_ts_web/elements/sz-demo-view-registries.js +240 -0
- package/dist_ts_web/elements/sz-demo-view-services.d.ts +32 -0
- package/dist_ts_web/elements/sz-demo-view-services.js +468 -0
- package/dist_ts_web/elements/sz-demo-view-settings.d.ts +19 -0
- package/dist_ts_web/elements/sz-demo-view-settings.js +151 -0
- package/dist_ts_web/elements/sz-demo-view-tokens.d.ts +20 -0
- package/dist_ts_web/elements/sz-demo-view-tokens.js +141 -0
- package/dist_ts_web/elements/sz-dns-ssl-card.d.ts +13 -0
- package/dist_ts_web/elements/sz-dns-ssl-card.js +180 -0
- package/dist_ts_web/elements/sz-domain-detail-view.d.ts +48 -0
- package/dist_ts_web/elements/sz-domain-detail-view.js +789 -0
- package/dist_ts_web/elements/sz-login-view.d.ts +18 -0
- package/dist_ts_web/elements/sz-login-view.js +384 -0
- package/dist_ts_web/elements/sz-network-dns-view.d.ts +20 -0
- package/dist_ts_web/elements/sz-network-dns-view.js +244 -0
- package/dist_ts_web/elements/sz-network-domains-view.d.ts +28 -0
- package/dist_ts_web/elements/sz-network-domains-view.js +312 -0
- package/dist_ts_web/elements/sz-network-proxy-view.d.ts +39 -0
- package/dist_ts_web/elements/sz-network-proxy-view.js +510 -0
- package/dist_ts_web/elements/sz-platform-service-detail-view.d.ts +49 -0
- package/dist_ts_web/elements/sz-platform-service-detail-view.js +733 -0
- package/dist_ts_web/elements/sz-platform-services-card.d.ts +19 -0
- package/dist_ts_web/elements/sz-platform-services-card.js +196 -0
- package/dist_ts_web/elements/sz-quick-actions-card.d.ts +19 -0
- package/dist_ts_web/elements/sz-quick-actions-card.js +194 -0
- package/dist_ts_web/elements/sz-registry-external-view.d.ts +22 -0
- package/dist_ts_web/elements/sz-registry-external-view.js +313 -0
- package/dist_ts_web/elements/sz-registry-onebox-view.d.ts +14 -0
- package/dist_ts_web/elements/sz-registry-onebox-view.js +307 -0
- package/dist_ts_web/elements/sz-resource-usage-card.d.ts +25 -0
- package/dist_ts_web/elements/sz-resource-usage-card.js +323 -0
- package/dist_ts_web/elements/sz-reverse-proxy-card.d.ts +16 -0
- package/dist_ts_web/elements/sz-reverse-proxy-card.js +216 -0
- package/dist_ts_web/elements/sz-service-create-view.d.ts +67 -0
- package/dist_ts_web/elements/sz-service-create-view.js +828 -0
- package/dist_ts_web/elements/sz-service-detail-view.d.ts +57 -0
- package/dist_ts_web/elements/sz-service-detail-view.js +728 -0
- package/dist_ts_web/elements/sz-services-backups-view.d.ts +37 -0
- package/dist_ts_web/elements/sz-services-backups-view.js +413 -0
- package/dist_ts_web/elements/sz-services-list-view.d.ts +20 -0
- package/dist_ts_web/elements/sz-services-list-view.js +272 -0
- package/dist_ts_web/elements/sz-settings-view.d.ts +30 -0
- package/dist_ts_web/elements/sz-settings-view.js +448 -0
- package/dist_ts_web/elements/sz-stat-card.d.ts +17 -0
- package/dist_ts_web/elements/sz-stat-card.js +249 -0
- package/dist_ts_web/elements/sz-status-grid-cluster.d.ts +19 -0
- package/dist_ts_web/elements/sz-status-grid-cluster.js +142 -0
- package/dist_ts_web/elements/sz-status-grid-infra.d.ts +17 -0
- package/dist_ts_web/elements/sz-status-grid-infra.js +140 -0
- package/dist_ts_web/elements/sz-status-grid-network.d.ts +30 -0
- package/dist_ts_web/elements/sz-status-grid-network.js +190 -0
- package/dist_ts_web/elements/sz-status-grid-services.d.ts +17 -0
- package/dist_ts_web/elements/sz-status-grid-services.js +145 -0
- package/dist_ts_web/elements/sz-tokens-view.d.ts +26 -0
- package/dist_ts_web/elements/sz-tokens-view.js +344 -0
- package/dist_ts_web/elements/sz-traffic-card.d.ts +24 -0
- package/dist_ts_web/elements/sz-traffic-card.js +255 -0
- package/dist_ts_web/index.d.ts +2 -0
- package/dist_ts_web/index.js +3 -0
- package/dist_ts_web/pages/index.d.ts +3 -0
- package/dist_ts_web/pages/index.js +4 -0
- package/dist_ts_web/pages/mainpage.d.ts +1 -0
- package/dist_ts_web/pages/mainpage.js +46 -0
- package/dist_ts_web/pages/sz-demo-app-shell.d.ts +13 -0
- package/dist_ts_web/pages/sz-demo-app-shell.js +212 -0
- package/dist_ts_web/pages/sz-demo-app.d.ts +2 -0
- package/dist_ts_web/pages/sz-demo-app.js +20 -0
- package/npmextra.json +24 -0
- package/package.json +45 -0
- package/ts_web/00_commitinfo_data.ts +8 -0
- package/ts_web/elements/index.ts +54 -0
- package/ts_web/elements/sz-certificates-card.ts +155 -0
- package/ts_web/elements/sz-dashboard-view.ts +217 -0
- package/ts_web/elements/sz-demo-view-dashboard.ts +150 -0
- package/ts_web/elements/sz-demo-view-network.ts +354 -0
- package/ts_web/elements/sz-demo-view-registries.ts +206 -0
- package/ts_web/elements/sz-demo-view-services.ts +434 -0
- package/ts_web/elements/sz-demo-view-settings.ts +118 -0
- package/ts_web/elements/sz-demo-view-tokens.ts +109 -0
- package/ts_web/elements/sz-dns-ssl-card.ts +130 -0
- package/ts_web/elements/sz-domain-detail-view.ts +766 -0
- package/ts_web/elements/sz-login-view.ts +329 -0
- package/ts_web/elements/sz-network-dns-view.ts +208 -0
- package/ts_web/elements/sz-network-domains-view.ts +273 -0
- package/ts_web/elements/sz-network-proxy-view.ts +456 -0
- package/ts_web/elements/sz-platform-service-detail-view.ts +714 -0
- package/ts_web/elements/sz-platform-services-card.ts +163 -0
- package/ts_web/elements/sz-quick-actions-card.ts +161 -0
- package/ts_web/elements/sz-registry-external-view.ts +279 -0
- package/ts_web/elements/sz-registry-onebox-view.ts +258 -0
- package/ts_web/elements/sz-resource-usage-card.ts +284 -0
- package/ts_web/elements/sz-reverse-proxy-card.ts +151 -0
- package/ts_web/elements/sz-service-create-view.ts +773 -0
- package/ts_web/elements/sz-service-detail-view.ts +710 -0
- package/ts_web/elements/sz-services-backups-view.ts +390 -0
- package/ts_web/elements/sz-services-list-view.ts +237 -0
- package/ts_web/elements/sz-settings-view.ts +417 -0
- package/ts_web/elements/sz-stat-card.ts +187 -0
- package/ts_web/elements/sz-status-grid-cluster.ts +105 -0
- package/ts_web/elements/sz-status-grid-infra.ts +88 -0
- package/ts_web/elements/sz-status-grid-network.ts +152 -0
- package/ts_web/elements/sz-status-grid-services.ts +99 -0
- package/ts_web/elements/sz-tokens-view.ts +308 -0
- package/ts_web/elements/sz-traffic-card.ts +222 -0
- package/ts_web/index.ts +2 -0
- package/ts_web/pages/index.ts +3 -0
- package/ts_web/pages/mainpage.ts +46 -0
- package/ts_web/pages/sz-demo-app-shell.ts +179 -0
- package/ts_web/pages/sz-demo-app.ts +20 -0
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeesElement,
|
|
3
|
+
customElement,
|
|
4
|
+
html,
|
|
5
|
+
css,
|
|
6
|
+
cssManager,
|
|
7
|
+
property,
|
|
8
|
+
state,
|
|
9
|
+
type TemplateResult,
|
|
10
|
+
} from '@design.estate/dees-element';
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
interface HTMLElementTagNameMap {
|
|
14
|
+
'sz-service-create-view': SzServiceCreateView;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IRegistry {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
url: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IPortMapping {
|
|
25
|
+
hostPort: string;
|
|
26
|
+
containerPort: string;
|
|
27
|
+
protocol: 'tcp' | 'udp';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface IEnvVar {
|
|
31
|
+
key: string;
|
|
32
|
+
value: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface IVolumeMount {
|
|
36
|
+
hostPath: string;
|
|
37
|
+
containerPath: string;
|
|
38
|
+
readOnly: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface IServiceConfig {
|
|
42
|
+
name: string;
|
|
43
|
+
image: string;
|
|
44
|
+
ports: IPortMapping[];
|
|
45
|
+
envVars: IEnvVar[];
|
|
46
|
+
volumes: IVolumeMount[];
|
|
47
|
+
cpuLimit: string;
|
|
48
|
+
memoryLimit: string;
|
|
49
|
+
restartPolicy: 'always' | 'on-failure' | 'never';
|
|
50
|
+
networkMode: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@customElement('sz-service-create-view')
|
|
54
|
+
export class SzServiceCreateView extends DeesElement {
|
|
55
|
+
public static demo = () => html`
|
|
56
|
+
<div style="padding: 24px; max-width: 800px;">
|
|
57
|
+
<sz-service-create-view
|
|
58
|
+
.registries=${[
|
|
59
|
+
{ id: '1', name: 'Onebox Registry', url: 'registry.onebox.local' },
|
|
60
|
+
{ id: '2', name: 'Docker Hub', url: 'docker.io' },
|
|
61
|
+
]}
|
|
62
|
+
></sz-service-create-view>
|
|
63
|
+
</div>
|
|
64
|
+
`;
|
|
65
|
+
|
|
66
|
+
@property({ type: Array })
|
|
67
|
+
public accessor registries: IRegistry[] = [];
|
|
68
|
+
|
|
69
|
+
@property({ type: Boolean })
|
|
70
|
+
public accessor loading: boolean = false;
|
|
71
|
+
|
|
72
|
+
@state()
|
|
73
|
+
private accessor serviceName: string = '';
|
|
74
|
+
|
|
75
|
+
@state()
|
|
76
|
+
private accessor imageUrl: string = '';
|
|
77
|
+
|
|
78
|
+
@state()
|
|
79
|
+
private accessor selectedRegistry: string = '';
|
|
80
|
+
|
|
81
|
+
@state()
|
|
82
|
+
private accessor ports: IPortMapping[] = [{ hostPort: '', containerPort: '', protocol: 'tcp' }];
|
|
83
|
+
|
|
84
|
+
@state()
|
|
85
|
+
private accessor envVars: IEnvVar[] = [{ key: '', value: '' }];
|
|
86
|
+
|
|
87
|
+
@state()
|
|
88
|
+
private accessor volumes: IVolumeMount[] = [];
|
|
89
|
+
|
|
90
|
+
@state()
|
|
91
|
+
private accessor cpuLimit: string = '';
|
|
92
|
+
|
|
93
|
+
@state()
|
|
94
|
+
private accessor memoryLimit: string = '';
|
|
95
|
+
|
|
96
|
+
@state()
|
|
97
|
+
private accessor restartPolicy: 'always' | 'on-failure' | 'never' = 'always';
|
|
98
|
+
|
|
99
|
+
@state()
|
|
100
|
+
private accessor networkMode: string = 'bridge';
|
|
101
|
+
|
|
102
|
+
@state()
|
|
103
|
+
private accessor showAdvanced: boolean = false;
|
|
104
|
+
|
|
105
|
+
public static styles = [
|
|
106
|
+
cssManager.defaultStyles,
|
|
107
|
+
css`
|
|
108
|
+
:host {
|
|
109
|
+
display: block;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.header {
|
|
113
|
+
display: flex;
|
|
114
|
+
justify-content: space-between;
|
|
115
|
+
align-items: center;
|
|
116
|
+
margin-bottom: 24px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.header-title {
|
|
120
|
+
font-size: 20px;
|
|
121
|
+
font-weight: 600;
|
|
122
|
+
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.header-subtitle {
|
|
126
|
+
font-size: 14px;
|
|
127
|
+
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
|
128
|
+
margin-top: 4px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.section {
|
|
132
|
+
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
|
|
133
|
+
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
|
134
|
+
border-radius: 8px;
|
|
135
|
+
padding: 20px;
|
|
136
|
+
margin-bottom: 16px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.section-title {
|
|
140
|
+
font-size: 15px;
|
|
141
|
+
font-weight: 600;
|
|
142
|
+
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
143
|
+
margin-bottom: 16px;
|
|
144
|
+
display: flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
gap: 8px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.section-title svg {
|
|
150
|
+
width: 18px;
|
|
151
|
+
height: 18px;
|
|
152
|
+
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.form-row {
|
|
156
|
+
display: grid;
|
|
157
|
+
grid-template-columns: 1fr 1fr;
|
|
158
|
+
gap: 16px;
|
|
159
|
+
margin-bottom: 16px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.form-row.single {
|
|
163
|
+
grid-template-columns: 1fr;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.form-group {
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
gap: 6px;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.form-label {
|
|
173
|
+
font-size: 13px;
|
|
174
|
+
font-weight: 500;
|
|
175
|
+
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.form-label .required {
|
|
179
|
+
color: ${cssManager.bdTheme('#ef4444', '#f87171')};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.form-hint {
|
|
183
|
+
font-size: 12px;
|
|
184
|
+
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.form-input,
|
|
188
|
+
.form-select {
|
|
189
|
+
width: 100%;
|
|
190
|
+
padding: 10px 12px;
|
|
191
|
+
background: ${cssManager.bdTheme('#ffffff', '#18181b')};
|
|
192
|
+
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
|
193
|
+
border-radius: 6px;
|
|
194
|
+
font-size: 14px;
|
|
195
|
+
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
196
|
+
outline: none;
|
|
197
|
+
transition: border-color 200ms ease;
|
|
198
|
+
box-sizing: border-box;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.form-input:focus,
|
|
202
|
+
.form-select:focus {
|
|
203
|
+
border-color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.form-input::placeholder {
|
|
207
|
+
color: ${cssManager.bdTheme('#a1a1aa', '#52525b')};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.form-select {
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.dynamic-list {
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-direction: column;
|
|
217
|
+
gap: 8px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.dynamic-row {
|
|
221
|
+
display: flex;
|
|
222
|
+
gap: 8px;
|
|
223
|
+
align-items: flex-start;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.dynamic-row .form-input {
|
|
227
|
+
flex: 1;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.dynamic-row .form-select {
|
|
231
|
+
width: 80px;
|
|
232
|
+
flex-shrink: 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.remove-button {
|
|
236
|
+
padding: 10px;
|
|
237
|
+
background: transparent;
|
|
238
|
+
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
|
239
|
+
border-radius: 6px;
|
|
240
|
+
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
|
241
|
+
cursor: pointer;
|
|
242
|
+
transition: all 200ms ease;
|
|
243
|
+
flex-shrink: 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.remove-button:hover {
|
|
247
|
+
background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')};
|
|
248
|
+
border-color: ${cssManager.bdTheme('#fecaca', 'rgba(239, 68, 68, 0.3)')};
|
|
249
|
+
color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.add-button {
|
|
253
|
+
display: inline-flex;
|
|
254
|
+
align-items: center;
|
|
255
|
+
gap: 6px;
|
|
256
|
+
padding: 8px 12px;
|
|
257
|
+
background: transparent;
|
|
258
|
+
border: 1px dashed ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
|
259
|
+
border-radius: 6px;
|
|
260
|
+
font-size: 13px;
|
|
261
|
+
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
|
|
262
|
+
cursor: pointer;
|
|
263
|
+
transition: all 200ms ease;
|
|
264
|
+
margin-top: 8px;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.add-button:hover {
|
|
268
|
+
background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
|
|
269
|
+
border-color: ${cssManager.bdTheme('#a1a1aa', '#52525b')};
|
|
270
|
+
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.add-button svg {
|
|
274
|
+
width: 14px;
|
|
275
|
+
height: 14px;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.toggle-advanced {
|
|
279
|
+
display: flex;
|
|
280
|
+
align-items: center;
|
|
281
|
+
gap: 8px;
|
|
282
|
+
padding: 12px 0;
|
|
283
|
+
font-size: 14px;
|
|
284
|
+
font-weight: 500;
|
|
285
|
+
color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
|
|
286
|
+
cursor: pointer;
|
|
287
|
+
background: none;
|
|
288
|
+
border: none;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.toggle-advanced svg {
|
|
292
|
+
width: 16px;
|
|
293
|
+
height: 16px;
|
|
294
|
+
transition: transform 200ms ease;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.toggle-advanced.open svg {
|
|
298
|
+
transform: rotate(180deg);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.checkbox-row {
|
|
302
|
+
display: flex;
|
|
303
|
+
align-items: center;
|
|
304
|
+
gap: 8px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.checkbox {
|
|
308
|
+
width: 18px;
|
|
309
|
+
height: 18px;
|
|
310
|
+
accent-color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.actions {
|
|
314
|
+
display: flex;
|
|
315
|
+
justify-content: flex-end;
|
|
316
|
+
gap: 12px;
|
|
317
|
+
padding-top: 16px;
|
|
318
|
+
border-top: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
|
319
|
+
margin-top: 8px;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.button {
|
|
323
|
+
padding: 10px 20px;
|
|
324
|
+
border-radius: 6px;
|
|
325
|
+
font-size: 14px;
|
|
326
|
+
font-weight: 500;
|
|
327
|
+
cursor: pointer;
|
|
328
|
+
transition: all 200ms ease;
|
|
329
|
+
display: inline-flex;
|
|
330
|
+
align-items: center;
|
|
331
|
+
gap: 8px;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.button.secondary {
|
|
335
|
+
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
|
|
336
|
+
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
|
|
337
|
+
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.button.secondary:hover {
|
|
341
|
+
background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.button.primary {
|
|
345
|
+
background: ${cssManager.bdTheme('#18181b', '#fafafa')};
|
|
346
|
+
border: none;
|
|
347
|
+
color: ${cssManager.bdTheme('#fafafa', '#18181b')};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.button.primary:hover:not(:disabled) {
|
|
351
|
+
opacity: 0.9;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.button.primary:disabled {
|
|
355
|
+
opacity: 0.6;
|
|
356
|
+
cursor: not-allowed;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.spinner {
|
|
360
|
+
width: 16px;
|
|
361
|
+
height: 16px;
|
|
362
|
+
border: 2px solid transparent;
|
|
363
|
+
border-top-color: currentColor;
|
|
364
|
+
border-radius: 50%;
|
|
365
|
+
animation: spin 0.8s linear infinite;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
@keyframes spin {
|
|
369
|
+
to {
|
|
370
|
+
transform: rotate(360deg);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
`,
|
|
374
|
+
];
|
|
375
|
+
|
|
376
|
+
public render(): TemplateResult {
|
|
377
|
+
return html`
|
|
378
|
+
<div class="header">
|
|
379
|
+
<div>
|
|
380
|
+
<div class="header-title">Deploy New Service</div>
|
|
381
|
+
<div class="header-subtitle">Configure and deploy a new Docker container</div>
|
|
382
|
+
</div>
|
|
383
|
+
</div>
|
|
384
|
+
|
|
385
|
+
<!-- Basic Info Section -->
|
|
386
|
+
<div class="section">
|
|
387
|
+
<div class="section-title">
|
|
388
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
389
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
390
|
+
<line x1="9" y1="9" x2="15" y2="9"></line>
|
|
391
|
+
<line x1="9" y1="15" x2="15" y2="15"></line>
|
|
392
|
+
</svg>
|
|
393
|
+
Basic Information
|
|
394
|
+
</div>
|
|
395
|
+
<div class="form-row">
|
|
396
|
+
<div class="form-group">
|
|
397
|
+
<label class="form-label">Service Name <span class="required">*</span></label>
|
|
398
|
+
<input
|
|
399
|
+
type="text"
|
|
400
|
+
class="form-input"
|
|
401
|
+
placeholder="my-service"
|
|
402
|
+
.value=${this.serviceName}
|
|
403
|
+
@input=${(e: Event) => this.serviceName = (e.target as HTMLInputElement).value}
|
|
404
|
+
>
|
|
405
|
+
<div class="form-hint">Unique name for the service (alphanumeric and hyphens)</div>
|
|
406
|
+
</div>
|
|
407
|
+
<div class="form-group">
|
|
408
|
+
<label class="form-label">Registry</label>
|
|
409
|
+
<select
|
|
410
|
+
class="form-select"
|
|
411
|
+
.value=${this.selectedRegistry}
|
|
412
|
+
@change=${(e: Event) => this.selectedRegistry = (e.target as HTMLSelectElement).value}
|
|
413
|
+
>
|
|
414
|
+
<option value="">Custom Image URL</option>
|
|
415
|
+
${this.registries.map(reg => html`
|
|
416
|
+
<option value=${reg.id}>${reg.name}</option>
|
|
417
|
+
`)}
|
|
418
|
+
</select>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
<div class="form-row single">
|
|
422
|
+
<div class="form-group">
|
|
423
|
+
<label class="form-label">Image <span class="required">*</span></label>
|
|
424
|
+
<input
|
|
425
|
+
type="text"
|
|
426
|
+
class="form-input"
|
|
427
|
+
placeholder="nginx:latest or registry.example.com/image:tag"
|
|
428
|
+
.value=${this.imageUrl}
|
|
429
|
+
@input=${(e: Event) => this.imageUrl = (e.target as HTMLInputElement).value}
|
|
430
|
+
>
|
|
431
|
+
<div class="form-hint">Docker image to deploy (include tag)</div>
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
|
|
436
|
+
<!-- Port Configuration -->
|
|
437
|
+
<div class="section">
|
|
438
|
+
<div class="section-title">
|
|
439
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
440
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
441
|
+
<line x1="2" y1="12" x2="22" y2="12"></line>
|
|
442
|
+
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
|
|
443
|
+
</svg>
|
|
444
|
+
Port Configuration
|
|
445
|
+
</div>
|
|
446
|
+
<div class="dynamic-list">
|
|
447
|
+
${this.ports.map((port, index) => html`
|
|
448
|
+
<div class="dynamic-row">
|
|
449
|
+
<input
|
|
450
|
+
type="text"
|
|
451
|
+
class="form-input"
|
|
452
|
+
placeholder="Host Port"
|
|
453
|
+
.value=${port.hostPort}
|
|
454
|
+
@input=${(e: Event) => this.updatePort(index, 'hostPort', (e.target as HTMLInputElement).value)}
|
|
455
|
+
>
|
|
456
|
+
<input
|
|
457
|
+
type="text"
|
|
458
|
+
class="form-input"
|
|
459
|
+
placeholder="Container Port"
|
|
460
|
+
.value=${port.containerPort}
|
|
461
|
+
@input=${(e: Event) => this.updatePort(index, 'containerPort', (e.target as HTMLInputElement).value)}
|
|
462
|
+
>
|
|
463
|
+
<select
|
|
464
|
+
class="form-select"
|
|
465
|
+
.value=${port.protocol}
|
|
466
|
+
@change=${(e: Event) => this.updatePort(index, 'protocol', (e.target as HTMLSelectElement).value)}
|
|
467
|
+
>
|
|
468
|
+
<option value="tcp">TCP</option>
|
|
469
|
+
<option value="udp">UDP</option>
|
|
470
|
+
</select>
|
|
471
|
+
${this.ports.length > 1 ? html`
|
|
472
|
+
<button class="remove-button" @click=${() => this.removePort(index)}>
|
|
473
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
474
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
475
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
476
|
+
</svg>
|
|
477
|
+
</button>
|
|
478
|
+
` : ''}
|
|
479
|
+
</div>
|
|
480
|
+
`)}
|
|
481
|
+
</div>
|
|
482
|
+
<button class="add-button" @click=${() => this.addPort()}>
|
|
483
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
484
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
485
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
486
|
+
</svg>
|
|
487
|
+
Add Port Mapping
|
|
488
|
+
</button>
|
|
489
|
+
</div>
|
|
490
|
+
|
|
491
|
+
<!-- Environment Variables -->
|
|
492
|
+
<div class="section">
|
|
493
|
+
<div class="section-title">
|
|
494
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
495
|
+
<polyline points="4 17 10 11 4 5"></polyline>
|
|
496
|
+
<line x1="12" y1="19" x2="20" y2="19"></line>
|
|
497
|
+
</svg>
|
|
498
|
+
Environment Variables
|
|
499
|
+
</div>
|
|
500
|
+
<div class="dynamic-list">
|
|
501
|
+
${this.envVars.map((env, index) => html`
|
|
502
|
+
<div class="dynamic-row">
|
|
503
|
+
<input
|
|
504
|
+
type="text"
|
|
505
|
+
class="form-input"
|
|
506
|
+
placeholder="KEY"
|
|
507
|
+
.value=${env.key}
|
|
508
|
+
@input=${(e: Event) => this.updateEnvVar(index, 'key', (e.target as HTMLInputElement).value)}
|
|
509
|
+
>
|
|
510
|
+
<input
|
|
511
|
+
type="text"
|
|
512
|
+
class="form-input"
|
|
513
|
+
placeholder="value"
|
|
514
|
+
.value=${env.value}
|
|
515
|
+
@input=${(e: Event) => this.updateEnvVar(index, 'value', (e.target as HTMLInputElement).value)}
|
|
516
|
+
>
|
|
517
|
+
${this.envVars.length > 1 ? html`
|
|
518
|
+
<button class="remove-button" @click=${() => this.removeEnvVar(index)}>
|
|
519
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
520
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
521
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
522
|
+
</svg>
|
|
523
|
+
</button>
|
|
524
|
+
` : ''}
|
|
525
|
+
</div>
|
|
526
|
+
`)}
|
|
527
|
+
</div>
|
|
528
|
+
<button class="add-button" @click=${() => this.addEnvVar()}>
|
|
529
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
530
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
531
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
532
|
+
</svg>
|
|
533
|
+
Add Environment Variable
|
|
534
|
+
</button>
|
|
535
|
+
</div>
|
|
536
|
+
|
|
537
|
+
<!-- Advanced Options Toggle -->
|
|
538
|
+
<button
|
|
539
|
+
class="toggle-advanced ${this.showAdvanced ? 'open' : ''}"
|
|
540
|
+
@click=${() => this.showAdvanced = !this.showAdvanced}
|
|
541
|
+
>
|
|
542
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
543
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
544
|
+
</svg>
|
|
545
|
+
Advanced Options
|
|
546
|
+
</button>
|
|
547
|
+
|
|
548
|
+
${this.showAdvanced ? html`
|
|
549
|
+
<!-- Volumes -->
|
|
550
|
+
<div class="section">
|
|
551
|
+
<div class="section-title">
|
|
552
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
553
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
|
|
554
|
+
</svg>
|
|
555
|
+
Volume Mounts
|
|
556
|
+
</div>
|
|
557
|
+
<div class="dynamic-list">
|
|
558
|
+
${this.volumes.length === 0 ? html`
|
|
559
|
+
<div class="form-hint">No volumes configured</div>
|
|
560
|
+
` : this.volumes.map((vol, index) => html`
|
|
561
|
+
<div class="dynamic-row">
|
|
562
|
+
<input
|
|
563
|
+
type="text"
|
|
564
|
+
class="form-input"
|
|
565
|
+
placeholder="/host/path"
|
|
566
|
+
.value=${vol.hostPath}
|
|
567
|
+
@input=${(e: Event) => this.updateVolume(index, 'hostPath', (e.target as HTMLInputElement).value)}
|
|
568
|
+
>
|
|
569
|
+
<input
|
|
570
|
+
type="text"
|
|
571
|
+
class="form-input"
|
|
572
|
+
placeholder="/container/path"
|
|
573
|
+
.value=${vol.containerPath}
|
|
574
|
+
@input=${(e: Event) => this.updateVolume(index, 'containerPath', (e.target as HTMLInputElement).value)}
|
|
575
|
+
>
|
|
576
|
+
<div class="checkbox-row">
|
|
577
|
+
<input
|
|
578
|
+
type="checkbox"
|
|
579
|
+
class="checkbox"
|
|
580
|
+
?checked=${vol.readOnly}
|
|
581
|
+
@change=${(e: Event) => this.updateVolume(index, 'readOnly', (e.target as HTMLInputElement).checked)}
|
|
582
|
+
>
|
|
583
|
+
<span class="form-hint">RO</span>
|
|
584
|
+
</div>
|
|
585
|
+
<button class="remove-button" @click=${() => this.removeVolume(index)}>
|
|
586
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
587
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
588
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
589
|
+
</svg>
|
|
590
|
+
</button>
|
|
591
|
+
</div>
|
|
592
|
+
`)}
|
|
593
|
+
</div>
|
|
594
|
+
<button class="add-button" @click=${() => this.addVolume()}>
|
|
595
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
596
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
597
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
598
|
+
</svg>
|
|
599
|
+
Add Volume Mount
|
|
600
|
+
</button>
|
|
601
|
+
</div>
|
|
602
|
+
|
|
603
|
+
<!-- Resource Limits -->
|
|
604
|
+
<div class="section">
|
|
605
|
+
<div class="section-title">
|
|
606
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
607
|
+
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect>
|
|
608
|
+
<line x1="1" y1="10" x2="23" y2="10"></line>
|
|
609
|
+
</svg>
|
|
610
|
+
Resource Limits
|
|
611
|
+
</div>
|
|
612
|
+
<div class="form-row">
|
|
613
|
+
<div class="form-group">
|
|
614
|
+
<label class="form-label">CPU Limit</label>
|
|
615
|
+
<input
|
|
616
|
+
type="text"
|
|
617
|
+
class="form-input"
|
|
618
|
+
placeholder="e.g., 1.0 or 0.5"
|
|
619
|
+
.value=${this.cpuLimit}
|
|
620
|
+
@input=${(e: Event) => this.cpuLimit = (e.target as HTMLInputElement).value}
|
|
621
|
+
>
|
|
622
|
+
<div class="form-hint">Number of CPUs (leave empty for unlimited)</div>
|
|
623
|
+
</div>
|
|
624
|
+
<div class="form-group">
|
|
625
|
+
<label class="form-label">Memory Limit</label>
|
|
626
|
+
<input
|
|
627
|
+
type="text"
|
|
628
|
+
class="form-input"
|
|
629
|
+
placeholder="e.g., 512m or 1g"
|
|
630
|
+
.value=${this.memoryLimit}
|
|
631
|
+
@input=${(e: Event) => this.memoryLimit = (e.target as HTMLInputElement).value}
|
|
632
|
+
>
|
|
633
|
+
<div class="form-hint">Memory limit (leave empty for unlimited)</div>
|
|
634
|
+
</div>
|
|
635
|
+
</div>
|
|
636
|
+
</div>
|
|
637
|
+
|
|
638
|
+
<!-- Restart Policy & Network -->
|
|
639
|
+
<div class="section">
|
|
640
|
+
<div class="section-title">
|
|
641
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
642
|
+
<circle cx="12" cy="12" r="3"></circle>
|
|
643
|
+
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
|
|
644
|
+
</svg>
|
|
645
|
+
Container Settings
|
|
646
|
+
</div>
|
|
647
|
+
<div class="form-row">
|
|
648
|
+
<div class="form-group">
|
|
649
|
+
<label class="form-label">Restart Policy</label>
|
|
650
|
+
<select
|
|
651
|
+
class="form-select"
|
|
652
|
+
.value=${this.restartPolicy}
|
|
653
|
+
@change=${(e: Event) => this.restartPolicy = (e.target as HTMLSelectElement).value as any}
|
|
654
|
+
>
|
|
655
|
+
<option value="always">Always</option>
|
|
656
|
+
<option value="on-failure">On Failure</option>
|
|
657
|
+
<option value="never">Never</option>
|
|
658
|
+
</select>
|
|
659
|
+
</div>
|
|
660
|
+
<div class="form-group">
|
|
661
|
+
<label class="form-label">Network Mode</label>
|
|
662
|
+
<select
|
|
663
|
+
class="form-select"
|
|
664
|
+
.value=${this.networkMode}
|
|
665
|
+
@change=${(e: Event) => this.networkMode = (e.target as HTMLSelectElement).value}
|
|
666
|
+
>
|
|
667
|
+
<option value="bridge">Bridge</option>
|
|
668
|
+
<option value="host">Host</option>
|
|
669
|
+
<option value="none">None</option>
|
|
670
|
+
</select>
|
|
671
|
+
</div>
|
|
672
|
+
</div>
|
|
673
|
+
</div>
|
|
674
|
+
` : ''}
|
|
675
|
+
|
|
676
|
+
<div class="actions">
|
|
677
|
+
<button class="button secondary" @click=${() => this.handleCancel()}>Cancel</button>
|
|
678
|
+
<button
|
|
679
|
+
class="button primary"
|
|
680
|
+
?disabled=${this.loading || !this.isValid()}
|
|
681
|
+
@click=${() => this.handleCreate()}
|
|
682
|
+
>
|
|
683
|
+
${this.loading ? html`<div class="spinner"></div>` : ''}
|
|
684
|
+
${this.loading ? 'Deploying...' : 'Deploy Service'}
|
|
685
|
+
</button>
|
|
686
|
+
</div>
|
|
687
|
+
`;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
private isValid(): boolean {
|
|
691
|
+
return this.serviceName.trim() !== '' && this.imageUrl.trim() !== '';
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
private addPort() {
|
|
695
|
+
this.ports = [...this.ports, { hostPort: '', containerPort: '', protocol: 'tcp' }];
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
private removePort(index: number) {
|
|
699
|
+
this.ports = this.ports.filter((_, i) => i !== index);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
private updatePort(index: number, field: keyof IPortMapping, value: string) {
|
|
703
|
+
const newPorts = [...this.ports];
|
|
704
|
+
(newPorts[index] as any)[field] = value;
|
|
705
|
+
this.ports = newPorts;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
private addEnvVar() {
|
|
709
|
+
this.envVars = [...this.envVars, { key: '', value: '' }];
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
private removeEnvVar(index: number) {
|
|
713
|
+
this.envVars = this.envVars.filter((_, i) => i !== index);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
private updateEnvVar(index: number, field: keyof IEnvVar, value: string) {
|
|
717
|
+
const newEnvVars = [...this.envVars];
|
|
718
|
+
newEnvVars[index][field] = value;
|
|
719
|
+
this.envVars = newEnvVars;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
private addVolume() {
|
|
723
|
+
this.volumes = [...this.volumes, { hostPath: '', containerPath: '', readOnly: false }];
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
private removeVolume(index: number) {
|
|
727
|
+
this.volumes = this.volumes.filter((_, i) => i !== index);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
private updateVolume(index: number, field: keyof IVolumeMount, value: string | boolean) {
|
|
731
|
+
const newVolumes = [...this.volumes];
|
|
732
|
+
(newVolumes[index] as any)[field] = value;
|
|
733
|
+
this.volumes = newVolumes;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
private handleCancel() {
|
|
737
|
+
this.dispatchEvent(new CustomEvent('cancel', { bubbles: true, composed: true }));
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
private handleCreate() {
|
|
741
|
+
const config: IServiceConfig = {
|
|
742
|
+
name: this.serviceName.trim(),
|
|
743
|
+
image: this.imageUrl.trim(),
|
|
744
|
+
ports: this.ports.filter(p => p.hostPort && p.containerPort),
|
|
745
|
+
envVars: this.envVars.filter(e => e.key),
|
|
746
|
+
volumes: this.volumes.filter(v => v.hostPath && v.containerPath),
|
|
747
|
+
cpuLimit: this.cpuLimit,
|
|
748
|
+
memoryLimit: this.memoryLimit,
|
|
749
|
+
restartPolicy: this.restartPolicy,
|
|
750
|
+
networkMode: this.networkMode,
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
this.dispatchEvent(new CustomEvent('create-service', {
|
|
754
|
+
detail: config,
|
|
755
|
+
bubbles: true,
|
|
756
|
+
composed: true,
|
|
757
|
+
}));
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
public reset() {
|
|
761
|
+
this.serviceName = '';
|
|
762
|
+
this.imageUrl = '';
|
|
763
|
+
this.selectedRegistry = '';
|
|
764
|
+
this.ports = [{ hostPort: '', containerPort: '', protocol: 'tcp' }];
|
|
765
|
+
this.envVars = [{ key: '', value: '' }];
|
|
766
|
+
this.volumes = [];
|
|
767
|
+
this.cpuLimit = '';
|
|
768
|
+
this.memoryLimit = '';
|
|
769
|
+
this.restartPolicy = 'always';
|
|
770
|
+
this.networkMode = 'bridge';
|
|
771
|
+
this.showAdvanced = false;
|
|
772
|
+
}
|
|
773
|
+
}
|