mirror of https://github.com/halo-dev/halo
fix: splash screen issue caused by refreshing the list at regular intervals (halo-dev/console#708)
#### What type of PR is this? /kind bug /milestone 2.0 #### What this PR does / why we need it: 修复因为 https://github.com/halo-dev/console/pull/703 中添加了 Loading 动画但是没有考虑到定时刷新列表导致页面闪动的问题。 #### Special notes for your reviewer: /cc @halo-dev/sig-halo-console 测试方式:删除任意资源,检查列表定时刷新的时候是否出现 loading 状态。 #### Does this PR introduce a user-facing change? ```release-note None ```pull/3445/head
parent
e7ac73f0b6
commit
73676ee815
|
@ -93,17 +93,17 @@ const selectedSortItemValue = computed(() => {
|
|||
|
||||
function handleSelectPolicy(policy: Policy | undefined) {
|
||||
selectedPolicy.value = policy;
|
||||
handleFetchAttachments(1);
|
||||
handleFetchAttachments({ page: 1 });
|
||||
}
|
||||
|
||||
function handleSelectUser(user: User | undefined) {
|
||||
selectedUser.value = user;
|
||||
handleFetchAttachments(1);
|
||||
handleFetchAttachments({ page: 1 });
|
||||
}
|
||||
|
||||
function handleSortItemChange(sortItem?: SortItem) {
|
||||
selectedSortItem.value = sortItem;
|
||||
handleFetchAttachments(1);
|
||||
handleFetchAttachments({ page: 1 });
|
||||
}
|
||||
|
||||
function handleKeywordChange() {
|
||||
|
@ -111,12 +111,12 @@ function handleKeywordChange() {
|
|||
if (keywordNode) {
|
||||
keyword.value = keywordNode._value as string;
|
||||
}
|
||||
handleFetchAttachments(1);
|
||||
handleFetchAttachments({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearKeyword() {
|
||||
keyword.value = "";
|
||||
handleFetchAttachments(1);
|
||||
handleFetchAttachments({ page: 1 });
|
||||
}
|
||||
|
||||
const hasFilters = computed(() => {
|
||||
|
@ -133,7 +133,7 @@ function handleClearFilters() {
|
|||
selectedUser.value = undefined;
|
||||
selectedSortItem.value = undefined;
|
||||
keyword.value = "";
|
||||
handleFetchAttachments(1);
|
||||
handleFetchAttachments({ page: 1 });
|
||||
}
|
||||
|
||||
const {
|
||||
|
@ -208,16 +208,12 @@ const onDetailModalClose = () => {
|
|||
selectedAttachment.value = undefined;
|
||||
nameQuery.value = undefined;
|
||||
nameQueryAttachment.value = undefined;
|
||||
setTimeout(() => {
|
||||
handleFetchAttachments();
|
||||
}, 200);
|
||||
handleFetchAttachments({ mute: true });
|
||||
};
|
||||
|
||||
const onUploadModalClose = () => {
|
||||
routeQueryAction.value = undefined;
|
||||
setTimeout(() => {
|
||||
handleFetchAttachments();
|
||||
}, 200);
|
||||
handleFetchAttachments({ mute: true });
|
||||
};
|
||||
|
||||
const onGroupChange = () => {
|
||||
|
|
|
@ -19,7 +19,7 @@ interface useAttachmentControlReturn {
|
|||
selectedAttachment: Ref<Attachment | undefined>;
|
||||
selectedAttachments: Ref<Set<Attachment>>;
|
||||
checkedAll: Ref<boolean>;
|
||||
handleFetchAttachments: (page?: number) => void;
|
||||
handleFetchAttachments: (options?: { mute?: boolean; page?: number }) => void;
|
||||
handlePaginationChange: ({
|
||||
page,
|
||||
size,
|
||||
|
@ -68,14 +68,19 @@ export function useAttachmentControl(filterOptions?: {
|
|||
const checkedAll = ref(false);
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchAttachments = async (page?: number) => {
|
||||
const handleFetchAttachments = async (options?: {
|
||||
mute?: boolean;
|
||||
page?: number;
|
||||
}) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
if (page) {
|
||||
attachments.value.page = page;
|
||||
if (options?.page) {
|
||||
attachments.value.page = options.page;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.attachment.searchAttachments({
|
||||
|
@ -96,7 +101,7 @@ export function useAttachmentControl(filterOptions?: {
|
|||
|
||||
if (deletedAttachments.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchAttachments();
|
||||
handleFetchAttachments({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -44,14 +44,19 @@ const selectedCommentNames = ref<string[]>([]);
|
|||
const keyword = ref("");
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchComments = async (page?: number) => {
|
||||
const handleFetchComments = async (options?: {
|
||||
mute?: boolean;
|
||||
page?: number;
|
||||
}) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
if (page) {
|
||||
comments.value.page = page;
|
||||
if (options?.page) {
|
||||
comments.value.page = options.page;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.comment.listComments({
|
||||
|
@ -70,7 +75,7 @@ const handleFetchComments = async (page?: number) => {
|
|||
|
||||
if (deletedComments.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchComments();
|
||||
handleFetchComments({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -238,7 +243,7 @@ const handleApprovedFilterItemChange = (filterItem: {
|
|||
}) => {
|
||||
selectedApprovedFilterItem.value = filterItem;
|
||||
selectedCommentNames.value = [];
|
||||
handleFetchComments(1);
|
||||
handleFetchComments({ page: 1 });
|
||||
};
|
||||
|
||||
const handleSortFilterItemChange = (filterItem: {
|
||||
|
@ -247,12 +252,12 @@ const handleSortFilterItemChange = (filterItem: {
|
|||
}) => {
|
||||
selectedSortFilterItem.value = filterItem;
|
||||
selectedCommentNames.value = [];
|
||||
handleFetchComments(1);
|
||||
handleFetchComments({ page: 1 });
|
||||
};
|
||||
|
||||
function handleSelectUser(user: User | undefined) {
|
||||
selectedUser.value = user;
|
||||
handleFetchComments(1);
|
||||
handleFetchComments({ page: 1 });
|
||||
}
|
||||
|
||||
function handleKeywordChange() {
|
||||
|
@ -260,12 +265,12 @@ function handleKeywordChange() {
|
|||
if (keywordNode) {
|
||||
keyword.value = keywordNode._value as string;
|
||||
}
|
||||
handleFetchComments(1);
|
||||
handleFetchComments({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearKeyword() {
|
||||
keyword.value = "";
|
||||
handleFetchComments(1);
|
||||
handleFetchComments({ page: 1 });
|
||||
}
|
||||
|
||||
const hasFilters = computed(() => {
|
||||
|
@ -282,7 +287,7 @@ function handleClearFilters() {
|
|||
selectedSortFilterItem.value = SortFilterItems[0];
|
||||
selectedUser.value = undefined;
|
||||
keyword.value = "";
|
||||
handleFetchComments(1);
|
||||
handleFetchComments({ page: 1 });
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
|
@ -479,7 +484,7 @@ function handleClearFilters() {
|
|||
<CommentListItem
|
||||
:comment="comment"
|
||||
:is-selected="checkSelection(comment)"
|
||||
@reload="handleFetchComments"
|
||||
@reload="handleFetchComments({ mute: true })"
|
||||
>
|
||||
<template #checkbox>
|
||||
<input
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
VEmpty,
|
||||
IconAddCircle,
|
||||
IconExternalLinkLine,
|
||||
VLoading,
|
||||
} from "@halo-dev/components";
|
||||
import ReplyCreationModal from "./ReplyCreationModal.vue";
|
||||
import type {
|
||||
|
@ -114,13 +115,18 @@ const handleApprove = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleFetchReplies = async () => {
|
||||
const handleFetchReplies = async (options?: { mute?: boolean }) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.reply.listReplies({
|
||||
commentName: props.comment.comment.metadata.name,
|
||||
page: 0,
|
||||
size: 0,
|
||||
});
|
||||
replies.value = data.items;
|
||||
|
||||
|
@ -130,7 +136,7 @@ const handleFetchReplies = async () => {
|
|||
|
||||
if (deletedReplies.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchReplies();
|
||||
handleFetchReplies({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -185,7 +191,7 @@ const onTriggerReply = (reply: ListedReply) => {
|
|||
|
||||
const onReplyCreationModalClose = () => {
|
||||
selectedReply.value = undefined;
|
||||
handleFetchReplies();
|
||||
handleFetchReplies({ mute: true });
|
||||
};
|
||||
|
||||
// Subject ref processing
|
||||
|
@ -391,11 +397,9 @@ const subjectRefResult = computed(() => {
|
|||
<div
|
||||
class="ml-8 mt-3 divide-y divide-gray-100 rounded-base border-t border-gray-100 pt-3"
|
||||
>
|
||||
<VEmpty
|
||||
v-if="!replies.length && !loading"
|
||||
message="你可以尝试刷新或者创建新回复"
|
||||
title="当前没有回复"
|
||||
>
|
||||
<VLoading v-if="loading" />
|
||||
<Transition v-else-if="!replies.length" appear name="fade">
|
||||
<VEmpty message="你可以尝试刷新或者创建新回复" title="当前没有回复">
|
||||
<template #actions>
|
||||
<VSpace>
|
||||
<VButton @click="handleFetchReplies">刷新</VButton>
|
||||
|
@ -408,17 +412,21 @@ const subjectRefResult = computed(() => {
|
|||
</VSpace>
|
||||
</template>
|
||||
</VEmpty>
|
||||
</Transition>
|
||||
<Transition v-else appear name="fade">
|
||||
<div>
|
||||
<ReplyListItem
|
||||
v-for="reply in replies"
|
||||
v-else
|
||||
:key="reply.reply.metadata.name"
|
||||
:class="{ 'hover:bg-white': showReplies }"
|
||||
:reply="reply"
|
||||
:replies="replies"
|
||||
@reload="handleFetchReplies"
|
||||
@reload="handleFetchReplies({ mute: true })"
|
||||
@reply="onTriggerReply"
|
||||
></ReplyListItem>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
</VEntity>
|
||||
</template>
|
||||
|
|
|
@ -45,14 +45,19 @@ const checkedAll = ref(false);
|
|||
const refreshInterval = ref();
|
||||
const keyword = ref("");
|
||||
|
||||
const handleFetchSinglePages = async (page?: number) => {
|
||||
const handleFetchSinglePages = async (options?: {
|
||||
mute?: boolean;
|
||||
page?: number;
|
||||
}) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
if (page) {
|
||||
singlePages.value.page = page;
|
||||
if (options?.page) {
|
||||
singlePages.value.page = options.page;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.singlePage.listSinglePages({
|
||||
|
@ -72,7 +77,7 @@ const handleFetchSinglePages = async (page?: number) => {
|
|||
|
||||
if (deletedSinglePages.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchSinglePages();
|
||||
handleFetchSinglePages({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -212,12 +217,12 @@ function handleKeywordChange() {
|
|||
if (keywordNode) {
|
||||
keyword.value = keywordNode._value as string;
|
||||
}
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearKeyword() {
|
||||
keyword.value = "";
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -58,11 +58,16 @@ const selectedPageNames = ref<string[]>([]);
|
|||
const checkedAll = ref(false);
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchSinglePages = async (page?: number) => {
|
||||
const handleFetchSinglePages = async (options?: {
|
||||
mute?: boolean;
|
||||
page?: number;
|
||||
}) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
let contributors: string[] | undefined;
|
||||
const labelSelector: string[] = ["content.halo.run/deleted=false"];
|
||||
|
@ -77,8 +82,8 @@ const handleFetchSinglePages = async (page?: number) => {
|
|||
);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
singlePages.value.page = page;
|
||||
if (options?.page) {
|
||||
singlePages.value.page = options.page;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.singlePage.listSinglePages({
|
||||
|
@ -105,8 +110,8 @@ const handleFetchSinglePages = async (page?: number) => {
|
|||
|
||||
if (abnormalSinglePages.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchSinglePages();
|
||||
}, 1000);
|
||||
handleFetchSinglePages({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch single pages", error);
|
||||
|
@ -142,7 +147,7 @@ const handleOpenSettingModal = async (singlePage: SinglePage) => {
|
|||
|
||||
const onSettingModalClose = () => {
|
||||
selectedSinglePage.value = undefined;
|
||||
handleFetchSinglePages();
|
||||
handleFetchSinglePages({ mute: true });
|
||||
};
|
||||
|
||||
const handleSelectPrevious = async () => {
|
||||
|
@ -361,22 +366,22 @@ const keyword = ref("");
|
|||
|
||||
function handleVisibleItemChange(visibleItem: VisibleItem) {
|
||||
selectedVisibleItem.value = visibleItem;
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
|
||||
const handleSelectUser = (user?: User) => {
|
||||
selectedContributor.value = user;
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
};
|
||||
|
||||
function handlePublishStatusItemChange(publishStatusItem: PublishStatusItem) {
|
||||
selectedPublishStatusItem.value = publishStatusItem;
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
|
||||
function handleSortItemChange(sortItem?: SortItem) {
|
||||
selectedSortItem.value = sortItem;
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
|
||||
function handleKeywordChange() {
|
||||
|
@ -384,12 +389,12 @@ function handleKeywordChange() {
|
|||
if (keywordNode) {
|
||||
keyword.value = keywordNode._value as string;
|
||||
}
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearKeyword() {
|
||||
keyword.value = "";
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
|
||||
const hasFilters = computed(() => {
|
||||
|
@ -408,7 +413,7 @@ function handleClearFilters() {
|
|||
selectedPublishStatusItem.value = PublishStatusItems[0];
|
||||
selectedSortItem.value = undefined;
|
||||
keyword.value = "";
|
||||
handleFetchSinglePages(1);
|
||||
handleFetchSinglePages({ page: 1 });
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -64,11 +64,16 @@ const checkedAll = ref(false);
|
|||
const selectedPostNames = ref<string[]>([]);
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchPosts = async (page?: number) => {
|
||||
const handleFetchPosts = async (options?: {
|
||||
mute?: boolean;
|
||||
page?: number;
|
||||
}) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
let categories: string[] | undefined;
|
||||
let tags: string[] | undefined;
|
||||
|
@ -96,8 +101,8 @@ const handleFetchPosts = async (page?: number) => {
|
|||
);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
posts.value.page = page;
|
||||
if (options?.page) {
|
||||
posts.value.page = options.page;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.post.listPosts({
|
||||
|
@ -126,8 +131,8 @@ const handleFetchPosts = async (page?: number) => {
|
|||
|
||||
if (abnormalPosts.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchPosts();
|
||||
}, 1000);
|
||||
handleFetchPosts({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch posts", e);
|
||||
|
@ -164,7 +169,7 @@ const handleOpenSettingModal = async (post: Post) => {
|
|||
|
||||
const onSettingModalClose = () => {
|
||||
selectedPost.value = undefined;
|
||||
handleFetchPosts();
|
||||
handleFetchPosts({ mute: true });
|
||||
};
|
||||
|
||||
const handleSelectPrevious = async () => {
|
||||
|
@ -376,32 +381,32 @@ const keyword = ref("");
|
|||
|
||||
function handleVisibleItemChange(visibleItem: VisibleItem) {
|
||||
selectedVisibleItem.value = visibleItem;
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handlePublishStatusItemChange(publishStatusItem: PublishStatuItem) {
|
||||
selectedPublishStatusItem.value = publishStatusItem;
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleSortItemChange(sortItem?: SortItem) {
|
||||
selectedSortItem.value = sortItem;
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleCategoryChange(category?: Category) {
|
||||
selectedCategory.value = category;
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleTagChange(tag?: Tag) {
|
||||
selectedTag.value = tag;
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleContributorChange(user?: User) {
|
||||
selectedContributor.value = user;
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleKeywordChange() {
|
||||
|
@ -409,12 +414,12 @@ function handleKeywordChange() {
|
|||
if (keywordNode) {
|
||||
keyword.value = keywordNode._value as string;
|
||||
}
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearKeyword() {
|
||||
keyword.value = "";
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearFilters() {
|
||||
|
@ -425,7 +430,7 @@ function handleClearFilters() {
|
|||
selectedTag.value = undefined;
|
||||
selectedContributor.value = undefined;
|
||||
keyword.value = "";
|
||||
handleFetchPosts(1);
|
||||
handleFetchPosts({ page: 1 });
|
||||
}
|
||||
|
||||
const hasFilters = computed(() => {
|
||||
|
|
|
@ -11,7 +11,7 @@ interface usePostCategoryReturn {
|
|||
categories: Ref<Category[]>;
|
||||
categoriesTree: Ref<CategoryTree[]>;
|
||||
loading: Ref<boolean>;
|
||||
handleFetchCategories: () => void;
|
||||
handleFetchCategories: (fetchOptions?: { mute?: boolean }) => void;
|
||||
handleDelete: (category: CategoryTree) => void;
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,13 @@ export function usePostCategory(options?: {
|
|||
const loading = ref(false);
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchCategories = async () => {
|
||||
const handleFetchCategories = async (fetchOptions?: { mute?: boolean }) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!fetchOptions?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
const { data } =
|
||||
await apiClient.extension.category.listcontentHaloRunV1alpha1Category({
|
||||
page: 0,
|
||||
|
@ -44,7 +46,7 @@ export function usePostCategory(options?: {
|
|||
|
||||
if (deletedCategories.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchCategories();
|
||||
handleFetchCategories({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { onBeforeRouteLeave } from "vue-router";
|
|||
interface usePostTagReturn {
|
||||
tags: Ref<Tag[]>;
|
||||
loading: Ref<boolean>;
|
||||
handleFetchTags: () => void;
|
||||
handleFetchTags: (fetchOptions?: { mute?: boolean }) => void;
|
||||
handleDelete: (tag: Tag) => void;
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,13 @@ export function usePostTag(options?: {
|
|||
const loading = ref(false);
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchTags = async () => {
|
||||
const handleFetchTags = async (fetchOptions?: { mute?: boolean }) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!fetchOptions?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
const { data } =
|
||||
await apiClient.extension.tag.listcontentHaloRunV1alpha1Tag({
|
||||
page: 0,
|
||||
|
@ -40,7 +42,7 @@ export function usePostTag(options?: {
|
|||
|
||||
if (deletedTags.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchTags();
|
||||
handleFetchTags({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -38,11 +38,13 @@ const menuListRef = ref();
|
|||
const menuItemEditingModal = ref();
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchMenuItems = async () => {
|
||||
const handleFetchMenuItems = async (options?: { mute?: boolean }) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
if (!selectedMenu.value?.spec.menuItems) {
|
||||
return;
|
||||
|
@ -65,7 +67,7 @@ const handleFetchMenuItems = async () => {
|
|||
|
||||
if (deletedMenuItems.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchMenuItems();
|
||||
handleFetchMenuItems({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -113,7 +115,7 @@ const onMenuItemSaved = async (menuItem: MenuItem) => {
|
|||
}
|
||||
|
||||
await menuListRef.value.handleFetchMenus();
|
||||
await handleFetchMenuItems();
|
||||
await handleFetchMenuItems({ mute: true });
|
||||
};
|
||||
|
||||
const handleUpdateInBatch = useDebounceFn(async () => {
|
||||
|
@ -131,7 +133,7 @@ const handleUpdateInBatch = useDebounceFn(async () => {
|
|||
console.log("Failed to update menu items", e);
|
||||
} finally {
|
||||
await menuListRef.value.handleFetchMenus();
|
||||
await handleFetchMenuItems();
|
||||
await handleFetchMenuItems({ mute: true });
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
@ -191,7 +193,7 @@ const handleDelete = async (menuItem: MenuTreeItem) => {
|
|||
<MenuList
|
||||
ref="menuListRef"
|
||||
v-model:selected-menu="selectedMenu"
|
||||
@select="handleFetchMenuItems"
|
||||
@select="handleFetchMenuItems()"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
|
@ -229,7 +231,7 @@ const handleDelete = async (menuItem: MenuTreeItem) => {
|
|||
>
|
||||
<template #actions>
|
||||
<VSpace>
|
||||
<VButton @click="handleFetchMenuItems"> 刷新</VButton>
|
||||
<VButton @click="handleFetchMenuItems()"> 刷新</VButton>
|
||||
<VButton
|
||||
v-permission="['system:menus:manage']"
|
||||
type="primary"
|
||||
|
|
|
@ -41,12 +41,14 @@ const selectedMenuToUpdate = ref<Menu>();
|
|||
const menuEditingModal = ref<boolean>(false);
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchMenus = async () => {
|
||||
const handleFetchMenus = async (options?: { mute?: boolean }) => {
|
||||
selectedMenuToUpdate.value = undefined;
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.extension.menu.listv1alpha1Menu();
|
||||
menus.value = data.items;
|
||||
|
@ -67,7 +69,7 @@ const handleFetchMenus = async () => {
|
|||
|
||||
if (deletedMenus.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchMenus();
|
||||
handleFetchMenus({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -187,7 +189,7 @@ onMounted(handleFetchPrimaryMenuName);
|
|||
<MenuEditingModal
|
||||
v-model:visible="menuEditingModal"
|
||||
:menu="selectedMenuToUpdate"
|
||||
@close="handleFetchMenus"
|
||||
@close="handleFetchMenus()"
|
||||
@created="handleSelect"
|
||||
/>
|
||||
<VCard :body-class="['!p-0']" title="菜单">
|
||||
|
@ -196,7 +198,7 @@ onMounted(handleFetchPrimaryMenuName);
|
|||
<VEmpty message="你可以尝试刷新或者新建菜单" title="当前没有菜单">
|
||||
<template #actions>
|
||||
<VSpace>
|
||||
<VButton size="sm" @click="handleFetchMenus"> 刷新</VButton>
|
||||
<VButton size="sm" @click="handleFetchMenus()"> 刷新</VButton>
|
||||
</VSpace>
|
||||
</template>
|
||||
</VEmpty>
|
||||
|
|
|
@ -59,11 +59,13 @@ const modalTitle = computed(() => {
|
|||
|
||||
const { activatedTheme } = storeToRefs(useThemeStore());
|
||||
|
||||
const handleFetchThemes = async () => {
|
||||
const handleFetchThemes = async (options?: { mute?: boolean }) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
const { data } = await apiClient.theme.listThemes({
|
||||
page: 0,
|
||||
size: 0,
|
||||
|
@ -81,7 +83,7 @@ const handleFetchThemes = async () => {
|
|||
|
||||
if (deletedThemes.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchThemes();
|
||||
handleFetchThemes({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -223,7 +225,7 @@ const handleOpenPreview = (theme: Theme) => {
|
|||
>
|
||||
<template #actions>
|
||||
<VSpace>
|
||||
<VButton :loading="loading" @click="handleFetchThemes">
|
||||
<VButton :loading="loading" @click="handleFetchThemes()">
|
||||
刷新
|
||||
</VButton>
|
||||
<VButton
|
||||
|
|
|
@ -41,14 +41,19 @@ const pluginInstall = ref(false);
|
|||
const keyword = ref("");
|
||||
const refreshInterval = ref();
|
||||
|
||||
const handleFetchPlugins = async (page?: number) => {
|
||||
const handleFetchPlugins = async (options?: {
|
||||
mute?: boolean;
|
||||
page?: number;
|
||||
}) => {
|
||||
try {
|
||||
clearInterval(refreshInterval.value);
|
||||
|
||||
if (!options?.mute) {
|
||||
loading.value = true;
|
||||
}
|
||||
|
||||
if (page) {
|
||||
plugins.value.page = page;
|
||||
if (options?.page) {
|
||||
plugins.value.page = options.page;
|
||||
}
|
||||
|
||||
const { data } = await apiClient.plugin.listPlugins({
|
||||
|
@ -69,7 +74,7 @@ const handleFetchPlugins = async (page?: number) => {
|
|||
|
||||
if (deletedPlugins.length) {
|
||||
refreshInterval.value = setInterval(() => {
|
||||
handleFetchPlugins();
|
||||
handleFetchPlugins({ mute: true });
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -139,12 +144,12 @@ const selectedSortItem = ref<SortItem>();
|
|||
|
||||
function handleEnabledItemChange(enabledItem: EnabledItem) {
|
||||
selectedEnabledItem.value = enabledItem;
|
||||
handleFetchPlugins(1);
|
||||
handleFetchPlugins({ page: 1 });
|
||||
}
|
||||
|
||||
function handleSortItemChange(sortItem?: SortItem) {
|
||||
selectedSortItem.value = sortItem;
|
||||
handleFetchPlugins(1);
|
||||
handleFetchPlugins({ page: 1 });
|
||||
}
|
||||
|
||||
function handleKeywordChange() {
|
||||
|
@ -152,12 +157,12 @@ function handleKeywordChange() {
|
|||
if (keywordNode) {
|
||||
keyword.value = keywordNode._value as string;
|
||||
}
|
||||
handleFetchPlugins(1);
|
||||
handleFetchPlugins({ page: 1 });
|
||||
}
|
||||
|
||||
function handleClearKeyword() {
|
||||
keyword.value = "";
|
||||
handleFetchPlugins(1);
|
||||
handleFetchPlugins({ page: 1 });
|
||||
}
|
||||
|
||||
const hasFilters = computed(() => {
|
||||
|
@ -172,14 +177,14 @@ function handleClearFilters() {
|
|||
selectedEnabledItem.value = undefined;
|
||||
selectedSortItem.value = undefined;
|
||||
keyword.value = "";
|
||||
handleFetchPlugins(1);
|
||||
handleFetchPlugins({ page: 1 });
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<PluginUploadModal
|
||||
v-if="currentUserHasPermission(['system:plugins:manage'])"
|
||||
v-model:visible="pluginInstall"
|
||||
@close="handleFetchPlugins"
|
||||
@close="handleFetchPlugins()"
|
||||
/>
|
||||
|
||||
<VPageHeader title="插件">
|
||||
|
@ -320,7 +325,7 @@ function handleClearFilters() {
|
|||
>
|
||||
<template #actions>
|
||||
<VSpace>
|
||||
<VButton @click="handleFetchPlugins">刷新</VButton>
|
||||
<VButton @click="handleFetchPlugins()">刷新</VButton>
|
||||
<VButton
|
||||
v-permission="['system:plugins:manage']"
|
||||
type="secondary"
|
||||
|
@ -342,7 +347,7 @@ function handleClearFilters() {
|
|||
role="list"
|
||||
>
|
||||
<li v-for="(plugin, index) in plugins.items" :key="index">
|
||||
<PluginListItem :plugin="plugin" @reload="handleFetchPlugins" />
|
||||
<PluginListItem :plugin="plugin" @reload="handleFetchPlugins()" />
|
||||
</li>
|
||||
</ul>
|
||||
</Transition>
|
||||
|
|
Loading…
Reference in New Issue