Web: Files/Common: added ViewSelector component

This commit is contained in:
Alexey 2020-06-30 09:40:09 +03:00
parent 506642b02c
commit a3dd53878e
11 changed files with 174 additions and 17 deletions

View File

@ -79,6 +79,7 @@ class SectionFilterContent extends React.Component {
const sortBy = data.sortId;
const sortOrder =
data.sortDirection === "desc" ? "descending" : "ascending";
const viewAs = data.viewAs;
const authorType = getAuthorType(data.filterValues);
const withSubfolders = getSearchParams(data.filterValues);
@ -95,6 +96,7 @@ class SectionFilterContent extends React.Component {
newFilter.page = 0;
newFilter.sortBy = sortBy;
newFilter.sortOrder = sortOrder;
newFilter.viewAs = viewAs;
newFilter.filterType = filterType;
newFilter.search = search;
newFilter.authorType = authorType;
@ -222,7 +224,8 @@ class SectionFilterContent extends React.Component {
const selectedFilterData = {
filterValues: [],
sortDirection: filter.sortOrder === "ascending" ? "asc" : "desc",
sortId: filter.sortBy
sortId: filter.sortBy,
viewAs: filter.viewAs
};
selectedFilterData.inputValue = filter.search;

View File

@ -5,6 +5,7 @@ export const FILTER_TYPE = "filterType";
export const SEARCH = "search";
export const SORT_BY = "sortby";
export const SORT_ORDER = "sortorder";
export const VIEW_AS = "viewas";
export const PAGE = "page";
export const PAGE_COUNT = "pagecount";
export const FOLDER = "folder";

View File

@ -4,6 +4,7 @@ import {
SEARCH,
SORT_BY,
SORT_ORDER,
VIEW_AS,
PAGE,
PAGE_COUNT,
AUTHOR_TYPE,
@ -28,6 +29,7 @@ export function getFilterByLocation(location) {
defaultFilter.withSubfolders;
const search = urlFilter[SEARCH] || defaultFilter.search;
const sortBy = urlFilter[SORT_BY] || defaultFilter.sortBy;
const viewAs = urlFilter[VIEW_AS] || defaultFilter.viewAs;
const sortOrder = urlFilter[SORT_ORDER] || defaultFilter.sortOrder;
const page = (urlFilter[PAGE] && (+urlFilter[PAGE]-1)) || defaultFilter.page;
const pageCount =
@ -41,6 +43,7 @@ export function getFilterByLocation(location) {
defaultFilter.total,
sortBy,
sortOrder,
viewAs,
filterType,
withSubfolders,
search,

View File

@ -5,6 +5,7 @@ const DEFAULT_PAGE_COUNT = 25;
const DEFAULT_TOTAL = 0;
const DEFAULT_SORT_BY = "lastModifiedDate";
const DEFAULT_SORT_ORDER = "ascending";
const DEFAULT_VIEW = "row";
const DEFAULT_FILTER_TYPE = null;
const DEFAULT_SEARCH_TYPE = true; //withSubfolders
const DEFAULT_SEARCH = null;
@ -29,6 +30,7 @@ class FilesFilter {
total = DEFAULT_TOTAL,
sortBy = DEFAULT_SORT_BY,
sortOrder = DEFAULT_SORT_ORDER,
viewAs = DEFAULT_VIEW,
filterType = DEFAULT_FILTER_TYPE,
withSubfolders = DEFAULT_SEARCH_TYPE,
search = DEFAULT_SEARCH,
@ -41,6 +43,7 @@ class FilesFilter {
this.pageCount = pageCount;
this.sortBy = sortBy;
this.sortOrder = sortOrder;
this.viewAs = viewAs;
this.filterType = filterType;
this.withSubfolders = withSubfolders;
this.search = search;
@ -106,6 +109,7 @@ class FilesFilter {
this.total,
this.sortBy,
this.sortOrder,
this.viewAs,
this.filterType,
this.withSubfolders,
this.search,
@ -124,6 +128,7 @@ class FilesFilter {
this.search === filter.search &&
this.sortBy === filter.sortBy &&
this.sortOrder === filter.sortOrder &&
this.viewAs === filter.viewAs &&
this.page === filter.page &&
this.selectedItem.key === filter.selectedItem.key &&
this.folder === filter.folder &&

View File

@ -5,6 +5,7 @@ import isEqual from 'lodash/isEqual';
import throttle from 'lodash/throttle';
import FilterBlock from './sub-components/FilterBlock';
import SortComboBox from './sub-components/SortComboBox';
import ViewSelector from './sub-components/ViewSelector';
import map from 'lodash/map';
import clone from 'lodash/clone';
import StyledFilterInput from './StyledFilterInput';
@ -92,6 +93,7 @@ class FilterInput extends React.Component {
this.state = {
sortDirection: props.selectedFilterData.sortDirection === "desc" ? true : false,
viewAs: props.selectedFilterData.viewAs,
sortId: props.getSortData().findIndex(x => x.key === props.selectedFilterData.sortId) != -1 ? props.selectedFilterData.sortId : props.getSortData().length > 0 ? props.getSortData()[0].key : "",
searchText: props.selectedFilterData.inputValue || props.value,
@ -120,6 +122,8 @@ class FilterInput extends React.Component {
this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this);
this.clearFilter = this.clearFilter.bind(this);
this.onClickViewSelector = this.onClickViewSelector.bind(this);
this.throttledResize = throttle(this.resize, 300);
}
@ -230,9 +234,15 @@ class FilterInput extends React.Component {
})
}
onChangeSortDirection(key) {
this.onFilter(this.state.filterValues, this.state.sortId, key ? "desc" : "asc");
this.onFilter(this.state.filterValues, this.state.sortId, key ? "desc" : "asc", this.state.viewAs);
this.setState({ sortDirection: !!key });
}
onClickViewSelector(item) {
const itemId = item.target.dataset.for;
const viewAs = itemId.indexOf("row") === -1 ? "tile" : "row"
this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", viewAs);
this.setState({ viewAs: viewAs });
}
getDefaultSelectedIndex() {
const sortData = this.props.getSortData();
if (sortData.length > 0) {
@ -243,19 +253,19 @@ class FilterInput extends React.Component {
}
onClickSortItem(key) {
this.setState({ sortId: key });
this.onFilter(this.state.filterValues, key, this.state.sortDirection ? "desc" : "asc");
this.onFilter(this.state.filterValues, key, this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
}
onSortDirectionClick() {
this.onFilter(this.state.filterValues, this.state.sortId, !this.state.sortDirection ? "desc" : "asc");
this.onFilter(this.state.filterValues, this.state.sortId, !this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
this.setState({ sortDirection: !this.state.sortDirection });
}
onSearchChanged(value) {
this.setState({ searchText: value });
this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", value);
this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs, value);
}
onSearch(result) {
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc");
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
}
getFilterData() {
const _this = this;
@ -280,7 +290,7 @@ class FilterInput extends React.Component {
openFilterItems: [],
hideFilterItems: []
});
this.onFilter([], this.state.sortId, this.state.sortDirection ? "desc" : "asc", '');
this.onFilter([], this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs, '');
}
updateFilter(inputFilterItems) {
const currentFilterItems = inputFilterItems || cloneObjectsArray(this.state.filterValues);
@ -344,9 +354,9 @@ class FilterInput extends React.Component {
item.key = item.key.replace(item.group + "_", '');
return item;
})
this.onFilter(filterValues.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc");
this.onFilter(filterValues.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
}
onFilter(filterValues, sortId, sortDirection, searchText) {
onFilter(filterValues, sortId, sortDirection, viewAs, searchText) {
let cloneFilterValues = cloneObjectsArray(filterValues);
cloneFilterValues = cloneFilterValues.map(function (item) {
item.key = item.key.replace(item.group + "_", '');
@ -356,7 +366,8 @@ class FilterInput extends React.Component {
inputValue: searchText != undefined ? searchText : this.state.searchText,
filterValues: cloneFilterValues.filter(item => item.key != '-1'),
sortId: sortId,
sortDirection: sortDirection
sortDirection: sortDirection,
viewAs: viewAs
});
}
onChangeFilter(result) {
@ -364,7 +375,7 @@ class FilterInput extends React.Component {
searchText: result.inputValue,
filterValues: result.filterValues,
});
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", result.inputValue);
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs, result.inputValue);
}
onFilterRender() {
if (this.isResizeUpdate) {
@ -419,7 +430,7 @@ class FilterInput extends React.Component {
})
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc");
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
}
return;
@ -467,7 +478,7 @@ class FilterInput extends React.Component {
item.key = item.key.replace(item.group + "_", '');
return item;
})
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc");
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
this.setState({
filterValues: currentFilterItems,
openFilterItems: currentFilterItems,
@ -503,7 +514,7 @@ class FilterInput extends React.Component {
item.key = item.key.replace(item.group + "_", '');
return item;
})
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc");
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs);
}
}
@ -517,7 +528,7 @@ class FilterInput extends React.Component {
/* eslint-enable react/prop-types */
const { searchText, filterValues, openFilterItems,
hideFilterItems, sortId, sortDirection } = this.state;
hideFilterItems, sortId, sortDirection, viewAs } = this.state;
// console.log("filter input render, openFilterItems", openFilterItems, 'hideFilterItems', hideFilterItems);
let iconSize = 33;
@ -581,6 +592,11 @@ class FilterInput extends React.Component {
directionAscLabel={directionAscLabel}
directionDescLabel={directionDescLabel}
/>
<ViewSelector
isDisabled={isDisabled}
onClickViewSelector={this.onClickViewSelector}
viewAs={viewAs}
/>
</StyledFilterInput>
);

View File

@ -43,7 +43,8 @@ class FilterStory extends React.Component {
inputValue: "text",
filterValues: [
{key: "1", group: "filter-status"}
]
],
viewAs: "row"
}
};
this.buttonClick = this.buttonClick.bind(this);

View File

@ -17,7 +17,10 @@ const StyledFilterInput = styled.div`
.styled-search-input {
display: block;
float: left;
width: calc(100% - 140px);
width: calc(100% - 212px);
@media (max-width: 460px) {
width: calc(100% - 140px);
}
@media ${mobile} {
width: calc(100% - 58px);
}
@ -121,8 +124,50 @@ const StyledFilterInput = styled.div`
color: #333;
}
}
`;
export const StyledViewSelector = styled.div`
display: flex;
float: left;
width: 64px;
margin-left: 8px;
@media (max-width: 460px) {
display:none;
}
.view-selector-button{
border: 1px solid ${props => props.isDisabled ? '#ECEEF1' : '#D0D5DA'};
border-radius: 3px;
padding: 7px;
${props => props.isDisabled && 'background-color: #F8F9F9;' }
svg{
pointer-events: none;
}
&.active{
background-color:#A3A9AE;
border-color: #A3A9AE;
}
&:hover{
${props => !props.isDisabled && 'background-color: #A3A9AE;' }
${props => !props.isDisabled && 'border-color: #A3A9AE;' }
}
&:first-child{
border-right: none;
border-top-right-radius:0;
border-bottom-right-radius:0;
}
&:last-child{
border-left: none;
border-top-left-radius:0;
border-bottom-left-radius:0;
}
}
`;
export const StyledFilterItem = styled.div`
@ -228,4 +273,11 @@ export const StyledIconButton = styled.div`
transform: ${state => !state.sortDirection ? 'scale(1, -1)' : 'scale(1)'};
`;
export const StyledIconWrapper = styled.div`
display: inline-flex;
width: 32px;
height: 100%;
`;
export default StyledFilterInput;

View File

@ -0,0 +1,60 @@
import React from 'react';
import { IconButton } from 'asc-web-components';
import PropTypes from 'prop-types';
import { StyledViewSelector } from '../StyledFilterInput';
class ViewSelector extends React.Component {
constructor(props) {
super(props)
this.state = {
viewAs: props.viewAs
}
}
render(){
const { isDisabled, viewAs} = this.props;
return(
<StyledViewSelector isDisabled={isDisabled}>
<IconButton
className={`view-selector-button ${viewAs === "row" ? "active" : ""}`}
color={viewAs === "row" ? "#ffffff" : "#A3A9AE"}
hoverColor={"#ffffff"}
clickColor={"#ffffff"}
iconName={'FilterViewSelectorRowIcon'}
isDisabled={isDisabled}
isFill={true}
onClick={(item) => this.props.onClickViewSelector(item)}
size={16}
id="rowSelectorButton"
/>
<IconButton
className={`view-selector-button ${viewAs === "tile" ? "active" : ""}`}
color={viewAs === "tile" ? "#ffffff" : "#A3A9AE"}
hoverColor={"#ffffff"}
clickColor={"#ffffff"}
iconName={'FilterViewSelectorTileIcon'}
isDisabled={isDisabled}
isFill={true}
onClick={(item) => this.props.onClickViewSelector(item)}
size={16}
id="tileSelectorButton"
/>
</StyledViewSelector>
)
}
}
ViewSelector.propTypes = {
isDisabled: PropTypes.bool,
viewAs: PropTypes.string,
onClickViewSelector: PropTypes.func
}
ViewSelector.defaultProps = {
isDisabled: false
}
export default ViewSelector;

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="M0 15C0 15.5523 0.447715 16 1 16H15C15.5523 16 16 15.5523 16 15C16 14.4477 15.5523 14 15 14H1C0.447715 14 0 14.4477 0 15ZM0 8C0 8.55228 0.447715 9 1 9H15C15.5523 9 16 8.55228 16 8C16 7.44771 15.5523 7 15 7H1C0.447715 7 0 7.44771 0 8ZM1 2C0.447715 2 0 1.55229 0 1C0 0.447715 0.447715 0 1 0H15C15.5523 0 16 0.447715 16 1C16 1.55229 15.5523 2 15 2H1Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 516 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="M1 0C0.447715 0 0 0.447715 0 1V6C0 6.55228 0.447715 7 1 7H6C6.55228 7 7 6.55228 7 6V1C7 0.447715 6.55228 0 6 0H1ZM1 9C0.447715 9 0 9.44771 0 10V15C0 15.5523 0.447715 16 1 16H6C6.55228 16 7 15.5523 7 15V10C7 9.44772 6.55228 9 6 9H1ZM9 1C9 0.447715 9.44772 0 10 0H15C15.5523 0 16 0.447715 16 1V6C16 6.55228 15.5523 7 15 7H10C9.44771 7 9 6.55228 9 6V1ZM10 9C9.44772 9 9 9.44771 9 10V15C9 15.5523 9.44771 16 10 16H15C15.5523 16 16 15.5523 16 15V10C16 9.44772 15.5523 9 15 9H10Z" fill="#A3A9AE"/>
</svg>

After

Width:  |  Height:  |  Size: 644 B

View File

@ -133,6 +133,8 @@ import OrigCrossSidebarIcon from './cross.sidebar.react.svg';
import OrigCheckboxIcon from './checkbox.react.svg';
import OrigCheckboxCheckedIcon from './checkbox.checked.react.svg';
import OrigCheckboxIndeterminateIcon from './checkbox.indeterminate.react.svg';
import OrigFilterViewSelectorRowIcon from './filter.view.selector.row.react.svg';
import OrigFilterViewSelectorTileIcon from './filter.view.selector.tile.react.svg';
import OrigEyeIcon from './eye.react.svg';
import OrigEyeOffIcon from './eye.off.react.svg';
@ -800,4 +802,12 @@ export const ShareLinkedInIcon = createStyledIcon(
export const KeyIcon = createStyledIcon(
OrigKeyIcon,
'KeyIcon'
);
export const FilterViewSelectorRowIcon = createStyledIcon(
OrigFilterViewSelectorRowIcon,
'FilterViewSelectorRowIcon'
);
export const FilterViewSelectorTileIcon = createStyledIcon(
OrigFilterViewSelectorTileIcon,
'FilterViewSelectorTileIcon'
);