mirror of https://github.com/1Panel-dev/1Panel
feat: compose 详情界面增加启动、停止操作
parent
cecc108784
commit
41be181c7d
|
@ -89,8 +89,6 @@ func (b *BaseApi) UpdateComposeTemplate(c *gin.Context) {
|
|||
}
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["from"] = req.From
|
||||
upMap["path"] = req.Path
|
||||
upMap["content"] = req.Content
|
||||
upMap["description"] = req.Description
|
||||
if err := composeTemplateService.Update(id, upMap); err != nil {
|
||||
|
|
|
@ -4,16 +4,12 @@ import "time"
|
|||
|
||||
type ComposeTemplateCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
From string `json:"from" validate:"required,oneof=edit path"`
|
||||
Description string `json:"description"`
|
||||
Path string `json:"path"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type ComposeTemplateUpdate struct {
|
||||
From string `json:"from" validate:"required,oneof=edit path"`
|
||||
Description string `json:"description"`
|
||||
Path string `json:"path"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
|
@ -21,8 +17,6 @@ type ComposeTemplateInfo struct {
|
|||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name"`
|
||||
From string `json:"from"`
|
||||
Description string `json:"description"`
|
||||
Path string `json:"path"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ type ComposeCreate struct {
|
|||
type ComposeOperation struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
Operation string `json:"operation" validate:"required,oneof=up stop down"`
|
||||
Operation string `json:"operation" validate:"required,oneof=start stop down"`
|
||||
}
|
||||
type ComposeUpdate struct {
|
||||
Path string `json:"path" validate:"required"`
|
||||
|
|
|
@ -4,9 +4,7 @@ type ComposeTemplate struct {
|
|||
BaseModel
|
||||
|
||||
Name string `gorm:"type:varchar(64);not null;unique" json:"name"`
|
||||
From string `gorm:"type:varchar(64);not null" json:"from"`
|
||||
Description string `gorm:"type:varchar(256)" json:"description"`
|
||||
Path string `gorm:"type:varchar(64)" json:"path"`
|
||||
Content string `gorm:"type:longtext" json:"content"`
|
||||
}
|
||||
|
||||
|
|
|
@ -114,12 +114,8 @@ func (u *ContainerService) CreateCompose(req dto.ComposeCreate) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.From = template.From
|
||||
if req.From == "edit" {
|
||||
req.File = template.Content
|
||||
} else {
|
||||
req.Path = template.Path
|
||||
}
|
||||
req.From = "edit"
|
||||
req.File = template.Content
|
||||
}
|
||||
if req.From == "edit" {
|
||||
dir := fmt.Sprintf("%s/%s", constant.TmpComposeBuildDir, req.Name)
|
||||
|
@ -159,6 +155,7 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
|||
global.LOG.Debugf("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, req.Name+"/docker-compose.yml", ""))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -193,6 +193,7 @@ export namespace Container {
|
|||
template: number;
|
||||
}
|
||||
export interface ComposeOpration {
|
||||
name: string;
|
||||
operation: string;
|
||||
path: string;
|
||||
}
|
||||
|
|
|
@ -446,7 +446,9 @@ export default {
|
|||
containerNumber: 'Container number',
|
||||
down: 'Down',
|
||||
up: 'Up',
|
||||
operatorComposeHelper: '{0} will be performed on the selected compose. Do you want to continue?',
|
||||
composeDetailHelper:
|
||||
'The compose is created external to 1Panel. The start and stop operations are not supported.',
|
||||
composeOperatorHelper: '{1} operation will be performed on {0}. Do you want to continue?',
|
||||
},
|
||||
cronjob: {
|
||||
cronTask: 'Task',
|
||||
|
|
|
@ -355,7 +355,7 @@ export default {
|
|||
pause: '暂停',
|
||||
unpause: '恢复',
|
||||
rename: '重命名',
|
||||
remove: '移除',
|
||||
remove: '删除',
|
||||
container: '容器',
|
||||
upTime: '运行时长',
|
||||
all: '全部',
|
||||
|
@ -455,7 +455,8 @@ export default {
|
|||
containerNumber: '容器数量',
|
||||
down: '删除',
|
||||
up: '启动',
|
||||
operatorComposeHelper: '将对选中 Compose 进行 {0} 操作,是否继续?',
|
||||
composeDetailHelper: '该 compose 为 1Panel 编排外部创建。暂不支持启停操作。',
|
||||
composeOperatorHelper: '将对 {0} 进行 {1} 操作,是否继续?',
|
||||
|
||||
setting: '容器配置',
|
||||
mirrors: '镜像加速',
|
||||
|
|
|
@ -1,100 +1,102 @@
|
|||
<template>
|
||||
<div v-loading="loading">
|
||||
<Submenu activeName="compose" />
|
||||
<el-card style="margin-top: 20px">
|
||||
<LayoutContent :header="'Compose-' + composeName" back-name="Compose" :reload="true">
|
||||
<div>
|
||||
<el-button icon="VideoPause">停止</el-button>
|
||||
<el-button icon="Delete" plain type="danger">删除</el-button>
|
||||
</div>
|
||||
<el-card style="margin-top: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>Containers</span>
|
||||
</div>
|
||||
<LayoutContent :header="'Compose-' + composeName" back-name="Compose" :reload="true">
|
||||
<div v-if="createdBy === 'local'">
|
||||
<el-button icon="VideoPlay" @click="onComposeOperate('start')">{{ $t('container.start') }}</el-button>
|
||||
<el-button icon="VideoPause" @click="onComposeOperate('stop')">{{ $t('container.stop') }}</el-button>
|
||||
<el-button icon="Delete" @click="onComposeOperate('down')" plain type="danger">
|
||||
{{ $t('container.remove') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-alert :closable="false" show-icon :title="$t('container.composeDetailHelper')" type="info" />
|
||||
</div>
|
||||
<el-card style="margin-top: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>Containers</span>
|
||||
</div>
|
||||
</template>
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
v-model:selects="selects"
|
||||
:data="data"
|
||||
@search="search"
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-button-group>
|
||||
<el-button :disabled="checkStatus('start')" @click="onOperate('start')">
|
||||
{{ $t('container.start') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('stop')" @click="onOperate('stop')">
|
||||
{{ $t('container.stop') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('restart')" @click="onOperate('restart')">
|
||||
{{ $t('container.restart') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('kill')" @click="onOperate('kill')">
|
||||
{{ $t('container.kill') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('pause')" @click="onOperate('pause')">
|
||||
{{ $t('container.pause') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('unpause')" @click="onOperate('unpause')">
|
||||
{{ $t('container.unpause') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('remove')" @click="onOperate('remove')">
|
||||
{{ $t('container.remove') }}
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
</template>
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
v-model:selects="selects"
|
||||
:data="data"
|
||||
@search="search"
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
show-overflow-tooltip
|
||||
min-width="100"
|
||||
prop="name"
|
||||
fix
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-button-group>
|
||||
<el-button :disabled="checkStatus('start')" @click="onOperate('start')">
|
||||
{{ $t('container.start') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('stop')" @click="onOperate('stop')">
|
||||
{{ $t('container.stop') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('restart')" @click="onOperate('restart')">
|
||||
{{ $t('container.restart') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('kill')" @click="onOperate('kill')">
|
||||
{{ $t('container.kill') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('pause')" @click="onOperate('pause')">
|
||||
{{ $t('container.pause') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('unpause')" @click="onOperate('unpause')">
|
||||
{{ $t('container.unpause') }}
|
||||
</el-button>
|
||||
<el-button :disabled="checkStatus('remove')" @click="onOperate('remove')">
|
||||
{{ $t('container.remove') }}
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<template #default="{ row }">
|
||||
<el-link @click="onInspect(row.containerID)" type="primary">{{ row.name }}</el-link>
|
||||
</template>
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
show-overflow-tooltip
|
||||
min-width="100"
|
||||
prop="name"
|
||||
fix
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-link @click="onInspect(row.containerID)" type="primary">{{ row.name }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('container.image')"
|
||||
show-overflow-tooltip
|
||||
min-width="100"
|
||||
prop="imageName"
|
||||
/>
|
||||
<el-table-column :label="$t('commons.table.status')" min-width="50" prop="state" fix />
|
||||
<el-table-column :label="$t('container.upTime')" min-width="100" prop="runTime" fix />
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
:label="$t('commons.table.date')"
|
||||
:formatter="dateFromat"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<fu-table-operations
|
||||
width="200px"
|
||||
:ellipsis="10"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('container.image')"
|
||||
show-overflow-tooltip
|
||||
min-width="100"
|
||||
prop="imageName"
|
||||
/>
|
||||
<el-table-column :label="$t('commons.table.status')" min-width="50" prop="state" fix />
|
||||
<el-table-column :label="$t('container.upTime')" min-width="100" prop="runTime" fix />
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
:label="$t('commons.table.date')"
|
||||
:formatter="dateFromat"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<fu-table-operations
|
||||
width="200px"
|
||||
:ellipsis="10"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
|
||||
<CodemirrorDialog ref="mydetail" />
|
||||
<CodemirrorDialog ref="mydetail" />
|
||||
|
||||
<ReNameDialog @search="search" ref="dialogReNameRef" />
|
||||
<ContainerLogDialog ref="dialogContainerLogRef" />
|
||||
<CreateDialog @search="search" ref="dialogCreateRef" />
|
||||
<MonitorDialog ref="dialogMonitorRef" />
|
||||
<TerminalDialog ref="dialogTerminalRef" />
|
||||
</el-card>
|
||||
</LayoutContent>
|
||||
</el-card>
|
||||
<ReNameDialog @search="search" ref="dialogReNameRef" />
|
||||
<ContainerLogDialog ref="dialogContainerLogRef" />
|
||||
<CreateDialog @search="search" ref="dialogCreateRef" />
|
||||
<MonitorDialog ref="dialogMonitorRef" />
|
||||
<TerminalDialog ref="dialogTerminalRef" />
|
||||
</el-card>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import Submenu from '@/views/container/index.vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import ReNameDialog from '@/views/container/container/rename/index.vue';
|
||||
import CreateDialog from '@/views/container/container/create/index.vue';
|
||||
|
@ -104,19 +106,30 @@ import TerminalDialog from '@/views/container/container/terminal/index.vue';
|
|||
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { dateFromat } from '@/utils/util';
|
||||
import { ContainerOperator, inspect, searchContainer } from '@/api/modules/container';
|
||||
import { composeOperator, ContainerOperator, inspect, searchContainer } from '@/api/modules/container';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import i18n from '@/lang';
|
||||
import { Container } from '@/api/interface/container';
|
||||
|
||||
interface Filters {
|
||||
filters?: string;
|
||||
}
|
||||
const props = withDefaults(defineProps<Filters>(), {
|
||||
filters: '',
|
||||
});
|
||||
|
||||
const composeName = ref();
|
||||
const composePath = ref();
|
||||
const filters = ref();
|
||||
const createdBy = ref();
|
||||
|
||||
const emit = defineEmits<{ (e: 'back'): void }>();
|
||||
interface DialogProps {
|
||||
createdBy: string;
|
||||
name: string;
|
||||
path: string;
|
||||
filters: string;
|
||||
}
|
||||
const acceptParams = (props: DialogProps): void => {
|
||||
composePath.value = props.path;
|
||||
composeName.value = props.name;
|
||||
filters.value = props.filters;
|
||||
createdBy.value = props.createdBy;
|
||||
search();
|
||||
};
|
||||
|
||||
const data = ref();
|
||||
const selects = ref<any>([]);
|
||||
|
@ -129,8 +142,7 @@ const paginationConfig = reactive({
|
|||
const loading = ref(false);
|
||||
|
||||
const search = async () => {
|
||||
let filterItem = props.filters ? props.filters : '';
|
||||
composeName.value = props.filters.replaceAll('com.docker.compose.project=', '');
|
||||
let filterItem = filters.value;
|
||||
let params = {
|
||||
page: paginationConfig.page,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
|
@ -173,20 +185,6 @@ const checkStatus = (operation: string) => {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
case 'pause':
|
||||
for (const item of selects.value) {
|
||||
if (item.state === 'paused' || item.state === 'exited') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case 'unpause':
|
||||
for (const item of selects.value) {
|
||||
if (item.state !== 'paused') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -220,6 +218,38 @@ const onOperate = async (operation: string) => {
|
|||
});
|
||||
};
|
||||
|
||||
const onComposeOperate = async (operation: string) => {
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('container.composeOperatorHelper', [composeName.value, i18n.global.t('container.' + operation)]),
|
||||
i18n.global.t('container.' + operation),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
).then(async () => {
|
||||
let params = {
|
||||
name: composeName.value,
|
||||
path: composePath.value,
|
||||
operation: operation,
|
||||
};
|
||||
loading.value = true;
|
||||
await composeOperator(params)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
if (operation === 'down') {
|
||||
emit('back');
|
||||
} else {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const dialogMonitorRef = ref();
|
||||
const onMonitor = (containerID: string) => {
|
||||
dialogMonitorRef.value!.acceptParams({ containerID: containerID });
|
||||
|
@ -265,7 +295,8 @@ const buttons = [
|
|||
},
|
||||
},
|
||||
];
|
||||
onMounted(() => {
|
||||
search();
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -2,34 +2,49 @@
|
|||
<div v-loading="loading">
|
||||
<Submenu activeName="compose" />
|
||||
<el-card style="margin-top: 20px">
|
||||
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
|
||||
<template #toolbar>
|
||||
<el-button icon="Plus" type="primary" @click="onOpenDialog()">
|
||||
{{ $t('commons.button.create') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
show-overflow-tooltip
|
||||
min-width="100"
|
||||
prop="name"
|
||||
fix
|
||||
<div v-if="!isOnDetail">
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
v-model:selects="selects"
|
||||
:data="data"
|
||||
@search="search"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-link @click="goContainer(row.name)" type="primary">{{ row.name }}</el-link>
|
||||
<template #toolbar>
|
||||
<el-button icon="Plus" type="primary" @click="onOpenDialog()">
|
||||
{{ $t('commons.button.create') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('container.from')" prop="createdBy" min-width="80" fix />
|
||||
<el-table-column :label="$t('container.containerNumber')" prop="containerNumber" min-width="80" fix />
|
||||
<el-table-column :label="$t('commons.table.createdAt')" prop="createdAt" min-width="80" fix />
|
||||
<fu-table-operations
|
||||
width="200px"
|
||||
:ellipsis="10"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
show-overflow-tooltip
|
||||
min-width="100"
|
||||
prop="name"
|
||||
fix
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-link @click="loadDetail(row)" type="primary">{{ row.name }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('container.from')" prop="createdBy" min-width="80" fix />
|
||||
<el-table-column
|
||||
:label="$t('container.containerNumber')"
|
||||
prop="containerNumber"
|
||||
min-width="80"
|
||||
fix
|
||||
/>
|
||||
<el-table-column :label="$t('commons.table.createdAt')" prop="createdAt" min-width="80" fix />
|
||||
<fu-table-operations
|
||||
width="200px"
|
||||
:ellipsis="10"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
</div>
|
||||
<div v-show="isOnDetail">
|
||||
<ComposeDetial @back="backList" ref="composeDetailRef" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<EditDialog ref="dialogEditRef" />
|
||||
|
@ -40,13 +55,13 @@
|
|||
<script lang="ts" setup>
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { reactive, onMounted, ref } from 'vue';
|
||||
import CreateDialog from '@/views/container/compose/create/index.vue';
|
||||
import EditDialog from '@/views/container/compose/edit/index.vue';
|
||||
import CreateDialog from '@/views/container/compose/create/index.vue';
|
||||
import ComposeDetial from '@/views/container/compose/detail/index.vue';
|
||||
import Submenu from '@/views/container/index.vue';
|
||||
import { composeOperator, searchCompose } from '@/api/modules/container';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import router from '@/routers';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import { LoadFile } from '@/api/modules/files';
|
||||
|
@ -55,6 +70,8 @@ const data = ref();
|
|||
const selects = ref<any>([]);
|
||||
const loading = ref(false);
|
||||
|
||||
const isOnDetail = ref(false);
|
||||
|
||||
const paginationConfig = reactive({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
|
@ -78,8 +95,20 @@ const search = async () => {
|
|||
});
|
||||
};
|
||||
|
||||
const goContainer = async (name: string) => {
|
||||
router.push({ name: 'ComposeDetail', params: { filters: 'com.docker.compose.project=' + name } });
|
||||
const composeDetailRef = ref();
|
||||
const loadDetail = async (row: Container.ComposeInfo) => {
|
||||
let params = {
|
||||
createdBy: row.createdBy,
|
||||
name: row.name,
|
||||
path: row.path,
|
||||
filters: 'com.docker.compose.project=' + row.name,
|
||||
};
|
||||
isOnDetail.value = true;
|
||||
composeDetailRef.value!.acceptParams(params);
|
||||
};
|
||||
const backList = async () => {
|
||||
isOnDetail.value = false;
|
||||
search();
|
||||
};
|
||||
|
||||
const dialogRef = ref();
|
||||
|
@ -114,12 +143,18 @@ const buttons = [
|
|||
click: (row: Container.ComposeInfo) => {
|
||||
onEdit(row);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
return row.createdBy !== 'local';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Container.ComposeInfo) => {
|
||||
onDelete(row);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
return row.createdBy === 'apps';
|
||||
},
|
||||
},
|
||||
];
|
||||
onMounted(() => {
|
||||
|
|
|
@ -77,7 +77,6 @@ import OperatorDialog from '@/views/container/template/operator/index.vue';
|
|||
import { deleteComposeTemplate, searchComposeTemplate } from '@/api/modules/container';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import i18n from '@/lang';
|
||||
import { LoadFile } from '@/api/modules/files';
|
||||
|
||||
const data = ref();
|
||||
const selects = ref<any>([]);
|
||||
|
@ -104,14 +103,8 @@ const search = async () => {
|
|||
};
|
||||
|
||||
const onOpenDetail = async (row: Container.TemplateInfo) => {
|
||||
if (row.from === 'edit') {
|
||||
detailInfo.value = row.content;
|
||||
detailVisiable.value = true;
|
||||
} else {
|
||||
const res = await LoadFile({ path: row.path });
|
||||
detailInfo.value = res.data;
|
||||
detailVisiable.value = true;
|
||||
}
|
||||
detailInfo.value = row.content;
|
||||
detailVisiable.value = true;
|
||||
};
|
||||
|
||||
const dialogRef = ref();
|
||||
|
@ -119,10 +112,8 @@ const onOpenDialog = async (
|
|||
title: string,
|
||||
rowData: Partial<Container.TemplateInfo> = {
|
||||
name: '',
|
||||
from: 'edit',
|
||||
description: '',
|
||||
path: '',
|
||||
content: '',
|
||||
},
|
||||
) => {
|
||||
let params = {
|
||||
|
|
|
@ -12,24 +12,7 @@
|
|||
<el-form-item :label="$t('container.description')">
|
||||
<el-input v-model="dialogData.rowData!.description"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.from')">
|
||||
<el-radio-group v-model="dialogData.rowData!.from">
|
||||
<el-radio label="edit">{{ $t('container.edit') }}</el-radio>
|
||||
<el-radio label="path">{{ $t('container.pathSelect') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="dialogData.rowData!.from === 'path'" prop="path">
|
||||
<el-input
|
||||
clearable
|
||||
:placeholder="$t('commons.example') + '/tmp/docker-compose.yml'"
|
||||
v-model="dialogData.rowData!.path"
|
||||
>
|
||||
<template #append>
|
||||
<FileList @choose="loadDir" :dir="false"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="dialogData.rowData!.from === 'edit'">
|
||||
<el-form-item>
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder="None data"
|
||||
|
@ -59,7 +42,6 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import FileList from '@/components/file-list/index.vue';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
|
@ -87,16 +69,8 @@ const acceptParams = (params: DialogProps): void => {
|
|||
};
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const varifyPath = (rule: any, value: any, callback: any) => {
|
||||
console.log(value, value.indexOf('docker-compose.yml'));
|
||||
if (value.indexOf('docker-compose.yml') === -1) {
|
||||
callback(new Error(i18n.global.t('commons.rule.selectHelper', ['docker-compose.yml'])));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
const rules = reactive({
|
||||
name: [Rules.requiredInput, Rules.name],
|
||||
path: [Rules.requiredInput, { validator: varifyPath, trigger: 'change', required: true }],
|
||||
content: [Rules.requiredInput],
|
||||
});
|
||||
|
||||
|
@ -125,10 +99,6 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
|||
});
|
||||
};
|
||||
|
||||
const loadDir = async (path: string) => {
|
||||
dialogData.value.rowData!.path = path;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue