diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go index 40035333b..b8c54eab6 100644 --- a/backend/app/dto/container.go +++ b/backend/app/dto/container.go @@ -146,6 +146,7 @@ type ComposeOperation struct { Name string `json:"name" validate:"required"` Path string `json:"path" validate:"required"` Operation string `json:"operation" validate:"required,oneof=start stop down"` + WithFile bool `json:"withFile"` } type ComposeUpdate struct { Name string `json:"name" validate:"required"` diff --git a/backend/app/service/container_compose.go b/backend/app/service/container_compose.go index 44476756d..300a237d9 100644 --- a/backend/app/service/container_compose.go +++ b/backend/app/service/container_compose.go @@ -182,7 +182,9 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error { global.LOG.Infof("docker-compose %s %s successful", req.Operation, req.Name) if req.Operation == "down" { _ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name)) - _ = os.RemoveAll(strings.ReplaceAll(req.Path, "/docker-compose.yml", "")) + if req.WithFile { + _ = os.RemoveAll(path.Dir(req.Path)) + } } return nil diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index 8453c2d99..cd04091cb 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -208,6 +208,7 @@ export namespace Container { name: string; operation: string; path: string; + withFile: boolean; } export interface ComposeUpdate { name: string; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 93b2f61c6..6a5ae4cc4 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -546,6 +546,11 @@ const message = { compose: 'Compose', fromChangeHelper: 'Switching the source will clear the current edited content. Do you want to continue?', composePathHelper: 'Config file save path: {0}', + composeHelper: + 'The composition created through 1Panel editor or template will be saved in the {0}/docker/compose directory.', + deleteFile: 'Delete file', + deleteComposeHelper: 'Delete the corresponding composition file.', + deleteCompose: '" Delete this composition.', apps: 'Apps', local: 'Local', createCompose: 'Create compose', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index e1a383c9b..518024cd6 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -563,6 +563,10 @@ const message = { compose: '编排', fromChangeHelper: '切换来源将清空当前已编辑内容,是否继续?', composePathHelper: '配置文件保存路径: {0}', + composeHelper: '通过 1Panel 编辑或者模版创建的编排,将保存在 {0}/docker/compose 路径下', + deleteFile: '删除文件', + deleteComposeHelper: '删除对应的编排文件', + deleteCompose: '" 删除此编排', apps: '应用商店', local: '本地', createCompose: '创建编排', diff --git a/frontend/src/views/container/compose/create/index.vue b/frontend/src/views/container/compose/create/index.vue index 422b32b60..891153bec 100644 --- a/frontend/src/views/container/compose/create/index.vue +++ b/frontend/src/views/container/compose/create/index.vue @@ -172,6 +172,7 @@ const acceptParams = (): void => { form.from = 'edit'; form.path = ''; form.file = ''; + form.template = null; logInfo.value = ''; loadTemplates(); loadPath(); diff --git a/frontend/src/views/container/compose/delete/index.vue b/frontend/src/views/container/compose/delete/index.vue new file mode 100644 index 000000000..9dc6ae7ac --- /dev/null +++ b/frontend/src/views/container/compose/delete/index.vue @@ -0,0 +1,90 @@ + + diff --git a/frontend/src/views/container/compose/index.vue b/frontend/src/views/container/compose/index.vue index 18e0751a5..5319ff25d 100644 --- a/frontend/src/views/container/compose/index.vue +++ b/frontend/src/views/container/compose/index.vue @@ -10,6 +10,20 @@ + @@ -83,12 +98,13 @@ import { reactive, onMounted, ref } from 'vue'; import LayoutContent from '@/layout/layout-content.vue'; import EditDialog from '@/views/container/compose/edit/index.vue'; import CreateDialog from '@/views/container/compose/create/index.vue'; +import DeleteDialog from '@/views/container/compose/delete/index.vue'; import ComposeDetial from '@/views/container/compose/detail/index.vue'; -import { composeOperator, loadDockerStatus, searchCompose } from '@/api/modules/container'; +import { loadDockerStatus, searchCompose } from '@/api/modules/container'; import i18n from '@/lang'; import { Container } from '@/api/interface/container'; -import { useDeleteData } from '@/hooks/use-delete-data'; import { LoadFile } from '@/api/modules/files'; +import { loadBaseDir } from '@/api/modules/setting'; import router from '@/routers'; const data = ref(); @@ -96,6 +112,7 @@ const selects = ref([]); const loading = ref(false); const isOnDetail = ref(false); +const baseDir = ref(); const paginationConfig = reactive({ currentPage: 1, @@ -124,6 +141,15 @@ const goSetting = async () => { router.push({ name: 'ContainerSetting' }); }; +const toFolder = async () => { + router.push({ path: '/hosts/files', query: { path: baseDir.value + '/docker/compose' } }); +}; + +const loadPath = async () => { + const pathRes = await loadBaseDir(); + baseDir.value = pathRes.data; +}; + const search = async () => { let params = { info: searchName.value, @@ -163,14 +189,13 @@ const onOpenDialog = async () => { dialogRef.value!.acceptParams(); }; +const dialogDelRef = ref(); const onDelete = async (row: Container.ComposeInfo) => { const param = { name: row.name, path: row.path, - operation: 'down', }; - await useDeleteData(composeOperator, param, 'commons.msg.delete'); - search(); + dialogDelRef.value.acceptParams(param); }; const dialogEditRef = ref(); @@ -205,6 +230,7 @@ const buttons = [ }, ]; onMounted(() => { + loadPath(); loadStatus(); });