This commit is contained in:
NikolayRechkin 2019-07-18 16:55:16 +03:00
commit cb42059bad
19 changed files with 357 additions and 126 deletions

View File

@ -2,16 +2,24 @@ PUSHD %~dp0
call start\stop.bat
PUSHD %~dp0..
del /s /q web\npm-local
echo "ASC.Web.Components"
call yarn install --cwd web/ASC.Web.Components --frozen-lockfile > build\ASC.Web.Components.log
xcopy web\ASC.Web.Components\node_modules web\npm-local\asc-web-components\node_modules\ /E /R /Y >> build\ASC.Web.Components.log
call yarn link --cwd web/npm-local/asc-web-components
echo "ASC.Web.Storybook"
call yarn link "asc-web-components" --cwd web/ASC.Web.Storybook
call yarn install --cwd web/ASC.Web.Storybook --frozen-lockfile > build\ASC.Web.Storybook.log
echo "ASC.Web.Client"
call yarn link "asc-web-components" --cwd web/ASC.Web.Client
call yarn install --cwd web/ASC.Web.Client --frozen-lockfile > build\ASC.Web.Client.log
echo "ASC.Web.People.Client"
call yarn link "asc-web-components" --cwd products/ASC.People/Client
call yarn install --cwd products/ASC.People/Client --frozen-lockfile > build\ASC.Web.People.Client.log
xcopy build\cra\*.* products\ASC.People\Client\node_modules\ /E /R /Y

View File

@ -7,14 +7,19 @@ del /s /q web\npm-local
echo "ASC.Web.Components"
call yarn install --cwd web/ASC.Web.Components > build\ASC.Web.Components.log
xcopy web\ASC.Web.Components\node_modules web\npm-local\asc-web-components\node_modules\ /E /R /Y >> build\ASC.Web.Components.log
call yarn link --cwd web/npm-local/asc-web-components
echo "ASC.Web.Storybook"
call yarn link "asc-web-components" --cwd web/ASC.Web.Storybook
call yarn install --cwd web/ASC.Web.Storybook > build\ASC.Web.Storybook.log
echo "ASC.Web.Client"
call yarn link "asc-web-components" --cwd web/ASC.Web.Client
call yarn install --cwd web/ASC.Web.Client > build\ASC.Web.Client.log
echo "ASC.Web.People.Client"
call yarn link "asc-web-components" --cwd products/ASC.People/Client
call yarn install --cwd products/ASC.People/Client > build\ASC.Web.People.Client.log
xcopy build\cra\*.* products\ASC.People\Client\node_modules\ /E /R /Y

View File

@ -2,15 +2,14 @@ import React from 'react';
import { Container, Row, Col } from "reactstrap";
import {ContentRow, Link} from 'asc-web-components';
const peopleContent = (
const UserContent = ({
userName,
department,
phone,
email,
headDepartment,
status
) => {
return (
}) => (
<Container fluid={true}>
<Row className="justify-content-start no-gutters">
<Col className="col-12 col-sm-12 col-lg-4 text-truncate">
@ -95,7 +94,6 @@ const peopleContent = (
</Row>
</Container>
);
};
const SectionBodyContent = ({ users, onSelect/*, isHeaderChecked*/ }) => {
//const [isChecked, toggleChecked] = useState(false);
@ -118,14 +116,14 @@ const SectionBodyContent = ({ users, onSelect/*, isHeaderChecked*/ }) => {
avatarName={user.userName}
contextOptions={user.contextOptions}
>
{peopleContent(
user.userName,
user.departments[0],
user.phones[0],
user.emails[0],
user.isHead,
user.status
)}
<UserContent
userName={user.userName}
department={user.departments[0]}
phone={user.phones[0]}
email={user.emails[0]}
headDepartment={user.isHead}
status={user.status}
/>
</ContentRow>
))}
</>

View File

@ -0,0 +1,12 @@
{
"folders": [
{
"path": "."
},
{
"name": "ASC.People.Client"
"path": "D:\\GitHub\\portals_core\\products\\ASC.People\\Client"
}
],
"settings": {}
}

View File

@ -35,7 +35,7 @@
"react-custom-scrollbars": "^4.2.1",
"react-datepicker": "^2.7.0",
"react-lifecycles-compat": "^3.0.4",
"react-toastify": "^5.3.1",
"react-toastify": "^5.3.2",
"reactstrap": "^8.0.0",
"styled-components": "^4.3.2"
},

View File

@ -36,16 +36,19 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
}))`
height: ${props =>
(props.size === 'big' && '36px') ||
(props.size === 'medium' && '32px') ||
(props.size === 'base' && '24px')
};
line-height: ${props =>
(props.size === 'big' && '19px') ||
(props.size === 'medium' && '18px') ||
(props.size === 'base' && '16px')
};
font-size: ${props =>
(props.size === 'big' && '14px') ||
(props.size === 'medium' && '13px') ||
(props.size === 'base' && '12px')
};
@ -68,6 +71,16 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
: (props.label ? '8px 27px 9px 28px' : '8px 10px 9px 10px')
))
) ||
(props.size === 'medium' && (props.primary
? (props.icon
? (props.label ? '7px 24px 7px 24px' : '7px 10px 7px 10px')
: (props.label ? '7px 24px 7px 24px' : '7px 10px 7px 10px')
)
: (props.icon
? (props.label ? '7px 24px 7px 24px' : '7px 10px 7px 10px')
: (props.label ? '7px 24px 7px 24px' : '7px 10px 7px 10px')
))
) ||
(props.size === 'base' && (props.primary
? (props.icon
? (props.label ? '3px 20px 5px 20px' : '3px 5px 5px 5px')
@ -180,7 +193,7 @@ const Button = props => {
Button.propTypes = {
label: PropTypes.string,
primary: PropTypes.bool,
size: PropTypes.oneOf(['base', 'big']),
size: PropTypes.oneOf(['base', 'medium', 'big']),
icon: PropTypes.node,
tabIndex: PropTypes.number,

View File

@ -1,146 +1,187 @@
import React, { useState, useEffect, useRef } from 'react'
import styled, { css } from 'styled-components'
import PropTypes from 'prop-types'
import { Icons } from '../icons'
import DropDown from '../drop-down'
import Checkbox from '../checkbox'
import React from "react";
import styled, { css } from "styled-components";
import PropTypes from "prop-types";
import { Icons } from "../icons";
import DropDown from "../drop-down";
import DropDownItem from "../drop-down-item";
const textColor = '#333333',
disabledTextColor = '#A3A9AE';
const textColor = "#333333",
disabledTextColor = "#A3A9AE";
const activatedCss = css`
cursor: pointer;
cursor: pointer;
`;
const hoveredCss = css`
cursor: pointer;
cursor: pointer;
`;
const StyledGroupButton = styled.div`
position: relative;
display: inline-flex;
vertical-align: middle;
position: relative;
display: inline-flex;
vertical-align: middle;
`;
const StyledDropdownToggle = styled.div`
font-family: Open Sans;
font-style: normal;
font-weight: ${props => props.fontWeight};
font-size: 14px;
line-height: 19px;
font-family: Open Sans;
font-style: normal;
font-weight: ${props => props.fontWeight};
font-size: 14px;
line-height: 19px;
cursor: default;
cursor: default;
color: ${props => (props.disabled ? disabledTextColor : textColor)};
float: left;
height: 19px;
margin: 18px 12px 19px 12px;
overflow: hidden;
padding: 0px;
color: ${props => (props.disabled ? disabledTextColor : textColor)};
text-align: center;
text-decoration: none;
white-space: nowrap;
float: left;
height: 19px;
margin: 18px 12px 19px 12px;
overflow: hidden;
padding: 0px;
user-select: none;
-o-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
text-align: center;
text-decoration: none;
white-space: nowrap;
${props => !props.disabled && (props.activated ? `${activatedCss}` : css`
&:active {
user-select: none;
-o-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
${props =>
!props.disabled &&
(props.activated
? `${activatedCss}`
: css`
&:active {
${activatedCss}
}`)
}
}
`)}
${props => !props.disabled && (props.hovered ? `${hoveredCss}` : css`
&:hover {
${props =>
!props.disabled &&
(props.hovered
? `${hoveredCss}`
: css`
&:hover {
${hoveredCss}
}`)
}
}
`)}
`;
const Caret = styled(Icons.ExpanderDownIcon)`
width: 10px;
margin-left: 4px;
width: 10px;
margin-left: 4px;
`;
const Separator = styled.div`
vertical-align: middle;
border: 0.5px solid #ECEEF1;
width: 1px;
height: 24px;
margin-top: 16px;
vertical-align: middle;
border: 0.5px solid #eceef1;
width: 1px;
height: 24px;
margin-top: 16px;
`;
const useOuterClickNotifier = (onOuterClick, ref) => {
useEffect(() => {
const handleClick = (e) => !ref.current.contains(e.target) && onOuterClick(e);
class GroupButton extends React.Component {
constructor(props) {
super(props);
if (ref.current) {
document.addEventListener("click", handleClick);
}
this.ref = React.createRef();
return () => document.removeEventListener("click", handleClick);
},
[onOuterClick, ref]
);
}
this.state = {
isOpen: props.opened
};
}
const GroupButton = (props) => {
const { label, isDropdown, opened, disabled, isSeparator} = props;
const [isOpen, toggle] = useState(opened);
onOuterClick = e => this.toggle(false);
handleClick = e =>
!this.ref.current.contains(e.target) && this.onOuterClick(e);
stopAction = e => e.preventDefault();
toggle = isOpen => this.setState({ isOpen: isOpen });
let ref = useRef(null);
componentDidMount() {
if (this.ref.current) {
document.addEventListener("click", this.handleClick);
}
}
useOuterClickNotifier(() => toggle(false), ref);
componentWillUnmount() {
document.removeEventListener("click", this.handleClick);
}
const dropMenu = <DropDown isOpen={isOpen} {...props}/>;
componentDidUpdate(prevProps) {
// Store prevId in state so we can compare when props change.
// Clear out previously-loaded data (so we don't render stale stuff).
if (this.props.opened !== prevProps.opened) {
this.toggle(this.props.opened);
}
}
const dropDownButton =
<StyledDropdownToggle {...props} onClick={() => { disabled ? false : toggle(!isOpen) }}>
{label}
<Caret size='small' color={disabled ? disabledTextColor : textColor} />
</StyledDropdownToggle>;
render() {
const { label, isDropdown, disabled, isSeparator } = this.props;
return (
<StyledGroupButton ref={ref}>
{isDropdown
? {...dropDownButton}
: <StyledDropdownToggle {...props} >
{label}
</StyledDropdownToggle>
<StyledGroupButton ref={this.ref}>
{isDropdown ? (
<>
<StyledDropdownToggle
{...this.props}
onClick={() => {
disabled ? false : this.toggle(!this.state.isOpen);
}}
>
{label}
<Caret
size="small"
color={disabled ? disabledTextColor : textColor}
/>
</StyledDropdownToggle>
<DropDown isOpen={this.state.isOpen}>
{
React.Children.map(this.props.children, (child) =>
<DropDownItem
{...child.props}
onClick={() => {
child.props.onClick && child.props.onClick();
this.toggle(!this.state.isOpen);
}}
/>
)
}
{isSeparator && <Separator/>}
{isDropdown && {...dropMenu}}
</StyledGroupButton>
</DropDown>
</>
) : (
<StyledDropdownToggle {...this.props}>{label}</StyledDropdownToggle>
)}
{isSeparator && <Separator />}
</StyledGroupButton>
);
}
}
GroupButton.propTypes = {
label: PropTypes.string,
disabled: PropTypes.bool,
activated: PropTypes.bool,
opened: PropTypes.bool,
hovered: PropTypes.bool,
isDropdown: PropTypes.bool,
isSeparator: PropTypes.bool,
tabIndex: PropTypes.number,
onClick: PropTypes.func,
fontWeight: PropTypes.string
label: PropTypes.string,
disabled: PropTypes.bool,
activated: PropTypes.bool,
opened: PropTypes.bool,
hovered: PropTypes.bool,
isDropdown: PropTypes.bool,
isSeparator: PropTypes.bool,
tabIndex: PropTypes.number,
onClick: PropTypes.func,
fontWeight: PropTypes.string
};
GroupButton.defaultProps = {
label: 'Group button',
disabled: false,
activated: false,
opened: false,
hovered: false,
isDropdown: false,
isSeparator: false,
tabIndex: -1,
fontWeight: '600'
label: "Group button",
disabled: false,
activated: false,
opened: false,
hovered: false,
isDropdown: false,
isSeparator: false,
tabIndex: -1,
fontWeight: "600"
};
export default GroupButton
export default GroupButton;

View File

@ -62,7 +62,7 @@ class GroupButtonsMenu extends React.Component {
constructor(props) {
super(props);
this.updateMenu = this.updateMenu.bind(this);
this.updateMenu = this.updateMenu.bind(this);
this.state = {
priorityItems: props.menuItems,
moreItems: [],
@ -76,7 +76,7 @@ class GroupButtonsMenu extends React.Component {
}
componentDidMount() {
this.widthsArray = Array.from(this.refs.groupMenu.children).map(item => item.getBoundingClientRect().width);
this.widthsArray = Array.from(document.getElementById("groupMenu").children).map(item => item.getBoundingClientRect().width);
window.addEventListener('resize', _.throttle(this.updateMenu), 100);
this.updateMenu();
@ -126,7 +126,7 @@ class GroupButtonsMenu extends React.Component {
}} />
</StyledCheckbox>
}
<div ref="groupMenu" style={{display: 'inline-block'}}>
<div id="groupMenu" style={{display: 'inline-block'}}>
{priorityItems.map((item, i) =>
<GroupButton key={`navItem-${i}`}
label={item.label}

View File

@ -0,0 +1,66 @@
import React from 'react'
import styled, { css } from 'styled-components'
import PropTypes from 'prop-types'
import Button from '../button'
import ComboBox from '../combobox'
import device from '../device'
const StyledPaging = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-start;
& > button, div:not(:last-of-type) {
margin-right: 8px;
}
`;
const StyledOnPage = styled.div`
width: 120px;
margin-left: auto;
@media ${device.mobile} {
display: none;
}
`;
const StyledPage = styled.div`
width: 80px;
`;
const Paging = props => {
const {previousLabel, nextLabel, previousAction, nextAction, pageItems, perPageItems} = props;
return (
<StyledPaging>
{pageItems &&
<>
<Button size='medium' label={previousLabel} onClick={previousAction}/>
<StyledPage>
<ComboBox items={pageItems} />
</StyledPage>
<Button size='medium' label={nextLabel} onClick={nextAction}/>
</>
}
<StyledOnPage>
<ComboBox items={perPageItems} />
</StyledOnPage>
</StyledPaging>
);
};
Paging.propTypes = {
previousAction: PropTypes.func,
nextAction: PropTypes.func,
previousLabel: PropTypes.string,
nextLabel: PropTypes.string
}
Paging.defaultProps = {
previousAction: () => console.log('Prev action'),
nextAction: () => console.log('Next action')
}
export default Paging;

View File

@ -1,6 +1,5 @@
import React from 'react'
import { ToastContainer, cssTransition } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
import styled from 'styled-components'
import PropTypes from 'prop-types'

View File

@ -30,4 +30,5 @@ export { default as Backdrop } from './components/backdrop'
export { default as Scrollbar } from './components/scrollbar'
export { default as Toast } from './components/toast'
export { default as toastr } from './components/toast/toastr'
export { default as ComboBox } from './components/combobox'
export { default as ComboBox } from './components/combobox'
export { default as Paging } from './components/paging'

View File

@ -6743,7 +6743,7 @@ react-testing-library@7.0.0:
"@babel/runtime" "^7.4.3"
dom-testing-library "^4.0.0"
react-toastify@^5.3.1:
react-toastify@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-5.3.2.tgz#9de4b426656587722f7e2f99f5f90e974ba5fee6"
integrity sha512-YHTTey7JWqXVkkBIeJ34PAvQELmGfLEGCx9bu68aIZYd+kRU2u9k/nG3AydgbX/uevIb4QNpeeE98DjkooMs5w==

View File

@ -3,6 +3,7 @@ import { addParameters, configure } from '@storybook/react';
import { addDecorator } from '@storybook/react';
import { withConsole } from '@storybook/addon-console';
import 'bootstrap/dist/css/bootstrap.css';
import 'react-toastify/dist/ReactToastify.css';
// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /\.stories\.js$/);

View File

@ -12,7 +12,7 @@ function onClick(e) {
const getButtons = (primary) => {
const sizes = ['big', 'base'];
const sizes = ['big', 'medium', 'base'];
const states = ['isActivated', 'isHovered', 'isClicked', 'isDisabled'];
const baseButton = {

View File

@ -12,7 +12,7 @@ storiesOf('Components|Buttons', module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add('base', () => {
const sizeOptions = ['base', 'big'];
const sizeOptions = ['base', 'medium', 'big'];
const iconNames = orderBy(Object.keys(Icons), [name => name.toLowerCase()], ['asc']);
const iconName = select("icon", ['', ...iconNames], '');

View File

@ -25,10 +25,10 @@ storiesOf('Components|GroupButton', module)
<Col><GroupButton disabled /></Col>
</Row>
<Row style={rowStyle}>
<Col><GroupButton isDropdown ><DropDownItem /></GroupButton></Col>
<Col><GroupButton isDropdown hovered ><DropDownItem /></GroupButton></Col>
<Col><GroupButton isDropdown activated ><DropDownItem /></GroupButton></Col>
<Col><GroupButton isDropdown disabled ><DropDownItem /></GroupButton></Col>
<Col><GroupButton isDropdown ><DropDownItem label="Action 1" /></GroupButton></Col>
<Col><GroupButton isDropdown hovered ><DropDownItem label="Action 2" /></GroupButton></Col>
<Col><GroupButton isDropdown activated ><DropDownItem label="Action 3" /></GroupButton></Col>
<Col><GroupButton isDropdown disabled ><DropDownItem label="Action 4" /></GroupButton></Col>
</Row>
</Container>
));

View File

@ -15,6 +15,8 @@ storiesOf('Components|GroupButton', module)
isDropdown = {boolean('isDropdown', false)}
opened = {boolean('opened', false)}
>
<DropDownItem/>
<DropDownItem label="Action 1" />
<DropDownItem label="Action 2" />
<DropDownItem label="Action 3" />
</GroupButton>
));

View File

@ -0,0 +1,24 @@
# Paging
#### Description
Paging is used to navigate med content pages.
#### Usage
```js
import { Paging } from 'asc-web-components';
<ComboBox previousLabel='Previous' nextLabel='Next' pageItems={pageItems} perPageItems={perPageItems}/>
```
#### Properties
| Props | Type | Required | Values | Default | Description |
| ---------------------- | ----------------- | :------: | ---------------------------- | ------- | -------------------------------------------- |
| `pageItems` | `object` | - | - | - | Paging combo box items |
| `perPageItems` | `object` | ✅ | - | - | Items per page combo box items |
| `previousLabel` | `string` | - | - | `Previous`| Label for previous button |
| `nextLabel` | `string` | - | - | `Next` | Label for next button |
| `previousAction` | `function` | - | - | - | Action for previous button |
| `nextAction` | `function` | - | - | - | Action for next button |

View File

@ -0,0 +1,61 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import withReadme from 'storybook-readme/with-readme';
import Readme from './README.md';
import { Paging } from 'asc-web-components';
import Section from '../../../.storybook/decorators/section';
storiesOf('Components|Paging', module)
.addDecorator(withReadme(Readme))
.add('base', () => {
const pageItems = [
{
label: '1 of 5',
onClick: () => console.log('set paging 1 of 5')
},
{
label: '2 of 5',
onClick: () => console.log('set paging 2 of 5')
},
{
label: '3 of 5',
onClick: () => console.log('set paging 3 of 5')
},
{
label: '4 of 5',
onClick: () => console.log('set paging 4 of 5')
},
{
label: '5 of 5',
onClick: () => console.log('set paging 5 of 5')
}
];
const perPageItems = [
{
label: '25 per page',
onClick: () => console.log('set paging 25 action')
},
{
label: '50 per page',
onClick: () => console.log('set paging 50 action')
},
{
label: '100 per page',
onClick: () => console.log('set paging 100 action')
}
];
return (
<Section>
<Paging previousLabel='Previous'
nextLabel='Next'
pageItems={pageItems}
perPageItems={perPageItems}
previousAction={ () => console.log('Prev')}
nextAction={ () => console.log('Next')}
/>
</Section>
)
});