mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-09-11 00:54:55 +08:00
parent
66465beb39
commit
5a0c50b9a2
3 changed files with 93 additions and 30 deletions
|
@ -209,11 +209,12 @@ type NetworkCreate struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Labels []string `json:"labels"`
|
Labels []VolumeOption `json:"labels"`
|
||||||
Driver string `json:"driver"`
|
Driver string `json:"driver"`
|
||||||
Mountpoint string `json:"mountpoint"`
|
Mountpoint string `json:"mountpoint"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Options []VolumeOption `json:"options"`
|
||||||
}
|
}
|
||||||
type VolumeCreate struct {
|
type VolumeCreate struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
|
@ -221,7 +222,10 @@ type VolumeCreate struct {
|
||||||
Options []string `json:"options"`
|
Options []string `json:"options"`
|
||||||
Labels []string `json:"labels"`
|
Labels []string `json:"labels"`
|
||||||
}
|
}
|
||||||
|
type VolumeOption struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
type BatchDelete struct {
|
type BatchDelete struct {
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
Force bool `json:"force"`
|
Force bool `json:"force"`
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||||
|
@ -53,25 +54,27 @@ func (u *ContainerService) PageVolume(req dto.SearchWithPage) (int64, interface{
|
||||||
|
|
||||||
nyc, _ := time.LoadLocation(common.LoadTimeZoneByCmd())
|
nyc, _ := time.LoadLocation(common.LoadTimeZoneByCmd())
|
||||||
for _, item := range records {
|
for _, item := range records {
|
||||||
tag := make([]string, 0)
|
var volume dto.Volume
|
||||||
for _, val := range item.Labels {
|
volume.Driver = item.Driver
|
||||||
tag = append(tag, val)
|
volume.Mountpoint = item.Mountpoint
|
||||||
|
volume.Name = simplifyVolumeName(item.Name)
|
||||||
|
for key, val := range item.Labels {
|
||||||
|
volume.Labels = append(volume.Labels, dto.VolumeOption{Key: key, Value: val})
|
||||||
}
|
}
|
||||||
var createTime time.Time
|
for key, val := range item.Options {
|
||||||
if strings.Contains(item.CreatedAt, "Z") {
|
volume.Options = append(volume.Options, dto.VolumeOption{Key: key, Value: val})
|
||||||
createTime, _ = time.ParseInLocation("2006-01-02T15:04:05Z", item.CreatedAt, nyc)
|
|
||||||
} else if strings.Contains(item.CreatedAt, "+") {
|
|
||||||
createTime, _ = time.ParseInLocation("2006-01-02T15:04:05+08:00", item.CreatedAt, nyc)
|
|
||||||
} else {
|
|
||||||
createTime, _ = time.ParseInLocation("2006-01-02T15:04:05", item.CreatedAt, nyc)
|
|
||||||
}
|
}
|
||||||
data = append(data, dto.Volume{
|
sort.Slice(volume.Options, func(i, j int) bool {
|
||||||
CreatedAt: createTime,
|
return volume.Options[i].Key < volume.Options[j].Key
|
||||||
Name: item.Name,
|
|
||||||
Driver: item.Driver,
|
|
||||||
Mountpoint: item.Mountpoint,
|
|
||||||
Labels: tag,
|
|
||||||
})
|
})
|
||||||
|
if strings.Contains(item.CreatedAt, "Z") {
|
||||||
|
volume.CreatedAt, _ = time.ParseInLocation("2006-01-02T15:04:05Z", item.CreatedAt, nyc)
|
||||||
|
} else if strings.Contains(item.CreatedAt, "+") {
|
||||||
|
volume.CreatedAt, _ = time.ParseInLocation("2006-01-02T15:04:05+08:00", item.CreatedAt, nyc)
|
||||||
|
} else {
|
||||||
|
volume.CreatedAt, _ = time.ParseInLocation("2006-01-02T15:04:05", item.CreatedAt, nyc)
|
||||||
|
}
|
||||||
|
data = append(data, volume)
|
||||||
}
|
}
|
||||||
|
|
||||||
return int64(total), data, nil
|
return int64(total), data, nil
|
||||||
|
@ -140,3 +143,16 @@ func (u *ContainerService) CreateVolume(req dto.VolumeCreate) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func simplifyVolumeName(name string) string {
|
||||||
|
if len(name) != 64 {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range name {
|
||||||
|
if !unicode.Is(unicode.ASCII_Hex_Digit, char) {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name[:12]
|
||||||
|
}
|
||||||
|
|
|
@ -47,15 +47,35 @@
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('container.volumeDir')" min-width="100">
|
<el-table-column label="Options" min-width="160">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tooltip :content="row.mountpoint">
|
<div v-for="(item, index) in row.options" :key="index">
|
||||||
<el-button type="primary" link @click="routerToFileWithPath(row.mountpoint)">
|
<div v-if="row.expand || (!row.expand && index < 3)">
|
||||||
<el-icon>
|
<el-button
|
||||||
<FolderOpened />
|
v-if="item.key === 'device'"
|
||||||
</el-icon>
|
@click="jumpTo(item.value)"
|
||||||
|
class="mt-0.5"
|
||||||
|
icon="Position"
|
||||||
|
plain
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ item.key + ': ' + item.value }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-else class="mt-0.5" plain size="small">
|
||||||
|
{{ item.key + ': ' + item.value }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="!row.expand && row.options.length > 3">
|
||||||
|
<el-button type="primary" link @click="row.expand = true">
|
||||||
|
{{ $t('commons.button.expand') }}...
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</div>
|
||||||
|
<div v-if="row.expand && row.options.length > 3">
|
||||||
|
<el-button type="primary" link @click="row.expand = false">
|
||||||
|
{{ $t('commons.button.collapse') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
@ -63,7 +83,18 @@
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
min-width="120"
|
min-width="120"
|
||||||
prop="mountpoint"
|
prop="mountpoint"
|
||||||
/>
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tooltip :content="row.mountpoint">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="FolderOpened"
|
||||||
|
link
|
||||||
|
@click="routerToFileWithPath(row.mountpoint)"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:label="$t('container.driver')"
|
:label="$t('container.driver')"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
|
@ -102,6 +133,8 @@ import i18n from '@/lang';
|
||||||
import { ElMessageBox } from 'element-plus';
|
import { ElMessageBox } from 'element-plus';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
import { routerToFileWithPath } from '@/utils/router';
|
import { routerToFileWithPath } from '@/utils/router';
|
||||||
|
import { checkFile } from '@/api/modules/files';
|
||||||
|
import { MsgError } from '@/utils/message';
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
const taskLogRef = ref();
|
const taskLogRef = ref();
|
||||||
|
@ -193,6 +226,16 @@ const openTaskLog = (taskID: string) => {
|
||||||
taskLogRef.value.openWithTaskID(taskID);
|
taskLogRef.value.openWithTaskID(taskID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const jumpTo = async (path: any) => {
|
||||||
|
await checkFile(path, false).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
routerToFileWithPath(path);
|
||||||
|
} else {
|
||||||
|
MsgError(i18n.global.t('file.noSuchFile'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const batchDelete = async (row: Container.VolumeInfo | null) => {
|
const batchDelete = async (row: Container.VolumeInfo | null) => {
|
||||||
let names = [];
|
let names = [];
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue