From f6769341bd805074f73575b53c0f96ac42d770e4 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Sat, 7 Jan 2023 23:31:09 +0800 Subject: [PATCH] fix: FixedBlock does not disappear when the current tab is deleted (#1324) * fix: fixed block does not disappear when the current tab is deleted * fix: using template and fixedBlock together causes props to conflict * fix: reference templates do not work properly --- .../schema-component/antd/page/FixedBlock.tsx | 46 +++++++++++----- .../src/schema-component/antd/page/Page.tsx | 55 ++++++++++++------- .../schema-component/hooks/useDesignable.tsx | 4 +- .../src/schema-templates/BlockTemplate.tsx | 8 +-- .../SchemaTemplateManagerProvider.tsx | 5 +- 5 files changed, 72 insertions(+), 46 deletions(-) diff --git a/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx b/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx index 8a1b853bf..518a6732e 100644 --- a/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx +++ b/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx @@ -4,32 +4,37 @@ import { css } from '@emotion/css'; import { SchemaSettings } from '../../../schema-settings'; import { useTranslation } from 'react-i18next'; import { useDesignable } from '../../hooks'; -import { useGridContext } from '../grid'; import { useRecord } from '../../../record-provider'; +import { useBlockTemplateContext } from '../../../schema-templates/BlockTemplate'; const FixedBlockContext = React.createContext({ setFixedSchema: (schema: Schema) => {}, height: 0, - schema: {} as unknown as Schema, + fixedSchemaRef: {} as unknown as React.MutableRefObject, }); export const useFixedSchema = () => { const field = useField(); const fieldSchema = useFieldSchema(); - const { setFixedSchema } = useFixedBlock(); + const { setFixedSchema, fixedSchemaRef } = useFixedBlock(); + const { fieldSchema: templateFieldSchema } = useBlockTemplateContext(); const hasSet = useRef(false); useEffect(() => { if (fieldSchema?.['x-decorator-props']?.fixedBlock) { - setFixedSchema(fieldSchema); + const nextSchema = templateFieldSchema || fieldSchema; + setFixedSchema(nextSchema); hasSet.current = true; + } else if (hasSet.current) { + setFixedSchema(null); } }, [field?.decoratorProps?.fixedBlock, fieldSchema?.['x-decorator-props']?.fixedBlock]); useEffect( () => () => { - if (hasSet.current) { + if (hasSet.current && fixedSchemaRef.current) { setFixedSchema(null); + fixedSchemaRef.current = null; } }, [], @@ -55,15 +60,18 @@ export const useFixedBlockDesignerSetting = () => { { - field.decoratorProps.fixedBlock = fixedBlock; - fieldSchema['x-decorator-props'].fixedBlock = fixedBlock; - dn.emit('patch', { + onChange={async (fixedBlock) => { + const decoratorProps = { + ...fieldSchema['x-decorator-props'], + fixedBlock, + }; + await dn.emit('patch', { schema: { ['x-uid']: fieldSchema['x-uid'], - 'x-decorator-props': fieldSchema['x-decorator-props'], + 'x-decorator-props': decoratorProps, }, }); + field.decoratorProps = fieldSchema['x-decorator-props'] = decoratorProps; }} /> ); @@ -76,14 +84,22 @@ interface FixedBlockProps { const FixedBlock: React.FC = (props) => { const { height } = props; - const [fixedSchema, setFixedSchema] = useState(); + const [fixedSchema, _setFixedSchema] = useState(); + const fixedSchemaRef = useRef(fixedSchema); + + const setFixedSchema = (next) => { + if (fixedSchema && next) { + fixedSchemaRef.current = next; + } + _setFixedSchema(next); + }; + const schema = useMemo(() => { - if (!fixedSchema || fixedSchema['x-decorator-props']?.fixedBlock !== true) return; - return fixedSchema.parent; - }, [fixedSchema, fixedSchema?.['x-decorator-props']['fixedBlock']]); + return fixedSchema?.parent; + }, [fixedSchema]); return ( - + {schema ? (
{
{loading ? ( + ) : !disablePageHeader && enablePageTabs ? ( + fieldSchema.mapProperties((schema) => { + if (schema.name !== activeKey) return null; + return ( + + + + ); + }) ) : ( { height + 46 + 48 } > - {!disablePageHeader && enablePageTabs ? ( - { - return s.name === activeKey; - }} - /> - ) : ( -
.nb-grid:not(:last-child) { - > .nb-schema-initializer-button { - display: none; - } +
.nb-grid:not(:last-child) { + > .nb-schema-initializer-button { + display: none; } - `} - > - {props.children} -
- )} + } + `} + > + {props.children} +
)}
diff --git a/packages/core/client/src/schema-component/hooks/useDesignable.tsx b/packages/core/client/src/schema-component/hooks/useDesignable.tsx index fd29cf98d..eba69d0a8 100644 --- a/packages/core/client/src/schema-component/hooks/useDesignable.tsx +++ b/packages/core/client/src/schema-component/hooks/useDesignable.tsx @@ -239,12 +239,12 @@ export class Designable { this.events[name].push(listener); } - emit(name: 'insertAdjacent' | 'remove' | 'error' | 'patch' | 'batchPatch', ...args) { + async emit(name: 'insertAdjacent' | 'remove' | 'error' | 'patch' | 'batchPatch', ...args) { if (!this.events[name]) { return; } const [opts, ...others] = args; - this.events[name].forEach((fn) => fn.bind(this)({ current: this.current, ...opts }, ...others)); + return Promise.all(this.events[name].map((fn) => fn.bind(this)({ current: this.current, ...opts }, ...others))); } parentsIn(schema: Schema) { diff --git a/packages/core/client/src/schema-templates/BlockTemplate.tsx b/packages/core/client/src/schema-templates/BlockTemplate.tsx index f8ff8faf3..1c1cb19e4 100644 --- a/packages/core/client/src/schema-templates/BlockTemplate.tsx +++ b/packages/core/client/src/schema-templates/BlockTemplate.tsx @@ -19,10 +19,8 @@ export const BlockTemplate = observer((props: any) => { const { t } = useTranslation(); const template = useMemo(() => getTemplateById(templateId), [templateId]); return template ? ( -
- - - -
+ + + ) : null; }); diff --git a/packages/core/client/src/schema-templates/SchemaTemplateManagerProvider.tsx b/packages/core/client/src/schema-templates/SchemaTemplateManagerProvider.tsx index bb63c746f..c01567f45 100644 --- a/packages/core/client/src/schema-templates/SchemaTemplateManagerProvider.tsx +++ b/packages/core/client/src/schema-templates/SchemaTemplateManagerProvider.tsx @@ -39,7 +39,7 @@ export const SchemaTemplateManagerProvider: React.FC = (props) => { }; const regenerateUid = (s: ISchema) => { - s['x-uid'] = uid(); + s['name'] = s['x-uid'] = uid(); Object.keys(s.properties || {}).forEach((key) => { regenerateUid(s.properties[key]); }); @@ -120,10 +120,9 @@ export const useSchemaTemplateManager = () => { return templates?.find((template) => template.key === key); }, getTemplatesByCollection(collectionName: string, resourceName: string = null) { - const items = templates?.filter?.((template) => (template.collectionName === collectionName)); + const items = templates?.filter?.((template) => template.collectionName === collectionName); return items || []; }, - }; };