1.0.2 • Published 7 months ago

@easytool/react-permission v1.0.2

Weekly downloads
81
License
MIT
Repository
github
Last release
7 months ago

@easytool/react-permission

Easy to handle react component permissions.

Install

npm install -S @easytool/react-permission

Usage

import Permission from '@easytool/react-permission';
import React from 'react';
import { render } from 'react-dom';

render(
    <Permission hasPermission={[1, 2, 3, 4]}>
        <div permission="1">1</div>
        <div permission="1, 2">1, 2</div>
        <div permission={[1, 2, 3]}>1, 2, 3</div>
        <MyComponent permission={4}>4</MyComponent>
    </Permission>,
    document.getElementById('app')
);

Asynchronous setting permission

var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve([1, 2, 3]);
    }, 3000);
});

render(
    <Permission hasPermission={promise}>
        <div permission="1">1</div>
        <div permission="2">2</div>
        <div permission="3">3</div>
    </Permission>,
    document.getElementById('app')
);

onLoad

var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve([1, 2, 3]);
    }, 3000);
});

render(
    <Permission hasPermission={promise} onLoad={<div>Loading...</div>}>
        <div permission="1">1</div>
        <div permission="2">2</div>
        <div permission="3">3</div>
    </Permission>,
    document.getElementById('app')
);

onDeny

Change denied element.

render(
    <Permission hasPermission={[1]} onDeny={el => React.cloneElement(el, { style: { color: 'red' } })}>
        <div permission="1">1</div>
        <MyComponent permission="2">2</MyComponent>
    </Permission>,
    document.getElementById('app')
);

Replace denied element.

render(
    <Permission hasPermission={[1]} onDeny={<h3>Permission denied</h3>}>
        <div permission="1">1</div>
        <MyComponent permission="2">2</MyComponent>
    </Permission>,
    document.getElementById('app')
);

Handle deny to specific element.

render(
    <Permission hasPermission={[1]}>
        // DOM Elements can not use 'onxxx' custom attributes, so use 'deny' in place of it.
        <div permission="1" deny={<h3>Permission denied</h3>}>1</div>
        <MyComponent permission="2" onDeny={<h3>Not Allow</h3>}>2</MyComponent>
    </Permission>,
    document.getElementById('app')
);

Use Context Provider

Set global Permission.

import Permission, { PermissionContext } from '@easytool/react-permission';

render(
    <PermissionContext.Provider value={{ hasPermission: [1, 2, 3] }}>
        <Permission>
            <div permission="1">1</div>
            <div permission="2">2</div>
        </Permission>
        <Permission>
            <div permission="3">3</div>
            <MyComponent permission="4" />
        </Permission>
    </PermissionContext.Provider>,
    document.getElementById('app')
);

Asynchronous setting permission.

import Permission, { PermissionContext } from '@easytool/react-permission';

var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve([1, 2, 3]);
    }, 3000);
});

render(
    <PermissionContext.Provider value={{ hasPermission: promise, onDeny: <h3>Permission denied</h3> }}>
        <Permission>
            <div permission="1">1</div>
            <div permission="2">2</div>
        </Permission>
        <Permission>
            <div permission="3">3</div>
            <MyComponent permission="4" />
        </Permission>
    </PermissionContext.Provider>,
    document.getElementById('app')
);

Updating permission from a nested component.

class Home extends React.Component {
    static contextType = PermissionContext;

    componentDidMount() {
        setTimeout(() => {
            this.context.togglePermission([1, 2, 3]);
        }, 2000);
    }

    render() {
        return (
            <Permission>
                <h1 permission="1">Home</h1>
                <p permission="2">permission 2</p>
                <p permission="3">permission 3</p>
            </Permission>
        );
    }
}

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            hasPermission: [1, 2],
            togglePermission: (permissions) => {
                this.setState({
                    hasPermission: permissions
                });
            }
        };
    }

    render() {
        return (
            <PermissionContext.Provider value={this.state}>
                <Home />
            </PermissionContext.Provider>
        );
    }
}

render(
    <App />,
    document.getElementById('app')
);

Work with React Router

react-router@4-5

import Permission, { PermissionContext } from '@easytool/react-permission';

function Deny() {
    return <p>Permission denied</p>;
}

let res, rej;
const context = { 
    hasPermission: new Promise((resolve, reject) => {
        res = resolve;
        rej = reject;
    }),
    onDeny: (el, index) => React.cloneElement(el, { component: Deny })
};

class App extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        // request permission
        setTimeout(() => {
            res([1, 2]);
        }, 2000);
    }

    render() {
        return (
            {/* using global setting */}
            <PermissionContext.Provider value={context}>
                <Permission>
                    <HashRouter>
                        <Switch>
                            <Route path="/home" component={Home} permission="2" />
                            {/* this route will be denied  */}
                            <Route path="/list" component={List} permission="3" />                            
                            <Route path="/" component={App} permission="1" />
                        </Switch>
                    </HashRouter>
                </Permission>
            </PermissionContext.Provider>
        );
    }
}

render(
    <App />,
    document.getElementById('app')
);

react-router@3

function Deny() {
    return <p>Permission denied</p>;
}

render(
    <Permission hasPermission={[1, 2]} onDeny={(el, index) => React.cloneElement(el, { key: index, component: Deny })}>
        <Router history={hashHistory} >
            <Route path="/" permission="1">
                <Route path="/home" component={Home} permission="2" />
                <Route path="/detail" component={Detail} permission="3" />
            </Route>
        </Router>
    </Permission>,
    document.getElementById('app')
);

onLoad props is required when use Promise for react-router@3.

var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve([1, 2]);
    }, 3000);
});

render(
    <Permission hasPermission={promise} onLoad={<h1>Loading...</h1>}>
        <Router history={hashHistory} >
            <Route path="/" permission="1">
                <Route path="/home" component={Home} permission="2" />
                <Route path="/detail" component={Detail} permission="3" />
            </Route>
        </Router>
    </Permission>,
    document.getElementById('app')
);

Work with AntD Table

import { Table } from 'antd';
import Permission, { PermissionContext } from '@easytool/react-permission';

var dataSource = [{
    key: '1',
    permission: 1,
    name: 'Stephen'
}, {
    key: '2',
    permission: 2,
    name: 'Ricky'
}, {
    key: '3',
    permission: 3,
    name: 'Ray'
}];

render(
    <PermissionContext.Provider value={{ hasPermission: [1, 2] }}>
        <Table dataSource={dataSource}>
            <Column
                title="Name"
                dataIndex="name"
                key="name"
                render={(text, record, index) => {
                    return (
                        <Permission onDeny={<span>Permission denied</span>}>
                            <span permission={record.permission}>{text}</span>
                        </Permission>
                    );
                }}
            />
        </Table>
    </PermissionContext.Provider>,
    document.getElementById('app')
);

API

Permission

ParamTypeDescription
hasPermissionstring|number|array|promiseset user's permission.
comparePermissionfunctioncustom compare function, receive(elementPermission, hasPermission). return true means authorized, false means denied.
onLoadreact elementwhen the hasPermission prop is promise type and state is pending then will use this element to render.
onDenyreact element|functionthis method will be invoked when permission denied occur, function receive denied element and element index in parent children, return a replace element or nothing.
onErrorfunctionwhen hasPermission is promise and throw error, it will be invoked.

PermissionContext.Provider

You can specify Context Provider that will be applied to every \<Permission>.

value

ParamTypeDescription
hasPermissionstring|number|array|promiseas above.
comparePermissionfunctionas above.
onLoadreact elementas above.
onDenyreact element|functionas above.
onErrorfunctionas above.

TODO

  1. 用户自己选择查找的子元素, 默认是children
  2. 对比方法用户自定义
  3. 返回时添加装饰器
  4. filterChildren 增加用户自定义判断
1.0.2

7 months ago

1.0.1

1 year ago

0.1.10

3 years ago

0.1.11

3 years ago

0.1.8

3 years ago

0.1.9

3 years ago

0.1.7

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.1.4

4 years ago

0.1.3

4 years ago

0.1.2

4 years ago

0.1.1

5 years ago