fix: 完善右键全屏 (#1572)
Reviewed-on: daoyoucloud/tachybase#1572 Co-authored-by: wjh <wwwjh0710@163.com> Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
parent
5cb9529900
commit
17f9f3b00b
@ -450,7 +450,7 @@ export const InternalAdminLayout = (props: any) => {
|
||||
{params.name && <Layout.Sider className={styles.sider} theme={'light'} ref={sideMenuRef}></Layout.Sider>}
|
||||
<Layout.Content className={styles.main}>
|
||||
<header className={styles.mainHeader}></header>
|
||||
{params.name && pageStyle === 'tab' ? <PageTab /> : <Outlet />}
|
||||
<div className="amplifier-block">{params.name && pageStyle === 'tab' ? <PageTab /> : <Outlet />}</div>
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { uid } from '@tachybase/utils/client';
|
||||
|
||||
import { css } from '@emotion/css';
|
||||
import { App } from 'antd';
|
||||
@ -92,56 +93,91 @@ export const disableRightMenu = {
|
||||
};
|
||||
|
||||
const checkedAutoPage = (position, message, t) => {
|
||||
const layoutSider = document.querySelector('.ant-layout-sider');
|
||||
const layoutContent = document.querySelector('.ant-layout-content');
|
||||
const sibling = layoutContent.previousElementSibling;
|
||||
if (!sibling.classList.contains('autoPage')) {
|
||||
const element = document.elementFromPoint(position?.x, position?.y);
|
||||
const blockElement = element.closest('.ant-card');
|
||||
const gridRow = blockElement?.closest('.CardRow');
|
||||
const navbar = document.querySelector('.ant-layout-header');
|
||||
const modal = blockElement.closest('.ant-modal-body');
|
||||
const amplifierBlock = blockElement.closest('.amplifier-block');
|
||||
const navbarHeight = navbar.getBoundingClientRect();
|
||||
const classId = uid();
|
||||
if (blockElement) {
|
||||
//需要展示的区块
|
||||
const copyBlockElement = blockElement.cloneNode(true);
|
||||
copyBlockElement.style.width = '100%';
|
||||
copyBlockElement.style.height = '90vh';
|
||||
copyBlockElement.style.overflow = 'auto';
|
||||
copyBlockElement.style.backgroundColor = '#ffffff';
|
||||
|
||||
const page = blockElement?.closest('.ant-nb-page ');
|
||||
const drawer = blockElement?.closest('.ant-drawer-body');
|
||||
const modal = blockElement?.closest('.ant-modal-body');
|
||||
const tabNav = amplifierBlock.querySelector('.ant-tabs-nav');
|
||||
if (tabNav) tabNav.style.display = 'none';
|
||||
const parentNode = gridRow.parentNode;
|
||||
Array.from(parentNode.children).forEach((sibling) => {
|
||||
if (sibling !== gridRow) {
|
||||
sibling.style.display = 'none';
|
||||
}
|
||||
});
|
||||
const autoNode = document.createElement('div');
|
||||
autoNode.style.marginTop = `${navbarHeight.height}px`;
|
||||
autoNode.style.width = '100%';
|
||||
autoNode.className = 'autoPage';
|
||||
autoNode.style.width = amplifierBlock.getBoundingClientRect().width + 'px';
|
||||
autoNode.className = 'autoPage' + classId;
|
||||
autoNode.style.position = 'fixed';
|
||||
autoNode.style.top = '0';
|
||||
autoNode.style.zIndex = '100';
|
||||
//退出按钮
|
||||
const exitNode = document.createElement('div');
|
||||
exitNode.style.width = '100%';
|
||||
exitNode.style.height = '4vh';
|
||||
exitNode.style.height = '30px';
|
||||
exitNode.style.textAlign = 'center';
|
||||
exitNode.style.lineHeight = '4vh';
|
||||
exitNode.style.lineHeight = '30px';
|
||||
exitNode.style.backgroundColor = '#e6e6e6';
|
||||
exitNode.textContent = `${t('Exit Full Screen')}`;
|
||||
autoNode.appendChild(exitNode);
|
||||
autoNode.appendChild(copyBlockElement);
|
||||
autoNode.addEventListener('click', () => {
|
||||
removeNode(layoutSider);
|
||||
removeNode({ gridRow, classId });
|
||||
});
|
||||
const fragment = document.createDocumentFragment();
|
||||
fragment.appendChild(autoNode);
|
||||
|
||||
if (page) {
|
||||
autoNode.style.marginTop = `${navbarHeight.height}px`;
|
||||
const header = document.querySelector('.ant-page-header');
|
||||
const layoutSider = document.querySelector('.ant-layout-sider');
|
||||
header.style.display = 'none';
|
||||
layoutSider.style.display = 'none';
|
||||
layoutContent.style.display = 'none';
|
||||
layoutContent?.parentNode.insertBefore(fragment, layoutContent);
|
||||
page.style.marginTop = '30px';
|
||||
page.insertAdjacentElement('beforebegin', autoNode);
|
||||
} else if (drawer) {
|
||||
autoNode.style.position = '';
|
||||
drawer.insertAdjacentElement('beforebegin', autoNode);
|
||||
} else if (modal) {
|
||||
autoNode.style.position = '';
|
||||
autoNode.style.width = '100%';
|
||||
modal.insertAdjacentElement('beforebegin', autoNode);
|
||||
}
|
||||
} else {
|
||||
message.warning(t('There are no full screen blocks available at the current location'));
|
||||
}
|
||||
} else {
|
||||
removeNode(layoutSider);
|
||||
}
|
||||
};
|
||||
|
||||
const removeNode = (layoutSider) => {
|
||||
const layoutContent = document.querySelector('.ant-layout-content');
|
||||
const sibling = layoutContent.previousElementSibling;
|
||||
layoutSider.style.display = 'block';
|
||||
layoutContent.style.display = 'block';
|
||||
if (sibling.classList.contains('autoPage')) sibling.parentNode.removeChild(sibling);
|
||||
const removeNode = ({ gridRow: blockElement, classId }) => {
|
||||
const page = blockElement?.closest('.ant-nb-page ');
|
||||
const drawer = blockElement?.closest('.ant-drawer-body');
|
||||
const parentNode = blockElement.parentNode;
|
||||
const tabNav = document.querySelector('.ant-tabs-nav');
|
||||
if (tabNav) tabNav.style.display = '';
|
||||
Array.from(parentNode.children).forEach((sibling) => {
|
||||
if (sibling !== blockElement) {
|
||||
sibling.style.display = '';
|
||||
}
|
||||
if ((sibling.id as string).includes('DndDescribedBy')) {
|
||||
sibling.style.display = 'none';
|
||||
}
|
||||
});
|
||||
if (page) {
|
||||
page.style.marginTop = '';
|
||||
const layoutSider = document.querySelector('.ant-layout-sider');
|
||||
const header = document.querySelector('.ant-page-header');
|
||||
layoutSider.style.display = '';
|
||||
header.style.display = '';
|
||||
} else if (drawer) {
|
||||
drawer.style.marginTop = '';
|
||||
}
|
||||
|
||||
const autoPage = document.querySelector('.autoPage' + classId);
|
||||
|
||||
if (autoPage) autoPage.parentNode.removeChild(autoPage);
|
||||
};
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { observer, RecursionField, useField, useFieldSchema } from '@tachybase/schema';
|
||||
|
||||
import { Drawer } from 'antd';
|
||||
import { ArrowsAltOutlined, CloseOutlined, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
|
||||
import { css } from '@emotion/css';
|
||||
import { Button, Drawer } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { OpenSize } from './';
|
||||
@ -61,6 +63,10 @@ export const ActionDrawer: ComposedActionDrawer = observer(
|
||||
</div>
|
||||
)
|
||||
}
|
||||
className={`${props.className} ${css`
|
||||
position: relative;
|
||||
padding-top: 30px;
|
||||
`} amplifier-block`}
|
||||
>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
@ -70,6 +76,24 @@ export const ActionDrawer: ComposedActionDrawer = observer(
|
||||
return s['x-component'] !== footerNodeName;
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className={css`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 5px;
|
||||
display: flex;
|
||||
`}
|
||||
>
|
||||
<Amplifier />
|
||||
<Button
|
||||
icon={<CloseOutlined />}
|
||||
className={css`
|
||||
background: none;
|
||||
border: none;
|
||||
`}
|
||||
onClick={() => setVisible(false, true)}
|
||||
/>
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
},
|
||||
@ -86,3 +110,27 @@ ActionDrawer.Footer = observer(
|
||||
);
|
||||
|
||||
export default ActionDrawer;
|
||||
|
||||
export const Amplifier = () => {
|
||||
const [isAmplifier, setIsAmplifier] = useState(false);
|
||||
const [blockWidth, setBlockWidth] = useState('');
|
||||
return (
|
||||
<Button
|
||||
icon={isAmplifier ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
|
||||
className={css`
|
||||
background: none;
|
||||
border: none;
|
||||
`}
|
||||
onClick={(e) => {
|
||||
const element = e.target.closest('.ant-drawer-content-wrapper');
|
||||
if (isAmplifier) {
|
||||
element.style.width = blockWidth;
|
||||
} else {
|
||||
setBlockWidth(element.getBoundingClientRect().width + 'px');
|
||||
element.style.width = '100%';
|
||||
}
|
||||
setIsAmplifier(!isAmplifier);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { observer, RecursionField, useField, useFieldSchema } from '@tachybase/schema';
|
||||
|
||||
import { Modal, ModalProps } from 'antd';
|
||||
import { CloseOutlined, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
|
||||
import { css } from '@emotion/css';
|
||||
import { Button, Modal, ModalProps } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
|
||||
@ -61,8 +63,18 @@ export const ActionModal: ComposedActionDrawer<ModalProps> = observer(
|
||||
}}
|
||||
destroyOnClose
|
||||
open={visible}
|
||||
onCancel={() => setVisible(false, true)}
|
||||
className={classNames(others.className, modalProps?.className, styles.container)}
|
||||
closable={false}
|
||||
className={classNames(
|
||||
others.className,
|
||||
modalProps?.className,
|
||||
styles.container,
|
||||
'amplifier-block',
|
||||
css`
|
||||
.ant-modal-content {
|
||||
padding-top: 32px;
|
||||
}
|
||||
`,
|
||||
)}
|
||||
footer={
|
||||
footerSchema ? (
|
||||
<RecursionField
|
||||
@ -86,6 +98,24 @@ export const ActionModal: ComposedActionDrawer<ModalProps> = observer(
|
||||
return s['x-component'] !== footerNodeName;
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className={css`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 5px;
|
||||
display: flex;
|
||||
`}
|
||||
>
|
||||
<Amplifier />
|
||||
<Button
|
||||
icon={<CloseOutlined />}
|
||||
className={css`
|
||||
background: none;
|
||||
border: none;
|
||||
`}
|
||||
onClick={() => setVisible(false, true)}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
},
|
||||
@ -102,3 +132,39 @@ ActionModal.Footer = observer(
|
||||
);
|
||||
|
||||
export default ActionModal;
|
||||
|
||||
export const Amplifier = () => {
|
||||
const [isAmplifier, setIsAmplifier] = useState(false);
|
||||
const [blockWidth, setBlockWidth] = useState('');
|
||||
return (
|
||||
<Button
|
||||
icon={isAmplifier ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
|
||||
className={css`
|
||||
background: none;
|
||||
border: none;
|
||||
`}
|
||||
onClick={(e) => {
|
||||
const element = e.target.closest('.ant-modal-content');
|
||||
const modal = document.querySelector('.ant-modal');
|
||||
const mask = document.querySelector('.ant-modal-mask');
|
||||
if (isAmplifier) {
|
||||
modal.style.width = blockWidth;
|
||||
element.style.width = '';
|
||||
modal.style.top = '';
|
||||
modal.style.padding = '';
|
||||
modal.style.margin = '';
|
||||
mask.style.backgroundColor = '';
|
||||
} else {
|
||||
setBlockWidth(modal.getBoundingClientRect().width + 'px');
|
||||
element.style.width = '100vw';
|
||||
modal.style.width = '100%';
|
||||
modal.style.top = '0';
|
||||
modal.style.padding = '0';
|
||||
modal.style.margin = '0';
|
||||
mask.style.backgroundColor = '#f3f3f3';
|
||||
}
|
||||
setIsAmplifier(!isAmplifier);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -57,6 +57,7 @@ export const ActionSheet: ComposedActionDrawer = observer(
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
className={`${props.className} amplifier-block`}
|
||||
>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
|
@ -504,7 +504,7 @@ Grid.Col = observer(
|
||||
|
||||
return (
|
||||
<GridColContext.Provider value={{ cols, schema }}>
|
||||
<div ref={setNodeRef} style={{ ...style, ...droppableStyle }} className={cls('nb-grid-col')}>
|
||||
<div ref={setNodeRef} style={{ ...style, ...droppableStyle }} className={cls('nb-grid-col CardCol')}>
|
||||
{props.children}
|
||||
</div>
|
||||
</GridColContext.Provider>
|
||||
|
Loading…
Reference in New Issue
Block a user