mirror of
https://github.com/nocobase/nocobase
synced 2024-11-14 16:34:14 +00:00
fix(popup): z-index (#5373)
Some checks are pending
auto-merge / push-commit (push) Waiting to run
Build Docker Image / build-and-push (push) Waiting to run
Build Pro Image / build-and-push (push) Waiting to run
deploy client docs / Build (push) Waiting to run
E2E / Build (push) Waiting to run
E2E / Core and plugins (push) Blocked by required conditions
E2E / plugin-workflow (push) Blocked by required conditions
E2E / plugin-workflow-approval (push) Blocked by required conditions
E2E / plugin-data-source-main (push) Blocked by required conditions
E2E / Comment on PR (push) Blocked by required conditions
NocoBase Backend Test / sqlite-test (20, false) (push) Waiting to run
NocoBase Backend Test / sqlite-test (20, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, nocobase, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, nocobase, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, public, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, public, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, public, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, public, true) (push) Waiting to run
NocoBase Backend Test / mysql-test (20, false) (push) Waiting to run
NocoBase Backend Test / mysql-test (20, true) (push) Waiting to run
NocoBase Backend Test / mariadb-test (20, false) (push) Waiting to run
NocoBase Backend Test / mariadb-test (20, true) (push) Waiting to run
NocoBase FrontEnd Test / frontend-test (18) (push) Waiting to run
Test on Windows / build (push) Waiting to run
Some checks are pending
auto-merge / push-commit (push) Waiting to run
Build Docker Image / build-and-push (push) Waiting to run
Build Pro Image / build-and-push (push) Waiting to run
deploy client docs / Build (push) Waiting to run
E2E / Build (push) Waiting to run
E2E / Core and plugins (push) Blocked by required conditions
E2E / plugin-workflow (push) Blocked by required conditions
E2E / plugin-workflow-approval (push) Blocked by required conditions
E2E / plugin-data-source-main (push) Blocked by required conditions
E2E / Comment on PR (push) Blocked by required conditions
NocoBase Backend Test / sqlite-test (20, false) (push) Waiting to run
NocoBase Backend Test / sqlite-test (20, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, nocobase, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, nocobase, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, public, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (public, 20, public, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, true) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, public, false) (push) Waiting to run
NocoBase Backend Test / postgres-test (user_schema, 20, public, true) (push) Waiting to run
NocoBase Backend Test / mysql-test (20, false) (push) Waiting to run
NocoBase Backend Test / mysql-test (20, true) (push) Waiting to run
NocoBase Backend Test / mariadb-test (20, false) (push) Waiting to run
NocoBase Backend Test / mariadb-test (20, true) (push) Waiting to run
NocoBase FrontEnd Test / frontend-test (18) (push) Waiting to run
Test on Windows / build (push) Waiting to run
* fix(popup): z-index
* test: add e2e test
* chore: fix build error
* Revert "chore: fix build error"
This reverts commit d0fe9ba217
.
* refactor: avoid build error
* chore: make e2e more stable
This commit is contained in:
parent
259b0b707a
commit
1fc2f388e3
@ -51,4 +51,26 @@ test.describe('z-index of dialog', () => {
|
||||
await page.getByRole('button', { name: 'Cancel' }).click({ timeout: 1000 });
|
||||
await expect(page.getByRole('dialog').getByText('Assign field values')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('Users & Permissions', async ({ page }) => {
|
||||
await page.goto('/admin/settings/users-permissions/roles');
|
||||
|
||||
// Data source
|
||||
await page.getByRole('tab', { name: 'Data sources' }).click();
|
||||
await page.getByLabel('action-Action.Link-Configure-').click();
|
||||
await page.getByRole('tab', { name: 'Action permissions', exact: true }).click();
|
||||
await page.getByLabel('action-Action.Link-Configure-dataSourcesCollections-users', { exact: true }).click();
|
||||
await page.getByLabel('Individual').check();
|
||||
await page
|
||||
.getByTestId('drawer-Action.Drawer-dataSourcesCollections-Configure permission')
|
||||
.getByRole('cell')
|
||||
.locator('.ant-select-selector')
|
||||
.first()
|
||||
.click();
|
||||
await page
|
||||
.getByTestId('drawer-RecordPicker.Selector-dataSourcesCollections-Select record')
|
||||
.getByLabel('action-Action-Add new-create-')
|
||||
.click();
|
||||
await expect(page.getByText('Add condition', { exact: true })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
@ -19,7 +19,7 @@ import { useStyles } from './Action.Drawer.style';
|
||||
import { useActionContext } from './hooks';
|
||||
import { useSetAriaLabelForDrawer } from './hooks/useSetAriaLabelForDrawer';
|
||||
import { ActionDrawerProps, ComposedActionDrawer, OpenSize } from './types';
|
||||
import { antdDrawerZIndex } from './utils';
|
||||
import { useZIndexContext, zIndexContext } from './zIndexContext';
|
||||
|
||||
const DrawerErrorFallback: React.FC<FallbackProps> = (props) => {
|
||||
const { visible, setVisible } = useActionContext();
|
||||
@ -43,6 +43,7 @@ export const InternalActionDrawer: React.FC<ActionDrawerProps> = observer(
|
||||
const field = useField();
|
||||
const { componentCls, hashId } = useStyles();
|
||||
const tabContext = useTabsContext();
|
||||
const parentZIndex = useZIndexContext();
|
||||
const footerSchema = schema.reduceProperties((buf, s) => {
|
||||
if (s['x-component'] === footerNodeName) {
|
||||
return s;
|
||||
@ -62,44 +63,48 @@ export const InternalActionDrawer: React.FC<ActionDrawerProps> = observer(
|
||||
useSetAriaLabelForDrawer(visible);
|
||||
}
|
||||
|
||||
const zIndex = parentZIndex + (props.level || 0);
|
||||
|
||||
return (
|
||||
<TabsContextProvider {...tabContext} tabBarExtraContent={null}>
|
||||
<Drawer
|
||||
zIndex={antdDrawerZIndex + props.level}
|
||||
width={openSizeWidthMap.get(openSize)}
|
||||
title={field.title}
|
||||
{...others}
|
||||
{...drawerProps}
|
||||
rootStyle={rootStyle}
|
||||
destroyOnClose
|
||||
open={visible}
|
||||
onClose={() => setVisible(false, true)}
|
||||
rootClassName={classNames(componentCls, hashId, drawerProps?.className, others.className, 'reset')}
|
||||
footer={
|
||||
footerSchema && (
|
||||
<div className={'footer'}>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === footerNodeName;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] !== footerNodeName;
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
</TabsContextProvider>
|
||||
<zIndexContext.Provider value={zIndex}>
|
||||
<TabsContextProvider {...tabContext} tabBarExtraContent={null}>
|
||||
<Drawer
|
||||
zIndex={zIndex}
|
||||
width={openSizeWidthMap.get(openSize)}
|
||||
title={field.title}
|
||||
{...others}
|
||||
{...drawerProps}
|
||||
rootStyle={rootStyle}
|
||||
destroyOnClose
|
||||
open={visible}
|
||||
onClose={() => setVisible(false, true)}
|
||||
rootClassName={classNames(componentCls, hashId, drawerProps?.className, others.className, 'reset')}
|
||||
footer={
|
||||
footerSchema && (
|
||||
<div className={'footer'}>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === footerNodeName;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] !== footerNodeName;
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
</TabsContextProvider>
|
||||
</zIndexContext.Provider>
|
||||
);
|
||||
},
|
||||
{ displayName: 'ActionDrawer' },
|
||||
|
@ -20,7 +20,7 @@ import { TabsContextProvider, useTabsContext } from '../tabs/context';
|
||||
import { useActionContext } from './hooks';
|
||||
import { useSetAriaLabelForModal } from './hooks/useSetAriaLabelForModal';
|
||||
import { ActionDrawerProps, ComposedActionDrawer, OpenSize } from './types';
|
||||
import { antdDrawerZIndex } from './utils';
|
||||
import { useZIndexContext, zIndexContext } from './zIndexContext';
|
||||
|
||||
const ModalErrorFallback: React.FC<FallbackProps> = (props) => {
|
||||
const { visible, setVisible } = useActionContext();
|
||||
@ -47,6 +47,7 @@ export const InternalActionModal: React.FC<ActionDrawerProps<ModalProps>> = obse
|
||||
const field = useField();
|
||||
const { token } = useToken();
|
||||
const tabContext = useTabsContext();
|
||||
const parentZIndex = useZIndexContext();
|
||||
const footerSchema = schema.reduceProperties((buf, s) => {
|
||||
if (s['x-component'] === footerNodeName) {
|
||||
return s;
|
||||
@ -70,79 +71,83 @@ export const InternalActionModal: React.FC<ActionDrawerProps<ModalProps>> = obse
|
||||
useSetAriaLabelForModal(visible);
|
||||
}
|
||||
|
||||
const zIndex = parentZIndex + (props.level || 0);
|
||||
|
||||
return (
|
||||
<TabsContextProvider {...tabContext} tabBarExtraContent={null}>
|
||||
<Modal
|
||||
zIndex={antdDrawerZIndex + props.level}
|
||||
width={actualWidth}
|
||||
title={field.title}
|
||||
{...(others as ModalProps)}
|
||||
{...modalProps}
|
||||
styles={styles}
|
||||
style={{
|
||||
...modalProps?.style,
|
||||
...others?.style,
|
||||
}}
|
||||
destroyOnClose
|
||||
open={visible}
|
||||
onCancel={() => {
|
||||
setVisible(false, true);
|
||||
form.reset();
|
||||
}}
|
||||
className={classNames(
|
||||
others.className,
|
||||
modalProps?.className,
|
||||
css`
|
||||
&.nb-action-popup {
|
||||
.ant-modal-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
background: var(--nb-box-bg);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
// 这里的样式是为了保证页面 tabs 标签下面的分割线和页面内容对齐(页面内边距可以通过主题编辑器调节)
|
||||
.ant-tabs-nav {
|
||||
padding-left: ${token.paddingLG - token.paddingPageHorizontal}px;
|
||||
padding-right: ${token.paddingLG - token.paddingPageHorizontal}px;
|
||||
margin-left: ${token.paddingPageHorizontal - token.paddingLG}px;
|
||||
margin-right: ${token.paddingPageHorizontal - token.paddingLG}px;
|
||||
}
|
||||
|
||||
.ant-modal-footer {
|
||||
display: ${showFooter ? 'block' : 'none'};
|
||||
}
|
||||
}
|
||||
`,
|
||||
)}
|
||||
footer={
|
||||
showFooter ? (
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === footerNodeName;
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
false
|
||||
)
|
||||
}
|
||||
>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] !== footerNodeName;
|
||||
<zIndexContext.Provider value={zIndex}>
|
||||
<TabsContextProvider {...tabContext} tabBarExtraContent={null}>
|
||||
<Modal
|
||||
zIndex={zIndex}
|
||||
width={actualWidth}
|
||||
title={field.title}
|
||||
{...(others as ModalProps)}
|
||||
{...modalProps}
|
||||
styles={styles}
|
||||
style={{
|
||||
...modalProps?.style,
|
||||
...others?.style,
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
</TabsContextProvider>
|
||||
destroyOnClose
|
||||
open={visible}
|
||||
onCancel={() => {
|
||||
setVisible(false, true);
|
||||
form.reset();
|
||||
}}
|
||||
className={classNames(
|
||||
others.className,
|
||||
modalProps?.className,
|
||||
css`
|
||||
&.nb-action-popup {
|
||||
.ant-modal-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
background: var(--nb-box-bg);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
// 这里的样式是为了保证页面 tabs 标签下面的分割线和页面内容对齐(页面内边距可以通过主题编辑器调节)
|
||||
.ant-tabs-nav {
|
||||
padding-left: ${token.paddingLG - token.paddingPageHorizontal}px;
|
||||
padding-right: ${token.paddingLG - token.paddingPageHorizontal}px;
|
||||
margin-left: ${token.paddingPageHorizontal - token.paddingLG}px;
|
||||
margin-right: ${token.paddingPageHorizontal - token.paddingLG}px;
|
||||
}
|
||||
|
||||
.ant-modal-footer {
|
||||
display: ${showFooter ? 'block' : 'none'};
|
||||
}
|
||||
}
|
||||
`,
|
||||
)}
|
||||
footer={
|
||||
showFooter ? (
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === footerNodeName;
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
false
|
||||
)
|
||||
}
|
||||
>
|
||||
<RecursionField
|
||||
basePath={field.address}
|
||||
schema={schema}
|
||||
onlyRenderProperties
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] !== footerNodeName;
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
</TabsContextProvider>
|
||||
</zIndexContext.Provider>
|
||||
);
|
||||
},
|
||||
{ displayName: 'ActionModal' },
|
||||
|
@ -15,7 +15,7 @@ import { BackButtonUsedInSubPage } from '../page/BackButtonUsedInSubPage';
|
||||
import { TabsContextProvider, useTabsContext } from '../tabs/context';
|
||||
import { useActionPageStyle } from './Action.Page.style';
|
||||
import { usePopupOrSubpagesContainerDOM } from './hooks/usePopupSlotDOM';
|
||||
import { antdDrawerZIndex } from './utils';
|
||||
import { useZIndexContext, zIndexContext } from './zIndexContext';
|
||||
|
||||
export function ActionPage({ level }) {
|
||||
const filedSchema = useFieldSchema();
|
||||
@ -23,12 +23,13 @@ export function ActionPage({ level }) {
|
||||
const { getContainerDOM } = usePopupOrSubpagesContainerDOM();
|
||||
const { styles } = useActionPageStyle();
|
||||
const tabContext = useTabsContext();
|
||||
const parentZIndex = useZIndexContext();
|
||||
|
||||
const style = useMemo(() => {
|
||||
return {
|
||||
zIndex: antdDrawerZIndex + level,
|
||||
zIndex: parentZIndex + (level || 0),
|
||||
};
|
||||
}, [level]);
|
||||
}, [parentZIndex, level]);
|
||||
|
||||
if (!ctx.visible) {
|
||||
return null;
|
||||
@ -37,7 +38,9 @@ export function ActionPage({ level }) {
|
||||
const actionPageNode = (
|
||||
<div className={styles.container} style={style}>
|
||||
<TabsContextProvider {...tabContext} tabBarExtraContent={<BackButtonUsedInSubPage />}>
|
||||
<RecursionField schema={filedSchema} onlyRenderProperties />
|
||||
<zIndexContext.Provider value={style.zIndex}>
|
||||
<RecursionField schema={filedSchema} onlyRenderProperties />
|
||||
</zIndexContext.Provider>
|
||||
</TabsContextProvider>
|
||||
</div>
|
||||
);
|
||||
|
@ -154,5 +154,3 @@ export const setInitialActionState = (field) => {
|
||||
field.data.hidden = false;
|
||||
field.componentProps['disabled'] = false;
|
||||
};
|
||||
|
||||
export const antdDrawerZIndex = 100;
|
||||
|
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export const zIndexContext = React.createContext(100);
|
||||
|
||||
export const useZIndexContext = () => {
|
||||
return React.useContext(zIndexContext);
|
||||
};
|
Loading…
Reference in New Issue
Block a user