Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions agent/app/api/v2/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
// @Tags Container Image
// @Summary Page images
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Param request body dto.PageImage true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/search [post]
func (b *BaseApi) SearchImage(c *gin.Context) {
var req dto.SearchWithPage
var req dto.PageImage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
Expand Down
9 changes: 8 additions & 1 deletion agent/app/dto/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ package dto

import "time"

type PageImage struct {
PageInfo
Name string `json:"name"`
OrderBy string `json:"orderBy" validate:"required,oneof=size tags createdAt isUsed"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}

type ImageInfo struct {
ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"`
IsUsed bool `json:"isUsed"`
Tags []string `json:"tags"`
Size string `json:"size"`
Size int64 `json:"size"`
}

type ImageLoad struct {
Expand Down
42 changes: 34 additions & 8 deletions agent/app/service/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io"
"os"
"path"
"sort"
"strings"
"time"

Expand All @@ -34,7 +35,7 @@ import (
type ImageService struct{}

type IImageService interface {
Page(req dto.SearchWithPage) (int64, interface{}, error)
Page(req dto.PageImage) (int64, interface{}, error)
List() ([]dto.Options, error)
ListAll() ([]dto.ImageInfo, error)
ImageBuild(req dto.ImageBuild) error
Expand All @@ -49,7 +50,7 @@ type IImageService interface {
func NewIImageService() IImageService {
return &ImageService{}
}
func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error) {
func (u *ImageService) Page(req dto.PageImage) (int64, interface{}, error) {
var (
list []image.Summary
records []dto.ImageInfo
Expand All @@ -65,12 +66,12 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error)
return 0, nil, err
}
containers, _ := client.ContainerList(context.Background(), container.ListOptions{All: true})
if len(req.Info) != 0 {
if len(req.Name) != 0 {
length, count := len(list), 0
for count < length {
hasTag := false
for _, tag := range list[count].RepoTags {
if strings.Contains(tag, req.Info) {
if strings.Contains(tag, req.Name) {
hasTag = true
break
}
Expand All @@ -85,15 +86,41 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error)
}

for _, image := range list {
size := formatFileSize(image.Size)
records = append(records, dto.ImageInfo{
ID: image.ID,
Tags: image.RepoTags,
IsUsed: checkUsed(image.ID, containers),
CreatedAt: time.Unix(image.Created, 0),
Size: size,
Size: image.Size,
})
}
switch req.OrderBy {
case "size":
sort.Slice(records, func(i, j int) bool {
if req.Order == constant.OrderAsc {
return records[i].Size < records[j].Size
}
return records[i].Size > records[j].Size
})
case "tags":
sort.Slice(records, func(i, j int) bool {
if len(records[i].Tags) == 0 || len(records[j].Tags) == 0 {
return true
}
if req.Order == constant.OrderAsc {
return records[i].Tags[0] < records[j].Tags[0]
}
return records[i].Tags[0] > records[j].Tags[0]
})
default:
sort.Slice(records, func(i, j int) bool {
if req.Order == constant.OrderAsc {
return records[i].CreatedAt.Before(records[j].CreatedAt)
}
return records[i].CreatedAt.After(records[j].CreatedAt)
})
}

total, start, end := len(records), (req.Page-1)*req.PageSize, req.Page*req.PageSize
if start > total {
backDatas = make([]dto.ImageInfo, 0)
Expand All @@ -120,13 +147,12 @@ func (u *ImageService) ListAll() ([]dto.ImageInfo, error) {
}
containers, _ := client.ContainerList(context.Background(), container.ListOptions{All: true})
for _, image := range list {
size := formatFileSize(image.Size)
records = append(records, dto.ImageInfo{
ID: image.ID,
Tags: image.RepoTags,
IsUsed: checkUsed(image.ID, containers),
CreatedAt: time.Unix(image.Created, 0),
Size: size,
Size: image.Size,
})
}
return records, nil
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/api/interface/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ export namespace Container {
option: string;
}

export interface ImageSearch extends ReqPage {
name: string;
orderBy: string;
order: string;
}
export interface ImageInfo {
id: string;
createdAt: Date;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/modules/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const DownloadFile = (params: Container.ContainerLogInfo) => {
};

// image
export const searchImage = (params: SearchWithPage) => {
export const searchImage = (params: Container.ImageSearch) => {
return http.post<ResPage<Container.ImageInfo>>(`/containers/image/search`, params);
};
export const listAllImage = () => {
Expand Down
39 changes: 30 additions & 9 deletions frontend/src/views/container/image/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,35 @@
</el-button>
</template>
<template #rightToolBar>
<TableSearch @search="search()" v-model:searchName="searchName" />
<TableSearch @search="search()" v-model:searchName="paginationConfig.name" />
<TableRefresh @search="search()" />
<TableSetting title="image-refresh" @search="search()" />
</template>
<template #main>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="300">
<ComplexTable
:pagination-config="paginationConfig"
:data="data"
@sort-change="search"
:columns="columns"
@search="search"
:heightDiff="300"
>
<el-table-column label="ID" prop="id" width="140">
<template #default="{ row }">
<el-text type="primary" class="cursor-pointer" @click="onInspect(row.id)">
{{ row.id.replaceAll('sha256:', '').substring(0, 12) }}
</el-text>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="isUsed" width="100">
<el-table-column :label="$t('commons.table.status')" prop="isUsed" width="100" sortable>
<template #default="{ row }">
<Status :status="row.isUsed ? 'used' : 'unused'" />
</template>
</el-table-column>
<el-table-column
:label="$t('container.tag')"
prop="tags"
sortable
min-width="160"
:width="mobile ? 400 : 'auto'"
fix
Expand All @@ -64,8 +72,13 @@
</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('container.size')" prop="size" min-width="60" fix />
<el-table-column :label="$t('container.size')" prop="size" min-width="60" fix sortable>
<template #default="{ row }">
{{ computeSize(row.size) }}
</template>
</el-table-column>
<el-table-column
sortable
prop="createdAt"
min-width="80"
:label="$t('commons.table.date')"
Expand Down Expand Up @@ -113,6 +126,7 @@ import CodemirrorDrawer from '@/components/codemirror-pro/drawer.vue';
import TaskLog from '@/components/log/task/index.vue';
import { searchImage, listImageRepo, imageRemove, inspect, containerPrune } from '@/api/modules/container';
import i18n from '@/lang';
import { computeSize } from '@/utils/util';
import { GlobalStore } from '@/store';
import { ElMessageBox } from 'element-plus';
const globalStore = GlobalStore();
Expand All @@ -133,8 +147,11 @@ const paginationConfig = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
name: '',
orderBy: 'createdAt',
order: 'null',
});
const searchName = ref();
const columns = ref([]);

const isActive = ref(false);
const isExist = ref(false);
Expand All @@ -149,17 +166,21 @@ const dialogBuildRef = ref();
const dialogDeleteRef = ref();
const dialogPruneRef = ref();

const search = async () => {
const search = async (column?: any) => {
if (!isActive.value || !isExist.value) {
return;
}
const repoSearch = {
info: searchName.value,
paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy;
paginationConfig.order = column?.order ? column.order : paginationConfig.order;
const params = {
name: paginationConfig.name,
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
orderBy: paginationConfig.orderBy,
order: paginationConfig.order,
};
loading.value = true;
await searchImage(repoSearch)
await searchImage(params)
.then((res) => {
loading.value = false;
data.value = res.data.items || [];
Expand Down
Loading