mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-19 15:26:59 +08:00
feat(core): sidebar local workspace enable cloud directly (#6366)
- Add a new hook `useEnableClould`, remove `<EnableAffineClouldModal />` - Sidebar local workspace list item support enable AFFiNE Cloud
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
|
||||
import type { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { CollaborationIcon, SettingsIcon } from '@blocksuite/icons';
|
||||
import type { WorkspaceMetadata } from '@toeverything/infra';
|
||||
import { useCallback } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { type MouseEvent, useCallback } from 'react';
|
||||
|
||||
import { Avatar, type AvatarProps } from '../../../ui/avatar';
|
||||
import { Button } from '../../../ui/button';
|
||||
import { Skeleton } from '../../../ui/skeleton';
|
||||
import * as styles from './styles.css';
|
||||
|
||||
@@ -18,7 +20,10 @@ export interface WorkspaceCardProps {
|
||||
meta: WorkspaceMetadata;
|
||||
onClick: (metadata: WorkspaceMetadata) => void;
|
||||
onSettingClick: (metadata: WorkspaceMetadata) => void;
|
||||
onEnableCloudClick?: (meta: WorkspaceMetadata) => void;
|
||||
isOwner?: boolean;
|
||||
openingId?: string | null;
|
||||
enableCloudText?: string;
|
||||
avatar?: string;
|
||||
name?: string;
|
||||
}
|
||||
@@ -45,13 +50,25 @@ const avatarImageProps = {
|
||||
export const WorkspaceCard = ({
|
||||
onClick,
|
||||
onSettingClick,
|
||||
onEnableCloudClick,
|
||||
openingId,
|
||||
currentWorkspaceId,
|
||||
meta,
|
||||
isOwner = true,
|
||||
enableCloudText = 'Enable Cloud',
|
||||
name,
|
||||
avatar,
|
||||
}: WorkspaceCardProps) => {
|
||||
const isLocal = meta.flavour === WorkspaceFlavour.LOCAL;
|
||||
const displayName = name ?? UNTITLED_WORKSPACE_NAME;
|
||||
|
||||
const onEnableCloud = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
onEnableCloudClick?.(meta);
|
||||
},
|
||||
[meta, onEnableCloudClick]
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={styles.card}
|
||||
@@ -73,6 +90,17 @@ export const WorkspaceCard = ({
|
||||
<div className={styles.workspaceTitle}>{displayName}</div>
|
||||
|
||||
<div className={styles.actionButtons}>
|
||||
{isLocal ? (
|
||||
<Button
|
||||
loading={!!openingId && openingId === meta.id}
|
||||
disabled={!!openingId}
|
||||
type="default"
|
||||
className={clsx(styles.enableCloudButton, styles.showOnCardHover)}
|
||||
onClick={onEnableCloud}
|
||||
>
|
||||
{enableCloudText}
|
||||
</Button>
|
||||
) : null}
|
||||
{isOwner ? null : <CollaborationIcon />}
|
||||
<div
|
||||
className={styles.settingButton}
|
||||
|
||||
@@ -84,3 +84,16 @@ export const settingButton = style({
|
||||
// },
|
||||
},
|
||||
});
|
||||
|
||||
export const enableCloudButton = style({
|
||||
background: 'transparent',
|
||||
});
|
||||
|
||||
export const showOnCardHover = style({
|
||||
display: 'none',
|
||||
selectors: {
|
||||
[`.${card}:hover &`]: {
|
||||
display: 'block',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,8 +19,10 @@ export interface WorkspaceListProps {
|
||||
disabled?: boolean;
|
||||
currentWorkspaceId?: string | null;
|
||||
items: WorkspaceMetadata[];
|
||||
openingId?: string | null;
|
||||
onClick: (workspace: WorkspaceMetadata) => void;
|
||||
onSettingClick: (workspace: WorkspaceMetadata) => void;
|
||||
onEnableCloudClick?: (meta: WorkspaceMetadata) => void;
|
||||
onDragEnd: (event: DragEndEvent) => void;
|
||||
useIsWorkspaceOwner: (workspaceMetadata: WorkspaceMetadata) => boolean;
|
||||
useWorkspaceAvatar: (
|
||||
@@ -38,12 +40,14 @@ interface SortableWorkspaceItemProps extends Omit<WorkspaceListProps, 'items'> {
|
||||
const SortableWorkspaceItem = ({
|
||||
disabled,
|
||||
item,
|
||||
openingId,
|
||||
useIsWorkspaceOwner,
|
||||
useWorkspaceAvatar,
|
||||
useWorkspaceName,
|
||||
currentWorkspaceId,
|
||||
onClick,
|
||||
onSettingClick,
|
||||
onEnableCloudClick,
|
||||
}: SortableWorkspaceItemProps) => {
|
||||
const { setNodeRef, attributes, listeners, transform, transition } =
|
||||
useSortable({
|
||||
@@ -77,6 +81,8 @@ const SortableWorkspaceItem = ({
|
||||
meta={item}
|
||||
onClick={onClick}
|
||||
onSettingClick={onSettingClick}
|
||||
onEnableCloudClick={onEnableCloudClick}
|
||||
openingId={openingId}
|
||||
isOwner={isOwner}
|
||||
name={name}
|
||||
avatar={avatar}
|
||||
|
||||
@@ -56,9 +56,16 @@ export const ConfirmModal = ({
|
||||
);
|
||||
};
|
||||
|
||||
interface OpenConfirmModalOptions {
|
||||
autoClose?: boolean;
|
||||
onSuccess?: () => void;
|
||||
}
|
||||
interface ConfirmModalContextProps {
|
||||
modalProps: ConfirmModalProps;
|
||||
openConfirmModal: (props?: ConfirmModalProps) => void;
|
||||
openConfirmModal: (
|
||||
props?: ConfirmModalProps,
|
||||
options?: OpenConfirmModalOptions
|
||||
) => void;
|
||||
closeConfirmModal: () => void;
|
||||
}
|
||||
const ConfirmModalContext = createContext<ConfirmModalContextProps>({
|
||||
@@ -86,7 +93,8 @@ export const ConfirmModalProvider = ({ children }: PropsWithChildren) => {
|
||||
}, []);
|
||||
|
||||
const openConfirmModal = useCallback(
|
||||
(props?: ConfirmModalProps) => {
|
||||
(props?: ConfirmModalProps, options?: OpenConfirmModalOptions) => {
|
||||
const { autoClose = true, onSuccess } = options ?? {};
|
||||
if (!props) {
|
||||
setModalProps({ open: true });
|
||||
return;
|
||||
@@ -97,17 +105,22 @@ export const ConfirmModalProvider = ({ children }: PropsWithChildren) => {
|
||||
const onConfirm = () => {
|
||||
setLoading(true);
|
||||
_onConfirm?.()
|
||||
?.catch(console.error)
|
||||
?.finally(() => closeConfirmModal());
|
||||
?.then(() => onSuccess?.())
|
||||
.catch(console.error)
|
||||
.finally(() => autoClose && closeConfirmModal());
|
||||
};
|
||||
setModalProps({ ...otherProps, onConfirm, open: true });
|
||||
},
|
||||
[closeConfirmModal, setLoading]
|
||||
);
|
||||
|
||||
const onOpenChange = useCallback((open: boolean) => {
|
||||
setModalProps(props => ({ ...props, open }));
|
||||
}, []);
|
||||
const onOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
modalProps.onOpenChange?.(open);
|
||||
setModalProps(props => ({ ...props, open }));
|
||||
},
|
||||
[modalProps]
|
||||
);
|
||||
|
||||
return (
|
||||
<ConfirmModalContext.Provider
|
||||
@@ -115,7 +128,7 @@ export const ConfirmModalProvider = ({ children }: PropsWithChildren) => {
|
||||
>
|
||||
{children}
|
||||
{/* TODO: multi-instance support(unnecessary for now) */}
|
||||
<ConfirmModal onOpenChange={onOpenChange} {...modalProps} />
|
||||
<ConfirmModal {...modalProps} onOpenChange={onOpenChange} />
|
||||
</ConfirmModalContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user