2022-09-04 17:06:11 +00:00
|
|
|
<script lang="ts" setup>
|
|
|
|
// core libs
|
2022-11-18 07:22:22 +00:00
|
|
|
import { onMounted, ref, watch } from "vue";
|
2022-09-04 17:06:11 +00:00
|
|
|
|
|
|
|
// components
|
2022-11-18 07:22:22 +00:00
|
|
|
import {
|
|
|
|
Dialog,
|
|
|
|
IconAddCircle,
|
|
|
|
IconMore,
|
|
|
|
Toast,
|
2023-03-27 08:06:13 +00:00
|
|
|
VDropdown,
|
|
|
|
VDropdownItem,
|
2022-11-18 07:22:22 +00:00
|
|
|
VStatusDot,
|
|
|
|
} from "@halo-dev/components";
|
2022-09-04 17:06:11 +00:00
|
|
|
import AttachmentGroupEditingModal from "./AttachmentGroupEditingModal.vue";
|
|
|
|
|
|
|
|
// types
|
|
|
|
import type { Group } from "@halo-dev/api-client";
|
|
|
|
|
|
|
|
import { useRouteQuery } from "@vueuse/router";
|
|
|
|
import { useFetchAttachmentGroup } from "../composables/use-attachment-group";
|
2022-11-18 07:22:22 +00:00
|
|
|
import { apiClient } from "@/utils/api-client";
|
2023-03-23 08:54:33 +00:00
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
|
|
|
|
const { t } = useI18n();
|
2022-09-04 17:06:11 +00:00
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
defineProps<{
|
|
|
|
selectedGroup: Group | undefined;
|
|
|
|
readonly?: boolean;
|
|
|
|
}>(),
|
|
|
|
{
|
|
|
|
selectedGroup: undefined,
|
|
|
|
readonly: false,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
(event: "update:selectedGroup", group: Group): void;
|
|
|
|
(event: "select", group: Group): void;
|
|
|
|
(event: "update"): void;
|
2022-11-18 07:22:22 +00:00
|
|
|
(event: "reload-attachments"): void;
|
2022-09-04 17:06:11 +00:00
|
|
|
}>();
|
|
|
|
|
|
|
|
const defaultGroups: Group[] = [
|
|
|
|
{
|
|
|
|
spec: {
|
2023-03-23 08:54:33 +00:00
|
|
|
displayName: t("core.attachment.group_list.internal_groups.all"),
|
2022-09-04 17:06:11 +00:00
|
|
|
},
|
|
|
|
apiVersion: "",
|
|
|
|
kind: "",
|
|
|
|
metadata: {
|
|
|
|
name: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
spec: {
|
2023-03-23 08:54:33 +00:00
|
|
|
displayName: t("core.attachment.common.text.ungrouped"),
|
2022-09-04 17:06:11 +00:00
|
|
|
},
|
|
|
|
apiVersion: "",
|
|
|
|
kind: "",
|
|
|
|
metadata: {
|
2022-11-24 13:17:05 +00:00
|
|
|
name: "ungrouped",
|
2022-09-04 17:06:11 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const { groups, handleFetchGroups } = useFetchAttachmentGroup();
|
|
|
|
|
|
|
|
const groupToUpdate = ref<Group | null>(null);
|
|
|
|
const loading = ref<boolean>(false);
|
|
|
|
const editingModal = ref(false);
|
|
|
|
|
2022-11-24 13:17:05 +00:00
|
|
|
const routeQuery = useRouteQuery<string>("group");
|
2022-09-04 17:06:11 +00:00
|
|
|
|
|
|
|
const handleSelectGroup = (group: Group) => {
|
|
|
|
emit("update:selectedGroup", group);
|
|
|
|
emit("select", group);
|
|
|
|
|
|
|
|
if (!props.readonly) {
|
|
|
|
routeQuery.value = group.metadata.name;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleOpenEditingModal = (group: Group) => {
|
|
|
|
groupToUpdate.value = group;
|
|
|
|
editingModal.value = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
const onEditingModalClose = () => {
|
|
|
|
emit("update");
|
|
|
|
handleFetchGroups();
|
|
|
|
};
|
|
|
|
|
2022-11-18 07:22:22 +00:00
|
|
|
const handleDelete = (group: Group) => {
|
|
|
|
Dialog.warning({
|
2023-03-23 08:54:33 +00:00
|
|
|
title: t("core.attachment.group_list.operations.delete.title"),
|
2024-03-27 14:20:07 +00:00
|
|
|
description: t("core.attachment.group_list.operations.delete.description"),
|
2022-11-18 07:22:22 +00:00
|
|
|
confirmType: "danger",
|
2023-03-23 08:54:33 +00:00
|
|
|
confirmText: t("core.common.buttons.confirm"),
|
|
|
|
cancelText: t("core.common.buttons.cancel"),
|
2022-11-18 07:22:22 +00:00
|
|
|
onConfirm: async () => {
|
|
|
|
// TODO: 后续将修改为在后端进行批量操作处理
|
|
|
|
const { data } = await apiClient.attachment.searchAttachments({
|
2024-02-20 02:58:09 +00:00
|
|
|
fieldSelector: [`spec.groupName=${group.metadata.name}`],
|
2022-11-18 07:22:22 +00:00
|
|
|
page: 0,
|
|
|
|
size: 0,
|
|
|
|
});
|
|
|
|
|
|
|
|
await apiClient.extension.storage.group.deletestorageHaloRunV1alpha1Group(
|
|
|
|
{ name: group.metadata.name }
|
|
|
|
);
|
|
|
|
|
|
|
|
// move attachments to none group
|
|
|
|
const moveToUnGroupRequests = data.items.map((attachment) => {
|
2022-11-30 02:23:46 +00:00
|
|
|
attachment.spec.groupName = undefined;
|
2022-11-18 07:22:22 +00:00
|
|
|
return apiClient.extension.storage.attachment.updatestorageHaloRunV1alpha1Attachment(
|
|
|
|
{
|
|
|
|
name: attachment.metadata.name,
|
|
|
|
attachment: attachment,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
await Promise.all(moveToUnGroupRequests);
|
|
|
|
|
|
|
|
handleFetchGroups();
|
|
|
|
emit("reload-attachments");
|
|
|
|
emit("update");
|
|
|
|
|
2023-03-23 08:54:33 +00:00
|
|
|
Toast.success(
|
|
|
|
t("core.attachment.group_list.operations.delete.toast_success", {
|
|
|
|
total: data.total,
|
|
|
|
})
|
|
|
|
);
|
2022-11-18 07:22:22 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleDeleteWithAttachments = (group: Group) => {
|
|
|
|
Dialog.warning({
|
2023-03-23 08:54:33 +00:00
|
|
|
title: t(
|
|
|
|
"core.attachment.group_list.operations.delete_with_attachments.title"
|
|
|
|
),
|
|
|
|
description: t(
|
|
|
|
"core.attachment.group_list.operations.delete_with_attachments.description"
|
|
|
|
),
|
2022-11-18 07:22:22 +00:00
|
|
|
confirmType: "danger",
|
2023-03-23 08:54:33 +00:00
|
|
|
confirmText: t("core.common.buttons.confirm"),
|
|
|
|
cancelText: t("core.common.buttons.cancel"),
|
2022-11-18 07:22:22 +00:00
|
|
|
onConfirm: async () => {
|
|
|
|
// TODO: 后续将修改为在后端进行批量操作处理
|
|
|
|
const { data } = await apiClient.attachment.searchAttachments({
|
2024-02-20 02:58:09 +00:00
|
|
|
fieldSelector: [`spec.groupName=${group.metadata.name}`],
|
2022-11-18 07:22:22 +00:00
|
|
|
page: 0,
|
|
|
|
size: 0,
|
|
|
|
});
|
|
|
|
|
|
|
|
await apiClient.extension.storage.group.deletestorageHaloRunV1alpha1Group(
|
|
|
|
{ name: group.metadata.name }
|
|
|
|
);
|
|
|
|
|
|
|
|
const deleteAttachmentRequests = data.items.map((attachment) => {
|
|
|
|
return apiClient.extension.storage.attachment.deletestorageHaloRunV1alpha1Attachment(
|
|
|
|
{ name: attachment.metadata.name }
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
await Promise.all(deleteAttachmentRequests);
|
|
|
|
|
|
|
|
handleFetchGroups();
|
|
|
|
emit("reload-attachments");
|
|
|
|
emit("update");
|
|
|
|
|
2023-03-23 08:54:33 +00:00
|
|
|
Toast.success(
|
|
|
|
t(
|
|
|
|
"core.attachment.group_list.operations.delete_with_attachments.toast_success",
|
|
|
|
{ total: data.total }
|
|
|
|
)
|
|
|
|
);
|
2022-11-18 07:22:22 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
watch(
|
2023-02-23 09:08:12 +00:00
|
|
|
() => groups.value?.length,
|
2022-11-18 07:22:22 +00:00
|
|
|
() => {
|
2023-02-23 09:08:12 +00:00
|
|
|
const allGroups = [...defaultGroups, ...(groups.value || [])];
|
2022-11-24 13:17:05 +00:00
|
|
|
const groupIndex = allGroups.findIndex(
|
2022-11-18 07:22:22 +00:00
|
|
|
(group) => group.metadata.name === routeQuery.value
|
|
|
|
);
|
|
|
|
|
|
|
|
if (groupIndex < 0) {
|
|
|
|
handleSelectGroup(defaultGroups[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2022-09-04 17:06:11 +00:00
|
|
|
onMounted(async () => {
|
|
|
|
await handleFetchGroups();
|
|
|
|
if (routeQuery.value && !props.readonly) {
|
2023-02-23 09:08:12 +00:00
|
|
|
const allGroups = [...defaultGroups, ...(groups.value || [])];
|
2022-09-04 17:06:11 +00:00
|
|
|
const group = allGroups.find(
|
|
|
|
(group) => group.metadata.name === routeQuery.value
|
|
|
|
);
|
|
|
|
if (group) {
|
|
|
|
handleSelectGroup(group);
|
2022-11-24 13:17:05 +00:00
|
|
|
return;
|
2022-09-04 17:06:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleSelectGroup(defaultGroups[0]);
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
<template>
|
|
|
|
<AttachmentGroupEditingModal
|
2022-11-01 03:06:18 +00:00
|
|
|
v-if="!readonly"
|
2022-09-04 17:06:11 +00:00
|
|
|
v-model:visible="editingModal"
|
|
|
|
:group="groupToUpdate"
|
|
|
|
@close="onEditingModalClose"
|
|
|
|
/>
|
|
|
|
<div class="mb-5 grid grid-cols-2 gap-x-2 gap-y-3 sm:grid-cols-6">
|
|
|
|
<div
|
|
|
|
v-for="(defaultGroup, index) in defaultGroups"
|
|
|
|
:key="index"
|
|
|
|
:class="{
|
|
|
|
'!bg-gray-200 !text-gray-900':
|
|
|
|
defaultGroup.metadata.name === selectedGroup?.metadata.name,
|
|
|
|
}"
|
|
|
|
class="flex cursor-pointer items-center rounded-base bg-gray-100 p-2 text-gray-500 transition-all hover:bg-gray-200 hover:text-gray-900 hover:shadow-sm"
|
|
|
|
@click="handleSelectGroup(defaultGroup)"
|
|
|
|
>
|
|
|
|
<div class="flex flex-1 items-center">
|
|
|
|
<span class="text-sm">{{ defaultGroup.spec.displayName }}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-for="(group, index) in groups"
|
|
|
|
:key="index"
|
|
|
|
:class="{
|
|
|
|
'!bg-gray-200 !text-gray-900':
|
|
|
|
group.metadata.name === selectedGroup?.metadata.name,
|
|
|
|
}"
|
|
|
|
class="flex cursor-pointer items-center rounded-base bg-gray-100 p-2 text-gray-500 transition-all hover:bg-gray-200 hover:text-gray-900 hover:shadow-sm"
|
|
|
|
@click="handleSelectGroup(group)"
|
|
|
|
>
|
2022-11-18 07:22:22 +00:00
|
|
|
<div class="flex flex-1 items-center gap-2 truncate">
|
2022-09-04 17:06:11 +00:00
|
|
|
<span class="truncate text-sm">
|
|
|
|
{{ group.spec.displayName }}
|
|
|
|
</span>
|
2022-11-18 07:22:22 +00:00
|
|
|
<VStatusDot
|
|
|
|
v-if="group.metadata.deletionTimestamp"
|
2023-03-23 08:54:33 +00:00
|
|
|
v-tooltip="$t('core.common.status.deleting')"
|
2022-11-18 07:22:22 +00:00
|
|
|
state="warning"
|
|
|
|
animate
|
|
|
|
/>
|
2022-09-04 17:06:11 +00:00
|
|
|
</div>
|
2023-03-27 08:06:13 +00:00
|
|
|
<VDropdown v-if="!readonly" v-permission="['system:attachments:manage']">
|
2022-09-09 13:48:07 +00:00
|
|
|
<IconMore @click.stop />
|
2022-09-04 17:06:11 +00:00
|
|
|
<template #popper>
|
2023-03-27 08:06:13 +00:00
|
|
|
<VDropdownItem @click="handleOpenEditingModal(group)">
|
|
|
|
{{ $t("core.attachment.group_list.operations.rename.button") }}
|
|
|
|
</VDropdownItem>
|
|
|
|
<VDropdown placement="right" :triggers="['click']">
|
|
|
|
<VDropdownItem type="danger">
|
|
|
|
{{ $t("core.common.buttons.delete") }}
|
|
|
|
</VDropdownItem>
|
|
|
|
<template #popper>
|
2023-06-26 13:21:57 +00:00
|
|
|
<VDropdownItem type="danger" @click="handleDelete(group)">
|
2023-03-27 08:06:13 +00:00
|
|
|
{{ $t("core.attachment.group_list.operations.delete.button") }}
|
|
|
|
</VDropdownItem>
|
|
|
|
<VDropdownItem
|
|
|
|
type="danger"
|
|
|
|
@click="handleDeleteWithAttachments(group)"
|
2022-11-18 07:22:22 +00:00
|
|
|
>
|
2023-03-27 08:06:13 +00:00
|
|
|
{{
|
|
|
|
$t(
|
|
|
|
"core.attachment.group_list.operations.delete_with_attachments.button"
|
|
|
|
)
|
|
|
|
}}
|
|
|
|
</VDropdownItem>
|
|
|
|
</template>
|
|
|
|
</VDropdown>
|
2022-09-04 17:06:11 +00:00
|
|
|
</template>
|
2023-03-27 08:06:13 +00:00
|
|
|
</VDropdown>
|
2022-09-04 17:06:11 +00:00
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-if="!loading && !readonly"
|
2022-09-30 09:48:19 +00:00
|
|
|
v-permission="['system:attachments:manage']"
|
2022-09-04 17:06:11 +00:00
|
|
|
class="flex cursor-pointer items-center rounded-base bg-gray-100 p-2 text-gray-500 transition-all hover:bg-gray-200 hover:text-gray-900 hover:shadow-sm"
|
|
|
|
@click="editingModal = true"
|
|
|
|
>
|
|
|
|
<div class="flex flex-1 items-center truncate">
|
2023-03-23 08:54:33 +00:00
|
|
|
<span class="truncate text-sm">
|
|
|
|
{{ $t("core.common.buttons.new") }}
|
|
|
|
</span>
|
2022-09-04 17:06:11 +00:00
|
|
|
</div>
|
|
|
|
<IconAddCircle />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|