feat(app): add mobile responsive
This commit is contained in:
parent
63033d57c4
commit
31edb3a1fe
@ -1,6 +1,14 @@
|
|||||||
import './css_browser_selector';
|
import './css_browser_selector';
|
||||||
import { RequestConfig, request as umiRequest, history } from 'umi';
|
import { RequestConfig, request as umiRequest, history } from 'umi';
|
||||||
|
|
||||||
|
import { configResponsive } from 'ahooks';
|
||||||
|
|
||||||
|
configResponsive({
|
||||||
|
small: 0,
|
||||||
|
middle: 800,
|
||||||
|
large: 1200,
|
||||||
|
});
|
||||||
|
|
||||||
export const request: RequestConfig = {
|
export const request: RequestConfig = {
|
||||||
prefix: process.env.API,
|
prefix: process.env.API,
|
||||||
errorConfig: {
|
errorConfig: {
|
||||||
|
@ -55,6 +55,7 @@ function DrawerSelectComponent(props) {
|
|||||||
onChange(data.value);
|
onChange(data.value);
|
||||||
setSelectedRowKeys([data.value]);
|
setSelectedRowKeys([data.value]);
|
||||||
} else {
|
} else {
|
||||||
|
console.log(data);
|
||||||
onChange(null);
|
onChange(null);
|
||||||
setSelectedRowKeys([]);
|
setSelectedRowKeys([]);
|
||||||
}
|
}
|
||||||
@ -65,6 +66,7 @@ function DrawerSelectComponent(props) {
|
|||||||
></Select>
|
></Select>
|
||||||
<Drawer
|
<Drawer
|
||||||
width={'40%'}
|
width={'40%'}
|
||||||
|
className={'noco-drawer'}
|
||||||
title={'关联数据'}
|
title={'关联数据'}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
bodyStyle={{padding: 0}}
|
bodyStyle={{padding: 0}}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { connect } from '@formily/react-schema-renderer'
|
import { connect } from '@formily/react-schema-renderer'
|
||||||
|
import React from 'react';
|
||||||
import { Input as AntdInput } from 'antd'
|
import { Input as AntdInput } from 'antd'
|
||||||
import { acceptEnum, mapStyledProps, mapTextComponent } from '../shared'
|
import { acceptEnum, mapStyledProps, mapTextComponent } from '../shared'
|
||||||
|
|
||||||
@ -10,6 +11,6 @@ export const Input = connect<'TextArea'>({
|
|||||||
Input.TextArea = connect({
|
Input.TextArea = connect({
|
||||||
getProps: mapStyledProps,
|
getProps: mapStyledProps,
|
||||||
getComponent: mapTextComponent
|
getComponent: mapTextComponent
|
||||||
})(acceptEnum(AntdInput.TextArea))
|
})(acceptEnum((props) => <AntdInput.TextArea autoSize={{minRows: 2}} {...props}/>))
|
||||||
|
|
||||||
export default Input
|
export default Input
|
||||||
|
@ -48,6 +48,7 @@ export default forwardRef((props: any, ref) => {
|
|||||||
{...props}
|
{...props}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
className={'noco-drawer'}
|
||||||
width={'40%'}
|
width={'40%'}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
@ -10,4 +10,17 @@
|
|||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.avatar-dropdown-wrapper {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
width: 100%;
|
||||||
|
.dropdown-link {
|
||||||
|
display: block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -37,6 +37,13 @@
|
|||||||
margin: 16px;
|
margin: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.collection-content {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// .ant-page-header.has-footer {
|
// .ant-page-header.has-footer {
|
||||||
// padding-top: 50px;
|
// padding-top: 50px;
|
||||||
// }
|
// }
|
@ -1,29 +1,51 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Layout, Breadcrumb } from 'antd';
|
import { Layout, Breadcrumb, Drawer } from 'antd';
|
||||||
import { Link } from 'umi';
|
import { Link } from 'umi';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
import Menu from '@/components/menu';
|
import Menu from '@/components/menu';
|
||||||
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons';
|
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons';
|
||||||
import { useLocalStorageState } from 'ahooks';
|
import { useLocalStorageState } from 'ahooks';
|
||||||
|
import { useResponsive } from 'ahooks';
|
||||||
|
|
||||||
export function SideMenuLayout(props: any) {
|
export function SideMenuLayout(props: any) {
|
||||||
const { menu = [], id } = props.page;
|
const { menu = [], id } = props.page;
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
// console.log(menu);
|
// console.log(menu);
|
||||||
const [collapsed, setCollapsed] = useLocalStorageState(`nocobase-menu-collapsed-${id}`, false);
|
const [collapsed, setCollapsed] = useLocalStorageState(`nocobase-menu-collapsed-${id}`, false);
|
||||||
|
const responsive = useResponsive();
|
||||||
|
const isMobile = responsive.small && !responsive.middle && !responsive.large;
|
||||||
return (
|
return (
|
||||||
<Layout style={{height: 'calc(100vh - 48px)'}}>
|
<Layout style={{height: 'calc(100vh - 48px)'}}>
|
||||||
<Layout.Sider className={`nb-sider${collapsed ? ' collapsed' : ''}`} theme={'light'}>
|
{!isMobile && <Layout.Sider className={`nb-sider${collapsed ? ' collapsed' : ''}`} theme={'light'}>
|
||||||
<Menu items={menu} mode={'inline'}/>
|
<Menu items={menu} mode={'inline'}/>
|
||||||
<div onClick={() => {
|
<div onClick={() => {
|
||||||
setCollapsed(!collapsed);
|
setCollapsed(!collapsed);
|
||||||
|
setVisible(true);
|
||||||
}} className={'menu-toggle'}>
|
}} className={'menu-toggle'}>
|
||||||
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||||
style: { fontSize: 16 },
|
style: { fontSize: 16 },
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</Layout.Sider>
|
</Layout.Sider>}
|
||||||
<Layout.Content>
|
<Layout.Content>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
{isMobile && <Drawer visible={visible} onClose={() => {
|
||||||
|
setCollapsed(!collapsed);
|
||||||
|
setVisible(false);
|
||||||
|
}} placement={'left'} closable={false} bodyStyle={{padding: 0}}>
|
||||||
|
<Menu onSelect={() => {
|
||||||
|
setCollapsed(false);
|
||||||
|
setVisible(false);
|
||||||
|
}} items={menu} mode={'inline'}/>
|
||||||
|
</Drawer>}
|
||||||
|
{isMobile && <div onClick={() => {
|
||||||
|
setCollapsed(!collapsed);
|
||||||
|
setVisible(true);
|
||||||
|
}} className={'menu-toggle'}>
|
||||||
|
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||||
|
style: { fontSize: 16 },
|
||||||
|
})}
|
||||||
|
</div>}
|
||||||
</Layout.Content>
|
</Layout.Content>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
@ -9,11 +9,13 @@
|
|||||||
.ant-menu-light {
|
.ant-menu-light {
|
||||||
border-right-color: transparent !important;
|
border-right-color: transparent !important;
|
||||||
}
|
}
|
||||||
.menu-toggle {
|
}
|
||||||
position: fixed;
|
|
||||||
bottom: 12px;
|
.menu-toggle {
|
||||||
left: 12px;
|
position: fixed;
|
||||||
line-height: 1;
|
bottom: 12px;
|
||||||
cursor: pointer;
|
left: 12px;
|
||||||
}
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
@ -1,21 +1,42 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Layout, Dropdown, Avatar } from 'antd';
|
import { Layout, Dropdown, Avatar, Drawer } from 'antd';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
import { history, Link, request, useModel } from 'umi';
|
import { history, Link, request, useModel } from 'umi';
|
||||||
import { UserOutlined, CodeOutlined } from '@ant-design/icons';
|
import { UserOutlined, CodeOutlined, MenuOutlined } from '@ant-design/icons';
|
||||||
import AvatarDropdown from '../AvatarDropdown';
|
import AvatarDropdown from '../AvatarDropdown';
|
||||||
import Menu from '@/components/menu';
|
import Menu from '@/components/menu';
|
||||||
import { ReactComponent as Logo } from './logo-white.svg';
|
import { ReactComponent as Logo } from './logo-white.svg';
|
||||||
|
import { useResponsive, useLocalStorageState } from 'ahooks';
|
||||||
|
|
||||||
export function TopMenuLayout(props: any) {
|
export function TopMenuLayout(props: any) {
|
||||||
const { menu = [] } = props.page;
|
const { menu = [] } = props.page;
|
||||||
|
// const [visible, setVisible] = useState(false);
|
||||||
|
const [visible, setVisible] = useLocalStorageState(`nocobase-nav-visible`, false);
|
||||||
|
const responsive = useResponsive();
|
||||||
|
const isMobile = responsive.small && !responsive.middle && !responsive.large;
|
||||||
return (
|
return (
|
||||||
<Layout style={{ height: '100vh' }}>
|
<Layout style={{ height: '100vh' }}>
|
||||||
<Layout.Header style={{height: 48, lineHeight: '48px', padding: 0}} className="nb-header">
|
<Layout.Header style={{height: 48, lineHeight: '48px', padding: 0}} className="nb-header">
|
||||||
<div className="logo" style={{width: 200, height: 20, float: 'left'}}><Logo/></div>
|
<div className="logo" style={{width: 200, height: 20, float: 'left'}}><Logo/></div>
|
||||||
<Menu hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark" mode="horizontal">
|
{!isMobile && <Menu hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark" mode="horizontal"/>}
|
||||||
</Menu>
|
{!isMobile && <AvatarDropdown/>}
|
||||||
<AvatarDropdown/>
|
{isMobile && <MenuOutlined onClick={() => {
|
||||||
|
setVisible(true);
|
||||||
|
}} style={{
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#fff',
|
||||||
|
position: 'absolute',
|
||||||
|
right: 16,
|
||||||
|
top: 16,
|
||||||
|
}}/>}
|
||||||
|
{isMobile && <Drawer visible={visible} onClose={() => {
|
||||||
|
setVisible(false);
|
||||||
|
}} placement={'right'} closable={false} bodyStyle={{background: '#001529', padding: 0}}>
|
||||||
|
<Menu onSelect={() => {
|
||||||
|
setVisible(false);
|
||||||
|
}} mode={'inline'} hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark"/>
|
||||||
|
<AvatarDropdown/>
|
||||||
|
</Drawer>}
|
||||||
</Layout.Header>
|
</Layout.Header>
|
||||||
<Layout.Content>
|
<Layout.Content>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
@ -6,8 +6,17 @@ import { useRequest } from 'umi';
|
|||||||
import { Spin } from '@nocobase/client';
|
import { Spin } from '@nocobase/client';
|
||||||
import Field from './Field';
|
import Field from './Field';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
|
import { useSize } from 'ahooks';
|
||||||
|
import { configResponsive, useResponsive } from 'ahooks';
|
||||||
|
configResponsive({
|
||||||
|
small: 0,
|
||||||
|
middle: 800,
|
||||||
|
large: 1200,
|
||||||
|
});
|
||||||
export function Details(props: any) {
|
export function Details(props: any) {
|
||||||
|
const dom = document.querySelector('body');
|
||||||
|
const responsive = useResponsive();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
activeTab = {},
|
activeTab = {},
|
||||||
pageInfo = {},
|
pageInfo = {},
|
||||||
@ -26,6 +35,15 @@ export function Details(props: any) {
|
|||||||
...actionDefaultParams,
|
...actionDefaultParams,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
let descriptionsProps: any = {
|
||||||
|
size: 'middle',
|
||||||
|
bordered: true,
|
||||||
|
}
|
||||||
|
if (responsive.small && !responsive.middle && !responsive.large) {
|
||||||
|
descriptionsProps = {
|
||||||
|
layout: 'vertical'
|
||||||
|
}
|
||||||
|
}
|
||||||
console.log(props);
|
console.log(props);
|
||||||
return (
|
return (
|
||||||
<Card bordered={false}>
|
<Card bordered={false}>
|
||||||
@ -38,7 +56,12 @@ export function Details(props: any) {
|
|||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
{loading ? <Spin/> : (
|
{loading ? <Spin/> : (
|
||||||
<Descriptions size={'middle'} bordered column={1}>
|
<Descriptions
|
||||||
|
// layout={'vertical'}
|
||||||
|
// size={'middle'}
|
||||||
|
// bordered
|
||||||
|
{...descriptionsProps}
|
||||||
|
column={1}>
|
||||||
{fields.map((field: any) => {
|
{fields.map((field: any) => {
|
||||||
return (
|
return (
|
||||||
<Descriptions.Item label={field.title||field.name}>
|
<Descriptions.Item label={field.title||field.name}>
|
||||||
|
@ -219,6 +219,7 @@ export function LinkToFieldLink(props) {
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
|
className={'noco-drawer'}
|
||||||
bodyStyle={{padding: 0}}
|
bodyStyle={{padding: 0}}
|
||||||
width={'40%'}
|
width={'40%'}
|
||||||
title={`查看${title}详情`}
|
title={`查看${title}详情`}
|
||||||
|
@ -60,6 +60,7 @@ export const DrawerForm = forwardRef((props: any, ref) => {
|
|||||||
destroyOnClose
|
destroyOnClose
|
||||||
visible={visible}
|
visible={visible}
|
||||||
width={'40%'}
|
width={'40%'}
|
||||||
|
className={'noco-drawer'}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}}
|
}}
|
||||||
|
@ -41,4 +41,18 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
max-height: inherit !important;
|
max-height: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-drawer.noco-drawer {
|
||||||
|
.ant-drawer-content-wrapper {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.ant-drawer.noco-drawer {
|
||||||
|
.ant-drawer-content-wrapper {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user