fix(mobile-client): fix multiple bugs and do some improvement (#2072)

This commit is contained in:
Dunqing 2023-06-21 22:26:15 +08:00 committed by GitHub
parent 6254fceb04
commit b80aaacb38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 103 additions and 103 deletions

View File

@ -42,7 +42,5 @@
}
html body {
--adm-font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji,
Segoe UI Symbol;
--adm-font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}

View File

@ -2,45 +2,36 @@ import { css } from '@emotion/css';
import { observer, RecursionField, useField, useFieldSchema } from '@formily/react';
import { TabPaneProps, Tabs as AntdTabs, TabsProps } from 'antd';
import classNames from 'classnames';
import React, { useMemo } from 'react';
import React from 'react';
import { Icon } from '../../../icon';
import { useSchemaInitializer } from '../../../schema-initializer';
import { DndContext, SortableItem } from '../../common';
import { useDesigner } from '../../hooks/useDesigner';
import { TabsContextProvider, useTabsContext } from './context';
import { useTabsContext } from './context';
import { TabsDesigner } from './Tabs.Designer';
import { useDesignable } from '../../hooks';
export const Tabs: any = observer(
(props: TabsProps) => {
const fieldSchema = useFieldSchema();
const { render } = useSchemaInitializer(fieldSchema['x-initializer']);
const { designable } = useDesignable();
const contextProps = useTabsContext();
const PaneProvider = useMemo(() => {
if (contextProps.deep === false) {
return TabsContextProvider;
}
return React.Fragment;
}, [contextProps.deep]);
const { PaneRoot = React.Fragment as React.FC<any> } = contextProps;
return (
<DndContext>
<AntdTabs
{...contextProps}
style={props.style}
tabBarExtraContent={{
right: render(),
}}
>
<AntdTabs {...contextProps} style={props.style}>
{fieldSchema.mapProperties((schema, key) => {
return (
<AntdTabs.TabPane tab={<RecursionField name={key} schema={schema} onlyRenderSelf />} key={key}>
<PaneProvider>
<PaneRoot active={key === contextProps.activeKey}>
<RecursionField name={key} schema={schema} onlyRenderProperties />
</PaneProvider>
</PaneRoot>
</AntdTabs.TabPane>
);
})}
{designable && <AntdTabs.TabPane tab={render()} />}
</AntdTabs>
</DndContext>
);

View File

@ -2,7 +2,7 @@ import { TabsProps } from 'antd';
import React from 'react';
interface TabsContextProps extends TabsProps {
deep?: boolean;
PaneRoot?: React.FC<any>;
}
const TabsContext = React.createContext<TabsContextProps>({});

View File

@ -3,12 +3,13 @@ interface InvokeFunction {
(params: { action: 'moveTaskToBack' }, cb?: () => void): void;
}
const JsBridge = (window as any).JsBridge as {
invoke: InvokeFunction;
};
const getJsBridge = () =>
(window as any).JsBridge as {
invoke: InvokeFunction;
};
export const invoke: InvokeFunction = (params, cb) => {
JsBridge.invoke(params, cb);
return getJsBridge().invoke(params, cb);
};
export const isJSBridge = !!JsBridge;
export const isJSBridge = () => !!getJsBridge();

View File

@ -6,6 +6,7 @@ import React from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from '../../../../locale';
import { useSchemaPatch } from '../../hooks';
import { menuItemSchema } from './schema';
interface MMenuItemProps extends ListItemProps {
name: string;
@ -56,24 +57,7 @@ const MenuItemDesigner: React.FC = () => {
<SchemaSettings.ModalItem
title={t('Edit menu info')}
initialValues={field.componentProps}
schema={{
properties: {
name: {
type: 'string',
title: t('Menu name'),
required: true,
'x-component': 'Input',
'x-decorator': 'FormItem',
},
icon: {
required: true,
'x-decorator': 'FormItem',
'x-component': 'IconPicker',
title: t('Icon'),
'x-component-props': {},
},
},
}}
schema={menuItemSchema}
onSubmit={onUpdateComponentProps}
/>
<SchemaSettings.Remove

View File

@ -1,8 +1,10 @@
import { generateNTemplate } from '../../../../locale';
export const menuItemSchema = {
properties: {
name: {
type: 'string',
title: `{{t('Menu name')}}`,
title: generateNTemplate('Menu name'),
required: true,
'x-component': 'Input',
'x-decorator': 'FormItem',
@ -10,7 +12,7 @@ export const menuItemSchema = {
icon: {
'x-decorator': 'FormItem',
'x-component': 'IconPicker',
title: `{{t('Icon')}}`,
title: generateNTemplate('Icon'),
'x-component-props': {},
},
},

View File

@ -2,7 +2,7 @@ import { css, cx } from '@emotion/css';
import { RecursionField, useFieldSchema } from '@formily/react';
import { ActionBarProvider, SortableItem, TabsContextProvider, useDesigner } from '@nocobase/client';
import { TabsProps } from 'antd';
import React, { useCallback, useMemo } from 'react';
import React, { useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
import { countGridCol } from '../../helpers';
import { PageDesigner } from './Page.Designer';
@ -28,90 +28,113 @@ const InternalPage: React.FC = (props) => {
// Only support globalActions in page
const onlyInPage = fieldSchema.root === fieldSchema.parent;
let hasGlobalActions = false;
if (!tabsSchema) {
if (!tabsSchema && fieldSchema.properties) {
hasGlobalActions = countGridCol(fieldSchema.properties['grid'], 2) === 1;
} else if (searchParams.has('tab') && tabsSchema.properties?.[searchParams.get('tab')]) {
} else if (searchParams.has('tab') && tabsSchema?.properties?.[searchParams.get('tab')]) {
hasGlobalActions = countGridCol(tabsSchema.properties[searchParams.get('tab')]?.properties?.['grid'], 2) === 1;
} else if (tabsSchema.properties) {
} else if (tabsSchema?.properties) {
const schema = Object.values(tabsSchema.properties).sort((t1, t2) => t1['x-index'] - t2['x-index'])[0];
if (schema) {
setTimeout(() => {
setSearchParams([['tab', schema.name.toString()]]);
setSearchParams([['tab', schema.name.toString()]], {
replace: true,
});
});
}
}
const onTabsChange = useCallback<TabsProps['onChange']>(
(key) => {
setSearchParams([['tab', key]]);
setSearchParams([['tab', key]], {
replace: true,
});
},
[setSearchParams],
);
const GlobalActionProvider = useMemo(() => {
if (hasGlobalActions) {
return ActionBarProvider;
}
return (props) => <>{props.children}</>;
}, [hasGlobalActions]);
const GlobalActionProvider = useCallback(
(props) => {
if (hasGlobalActions) {
return (
<TabsContextProvider>
<ActionBarProvider
container={
(typeof props.active !== 'undefined' ? props.active : true) && onlyInPage
? document.getElementById('nb-position-container')
: null
}
forceProps={{
layout: 'one-column',
className: globalActionCSS,
}}
>
{props.children}
</ActionBarProvider>
</TabsContextProvider>
);
}
return <>{props.children}</>;
},
[hasGlobalActions, onlyInPage],
);
return (
<GlobalActionProvider
container={hasGlobalActions && onlyInPage ? document.getElementById('nb-position-container') : null}
forceProps={{
layout: 'one-column',
className: globalActionCSS,
}}
<SortableItem
eid="nb-mobile-scroll-wrapper"
className={cx(
'nb-mobile-page',
css`
background: #f0f2f5;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
padding-bottom: var(--nb-spacing);
`,
)}
>
<SortableItem
eid="nb-mobile-scroll-wrapper"
<Designer {...fieldSchema?.['x-designer-props']}></Designer>
<div
style={{
paddingBottom: tabsSchema ? null : 'var(--nb-spacing)',
}}
className={cx(
'nb-mobile-page',
'nb-mobile-page-header',
css`
background: #f0f2f5;
& > .ant-tabs > .ant-tabs-nav {
.ant-tabs-tab {
margin: 0 !important;
padding: 0 16px !important;
}
background: #fff;
}
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
padding-bottom: var(--nb-spacing);
`,
)}
>
<Designer {...fieldSchema?.['x-designer-props']}></Designer>
<div
style={{
paddingBottom: tabsSchema ? null : 'var(--nb-spacing)',
<RecursionField
schema={fieldSchema}
filterProperties={(s) => {
return 'MHeader' === s['x-component'];
}}
className={cx(
'nb-mobile-page-header',
css`
& > .ant-tabs > .ant-tabs-nav {
background: #fff;
padding: 0 var(--nb-spacing);
}
display: flex;
flex-direction: column;
`,
)}
></RecursionField>
<TabsContextProvider
PaneRoot={GlobalActionProvider}
activeKey={searchParams.get('tab')}
onChange={onTabsChange}
>
<RecursionField
schema={fieldSchema}
filterProperties={(s) => {
return 'MHeader' === s['x-component'];
return 'Tabs' === s['x-component'];
}}
></RecursionField>
<TabsContextProvider deep={false} activeKey={searchParams.get('tab')} onChange={onTabsChange}>
<RecursionField
schema={fieldSchema}
filterProperties={(s) => {
return 'Tabs' === s['x-component'];
}}
></RecursionField>
</TabsContextProvider>
</div>
</TabsContextProvider>
</div>
<GlobalActionProvider>
{!tabsSchema && (
<RecursionField
schema={fieldSchema}
@ -120,8 +143,8 @@ const InternalPage: React.FC = (props) => {
}}
></RecursionField>
)}
</SortableItem>
</GlobalActionProvider>
</GlobalActionProvider>
</SortableItem>
);
};

View File

@ -115,6 +115,7 @@ const MApplication: React.FC = (props) => {
{props.children}
</RemoteSchemaComponent>
)}
{/* Global action will insert here */}
<div id="nb-position-container"></div>
</div>
</ActionContextProvider>

View File

@ -10,7 +10,7 @@ export const RouterSwitchProvider = (props) => {
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
if (isJSBridge) {
if (isJSBridge()) {
if (location.pathname.includes('/admin')) {
navigate('/mobile');
}