Merge branch 'master' of github.com:ONLYOFFICE/CommunityServer-AspNetCore
This commit is contained in:
commit
254b2104ef
@ -3,16 +3,16 @@ call start\stop.bat
|
||||
|
||||
PUSHD %~dp0..
|
||||
echo "ASC.Web.Components"
|
||||
call npm ci --prefix web/ASC.Web.Components
|
||||
call yarn install --cwd web/ASC.Web.Components --frozen-lockfile > build\ASC.Web.Components.log
|
||||
|
||||
echo "ASC.Web.Storybook"
|
||||
call npm ci --prefix web/ASC.Web.Storybook
|
||||
call yarn install --cwd web/ASC.Web.Storybook --frozen-lockfile > build\ASC.Web.Storybook.log
|
||||
|
||||
echo "ASC.Web.Client"
|
||||
call npm ci --prefix 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 npm ci --prefix 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
|
||||
|
||||
|
@ -2,36 +2,26 @@ PUSHD %~dp0
|
||||
call start\stop.bat
|
||||
|
||||
PUSHD %~dp0..
|
||||
echo "REMOVE npm-local"
|
||||
|
||||
del /s /q web\npm-local
|
||||
|
||||
PUSHD %~dp0..
|
||||
echo "ASC.Web.Components"
|
||||
cd web/ASC.Web.Components
|
||||
call npm i
|
||||
call yarn install --cwd web/ASC.Web.Components > build\ASC.Web.Components.log
|
||||
|
||||
PUSHD %~dp0..
|
||||
echo "ASC.Web.Storybook"
|
||||
cd web\ASC.Web.Storybook
|
||||
call npm i
|
||||
call yarn install --cwd web/ASC.Web.Storybook > build\ASC.Web.Storybook.log
|
||||
|
||||
PUSHD %~dp0..
|
||||
echo "ASC.Web.Client"
|
||||
cd web\ASC.Web.Client
|
||||
call npm i
|
||||
call yarn install --cwd web/ASC.Web.Client > build\ASC.Web.Client.log
|
||||
|
||||
PUSHD %~dp0..
|
||||
echo "ASC.Web.People.Client"
|
||||
cd products/ASC.People/Client
|
||||
call npm i
|
||||
call yarn install --cwd products/ASC.People/Client > build\ASC.Web.People.Client.log
|
||||
|
||||
PUSHD %~dp0..
|
||||
xcopy build\cra\*.* products\ASC.People\Client\node_modules\ /E /R /Y
|
||||
|
||||
echo "ASC.Web.sln"
|
||||
call dotnet build ASC.Web.sln /fl1 /flp1:LogFile=build/ASC.Web.log;Verbosity=Normal
|
||||
|
||||
PUSHD %~dp0
|
||||
start /b call start\start.bat
|
||||
start /b call build\start\start.bat
|
||||
|
||||
pause
|
14991
products/ASC.People/Client/package-lock.json
generated
14991
products/ASC.People/Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv": "^6.10.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-eslint": "10.0.1",
|
||||
"cross-env": "^5.2.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-react-app": "^4.0.1",
|
||||
|
11232
products/ASC.People/Client/yarn.lock
Normal file
11232
products/ASC.People/Client/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
14954
web/ASC.Web.Client/package-lock.json
generated
14954
web/ASC.Web.Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv": "^6.10.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-eslint": "10.0.1",
|
||||
"cross-env": "^5.2.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-react-app": "^4.0.1",
|
||||
|
11232
web/ASC.Web.Client/yarn.lock
Normal file
11232
web/ASC.Web.Client/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
11417
web/ASC.Web.Components/package-lock.json
generated
11417
web/ASC.Web.Components/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -50,24 +50,28 @@ const StyledInputGroup = styled(CustomInputGroup)`
|
||||
const InputBlock = React.forwardRef((props, ref) => {
|
||||
const {onChange, value, children, size } = props;
|
||||
let iconButtonSize = 0;
|
||||
|
||||
switch (size) {
|
||||
case 'base':
|
||||
iconButtonSize = 15;
|
||||
break;
|
||||
case 'middle':
|
||||
iconButtonSize = 18;
|
||||
break;
|
||||
case 'big':
|
||||
iconButtonSize = 21;
|
||||
break;
|
||||
case 'huge':
|
||||
iconButtonSize = 24;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if(typeof props.iconSize == "number" && props.iconSize > 0){
|
||||
iconButtonSize = props.iconSize;
|
||||
}else{
|
||||
switch (size) {
|
||||
case 'base':
|
||||
iconButtonSize = 15;
|
||||
break;
|
||||
case 'middle':
|
||||
iconButtonSize = 18;
|
||||
break;
|
||||
case 'big':
|
||||
iconButtonSize = 21;
|
||||
break;
|
||||
case 'huge':
|
||||
iconButtonSize = 24;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<StyledInputGroup hasError={props.hasError} hasWarning={props.hasWarning} isDisabled={props.isDisabled} scale={props.scale} size={props.size}>
|
||||
@ -135,6 +139,7 @@ InputBlock.propTypes = {
|
||||
value: PropTypes.string,
|
||||
iconName: PropTypes.string,
|
||||
iconColor: PropTypes.string,
|
||||
iconSize: PropTypes.number,
|
||||
isIconFill: PropTypes.bool,
|
||||
isDisabled: PropTypes.bool,
|
||||
onIconClick: PropTypes.func,
|
||||
|
@ -3,27 +3,83 @@ import PropTypes from "prop-types";
|
||||
import styled from 'styled-components';
|
||||
import InputBlock from '../input-block';
|
||||
import IconButton from '../icon-button';
|
||||
import { Icons } from '../icons';
|
||||
import ContextMenuButton from '../context-menu-button';
|
||||
import {UncontrolledPopover, PopoverBody } from 'reactstrap';
|
||||
|
||||
const StyledSearchInput = styled.div`
|
||||
min-width: 200px;
|
||||
`;
|
||||
const Caret = styled.div`
|
||||
width: 7px;
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
transform: ${props => props.isOpen ? 'rotate(180deg)' : 'rotate(0)'};
|
||||
top: ${props => props.isOpen ? '2px' : '0'};
|
||||
`;
|
||||
const StyledFilterItem = styled.div`
|
||||
display: flex;
|
||||
display: ${props => props.block ? 'block' : 'inline-block'};
|
||||
margin-bottom: ${props => props.block ? '3px' : '0'};
|
||||
position relative;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 3px;
|
||||
padding-right: 18px;
|
||||
margin-right: 2px;
|
||||
border: 1px solid #d4e4ec;
|
||||
border: 1px solid #ECEEF1;
|
||||
border-radius: 3px;
|
||||
background-color: #edf6fd;
|
||||
background-color: #F8F9F9;
|
||||
&:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`;
|
||||
const StyledHideFilterButton = styled.div`
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
height: 100%;
|
||||
border: 1px solid #ECEEF1;
|
||||
border-radius: 3px;
|
||||
background-color: #F8F9F9;
|
||||
padding: 0 20px 0 9px;
|
||||
margin-right: 2px;
|
||||
cursor: pointer;
|
||||
font-family: Open Sans;
|
||||
font-style: normal;
|
||||
|
||||
:hover{
|
||||
border-color: #A3A9AE;
|
||||
}
|
||||
:active{
|
||||
background-color: #ECEEF1;
|
||||
}
|
||||
`;
|
||||
const StyledIconButtonBlock = styled.div`
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
position absolute;
|
||||
right: 0;
|
||||
right: 3px;
|
||||
top: calc(50% - 5px);
|
||||
`;
|
||||
const StyledHideFilter = styled.div`
|
||||
display: inline-block;
|
||||
font-size: 1rem;
|
||||
height: 100%;
|
||||
`;
|
||||
const StyledPopoverBody = styled(PopoverBody)`
|
||||
font-size: 1rem;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0px 2px 18px rgba(0, 0, 0, 0.13);
|
||||
`;
|
||||
|
||||
const FilterItem = props => {
|
||||
const { groupLabel, id, label } = props;
|
||||
const { groupLabel, id, label, block } = props;
|
||||
return (
|
||||
<StyledFilterItem key={id}>
|
||||
{groupLabel} {label}
|
||||
<StyledFilterItem key={id} id={id} block={block} >
|
||||
{groupLabel}: {label}
|
||||
<StyledIconButtonBlock>
|
||||
<IconButton
|
||||
color={props.color}
|
||||
@ -37,21 +93,59 @@ const FilterItem = props => {
|
||||
</StyledFilterItem>
|
||||
);
|
||||
};
|
||||
class HideFilter extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.state = {
|
||||
popoverOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<StyledHideFilter>
|
||||
<StyledHideFilterButton id="PopoverLegacy" >{this.props.count} <Caret isOpen={this.state.popoverOpen}><Icons.ExpanderDownIcon size='scale' isfill={true} color="#A3A9AE"/></Caret></StyledHideFilterButton>
|
||||
|
||||
<UncontrolledPopover isOpen={this.state.popoverOpen} trigger="legacy" placement="bottom-start" target="PopoverLegacy" hideArrow={true} toggle={this.toggle}>
|
||||
<StyledPopoverBody>{this.props.children}</StyledPopoverBody>
|
||||
</UncontrolledPopover>
|
||||
</StyledHideFilter>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SearchInput extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.minWidth = 190;
|
||||
this.isUpdateFilter = true;
|
||||
this.state = {
|
||||
filterItems: []
|
||||
filterItems: [],
|
||||
openFilterItems: [],
|
||||
hideFilterItems: []
|
||||
};
|
||||
|
||||
this.searchWrapper = React.createRef();
|
||||
this.filterWrapper = React.createRef();
|
||||
|
||||
this.onClickDropDownItem = this.onClickDropDownItem.bind(this);
|
||||
this.getData = this.getData.bind(this);
|
||||
this.onSearchClick = this.onSearchClick.bind(this);
|
||||
this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this);
|
||||
this.getFilterItems = this.getFilterItems.bind(this);
|
||||
|
||||
this.updateFilter = this.updateFilter.bind(this);
|
||||
this.resize = this.resize.bind(this);
|
||||
|
||||
}
|
||||
|
||||
onClickDropDownItem(event, filterItem){
|
||||
@ -77,11 +171,12 @@ class SearchInput extends React.Component {
|
||||
inputValue: this.props.value,
|
||||
filterValue: this.props.isNeedFilter ? curentFilterItems : null
|
||||
});
|
||||
this.isUpdateFilter = false;
|
||||
}
|
||||
|
||||
getData(){
|
||||
let _this = this;
|
||||
let d= this.props.getFilterData();
|
||||
let d = this.props.getFilterData();
|
||||
d.map(function(item){
|
||||
item.onClick = !item.isSeparator && !item.isHeader && !item.disabled ? ((e) => _this.onClickDropDownItem(e, item)) : undefined;
|
||||
return item;
|
||||
@ -112,26 +207,110 @@ class SearchInput extends React.Component {
|
||||
inputValue: this.props.value,
|
||||
filterValue: this.props.isNeedFilter ? curentFilterItems : null
|
||||
});
|
||||
this.isUpdateFilter = false;
|
||||
}
|
||||
|
||||
getFilterItems(){
|
||||
let _this = this;
|
||||
|
||||
const result = this.state.filterItems.map(function(item) {
|
||||
|
||||
return <FilterItem
|
||||
isDisabled={_this.props.isDisabled}
|
||||
key={item.key}
|
||||
id={item.key}
|
||||
groupLabel={item.groupLabel}
|
||||
label={item.label}
|
||||
onClose={_this.onDeleteFilterItem}>
|
||||
|
||||
</FilterItem>
|
||||
})
|
||||
let result = [];
|
||||
let openItems = [];
|
||||
let hideItems = [];
|
||||
if(this.state.filterItems.length > 0 && !this.isUpdateFilter){
|
||||
openItems = this.state.filterItems.map(function(item) {
|
||||
return <FilterItem
|
||||
isDisabled={_this.props.isDisabled}
|
||||
key={item.key}
|
||||
id={item.value}
|
||||
groupLabel={item.groupLabel}
|
||||
label={item.label}
|
||||
onClose={_this.onDeleteFilterItem}>
|
||||
</FilterItem>
|
||||
});
|
||||
}
|
||||
if(this.state.hideFilterItems.length > 0 && this.isUpdateFilter){
|
||||
hideItems.push(
|
||||
<HideFilter key="hide-filter" count={this.state.hideFilterItems.length}>
|
||||
{
|
||||
this.state.hideFilterItems.map(function(item) {
|
||||
return <FilterItem
|
||||
block={true}
|
||||
isDisabled={_this.props.isDisabled}
|
||||
key={item.key}
|
||||
id={item.key}
|
||||
groupLabel={item.groupLabel}
|
||||
label={item.label}
|
||||
onClose={_this.onDeleteFilterItem}>
|
||||
</FilterItem>
|
||||
})
|
||||
}
|
||||
</HideFilter>
|
||||
);
|
||||
}
|
||||
if(this.state.openFilterItems.length > 0 && this.isUpdateFilter){
|
||||
openItems = this.state.openFilterItems.map(function(item) {
|
||||
return <FilterItem
|
||||
isDisabled={_this.props.isDisabled}
|
||||
key={item.key}
|
||||
id={item.key}
|
||||
groupLabel={item.groupLabel}
|
||||
label={item.label}
|
||||
onClose={_this.onDeleteFilterItem}>
|
||||
</FilterItem>
|
||||
});
|
||||
}
|
||||
|
||||
result = hideItems.concat(openItems);
|
||||
return result;
|
||||
}
|
||||
|
||||
updateFilter(){
|
||||
let fullWidth = this.searchWrapper.current.getBoundingClientRect().width;
|
||||
let filterWidth = this.filterWrapper.current.getBoundingClientRect().width;
|
||||
|
||||
if(fullWidth <= this.minWidth){
|
||||
this.setState({ openFilterItems: []});
|
||||
this.setState({ hideFilterItems: this.state.filterItems.slice()});
|
||||
}else if(filterWidth > fullWidth/2){
|
||||
let newOpenFilterItems = [];
|
||||
let newHideFilterItems = [];
|
||||
let openFilterWidth = 0;
|
||||
|
||||
let sortArr = Array.from(this.filterWrapper.current.children).sort(function(a,b) {
|
||||
return a.getBoundingClientRect().width - b.getBoundingClientRect().width;
|
||||
});
|
||||
|
||||
sortArr.forEach(element => {
|
||||
openFilterWidth = openFilterWidth + element.getBoundingClientRect().width;
|
||||
if(openFilterWidth < fullWidth/3){
|
||||
newOpenFilterItems.push(this.state.filterItems.find(x => x.value === element.getAttribute('id')));
|
||||
}else{
|
||||
newHideFilterItems.push(this.state.filterItems.find(x => x.value === element.getAttribute('id')));
|
||||
}
|
||||
});
|
||||
this.setState({ openFilterItems: newOpenFilterItems});
|
||||
this.setState({ hideFilterItems: newHideFilterItems});
|
||||
|
||||
}else{
|
||||
this.setState({ openFilterItems: this.state.filterItems.slice()});
|
||||
this.setState({ hideFilterItems: []});
|
||||
}
|
||||
this.isUpdateFilter = true;
|
||||
}
|
||||
resize(){
|
||||
this.isUpdateFilter = false;
|
||||
this.forceUpdate();
|
||||
}
|
||||
componentDidUpdate(){
|
||||
if(!this.isUpdateFilter) this.updateFilter();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', _.throttle(this.resize), 100);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.resize());
|
||||
}
|
||||
|
||||
render() {
|
||||
let _this = this;
|
||||
let iconSize = 32;
|
||||
@ -149,7 +328,8 @@ class SearchInput extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<InputBlock
|
||||
<StyledSearchInput ref={this.searchWrapper}>
|
||||
<InputBlock
|
||||
id={this.props.id}
|
||||
isDisabled={this.props.isDisabled}
|
||||
iconName={"SearchIcon"}
|
||||
@ -161,19 +341,24 @@ class SearchInput extends React.Component {
|
||||
value={this.props.value}
|
||||
placeholder={this.props.placeholder}
|
||||
onChange={this.props.onChange}
|
||||
>
|
||||
{ this.props.isNeedFilter && this.getFilterItems()}
|
||||
{
|
||||
this.props.isNeedFilter &&
|
||||
<ContextMenuButton
|
||||
title={'Actions'}
|
||||
iconName={'RectangleFilterIcon'}
|
||||
color='#A3A9AE'
|
||||
size={iconSize}
|
||||
getData={_this.getData}
|
||||
/>
|
||||
}
|
||||
</InputBlock>
|
||||
>
|
||||
{ this.props.isNeedFilter &&
|
||||
<div ref={this.filterWrapper}>
|
||||
{this.getFilterItems()}
|
||||
</div>
|
||||
}
|
||||
|
||||
{ this.props.isNeedFilter &&
|
||||
<ContextMenuButton
|
||||
title={'Actions'}
|
||||
iconName={'RectangleFilterIcon'}
|
||||
color='#A3A9AE'
|
||||
size={iconSize}
|
||||
getData={_this.getData}
|
||||
/>
|
||||
}
|
||||
</InputBlock>
|
||||
</StyledSearchInput>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
8505
web/ASC.Web.Components/yarn.lock
Normal file
8505
web/ASC.Web.Components/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
18815
web/ASC.Web.Storybook/package-lock.json
generated
18815
web/ASC.Web.Storybook/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -41,3 +41,4 @@ InputBlock description
|
||||
| `iconColor` | `string` | | | `black` | Specifies the icon color |
|
||||
| `isIconFill` | `bool` | | | `false` | Determines if icon fill is needed |
|
||||
| `onIconClick` | `func` | ✅ | - | - | Will be triggered whenever an icon is clicked |
|
||||
| `iconSize` | `number` | ✅ | - | - | Size icon |
|
||||
|
@ -70,6 +70,7 @@ storiesOf('Components|Input', module)
|
||||
scale={boolean('scale', false)}
|
||||
autoComplete={text('autoComplete', 'off')}
|
||||
tabIndex={number('tabIndex', 1)}
|
||||
iconSize={number('iconSize', 0)}
|
||||
|
||||
isDisabled={boolean('isDisabled', false)}
|
||||
iconName={select('iconName', iconNames, 'SearchIcon')}
|
||||
|
13557
web/ASC.Web.Storybook/yarn.lock
Normal file
13557
web/ASC.Web.Storybook/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user