GithubHelp home page GithubHelp logo

arco-design / arco-design-pro Goto Github PK

View Code? Open in Web Editor NEW
456.0 5.0 91.0 2.31 MB

An out-of-the-box solution to quickly build enterprise-level applications based on Arco Design.

Home Page: https://pro.arco.design

License: MIT License

JavaScript 2.48% HTML 0.22% TypeScript 89.67% Less 7.63%
arco-design pro arco-design-pro react template boilerplate

arco-design-pro's Introduction

Arco Design Pro

An out-of-the-box solution to quickly build enterprise-level applications based on Arco Design.

license

English | 简体中文

f769c408-adf4-4a85-b4a5-cc0d7e7f29ef

✨ Features

  • TypeScript - The code is completely written in TypeScript
  • Arco Design - Powered by ArcoDesign React component library
  • Templates - 16+ page templates, covering tables, lists, forms, dashboard, visualization and other scenes.
  • Themes - Based on the rich theme market of DesignLab, make your projects ever-changing.
  • Dark Theme - Switch to dark theme with one click.
  • Mock - Built-in API simulation solution
  • Flexible - Flexible multi-architecture solution, support next.js / vite / cra and other development frameworks
  • I18n - Built-in internationalized multi-language solution
  • Config - Flexible configuration of page color, layout, etc

🔥 Multi-architecture solution

In essence, a Pro project is a set of project templates. The common pro project templates on the market generally have a fixed selection and structure, so that if users want to modify the structure themselves, the cost will be relatively high.

Therefore, the Arco Pro v2 version has designed a set of multi-architecture solutions that can output pro templates of multiple architectures on the basis of maximizing code reuse.

2c7d7cf6-75a8-4014-bc9c-c9999e006c3b

🌈 Usage

$ npm i @arco-design/arco-cli@latest yarn -g

$ arco init my-project

💎 Changelog

LICENSE

MIT © ArcoDesign

arco-design-pro's People

Contributors

declanchiu avatar drizzlesconsin avatar gmengjie avatar hkhere avatar kirazxyun avatar lyqeyes avatar misterluffy avatar muyiyr avatar pengjiyuan avatar queensbarry avatar show8e avatar wenyxu avatar windspiritsr avatar yuhan0709 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

arco-design-pro's Issues

rtl support

Basic Info

add support for rtl. to enable usage for languages like Hebrew or Arabic

What are the similar cases of this feature

Most ui libraries offer this out of the box. (Material ui, Ant Design)

What problem does this feature solve?

add support for rtl. to enable usage for languages like Hebrew or Arabic

展开折叠的目录时“工作台”不会自适应宽度而溢出屏幕

Basic Info

Extra info

本地创建项目时简单版可复现bug,而完整版没有该bug

What is expected?

工作台应该自适应折叠和展开后的宽度,但是实际上不会在展开时调整图表宽度

Steps to reproduce

  1. 点击目录右下角按钮折叠目录
  2. 再次点击展开目录

index的 Form 与弹框的 Form 中的 field 相同时,可能出现警告

基本信息

  1. 使用arco脚本初始化,并修改以下几个文件
    image

  2. 各个文件代码如下:

local/index.tsx

const i18n = {
  'en-US': {
    'menu.list': 'List',
    'menu.list.searchTable': 'Search Table',
    'searchTable.form.search': 'Search',
    'searchTable.form.reset': 'Reset',
    'searchTable.columns.id': 'Collection ID',
    'searchTable.columns.name': 'Collection Name',
    'searchTable.columns.contentType': 'Content genre',
    'searchTable.columns.filterType': 'Filter method',
    'searchTable.columns.createdTime': 'Creation time',
    'searchTable.columns.status': 'Status',
    'searchTable.columns.contentNum': 'Content quantity',
    'searchTable.columns.operations': 'Operation',
    'searchTable.columns.operations.view': 'View',
    'searchTable.columns.operations.update': 'Edit',
    'searchTable.columns.operations.offline': 'Offline',
    'searchTable.columns.operations.online': 'Online',
    'searchTable.operations.add': 'New',
    'searchTable.operations.upload': 'Bulk upload',
    'searchTable.operation.download': 'Download',
    'searchForm.id.placeholder': 'Please enter the collection ID',
    'searchForm.name.placeholder': 'Please enter the collection name',
    'searchForm.all.placeholder': 'all',
    'searchForm.username.placeholder': 'Please enter the username',
    'searchForm.all.select.placeholder': 'Please select',
    'searchForm.phone_number.placeholder': 'Please enter the phone number',
    'searchForm.email_address.placeholder': 'Please enter the email',
    'searchTable.columns.username': 'Username',
    'searchTable.columns.full_name': 'Name',
    'searchTable.columns.gender': 'Gender',
    'searchTable.columns.phone_number': 'Phone Number',
    'searchTable.columns.email_address': 'Email',
    'searchTable.columns.account_expired': 'Account Expired',
    'searchTable.columns.account_locked': 'Account Locked',
    'searchTable.columns.credentials_expired': 'Credentials Expired',
    'searchTable.columns.enabled': 'Enabled',
    'searchTable.operations.addUser': 'Add User',
  },
  'zh-CN': {
    'menu.list': '列表页',
    'menu.list.searchTable': '查询表格',
    'searchTable.form.search': '查询',
    'searchTable.form.reset': '重置',
    'searchTable.columns.id': '集合编号',
    'searchTable.columns.name': '集合名称',
    'searchTable.columns.contentType': '内容体裁',
    'searchTable.columns.filterType': '筛选方式',
    'searchTable.columns.createdTime': '创建时间',
    'searchTable.columns.status': '状态',
    'searchTable.columns.contentNum': '内容量',
    'searchTable.columns.operations': '操作',
    'searchTable.columns.operations.view': '查看',
    'searchTable.columns.operations.update': '修改',
    'searchTable.columns.operations.online': '上线',
    'searchTable.columns.operations.offline': '下线',
    'searchTable.operations.add': '新建',
    'searchTable.operations.upload': '批量导入',
    'searchTable.operation.download': '下载',
    'searchForm.id.placeholder': '请输入集合编号',
    'searchForm.name.placeholder': '请输入集合名称',
    'searchForm.all.placeholder': '全部',
    'searchForm.username.placeholder': '请输入用户名',
    'searchForm.all.select.placeholder': '请选择',
    'searchForm.phone_number.placeholder': '请输入手机号码',
    'searchForm.email_address.placeholder': '请输入邮箱地址',
    'searchTable.columns.username': '用户名',
    'searchTable.columns.full_name': '姓名',
    'searchTable.columns.gender': '性别',
    'searchTable.columns.phone_number': '手机号码',
    'searchTable.columns.email_address': '邮箱',
    'searchTable.columns.account_expired': '账号过期',
    'searchTable.columns.account_locked': '账号被锁',
    'searchTable.columns.credentials_expired': '密码过期',
    'searchTable.columns.enabled': '账号状态',
    'searchTable.operations.addUser': '添加用户',
  },
};

export default i18n;

add-form.tsx

import React, { useContext } from "react";
import { Modal, Button, Switch } from '@arco-design/web-react';
import dayjs from 'dayjs';
import {
  Form,
  Input,
  Select,
  DatePicker,
  Grid,
} from '@arco-design/web-react';
import { GlobalContext } from '@/context';
import locale from './locale';
import useLocale from '@/utils/useLocale';
import { IconRefresh, IconSearch } from '@arco-design/web-react/icon';
import { ContentType, FilterType, Status } from './constants';
import styles from './style/index.module.less';

const { Row, Col } = Grid;
const { useForm } = Form;

function AddForm(props: any) {

    const { lang } = useContext(GlobalContext);

    const t = useLocale(locale);
    const [form] = useForm();
  
    const handleSubmit = () => {
      const values = form.getFieldsValue();
      props.onSearch(values);
    };
  
    const handleReset = () => {
      form.resetFields();
      props.onSearch({});
    };
  
    const colSpan = lang === 'zh-CN' ? 8 : 12;
    
    return (<>
    <Modal
    style={{width: 1000}}
        title='Modal Title'
        visible={props.visible}
        onOk={() => props.onOk()}
        onCancel={() => props.onOk()}
        autoFocus={false}
        focusLock={true}
      >
<Form form={form} labelCol={{span: 6}} wrapperCol={{span: 16}}>
        <Row gutter={20}>
          <Col span={8}>
            <Form.Item
              label="用户名"
              field="username"
              rules={[
                {required: true, message: '请输入用户名'},
                {max: 10, message: '用户名的长度不能超过 10'},
              ]}
            >
              <Input placeholder="请输入用户名"/>
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="姓名"
              field="full_name"
              rules={[
                {required: true, message: '请输入姓名'},
                {max: 10, message: '姓名的长度不能超过 10'},
              ]}
            >
              <Input placeholder="请输入姓名"/>
            </Form.Item>
          </Col>
          <Col span={8}>
            <Form.Item
              label="性别"
              field="gender"
              rules={[{required: true, message: '请选择性别'}]}
            >
              <Select placeholder="请选择">
                <Select.Option value="MALE"></Select.Option>
                <Select.Option value="FEMALE"></Select.Option>
              </Select>
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="密码"
              field="secret_code"
              rules={[
                {required: true, message: '请输入密码'},
                {min: 5, max: 16, message: '密码长度要在 5 - 16 之间'},
              ]}
            >
              <Input.Password placeholder="请输入密码"/>
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="确认密码"
              field="confirm_secret_code"
              rules={[
                {required: true, message: '请确认密码'},
                {
                  validator: async (value, callback) => {
                    return new Promise((resolve) => {
                      if (value !== form.getFieldValue('secret_code')) {
                        setTimeout(() => {
                          callback('两次输入的密码不匹配');
                          resolve();
                        }, 1000);
                      } else {
                        resolve();
                      }
                    })
                  }
                },
              ]}
            >
              <Input.Password placeholder="请确认密码"/>
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="手机号"
              field="phone_number"
              rules={[
                {
                  required: true,
                  message: '请输入手机号',
                },
                {
                  match: /^1\d{10}$/,
                  message: '手机号格式错误',
                },
              ]}
            >
              <Input placeholder="请输入手机号"/>
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              label="联系邮箱"
              field="email_address"
              rules={[{type: 'email', message: '邮箱格式不正确'}]}
            >
              <Input placeholder="请输入联系邮箱"/>
            </Form.Item>
          </Col>
            <>
              <Col span={12}>
                <Form.Item label="是否锁定" field={'account_locked'} triggerPropName={'checked'}>
                  <Switch checkedText="是" uncheckedText="否" defaultChecked/>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="账号是否到期" field="account_expired" triggerPropName={'checked'}>
                  <Switch checkedText="是" uncheckedText="否" defaultChecked/>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="账号是否启用" field="enabled" triggerPropName={'checked'}>
                  <Switch checkedText="是" uncheckedText="否" defaultChecked/>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item
                  label="密码是否过期"
                  field="credentials_expired"
                  triggerPropName={'checked'}
                >
                  <Switch checkedText="是" uncheckedText="否" defaultChecked/>
                </Form.Item>
              </Col>
            </>
        </Row>
             </Form>
      </Modal>
    </>)
}

export default AddForm;

form.tsx

import React, { useContext } from 'react';
import dayjs from 'dayjs';
import {
  Form,
  Input,
  Select,
  DatePicker,
  Button,
  Grid,
} from '@arco-design/web-react';
import { GlobalContext } from '@/context';
import locale from './locale';
import useLocale from '@/utils/useLocale';
import { IconRefresh, IconSearch } from '@arco-design/web-react/icon';
import { ContentType, FilterType, Status } from './constants';
import styles from './style/index.module.less';
import AddForm from './add-form';

const { Row, Col } = Grid;
const { useForm } = Form;

function SearchForm(props: {
  onSearch: (values: Record<string, any>) => void;
}) {
  const { lang } = useContext(GlobalContext);

  const t = useLocale(locale);
  const [form] = useForm();

  const handleSubmit = () => {
    const values = form.getFieldsValue();
    props.onSearch(values);
  };

  const handleReset = () => {
    form.resetFields();
    props.onSearch({});
  };

  const colSpan = lang === 'zh-CN' ? 8 : 12;

  return (
    <div className={styles['search-form-wrapper']}>
       <Form
        form={form}
        className={styles['search-form']}
        labelAlign="left"
        labelCol={{span: 5}}
        wrapperCol={{span: 19}}
      >
        <Row gutter={24}>
          <Col span={colSpan}>
            <Form.Item label={'ID'} field="id">
              <Input placeholder={t['searchForm.id.placeholder']} allowClear/>
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item label={t['searchTable.columns.username']} field="username">
              <Input
                allowClear
                placeholder={t['searchForm.username.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.gender']}
              field="gender"
            >
              <Select
                allowClear
                placeholder={t['searchForm.all.select.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.phone_number']}
              field="phone_number"
            >
              <Input
                allowClear
                placeholder={t['searchForm.phone_number.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.email_address']}
              field="email_address"
            >
              <Input
                allowClear
                placeholder={t['searchForm.email_address.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.account_expired']}
              field="account_expired"
            >
              <Select
                allowClear
                placeholder={t['searchForm.all.select.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.account_locked']}
              field="account_locked"
            >
              <Select
                allowClear
                placeholder={t['searchForm.all.select.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.credentials_expired']}
              field="credentials_expired"
            >
              <Select
                allowClear
                placeholder={t['searchForm.all.select.placeholder']}
              />
            </Form.Item>
          </Col>
          <Col span={colSpan}>
            <Form.Item
              label={t['searchTable.columns.enabled']}
              field="enabled"
            >
              <Select
                allowClear
                placeholder={t['searchForm.all.select.placeholder']}
              />
            </Form.Item>
          </Col>
        </Row>
      </Form>
      <div className={styles['right-button']}>
        <Button type="primary" icon={<IconSearch/>} onClick={handleSubmit}>
          {t['searchTable.form.search']}
        </Button>
        <Button icon={<IconRefresh/>} onClick={handleReset}>
          {t['searchTable.form.reset']}
        </Button>
      </div>
    </div>
  );
}

export default SearchForm;

index.tsx

import React, { useState, useEffect, useMemo } from 'react';
import {
  Table,
  Card,
  PaginationProps,
  Button,
  Space,
} from '@arco-design/web-react';
import PermissionWrapper from '@/components/PermissionWrapper';
import { IconDownload, IconPlus } from '@arco-design/web-react/icon';
import axios from 'axios';
import useLocale from '@/utils/useLocale';
import SearchForm from './form';
import locale from './locale';
import styles from './style/index.module.less';
import './mock';
import { getColumns } from './constants';
import AddForm from './add-form';

export const ContentType = ['图文', '横版短视频', '竖版短视频'];
export const FilterType = ['规则筛选', '人工'];
export const Status = ['已上线', '未上线'];

function SearchTable() {
  const t = useLocale(locale);

  const tableCallback = async (record, type) => {
    console.log(record, type);
  };

  const columns = useMemo(() => getColumns(t, tableCallback), [t]);

  const [data, setData] = useState([]);
  const [visible, setVisible] = React.useState(false);
  const [pagination, setPatination] = useState<PaginationProps>({
    sizeCanChange: true,
    showTotal: true,
    pageSize: 10,
    current: 1,
    pageSizeChangeResetCurrent: true,
  });
  const [loading, setLoading] = useState(true);
  const [formParams, setFormParams] = useState({});

  useEffect(() => {
    fetchData();
  }, [pagination.current, pagination.pageSize, JSON.stringify(formParams)]);

  function fetchData() {
    const { current, pageSize } = pagination;
    setLoading(true);
    axios
      .get('/api/list', {
        params: {
          page: current,
          pageSize,
          ...formParams,
        },
      })
      .then((res) => {
        setData(res.data.list);
        setPatination({
          ...pagination,
          current,
          pageSize,
          total: res.data.total,
        });
        setLoading(false);
      });
  }

  function onChangeTable(pagination) {
    setPatination(pagination);
  }

  function handleSearch(params) {
    setFormParams(params);
  }

  return (
    <div>
      <AddForm visible={visible} onOk={() => setVisible(false)} />
      <Card
        title={t['menu.list.searchTable']}
        headerStyle={{ border: 'none', height: 'auto', paddingTop: '20px' }}
      >
        <SearchForm onSearch={handleSearch} />
        <PermissionWrapper
          requiredPermissions={[
            { resource: 'menu.list.searchTable', actions: ['write'] },
          ]}
        >
          <div className={styles['button-group']}>
            <Space>
              <Button type="primary" icon={<IconPlus />} onClick={() => setVisible(true)}>
                {t['searchTable.operations.add']}
              </Button>
              <Button>{t['searchTable.operations.upload']}</Button>
            </Space>
            <Space>
              <Button icon={<IconDownload />}>
                {t['searchTable.operation.download']}
              </Button>
            </Space>
          </div>
        </PermissionWrapper>
        <Table
          rowKey="id"
          loading={loading}
          onChange={onChangeTable}
          pagination={pagination}
          columns={columns}
          data={data}
        />
      </Card>
    </div>
  );
}

export default SearchTable;
  1. 点击pro查询表格的 新建 按钮
    image

预期结果

没有警告

希望arco-design-pro支持React 17.0全新jsx转换,否则引入第三方组件无法正常编译,比如react-dnd

Basic Info

What are the similar cases of this feature

暂无

What problem does this feature solve?

当尝试在arco-design-pro中使用react-dnd,执行npm run dev 遇到如下错误:
ERROR in ./node_modules/react-dnd/dist/esm/core/DndProvider.js
Module not found: Error: Can't resolve 'react/jsx-runtime' in 'arco-test/node_modules/react-dnd/dist/esm/core'

通过以下方式才得以解决,但成本较大:
1、尝试升级typescript(4 )、react(17.0.2)、react-dom(17.0.2)等
2、尝试去除arco-design-pro代码中 import React from 'react'
3、修改配置webpack.config、.babelrc、.tsconfig.json

template China map reverse bug

Basic Info

预期结果

the China map not reverse

复现步骤

just open the link, you will see that. https://arco.design/material/detail?name=@arco-design/pro-pages-multi-dimension-data-analysis

image

无法初始化项目

Basic Info

  • Package Name And Version: [email protected]
  • Framework version: 3.2.31
  • Browser: chrome103.0.5060.114

Steps to reproduce

使用 Node.js v16.15.1初始化项目失败:

$ arco init hello-arco-pro
? 请选择你希望使用的技术栈 Vue
? 请选择所要创建项目的类型 Arco Pro 项目
? 请选择 Arco Pro 模板 简单版(只包含一个基础页面)

正在初始化项目于 E:\Test\hello-arco-pro
√ 获取项目模板成功
× 模板内容拷贝失败
Error: Failed to copy project content.
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

    at module.exports (C:\Users\Max\.arco_template_cache\1658025588468\node_modules\arco-design-pro-vue\.arco-cli\init.js:25:13)
    at C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\arco-cli-create-project\lib\index.js:129:23
    at Generator.next (<anonymous>)
    at fulfilled (C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\arco-cli-create-project\lib\index.js:5:58)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
Error: EBUSY: resource busy or locked, rmdir 'C:\Users\Max\.arco_template_cache\1658025588468\node_modules\arco-design-pro-vue'
node:fs:1180
  return handleErrorFromBinding(ctx);
         ^

Error: EBUSY: resource busy or locked, rmdir 'C:\Users\Max\.arco_template_cache\1658025588468\node_modules\arco-design-pro-vue'
    at Object.rmdirSync (node:fs:1180:10)
    at rmdirSync (C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:264:13)
    at rimrafSync (C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:243:7)
    at C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:279:39
    at Array.forEach (<anonymous>)
    at rmkidsSync (C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:279:26)
    at rmdirSync (C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:269:7)
    at rimrafSync (C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:243:7)
    at C:\Users\Max\AppData\Roaming\npm\node_modules\arco-cli\node_modules\fs-extra\lib\remove\rimraf.js:279:39
    at Array.forEach (<anonymous>) {
  errno: -4082,
  syscall: 'rmdir',
  code: 'EBUSY',
  path: 'C:\\Users\\Max\\.arco_template_cache\\1658025588468\\node_modules\\arco-design-pro-vue'
}

使用 Node.js v18.6.0 初始化项目成果,但是依赖安装失败:

$ arco init hello-arco-pro
? 请选择你希望使用的技术栈 Vue
? 请选择所要创建项目的类型 Arco Pro 项目
? 请选择 Arco Pro 模板 简单版(只包含一个基础页面)

正在初始化项目于 E:\Test\hello-arco-pro
√ 获取项目模板成功
√ 模板内容拷贝完成
√ 模板内容适配完成
× 项目依赖安失败,你可以稍后尝试手动安装项目依赖
Error: Command 「npm install」 executed failed:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/eslint
npm ERR!   dev eslint@"^8.7.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer eslint@"^5.16.0 || ^6.8.0 || ^7.2.0" from [email protected]
npm ERR! node_modules/eslint-config-airbnb-base
npm ERR!   dev eslint-config-airbnb-base@"^14.2.1" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\Max\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Max\AppData\Local\npm-cache\_logs\2022-07-17T06_02_31_818Z-debug-0.log

 arco-init  项目初始化失败!
Error: spawnSync yarn.cmd ENOENT

手动安装依赖失败:

$ npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/eslint
npm ERR!   dev eslint@"^8.7.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer eslint@"^5.16.0 || ^6.8.0 || ^7.2.0" from [email protected]
npm ERR! node_modules/eslint-config-airbnb-base
npm ERR!   dev eslint-config-airbnb-base@"^14.2.1" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\Max\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Max\AppData\Local\npm-cache\_logs\2022-07-17T06_03_57_177Z-debug-0.log

当进行菜单的快速切换时,控制台提示内存泄漏

Basic Info

Extra info

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

What is expected?

这是否是一个需要修复的bug

跑不起来...

基本信息

  • 依赖包名 及 版本: [email protected]
  • 系统版本: macos
  • 浏览器版本: chrome98.0.4758.109
  • 复现地址:

预期结果

成功创建项目.

复现步骤

输入

arco init hello-arco-pro

选择公共版本
提示: TypeError: Cannot read properties of undefined (reading 'public')
image

支持环境变量配置

Basic Info

What are the similar cases of this feature

添加.env文件,可读取process.env

What problem does this feature solve?

添加.env文件,读取process.env为空

Extra info

# .env 文件
REACT_APP_DOCUMENT_TITLE = arco design
/* index.ts */
console.log(process.env);
// {}
console.log(process.env.REACT_APP_DOCUMENT_TITLE);
// undefined

react-router

Basic Info

What are the similar cases of this feature

希望能更新react-router@6版本

What problem does this feature solve?

希望能更新react-router@6版本

权限控制, 设置requiredPermissions时, source字段使用正则. 当用户权限不匹配任何source正则时, 被错误的判断为有权限

Basic Info

What is expected?

当用户权限不匹配任何source正则时, 应该正确的被识别为无权限.

Steps to reproduce

  1. 某个菜单/路由A 的 requiredPermissions 设置为:
    [{ resource: /whatever/, actions: ['read', 'write'] }]

  2. userInfo.permissions设置为空: {}

  3. 此时菜单/路由A对用户可见, 不符合预期.

vite-react 下,生产构建产物使用 koa server 时,lazy load module 失败

Basic Info

What is expected?

正确加载模块

Steps to reproduce

  1. 使用 cli 创建 react-vite 应用
  2. 执行构建 vite build
  3. 使用 koa server 静态资源
app.use(koaStatic(path.join(__dirname, '../public')));
router.get('*', async index(ctx) {
    const html = await fsExtra.readFile(
      path.join(__dirname, '../../public/index.html')
    );
    ctx.response.set('content-type', 'text/html');
    ctx.body = html;
  }

  async noop(ctx) {
    ctx.body = '';
  });

控制台报错:

image

希望不授权就能使用cli初始化项目

Basic Info

现有案例

我用过的所有cli(如ant design pro)没有一个是要授权才能用的

预期解决问题

现在是用vscode远程连接到服务器进行开发,而pro的cli必须要用github账号授权才能使用,但在我本机授权是没有办法回调到服务器的,所以希望取消必须授权的限制

In the useStorage removeStorage method, it is the variable key, not the string key, that should be taken to clear the local cache

基本信息

预期结果

After you click the clear method, the cache for the key in localStorage should disappear.

复现步骤

Use useStorage hooks on the page, use the array subscript 1 set cache method in useEffect to set a string. Then write a button to trigger the cleanup cache method provided by array subscript 2, but it doesn't work, and the corresponding key cache for localStorage still exists.

autoprefixer warning

arco-design for nextjs 搭建后

pnpm dev

提示

warn - ./node_modules/.pnpm/[email protected]_sfoxds7t5ydpegc3knd667wn6m/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[2].oneOf[11].use[1]!./node_modules/.pnpm/[email protected]_sfoxds7t5ydpegc3knd667wn6m/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[2].oneOf[11].use[2]!./node_modules/.pnpm/[email protected]_sfoxds7t5ydpegc3knd667wn6m/node_modules/next/dist/build/webpack/loaders/resolve-url-loader/index.js??ruleSet[1].rules[2].oneOf[11].use[3]!./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/less-loader/dist/cjs.js??ruleSet[1].rules[2].oneOf[11].use[4]!./src/style/global.less
Warning

autoprefixer: end value has mixed support, consider using flex-end instead

在手动把 align-item:end 改成 flex-end 之后警告消失

使用 PermissionWrapper 组件包裹固定元素进行权限管理, 并设置backup属性. 渲染时会先闪现backup, 然后再展示期望的组件.

Basic Info

What is expected?

有权限时直接展示被包裹的组件, backup不要出现.

Steps to reproduce

  1. PermissionWrapper 包裹组件, 并设置requiredPermissions 和 backup 属性.
  2. 当前用户具备requiredPermissions声明的权限
  3. 刷新页面
  4. 先闪现了backup的内容, 然后再快速恢复到期望的内容

代码示例:

<PermissionWrapper requiredPermissions={[ { resource: 'menu.list.searchTable', actions: ['write'] }, ]} backup={ <> <div> 申请权限!!!申请权限!!!申请权限!!!申请权限!!!申请权限!!! <hr /> WWWWWWWWWWWWWWWWWWWWW <hr /> WWWWWWWWWWWWWWWWWWWWW <hr /> WWWWWWWWWWWWWWWWWWWWW <hr /> WWWWWWWWWWWWWWWWWWWWW <hr /> WWWWWWWWWWWWWWWWWWWWW <hr /> WWWWWWWWWWWWWWWWWWWWW </div> </> } > <Card>...</Card> </PermissionWrapper>

20220628145028

routes.ts 中 children 有一个路由,这个路由的ignore=true,无法正常跳转

基本信息

预期结果

左侧菜单隐藏该路由,可以正常跳转到该路由,面包屑也能包含该层级的路由

复现步骤

在routes.ts文件中配置一个有 children 的路由,children 中包含一个配置了 ignore=true 的路由,提供一个按钮跳转到该路由

image

webpack 配置代理后路由跳转有问题

Basic Info

  • Package Name And Version: "@arco-design/webpack-plugin": "^1.5.2"
  • System: mac os
  • Browser: chrome
  • Reproduction Link: 官方是否可以提供一个简易的 jsfiddle/codepen/codesandbox 例子,我们再根据这个例子 fork 出来重现 bug,这样会方便一点~

What is expected?

登陆成功后,正常跳转

Steps to reproduce

如果有登陆,先退出登陆

  1. 在 webpack.config.js 添加配置
  config.devServer = {
    proxy: {
      '/simpleProxy': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        pathRewrite: { '^/simpleProxy': '' },
      },
    }
  }
  1. 输入账号密码,点击登陆

image

  1. 浏览器重新访问 http://localhost:9090/ 后,才可以正常访问

权限控制菜单,在初次渲染中,会渲染默认路由中所有的菜单(有权限/无权限)

image

- [ ] I'm sure this does not appear in [the issue list of the repository](https://github.com/arco-design/arco-design-pro/issues)

Basic Info

What is expected?

不应该出现没有权限的菜单

Steps to reproduce

  1. 在 arco-design-pro-next 下的 src/routes.ts 中的 useRoute 函数中打一个断点
  2. 在 src/routes.ts 中修改 routes 数组:
    export const routes: IRoute[] = [
    {
    name: 'menu.dashboard',
    key: 'dashboard',
    children: [
    {
    name: 'menu.dashboard.workplace',
    key: 'dashboard/workplace',
    },
    {
    name: 'menu.dashboard.monitor',
    key: 'dashboard/monitor',
    requiredPermissions: [
    { resource: 'menu.dashboard.monitor', actions: ['write']},
    ],
    },
    ],
    }]
  3. 页面中切换用户,将角色由管理员修改为普通用户
  4. 刷新页面,左侧菜单中出现了所有的菜单项(没有权限的菜单项也被渲染了)

路由权限控制有什么方式吗

Basic Info

What are the similar cases of this feature

类似 ant design pro 的权限控制,或者是否可以根据一个 http 请求动态生成菜单(这个我在 ant design pro 提过,没有好的解决方案就关了,现在那个 issue 还偶尔被挖出来,所以应该还是很多人希望有这个功能的。。。)

What problem does this feature solve?

根据权限控制菜单的显示

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.