diff --git a/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx b/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx index 86881478ff..86b43908d1 100644 --- a/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx +++ b/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx @@ -1,12 +1,12 @@ -import { useState } from 'react'; -import { CreateView } from '@toeverything/framework/virgo'; import { BlockPendantProvider, useOnSelect, } from '@toeverything/components/editor-core'; -import { Upload } from '../../components/upload/upload'; +import { CreateView } from '@toeverything/framework/virgo'; +import { useState } from 'react'; import { SourceView } from '../../components/source-view'; import { LinkContainer } from '../../components/style-container'; +import { Upload } from '../../components/upload/upload'; const MESSAGES = { ADD_EMBED_LINK: 'Add embed link', @@ -38,7 +38,6 @@ export const EmbedLinkView = (props: EmbedLinkView) => { {embedLinkUrl ? ( *': { + visibility: 'hidden', + position: 'absolute', + right: '24px', + top: '16px', + }, + '&:hover > *': { + visibility: 'visible', + }, +}); + export const CardItem = ({ id, block, @@ -64,24 +91,43 @@ export const CardItem = ({ }) => { const { addSubItem } = useKanban(); const { openSubPage } = useRefPage(); + const [editable, setEditable] = useState(false); const showKanbanRefPageFlag = useFlag('ShowKanbanRefPage', false); + const { editor } = useEditor(); + const onAddItem = async () => { + setEditable(true); await addSubItem(block); }; const onClickCard = async () => { - showKanbanRefPageFlag && openSubPage(id); + openSubPage(id); + }; + + const onClickPen = (e: MouseEvent) => { + e.stopPropagation(); + setEditable(true); + editor.selectionManager.activeNodeByNodeId(block.id); }; return ( - - - - - - - Add a sub-block - - + setEditable(false)}> + + + + + {showKanbanRefPageFlag && !editable && ( + + + + + + )} + + + Add a sub-block + + + ); }; diff --git a/libs/components/editor-core/src/ref-page/ModalPage.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/RefPage.tsx similarity index 80% rename from libs/components/editor-core/src/ref-page/ModalPage.tsx rename to libs/components/editor-blocks/src/blocks/group/scene-kanban/RefPage.tsx index 52e1d6554f..3d223d121d 100644 --- a/libs/components/editor-core/src/ref-page/ModalPage.tsx +++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/RefPage.tsx @@ -1,7 +1,7 @@ +import { useEditor } from '@toeverything/components/editor-core'; import { MuiBackdrop, styled, useTheme } from '@toeverything/components/ui'; import { createContext, ReactNode, useContext, useState } from 'react'; import { createPortal } from 'react-dom'; -import { RenderBlock } from '../render-block'; const Dialog = styled('div')({ flex: 1, @@ -30,7 +30,7 @@ const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => { onClick={closeSubPage} > { + onClick={(e: { stopPropagation: () => void }) => { e.stopPropagation(); }} > @@ -43,9 +43,21 @@ const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => { }; const ModalPage = ({ blockId }: { blockId: string | null }) => { + const { editor, editorElement } = useEditor(); + + const AffineEditor = editorElement as any; + return ( - {blockId && } + {blockId && ( + + )} ); }; diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx index 27d5543177..73424708a7 100644 --- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx +++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx @@ -4,30 +4,33 @@ import { SceneKanbanContext } from './context'; import { CardContainerWrapper } from './dndable/wrapper/CardContainerWrapper'; import type { ComponentType } from 'react'; import type { CreateView } from '@toeverything/framework/virgo'; +import { RefPageProvider } from './RefPage'; export const SceneKanban: ComponentType = withKanban( ({ editor, block }) => { const { kanban } = useKanban(); return ( - - ( - - )} - /> - + + + ( + + )} + /> + + ); } ); diff --git a/libs/components/editor-blocks/src/components/source-view/BlockView.tsx b/libs/components/editor-blocks/src/components/source-view/BlockView.tsx index 33c0f5d66c..0b2c953312 100644 --- a/libs/components/editor-blocks/src/components/source-view/BlockView.tsx +++ b/libs/components/editor-blocks/src/components/source-view/BlockView.tsx @@ -1,9 +1,9 @@ -import { memo, useEffect, useRef, useState } from 'react'; import { nanoid } from 'nanoid'; +import { memo, useEffect, useRef, useState } from 'react'; import { StyledBlockPreview } from '@toeverything/components/common'; +import { AsyncBlock, useEditor } from '@toeverything/components/editor-core'; import { services } from '@toeverything/datasource/db-service'; -import { AsyncBlock } from '@toeverything/framework/virgo'; import { debounce, sleep } from '@toeverything/utils'; const updateTitle = async ( @@ -73,15 +73,15 @@ const useBlockTitle = (block: AsyncBlock, blockId: string) => { type BlockPreviewProps = { block: AsyncBlock; blockId: string; - editorElement?: () => JSX.Element; }; const InternalBlockPreview = (props: BlockPreviewProps) => { const container = useRef(); const [preview, setPreview] = useState(true); const title = useBlockTitle(props.block, props.blockId); + const { editorElement } = useEditor(); - const AffineEditor = props.editorElement as any; + const AffineEditor = editorElement as any; useEffect(() => { if (container?.current) { diff --git a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx index b03189d7d4..27d19433bf 100644 --- a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx +++ b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx @@ -1,17 +1,15 @@ import { AsyncBlock, useCurrentView, - useLazyIframe, } from '@toeverything/components/editor-core'; import { styled } from '@toeverything/components/ui'; -import { ReactElement, ReactNode, useEffect, useRef, useState } from 'react'; +import { ReactNode, useEffect, useRef, useState } from 'react'; import { SCENE_CONFIG } from '../../blocks/group/config'; import { BlockPreview } from './BlockView'; import { formatUrl } from './format-url'; export interface Props { block: AsyncBlock; - editorElement?: () => JSX.Element; viewType?: string; link: string; // onResizeEnd: (data: any) => void; @@ -150,7 +148,7 @@ const LoadingContiner = () => { }; export const SourceView = (props: Props) => { - const { link, isSelected, block, editorElement } = props; + const { link, isSelected, block } = props; const src = formatUrl(link); // let iframeShow = useLazyIframe(src, 3000, iframeContainer); const [currentView] = useCurrentView(); @@ -161,10 +159,7 @@ export const SourceView = (props: Props) => { - + ); @@ -175,11 +170,7 @@ export const SourceView = (props: Props) => { style={{ padding: '0' }} scene={type} > - + ); } diff --git a/libs/components/editor-core/src/editor/views/base-view.ts b/libs/components/editor-core/src/editor/views/base-view.ts index b69cdd848a..eb5c293243 100644 --- a/libs/components/editor-core/src/editor/views/base-view.ts +++ b/libs/components/editor-core/src/editor/views/base-view.ts @@ -18,7 +18,6 @@ import { SelectBlock } from '../selection'; export interface CreateView { block: AsyncBlock; editor: Editor; - editorElement: () => JSX.Element; /** * @deprecated Use recast table instead */ diff --git a/libs/components/editor-core/src/index.ts b/libs/components/editor-core/src/index.ts index bea2fed3a0..d28d8e96b3 100644 --- a/libs/components/editor-core/src/index.ts +++ b/libs/components/editor-core/src/index.ts @@ -16,4 +16,4 @@ export * from './utils'; export * from './editor'; -export { RefPageProvider, useRefPage } from './ref-page'; +export { useEditor } from './Contexts'; diff --git a/libs/components/editor-core/src/recast-block/Context.tsx b/libs/components/editor-core/src/recast-block/Context.tsx index 47ec6cfcdb..4236ede55a 100644 --- a/libs/components/editor-core/src/recast-block/Context.tsx +++ b/libs/components/editor-core/src/recast-block/Context.tsx @@ -2,7 +2,6 @@ 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 @@ -48,7 +47,7 @@ export const RecastBlockProvider = ({ return ( - {children} + {children} ); }; diff --git a/libs/components/editor-core/src/ref-page/index.ts b/libs/components/editor-core/src/ref-page/index.ts deleted file mode 100644 index 4b06310a5c..0000000000 --- a/libs/components/editor-core/src/ref-page/index.ts +++ /dev/null @@ -1 +0,0 @@ -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 0627aba95b..0a1531a709 100644 --- a/libs/components/editor-core/src/render-block/RenderBlock.tsx +++ b/libs/components/editor-core/src/render-block/RenderBlock.tsx @@ -13,7 +13,7 @@ export function RenderBlock({ blockId, hasContainer = true, }: RenderBlockProps) { - const { editor, editorElement } = useEditor(); + const { editor } = useEditor(); const { block } = useBlock(blockId); const setRef = useCallback( @@ -50,7 +50,6 @@ export function RenderBlock({ block={block} columns={columns.columns} columnsFromId={columns.fromId} - editorElement={editorElement} /> ); diff --git a/libs/components/editor-plugins/src/index.ts b/libs/components/editor-plugins/src/index.ts index 73cfece84f..4c6ce9a1e1 100644 --- a/libs/components/editor-plugins/src/index.ts +++ b/libs/components/editor-plugins/src/index.ts @@ -21,7 +21,7 @@ export const plugins: PluginCreator[] = [ CommandMenuPlugin, DoubleLinkMenuPlugin, TemplatePlugin, - SelectionGroupPlugin, + // SelectionGroupPlugin, AddCommentPlugin, GroupMenuPlugin, ]; diff --git a/tools/executors/svgOptimize/executor.json b/tools/executors/svgOptimize/executor.json deleted file mode 100644 index 1c19a2f9c5..0000000000 --- a/tools/executors/svgOptimize/executor.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "executors": { - "svgOptimize": { - "implementation": "./svgo.js", - "schema": "./schema.json", - "description": "Run `svgo` (to optimize svg)." - } - } -} diff --git a/tools/executors/svgOptimize/package.json b/tools/executors/svgOptimize/package.json deleted file mode 100644 index 721ff1df5d..0000000000 --- a/tools/executors/svgOptimize/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "executors": "./executor.json" -} diff --git a/tools/executors/svgOptimize/schema.json b/tools/executors/svgOptimize/schema.json deleted file mode 100644 index dc2fdc029b..0000000000 --- a/tools/executors/svgOptimize/schema.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "type": "object", - "cli": "nx", - "properties": { - "svgOptimize": { - "type": "string", - "description": "optimize svg" - } - } -} diff --git a/tools/executors/svgOptimize/svgo.js b/tools/executors/svgOptimize/svgo.js deleted file mode 100644 index a0f6c21539..0000000000 --- a/tools/executors/svgOptimize/svgo.js +++ /dev/null @@ -1,133 +0,0 @@ -const path = require('path'); -const svgo = require('svgo'); -const { readdir, readFile, writeFile, exists } = require('fs/promises'); -const { pascalCase, paramCase } = require('change-case'); -const svgr = require('@svgr/core'); - -async function optimizeSvg(folder) { - try { - const icons = await readdir(folder); - const generateIcons = icons - .filter(n => n.endsWith('.svg')) - .map(async icon => { - let originSvg; - try { - originSvg = await readFile(path.resolve(folder, icon)); - } catch (err) { - console.error(err); - } - let optimizedSvg; - try { - const data = optimize(originSvg); - optimizedSvg = data.data; - } catch (err) { - console.error(err); - } - - const JSXContent = await getJSXContent( - pascalCase(icon), - optimizedSvg - ); - - const iconName = path.basename(icon, '.svg'); - await writeFile( - path.resolve(folder, `${iconName}.tsx`), - JSXContent, - { encoding: 'utf8', flag: '' } - ); - - console.log('Generated:', iconName); - }); - - await Promise.allSettled([ - ...generateIcons, - generateImportEntry(icons, folder), - ]); - } catch (err) { - console.error(err); - } -} - -function optimize(input) { - return svgo.optimize(input, { - plugins: [ - 'preset-default', - 'prefixIds', - { - name: 'sortAttrs', - params: { - xmlnsOrder: 'alphabetical', - }, - }, - ], - }); -} - -/** - * get icon component template - * - * @param {string} name - */ -async function getJSXContent(name, svgCode) { - let svgrContent = ''; - try { - svgrContent = await svgr.transform( - svgCode, - { - icon: true, - typescript: true, - }, - { componentName: `${name}Icon1` } - ); - } catch (err) { - console.error(err); - } - let matcher = svgrContent.match(/]+)>([\s\S]*?)<\/svg>/); - return ` -import { SvgIcon, SvgIconProps } from '@mui/material'; -export const ${name}Icon = (props: SvgIconProps) => ( - - ${matcher[2]} - -); -`; -} - -async function generateImportEntry(iconNodes, folder) { - const fileWithImportsPath = path.resolve(folder, 'index.ts'); - - const importsContent = iconNodes - .map(iconNode => { - const iconName = paramCase(iconNode.name); - if (!iconName) { - return `// Error: ${iconNode.name}`; - } - - return `export * from './${iconName}/${iconName}';`; - }) - .join('\n'); - - await fs.writeFile( - fileWithImportsPath, - `export const timestamp = ${Date.now()};\n${importsContent}`, - { encoding: 'utf8' } - ); -} - -/** - * @param {*} options - * @param {array} options.assets - * @param {string} options.assets.folder - * @param {*} context - * @returns - */ -exports['default'] = async function svgo(options, context) { - const libRoot = context.workspace.projects[context.projectName].root; - await Promise.allSettled( - (options.assets || []).map(async (asset, index) => { - await optimizeSvg(path.resolve(libRoot, asset.folder)); - }) - ); - - return { success: true }; -};