Merge pull request #498 from ONLYOFFICE/feature/accessRightSelect

Feature/access right select
This commit is contained in:
Ilya Oleshko 2022-01-28 13:00:47 +03:00 committed by GitHub
commit 8428ef730c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 414 additions and 0 deletions

View File

@ -0,0 +1,52 @@
# AccessRightSelect
### Usage
```js
import AccessRightSelect from "@appserver/components/AccessRightSelect";
```
```jsx
<AccessRightSelect
options={options}
onSelect={(option) => console.log("selected", option)}
selectedOption={{
key: "key1",
title: "Room administrator",
description: `Administration of rooms, archiving of rooms, inviting and managing users in rooms.`,
icon: CrownIcon,
quota: "free",
color: "#20D21F",
}}
/>
```
#### Options is an array of objects that contains the following fields:
- key
- title
- description
- icon
- quota
- color
##### Example:
```js
{
key: "key1",
title: "Room administrator",
description: `Administration of rooms, archiving of rooms, inviting and managing users in rooms.`,
icon: CrownIcon,
quota: "free",
color: "#20D21F",
}
```
### Properties
| Props | Type | Required | Values | Default | Description |
| ---------------- | :------------: | :------: | :----: | :-----: | ------------------------------------------------------------------ |
| `options` | `obj`, `array` | ✅ | - | - | List of options |
| `onSelect` | `obj`, `array` | - | - | - | Will be triggered whenever an AccessRightSelect is selected option |
| `selectedOption` | `obj` | - | - | - | The option that is selected by default |

View File

@ -0,0 +1,26 @@
import React from "react";
import AccessRightSelect from "./";
import { data } from "./data";
const Wrapper = (props) => (
<div
style={{
height: "420px",
}}
>
{props.children}
</div>
);
const Template = (args) => (
<Wrapper>
<AccessRightSelect {...args} />
</Wrapper>
);
export const Default = Template.bind({});
Default.args = {
options: data,
selectedOption: data[0],
};

View File

@ -0,0 +1,55 @@
import { Meta, Story, ArgsTable, Canvas } from "@storybook/addon-docs/blocks";
import AccessRightSelect from "./";
import * as stories from "./access-right-select.stories.js";
<Meta
title="Components/AccessRightSelect"
component={AccessRightSelect}
argTypes={{
onSelect: {
action: "onSelect",
},
options: { required: true },
}}
/>
# AccessRightSelect
Custom access-right-select
<Canvas>
<Story story={stories.Default} name="Default" />
</Canvas>
### Properties
<ArgsTable story="Default" />
### Import
```js
import AccessRightSelect from "@appserver/components/access-right-secelt";
```
#### Options is an array of objects that contains the following fields:
- key
- title
- description
- icon
- quota
- color
##### Example:
```js
{
key: "key1",
title: "Room administrator",
description: `Administration of rooms, archiving of rooms, inviting and managing users in rooms.`,
icon: CrownIcon,
quota: "free",
color: "#20D21F",
}
```

View File

@ -0,0 +1,60 @@
import {
AccessNoneIcon,
CheckRoundIcon,
CommentIcon,
CrownIcon,
EyeIcon,
PencilIcon,
ReviewIcon,
} from "./svg";
export const data = [
{
key: "key1",
title: "Room administrator",
description: `Administration of rooms, archiving of rooms, inviting and managing users in rooms.`,
icon: CrownIcon,
quota: "free",
color: "#20D21F",
},
{
key: "key2",
title: "Full access",
description: `Edit, upload, create, view, download, delete files and folders.`,
icon: CheckRoundIcon,
quota: "paid",
color: "#EDC409",
},
{ key: "key3", isSeparator: true },
{
key: "key4",
title: "Editing",
description: `Editing, viewing, downloading files and folders, filling out forms.`,
icon: PencilIcon,
},
{
key: "key5",
title: "Review",
description: `Reviewing, viewing, downloading files and folders, filling out forms.`,
icon: ReviewIcon,
},
{
key: "key6",
title: "Comment",
description: `Commenting on files, viewing, downloading files and folders, filling out forms.`,
icon: CommentIcon,
},
{
key: "key7",
title: "Read only",
description: `Viewing, downloading files and folders, filling out forms.`,
icon: EyeIcon,
},
{
key: "key8",
title: "Deny access",
description: "",
icon: AccessNoneIcon,
},
];

View File

@ -0,0 +1,99 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import ComboBox from "../combobox/index.js";
import DropDownItem from "../drop-down-item/index.js";
import Badge from "../badge/index.js";
import {
StyledAccessRightWrapper,
StyledAccessRightIcon,
StyledAccessRightDescriptionItem,
StyledAccessRightItem,
StyledAccessRightItemIcon,
StyledAccessRightItemContent,
StyledAccessRightItemTitleAndBadge,
} from "./styled-accessright.js";
const AccessRightSelect = ({ options, onSelect, selectedOption, ...props }) => {
const [currentItem, setCurrentItem] = useState(selectedOption);
function onSelectCurrentItem(e) {
const key = e.currentTarget.dataset.key;
const item = options.find((el) => {
return el.key === key;
});
if (item) {
setCurrentItem(item);
onSelect && onSelect(item);
}
}
const formatToAccessRightItem = (data) => {
return (
<>
{data.map((it) => {
return it.isSeparator ? (
<DropDownItem isSeparator />
) : (
<DropDownItem
key={it.key}
data-key={it.key}
onClick={onSelectCurrentItem}
>
<StyledAccessRightItem>
<StyledAccessRightItemIcon src={it.icon} />
<StyledAccessRightItemContent>
<StyledAccessRightItemTitleAndBadge>
{it.title}
{it.quota && (
<Badge
label={it.quota}
backgroundColor={it.color}
fontSize="8px"
/>
)}
</StyledAccessRightItemTitleAndBadge>
<StyledAccessRightDescriptionItem>
{it.description}
</StyledAccessRightDescriptionItem>
</StyledAccessRightItemContent>
</StyledAccessRightItem>
</DropDownItem>
);
})}
</>
);
};
return (
<StyledAccessRightWrapper>
<StyledAccessRightIcon src={currentItem?.icon} />
<ComboBox
advancedOptions={formatToAccessRightItem(options)}
directionX="left"
directionY="bottom"
opened
noBorder
options={[]}
scaled={false}
selectedOption={{
default: true,
key: currentItem?.key,
label: currentItem?.title,
}}
size="content"
/>
</StyledAccessRightWrapper>
);
};
AccessRightSelect.propTypes = {
/** List of rights */
options: PropTypes.arrayOf(PropTypes.object).isRequired,
/** Will be triggered whenever an AccessRightSelect is selected option */
onSelect: PropTypes.func,
/** The option that is selected by default */
selectedOption: PropTypes.object,
};
export default AccessRightSelect;

View File

@ -0,0 +1,59 @@
import styled from "styled-components";
import Base from "../themes/base";
const StyledAccessRightWrapper = styled.div`
display: flex;
`;
const StyledAccessRightIcon = styled.img`
margin-right: 4.18px;
`;
const StyledAccessRightItem = styled.div`
width: 424px;
display: flex;
align-items: flex-start;
justify-content: flex-start;
align-content: center;
padding: 7px 0px;
line-height: 16px;
font-style: normal;
`;
const StyledAccessRightDescriptionItem = styled.div`
margin: 1px 0px;
font-size: 13px;
font-style: normal;
font-weight: 400;
line-height: 16px;
color: #a3a9ae;
`;
const StyledAccessRightItemIcon = styled.img`
margin-right: 8px;
`;
const StyledAccessRightItemContent = styled.div`
width: 100%;
white-space: normal;
`;
const StyledAccessRightItemTitleAndBadge = styled.div`
display: flex;
align-items: center;
`;
StyledAccessRightItem.defaultProps = { theme: Base };
export {
StyledAccessRightItem,
StyledAccessRightDescriptionItem,
StyledAccessRightItemIcon,
StyledAccessRightItemContent,
StyledAccessRightItemTitleAndBadge,
StyledAccessRightWrapper,
StyledAccessRightIcon,
};

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_18889_63383)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.4769 3.10916C9.13367 1.43923 5.85958 1.65538 3.75736 3.7576C1.65513 5.85983 1.43898 9.13391 3.10891 11.4771L11.4769 3.10916ZM12.8911 4.52337L4.52313 12.8913C6.86633 14.5613 10.1404 14.3451 12.2426 12.2429C14.3449 10.1407 14.561 6.86657 12.8911 4.52337ZM2.34315 2.34339C5.46734 -0.780804 10.5327 -0.780804 13.6569 2.34339C16.781 5.46758 16.781 10.5329 13.6569 13.6571C10.5327 16.7813 5.46734 16.7813 2.34315 13.6571C-0.781049 10.5329 -0.781049 5.46758 2.34315 2.34339Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_18889_63383">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 792 B

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 8C14 7.75799 13.9857 7.51933 13.9578 7.28482L15.6359 5.60676C15.8725 6.36243 16 7.16632 16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C9.37506 0 10.6691 0.34692 11.7993 0.95801L10.3005 2.45685C9.59204 2.16249 8.815 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14C11.3137 14 14 11.3137 14 8ZM14.2071 4.20678L7.70711 10.7068C7.31659 11.0973 6.68342 11.0973 6.2929 10.7068L3.29289 7.70677L4.70711 6.29256L7.00001 8.58546L12.7929 2.79257L14.2071 4.20678Z" fill="#333333"/>
</svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_18889_63370)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2.99976C0 1.89519 0.89543 0.999756 2 0.999756H14C15.1046 0.999756 16 1.89519 16 2.99976V10.9998C16 12.1043 15.1046 12.9998 14 12.9998H5.41421L3.41421 14.9998C2.15428 16.2597 0 15.3673 0 13.5855V2.99976ZM14 2.99976L2 2.99976V13.5855L4 11.5855C4.37507 11.2105 4.88378 10.9998 5.41421 10.9998H14V2.99976Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_18889_63370">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 625 B

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_18889_63322)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.9285 0.629586C8.77663 0.249928 8.40892 0.000976562 8.00002 0.000976562C7.59111 0.000976562 7.22341 0.249928 7.07154 0.629586L5.44293 4.70111L1.37141 3.0725C0.985924 2.91831 0.545259 3.01834 0.264136 3.32387C-0.0169859 3.62939 -0.0800827 4.07684 0.105592 4.44819L2.10559 8.44819L3.89445 7.55376L3.07071 5.90628L5.62863 6.92945C6.14141 7.13457 6.72338 6.88515 6.9285 6.37237L8.00002 3.69356L9.07154 6.37237C9.27666 6.88515 9.85863 7.13457 10.3714 6.92945L12.9293 5.90628L12.1056 7.55376L13.8944 8.44819L15.8944 4.44819C16.0801 4.07684 16.017 3.62939 15.7359 3.32387C15.4548 3.01834 15.0141 2.91831 14.6286 3.0725L10.5571 4.70111L8.9285 0.629586ZM3.00002 13.001V14.001C3.00002 15.1055 3.89545 16.001 5.00002 16.001H11C12.1046 16.001 13 15.1055 13 14.001V13.001H11V14.001H5.00002V13.001H3.00002ZM4.00002 12.001C4.5523 12.001 5.00002 11.3294 5.00002 10.501C5.00002 9.67255 4.5523 9.00098 4.00002 9.00098C3.44773 9.00098 3.00002 9.67255 3.00002 10.501C3.00002 11.3294 3.44773 12.001 4.00002 12.001ZM9.50002 10.501C9.50002 11.8817 8.82845 13.001 8.00002 13.001C7.17159 13.001 6.50002 11.8817 6.50002 10.501C6.50002 9.12027 7.17159 8.00098 8.00002 8.00098C8.82845 8.00098 9.50002 9.12027 9.50002 10.501ZM12 12.001C12.5523 12.001 13 11.3294 13 10.501C13 9.67255 12.5523 9.00098 12 9.00098C11.4477 9.00098 11 9.67255 11 10.501C11 11.3294 11.4477 12.001 12 12.001Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_18889_63322">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.49952 10.4663C3.47193 9.6138 2.66403 8.61284 2.21523 8C2.66402 7.38716 3.47193 6.3862 4.49952 5.53367C5.58351 4.63435 6.79128 4 8.00001 4C9.20874 4 10.4165 4.63435 11.5005 5.53367C12.5281 6.3862 13.336 7.38716 13.7848 8C13.336 8.61284 12.5281 9.6138 11.5005 10.4663C10.4165 11.3656 9.20874 12 8.00001 12C6.79128 12 5.58351 11.3656 4.49952 10.4663ZM8.00001 2C6.1116 2 4.45712 2.97015 3.22251 3.99443C1.97234 5.03163 1.02832 6.22746 0.542514 6.8996C0.0652547 7.55992 0.0652569 8.44008 0.542514 9.1004C1.02832 9.77254 1.97234 10.9684 3.22251 12.0056C4.45713 13.0298 6.1116 14 8.00001 14C9.88842 14 11.5429 13.0298 12.7775 12.0056C14.0277 10.9684 14.9717 9.77254 15.4575 9.1004C15.9348 8.44008 15.9348 7.55992 15.4575 6.8996C14.9717 6.22746 14.0277 5.03163 12.7775 3.99443C11.5429 2.97015 9.88842 2 8.00001 2ZM8.00001 6C6.89544 6 6.00001 6.89543 6.00001 8C6.00001 9.10457 6.89544 10 8.00001 10C9.10458 10 10 9.10457 10 8C10 6.89543 9.10458 6 8.00001 6Z" fill="#333333"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
export { default as AccessNoneIcon } from "./access none.svg";
export { default as CheckRoundIcon } from "./check round.svg";
export { default as CommentIcon } from "./comment.svg";
export { default as CrownIcon } from "./crown.svg";
export { default as EyeIcon } from "./eye.svg";
export { default as PencilIcon } from "./pencil.svg";
export { default as ReviewIcon } from "./review.svg";

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_18889_63354)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.2929 1.29312C11.5119 0.074169 13.4882 0.0741679 14.7071 1.29312C15.9261 2.51207 15.9261 4.48838 14.7071 5.70733L5.70713 14.7073C5.57897 14.8355 5.41839 14.9264 5.24256 14.9704L1.24256 15.9704C0.901782 16.0556 0.541295 15.9557 0.292914 15.7073C0.0445341 15.459 -0.055315 15.0985 0.0298787 14.7577L1.02988 10.7577C1.07384 10.5819 1.16476 10.4213 1.29291 10.2931L10.2929 1.29312ZM13.2929 2.70733C12.855 2.26943 12.145 2.26943 11.7071 2.70733L10.9142 3.50023L12.5 5.08601L13.2929 4.29312C13.7308 3.85522 13.7308 3.14524 13.2929 2.70733ZM11.0858 6.50023L9.50002 4.91444L2.90299 11.5115L2.37439 13.6259L4.48877 13.0973L11.0858 6.50023Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_18889_63354">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 954 B

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_18889_63361)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2.99976L8.75736 2.99976L10.7574 0.999756H2C0.89543 0.999756 0 1.89519 0 2.99976V13.5855C0 15.3673 2.15428 16.2597 3.41421 14.9998L5.41421 12.9998H14C15.1046 12.9998 16 12.1043 16 10.9998V4.2424L14 6.2424V10.9998H5.41421C4.88378 10.9998 4.37507 11.2105 4 11.5855L2 13.5855V2.99976ZM14.7071 2.70686L8.20711 9.20686C7.81658 9.59739 7.18342 9.59739 6.79289 9.20686L3.79289 6.20686L5.2071 4.79264L7.5 7.08554L13.2929 1.29265L14.7071 2.70686Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_18889_63361">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 760 B