refactor: use patch api to refactor menu drag-and-drop sorting feature (#6462)

#### What type of PR is this?

/area ui
/kind improvement
/milestone 2.19.x

#### What this PR does / why we need it:

使用 patch 接口重构菜单项拖动排序等功能。

#### Which issue(s) this PR fixes:

None

#### Special notes for your reviewer:

需要测试菜单项的拖动排序功能是否符合预期。

#### Does this PR introduce a user-facing change?

```release-note
使用 patch 接口重构菜单项拖动排序功能。
```
pull/6482/head
Ryan Wang 2024-08-16 22:42:33 +08:00 committed by GitHub
parent 10e3f57ca0
commit 7774eb1a3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 60 additions and 39 deletions

View File

@ -15,7 +15,6 @@ import {
} from "@halo-dev/components";
import { useQuery, useQueryClient } from "@tanstack/vue-query";
import { useDebounceFn } from "@vueuse/core";
import { cloneDeep } from "lodash-es";
import { computed, ref } from "vue";
import { useI18n } from "vue-i18n";
import MenuItemEditingModal from "./components/MenuItemEditingModal.vue";
@ -94,23 +93,26 @@ const onMenuItemEditingModalClose = () => {
};
const onMenuItemSaved = async (menuItem: MenuItem) => {
const menuToUpdate = cloneDeep(selectedMenu.value);
if (!selectedMenu.value) {
return;
}
// update menu items
if (
menuToUpdate &&
!menuToUpdate.spec.menuItems?.includes(menuItem.metadata.name)
) {
menuToUpdate.spec.menuItems = [
...(menuToUpdate.spec.menuItems || []),
menuItem.metadata.name,
];
await coreApiClient.menu.updateMenu({
name: menuToUpdate.metadata.name,
menu: menuToUpdate,
});
}
await coreApiClient.menu.patchMenu({
name: selectedMenu.value.metadata.name,
jsonPatchInner: [
{
op: "add",
path: "/spec/menuItems",
value: Array.from(
new Set([
...(selectedMenu.value.spec.menuItems || []),
menuItem.metadata.name,
])
),
},
],
});
await queryClient.invalidateQueries({ queryKey: ["menus"] });
await refetch();
@ -124,9 +126,20 @@ const handleUpdateInBatch = useDebounceFn(async () => {
try {
batchUpdating.value = true;
const promises = menuItemsToUpdate.map((menuItem) =>
coreApiClient.menuItem.updateMenuItem({
coreApiClient.menuItem.patchMenuItem({
name: menuItem.metadata.name,
menuItem,
jsonPatchInner: [
{
op: "add",
path: "/spec/priority",
value: menuItem.spec.priority || 0,
},
{
op: "add",
path: "/spec/children",
value: menuItem.spec.children || [],
},
],
})
);
await Promise.all(promises);
@ -165,16 +178,20 @@ const handleDelete = async (menuItem: MenuTreeItem) => {
await refetch();
// update items under menu
const menuToUpdate = cloneDeep(selectedMenu.value);
if (menuToUpdate) {
menuToUpdate.spec.menuItems = menuToUpdate.spec.menuItems?.filter(
(name) => ![menuItem.metadata.name, ...childrenNames].includes(name)
);
await coreApiClient.menu.updateMenu({
name: menuToUpdate.metadata.name,
menu: menuToUpdate,
});
}
await coreApiClient.menu.patchMenu({
name: selectedMenu.value?.metadata.name as string,
jsonPatchInner: [
{
op: "add",
path: "/spec/menuItems",
value:
selectedMenu.value?.spec.menuItems?.filter(
(name) =>
![menuItem.metadata.name, ...childrenNames].includes(name)
) || [],
},
],
});
await queryClient.invalidateQueries({ queryKey: ["menus"] });

View File

@ -12,7 +12,7 @@ import { useI18n } from "vue-i18n";
const props = withDefaults(
defineProps<{
menu: Menu;
parentMenuItem: MenuItem;
parentMenuItem?: MenuItem;
menuItem?: MenuItem;
}>(),
{
@ -100,19 +100,23 @@ const handleSaveMenuItem = async () => {
// if parent menu item is selected, add the new menu item to the parent menu item
if (selectedParentMenuItem.value) {
const { data: menuItemToUpdate } =
const { data: parentMenuItem } =
await coreApiClient.menuItem.getMenuItem({
name: selectedParentMenuItem.value,
});
menuItemToUpdate.spec.children = [
...(menuItemToUpdate.spec.children || []),
data.metadata.name,
];
await coreApiClient.menuItem.updateMenuItem({
name: menuItemToUpdate.metadata.name,
menuItem: menuItemToUpdate,
await coreApiClient.menuItem.patchMenuItem({
name: selectedParentMenuItem.value,
jsonPatchInner: [
{
op: "add",
path: "/spec/children",
value: [
...(parentMenuItem.spec.children || []),
data.metadata.name,
],
},
],
});
}
@ -218,7 +222,7 @@ onMounted(() => {
}
}
selectedParentMenuItem.value = props.parentMenuItem?.metadata.name;
selectedParentMenuItem.value = props.parentMenuItem?.metadata.name || "";
setFocus("displayNameInput");
});