mirror of https://github.com/halo-dev/halo-admin
refactor: simplify MenuItem with targetRef instead of multi refs (#730)
#### What type of PR is this? /kind improvement /milestone 2.0 #### What this PR does / why we need it: 重构菜单项关联关系的引用方式。适配:https://github.com/halo-dev/halo/pull/2799 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/2739 #### Special notes for your reviewer: 测试方式: 1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/2799 分支。 2. Console 需要 `pnpm install` 3. 创建若干带有关联关系的菜单项,检查创建和更新是否正常。 #### Does this PR introduce a user-facing change? ```release-note None ```pull/733/head^2
parent
ed5b3c1496
commit
87fc8cacbd
|
@ -32,7 +32,7 @@
|
|||
"@formkit/themes": "^1.0.0-beta.12",
|
||||
"@formkit/utils": "^1.0.0-beta.12",
|
||||
"@formkit/vue": "^1.0.0-beta.12",
|
||||
"@halo-dev/api-client": "^0.0.56",
|
||||
"@halo-dev/api-client": "^0.0.58",
|
||||
"@halo-dev/components": "workspace:*",
|
||||
"@halo-dev/console-shared": "workspace:*",
|
||||
"@halo-dev/richtext-editor": "^0.0.0-alpha.16",
|
||||
|
|
|
@ -12,7 +12,7 @@ importers:
|
|||
'@formkit/themes': ^1.0.0-beta.12
|
||||
'@formkit/utils': ^1.0.0-beta.12
|
||||
'@formkit/vue': ^1.0.0-beta.12
|
||||
'@halo-dev/api-client': ^0.0.56
|
||||
'@halo-dev/api-client': ^0.0.58
|
||||
'@halo-dev/components': workspace:*
|
||||
'@halo-dev/console-shared': workspace:*
|
||||
'@halo-dev/richtext-editor': ^0.0.0-alpha.16
|
||||
|
@ -104,7 +104,7 @@ importers:
|
|||
'@formkit/themes': 1.0.0-beta.12-e579559_tailwindcss@3.2.4
|
||||
'@formkit/utils': 1.0.0-beta.12-e579559
|
||||
'@formkit/vue': 1.0.0-beta.12-e579559_ior6jr3fpijijuwpr34w2i25va
|
||||
'@halo-dev/api-client': 0.0.56
|
||||
'@halo-dev/api-client': 0.0.58
|
||||
'@halo-dev/components': link:packages/components
|
||||
'@halo-dev/console-shared': link:packages/shared
|
||||
'@halo-dev/richtext-editor': 0.0.0-alpha.16_vue@3.2.45
|
||||
|
@ -1962,8 +1962,8 @@ packages:
|
|||
- windicss
|
||||
dev: false
|
||||
|
||||
/@halo-dev/api-client/0.0.56:
|
||||
resolution: {integrity: sha512-Htwyk+pFNVGRrOLcabyNTPc5RQS/RwdUizrGWxRErBCXj4NIQyMYv3owcNS1lOMtsKXyfG1NX/cJKIw3g9y1WQ==}
|
||||
/@halo-dev/api-client/0.0.58:
|
||||
resolution: {integrity: sha512-CGDsHYrtVXD47Lt3S+KYJkyFZsrO85KE8wcuVb2y1iFLspTkKAPxD20Fuhf4TJYS/FVfjEi/esvU4sptTdLVjQ==}
|
||||
dev: false
|
||||
|
||||
/@halo-dev/richtext-editor/0.0.0-alpha.16_vue@3.2.45:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { VButton, VModal, VSpace } from "@halo-dev/components";
|
||||
import SubmitButton from "@/components/button/SubmitButton.vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import type { Menu, MenuItem } from "@halo-dev/api-client";
|
||||
import type { Menu, MenuItem, Ref } from "@halo-dev/api-client";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
import { reset } from "@formkit/core";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
|
@ -56,19 +56,15 @@ const handleSaveMenuItem = async () => {
|
|||
try {
|
||||
saving.value = true;
|
||||
|
||||
const menuItemSource = menuItemSources.find(
|
||||
(source) => source.value === selectedMenuItemSource.value
|
||||
const menuItemRef = menuItemRefs.find(
|
||||
(ref) => ref.ref?.kind === selectedRefKind.value
|
||||
);
|
||||
|
||||
if (menuItemSource) {
|
||||
const { ref } = menuItemSource;
|
||||
if (ref) {
|
||||
formState.value.spec[ref] = {
|
||||
version: "content.halo.run/v1alpha1",
|
||||
kind: menuItemSource.kind,
|
||||
name: selectedRef.value as string,
|
||||
};
|
||||
}
|
||||
if (menuItemRef) {
|
||||
formState.value.spec.targetRef = {
|
||||
...menuItemRef.ref,
|
||||
name: selectedRefName.value,
|
||||
};
|
||||
}
|
||||
|
||||
if (isUpdateMode.value) {
|
||||
|
@ -123,8 +119,8 @@ const onVisibleChange = (visible: boolean) => {
|
|||
|
||||
const handleResetForm = () => {
|
||||
formState.value = cloneDeep(initialFormState);
|
||||
selectedMenuItemSource.value = menuItemSources[0].value;
|
||||
selectedRef.value = "";
|
||||
selectedRefKind.value = "";
|
||||
selectedRefName.value = "";
|
||||
selectedParentMenuItem.value = "";
|
||||
reset("menuitem-form");
|
||||
};
|
||||
|
@ -137,7 +133,7 @@ watch(
|
|||
setFocus("displayNameInput");
|
||||
|
||||
if (!props.menuItem) {
|
||||
selectedRef.value = "";
|
||||
selectedRefName.value = "";
|
||||
}
|
||||
} else {
|
||||
handleResetForm();
|
||||
|
@ -152,79 +148,88 @@ watch(
|
|||
formState.value = cloneDeep(menuItem);
|
||||
|
||||
// Set Ref related
|
||||
const { postRef, categoryRef, tagRef, singlePageRef } =
|
||||
formState.value.spec;
|
||||
const { targetRef } = formState.value.spec;
|
||||
|
||||
if (postRef) {
|
||||
selectedMenuItemSource.value = "post";
|
||||
selectedRef.value = postRef.name;
|
||||
if (!targetRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (categoryRef) {
|
||||
selectedMenuItemSource.value = "category";
|
||||
selectedRef.value = categoryRef.name;
|
||||
}
|
||||
|
||||
if (tagRef) {
|
||||
selectedMenuItemSource.value = "tag";
|
||||
selectedRef.value = tagRef.name;
|
||||
}
|
||||
|
||||
if (singlePageRef) {
|
||||
selectedMenuItemSource.value = "singlePage";
|
||||
selectedRef.value = singlePageRef.name;
|
||||
}
|
||||
selectedRefName.value = targetRef.name;
|
||||
selectedRefKind.value = targetRef.kind as string;
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// MenuItem Ref
|
||||
interface MenuItemSource {
|
||||
interface MenuItemRef {
|
||||
label: string;
|
||||
value: string;
|
||||
ref?: "postRef" | "categoryRef" | "tagRef" | "singlePageRef";
|
||||
kind?: "Post" | "Category" | "Tag" | "SinglePage";
|
||||
inputType?: string;
|
||||
ref?: Ref;
|
||||
}
|
||||
|
||||
const menuItemSources: MenuItemSource[] = [
|
||||
const baseRef: Ref = {
|
||||
group: "content.halo.run",
|
||||
version: "v1alpha1",
|
||||
name: "",
|
||||
};
|
||||
|
||||
const menuItemRefs: MenuItemRef[] = [
|
||||
{
|
||||
label: "自定义链接",
|
||||
value: "custom",
|
||||
},
|
||||
{
|
||||
label: "文章",
|
||||
value: "post",
|
||||
ref: "postRef",
|
||||
kind: "Post",
|
||||
inputType: "postSelect",
|
||||
ref: {
|
||||
...baseRef,
|
||||
kind: "Post",
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "自定义页面",
|
||||
value: "singlePage",
|
||||
ref: "singlePageRef",
|
||||
kind: "SinglePage",
|
||||
inputType: "singlePageSelect",
|
||||
ref: {
|
||||
...baseRef,
|
||||
kind: "SinglePage",
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "分类",
|
||||
value: "category",
|
||||
ref: "categoryRef",
|
||||
kind: "Post",
|
||||
inputType: "categorySelect",
|
||||
ref: {
|
||||
...baseRef,
|
||||
kind: "Category",
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "标签",
|
||||
value: "tag",
|
||||
ref: "tagRef",
|
||||
kind: "Tag",
|
||||
inputType: "tagSelect",
|
||||
ref: {
|
||||
...baseRef,
|
||||
kind: "Tag",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const selectedMenuItemSource = ref<string>(menuItemSources[0].value);
|
||||
const menuItemRefsMap = menuItemRefs.map((menuItemRef) => {
|
||||
return {
|
||||
label: menuItemRef.label,
|
||||
value: menuItemRef.ref?.kind,
|
||||
};
|
||||
});
|
||||
|
||||
const selectedRef = ref<string>("");
|
||||
const selectedRef = computed(() => {
|
||||
return menuItemRefs.find(
|
||||
(menuItemRef) => menuItemRef.ref?.kind === selectedRefKind.value
|
||||
);
|
||||
});
|
||||
|
||||
const selectedRefKind = ref<string>("");
|
||||
const selectedRefName = ref<string>("");
|
||||
|
||||
const onMenuItemSourceChange = () => {
|
||||
selectedRef.value = "";
|
||||
selectedRefName.value = "";
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
|
@ -252,8 +257,8 @@ const onMenuItemSourceChange = () => {
|
|||
/>
|
||||
|
||||
<FormKit
|
||||
v-model="selectedMenuItemSource"
|
||||
:options="menuItemSources"
|
||||
v-model="selectedRefKind"
|
||||
:options="menuItemRefsMap"
|
||||
:disabled="isUpdateMode"
|
||||
label="类型"
|
||||
type="select"
|
||||
|
@ -261,7 +266,7 @@ const onMenuItemSourceChange = () => {
|
|||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'custom'"
|
||||
v-if="!selectedRefKind"
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="名称"
|
||||
|
@ -271,7 +276,7 @@ const onMenuItemSourceChange = () => {
|
|||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'custom'"
|
||||
v-if="!selectedRefKind"
|
||||
v-model="formState.spec.href"
|
||||
label="链接地址"
|
||||
type="text"
|
||||
|
@ -280,37 +285,13 @@ const onMenuItemSourceChange = () => {
|
|||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'post'"
|
||||
v-model="selectedRef"
|
||||
placeholder="请选择文章"
|
||||
label="文章"
|
||||
type="postSelect"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'singlePage'"
|
||||
v-model="selectedRef"
|
||||
label="自定义页面"
|
||||
type="singlePageSelect"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'tag'"
|
||||
v-model="selectedRef"
|
||||
placeholder="请选择标签"
|
||||
label="标签"
|
||||
type="tagSelect"
|
||||
validation="required"
|
||||
/>
|
||||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'category'"
|
||||
v-model="selectedRef"
|
||||
placeholder="请选择分类"
|
||||
label="分类"
|
||||
type="categorySelect"
|
||||
v-if="selectedRef?.ref"
|
||||
:id="selectedRef.inputType"
|
||||
:key="selectedRef.inputType"
|
||||
v-model="selectedRefName"
|
||||
:placeholder="`请选择${selectedRef.label}`"
|
||||
:label="selectedRef.label"
|
||||
:type="selectedRef.inputType"
|
||||
validation="required"
|
||||
/>
|
||||
</FormKit>
|
||||
|
|
|
@ -48,19 +48,20 @@ function onDelete(menuItem: MenuTreeItem) {
|
|||
emit("delete", menuItem);
|
||||
}
|
||||
|
||||
const TargetRef = {
|
||||
Post: "文章",
|
||||
SinglePage: "页面",
|
||||
Category: "分类",
|
||||
Tag: "标签",
|
||||
};
|
||||
|
||||
function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
|
||||
if (menuItem.spec.postRef) {
|
||||
return "文章";
|
||||
}
|
||||
if (menuItem.spec.singlePageRef) {
|
||||
return "自定义页面";
|
||||
}
|
||||
if (menuItem.spec.categoryRef) {
|
||||
return "分类";
|
||||
}
|
||||
if (menuItem.spec.tagRef) {
|
||||
return "标签";
|
||||
const { kind } = menuItem.spec.targetRef || {};
|
||||
|
||||
if (kind && TargetRef[kind]) {
|
||||
return TargetRef[kind];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
</script>
|
||||
|
@ -89,7 +90,7 @@ function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
|
|||
</div>
|
||||
</template>
|
||||
<template #start>
|
||||
<VEntityField :title="menuItem.status.displayName">
|
||||
<VEntityField :title="menuItem.status?.displayName">
|
||||
<template #extra>
|
||||
<VTag v-if="getMenuItemRefDisplayName(menuItem)">
|
||||
{{ getMenuItemRefDisplayName(menuItem) }}
|
||||
|
|
Loading…
Reference in New Issue