mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-10 09:02:42 +08:00
parent
3fb5e523a8
commit
4d279a521e
13 changed files with 77 additions and 46 deletions
|
@ -27,7 +27,6 @@ type ImagePull struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageTag struct {
|
type ImageTag struct {
|
||||||
RepoID uint `json:"repoID"`
|
|
||||||
SourceID string `json:"sourceID" validate:"required"`
|
SourceID string `json:"sourceID" validate:"required"`
|
||||||
TargetName string `json:"targetName" validate:"required"`
|
TargetName string `json:"targetName" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -15460,9 +15460,6 @@ const docTemplate = `{
|
||||||
"targetName"
|
"targetName"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"repoID": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"sourceID": {
|
"sourceID": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -18301,6 +18298,9 @@ const docTemplate = `{
|
||||||
"url"
|
"url"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"ignoreCertificate": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
|
@ -15453,9 +15453,6 @@
|
||||||
"targetName"
|
"targetName"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"repoID": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"sourceID": {
|
"sourceID": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -18294,6 +18291,9 @@
|
||||||
"url"
|
"url"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"ignoreCertificate": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1398,8 +1398,6 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
dto.ImageTag:
|
dto.ImageTag:
|
||||||
properties:
|
properties:
|
||||||
repoID:
|
|
||||||
type: integer
|
|
||||||
sourceID:
|
sourceID:
|
||||||
type: string
|
type: string
|
||||||
targetName:
|
targetName:
|
||||||
|
@ -3300,6 +3298,8 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
request.FileWget:
|
request.FileWget:
|
||||||
properties:
|
properties:
|
||||||
|
ignoreCertificate:
|
||||||
|
type: boolean
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
path:
|
path:
|
||||||
|
|
|
@ -133,7 +133,6 @@ export namespace Container {
|
||||||
imageName: string;
|
imageName: string;
|
||||||
}
|
}
|
||||||
export interface ImageTag {
|
export interface ImageTag {
|
||||||
repoID: number;
|
|
||||||
sourceID: string;
|
sourceID: string;
|
||||||
targetName: string;
|
targetName: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,6 +635,7 @@ const message = {
|
||||||
imagePush: 'Image push',
|
imagePush: 'Image push',
|
||||||
imageDelete: 'Image delete',
|
imageDelete: 'Image delete',
|
||||||
imageDeleteTag: 'Image tag delete',
|
imageDeleteTag: 'Image tag delete',
|
||||||
|
imageTagDeleteHelper: 'Remove other tags associated with this image ID',
|
||||||
repoName: 'Repo Name',
|
repoName: 'Repo Name',
|
||||||
imageName: 'Image name',
|
imageName: 'Image name',
|
||||||
pull: 'Pull',
|
pull: 'Pull',
|
||||||
|
|
|
@ -617,6 +617,7 @@ const message = {
|
||||||
imagePush: '推送鏡像',
|
imagePush: '推送鏡像',
|
||||||
imageDelete: '刪除鏡像',
|
imageDelete: '刪除鏡像',
|
||||||
imageDeleteTag: '刪除 Tag',
|
imageDeleteTag: '刪除 Tag',
|
||||||
|
imageTagDeleteHelper: '移除與該映像 ID 相關聯的其他標籤',
|
||||||
repoName: '倉庫名',
|
repoName: '倉庫名',
|
||||||
imageName: '鏡像名',
|
imageName: '鏡像名',
|
||||||
httpRepo: 'http 倉庫添加授信需要重啟 docker 服務',
|
httpRepo: 'http 倉庫添加授信需要重啟 docker 服務',
|
||||||
|
|
|
@ -618,6 +618,7 @@ const message = {
|
||||||
imagePush: '推送镜像',
|
imagePush: '推送镜像',
|
||||||
imageDelete: '删除镜像',
|
imageDelete: '删除镜像',
|
||||||
imageDeleteTag: '删除 Tag',
|
imageDeleteTag: '删除 Tag',
|
||||||
|
imageTagDeleteHelper: '移除与该镜像 ID 相关联的其他标签',
|
||||||
repoName: '仓库名',
|
repoName: '仓库名',
|
||||||
imageName: '镜像名',
|
imageName: '镜像名',
|
||||||
httpRepo: 'http 仓库添加授信需要重启 docker 服务',
|
httpRepo: 'http 仓库添加授信需要重启 docker 服务',
|
||||||
|
|
|
@ -94,6 +94,8 @@ const acceptParams = (props: DialogProps): void => {
|
||||||
form.hasName = props.image.indexOf('sha256:') === -1;
|
form.hasName = props.image.indexOf('sha256:') === -1;
|
||||||
if (form.hasName) {
|
if (form.hasName) {
|
||||||
form.newImageName = props.image;
|
form.newImageName = props.image;
|
||||||
|
} else {
|
||||||
|
form.newImageName = '';
|
||||||
}
|
}
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
{{ $t('container.removeAll') }}
|
{{ $t('container.removeAll') }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<el-checkbox-group v-model="form.deleteTags" @change="handleCheckedCitiesChange">
|
<el-checkbox-group v-model="form.deleteTags" @change="handleCheckedChange">
|
||||||
<div>
|
<div>
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -91,7 +91,7 @@ const handleCheckAllChange = (val: boolean) => {
|
||||||
form.deleteTags = val ? form.tags : [];
|
form.deleteTags = val ? form.tags : [];
|
||||||
isIndeterminate.value = false;
|
isIndeterminate.value = false;
|
||||||
};
|
};
|
||||||
const handleCheckedCitiesChange = (value: string[]) => {
|
const handleCheckedChange = (value: string[]) => {
|
||||||
const checkedCount = value.length;
|
const checkedCount = value.length;
|
||||||
deleteAll.value = checkedCount === form.tags.length;
|
deleteAll.value = checkedCount === form.tags.length;
|
||||||
isIndeterminate.value = checkedCount > 0 && checkedCount < form.tags.length;
|
isIndeterminate.value = checkedCount > 0 && checkedCount < form.tags.length;
|
||||||
|
|
|
@ -243,9 +243,9 @@ const buttons = [
|
||||||
label: i18n.global.t('container.tag'),
|
label: i18n.global.t('container.tag'),
|
||||||
click: (row: Container.ImageInfo) => {
|
click: (row: Container.ImageInfo) => {
|
||||||
let params = {
|
let params = {
|
||||||
itemName: row.tags && row.tags?.length !== 0 ? row.tags[0].split(':')[0] : '',
|
|
||||||
repos: repos.value,
|
repos: repos.value,
|
||||||
sourceID: row.id,
|
imageID: row.id,
|
||||||
|
tags: row.tags,
|
||||||
};
|
};
|
||||||
dialogTagRef.value!.acceptParams(params);
|
dialogTagRef.value!.acceptParams(params);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="drawerVisible" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
<el-drawer v-model="drawerVisible" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.imageTag')" :resource="form.itemName" :back="handleClose" />
|
<DrawerHeader :header="$t('container.imageTag')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
|
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
|
||||||
<el-row type="flex" justify="center">
|
<el-row type="flex" justify="center">
|
||||||
|
@ -13,16 +13,29 @@
|
||||||
v-if="form.fromRepo"
|
v-if="form.fromRepo"
|
||||||
:label="$t('container.repoName')"
|
:label="$t('container.repoName')"
|
||||||
:rules="Rules.requiredSelect"
|
:rules="Rules.requiredSelect"
|
||||||
prop="repoID"
|
prop="repo"
|
||||||
>
|
>
|
||||||
<el-select style="width: 100%" filterable v-model="form.repoID">
|
<el-select style="width: 100%" filterable v-model="form.repo" @change="changeRepo">
|
||||||
<el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" />
|
<el-option v-for="item in repos" :key="item.id" :value="item.name" :label="item.name" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('container.imageName')" :rules="Rules.imageName" prop="targetName">
|
<el-form-item :label="$t('container.imageTag')" :rules="Rules.imageName" prop="targetName">
|
||||||
<el-input v-model="form.targetName">
|
<el-input v-model="form.targetName" />
|
||||||
<template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
|
</el-form-item>
|
||||||
</el-input>
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-checkbox style="width: 100%" v-model="form.deleteTag">
|
||||||
|
{{ $t('container.imageTagDeleteHelper') }}
|
||||||
|
</el-checkbox>
|
||||||
|
<el-checkbox-group class="ml-5" v-if="form.deleteTag" v-model="form.deleteTags">
|
||||||
|
<el-checkbox
|
||||||
|
style="width: 100%"
|
||||||
|
v-for="item in tags"
|
||||||
|
:key="item"
|
||||||
|
:value="item"
|
||||||
|
:label="item"
|
||||||
|
/>
|
||||||
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -46,7 +59,7 @@ import { reactive, ref } from 'vue';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { ElForm } from 'element-plus';
|
import { ElForm } from 'element-plus';
|
||||||
import { imageTag } from '@/api/modules/container';
|
import { imageRemove, imageTag } from '@/api/modules/container';
|
||||||
import { Container } from '@/api/interface/container';
|
import { Container } from '@/api/interface/container';
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
@ -55,28 +68,35 @@ const loading = ref(false);
|
||||||
|
|
||||||
const drawerVisible = ref(false);
|
const drawerVisible = ref(false);
|
||||||
const repos = ref();
|
const repos = ref();
|
||||||
|
const tags = ref();
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
itemName: '',
|
imageID: '',
|
||||||
sourceID: '',
|
fromRepo: false,
|
||||||
fromRepo: true,
|
repo: '',
|
||||||
repoID: 1,
|
originName: '',
|
||||||
targetName: '',
|
targetName: '',
|
||||||
|
|
||||||
|
deleteTag: false,
|
||||||
|
deleteTags: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
itemName: string;
|
|
||||||
repos: Array<Container.RepoOptions>;
|
repos: Array<Container.RepoOptions>;
|
||||||
sourceID: string;
|
imageID: string;
|
||||||
|
tags: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const acceptParams = async (params: DialogProps): Promise<void> => {
|
const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
form.repoID = 1;
|
form.imageID = params.imageID;
|
||||||
form.itemName = params.itemName;
|
form.originName = params.tags?.length !== 0 ? params.tags[0] : '';
|
||||||
form.sourceID = params.sourceID;
|
form.targetName = params.tags?.length !== 0 ? params.tags[0] : '';
|
||||||
form.targetName = '';
|
form.fromRepo = false;
|
||||||
form.fromRepo = true;
|
form.repo = '';
|
||||||
|
form.deleteTag = false;
|
||||||
|
form.deleteTags = [];
|
||||||
repos.value = params.repos;
|
repos.value = params.repos;
|
||||||
|
tags.value = params.tags;
|
||||||
};
|
};
|
||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
|
|
||||||
|
@ -91,13 +111,17 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
formEl.validate(async (valid) => {
|
formEl.validate(async (valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (!form.fromRepo) {
|
let params = {
|
||||||
form.repoID = 0;
|
sourceID: form.imageID,
|
||||||
}
|
targetName: form.targetName,
|
||||||
|
};
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await imageTag(form)
|
await imageTag(params)
|
||||||
.then(() => {
|
.then(async () => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
if (form.deleteTag && form.deleteTags.length !== 0) {
|
||||||
|
await imageRemove({ names: form.deleteTags });
|
||||||
|
}
|
||||||
drawerVisible.value = false;
|
drawerVisible.value = false;
|
||||||
emit('search');
|
emit('search');
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
@ -108,14 +132,18 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadDetailInfo(id: number) {
|
const changeRepo = (val) => {
|
||||||
|
if (val === 'Docker Hub') {
|
||||||
|
form.targetName = form.originName;
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (const item of repos.value) {
|
for (const item of repos.value) {
|
||||||
if (item.id === id) {
|
if (item.name == val) {
|
||||||
return item.downloadUrl;
|
form.targetName = item.downloadUrl + '/' + form.originName;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '';
|
};
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
acceptParams,
|
acceptParams,
|
||||||
|
|
|
@ -147,7 +147,7 @@ const loadData = (path: string) => {
|
||||||
item.size = itemSize.size;
|
item.size = itemSize.size;
|
||||||
item.sizeUnit = itemSize.unit;
|
item.sizeUnit = itemSize.unit;
|
||||||
}
|
}
|
||||||
if (!isExist && path !== '') {
|
if (!isExist) {
|
||||||
form.swapDetails.push({
|
form.swapDetails.push({
|
||||||
path: path + '/.1panel_swap',
|
path: path + '/.1panel_swap',
|
||||||
size: 0,
|
size: 0,
|
||||||
|
|
Loading…
Reference in a new issue