mirror of https://github.com/halo-dev/halo
refactor: improve code base of attachment-related (#5967)
#### What type of PR is this? /area ui /kind improvement /milestone 2.16.x #### What this PR does / why we need it: 优化附件管理的相关代码。 1. 优化附件管理相关的对话框组件,减少重复和不必要的请求。 2. 简化附件存储策略编辑组件的逻辑。 #### Special notes for your reviewer: 需要测试: 1. 附件上传的相关功能。 2. 附件存储策略的编辑和新建。 3. 附件筛选条件功能。 #### Does this PR introduce a user-facing change? ```release-note 优化附件管理相关代码,减少重复和不必要的请求。 ```pull/5975/head
parent
ce5757ae10
commit
89b20bf5a3
|
@ -2,185 +2,11 @@
|
||||||
// types
|
// types
|
||||||
import { computed, watch, type ComputedRef, type Ref } from "vue";
|
import { computed, watch, type ComputedRef, type Ref } from "vue";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { apiClient } from "@/utils/api-client";
|
|
||||||
|
|
||||||
// libs
|
// libs
|
||||||
import { cloneDeep, merge } from "lodash-es";
|
import { cloneDeep } from "lodash-es";
|
||||||
import type { ConfigMap, Setting, SettingForm } from "@halo-dev/api-client";
|
import type { ConfigMap, Setting, SettingForm } from "@halo-dev/api-client";
|
||||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||||
import { Toast } from "@halo-dev/components";
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
|
|
||||||
const initialConfigMap: ConfigMap = {
|
|
||||||
apiVersion: "v1alpha1",
|
|
||||||
kind: "ConfigMap",
|
|
||||||
metadata: {
|
|
||||||
name: "",
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
interface useSettingFormReturn {
|
|
||||||
setting: Ref<Setting | undefined>;
|
|
||||||
configMap: Ref<ConfigMap>;
|
|
||||||
configMapFormData: Ref<Record<string, Record<string, string>> | undefined>;
|
|
||||||
saving: Ref<boolean>;
|
|
||||||
handleFetchSettings: () => void;
|
|
||||||
handleFetchConfigMap: () => void;
|
|
||||||
handleSaveConfigMap: () => void;
|
|
||||||
handleReset: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useSettingForm(
|
|
||||||
settingName: Ref<string | undefined>,
|
|
||||||
configMapName: Ref<string | undefined>
|
|
||||||
): useSettingFormReturn {
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const setting = ref<Setting>();
|
|
||||||
const configMap = ref<ConfigMap>(cloneDeep(initialConfigMap));
|
|
||||||
const configMapFormData = ref<
|
|
||||||
Record<string, Record<string, string>> | undefined
|
|
||||||
>();
|
|
||||||
|
|
||||||
const saving = ref(false);
|
|
||||||
|
|
||||||
const handleFetchSettings = async () => {
|
|
||||||
if (!settingName.value) {
|
|
||||||
setting.value = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const { data } = await apiClient.extension.setting.getv1alpha1Setting({
|
|
||||||
name: settingName.value,
|
|
||||||
});
|
|
||||||
setting.value = data;
|
|
||||||
|
|
||||||
// init configMapFormData
|
|
||||||
if (!configMapFormData.value) {
|
|
||||||
const { forms } = setting.value.spec;
|
|
||||||
const initialConfigMapFormData: Record<
|
|
||||||
string,
|
|
||||||
Record<string, string>
|
|
||||||
> = {};
|
|
||||||
forms.forEach((form) => {
|
|
||||||
initialConfigMapFormData[form.group] = {};
|
|
||||||
const formSchema = form.formSchema as (
|
|
||||||
| FormKitSchemaCondition
|
|
||||||
| FormKitSchemaNode
|
|
||||||
)[];
|
|
||||||
formSchema.forEach((schema) => {
|
|
||||||
// @ts-ignore
|
|
||||||
if ("name" in schema && "$formkit" in schema) {
|
|
||||||
initialConfigMapFormData[form.group][schema.name] =
|
|
||||||
schema.value || undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
configMapFormData.value = cloneDeep(initialConfigMapFormData);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to fetch setting", e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFetchConfigMap = async () => {
|
|
||||||
if (!configMapName.value) {
|
|
||||||
configMap.value = cloneDeep(initialConfigMap);
|
|
||||||
configMapFormData.value = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const response = await apiClient.extension.configMap.getv1alpha1ConfigMap(
|
|
||||||
{
|
|
||||||
name: configMapName.value,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mute: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
configMap.value = response.data;
|
|
||||||
|
|
||||||
const { data } = configMap.value;
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
// merge objects value
|
|
||||||
const { forms } = setting.value?.spec || {};
|
|
||||||
|
|
||||||
forms?.forEach((form) => {
|
|
||||||
if (!configMapFormData.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
configMapFormData.value[form.group] = merge(
|
|
||||||
configMapFormData.value[form.group] || {},
|
|
||||||
JSON.parse(data[form.group] || "{}")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to fetch configMap", e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveConfigMap = async () => {
|
|
||||||
try {
|
|
||||||
saving.value = true;
|
|
||||||
|
|
||||||
if (!configMap.value.metadata.name && configMapName.value) {
|
|
||||||
configMap.value.metadata.name = configMapName.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
setting.value?.spec.forms.forEach((item: SettingForm) => {
|
|
||||||
// @ts-ignore
|
|
||||||
configMap.value.data[item.group] = JSON.stringify(
|
|
||||||
configMapFormData?.value?.[item.group]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!configMap.value.metadata.creationTimestamp) {
|
|
||||||
const { data } =
|
|
||||||
await apiClient.extension.configMap.createv1alpha1ConfigMap({
|
|
||||||
configMap: configMap.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
configMapName.value = data.metadata.name;
|
|
||||||
} else {
|
|
||||||
const { data } =
|
|
||||||
await apiClient.extension.configMap.updatev1alpha1ConfigMap({
|
|
||||||
configMap: configMap.value,
|
|
||||||
name: configMap.value.metadata.name,
|
|
||||||
});
|
|
||||||
configMapName.value = data.metadata.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toast.success(t("core.common.toast.save_success"));
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to save configMap", e);
|
|
||||||
} finally {
|
|
||||||
await handleFetchSettings();
|
|
||||||
await handleFetchConfigMap();
|
|
||||||
saving.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
setting.value = undefined;
|
|
||||||
configMap.value = cloneDeep(initialConfigMap);
|
|
||||||
configMapFormData.value = undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
setting,
|
|
||||||
configMap,
|
|
||||||
configMapFormData,
|
|
||||||
saving,
|
|
||||||
handleFetchSettings,
|
|
||||||
handleFetchConfigMap,
|
|
||||||
handleSaveConfigMap,
|
|
||||||
handleReset,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface useSettingFormConvertReturn {
|
interface useSettingFormConvertReturn {
|
||||||
formSchema: ComputedRef<
|
formSchema: ComputedRef<
|
||||||
|
|
|
@ -4,28 +4,29 @@ import {
|
||||||
IconArrowRight,
|
IconArrowRight,
|
||||||
IconCheckboxFill,
|
IconCheckboxFill,
|
||||||
IconDatabase2Line,
|
IconDatabase2Line,
|
||||||
|
IconFolder,
|
||||||
IconGrid,
|
IconGrid,
|
||||||
IconList,
|
IconList,
|
||||||
IconUpload,
|
|
||||||
IconRefreshLine,
|
IconRefreshLine,
|
||||||
|
IconUpload,
|
||||||
|
Toast,
|
||||||
VButton,
|
VButton,
|
||||||
VCard,
|
VCard,
|
||||||
|
VDropdown,
|
||||||
|
VDropdownItem,
|
||||||
|
VEmpty,
|
||||||
|
VLoading,
|
||||||
VPageHeader,
|
VPageHeader,
|
||||||
VPagination,
|
VPagination,
|
||||||
VSpace,
|
VSpace,
|
||||||
VEmpty,
|
|
||||||
IconFolder,
|
|
||||||
VLoading,
|
|
||||||
Toast,
|
|
||||||
VDropdown,
|
|
||||||
VDropdownItem,
|
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import LazyImage from "@/components/image/LazyImage.vue";
|
import LazyImage from "@/components/image/LazyImage.vue";
|
||||||
import AttachmentDetailModal from "./components/AttachmentDetailModal.vue";
|
import AttachmentDetailModal from "./components/AttachmentDetailModal.vue";
|
||||||
import AttachmentUploadModal from "./components/AttachmentUploadModal.vue";
|
import AttachmentUploadModal from "./components/AttachmentUploadModal.vue";
|
||||||
import AttachmentPoliciesModal from "./components/AttachmentPoliciesModal.vue";
|
import AttachmentPoliciesModal from "./components/AttachmentPoliciesModal.vue";
|
||||||
import AttachmentGroupList from "./components/AttachmentGroupList.vue";
|
import AttachmentGroupList from "./components/AttachmentGroupList.vue";
|
||||||
import { computed, onMounted, ref, watch } from "vue";
|
import type { Ref } from "vue";
|
||||||
|
import { computed, onMounted, provide, ref, watch } from "vue";
|
||||||
import type { Attachment, Group } from "@halo-dev/api-client";
|
import type { Attachment, Group } from "@halo-dev/api-client";
|
||||||
import { useFetchAttachmentPolicy } from "./composables/use-attachment-policy";
|
import { useFetchAttachmentPolicy } from "./composables/use-attachment-policy";
|
||||||
import { useAttachmentControl } from "./composables/use-attachment";
|
import { useAttachmentControl } from "./composables/use-attachment";
|
||||||
|
@ -37,8 +38,6 @@ import { useFetchAttachmentGroup } from "./composables/use-attachment-group";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
import UserFilterDropdown from "@/components/filter/UserFilterDropdown.vue";
|
import UserFilterDropdown from "@/components/filter/UserFilterDropdown.vue";
|
||||||
import { provide } from "vue";
|
|
||||||
import type { Ref } from "vue";
|
|
||||||
import AttachmentListItem from "./components/AttachmentListItem.vue";
|
import AttachmentListItem from "./components/AttachmentListItem.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -50,7 +49,7 @@ const detailVisible = ref(false);
|
||||||
const { policies } = useFetchAttachmentPolicy();
|
const { policies } = useFetchAttachmentPolicy();
|
||||||
const { groups, handleFetchGroups } = useFetchAttachmentGroup();
|
const { groups, handleFetchGroups } = useFetchAttachmentGroup();
|
||||||
|
|
||||||
const selectedGroup = ref<Group>();
|
const selectedGroup = useRouteQuery<string | undefined>("group");
|
||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
const keyword = useRouteQuery<string>("keyword", "");
|
const keyword = useRouteQuery<string>("keyword", "");
|
||||||
|
@ -111,12 +110,8 @@ const {
|
||||||
isChecked,
|
isChecked,
|
||||||
handleReset,
|
handleReset,
|
||||||
} = useAttachmentControl({
|
} = useAttachmentControl({
|
||||||
group: selectedGroup,
|
groupName: selectedGroup,
|
||||||
policy: computed(() => {
|
policyName: selectedPolicy,
|
||||||
return policies.value?.find(
|
|
||||||
(policy) => policy.metadata.name === selectedPolicy.value
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
user: selectedUser,
|
user: selectedUser,
|
||||||
accepts: computed(() => {
|
accepts: computed(() => {
|
||||||
if (!selectedAccepts.value) {
|
if (!selectedAccepts.value) {
|
||||||
|
@ -187,6 +182,7 @@ const onDetailModalClose = () => {
|
||||||
const onUploadModalClose = () => {
|
const onUploadModalClose = () => {
|
||||||
routeQueryAction.value = undefined;
|
routeQueryAction.value = undefined;
|
||||||
handleFetchAttachments();
|
handleFetchAttachments();
|
||||||
|
uploadVisible.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// View type
|
// View type
|
||||||
|
@ -258,11 +254,11 @@ onMounted(() => {
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</AttachmentDetailModal>
|
</AttachmentDetailModal>
|
||||||
<AttachmentUploadModal
|
<AttachmentUploadModal v-if="uploadVisible" @close="onUploadModalClose" />
|
||||||
v-model:visible="uploadVisible"
|
<AttachmentPoliciesModal
|
||||||
@close="onUploadModalClose"
|
v-if="policyVisible"
|
||||||
|
@close="policyVisible = false"
|
||||||
/>
|
/>
|
||||||
<AttachmentPoliciesModal v-model:visible="policyVisible" />
|
|
||||||
<VPageHeader :title="$t('core.attachment.title')">
|
<VPageHeader :title="$t('core.attachment.title')">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<IconFolder class="mr-2 self-center" />
|
<IconFolder class="mr-2 self-center" />
|
||||||
|
@ -470,7 +466,6 @@ onMounted(() => {
|
||||||
|
|
||||||
<div :style="`${viewType === 'list' ? 'padding:12px 16px 0' : ''}`">
|
<div :style="`${viewType === 'list' ? 'padding:12px 16px 0' : ''}`">
|
||||||
<AttachmentGroupList
|
<AttachmentGroupList
|
||||||
v-model:selected-group="selectedGroup"
|
|
||||||
@select="handleReset"
|
@select="handleReset"
|
||||||
@update="handleFetchGroups"
|
@update="handleFetchGroups"
|
||||||
@reload-attachments="handleFetchAttachments"
|
@reload-attachments="handleFetchAttachments"
|
||||||
|
|
|
@ -2,32 +2,29 @@
|
||||||
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
||||||
import SubmitButton from "@/components/button/SubmitButton.vue";
|
import SubmitButton from "@/components/button/SubmitButton.vue";
|
||||||
import type { Group } from "@halo-dev/api-client";
|
import type { Group } from "@halo-dev/api-client";
|
||||||
import { computed, ref, watch } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { cloneDeep } from "lodash-es";
|
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import { reset } from "@formkit/core";
|
|
||||||
import { setFocus } from "@/formkit/utils/focus";
|
import { setFocus } from "@/formkit/utils/focus";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { cloneDeep } from "lodash-es";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
visible: boolean;
|
group?: Group;
|
||||||
group: Group | null;
|
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
visible: false,
|
group: undefined,
|
||||||
group: null,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "update:visible", visible: boolean): void;
|
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const initialFormState: Group = {
|
const modal = ref();
|
||||||
|
const formState = ref<Group>({
|
||||||
spec: {
|
spec: {
|
||||||
displayName: "",
|
displayName: "",
|
||||||
},
|
},
|
||||||
|
@ -37,25 +34,17 @@ const initialFormState: Group = {
|
||||||
name: "",
|
name: "",
|
||||||
generateName: "attachment-group-",
|
generateName: "attachment-group-",
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
const formState = ref<Group>(cloneDeep(initialFormState));
|
|
||||||
const saving = ref(false);
|
const saving = ref(false);
|
||||||
|
|
||||||
const isUpdateMode = computed(() => {
|
const modalTitle = props.group
|
||||||
return !!formState.value.metadata.creationTimestamp;
|
|
||||||
});
|
|
||||||
|
|
||||||
const modalTitle = computed(() => {
|
|
||||||
return isUpdateMode.value
|
|
||||||
? t("core.attachment.group_editing_modal.titles.update")
|
? t("core.attachment.group_editing_modal.titles.update")
|
||||||
: t("core.attachment.group_editing_modal.titles.create");
|
: t("core.attachment.group_editing_modal.titles.create");
|
||||||
});
|
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
try {
|
try {
|
||||||
saving.value = true;
|
saving.value = true;
|
||||||
if (isUpdateMode.value) {
|
if (props.group) {
|
||||||
await apiClient.extension.storage.group.updatestorageHaloRunV1alpha1Group(
|
await apiClient.extension.storage.group.updatestorageHaloRunV1alpha1Group(
|
||||||
{
|
{
|
||||||
name: formState.value.metadata.name,
|
name: formState.value.metadata.name,
|
||||||
|
@ -71,7 +60,7 @@ const handleSave = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
Toast.success(t("core.common.toast.save_success"));
|
Toast.success(t("core.common.toast.save_success"));
|
||||||
onVisibleChange(false);
|
modal.value.close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to save attachment group", e);
|
console.error("Failed to save attachment group", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -79,47 +68,16 @@ const handleSave = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVisibleChange = (visible: boolean) => {
|
onMounted(() => {
|
||||||
emit("update:visible", visible);
|
|
||||||
if (!visible) {
|
|
||||||
emit("close");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleResetForm = () => {
|
|
||||||
formState.value = cloneDeep(initialFormState);
|
|
||||||
reset("attachment-group-form");
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.visible,
|
|
||||||
(visible) => {
|
|
||||||
if (visible) {
|
|
||||||
setFocus("displayNameInput");
|
setFocus("displayNameInput");
|
||||||
} else {
|
|
||||||
handleResetForm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
if (props.group) {
|
||||||
() => props.group,
|
formState.value = cloneDeep(props.group);
|
||||||
(group) => {
|
|
||||||
if (group) {
|
|
||||||
formState.value = cloneDeep(group);
|
|
||||||
} else {
|
|
||||||
handleResetForm();
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VModal
|
<VModal ref="modal" :title="modalTitle" :width="500" @close="emit('close')">
|
||||||
:title="modalTitle"
|
|
||||||
:visible="visible"
|
|
||||||
:width="500"
|
|
||||||
@update:visible="onVisibleChange"
|
|
||||||
>
|
|
||||||
<FormKit
|
<FormKit
|
||||||
id="attachment-group-form"
|
id="attachment-group-form"
|
||||||
name="attachment-group-form"
|
name="attachment-group-form"
|
||||||
|
@ -142,14 +100,13 @@ watch(
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<VSpace>
|
<VSpace>
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
v-if="visible"
|
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
type="secondary"
|
type="secondary"
|
||||||
:text="$t('core.common.buttons.submit')"
|
:text="$t('core.common.buttons.submit')"
|
||||||
@submit="$formkit.submit('attachment-group-form')"
|
@submit="$formkit.submit('attachment-group-form')"
|
||||||
>
|
>
|
||||||
</SubmitButton>
|
</SubmitButton>
|
||||||
<VButton @click="onVisibleChange(false)">
|
<VButton @click="modal.close()">
|
||||||
{{ $t("core.common.buttons.cancel_and_shortcut") }}
|
{{ $t("core.common.buttons.cancel_and_shortcut") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
</VSpace>
|
</VSpace>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// core libs
|
// core libs
|
||||||
import { onMounted, ref, watch } from "vue";
|
import { ref } from "vue";
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import {
|
import {
|
||||||
|
@ -26,17 +26,14 @@ const { t } = useI18n();
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
selectedGroup: Group | undefined;
|
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
selectedGroup: undefined,
|
|
||||||
readonly: false,
|
readonly: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "update:selectedGroup", group: Group): void;
|
|
||||||
(event: "select", group: Group): void;
|
(event: "select", group: Group): void;
|
||||||
(event: "update"): void;
|
(event: "update"): void;
|
||||||
(event: "reload-attachments"): void;
|
(event: "reload-attachments"): void;
|
||||||
|
@ -67,19 +64,17 @@ const defaultGroups: Group[] = [
|
||||||
|
|
||||||
const { groups, handleFetchGroups } = useFetchAttachmentGroup();
|
const { groups, handleFetchGroups } = useFetchAttachmentGroup();
|
||||||
|
|
||||||
const groupToUpdate = ref<Group | null>(null);
|
const groupToUpdate = ref<Group>();
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const editingModal = ref(false);
|
const editingModal = ref(false);
|
||||||
|
|
||||||
const routeQuery = useRouteQuery<string>("group");
|
const selectedGroup = props.readonly
|
||||||
|
? ref("")
|
||||||
|
: useRouteQuery<string>("group", "");
|
||||||
|
|
||||||
const handleSelectGroup = (group: Group) => {
|
const handleSelectGroup = (group: Group) => {
|
||||||
emit("update:selectedGroup", group);
|
|
||||||
emit("select", group);
|
emit("select", group);
|
||||||
|
selectedGroup.value = group.metadata.name;
|
||||||
if (!props.readonly) {
|
|
||||||
routeQuery.value = group.metadata.name;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenEditingModal = (group: Group) => {
|
const handleOpenEditingModal = (group: Group) => {
|
||||||
|
@ -90,6 +85,7 @@ const handleOpenEditingModal = (group: Group) => {
|
||||||
const onEditingModalClose = () => {
|
const onEditingModalClose = () => {
|
||||||
emit("update");
|
emit("update");
|
||||||
handleFetchGroups();
|
handleFetchGroups();
|
||||||
|
editingModal.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (group: Group) => {
|
const handleDelete = (group: Group) => {
|
||||||
|
@ -181,51 +177,20 @@ const handleDeleteWithAttachments = (group: Group) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
|
||||||
() => groups.value?.length,
|
|
||||||
() => {
|
|
||||||
const allGroups = [...defaultGroups, ...(groups.value || [])];
|
|
||||||
const groupIndex = allGroups.findIndex(
|
|
||||||
(group) => group.metadata.name === routeQuery.value
|
|
||||||
);
|
|
||||||
|
|
||||||
if (groupIndex < 0) {
|
|
||||||
handleSelectGroup(defaultGroups[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await handleFetchGroups();
|
|
||||||
if (routeQuery.value && !props.readonly) {
|
|
||||||
const allGroups = [...defaultGroups, ...(groups.value || [])];
|
|
||||||
const group = allGroups.find(
|
|
||||||
(group) => group.metadata.name === routeQuery.value
|
|
||||||
);
|
|
||||||
if (group) {
|
|
||||||
handleSelectGroup(group);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSelectGroup(defaultGroups[0]);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<AttachmentGroupEditingModal
|
<AttachmentGroupEditingModal
|
||||||
v-if="!readonly"
|
v-if="!readonly && editingModal"
|
||||||
v-model:visible="editingModal"
|
|
||||||
:group="groupToUpdate"
|
:group="groupToUpdate"
|
||||||
@close="onEditingModalClose"
|
@close="onEditingModalClose"
|
||||||
/>
|
/>
|
||||||
<div class="mb-5 grid grid-cols-2 gap-x-2 gap-y-3 sm:grid-cols-6">
|
<div class="mb-5 grid grid-cols-2 gap-x-2 gap-y-3 sm:grid-cols-6">
|
||||||
<div
|
<div
|
||||||
v-for="(defaultGroup, index) in defaultGroups"
|
v-for="defaultGroup in defaultGroups"
|
||||||
:key="index"
|
:key="defaultGroup.metadata.name"
|
||||||
:class="{
|
:class="{
|
||||||
'!bg-gray-200 !text-gray-900':
|
'!bg-gray-200 !text-gray-900':
|
||||||
defaultGroup.metadata.name === selectedGroup?.metadata.name,
|
defaultGroup.metadata.name === selectedGroup,
|
||||||
}"
|
}"
|
||||||
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"
|
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)"
|
@click="handleSelectGroup(defaultGroup)"
|
||||||
|
@ -235,11 +200,10 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="(group, index) in groups"
|
v-for="group in groups"
|
||||||
:key="index"
|
:key="group.metadata.name"
|
||||||
:class="{
|
:class="{
|
||||||
'!bg-gray-200 !text-gray-900':
|
'!bg-gray-200 !text-gray-900': group.metadata.name === selectedGroup,
|
||||||
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"
|
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)"
|
@click="handleSelectGroup(group)"
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import {
|
||||||
VSpace,
|
Dialog,
|
||||||
VStatusDot,
|
Toast,
|
||||||
|
VDropdownDivider,
|
||||||
|
VDropdownItem,
|
||||||
VEntity,
|
VEntity,
|
||||||
VEntityField,
|
VEntityField,
|
||||||
Toast,
|
VSpace,
|
||||||
VDropdownItem,
|
VStatusDot,
|
||||||
Dialog,
|
|
||||||
VDropdownDivider,
|
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import { computed, ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
|
import { computed, inject, markRaw, ref, toRefs } from "vue";
|
||||||
import type { Attachment } from "@halo-dev/api-client";
|
import type { Attachment } from "@halo-dev/api-client";
|
||||||
import { formatDatetime } from "@/utils/date";
|
import { formatDatetime } from "@/utils/date";
|
||||||
import prettyBytes from "pretty-bytes";
|
import prettyBytes from "pretty-bytes";
|
||||||
|
@ -17,14 +18,10 @@ import { useFetchAttachmentPolicy } from "../composables/use-attachment-policy";
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import { usePermission } from "@/utils/permission";
|
import { usePermission } from "@/utils/permission";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { inject } from "vue";
|
|
||||||
import type { Ref } from "vue";
|
|
||||||
import { useQueryClient } from "@tanstack/vue-query";
|
import { useQueryClient } from "@tanstack/vue-query";
|
||||||
import { useOperationItemExtensionPoint } from "@console/composables/use-operation-extension-points";
|
import { useOperationItemExtensionPoint } from "@console/composables/use-operation-extension-points";
|
||||||
import { toRefs } from "vue";
|
|
||||||
import type { OperationItem } from "@halo-dev/console-shared";
|
import type { OperationItem } from "@halo-dev/console-shared";
|
||||||
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
import EntityDropdownItems from "@/components/entity/EntityDropdownItems.vue";
|
||||||
import { markRaw } from "vue";
|
|
||||||
|
|
||||||
const { currentUserHasPermission } = usePermission();
|
const { currentUserHasPermission } = usePermission();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -52,7 +49,7 @@ const selectedAttachments = inject<Ref<Set<Attachment>>>(
|
||||||
ref<Set<Attachment>>(new Set())
|
ref<Set<Attachment>>(new Set())
|
||||||
);
|
);
|
||||||
|
|
||||||
const policyName = computed(() => {
|
const policyDisplayName = computed(() => {
|
||||||
const policy = policies.value?.find(
|
const policy = policies.value?.find(
|
||||||
(p) => p.metadata.name === props.attachment.spec.policyName
|
(p) => p.metadata.name === props.attachment.spec.policyName
|
||||||
);
|
);
|
||||||
|
@ -180,7 +177,7 @@ const { operationItems } = useOperationItemExtensionPoint<Attachment>(
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
</template>
|
</template>
|
||||||
<template #end>
|
<template #end>
|
||||||
<VEntityField :description="policyName" />
|
<VEntityField :description="policyDisplayName" />
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
import { VButton } from "@halo-dev/components";
|
import { VButton } from "@halo-dev/components";
|
||||||
import type { Attachment } from "@halo-dev/api-client";
|
import type { Attachment } from "@halo-dev/api-client";
|
||||||
import { useAttachmentPermalinkCopy } from "../composables/use-attachment";
|
import { useAttachmentPermalinkCopy } from "../composables/use-attachment";
|
||||||
import { toRefs, computed } from "vue";
|
import { computed, toRefs } from "vue";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
visible: boolean;
|
|
||||||
attachment?: Attachment;
|
attachment?: Attachment;
|
||||||
mountToBody?: boolean;
|
mountToBody?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
visible: false,
|
|
||||||
attachment: undefined,
|
attachment: undefined,
|
||||||
mountToBody: false,
|
mountToBody: false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import {
|
||||||
IconAddCircle,
|
|
||||||
VButton,
|
|
||||||
VModal,
|
|
||||||
VSpace,
|
|
||||||
VEmpty,
|
|
||||||
Dialog,
|
Dialog,
|
||||||
VEntity,
|
IconAddCircle,
|
||||||
VEntityField,
|
Toast,
|
||||||
VStatusDot,
|
VButton,
|
||||||
VDropdown,
|
VDropdown,
|
||||||
VDropdownItem,
|
VDropdownItem,
|
||||||
Toast,
|
VEmpty,
|
||||||
|
VEntity,
|
||||||
|
VEntityField,
|
||||||
|
VModal,
|
||||||
|
VSpace,
|
||||||
|
VStatusDot,
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import AttachmentPolicyEditingModal from "./AttachmentPolicyEditingModal.vue";
|
import AttachmentPolicyEditingModal from "./AttachmentPolicyEditingModal.vue";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
@ -24,17 +24,7 @@ import {
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
withDefaults(
|
|
||||||
defineProps<{
|
|
||||||
visible: boolean;
|
|
||||||
}>(),
|
|
||||||
{
|
|
||||||
visible: false,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "update:visible", visible: boolean): void;
|
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
@ -43,36 +33,19 @@ const { t } = useI18n();
|
||||||
const { policies, isLoading, handleFetchPolicies } = useFetchAttachmentPolicy();
|
const { policies, isLoading, handleFetchPolicies } = useFetchAttachmentPolicy();
|
||||||
const { policyTemplates } = useFetchAttachmentPolicyTemplate();
|
const { policyTemplates } = useFetchAttachmentPolicyTemplate();
|
||||||
|
|
||||||
|
const modal = ref();
|
||||||
const selectedPolicy = ref<Policy>();
|
const selectedPolicy = ref<Policy>();
|
||||||
|
const selectedTemplateName = ref();
|
||||||
|
|
||||||
const policyEditingModal = ref(false);
|
const policyEditingModal = ref(false);
|
||||||
|
|
||||||
function onVisibleChange(visible: boolean) {
|
|
||||||
emit("update:visible", visible);
|
|
||||||
if (!visible) {
|
|
||||||
emit("close");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleOpenEditingModal = (policy: Policy) => {
|
const handleOpenEditingModal = (policy: Policy) => {
|
||||||
selectedPolicy.value = policy;
|
selectedPolicy.value = policy;
|
||||||
policyEditingModal.value = true;
|
policyEditingModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenCreateNewPolicyModal = (policyTemplate: PolicyTemplate) => {
|
const handleOpenCreateNewPolicyModal = (policyTemplate: PolicyTemplate) => {
|
||||||
selectedPolicy.value = {
|
selectedTemplateName.value = policyTemplate.metadata.name;
|
||||||
spec: {
|
|
||||||
displayName: "",
|
|
||||||
templateName: policyTemplate.metadata.name,
|
|
||||||
configMapName: "",
|
|
||||||
},
|
|
||||||
apiVersion: "storage.halo.run/v1alpha1",
|
|
||||||
kind: "Policy",
|
|
||||||
metadata: {
|
|
||||||
name: "",
|
|
||||||
generateName: "attachment-policy-",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
policyEditingModal.value = true;
|
policyEditingModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,16 +89,17 @@ const handleDelete = async (policy: Policy) => {
|
||||||
const onEditingModalClose = () => {
|
const onEditingModalClose = () => {
|
||||||
selectedPolicy.value = undefined;
|
selectedPolicy.value = undefined;
|
||||||
handleFetchPolicies();
|
handleFetchPolicies();
|
||||||
|
policyEditingModal.value = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VModal
|
<VModal
|
||||||
:visible="visible"
|
ref="modal"
|
||||||
:width="750"
|
:width="750"
|
||||||
:title="$t('core.attachment.policies_modal.title')"
|
:title="$t('core.attachment.policies_modal.title')"
|
||||||
:body-class="['!p-0']"
|
:body-class="['!p-0']"
|
||||||
:layer-closable="true"
|
:layer-closable="true"
|
||||||
@update:visible="onVisibleChange"
|
@close="emit('close')"
|
||||||
>
|
>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<VDropdown>
|
<VDropdown>
|
||||||
|
@ -216,16 +190,16 @@ const onEditingModalClose = () => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<VButton @click="onVisibleChange(false)">
|
<VButton @click="modal.close()">
|
||||||
{{ $t("core.common.buttons.close_and_shortcut") }}
|
{{ $t("core.common.buttons.close_and_shortcut") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
</template>
|
</template>
|
||||||
</VModal>
|
</VModal>
|
||||||
|
|
||||||
<AttachmentPolicyEditingModal
|
<AttachmentPolicyEditingModal
|
||||||
v-if="visible"
|
v-if="policyEditingModal"
|
||||||
v-model:visible="policyEditingModal"
|
|
||||||
:policy="selectedPolicy"
|
:policy="selectedPolicy"
|
||||||
|
:template-name="selectedTemplateName"
|
||||||
@close="onEditingModalClose"
|
@close="onEditingModalClose"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,38 +1,37 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
import { Toast, VButton, VLoading, VModal, VSpace } from "@halo-dev/components";
|
||||||
import SubmitButton from "@/components/button/SubmitButton.vue";
|
import SubmitButton from "@/components/button/SubmitButton.vue";
|
||||||
import type { Policy, PolicyTemplate } from "@halo-dev/api-client";
|
import type { Policy } from "@halo-dev/api-client";
|
||||||
import { cloneDeep } from "lodash-es";
|
import { cloneDeep } from "lodash-es";
|
||||||
import { computed, ref, toRaw, watch, watchEffect } from "vue";
|
import { computed, onMounted, ref, toRaw, toRefs } from "vue";
|
||||||
import { useSettingForm } from "@console/composables/use-setting-form";
|
import { useSettingFormConvert } from "@console/composables/use-setting-form";
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import {
|
|
||||||
reset,
|
|
||||||
type FormKitSchemaCondition,
|
|
||||||
type FormKitSchemaNode,
|
|
||||||
} from "@formkit/core";
|
|
||||||
import { setFocus } from "@/formkit/utils/focus";
|
import { setFocus } from "@/formkit/utils/focus";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { useQuery } from "@tanstack/vue-query";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
visible: boolean;
|
|
||||||
policy?: Policy;
|
policy?: Policy;
|
||||||
|
templateName?: string;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
visible: false,
|
|
||||||
policy: undefined,
|
policy: undefined,
|
||||||
|
templateName: undefined,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { policy } = toRefs(props);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "update:visible", visible: boolean): void;
|
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const initialFormState: Policy = {
|
const modal = ref();
|
||||||
|
|
||||||
|
const formState = ref<Policy>({
|
||||||
spec: {
|
spec: {
|
||||||
displayName: "",
|
displayName: "",
|
||||||
templateName: "",
|
templateName: "",
|
||||||
|
@ -44,82 +43,106 @@ const initialFormState: Policy = {
|
||||||
name: "",
|
name: "",
|
||||||
generateName: "attachment-policy-",
|
generateName: "attachment-policy-",
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
const formState = ref<Policy>(cloneDeep(initialFormState));
|
const isUpdateMode = !!props.policy;
|
||||||
const policyTemplate = ref<PolicyTemplate | undefined>();
|
|
||||||
|
|
||||||
const settingName = computed(() => policyTemplate.value?.spec?.settingName);
|
onMounted(async () => {
|
||||||
|
if (props.policy) {
|
||||||
|
formState.value = cloneDeep(props.policy);
|
||||||
|
}
|
||||||
|
if (props.templateName) {
|
||||||
|
formState.value.spec.templateName = props.templateName;
|
||||||
|
}
|
||||||
|
|
||||||
const configMapName = computed({
|
setFocus("displayNameInput");
|
||||||
get() {
|
});
|
||||||
return formState.value.spec.configMapName;
|
|
||||||
},
|
const { data: policyTemplate } = useQuery({
|
||||||
set(value) {
|
queryKey: [
|
||||||
formState.value.spec.configMapName = value;
|
"core:attachment:policy-template",
|
||||||
|
formState.value.spec.templateName,
|
||||||
|
],
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } =
|
||||||
|
await apiClient.extension.storage.policyTemplate.getstorageHaloRunV1alpha1PolicyTemplate(
|
||||||
|
{
|
||||||
|
name: formState.value.spec.templateName,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return data;
|
||||||
},
|
},
|
||||||
|
retry: 0,
|
||||||
|
enabled: computed(() => !!formState.value.spec.templateName),
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const { data: setting, isLoading } = useQuery({
|
||||||
setting,
|
queryKey: [
|
||||||
configMapFormData,
|
"core:attachment:policy-template:setting",
|
||||||
configMap,
|
policyTemplate.value?.spec?.settingName,
|
||||||
saving,
|
],
|
||||||
handleFetchConfigMap,
|
queryFn: async () => {
|
||||||
handleFetchSettings,
|
if (!policyTemplate.value?.spec?.settingName) {
|
||||||
handleSaveConfigMap,
|
throw new Error("No setting found");
|
||||||
handleReset: handleResetSettingForm,
|
|
||||||
} = useSettingForm(settingName, configMapName);
|
|
||||||
|
|
||||||
const formSchema = computed(() => {
|
|
||||||
if (!setting.value) {
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
const { forms } = setting.value.spec;
|
|
||||||
return forms.find((item) => item.group === "default")?.formSchema as (
|
|
||||||
| FormKitSchemaCondition
|
|
||||||
| FormKitSchemaNode
|
|
||||||
)[];
|
|
||||||
});
|
|
||||||
|
|
||||||
watchEffect(() => {
|
const { data } = await apiClient.extension.setting.getv1alpha1Setting({
|
||||||
if (settingName.value) {
|
name: policyTemplate.value.spec.settingName,
|
||||||
handleFetchSettings();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
watchEffect(() => {
|
|
||||||
if (configMapName.value && setting.value) {
|
|
||||||
handleFetchConfigMap();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const isUpdateMode = computed(() => {
|
|
||||||
return !!formState.value.metadata.creationTimestamp;
|
|
||||||
});
|
|
||||||
|
|
||||||
const modalTitle = computed(() => {
|
|
||||||
return isUpdateMode.value
|
|
||||||
? t("core.attachment.policy_editing_modal.titles.update", {
|
|
||||||
policy: props.policy?.spec.displayName,
|
|
||||||
})
|
|
||||||
: t("core.attachment.policy_editing_modal.titles.create", {
|
|
||||||
policy_template: policyTemplate.value?.spec?.displayName,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
retry: 0,
|
||||||
|
enabled: computed(() => !!policyTemplate.value?.spec?.settingName),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { data: configMap } = useQuery({
|
||||||
|
queryKey: [
|
||||||
|
"core:attachment:policy-template:configMap",
|
||||||
|
policy.value?.spec.configMapName,
|
||||||
|
],
|
||||||
|
initialData: {
|
||||||
|
data: {},
|
||||||
|
apiVersion: "v1alpha1",
|
||||||
|
kind: "ConfigMap",
|
||||||
|
metadata: {
|
||||||
|
generateName: "configMap-",
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
retry: 0,
|
||||||
|
queryFn: async () => {
|
||||||
|
if (!policy.value?.spec.configMapName) {
|
||||||
|
throw new Error("No configMap found");
|
||||||
|
}
|
||||||
|
const { data } = await apiClient.extension.configMap.getv1alpha1ConfigMap({
|
||||||
|
name: policy.value?.spec.configMapName,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
enabled: computed(() => !!policy.value?.spec.configMapName),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { configMapFormData, formSchema, convertToSave } = useSettingFormConvert(
|
||||||
|
setting,
|
||||||
|
configMap,
|
||||||
|
ref("default")
|
||||||
|
);
|
||||||
|
|
||||||
|
const submitting = ref(false);
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
try {
|
try {
|
||||||
saving.value = true;
|
submitting.value = true;
|
||||||
|
|
||||||
if (!isUpdateMode.value) {
|
const configMapToUpdate = convertToSave();
|
||||||
configMap.value.metadata.name = "";
|
|
||||||
configMap.value.metadata.generateName = "configMap-";
|
|
||||||
}
|
|
||||||
|
|
||||||
await handleSaveConfigMap();
|
if (isUpdateMode) {
|
||||||
|
await apiClient.extension.configMap.updatev1alpha1ConfigMap({
|
||||||
|
name: configMap.value.metadata.name,
|
||||||
|
configMap: configMapToUpdate,
|
||||||
|
});
|
||||||
|
|
||||||
if (isUpdateMode.value) {
|
|
||||||
await apiClient.extension.storage.policy.updatestorageHaloRunV1alpha1Policy(
|
await apiClient.extension.storage.policy.updatestorageHaloRunV1alpha1Policy(
|
||||||
{
|
{
|
||||||
name: formState.value.metadata.name,
|
name: formState.value.metadata.name,
|
||||||
|
@ -127,7 +150,12 @@ const handleSave = async () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
formState.value.spec.configMapName = configMap.value.metadata.name;
|
const { data: newConfigMap } =
|
||||||
|
await apiClient.extension.configMap.createv1alpha1ConfigMap({
|
||||||
|
configMap: configMapToUpdate,
|
||||||
|
});
|
||||||
|
|
||||||
|
formState.value.spec.configMapName = newConfigMap.metadata.name;
|
||||||
await apiClient.extension.storage.policy.createstorageHaloRunV1alpha1Policy(
|
await apiClient.extension.storage.policy.createstorageHaloRunV1alpha1Policy(
|
||||||
{
|
{
|
||||||
policy: formState.value,
|
policy: formState.value,
|
||||||
|
@ -136,78 +164,27 @@ const handleSave = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
Toast.success(t("core.common.toast.save_success"));
|
Toast.success(t("core.common.toast.save_success"));
|
||||||
onVisibleChange(false);
|
modal.value.close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to save attachment policy", e);
|
console.error("Failed to save attachment policy", e);
|
||||||
} finally {
|
} finally {
|
||||||
saving.value = false;
|
submitting.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleResetForm = () => {
|
const modalTitle = props.policy
|
||||||
formState.value = cloneDeep(initialFormState);
|
? t("core.attachment.policy_editing_modal.titles.update", {
|
||||||
reset("attachment-policy-form");
|
policy: props.policy?.spec.displayName,
|
||||||
};
|
})
|
||||||
|
: t("core.attachment.policy_editing_modal.titles.create", {
|
||||||
watch(
|
policy_template: policyTemplate.value?.spec?.displayName,
|
||||||
() => props.visible,
|
});
|
||||||
(visible) => {
|
|
||||||
if (visible) {
|
|
||||||
setFocus("displayNameInput");
|
|
||||||
} else {
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
policyTemplate.value = undefined;
|
|
||||||
handleResetForm();
|
|
||||||
handleResetSettingForm();
|
|
||||||
clearTimeout(timer);
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.policy,
|
|
||||||
async (policy) => {
|
|
||||||
if (policy) {
|
|
||||||
formState.value = cloneDeep(policy);
|
|
||||||
|
|
||||||
const { templateName } = formState.value.spec;
|
|
||||||
|
|
||||||
// Get policy template
|
|
||||||
if (templateName) {
|
|
||||||
const { data } =
|
|
||||||
await apiClient.extension.storage.policyTemplate.getstorageHaloRunV1alpha1PolicyTemplate(
|
|
||||||
{
|
|
||||||
name: templateName,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
policyTemplate.value = data;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
|
||||||
policyTemplate.value = undefined;
|
|
||||||
handleResetForm();
|
|
||||||
handleResetSettingForm();
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const onVisibleChange = (visible: boolean) => {
|
|
||||||
emit("update:visible", visible);
|
|
||||||
if (!visible) {
|
|
||||||
emit("close");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VModal
|
<VModal ref="modal" :title="modalTitle" :width="600" @close="emit('close')">
|
||||||
:title="modalTitle"
|
|
||||||
:visible="visible"
|
|
||||||
:width="600"
|
|
||||||
@update:visible="onVisibleChange"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
|
<VLoading v-if="isLoading" />
|
||||||
|
<template v-else>
|
||||||
<FormKit
|
<FormKit
|
||||||
v-if="formSchema && configMapFormData"
|
v-if="formSchema && configMapFormData"
|
||||||
id="attachment-policy-form"
|
id="attachment-policy-form"
|
||||||
|
@ -223,7 +200,9 @@ const onVisibleChange = (visible: boolean) => {
|
||||||
id="displayNameInput"
|
id="displayNameInput"
|
||||||
v-model="formState.spec.displayName"
|
v-model="formState.spec.displayName"
|
||||||
:label="
|
:label="
|
||||||
$t('core.attachment.policy_editing_modal.fields.display_name.label')
|
$t(
|
||||||
|
'core.attachment.policy_editing_modal.fields.display_name.label'
|
||||||
|
)
|
||||||
"
|
"
|
||||||
type="text"
|
type="text"
|
||||||
name="displayName"
|
name="displayName"
|
||||||
|
@ -234,19 +213,19 @@ const onVisibleChange = (visible: boolean) => {
|
||||||
:data="configMapFormData['default']"
|
:data="configMapFormData['default']"
|
||||||
/>
|
/>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<VSpace>
|
<VSpace>
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
v-if="visible"
|
:loading="submitting"
|
||||||
:loading="saving"
|
|
||||||
type="secondary"
|
type="secondary"
|
||||||
:text="$t('core.common.buttons.submit')"
|
:text="$t('core.common.buttons.submit')"
|
||||||
@submit="$formkit.submit('attachment-policy-form')"
|
@submit="$formkit.submit('attachment-policy-form')"
|
||||||
>
|
>
|
||||||
</SubmitButton>
|
</SubmitButton>
|
||||||
<VButton @click="onVisibleChange(false)">
|
<VButton @click="modal.close()">
|
||||||
{{ $t("core.common.buttons.cancel_and_shortcut") }}
|
{{ $t("core.common.buttons.cancel_and_shortcut") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
</VSpace>
|
</VSpace>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
VModal,
|
VModal,
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import type { Policy, PolicyTemplate } from "@halo-dev/api-client";
|
import type { PolicyTemplate } from "@halo-dev/api-client";
|
||||||
import {
|
import {
|
||||||
useFetchAttachmentPolicy,
|
useFetchAttachmentPolicy,
|
||||||
useFetchAttachmentPolicyTemplate,
|
useFetchAttachmentPolicyTemplate,
|
||||||
|
@ -16,17 +16,7 @@ import { useFetchAttachmentGroup } from "../composables/use-attachment-group";
|
||||||
import AttachmentPolicyEditingModal from "./AttachmentPolicyEditingModal.vue";
|
import AttachmentPolicyEditingModal from "./AttachmentPolicyEditingModal.vue";
|
||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
|
|
||||||
const props = withDefaults(
|
|
||||||
defineProps<{
|
|
||||||
visible: boolean;
|
|
||||||
}>(),
|
|
||||||
{
|
|
||||||
visible: false,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "update:visible", visible: boolean): void;
|
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
@ -34,11 +24,11 @@ const { groups } = useFetchAttachmentGroup();
|
||||||
const { policies, handleFetchPolicies } = useFetchAttachmentPolicy();
|
const { policies, handleFetchPolicies } = useFetchAttachmentPolicy();
|
||||||
const { policyTemplates } = useFetchAttachmentPolicyTemplate();
|
const { policyTemplates } = useFetchAttachmentPolicyTemplate();
|
||||||
|
|
||||||
|
const modal = ref();
|
||||||
const selectedGroupName = useLocalStorage("attachment-upload-group", "");
|
const selectedGroupName = useLocalStorage("attachment-upload-group", "");
|
||||||
const selectedPolicyName = useLocalStorage("attachment-upload-policy", "");
|
const selectedPolicyName = useLocalStorage("attachment-upload-policy", "");
|
||||||
const policyToCreate = ref<Policy>();
|
|
||||||
const uploadVisible = ref(false);
|
|
||||||
const policyEditingModal = ref(false);
|
const policyEditingModal = ref(false);
|
||||||
|
const policyTemplateNameToCreate = ref();
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => groups.value,
|
() => groups.value,
|
||||||
|
@ -71,57 +61,24 @@ watch(
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleOpenCreateNewPolicyModal = (policyTemplate: PolicyTemplate) => {
|
const handleOpenCreateNewPolicyModal = (policyTemplate: PolicyTemplate) => {
|
||||||
policyToCreate.value = {
|
policyTemplateNameToCreate.value = policyTemplate.metadata.name;
|
||||||
spec: {
|
|
||||||
displayName: "",
|
|
||||||
templateName: policyTemplate.metadata.name,
|
|
||||||
configMapName: "",
|
|
||||||
},
|
|
||||||
apiVersion: "storage.halo.run/v1alpha1",
|
|
||||||
kind: "Policy",
|
|
||||||
metadata: {
|
|
||||||
name: "",
|
|
||||||
generateName: "attachment-policy-",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
policyEditingModal.value = true;
|
policyEditingModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEditingModalClose = async () => {
|
const onEditingModalClose = async () => {
|
||||||
await handleFetchPolicies();
|
await handleFetchPolicies();
|
||||||
policyToCreate.value = policies.value?.[0];
|
selectedPolicyName.value = policies.value?.[0].metadata.name;
|
||||||
};
|
|
||||||
|
|
||||||
const onVisibleChange = (visible: boolean) => {
|
|
||||||
emit("update:visible", visible);
|
|
||||||
if (!visible) {
|
|
||||||
emit("close");
|
|
||||||
policyEditingModal.value = false;
|
policyEditingModal.value = false;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.visible,
|
|
||||||
(newValue) => {
|
|
||||||
if (newValue) {
|
|
||||||
uploadVisible.value = true;
|
|
||||||
} else {
|
|
||||||
const uploadVisibleTimer = setTimeout(() => {
|
|
||||||
uploadVisible.value = false;
|
|
||||||
clearTimeout(uploadVisibleTimer);
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VModal
|
<VModal
|
||||||
|
ref="modal"
|
||||||
:body-class="['!p-0']"
|
:body-class="['!p-0']"
|
||||||
:visible="visible"
|
|
||||||
:width="650"
|
:width="650"
|
||||||
:centered="false"
|
:centered="false"
|
||||||
:title="$t('core.attachment.upload_modal.title')"
|
:title="$t('core.attachment.upload_modal.title')"
|
||||||
@update:visible="onVisibleChange"
|
@close="emit('close')"
|
||||||
>
|
>
|
||||||
<div class="w-full p-4">
|
<div class="w-full p-4">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
|
@ -213,7 +170,6 @@ watch(
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<UppyUpload
|
<UppyUpload
|
||||||
v-if="uploadVisible"
|
|
||||||
endpoint="/apis/api.console.halo.run/v1alpha1/attachments/upload"
|
endpoint="/apis/api.console.halo.run/v1alpha1/attachments/upload"
|
||||||
:disabled="!selectedPolicyName"
|
:disabled="!selectedPolicyName"
|
||||||
:meta="{
|
:meta="{
|
||||||
|
@ -226,15 +182,14 @@ watch(
|
||||||
? ''
|
? ''
|
||||||
: $t('core.attachment.upload_modal.filters.policy.not_select')
|
: $t('core.attachment.upload_modal.filters.policy.not_select')
|
||||||
"
|
"
|
||||||
:done-button-handler="() => onVisibleChange(false)"
|
:done-button-handler="() => modal.close()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</VModal>
|
</VModal>
|
||||||
|
|
||||||
<AttachmentPolicyEditingModal
|
<AttachmentPolicyEditingModal
|
||||||
v-if="visible"
|
v-if="policyEditingModal"
|
||||||
v-model:visible="policyEditingModal"
|
:template-name="policyTemplateNameToCreate"
|
||||||
:policy="policyToCreate"
|
|
||||||
@close="onEditingModalClose"
|
@close="onEditingModalClose"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import {
|
||||||
IconCheckboxFill,
|
|
||||||
IconArrowLeft,
|
IconArrowLeft,
|
||||||
IconArrowRight,
|
IconArrowRight,
|
||||||
|
IconCheckboxCircle,
|
||||||
|
IconCheckboxFill,
|
||||||
|
IconEye,
|
||||||
|
IconUpload,
|
||||||
|
VButton,
|
||||||
VCard,
|
VCard,
|
||||||
VEmpty,
|
VEmpty,
|
||||||
VSpace,
|
|
||||||
VButton,
|
|
||||||
IconUpload,
|
|
||||||
VPagination,
|
VPagination,
|
||||||
IconEye,
|
VSpace,
|
||||||
IconCheckboxCircle,
|
|
||||||
} from "@halo-dev/components";
|
} from "@halo-dev/components";
|
||||||
import { watchEffect, ref } from "vue";
|
import { computed, ref, watchEffect } from "vue";
|
||||||
import { isImage } from "@/utils/image";
|
import { isImage } from "@/utils/image";
|
||||||
import { useAttachmentControl } from "../../composables/use-attachment";
|
import { useAttachmentControl } from "../../composables/use-attachment";
|
||||||
import LazyImage from "@/components/image/LazyImage.vue";
|
import LazyImage from "@/components/image/LazyImage.vue";
|
||||||
|
@ -22,7 +22,6 @@ import AttachmentUploadModal from "../AttachmentUploadModal.vue";
|
||||||
import AttachmentDetailModal from "../AttachmentDetailModal.vue";
|
import AttachmentDetailModal from "../AttachmentDetailModal.vue";
|
||||||
import AttachmentGroupList from "../AttachmentGroupList.vue";
|
import AttachmentGroupList from "../AttachmentGroupList.vue";
|
||||||
import { matchMediaTypes } from "@/utils/media-type";
|
import { matchMediaTypes } from "@/utils/media-type";
|
||||||
import { computed } from "vue";
|
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -44,7 +43,7 @@ const emit = defineEmits<{
|
||||||
(event: "change-provider", providerId: string): void;
|
(event: "change-provider", providerId: string): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const selectedGroup = ref<Group>();
|
const selectedGroup = ref();
|
||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
const size = ref(60);
|
const size = ref(60);
|
||||||
|
|
||||||
|
@ -61,7 +60,7 @@ const {
|
||||||
handleReset,
|
handleReset,
|
||||||
isChecked,
|
isChecked,
|
||||||
} = useAttachmentControl({
|
} = useAttachmentControl({
|
||||||
group: selectedGroup,
|
groupName: selectedGroup,
|
||||||
accepts: computed(() => {
|
accepts: computed(() => {
|
||||||
return props.accepts;
|
return props.accepts;
|
||||||
}),
|
}),
|
||||||
|
@ -97,13 +96,19 @@ const isDisabled = (attachment: Attachment) => {
|
||||||
|
|
||||||
return !isMatchMediaType;
|
return !isMatchMediaType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onUploadModalClose() {
|
||||||
|
handleFetchAttachments();
|
||||||
|
uploadVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onGroupSelect(group: Group) {
|
||||||
|
selectedGroup.value = group.metadata.name;
|
||||||
|
handleReset();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<AttachmentGroupList
|
<AttachmentGroupList readonly @select="onGroupSelect" />
|
||||||
v-model:selected-group="selectedGroup"
|
|
||||||
readonly
|
|
||||||
@select="handleReset"
|
|
||||||
/>
|
|
||||||
<div v-if="attachments?.length" class="mb-5">
|
<div v-if="attachments?.length" class="mb-5">
|
||||||
<VButton @click="uploadVisible = true">
|
<VButton @click="uploadVisible = true">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
|
@ -216,10 +221,7 @@ const isDisabled = (attachment: Attachment) => {
|
||||||
:size-options="[60, 120, 200]"
|
:size-options="[60, 120, 200]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<AttachmentUploadModal
|
<AttachmentUploadModal v-if="uploadVisible" @close="onUploadModalClose" />
|
||||||
v-model:visible="uploadVisible"
|
|
||||||
@close="handleFetchAttachments"
|
|
||||||
/>
|
|
||||||
<AttachmentDetailModal
|
<AttachmentDetailModal
|
||||||
v-model:visible="detailVisible"
|
v-model:visible="detailVisible"
|
||||||
:mount-to-body="true"
|
:mount-to-body="true"
|
||||||
|
|
|
@ -20,14 +20,15 @@ export function useFetchAttachmentGroup(): useFetchAttachmentGroupReturn {
|
||||||
sort: ["metadata.creationTimestamp,asc"],
|
sort: ["metadata.creationTimestamp,asc"],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return data.items;
|
return data.items;
|
||||||
},
|
},
|
||||||
refetchInterval(data) {
|
refetchInterval(data) {
|
||||||
const deletingGroups = data?.filter(
|
const hasDeletingGroup = data?.some(
|
||||||
(group) => !!group.metadata.deletionTimestamp
|
(group) => !!group.metadata.deletionTimestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
return deletingGroups?.length ? 1000 : false;
|
return hasDeletingGroup ? 1000 : false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@ export function useFetchAttachmentPolicy(): useFetchAttachmentPolicyReturn {
|
||||||
return data.items;
|
return data.items;
|
||||||
},
|
},
|
||||||
refetchInterval(data) {
|
refetchInterval(data) {
|
||||||
const deletingPolicies = data?.filter(
|
const hasDeletingPolicy = data?.some(
|
||||||
(policy) => !!policy.metadata.deletionTimestamp
|
(policy) => !!policy.metadata.deletionTimestamp
|
||||||
);
|
);
|
||||||
return deletingPolicies?.length ? 1000 : false;
|
return hasDeletingPolicy ? 1000 : false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import type { Attachment, Group, Policy } from "@halo-dev/api-client";
|
import type { Attachment } from "@halo-dev/api-client";
|
||||||
import { computed, nextTick, type Ref } from "vue";
|
import { computed, nextTick, type Ref, ref, watch } from "vue";
|
||||||
import { ref, watch } from "vue";
|
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import { Dialog, Toast } from "@halo-dev/components";
|
import { Dialog, Toast } from "@halo-dev/components";
|
||||||
import { useQuery } from "@tanstack/vue-query";
|
import { useQuery } from "@tanstack/vue-query";
|
||||||
|
@ -27,8 +26,8 @@ interface useAttachmentControlReturn {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useAttachmentControl(filterOptions: {
|
export function useAttachmentControl(filterOptions: {
|
||||||
policy?: Ref<Policy | undefined>;
|
policyName?: Ref<string | undefined>;
|
||||||
group?: Ref<Group | undefined>;
|
groupName?: Ref<string | undefined>;
|
||||||
user?: Ref<string | undefined>;
|
user?: Ref<string | undefined>;
|
||||||
accepts?: Ref<string[]>;
|
accepts?: Ref<string[]>;
|
||||||
keyword?: Ref<string | undefined>;
|
keyword?: Ref<string | undefined>;
|
||||||
|
@ -38,7 +37,7 @@ export function useAttachmentControl(filterOptions: {
|
||||||
}): useAttachmentControlReturn {
|
}): useAttachmentControlReturn {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const { user, policy, group, keyword, sort, page, size, accepts } =
|
const { user, policyName, groupName, keyword, sort, page, size, accepts } =
|
||||||
filterOptions;
|
filterOptions;
|
||||||
|
|
||||||
const selectedAttachment = ref<Attachment>();
|
const selectedAttachment = ref<Attachment>();
|
||||||
|
@ -52,9 +51,9 @@ export function useAttachmentControl(filterOptions: {
|
||||||
const { data, isLoading, isFetching, refetch } = useQuery<Attachment[]>({
|
const { data, isLoading, isFetching, refetch } = useQuery<Attachment[]>({
|
||||||
queryKey: [
|
queryKey: [
|
||||||
"attachments",
|
"attachments",
|
||||||
policy,
|
policyName,
|
||||||
keyword,
|
keyword,
|
||||||
group,
|
groupName,
|
||||||
user,
|
user,
|
||||||
accepts,
|
accepts,
|
||||||
page,
|
page,
|
||||||
|
@ -62,12 +61,12 @@ export function useAttachmentControl(filterOptions: {
|
||||||
sort,
|
sort,
|
||||||
],
|
],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const isUnGrouped = group?.value?.metadata.name === "ungrouped";
|
const isUnGrouped = groupName?.value === "ungrouped";
|
||||||
|
|
||||||
const fieldSelectorMap: Record<string, string | undefined> = {
|
const fieldSelectorMap: Record<string, string | undefined> = {
|
||||||
"spec.policyName": policy?.value?.metadata.name,
|
"spec.policyName": policyName?.value,
|
||||||
"spec.ownerName": user?.value,
|
"spec.ownerName": user?.value,
|
||||||
"spec.groupName": isUnGrouped ? undefined : group?.value?.metadata.name,
|
"spec.groupName": isUnGrouped ? undefined : groupName?.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
const fieldSelector = Object.entries(fieldSelectorMap)
|
const fieldSelector = Object.entries(fieldSelectorMap)
|
||||||
|
@ -95,10 +94,10 @@ export function useAttachmentControl(filterOptions: {
|
||||||
return data.items;
|
return data.items;
|
||||||
},
|
},
|
||||||
refetchInterval(data) {
|
refetchInterval(data) {
|
||||||
const deletingAttachments = data?.filter(
|
const hasDeletingAttachment = data?.some(
|
||||||
(attachment) => !!attachment.metadata.deletionTimestamp
|
(attachment) => !!attachment.metadata.deletionTimestamp
|
||||||
);
|
);
|
||||||
return deletingAttachments?.length ? 1000 : false;
|
return hasDeletingAttachment ? 1000 : false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue