Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Commit

Permalink
refactor: api of dialog component (#646)
Browse files Browse the repository at this point in the history
#### What type of PR is this?

/kind api-change
/kind improvement
/milestone 2.0

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

重构 Dialog 组件使用 API 的调用方式,改为与 Toast 组件一致。#644

同样的,使用此方式调用 Dialog 组件不限制在 Vue 组件。

#### Special notes for your reviewer:

/cc @halo-dev/sig-halo-console 

需要测试后台各个操作的会话框是否正常。

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

```release-note
重构 Dialog 组件使用 API 的调用方式。
```
  • Loading branch information
ruibaby committed Oct 18, 2022
1 parent 6d8a2dd commit 512ee82
Show file tree
Hide file tree
Showing 26 changed files with 153 additions and 164 deletions.
29 changes: 18 additions & 11 deletions packages/components/src/components/dialog/Dialog.story.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { VButton } from "@/components/button";
import { VDialog } from "@/components/dialog";
import { Dialog } from "@/components/dialog";
const initState = () => {
return {
Expand All @@ -18,19 +18,26 @@ const initState = () => {
},
};
};
function handleConfirm() {
Dialog.success({
title: "Hello",
description: "Hello World",
onConfirm: async () => {
await new Promise((resolve) =>
setTimeout(() => {
console.log("Timeout");
resolve("");
}, 1000)
);
},
});
}
</script>
<template>
<Story :init-state="initState" title="Dialog">
<template #default="{ state }">
<VButton type="danger" @click="state.visible = true">删除</VButton>
<VDialog
:cancel-text="state.cancelText"
:confirm-text="state.confirmText"
:description="state.description"
:title="state.title"
:type="state.type"
:visible="state.visible"
></VDialog>
<template #default>
<VButton @click="handleConfirm">确定</VButton>
</template>
</Story>
</template>
27 changes: 0 additions & 27 deletions packages/components/src/components/dialog/DialogProvider.vue

This file was deleted.

75 changes: 75 additions & 0 deletions packages/components/src/components/dialog/dialog-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import DialogComponent from "./Dialog.vue";
import { createVNode, render, type Component } from "vue";
import type { DialogProps } from "./interface";

export type DialogApiProps = Omit<DialogProps, "type" | "visible">;

export type DialogApi = (props?: DialogApiProps) => void;

export interface DialogEntry {
(props: DialogProps): void;
info: DialogApi;
success: DialogApi;
error: DialogApi;
warning: DialogApi;
}

const defaultProps: DialogProps = {
title: "",
visible: false,
};

const dialog: DialogEntry = (userProps: DialogProps) => {
const props = {
...defaultProps,
...userProps,
};

let container = document.body.querySelector(".dialog-container");
if (!container) {
container = document.createElement("div");
container.className = "dialog-container";
document.body.appendChild(container);
}

const { vnode, container: hostContainer } = createVNodeComponent(
DialogComponent,
props
);

if (hostContainer.firstElementChild) {
container.appendChild(hostContainer.firstElementChild);
}

if (vnode.component?.props) {
vnode.component.props.visible = true;
}

if (vnode?.props) {
// close emit

vnode.props.onClose = () => {
container?.remove();
render(null, hostContainer);
};
}
};

function createVNodeComponent(
component: Component,
props: Record<string, unknown>
) {
const vnode = createVNode(component, props);
const container = document.createElement("div");
render(vnode, container);
return { vnode, container };
}

dialog.success = (props?: DialogApiProps) =>
dialog({ ...props, type: "success" });
dialog.info = (props?: DialogApiProps) => dialog({ ...props, type: "info" });
dialog.warning = (props?: DialogApiProps) =>
dialog({ ...props, type: "warning" });
dialog.error = (props?: DialogApiProps) => dialog({ ...props, type: "error" });

export { dialog as Dialog };
3 changes: 1 addition & 2 deletions packages/components/src/components/dialog/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export { default as VDialog } from "./Dialog.vue";
export { default as VDialogProvider } from "./DialogProvider.vue";
export * from "./use-dialog";
export { Dialog } from "./dialog-manager";
12 changes: 12 additions & 0 deletions packages/components/src/components/dialog/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,16 @@ export interface useDialogOptions {
onCancel?: () => void;
}

export interface DialogProps {
type?: Type;
visible?: boolean;
title?: string;
description?: string;
confirmType?: ButtonType;
confirmText?: string;
cancelText?: string;
onConfirm?: () => void;
onCancel?: () => void;
}

export type useDialogUserOptions = Omit<useDialogOptions, "type" | "visible">;
39 changes: 0 additions & 39 deletions packages/components/src/components/dialog/use-dialog.ts

This file was deleted.

5 changes: 2 additions & 3 deletions packages/shared/src/layouts/BasicLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
VAvatar,
VSpace,
VButton,
useDialog,
Dialog,
} from "@halo-dev/components";
import type { MenuGroupType, MenuItemType } from "../types/menus";
import type { User } from "@halo-dev/api-client";
Expand All @@ -21,7 +21,6 @@ const menus = inject<MenuGroupType[]>("menus");
const minimenus = inject<MenuItemType[]>("minimenus");
const route = useRoute();
const router = useRouter();
const dialog = useDialog();
const moreMenuVisible = ref(false);
const moreMenuRootVisible = ref(false);
Expand All @@ -34,7 +33,7 @@ const handleRouteToProfile = () => {
};
const handleLogout = () => {
dialog.warning({
Dialog.warning({
title: "是否确认退出登录?",
onConfirm: async () => {
try {
Expand Down
7 changes: 2 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts" setup>
import { RouterView, useRoute } from "vue-router";
import { VDialogProvider } from "@halo-dev/components";
import { onMounted, provide, ref, watch, type Ref } from "vue";
import { useTitle } from "@vueuse/core";
import GlobalSearchModal from "@/components/global-search/GlobalSearchModal.vue";
Expand Down Expand Up @@ -41,10 +40,8 @@ onMounted(() => {
</script>

<template>
<VDialogProvider>
<RouterView />
<GlobalSearchModal v-model:visible="globalSearchVisible" />
</VDialogProvider>
<RouterView />
<GlobalSearchModal v-model:visible="globalSearchVisible" />
</template>

<style lang="scss">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
IconCheckboxFill,
VCard,
IconDeleteBin,
useDialog,
Dialog,
} from "@halo-dev/components";
import type { AttachmentLike } from "@halo-dev/console-shared";
Expand Down Expand Up @@ -103,10 +103,8 @@ const handleSelect = async (attachment: Attachment | undefined) => {
selectedAttachments.value.add(attachment);
};
const dialog = useDialog();
const handleDelete = async (attachment: Attachment) => {
dialog.warning({
Dialog.warning({
title: "确定要删除当前的附件吗?",
confirmType: "danger",
onConfirm: async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { Ref } from "vue";
import { ref, watch } from "vue";
import type { AttachmentLike } from "@halo-dev/console-shared";
import { apiClient } from "@/utils/api-client";
import { useDialog } from "@halo-dev/components";
import { Dialog } from "@halo-dev/components";
import type { Content, Editor } from "@halo-dev/richtext-editor";

interface useAttachmentControlReturn {
Expand Down Expand Up @@ -64,8 +64,6 @@ export function useAttachmentControl(filterOptions?: {
const selectedAttachments = ref<Set<Attachment>>(new Set<Attachment>());
const checkedAll = ref(false);

const dialog = useDialog();

const handleFetchAttachments = async () => {
try {
loading.value = true;
Expand Down Expand Up @@ -133,7 +131,7 @@ export function useAttachmentControl(filterOptions?: {
};

const handleDelete = (attachment: Attachment) => {
dialog.warning({
Dialog.warning({
title: "确定要删除该附件吗?",
description: "删除之后将无法恢复",
confirmType: "danger",
Expand All @@ -160,7 +158,7 @@ export function useAttachmentControl(filterOptions?: {
};

const handleDeleteInBatch = () => {
dialog.warning({
Dialog.warning({
title: "确定要删除所选的附件吗?",
description: "删除之后将无法恢复",
confirmType: "danger",
Expand Down
8 changes: 3 additions & 5 deletions src/modules/contents/comments/CommentList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
VSpace,
IconCloseCircle,
VEmpty,
useDialog,
Dialog,
} from "@halo-dev/components";
import CommentListItem from "./components/CommentListItem.vue";
import UserDropdownSelector from "@/components/dropdown-selector/UserDropdownSelector.vue";
Expand All @@ -21,8 +21,6 @@ import type {
import { onMounted, ref, watch } from "vue";
import { apiClient } from "@/utils/api-client";

const dialog = useDialog();

const comments = ref<ListedCommentList>({
page: 1,
size: 20,
Expand Down Expand Up @@ -101,7 +99,7 @@ watch(
);

const handleDeleteInBatch = async () => {
dialog.warning({
Dialog.warning({
title: "确定要删除所选的评论吗?",
description: "将同时删除所有评论下的回复,该操作不可恢复。",
confirmType: "danger",
Expand All @@ -126,7 +124,7 @@ const handleDeleteInBatch = async () => {
};

const handleApproveInBatch = async () => {
dialog.warning({
Dialog.warning({
title: "确定要审核通过所选评论吗?",
onConfirm: async () => {
try {
Expand Down
8 changes: 3 additions & 5 deletions src/modules/contents/comments/components/CommentListItem.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import {
useDialog,
Dialog,
VAvatar,
VButton,
VEntity,
Expand Down Expand Up @@ -44,8 +44,6 @@ const emit = defineEmits<{
(event: "reload"): void;
}>();

const dialog = useDialog();

const replies = ref<ListedReply[]>([] as ListedReply[]);
const selectedReply = ref<ListedReply>();
const hoveredReply = ref<ListedReply>();
Expand All @@ -56,7 +54,7 @@ const replyModal = ref(false);
provide<Ref<ListedReply | undefined>>("hoveredReply", hoveredReply);

const handleDelete = async () => {
dialog.warning({
Dialog.warning({
title: "是否确认删除该评论?",
description: "删除评论的同时会删除该评论下的所有回复,该操作不可恢复。",
confirmType: "danger",
Expand All @@ -75,7 +73,7 @@ const handleDelete = async () => {
};

const handleApproveReplyInBatch = async () => {
dialog.warning({
Dialog.warning({
title: "确定要审核通过该评论的所有回复吗?",
onConfirm: async () => {
try {
Expand Down
Loading

0 comments on commit 512ee82

Please sign in to comment.