mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 23:27:17 +08:00
382 lines
9.8 KiB
Vue
382 lines
9.8 KiB
Vue
<script setup lang="ts">
|
|
import { NButton, NCheckbox, NDataTable, NFlex, NInput, NPopconfirm, NTag } from 'naive-ui'
|
|
import { useGettext } from 'vue3-gettext'
|
|
|
|
import container from '@/api/panel/container'
|
|
import { useFileStore } from '@/store'
|
|
import { formatDateTime } from '@/utils'
|
|
|
|
const { $gettext } = useGettext()
|
|
const fileStore = useFileStore()
|
|
const router = useRouter()
|
|
|
|
const forcePush = ref(false)
|
|
|
|
const createModel = ref({
|
|
name: '',
|
|
compose: '',
|
|
envs: []
|
|
})
|
|
const createModal = ref(false)
|
|
|
|
const updateModel = ref({
|
|
name: '',
|
|
compose: '',
|
|
envs: []
|
|
})
|
|
const updateModal = ref(false)
|
|
|
|
const columns: any = [
|
|
{
|
|
title: $gettext('Name'),
|
|
key: 'name',
|
|
minWidth: 150,
|
|
resizable: true,
|
|
ellipsis: { tooltip: true }
|
|
},
|
|
{
|
|
title: $gettext('Directory'),
|
|
key: 'path',
|
|
minWidth: 150,
|
|
resizable: true,
|
|
render(row: any) {
|
|
return h(
|
|
NTag,
|
|
{
|
|
class: 'cursor-pointer hover:opacity-60',
|
|
type: 'info',
|
|
onClick: () => {
|
|
fileStore.path = row.path
|
|
router.push({ name: 'file-index' })
|
|
}
|
|
},
|
|
{ default: () => row.path }
|
|
)
|
|
}
|
|
},
|
|
{
|
|
title: $gettext('Status'),
|
|
key: 'status',
|
|
width: 300,
|
|
resizable: true,
|
|
ellipsis: { tooltip: true }
|
|
},
|
|
{
|
|
title: $gettext('Creation Time'),
|
|
key: 'created_at',
|
|
width: 200,
|
|
resizable: true,
|
|
render(row: any) {
|
|
return formatDateTime(row.created_at)
|
|
}
|
|
},
|
|
{
|
|
title: $gettext('Actions'),
|
|
key: 'actions',
|
|
width: 280,
|
|
hideInExcel: true,
|
|
render(row: any) {
|
|
return [
|
|
h(
|
|
NButton,
|
|
{
|
|
size: 'small',
|
|
onClick: () => {
|
|
useRequest(container.composeGet(row.name)).onSuccess(({ data }: { data: any }) => {
|
|
updateModel.value = {
|
|
name: row.name,
|
|
compose: data.compose,
|
|
envs: data.envs
|
|
}
|
|
updateModal.value = true
|
|
})
|
|
}
|
|
},
|
|
{
|
|
default: () => $gettext('Edit')
|
|
}
|
|
),
|
|
h(
|
|
NPopconfirm,
|
|
{
|
|
showIcon: false,
|
|
onPositiveClick: () => {
|
|
const messageReactive = window.$message.loading($gettext('Starting...'), {
|
|
duration: 0
|
|
})
|
|
useRequest(container.composeUp(row.name, forcePush.value))
|
|
.onSuccess(() => {
|
|
refresh()
|
|
forcePush.value = false
|
|
window.$message.success($gettext('Start successful'))
|
|
})
|
|
.onComplete(() => {
|
|
messageReactive?.destroy()
|
|
})
|
|
}
|
|
},
|
|
{
|
|
default: () => {
|
|
return h(
|
|
NFlex,
|
|
{
|
|
vertical: true
|
|
},
|
|
{
|
|
default: () => [
|
|
h(
|
|
'strong',
|
|
{},
|
|
{
|
|
default: () =>
|
|
$gettext(`Are you sure you want to start compose %{ name }?`, {
|
|
name: row.name
|
|
})
|
|
}
|
|
),
|
|
h(
|
|
NCheckbox,
|
|
{
|
|
checked: forcePush.value,
|
|
onUpdateChecked: (v) => (forcePush.value = v)
|
|
},
|
|
{ default: () => $gettext('Force pull images') }
|
|
)
|
|
]
|
|
}
|
|
)
|
|
},
|
|
trigger: () => {
|
|
return h(
|
|
NButton,
|
|
{
|
|
style: 'margin-left: 15px;',
|
|
size: 'small',
|
|
type: 'success'
|
|
},
|
|
{
|
|
default: () => $gettext('Start')
|
|
}
|
|
)
|
|
}
|
|
}
|
|
),
|
|
h(
|
|
NPopconfirm,
|
|
{
|
|
onPositiveClick: () => {
|
|
const messageReactive = window.$message.loading($gettext('Stopping...'), {
|
|
duration: 0
|
|
})
|
|
useRequest(container.composeDown(row.name))
|
|
.onSuccess(() => {
|
|
refresh()
|
|
forcePush.value = false
|
|
window.$message.success($gettext('Stop successful'))
|
|
})
|
|
.onComplete(() => {
|
|
messageReactive?.destroy()
|
|
})
|
|
}
|
|
},
|
|
{
|
|
default: () => {
|
|
return $gettext(`Are you sure you want to stop compose %{ name }?`, {
|
|
name: row.name
|
|
})
|
|
},
|
|
trigger: () => {
|
|
return h(
|
|
NButton,
|
|
{
|
|
style: 'margin-left: 15px;',
|
|
size: 'small',
|
|
type: 'warning'
|
|
},
|
|
{
|
|
default: () => $gettext('Stop')
|
|
}
|
|
)
|
|
}
|
|
}
|
|
),
|
|
h(
|
|
NPopconfirm,
|
|
{
|
|
onPositiveClick: () => {
|
|
useRequest(container.composeRemove(row.name)).onSuccess(() => {
|
|
refresh()
|
|
window.$message.success($gettext('Delete successful'))
|
|
})
|
|
}
|
|
},
|
|
{
|
|
default: () => {
|
|
return $gettext(`Are you sure you want to delete compose %{ name }?`, {
|
|
name: row.name
|
|
})
|
|
},
|
|
trigger: () => {
|
|
return h(
|
|
NButton,
|
|
{
|
|
style: 'margin-left: 15px;',
|
|
size: 'small',
|
|
type: 'error'
|
|
},
|
|
{
|
|
default: () => $gettext('Delete')
|
|
}
|
|
)
|
|
}
|
|
}
|
|
)
|
|
]
|
|
}
|
|
}
|
|
]
|
|
|
|
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
|
(page, pageSize) => container.composeList(page, pageSize),
|
|
{
|
|
initialData: { total: 0, list: [] },
|
|
initialPageSize: 20,
|
|
total: (res: any) => res.total,
|
|
data: (res: any) => res.items
|
|
}
|
|
)
|
|
|
|
const handleCreate = () => {
|
|
loading.value = true
|
|
useRequest(container.composeCreate(createModel.value))
|
|
.onSuccess(() => {
|
|
refresh()
|
|
window.$message.success($gettext('Created successfully'))
|
|
})
|
|
.onComplete(() => {
|
|
loading.value = false
|
|
createModal.value = false
|
|
createModel.value = {
|
|
name: '',
|
|
compose: '',
|
|
envs: []
|
|
}
|
|
})
|
|
}
|
|
|
|
const handleUpdate = () => {
|
|
loading.value = true
|
|
useRequest(container.composeUpdate(updateModel.value.name, updateModel.value))
|
|
.onSuccess(() => {
|
|
refresh()
|
|
window.$message.success($gettext('Update successful'))
|
|
})
|
|
.onComplete(() => {
|
|
loading.value = false
|
|
updateModal.value = false
|
|
updateModel.value = {
|
|
name: '',
|
|
compose: '',
|
|
envs: []
|
|
}
|
|
})
|
|
}
|
|
|
|
onMounted(() => {
|
|
refresh()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<n-flex vertical :size="20">
|
|
<n-flex>
|
|
<n-button type="primary" @click="createModal = true">{{
|
|
$gettext('Create Compose')
|
|
}}</n-button>
|
|
</n-flex>
|
|
<n-data-table
|
|
striped
|
|
remote
|
|
:loading="loading"
|
|
:scroll-x="1100"
|
|
:data="data"
|
|
:columns="columns"
|
|
:row-key="(row: any) => row.name"
|
|
v-model:page="page"
|
|
v-model:pageSize="pageSize"
|
|
:pagination="{
|
|
page: page,
|
|
pageCount: pageCount,
|
|
pageSize: pageSize,
|
|
itemCount: total,
|
|
showQuickJumper: true,
|
|
showSizePicker: true,
|
|
pageSizes: [20, 50, 100, 200]
|
|
}"
|
|
/>
|
|
</n-flex>
|
|
<n-modal
|
|
v-model:show="createModal"
|
|
preset="card"
|
|
:title="$gettext('Create Compose')"
|
|
style="width: 60vw"
|
|
size="huge"
|
|
:bordered="false"
|
|
:segmented="false"
|
|
>
|
|
<n-form :model="createModel">
|
|
<n-form-item path="name" :label="$gettext('Compose Name')">
|
|
<n-input v-model:value="createModel.name" type="text" />
|
|
</n-form-item>
|
|
<n-form-item path="compose" :label="$gettext('Compose')">
|
|
<n-input
|
|
v-model:value="createModel.compose"
|
|
type="textarea"
|
|
:autosize="{ minRows: 10, maxRows: 20 }"
|
|
/>
|
|
</n-form-item>
|
|
<n-form-item path="envs" :label="$gettext('Environment Variables')">
|
|
<n-dynamic-input
|
|
v-model:value="createModel.envs"
|
|
preset="pair"
|
|
:key-placeholder="$gettext('Variable Name')"
|
|
:value-placeholder="$gettext('Variable Value')"
|
|
/>
|
|
</n-form-item>
|
|
</n-form>
|
|
<n-button type="info" block :loading="loading" :disabled="loading" @click="handleCreate">
|
|
{{ $gettext('Submit') }}
|
|
</n-button>
|
|
</n-modal>
|
|
<n-modal
|
|
v-model:show="updateModal"
|
|
preset="card"
|
|
:title="$gettext('Edit Compose')"
|
|
style="width: 60vw"
|
|
size="huge"
|
|
:bordered="false"
|
|
:segmented="false"
|
|
>
|
|
<n-form :model="updateModel">
|
|
<n-form-item path="compose" :label="$gettext('Compose')">
|
|
<n-input
|
|
v-model:value="updateModel.compose"
|
|
type="textarea"
|
|
:autosize="{ minRows: 10, maxRows: 20 }"
|
|
/>
|
|
</n-form-item>
|
|
<n-form-item path="envs" :label="$gettext('Environment Variables')">
|
|
<n-dynamic-input
|
|
v-model:value="updateModel.envs"
|
|
preset="pair"
|
|
:key-placeholder="$gettext('Variable Name')"
|
|
:value-placeholder="$gettext('Variable Value')"
|
|
/>
|
|
</n-form-item>
|
|
</n-form>
|
|
<n-button type="info" block :loading="loading" :disabled="loading" @click="handleUpdate">
|
|
{{ $gettext('Submit') }}
|
|
</n-button>
|
|
</n-modal>
|
|
</template>
|