Skip to content

Commit d25b5f4

Browse files
authored
feat: Add quick operation features to node overview page (#11476)
1 parent 9a17bc7 commit d25b5f4

File tree

8 files changed

+108
-45
lines changed

8 files changed

+108
-45
lines changed

frontend/src/api/modules/backup.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import { GlobalStore } from '@/store';
88
const globalStore = GlobalStore();
99

1010
// backup-agent
11-
export const getLocalBackupDir = () => {
12-
return http.get<string>(`/backups/local`);
11+
export const getLocalBackupDir = (node?: string) => {
12+
const params = node ? `?operateNode=${node}` : '';
13+
return http.get<string>(`/backups/local${params}`);
1314
};
1415
export const searchBackup = (params: Backup.SearchWithType) => {
1516
return http.post<ResPage<Backup.BackupInfo>>(`/backups/search`, params);
@@ -40,35 +41,42 @@ export const listBucket = (params: Backup.ForBucket) => {
4041
}
4142
return http.post('/backups/buckets', request, TimeoutEnum.T_40S);
4243
};
43-
export const handleBackup = (params: Backup.Backup) => {
44-
return http.post(`/backups/backup`, params, TimeoutEnum.T_10M);
44+
export const handleBackup = (params: Backup.Backup, node?: string) => {
45+
const query = node ? `?operateNode=${node}` : '';
46+
return http.post(`/backups/backup${query}`, params, TimeoutEnum.T_10M);
4547
};
4648
export const listBackupOptions = () => {
4749
return http.get<Array<Backup.BackupOption>>(`/backups/options`);
4850
};
49-
export const handleRecover = (params: Backup.Recover) => {
50-
return http.post(`/backups/recover`, params, TimeoutEnum.T_10M);
51+
export const handleRecover = (params: Backup.Recover, node?: string) => {
52+
const query = node ? `?operateNode=${node}` : '';
53+
return http.post(`/backups/recover${query}`, params, TimeoutEnum.T_10M);
5154
};
5255
export const handleRecoverByUpload = (params: Backup.Recover) => {
5356
return http.post(`/backups/recover/byupload`, params, TimeoutEnum.T_10M);
5457
};
55-
export const downloadBackupRecord = (params: Backup.RecordDownload) => {
56-
return http.post<string>(`/backups/record/download`, params, TimeoutEnum.T_10M);
58+
export const downloadBackupRecord = (params: Backup.RecordDownload, node?: string) => {
59+
const query = node ? `?operateNode=${node}` : '';
60+
return http.post<string>(`/backups/record/download${query}`, params, TimeoutEnum.T_10M);
5761
};
58-
export const deleteBackupRecord = (params: { ids: number[] }) => {
59-
return http.post(`/backups/record/del`, params);
62+
export const deleteBackupRecord = (params: { ids: number[] }, node?: string) => {
63+
const query = node ? `?operateNode=${node}` : '';
64+
return http.post(`/backups/record/del${query}`, params);
6065
};
61-
export const updateRecordDescription = (id: Number, description: String) => {
62-
return http.post(`/backups/record/description/update`, { id: id, description: description });
66+
export const updateRecordDescription = (id: Number, description: String, node?: string) => {
67+
const query = node ? `?operateNode=${node}` : '';
68+
return http.post(`/backups/record/description/update${query}`, { id: id, description: description });
6369
};
6470
export const uploadByRecover = (filePath: string, targetDir: String) => {
6571
return http.post(`/backups/upload`, { filePath: filePath, targetDir: targetDir });
6672
};
67-
export const searchBackupRecords = (params: Backup.SearchBackupRecord) => {
68-
return http.post<ResPage<Backup.RecordInfo>>(`/backups/record/search`, params, TimeoutEnum.T_5M);
73+
export const searchBackupRecords = (params: Backup.SearchBackupRecord, node?: string) => {
74+
const query = node ? `?operateNode=${node}` : '';
75+
return http.post<ResPage<Backup.RecordInfo>>(`/backups/record/search${query}`, params, TimeoutEnum.T_5M);
6976
};
70-
export const loadRecordSize = (param: Backup.SearchForSize) => {
71-
return http.post<Array<Backup.RecordFileSize>>(`/backups/record/size`, param);
77+
export const loadRecordSize = (param: Backup.SearchForSize, node?: string) => {
78+
const query = node ? `?operateNode=${node}` : '';
79+
return http.post<Array<Backup.RecordFileSize>>(`/backups/record/size${query}`, param);
7280
};
7381
export const searchBackupRecordsByCronjob = (params: Backup.SearchBackupRecordByCronjob) => {
7482
return http.post<ResPage<Backup.RecordInfo>>(`/backups/record/search/bycronjob`, params, TimeoutEnum.T_5M);

frontend/src/api/modules/cronjob.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { ResPage, SearchWithPage } from '../interface';
33
import { Cronjob } from '../interface/cronjob';
44
import { TimeoutEnum } from '@/enums/http-enum';
55

6-
export const searchCronjobPage = (params: Cronjob.Search) => {
7-
return http.post<ResPage<Cronjob.CronjobInfo>>(`/cronjobs/search`, params);
6+
export const searchCronjobPage = (params: Cronjob.Search, node?: string) => {
7+
const query = node ? `?operateNode=${node}` : '';
8+
return http.post<ResPage<Cronjob.CronjobInfo>>(`/cronjobs/search${query}`, params);
89
};
910

1011
export const loadNextHandle = (spec: string) => {
@@ -58,12 +59,14 @@ export const cleanRecords = (id: number, cleanData: boolean, cleanRemoteData: bo
5859
return http.post(`cronjobs/records/clean`, { cronjobID: id, cleanData: cleanData, cleanRemoteData });
5960
};
6061

61-
export const updateStatus = (params: Cronjob.UpdateStatus) => {
62-
return http.post(`cronjobs/status`, params);
62+
export const updateStatus = (params: Cronjob.UpdateStatus, node?: string) => {
63+
const query = node ? `?operateNode=${node}` : '';
64+
return http.post(`cronjobs/status${query}`, params);
6365
};
6466

65-
export const handleOnce = (id: number) => {
66-
return http.post(`cronjobs/handle`, { id: id });
67+
export const handleOnce = (id: number, node?: string) => {
68+
const query = node ? `?operateNode=${node}` : '';
69+
return http.post(`cronjobs/handle${query}`, { id: id });
6770
};
6871

6972
export const searchScript = (params: SearchWithPage) => {

frontend/src/api/modules/database.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ export const bindPostgresqlUser = (params: Database.PgBind) => {
3030
export const changePrivileges = (params: Database.PgChangePrivileges) => {
3131
return http.post(`/databases/pg/privileges`, params, TimeoutEnum.T_40S);
3232
};
33-
export const searchPostgresqlDBs = (params: Database.SearchDBWithPage) => {
34-
return http.post<ResPage<Database.PostgresqlDBInfo>>(`/databases/pg/search`, params);
33+
export const searchPostgresqlDBs = (params: Database.SearchDBWithPage, node?: string) => {
34+
const query = node ? `?operateNode=${node}` : '';
35+
return http.post<ResPage<Database.PostgresqlDBInfo>>(`/databases/pg/search${query}`, params);
3536
};
3637
export const updatePostgresqlDescription = (params: DescriptionUpdate) => {
3738
return http.post(`/databases/pg/description`, params);
@@ -54,8 +55,9 @@ export const deletePostgresqlDB = (params: Database.PostgresqlDBDelete) => {
5455
};
5556

5657
// mysql
57-
export const searchMysqlDBs = (params: Database.SearchDBWithPage) => {
58-
return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search`, params);
58+
export const searchMysqlDBs = (params: Database.SearchDBWithPage, node?: string) => {
59+
const query = node ? `?operateNode=${node}` : '';
60+
return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search${query}`, params);
5961
};
6062
export const addMysqlDB = (params: Database.MysqlDBCreate) => {
6163
let request = deepCopy(params) as Database.MysqlDBCreate;
@@ -152,8 +154,9 @@ export const getDatabase = (name: string) => {
152154
export const searchDatabases = (params: Database.SearchDatabasePage) => {
153155
return http.post<ResPage<Database.DatabaseInfo>>(`/databases/db/search`, params);
154156
};
155-
export const listDatabases = (type: string) => {
156-
return http.get<Array<Database.DatabaseOption>>(`/databases/db/list/${type}`);
157+
export const listDatabases = (type: string, node?: string) => {
158+
const query = node ? `?operateNode=${node}` : '';
159+
return http.get<Array<Database.DatabaseOption>>(`/databases/db/list/${type}${query}`);
157160
};
158161
export const listDbItems = (type: string) => {
159162
return http.get<Array<Database.DbItem>>(`/databases/db/item/${type}`);

frontend/src/api/modules/website.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import { TimeoutEnum } from '@/enums/http-enum';
66
import { deepCopy } from '@/utils/util';
77
import { Base64 } from 'js-base64';
88

9-
export const searchWebsites = (req: Website.WebSiteSearch) => {
10-
return http.post<ResPage<Website.WebsiteRes>>(`/websites/search`, req);
9+
export const searchWebsites = (req: Website.WebSiteSearch, node?: string) => {
10+
const params = node ? `?operateNode=${node}` : '';
11+
return http.post<ResPage<Website.WebsiteRes>>(`/websites/search${params}`, req);
1112
};
1213

1314
export const listWebsites = () => {
@@ -22,8 +23,9 @@ export const createWebsite = (req: Website.WebSiteCreateReq) => {
2223
return http.post<any>(`/websites`, request, TimeoutEnum.T_10M);
2324
};
2425

25-
export const opWebsite = (req: Website.WebSiteOp) => {
26-
return http.post<any>(`/websites/operate`, req);
26+
export const opWebsite = (req: Website.WebSiteOp, node?: string) => {
27+
const query = node ? `?operateNode=${node}` : '';
28+
return http.post<any>(`/websites/operate${query}`, req);
2729
};
2830

2931
export const opWebsiteLog = (req: Website.WebSiteOpLog) => {

frontend/src/components/backup/index.vue

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ const secret = ref();
200200
const description = ref();
201201
const timeoutItem = ref(30);
202202
const timeoutUnit = ref('m');
203+
const node = ref();
203204
204205
const open = ref();
205206
const isBackup = ref();
@@ -212,9 +213,11 @@ interface DialogProps {
212213
detailName: string;
213214
status: string;
214215
appInstallID?: number;
216+
node?: string;
215217
}
216218
const acceptParams = (params: DialogProps): void => {
217219
type.value = params.type;
220+
node.value = params.node || currentNode.value;
218221
if (type.value === 'app') {
219222
appInstallID.value = params.appInstallID || 0;
220223
loadBackupDir();
@@ -235,7 +238,7 @@ const handleBackupClose = () => {
235238
};
236239
237240
const loadBackupDir = async () => {
238-
const res = await getLocalBackupDir();
241+
const res = await getLocalBackupDir(node.value);
239242
backupPath.value = res.data;
240243
};
241244
@@ -244,7 +247,7 @@ const goFile = async () => {
244247
};
245248
246249
const onChange = async (info: any) => {
247-
await updateRecordDescription(info.id, info.description);
250+
await updateRecordDescription(info.id, info.description, node.value);
248251
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
249252
};
250253
@@ -257,7 +260,7 @@ const search = async () => {
257260
detailName: detailName.value,
258261
};
259262
loading.value = true;
260-
await searchBackupRecords(params)
263+
await searchBackupRecords(params, node.value)
261264
.then((res) => {
262265
loading.value = false;
263266
loadSize(params);
@@ -270,7 +273,7 @@ const search = async () => {
270273
};
271274
272275
const loadSize = async (params: any) => {
273-
await loadRecordSize(params)
276+
await loadRecordSize(params, node.value)
274277
.then((res) => {
275278
let stats = res.data || [];
276279
if (stats.length === 0) {
@@ -310,7 +313,7 @@ const backup = async () => {
310313
description: description.value,
311314
};
312315
loading.value = true;
313-
await handleBackup(params)
316+
await handleBackup(params, node.value)
314317
.then(() => {
315318
loading.value = false;
316319
openTaskLog(taskID);
@@ -335,7 +338,7 @@ const recover = async (row?: any) => {
335338
timeout: timeoutItem.value === -1 ? -1 : transferTimeToSecond(timeoutItem.value + timeoutUnit.value),
336339
};
337340
loading.value = true;
338-
await handleRecover(params)
341+
await handleRecover(params, node.value)
339342
.then(() => {
340343
loading.value = false;
341344
openTaskLog(taskID);
@@ -374,8 +377,8 @@ const onDownload = async (row: Backup.RecordInfo) => {
374377
fileDir: row.fileDir,
375378
fileName: row.fileName,
376379
};
377-
await downloadBackupRecord(params).then(async (res) => {
378-
downloadFile(res.data, currentNode.value);
380+
await downloadBackupRecord(params, node.value).then(async (res) => {
381+
downloadFile(res.data, node.value);
379382
});
380383
};
381384
@@ -399,7 +402,7 @@ const onBatchDelete = async (row: Backup.RecordInfo | null) => {
399402
i18n.global.t('commons.button.backup'),
400403
i18n.global.t('commons.button.delete'),
401404
]),
402-
params: { ids: ids },
405+
params: { ids: ids, node: node.value },
403406
});
404407
};
405408

frontend/src/components/card-with-header/index.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<div>
33
<el-card :style="{ height: height }" class="home-card">
44
<div class="header">
5-
<div class="header-left">
5+
<div class="header-left flex flex-wrap gap-3">
66
<span class="header-span">{{ header }}</span>
77
<slot name="header-l" />
88
</div>
9-
<div class="header-right">
9+
<div class="header-right flex flex-wrap gap-3">
1010
<slot name="header-r" />
1111
</div>
1212
</div>

frontend/src/styles/common.scss

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ html {
126126
}
127127

128128
.search-button {
129-
width: 250px;
129+
width: 200px;
130130
}
131131

132132
.drawer-header-button {
@@ -351,3 +351,42 @@ html {
351351
--el-dialog-padding-primary: 0px !important;
352352
}
353353
}
354+
355+
.node-dashboard-card {
356+
.header {
357+
display: flex;
358+
justify-content: space-between;
359+
align-items: center;
360+
361+
.header-left {
362+
display: flex;
363+
align-items: center;
364+
gap: 12px;
365+
366+
.header-span {
367+
position: relative;
368+
font-size: 16px;
369+
font-weight: 500;
370+
margin-left: 18px;
371+
display: flex;
372+
align-items: center;
373+
374+
&::before {
375+
position: absolute;
376+
top: 50%;
377+
transform: translateY(-50%);
378+
left: -13px;
379+
width: 4px;
380+
height: 14px;
381+
content: '';
382+
background: $primary-color;
383+
border-radius: 10px;
384+
}
385+
}
386+
}
387+
.header-right {
388+
display: flex;
389+
align-items: center;
390+
}
391+
}
392+
}

frontend/src/views/container/container/terminal/index.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ import { reactive, ref, nextTick } from 'vue';
6464
import { ElForm, FormInstance } from 'element-plus';
6565
import { Rules } from '@/global/form-rules';
6666
import Terminal from '@/components/terminal/index.vue';
67+
import { useGlobalStore } from '@/composables/useGlobalStore';
68+
const { currentNode } = useGlobalStore();
6769
6870
const title = ref();
6971
const terminalVisible = ref(false);
@@ -74,13 +76,15 @@ const form = reactive({
7476
user: '',
7577
containerID: '',
7678
containerIDList: [],
79+
node: '',
7780
});
7881
const formRef = ref();
7982
const terminalRef = ref<InstanceType<typeof Terminal> | null>(null);
8083
8184
interface DialogProps {
8285
containerID: string;
8386
title: string;
87+
node?: string;
8488
}
8589
const acceptParams = async (params: DialogProps): Promise<void> => {
8690
terminalVisible.value = true;
@@ -90,6 +94,7 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
9094
form.isCustom = false;
9195
form.user = '';
9296
form.command = '/bin/sh';
97+
form.node = params.node || currentNode.value;
9398
terminalOpen.value = false;
9499
};
95100
@@ -105,7 +110,7 @@ const initTerm = (formEl: FormInstance | undefined) => {
105110
await nextTick();
106111
terminalRef.value!.acceptParams({
107112
endpoint: '/api/v2/containers/exec',
108-
args: `source=container&containerid=${form.containerID}&user=${form.user}&command=${form.command}`,
113+
args: `source=container&containerid=${form.containerID}&user=${form.user}&command=${form.command}&node=${form.node}`,
109114
error: '',
110115
initCmd: '',
111116
});

0 commit comments

Comments
 (0)