Merge branch 'master' of github.com:ONLYOFFICE/CommunityServer-AspNetCore

This commit is contained in:
Alexey Safronov 2019-07-17 16:55:20 +03:00
commit 254b2104ef
16 changed files with 44783 additions and 60252 deletions

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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,

View File

@ -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>
);
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 |

View File

@ -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')}

File diff suppressed because it is too large Load Diff