From d86247d6271f3e1e755fa3612fa8c8346ecb23fb Mon Sep 17 00:00:00 2001
From: lawvs <18554747+lawvs@users.noreply.github.com>
Date: Fri, 5 Aug 2022 22:44:01 +0800
Subject: [PATCH] Revert "Revert "Merge pull request #42 from
toeverything/feat/sub-page""
This reverts commit ecc708017968e4beca2c62979c257ef53cfd5b02.
---
.../blocks/group/scene-kanban/CardContext.tsx | 2 +-
.../blocks/group/scene-kanban/CardItem.tsx | 17 +++-
.../src/{contexts.tsx => Contexts.tsx} | 18 +---
.../components/editor-core/src/RenderRoot.tsx | 6 +-
libs/components/editor-core/src/hooks.ts | 20 ++---
libs/components/editor-core/src/index.ts | 3 +-
.../editor-core/src/kanban/kanban.ts | 2 +-
.../editor-core/src/recast-block/Context.tsx | 5 +-
.../editor-core/src/recast-block/README.md | 19 ----
.../editor-core/src/recast-block/group.ts | 4 +-
.../editor-core/src/ref-page/ModalPage.tsx | 90 +++++++++++++++++++
.../editor-core/src/ref-page/index.ts | 1 +
.../src/render-block/RenderBlock.tsx | 8 +-
libs/components/ui/src/mui.ts | 5 ++
libs/datasource/feature-flags/README.md | 13 ++-
libs/datasource/feature-flags/src/config.ts | 14 +++
16 files changed, 164 insertions(+), 63 deletions(-)
rename libs/components/editor-core/src/{contexts.tsx => Contexts.tsx} (70%)
create mode 100644 libs/components/editor-core/src/ref-page/ModalPage.tsx
create mode 100644 libs/components/editor-core/src/ref-page/index.ts
diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx
index cb313d14ee..f7f05b37d4 100644
--- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx
@@ -25,7 +25,7 @@ const AddCard = ({ group }: { group: KanbanGroup }) => {
const { addCard } = useKanban();
const handleClick = useCallback(async () => {
await addCard(group);
- }, [addCard]);
+ }, [addCard, group]);
return +;
};
diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
index f26374e4c3..76220d7ff0 100644
--- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
@@ -1,6 +1,11 @@
import type { KanbanCard } from '@toeverything/components/editor-core';
-import { RenderBlock, useKanban } from '@toeverything/components/editor-core';
+import {
+ RenderBlock,
+ useKanban,
+ useRefPage,
+} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
+import { useFlag } from '@toeverything/datasource/feature-flags';
const CardContent = styled('div')({
margin: '20px',
@@ -58,18 +63,24 @@ export const CardItem = ({
block: KanbanCard['block'];
}) => {
const { addSubItem } = useKanban();
+ const { openSubPage } = useRefPage();
+ const showKanbanRefPageFlag = useFlag('ShowKanbanRefPage', false);
const onAddItem = async () => {
await addSubItem(block);
};
+ const onClickCard = async () => {
+ showKanbanRefPageFlag && openSubPage(id);
+ };
+
return (
-
+
- Add item
+ Add a sub-block
);
diff --git a/libs/components/editor-core/src/contexts.tsx b/libs/components/editor-core/src/Contexts.tsx
similarity index 70%
rename from libs/components/editor-core/src/contexts.tsx
rename to libs/components/editor-core/src/Contexts.tsx
index cdd4dbf305..418fe0e8b4 100644
--- a/libs/components/editor-core/src/contexts.tsx
+++ b/libs/components/editor-core/src/Contexts.tsx
@@ -1,9 +1,8 @@
import { createContext, useContext } from 'react';
import type { BlockEditor, AsyncBlock } from './editor';
-import type { Column } from '@toeverything/datasource/db-service';
import { genErrorObj } from '@toeverything/utils';
-export const RootContext = createContext<{
+const RootContext = createContext<{
editor: BlockEditor;
// TODO: Temporary fix, dependencies in the new architecture are bottom-up, editors do not need to be passed down from the top
editorElement: () => JSX.Element;
@@ -14,6 +13,8 @@ export const RootContext = createContext<{
) as any
);
+export const EditorProvider = RootContext.Provider;
+
export const useEditor = () => {
return useContext(RootContext);
};
@@ -22,16 +23,3 @@ export const useEditor = () => {
* @deprecated
*/
export const BlockContext = createContext(null as any);
-
-/**
- * Context of column information
- *
- * @deprecated
- */
-export const ColumnsContext = createContext<{
- fromId: string;
- columns: Column[];
-}>({
- fromId: '',
- columns: [],
-});
diff --git a/libs/components/editor-core/src/RenderRoot.tsx b/libs/components/editor-core/src/RenderRoot.tsx
index 1d08db0b16..e4534b813d 100644
--- a/libs/components/editor-core/src/RenderRoot.tsx
+++ b/libs/components/editor-core/src/RenderRoot.tsx
@@ -2,7 +2,7 @@ import type { BlockEditor } from './editor';
import { styled, usePatchNodes } from '@toeverything/components/ui';
import type { FC, PropsWithChildren } from 'react';
import React, { useEffect, useRef, useState, useCallback } from 'react';
-import { RootContext } from './contexts';
+import { EditorProvider } from './Contexts';
import { SelectionRect, SelectionRef } from './Selection';
import {
Protocol,
@@ -151,7 +151,7 @@ export const RenderRoot: FC> = ({
};
return (
-
+
{
@@ -183,7 +183,7 @@ export const RenderRoot: FC> = ({
{editor.isWhiteboard ? null : }
{patchedNodes}
-
+
);
};
diff --git a/libs/components/editor-core/src/hooks.ts b/libs/components/editor-core/src/hooks.ts
index d7d1a00cef..f0af8a0f87 100644
--- a/libs/components/editor-core/src/hooks.ts
+++ b/libs/components/editor-core/src/hooks.ts
@@ -1,3 +1,6 @@
+import { noop, Point } from '@toeverything/utils';
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { useEditor } from './Contexts';
import {
AsyncBlock,
BlockEditor,
@@ -5,9 +8,6 @@ import {
SelectionInfo,
SelectionSettingsMap,
} from './editor';
-import { noop, Point } from '@toeverything/utils';
-import { useCallback, useContext, useEffect, useRef, useState } from 'react';
-import { RootContext } from './contexts';
function useRequestReRender() {
const [, setUpdateCounter] = useState(0);
@@ -56,7 +56,7 @@ function useRequestReRender() {
export const useBlock = (blockId: string) => {
const [block, setBlock] = useState();
const requestReRender = useRequestReRender();
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
if (!blockId) {
return undefined;
@@ -95,7 +95,7 @@ export const useOnSelect = (
blockId: string,
cb: (isSelect: boolean) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.observe(blockId, SelectEventTypes.onSelect, cb);
return () => {
@@ -117,7 +117,7 @@ export const useOnSelectActive = (
blockId: string,
cb: (position: Point | undefined) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.observe(blockId, SelectEventTypes.active, cb);
return () => {
@@ -139,7 +139,7 @@ export const useOnSelectSetSelection = (
blockId: string,
cb: (args: SelectionSettingsMap[T]) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.observe(
blockId,
@@ -162,7 +162,7 @@ export const useOnSelectSetSelection = (
* @export
*/
export const useOnSelectChange = (cb: (info: SelectionInfo) => void) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.onSelectionChange(cb);
return () => {
@@ -177,7 +177,7 @@ export const useOnSelectChange = (cb: (info: SelectionInfo) => void) => {
* @export
*/
export const useOnSelectEnd = (cb: (info: SelectionInfo) => void) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.onSelectEnd(cb);
return () => {
@@ -195,7 +195,7 @@ export const useOnSelectStartWith = (
blockId: string,
cb: (args: MouseEvent) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.mouseManager.onSelectStartWith(blockId, cb);
return () => {
diff --git a/libs/components/editor-core/src/index.ts b/libs/components/editor-core/src/index.ts
index 6cdd358058..bea2fed3a0 100644
--- a/libs/components/editor-core/src/index.ts
+++ b/libs/components/editor-core/src/index.ts
@@ -1,4 +1,3 @@
-export { ColumnsContext, RootContext } from './contexts';
export { RenderRoot, MIN_PAGE_WIDTH } from './RenderRoot';
export * from './render-block';
export * from './hooks';
@@ -16,3 +15,5 @@ export * from './kanban/types';
export * from './utils';
export * from './editor';
+
+export { RefPageProvider, useRefPage } from './ref-page';
diff --git a/libs/components/editor-core/src/kanban/kanban.ts b/libs/components/editor-core/src/kanban/kanban.ts
index ff33b17f1d..218476ac44 100644
--- a/libs/components/editor-core/src/kanban/kanban.ts
+++ b/libs/components/editor-core/src/kanban/kanban.ts
@@ -1,6 +1,6 @@
import { Protocol } from '@toeverything/datasource/db-service';
import { useCallback, useContext, useEffect, useState } from 'react';
-import { useEditor } from '../contexts';
+import { useEditor } from '../Contexts';
import { AsyncBlock } from '../editor';
import { useRecastView } from '../recast-block';
import { useRecastBlock } from '../recast-block/Context';
diff --git a/libs/components/editor-core/src/recast-block/Context.tsx b/libs/components/editor-core/src/recast-block/Context.tsx
index 55d334039b..47ec6cfcdb 100644
--- a/libs/components/editor-core/src/recast-block/Context.tsx
+++ b/libs/components/editor-core/src/recast-block/Context.tsx
@@ -2,6 +2,7 @@ import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock } from '../editor';
import { ComponentType, createContext, ReactNode, useContext } from 'react';
import { RecastBlock } from './types';
+import { RefPageProvider } from '../ref-page';
/**
* Determine whether the block supports RecastBlock
@@ -47,7 +48,7 @@ export const RecastBlockProvider = ({
return (
- {children}
+ {children}
);
};
@@ -60,7 +61,7 @@ export const useRecastBlock = () => {
const recastBlock = useContext(RecastBlockContext);
if (!recastBlock) {
throw new Error(
- 'Failed to find recastBlock! Please use the hook under `RecastTableProvider`.'
+ 'Failed to find recastBlock! Please use the hook under `RecastBlockProvider`.'
);
}
return recastBlock;
diff --git a/libs/components/editor-core/src/recast-block/README.md b/libs/components/editor-core/src/recast-block/README.md
index 59aed91be7..489412eab3 100644
--- a/libs/components/editor-core/src/recast-block/README.md
+++ b/libs/components/editor-core/src/recast-block/README.md
@@ -49,22 +49,3 @@ const SomeBlock = () => {
return ...
;
};
```
-
-## Scene
-
-**Notice: The scene API will refactor at next version.**
-
-```tsx
-const SomeBlock = () => {
- const { scene, setScene, setPage, setTable, setKanban } =
- useRecastBlockScene();
-
- return (
- <>
- Scene: {scene}
-
-
- >
- );
-};
-```
diff --git a/libs/components/editor-core/src/recast-block/group.ts b/libs/components/editor-core/src/recast-block/group.ts
index ae846fc238..9879ba43df 100644
--- a/libs/components/editor-core/src/recast-block/group.ts
+++ b/libs/components/editor-core/src/recast-block/group.ts
@@ -32,7 +32,7 @@ export const mergeGroup = async (...groups: AsyncBlock[]) => {
);
}
- await mergeGroupProperties(...(groups as RecastBlock[]));
+ await mergeGroupProperties(...(groups as unknown as RecastBlock[]));
const [headGroup, ...restGroups] = groups;
// Add all children to the head group
@@ -174,7 +174,7 @@ export const splitGroup = async (
}
splitGroupProperties(
- group as RecastBlock,
+ group as unknown as RecastBlock,
newGroupBlock as unknown as RecastBlock
);
await group.after(newGroupBlock);
diff --git a/libs/components/editor-core/src/ref-page/ModalPage.tsx b/libs/components/editor-core/src/ref-page/ModalPage.tsx
new file mode 100644
index 0000000000..276d5984d6
--- /dev/null
+++ b/libs/components/editor-core/src/ref-page/ModalPage.tsx
@@ -0,0 +1,90 @@
+import { MuiBackdrop, styled, useTheme } from '@toeverything/components/ui';
+import { createContext, ReactNode, useContext, useState } from 'react';
+import { createPortal } from 'react-dom';
+import { useEditor } from '../Contexts';
+import { RenderBlock } from '../render-block';
+
+const Dialog = styled('div')({
+ flex: 1,
+ width: '880px',
+ margin: '72px auto',
+ background: '#fff',
+ boxShadow: '0px 1px 10px rgba(152, 172, 189, 0.6)',
+ borderRadius: '10px',
+ padding: '72px 120px',
+ overflow: 'scroll',
+});
+
+const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => {
+ const theme = useTheme();
+ const { closeSubPage } = useRefPage();
+
+ return createPortal(
+
+
+ ,
+
+ document.body
+ );
+};
+
+const ModalPage = ({ blockId }: { blockId: string | null }) => {
+ const { editor } = useEditor();
+
+ return (
+
+ {blockId && }
+
+ );
+};
+
+const RefPageContext = createContext<
+ ReturnType> | undefined
+>(undefined);
+
+export const RefPageProvider = ({ children }: { children: ReactNode }) => {
+ const state = useState();
+ const [blockId, setBlockId] = state;
+
+ return (
+
+ {children}
+
+
+ );
+};
+
+export const useRefPage = () => {
+ const context = useContext(RefPageContext);
+ if (!context) {
+ throw new Error(
+ 'Wrap your app inside of a `SubPageProvider` to have access to the hook context!'
+ );
+ }
+ const [blockId, setBlockId] = context;
+ const openSubPage = (blockId: string) => {
+ setBlockId(blockId);
+ };
+ const closeSubPage = () => {
+ setBlockId(null);
+ };
+
+ return { blockId, open: !!blockId, openSubPage, closeSubPage };
+};
+
+// export const openSubPage = () => {};
diff --git a/libs/components/editor-core/src/ref-page/index.ts b/libs/components/editor-core/src/ref-page/index.ts
new file mode 100644
index 0000000000..4b06310a5c
--- /dev/null
+++ b/libs/components/editor-core/src/ref-page/index.ts
@@ -0,0 +1 @@
+export { useRefPage, RefPageProvider } from './ModalPage';
diff --git a/libs/components/editor-core/src/render-block/RenderBlock.tsx b/libs/components/editor-core/src/render-block/RenderBlock.tsx
index 46f068af2b..74f6c659cf 100644
--- a/libs/components/editor-core/src/render-block/RenderBlock.tsx
+++ b/libs/components/editor-core/src/render-block/RenderBlock.tsx
@@ -1,8 +1,8 @@
-import { styled, Theme } from '@toeverything/components/ui';
-import { FC, useContext, useLayoutEffect, useMemo, useRef } from 'react';
+import { styled } from '@toeverything/components/ui';
+import { FC, useLayoutEffect, useMemo, useRef } from 'react';
// import { RenderChildren } from './RenderChildren';
-import { RootContext } from '../contexts';
+import { useEditor } from '../Contexts';
import { useBlock } from '../hooks';
interface RenderBlockProps {
@@ -14,7 +14,7 @@ export const RenderBlock: FC = ({
blockId,
hasContainer = true,
}) => {
- const { editor, editorElement } = useContext(RootContext);
+ const { editor, editorElement } = useEditor();
const { block } = useBlock(blockId);
const blockRef = useRef(null);
diff --git a/libs/components/ui/src/mui.ts b/libs/components/ui/src/mui.ts
index b0658ad526..47588ce5e6 100644
--- a/libs/components/ui/src/mui.ts
+++ b/libs/components/ui/src/mui.ts
@@ -13,6 +13,7 @@ import type {
} from '@mui/material';
import {
Avatar,
+ Backdrop,
Box,
Button,
Checkbox,
@@ -243,3 +244,7 @@ export const MuiFade = Fade;
* @deprecated It is not recommended to use Mui directly, because the design will not refer to Mui's interaction logic.
*/
export const MuiRadio = Radio;
+/**
+ * @deprecated It is not recommended to use Mui directly, because the design will not refer to Mui's interaction logic.
+ */
+export const MuiBackdrop = Backdrop;
diff --git a/libs/datasource/feature-flags/README.md b/libs/datasource/feature-flags/README.md
index f5c59f4e13..7a04209c5d 100644
--- a/libs/datasource/feature-flags/README.md
+++ b/libs/datasource/feature-flags/README.md
@@ -2,7 +2,15 @@
## Usage
-- set provider
+- Set token at environment variable
+ - The key can be obtained from the [Feature Flag Portal](https://portal.featureflag.co/account-settings/projects)
+
+```shell
+# .env.local
+AFFINE_FEATURE_FLAG_TOKEN=XXXXXXX
+```
+
+- Set provider
```tsx
import { FeatureFlagsProvider } from '@toeverything/datasource/feature-flags';
@@ -42,7 +50,8 @@ const App = () => {
**When entering development mode feature flag will NOT be updated in real time**
-- `activateFfcDevMode()` play with feature flags locally
+- `activateFfcDevMode(PASSWORD)` play with feature flags locally
+ - The `devModePassword` can be obtained from `src/config.ts`
- `quitFfcDevMode()` quit dev mode
## Running unit tests
diff --git a/libs/datasource/feature-flags/src/config.ts b/libs/datasource/feature-flags/src/config.ts
index 7f3360d6db..5295dae995 100644
--- a/libs/datasource/feature-flags/src/config.ts
+++ b/libs/datasource/feature-flags/src/config.ts
@@ -8,4 +8,18 @@ export const config: IOption = {
// id: 'the user's unique identifier'
// }
devModePassword: '-',
+ enableDataSync: !!process.env['AFFINE_FEATURE_FLAG_TOKEN'],
+ // bootstrap: [
+ // {
+ // // the feature flag key
+ // id: 'flag',
+ // // the feature flag value
+ // variation: false,
+ // // the variation data type, string is used if not provided
+ // variationType: VariationDataType.boolean,
+ // variationOptions: [],
+ // timestamp: 0,
+ // sendToExperiment: false,
+ // },
+ // ],
};