Merge branch 'develop' into feature/version-hostory-redesign
This commit is contained in:
commit
efacc50ac4
@ -9,7 +9,7 @@
|
||||
"ConnectionStrings": {
|
||||
"default": {
|
||||
"name": "default",
|
||||
"connectionString": "Server=172.18.0.3;Port=3306;Database=onlyoffice;User ID=onlyoffice_user;Password=onlyoffice_pass;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none",
|
||||
"connectionString": "Server=172.18.0.5;Port=3306;Database=onlyoffice;User ID=onlyoffice_user;Password=onlyoffice_pass;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none",
|
||||
"providerName": "MySql.Data.MySqlClient"
|
||||
}
|
||||
},
|
||||
|
@ -16,10 +16,12 @@ import find from "lodash/find";
|
||||
import result from "lodash/result";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { withRouter } from "react-router";
|
||||
import { constants, FilterInput, store, Loaders } from "asc-web-common";
|
||||
import { constants, FilterInput, store, Loaders, utils } from "asc-web-common";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
|
||||
const { withLayoutSize } = utils;
|
||||
|
||||
const {
|
||||
getCurrentUser,
|
||||
getSettingsCustomNames,
|
||||
@ -287,20 +289,22 @@ class SectionFilterContent extends React.Component {
|
||||
this.props.selectedFolderId !== nextProps.selectedFolderId ||
|
||||
this.state.isReady !== nextState.isReady ||
|
||||
this.props.viewAs !== nextProps.viewAs ||
|
||||
this.props.firstLoad !== nextProps.firstLoad
|
||||
this.props.firstLoad !== nextProps.firstLoad ||
|
||||
this.props.sectionWidth !== nextProps.sectionWidth
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("Filter render");
|
||||
const selectedFilterData = this.getSelectedFilterData();
|
||||
const { t, language, firstLoad } = this.props;
|
||||
const { t, language, firstLoad, sectionWidth } = this.props;
|
||||
const filterColumnCount =
|
||||
window.innerWidth < 500 ? {} : { filterColumnCount: 3 };
|
||||
return firstLoad ? (
|
||||
<Loaders.Filter />
|
||||
) : (
|
||||
<FilterInput
|
||||
sectionWidth={sectionWidth}
|
||||
getFilterData={this.getData}
|
||||
getSortData={this.getSortData}
|
||||
selectedFilterData={selectedFilterData}
|
||||
@ -338,4 +342,4 @@ export default connect(mapStateToProps, {
|
||||
fetchFiles,
|
||||
setViewAs,
|
||||
setIsLoading,
|
||||
})(withRouter(withTranslation()(SectionFilterContent)));
|
||||
})(withRouter(withLayoutSize(withTranslation()(SectionFilterContent))));
|
||||
|
@ -19,7 +19,6 @@
|
||||
<PackageReference Include="AppLimit.CloudComputing.SharpBox" Version="1.1.0.451" />
|
||||
<PackageReference Include="Box.V2.Core" Version="3.24.0" />
|
||||
<PackageReference Include="DocuSign.eSign.dll" Version="4.4.1" />
|
||||
<PackageReference Include="DotNetZip" Version="1.13.8" />
|
||||
<PackageReference Include="Dropbox.Api" Version="4.10.0" />
|
||||
<PackageReference Include="Google.Apis.Drive.v3" Version="1.49.0.2111" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.32.0">
|
||||
@ -29,6 +28,7 @@
|
||||
<PackageReference Include="Microsoft.OneDriveSDK" Version="2.0.7.5" />
|
||||
<PackageReference Include="Microsoft.SharePoint.Client" Version="14.0.4762.1000" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.4" />
|
||||
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -45,11 +45,13 @@ using ASC.Web.Files.Helpers;
|
||||
using ASC.Web.Files.Utils;
|
||||
using ASC.Web.Studio.Core;
|
||||
|
||||
using Ionic.Zip;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Writers;
|
||||
using SharpCompress.Writers.Zip;
|
||||
|
||||
namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
{
|
||||
internal class FileDownloadOperationData<T> : FileOperationData<T>
|
||||
@ -84,13 +86,13 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
using var scope = ThirdPartyOperation.CreateScope();
|
||||
var scopeClass = scope.ServiceProvider.GetService<FileDownloadOperationScope>();
|
||||
var (globalStore, filesLinkUtility, _, _, _) = scopeClass;
|
||||
using var stream = TempStream.Create();
|
||||
using (var zip = new ZipOutputStream(stream, true)
|
||||
{
|
||||
CompressionLevel = Ionic.Zlib.CompressionLevel.Level3,
|
||||
AlternateEncodingUsage = ZipOption.AsNecessary,
|
||||
AlternateEncoding = Encoding.UTF8,
|
||||
})
|
||||
using var stream = TempStream.Create();
|
||||
|
||||
var writerOptions = new ZipWriterOptions(CompressionType.Deflate);
|
||||
writerOptions.ArchiveEncoding.Default = Encoding.UTF8;
|
||||
writerOptions.DeflateCompressionLevel = SharpCompress.Compressors.Deflate.CompressionLevel.Level3;
|
||||
|
||||
using (var zip = WriterFactory.Open(stream, ArchiveType.Zip, writerOptions))
|
||||
{
|
||||
(ThirdPartyOperation as FileDownloadOperation<string>).CompressToZip(zip, stream, scope);
|
||||
(DaoOperation as FileDownloadOperation<int>).CompressToZip(zip, stream, scope);
|
||||
@ -125,19 +127,16 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
get { return FileOperationType.Download; }
|
||||
}
|
||||
|
||||
public bool Compress { get; }
|
||||
|
||||
public FileDownloadOperation(IServiceProvider serviceProvider, FileDownloadOperationData<T> fileDownloadOperationData, bool compress = true)
|
||||
public FileDownloadOperation(IServiceProvider serviceProvider, FileDownloadOperationData<T> fileDownloadOperationData)
|
||||
: base(serviceProvider, fileDownloadOperationData)
|
||||
{
|
||||
files = fileDownloadOperationData.FilesDownload;
|
||||
headers = fileDownloadOperationData.Headers;
|
||||
Compress = compress;
|
||||
}
|
||||
|
||||
protected override void Do(IServiceScope scope)
|
||||
{
|
||||
if (!Compress && !Files.Any() && !Folders.Any()) return;
|
||||
if (!Files.Any() && !Folders.Any()) return;
|
||||
|
||||
entriesPathId = GetEntriesPathId(scope);
|
||||
if (entriesPathId == null || entriesPathId.Count == 0)
|
||||
@ -150,36 +149,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
throw new DirectoryNotFoundException(FilesCommonResource.ErrorMassage_FolderNotFound);
|
||||
}
|
||||
|
||||
var scopeClass = scope.ServiceProvider.GetService<FileDownloadOperationScope>();
|
||||
var (globalStore, filesLinkUtility, _, _, _) = scopeClass;
|
||||
ReplaceLongPath(entriesPathId);
|
||||
|
||||
if (Compress)
|
||||
{
|
||||
using var stream = TempStream.Create();
|
||||
using var zip = new ZipOutputStream(stream, true)
|
||||
{
|
||||
CompressionLevel = Ionic.Zlib.CompressionLevel.Level3,
|
||||
AlternateEncodingUsage = ZipOption.AsNecessary,
|
||||
AlternateEncoding = Encoding.UTF8
|
||||
};
|
||||
|
||||
CompressToZip(zip, stream, scope);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
stream.Position = 0;
|
||||
const string fileName = FileConstant.DownloadTitle + ".zip";
|
||||
var store = globalStore.GetStore();
|
||||
store.Save(
|
||||
FileConstant.StorageDomainTmp,
|
||||
string.Format(@"{0}\{1}", ((IAccount)Thread.CurrentPrincipal.Identity).ID, fileName),
|
||||
stream,
|
||||
"application/zip",
|
||||
"attachment; filename=\"" + fileName + "\"");
|
||||
Status = string.Format("{0}?{1}=bulk", filesLinkUtility.FileHandlerPath, FilesLinkUtility.Action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ItemNameValueCollection<T> ExecPathFromFile(IServiceScope scope, File<T> file, string path)
|
||||
@ -260,7 +230,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
return entriesPathId;
|
||||
}
|
||||
|
||||
internal void CompressToZip(ZipOutputStream zip, Stream stream, IServiceScope scope)
|
||||
internal void CompressToZip(IWriter zip, Stream stream, IServiceScope scope)
|
||||
{
|
||||
if (entriesPathId == null) return;
|
||||
var scopeClass = scope.ServiceProvider.GetService<FileDownloadOperationScope>();
|
||||
@ -325,17 +295,17 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
}
|
||||
}
|
||||
|
||||
zip.PutNextEntry(newtitle);
|
||||
|
||||
if (!entryId.Equals(default(T)) && file != null)
|
||||
{
|
||||
{
|
||||
Stream readStream = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (fileConverter.EnableConvert(file, convertToExt))
|
||||
{
|
||||
//Take from converter
|
||||
using var readStream = fileConverter.Exec(file, convertToExt);
|
||||
readStream.CopyTo(zip);
|
||||
readStream = fileConverter.Exec(file, convertToExt);
|
||||
|
||||
if (!string.IsNullOrEmpty(convertToExt))
|
||||
{
|
||||
filesMessageService.Send(file, headers, MessageAction.FileDownloadedAs, file.Title, convertToExt);
|
||||
@ -347,15 +317,24 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
}
|
||||
else
|
||||
{
|
||||
using var readStream = FileDao.GetFileStream(file);
|
||||
readStream.CopyTo(zip);
|
||||
readStream = FileDao.GetFileStream(file);
|
||||
filesMessageService.Send(file, headers, MessageAction.FileDownloaded, file.Title);
|
||||
}
|
||||
}
|
||||
|
||||
zip.Write(newtitle, readStream);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Error = ex.Message;
|
||||
Logger.Error(Error, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (readStream != null)
|
||||
{
|
||||
readStream.Close();
|
||||
readStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
|
@ -122,8 +122,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
throw new InvalidOperationException(FilesCommonResource.ErrorMassage_ManyDownloads);
|
||||
}
|
||||
|
||||
var op1 = new FileDownloadOperation<int>(ServiceProvider, new FileDownloadOperationData<int>(folders.Where(r => r.Key.ValueKind == JsonValueKind.Number).ToDictionary(r => r.Key.GetInt32(), r => r.Value), files.Where(r => r.Key.ValueKind == JsonValueKind.Number).ToDictionary(r => r.Key.GetInt32(), r => r.Value), tenant, headers), false);
|
||||
var op2 = new FileDownloadOperation<string>(ServiceProvider, new FileDownloadOperationData<string>(folders.Where(r => r.Key.ValueKind == JsonValueKind.String).ToDictionary(r => r.Key.GetString(), r => r.Value), files.Where(r => r.Key.ValueKind == JsonValueKind.String).ToDictionary(r => r.Key.GetString(), r => r.Value), tenant, headers), false);
|
||||
var op1 = new FileDownloadOperation<int>(ServiceProvider, new FileDownloadOperationData<int>(folders.Where(r => r.Key.ValueKind == JsonValueKind.Number).ToDictionary(r => r.Key.GetInt32(), r => r.Value), files.Where(r => r.Key.ValueKind == JsonValueKind.Number).ToDictionary(r => r.Key.GetInt32(), r => r.Value), tenant, headers));
|
||||
var op2 = new FileDownloadOperation<string>(ServiceProvider, new FileDownloadOperationData<string>(folders.Where(r => r.Key.ValueKind == JsonValueKind.String).ToDictionary(r => r.Key.GetString(), r => r.Value), files.Where(r => r.Key.ValueKind == JsonValueKind.String).ToDictionary(r => r.Key.GetString(), r => r.Value), tenant, headers));
|
||||
var op = new FileDownloadOperation(ServiceProvider, op2, op1);
|
||||
|
||||
return QueueTask(userId, op);
|
||||
|
@ -19,26 +19,6 @@
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AppLimit.CloudComputing.SharpBox" Version="1.1.0.451" />
|
||||
<PackageReference Include="Box.V2.Core" Version="3.24.0" />
|
||||
<PackageReference Include="DocuSign.eSign.dll" Version="4.4.1" />
|
||||
<PackageReference Include="DotNetZip" Version="1.13.8" />
|
||||
<PackageReference Include="Dropbox.Api" Version="4.10.0" />
|
||||
<PackageReference Include="Google.Apis.Drive.v3" Version="1.49.0.2111" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.32.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.OneDriveSDK" Version="2.0.7.5" />
|
||||
<PackageReference Include="Microsoft.SharePoint.Client" Version="14.0.4762.1000" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.4" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Common\ASC.Common.csproj" />
|
||||
|
@ -6,7 +6,7 @@ import result from "lodash/result";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { withRouter } from "react-router";
|
||||
import { getFilterByLocation } from "../../../../../helpers/converters";
|
||||
import { store, FilterInput, Loaders } from "asc-web-common";
|
||||
import { store, FilterInput, Loaders, utils } from "asc-web-common";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import { getFilter, getGroups } from "../../../../../store/people/selectors";
|
||||
const {
|
||||
@ -17,6 +17,8 @@ const {
|
||||
getIsLoaded,
|
||||
} = store.auth.selectors;
|
||||
|
||||
const { withLayoutSize } = utils;
|
||||
|
||||
const getEmployeeStatus = (filterValues) => {
|
||||
const employeeStatus = result(
|
||||
find(filterValues, (value) => {
|
||||
@ -248,9 +250,10 @@ class SectionFilterContent extends React.Component {
|
||||
|
||||
render() {
|
||||
const selectedFilterData = this.getSelectedFilterData();
|
||||
const { t, language, isLoaded } = this.props;
|
||||
const { t, language, isLoaded, sectionWidth } = this.props;
|
||||
return isLoaded ? (
|
||||
<FilterInput
|
||||
sectionWidth={sectionWidth}
|
||||
getFilterData={this.getData}
|
||||
getSortData={this.getSortData}
|
||||
selectedFilterData={selectedFilterData}
|
||||
@ -282,5 +285,5 @@ function mapStateToProps(state) {
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, { fetchPeople })(
|
||||
withRouter(withTranslation()(SectionFilterContent))
|
||||
withRouter(withLayoutSize(withTranslation()(SectionFilterContent)))
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "asc-web-common",
|
||||
"version": "1.0.279",
|
||||
"version": "1.0.275",
|
||||
"description": "Ascensio System SIA common components and solutions library",
|
||||
"license": "AGPL-3.0",
|
||||
"files": [
|
||||
|
@ -2,7 +2,6 @@ import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { SearchInput } from "asc-web-components";
|
||||
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";
|
||||
@ -81,203 +80,122 @@ const convertToInternalData = function (fullDataArray, inputDataArray) {
|
||||
return filterItems;
|
||||
};
|
||||
|
||||
const minWidth = 170;
|
||||
const filterItemPadding = 60;
|
||||
const maxFilterItemWidth = 260;
|
||||
const itemsContainerWidth = 40;
|
||||
const sectionPaddings = 48;
|
||||
|
||||
class FilterInput extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.isResizeUpdate = false;
|
||||
this.minWidth = 190;
|
||||
const { selectedFilterData, getSortData, value } = props;
|
||||
const { sortDirection, sortId, inputValue } = selectedFilterData;
|
||||
const sortData = getSortData();
|
||||
|
||||
function getDefaultFilterData() {
|
||||
const filterData = props.getFilterData();
|
||||
const filterItems = [];
|
||||
const selectedFilterData = cloneObjectsArray(
|
||||
props.selectedFilterData.filterValues
|
||||
);
|
||||
selectedFilterData.forEach((defaultFilterValue) => {
|
||||
const filterValue = filterData.find(
|
||||
(x) =>
|
||||
x.key ===
|
||||
defaultFilterValue.key.replace(
|
||||
defaultFilterValue.group + "_",
|
||||
""
|
||||
) && x.group === defaultFilterValue.group
|
||||
);
|
||||
let groupLabel = "";
|
||||
|
||||
const groupFilterItem = filterData.find(
|
||||
(x) => x.key === defaultFilterValue.group
|
||||
);
|
||||
if (groupFilterItem != undefined) {
|
||||
groupLabel = groupFilterItem.label;
|
||||
} else {
|
||||
const subgroupFilterItem = filterData.find(
|
||||
(x) => x.subgroup === defaultFilterValue.group
|
||||
);
|
||||
if (subgroupFilterItem != undefined) {
|
||||
groupLabel = subgroupFilterItem.label;
|
||||
}
|
||||
}
|
||||
|
||||
if (filterValue != undefined) {
|
||||
defaultFilterValue.key =
|
||||
defaultFilterValue.group + "_" + defaultFilterValue.key;
|
||||
defaultFilterValue.label = filterValue.label;
|
||||
defaultFilterValue.groupLabel = groupLabel;
|
||||
filterItems.push(defaultFilterValue);
|
||||
}
|
||||
});
|
||||
return filterItems;
|
||||
}
|
||||
|
||||
let filterValues = props.selectedFilterData ? getDefaultFilterData() : [];
|
||||
filterValues = [
|
||||
...filterValues,
|
||||
...this.convertSelectorToInternalData(
|
||||
props.getFilterData(),
|
||||
cloneObjectsArray(props.selectedFilterData.filterValues)
|
||||
),
|
||||
];
|
||||
const filterValues = selectedFilterData ? this.getDefaultFilterData() : [];
|
||||
|
||||
this.state = {
|
||||
sortDirection:
|
||||
props.selectedFilterData.sortDirection === "desc" ? true : false,
|
||||
sortDirection: sortDirection === "desc" ? true : false,
|
||||
sortId:
|
||||
props
|
||||
.getSortData()
|
||||
.findIndex((x) => x.key === props.selectedFilterData.sortId) != -1
|
||||
? props.selectedFilterData.sortId
|
||||
: props.getSortData().length > 0
|
||||
? props.getSortData()[0].key
|
||||
sortData.findIndex((x) => x.key === sortId) != -1
|
||||
? sortId
|
||||
: sortData.length > 0
|
||||
? sortData[0].key
|
||||
: "",
|
||||
searchText: props.selectedFilterData.inputValue || props.value,
|
||||
searchText: inputValue || value,
|
||||
|
||||
filterValues,
|
||||
openFilterItems: [],
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
needUpdateFilter: false,
|
||||
};
|
||||
|
||||
this.searchWrapper = React.createRef();
|
||||
this.filterWrapper = React.createRef();
|
||||
|
||||
this.onClickSortItem = this.onClickSortItem.bind(this);
|
||||
this.onSortDirectionClick = this.onSortDirectionClick.bind(this);
|
||||
this.onChangeSortDirection = this.onChangeSortDirection.bind(this);
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
this.onChangeFilter = this.onChangeFilter.bind(this);
|
||||
|
||||
this.onSearchChanged = this.onSearchChanged.bind(this);
|
||||
|
||||
this.getDefaultSelectedIndex = this.getDefaultSelectedIndex.bind(this);
|
||||
|
||||
this.updateFilter = this.updateFilter.bind(this);
|
||||
this.onClickFilterItem = this.onClickFilterItem.bind(this);
|
||||
this.getFilterData = this.getFilterData.bind(this);
|
||||
this.onFilterRender = this.onFilterRender.bind(this);
|
||||
this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this);
|
||||
this.clearFilter = this.clearFilter.bind(this);
|
||||
|
||||
this.onClickViewSelector = this.onClickViewSelector.bind(this);
|
||||
|
||||
this.throttledResize = throttle(this.resize, 300);
|
||||
this.rectComboBoxRef = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.throttledResize);
|
||||
if (this.state.filterValues.length > 0) this.updateFilter();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.throttledResize);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { selectedFilterData, sectionWidth, getSortData } = this.props;
|
||||
const { filterValues, searchText } = this.state;
|
||||
const { sortDirection, sortId, inputValue } = selectedFilterData;
|
||||
|
||||
if (
|
||||
this.props.needForUpdate &&
|
||||
this.props.needForUpdate(prevProps, this.props)
|
||||
) {
|
||||
let internalFilterData = convertToInternalData(
|
||||
this.props.getFilterData(),
|
||||
cloneObjectsArray(this.props.selectedFilterData.filterValues)
|
||||
cloneObjectsArray(selectedFilterData.filterValues)
|
||||
);
|
||||
this.updateFilter(internalFilterData);
|
||||
}
|
||||
|
||||
if (sectionWidth !== prevProps.sectionWidth) {
|
||||
this.updateFilter();
|
||||
}
|
||||
|
||||
if (
|
||||
(!isEqual(selectedFilterData.filterValues, filterValues) ||
|
||||
inputValue !== searchText) &&
|
||||
sectionWidth !== prevProps.sectionWidth
|
||||
) {
|
||||
const sortData = getSortData();
|
||||
const filterValues = this.getDefaultFilterData();
|
||||
this.setState({
|
||||
sortDirection: sortDirection === "desc" ? true : false,
|
||||
sortId:
|
||||
sortData.findIndex((x) => x.key === sortId) != -1
|
||||
? sortId
|
||||
: sortData.length > 0
|
||||
? sortData[0].key
|
||||
: "",
|
||||
filterValues: filterValues,
|
||||
searchText: selectedFilterData.inputValue || "",
|
||||
});
|
||||
this.updateFilter(filterValues);
|
||||
}
|
||||
|
||||
if (
|
||||
!isEqual(
|
||||
prevProps.selectedFilterData.filterValues,
|
||||
selectedFilterData.filterValues
|
||||
) &&
|
||||
selectedFilterData.filterValues &&
|
||||
(selectedFilterData.filterValues.length === 0 ||
|
||||
(selectedFilterData.filterValues.length === 1 &&
|
||||
selectedFilterData.filterValues[0].key === "null")) &&
|
||||
!selectedFilterData.inputValue
|
||||
) {
|
||||
this.clearFilter();
|
||||
}
|
||||
}
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const {
|
||||
selectedFilterData,
|
||||
getFilterData,
|
||||
getSortData,
|
||||
value,
|
||||
id,
|
||||
isDisabled,
|
||||
size,
|
||||
placeholder,
|
||||
sectionWidth,
|
||||
} = this.props;
|
||||
if (!isEqual(selectedFilterData, nextProps.selectedFilterData)) {
|
||||
let internalFilterData = cloneObjectsArray(this.state.filterValues);
|
||||
if (nextProps.selectedFilterData.filterValues) {
|
||||
internalFilterData = convertToInternalData(
|
||||
getFilterData(),
|
||||
cloneObjectsArray(nextProps.selectedFilterData.filterValues)
|
||||
);
|
||||
let internalFilterDataSelectors = this.convertSelectorToInternalData(
|
||||
getFilterData(),
|
||||
cloneObjectsArray(nextProps.selectedFilterData.filterValues)
|
||||
);
|
||||
internalFilterData = internalFilterData.concat(
|
||||
internalFilterDataSelectors
|
||||
);
|
||||
this.updateFilter(internalFilterData);
|
||||
}
|
||||
this.setState({
|
||||
sortDirection:
|
||||
nextProps.selectedFilterData.sortDirection === "desc" ? true : false,
|
||||
sortId:
|
||||
getSortData().findIndex(
|
||||
(x) => x.key === nextProps.selectedFilterData.sortId
|
||||
) != -1
|
||||
? nextProps.selectedFilterData.sortId
|
||||
: "",
|
||||
filterValues: internalFilterData,
|
||||
searchText: nextProps.selectedFilterData.inputValue || value,
|
||||
});
|
||||
|
||||
if (
|
||||
!isEqual(selectedFilterData, nextProps.selectedFilterData) ||
|
||||
this.props.viewAs !== nextProps.viewAs ||
|
||||
this.props.widthProp !== nextProps.widthProp ||
|
||||
sectionWidth !== nextProps.sectionWidth
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.props.viewAs !== nextProps.viewAs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.props.isReady !== nextProps.isReady) {
|
||||
let internalFilterData = cloneObjectsArray(this.state.filterValues);
|
||||
internalFilterData = convertToInternalData(
|
||||
getFilterData(),
|
||||
cloneObjectsArray(nextProps.selectedFilterData.filterValues)
|
||||
);
|
||||
|
||||
let internalFilterDataSelectors = this.convertSelectorToInternalData(
|
||||
getFilterData(),
|
||||
cloneObjectsArray(nextProps.selectedFilterData.filterValues)
|
||||
);
|
||||
internalFilterData = internalFilterData.concat(
|
||||
internalFilterDataSelectors
|
||||
);
|
||||
this.updateFilter(internalFilterData);
|
||||
|
||||
this.setState({
|
||||
sortDirection:
|
||||
nextProps.selectedFilterData.sortDirection === "desc" ? true : false,
|
||||
sortId:
|
||||
getSortData().findIndex(
|
||||
(x) => x.key === nextProps.selectedFilterData.sortId
|
||||
) != -1
|
||||
? nextProps.selectedFilterData.sortId
|
||||
: "",
|
||||
filterValues: internalFilterData,
|
||||
searchText: nextProps.selectedFilterData.inputValue || value,
|
||||
});
|
||||
// return true;
|
||||
}
|
||||
|
||||
if (
|
||||
id != nextProps.id ||
|
||||
isDisabled != nextProps.isDisabled ||
|
||||
@ -286,96 +204,41 @@ class FilterInput extends React.Component {
|
||||
value != nextProps.value
|
||||
)
|
||||
return true;
|
||||
if (this.isResizeUpdate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !isEqual(this.state, nextState);
|
||||
}
|
||||
|
||||
convertSelectorToInternalData = (filterData, filterValues) => {
|
||||
const resultValues = [];
|
||||
filterValues.forEach((item) => {
|
||||
const isSelector = item.group.includes("filter-author");
|
||||
if (isSelector) {
|
||||
const typeSelector = item.key.includes("user")
|
||||
? "user"
|
||||
: item.key.includes("group")
|
||||
? "group"
|
||||
: null;
|
||||
const hasUnderscore = item.key.indexOf("_") !== -1;
|
||||
const key = hasUnderscore
|
||||
? item.key.slice(0, item.key.indexOf("_"))
|
||||
: item.key;
|
||||
const finded = filterData.find(
|
||||
(x) => x.key === key && x.group === item.group
|
||||
);
|
||||
if (!finded) return;
|
||||
const convertedItem = {
|
||||
key: item.group + "_" + item.key,
|
||||
label: finded.label,
|
||||
group: item.group,
|
||||
groupLabel: finded.label,
|
||||
typeSelector,
|
||||
groupsCaption: finded.groupsCaption,
|
||||
defaultOptionLabel: finded.defaultOptionLabel,
|
||||
defaultOption: finded.defaultOption,
|
||||
defaultSelectLabel: finded.defaultSelectLabel,
|
||||
selectedItem: finded.selectedItem,
|
||||
};
|
||||
resultValues.push(convertedItem);
|
||||
}
|
||||
});
|
||||
return resultValues;
|
||||
};
|
||||
|
||||
resize = () => {
|
||||
this.isResizeUpdate = true;
|
||||
this.setState({
|
||||
filterValues: this.state.filterValues,
|
||||
openFilterItems: this.state.filterValues,
|
||||
hideFilterItems: [],
|
||||
});
|
||||
};
|
||||
onChangeSortDirection(key) {
|
||||
onChangeSortDirection = (key) => {
|
||||
this.onFilter(
|
||||
this.state.filterValues,
|
||||
this.state.sortId,
|
||||
key ? "desc" : "asc"
|
||||
);
|
||||
this.setState({ sortDirection: !!key });
|
||||
}
|
||||
onClickViewSelector(item) {
|
||||
};
|
||||
onClickViewSelector = (item) => {
|
||||
const itemId = (item.target && item.target.dataset.for) || item;
|
||||
const viewAs = itemId.indexOf("row") === -1 ? "tile" : "row";
|
||||
this.props.onChangeViewAs(viewAs);
|
||||
}
|
||||
getDefaultSelectedIndex() {
|
||||
const sortData = this.props.getSortData();
|
||||
if (sortData.length > 0) {
|
||||
const defaultIndex = sortData.findIndex(
|
||||
(x) => x.key === this.state.sortId
|
||||
);
|
||||
return defaultIndex != -1 ? defaultIndex : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
onClickSortItem(key) {
|
||||
};
|
||||
|
||||
onClickSortItem = (key) => {
|
||||
this.setState({ sortId: key });
|
||||
this.onFilter(
|
||||
this.state.filterValues,
|
||||
key,
|
||||
this.state.sortDirection ? "desc" : "asc"
|
||||
);
|
||||
}
|
||||
onSortDirectionClick() {
|
||||
};
|
||||
onSortDirectionClick = () => {
|
||||
this.onFilter(
|
||||
this.state.filterValues,
|
||||
this.state.sortId,
|
||||
!this.state.sortDirection ? "desc" : "asc"
|
||||
);
|
||||
this.setState({ sortDirection: !this.state.sortDirection });
|
||||
}
|
||||
onSearchChanged(value) {
|
||||
};
|
||||
onSearchChanged = (value) => {
|
||||
this.setState({ searchText: value });
|
||||
this.onFilter(
|
||||
this.state.filterValues,
|
||||
@ -383,23 +246,93 @@ class FilterInput extends React.Component {
|
||||
this.state.sortDirection ? "desc" : "asc",
|
||||
value
|
||||
);
|
||||
}
|
||||
onSearch(result) {
|
||||
};
|
||||
onSearch = (result) => {
|
||||
this.onFilter(
|
||||
result.filterValues,
|
||||
this.state.sortId,
|
||||
this.state.sortDirection ? "desc" : "asc"
|
||||
);
|
||||
}
|
||||
getFilterData() {
|
||||
const _this = this;
|
||||
};
|
||||
getDefaultFilterData = () => {
|
||||
const { getFilterData, selectedFilterData } = this.props;
|
||||
const filterData = getFilterData();
|
||||
const filterItems = [];
|
||||
const filterValues = cloneObjectsArray(selectedFilterData.filterValues);
|
||||
|
||||
for (let item of filterValues) {
|
||||
const filterValue = filterData.find(
|
||||
(x) => x.key === item.key && x.group === item.group
|
||||
);
|
||||
|
||||
if (!filterValue) {
|
||||
const isSelector = item.group.includes("filter-author");
|
||||
|
||||
if (isSelector) {
|
||||
const typeSelector = item.key.includes("user")
|
||||
? "user"
|
||||
: item.key.includes("group")
|
||||
? "group"
|
||||
: null;
|
||||
const underlined = item.key.indexOf("_") !== -1;
|
||||
const key = underlined
|
||||
? item.key.slice(0, item.key.indexOf("_"))
|
||||
: item.key;
|
||||
const filesFilterValue = filterData.find(
|
||||
(x) => x.key === key && x.group === item.group
|
||||
);
|
||||
|
||||
if (filesFilterValue) {
|
||||
const convertedItem = {
|
||||
key: item.group + "_" + item.key,
|
||||
label: filesFilterValue.label,
|
||||
group: item.group,
|
||||
groupLabel: filesFilterValue.label,
|
||||
typeSelector,
|
||||
groupsCaption: filesFilterValue.groupsCaption,
|
||||
defaultOptionLabel: filesFilterValue.defaultOptionLabel,
|
||||
defaultOption: filesFilterValue.defaultOption,
|
||||
defaultSelectLabel: filesFilterValue.defaultSelectLabel,
|
||||
selectedItem: filesFilterValue.selectedItem,
|
||||
};
|
||||
filterItems.push(convertedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let groupLabel = "";
|
||||
const groupFilterItem = filterData.find((x) => x.key === item.group);
|
||||
if (groupFilterItem) {
|
||||
groupLabel = groupFilterItem.label;
|
||||
} else {
|
||||
const subgroupFilterItem = filterData.find(
|
||||
(x) => x.subgroup === item.group
|
||||
);
|
||||
if (subgroupFilterItem) {
|
||||
groupLabel = subgroupFilterItem.label;
|
||||
}
|
||||
}
|
||||
|
||||
if (filterValue) {
|
||||
item.key = item.group + "_" + item.key;
|
||||
item.label = filterValue.selectedItem
|
||||
? filterValue.selectedItem.label
|
||||
: filterValue.label;
|
||||
item.groupLabel = groupLabel;
|
||||
filterItems.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return filterItems;
|
||||
};
|
||||
getFilterData = () => {
|
||||
const d = this.props.getFilterData();
|
||||
const result = [];
|
||||
d.forEach((element) => {
|
||||
if (!element.inSubgroup) {
|
||||
element.onClick =
|
||||
!element.isSeparator && !element.isHeader && !element.disabled
|
||||
? (e) => _this.props.onClickFilterItem(e, element)
|
||||
? () => this.onClickFilterItem(element)
|
||||
: undefined;
|
||||
element.key =
|
||||
element.group != element.key
|
||||
@ -413,13 +346,13 @@ class FilterInput extends React.Component {
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
clearFilter() {
|
||||
};
|
||||
clearFilter = () => {
|
||||
this.setState({
|
||||
searchText: "",
|
||||
filterValues: [],
|
||||
openFilterItems: [],
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
});
|
||||
this.onFilter(
|
||||
[],
|
||||
@ -427,77 +360,135 @@ class FilterInput extends React.Component {
|
||||
this.state.sortDirection ? "desc" : "asc",
|
||||
""
|
||||
);
|
||||
}
|
||||
updateFilter(inputFilterItems) {
|
||||
const currentFilterItems =
|
||||
inputFilterItems || cloneObjectsArray(this.state.filterValues);
|
||||
};
|
||||
|
||||
getTextWidth = (text, font) => {
|
||||
var canvas =
|
||||
this.getTextWidth.canvas ||
|
||||
(this.getTextWidth.canvas = document.createElement("canvas"));
|
||||
var context = canvas.getContext("2d");
|
||||
context.font = font;
|
||||
var metrics = context.measureText(text);
|
||||
return metrics.width;
|
||||
};
|
||||
|
||||
calcHiddenItemWidth = (item) => {
|
||||
if (!item) return;
|
||||
let label = this.getItemLabel(item);
|
||||
|
||||
const itemWidth =
|
||||
this.getTextWidth(
|
||||
item.groupLabel + " " + label,
|
||||
"bolder 13px sans-serif"
|
||||
) + filterItemPadding;
|
||||
return itemWidth;
|
||||
};
|
||||
|
||||
addItems = (searchWidth) => {
|
||||
const { hiddenFilterItems } = this.state;
|
||||
if (hiddenFilterItems.length === 0) return 0;
|
||||
|
||||
let newSearchWidth = searchWidth;
|
||||
let numberOfHiddenItems = hiddenFilterItems.length;
|
||||
|
||||
for (let i = 0; i < hiddenFilterItems.length; i++) {
|
||||
let hiddenItemWidth = this.calcHiddenItemWidth(hiddenFilterItems[i]);
|
||||
|
||||
if (hiddenItemWidth > maxFilterItemWidth)
|
||||
hiddenItemWidth = maxFilterItemWidth;
|
||||
newSearchWidth = newSearchWidth - hiddenItemWidth;
|
||||
if (newSearchWidth >= minWidth) {
|
||||
numberOfHiddenItems--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numberOfHiddenItems;
|
||||
};
|
||||
|
||||
hideItems = (searchWidth, currentFilterItems) => {
|
||||
const { hiddenFilterItems } = this.state;
|
||||
let newSearchWidth = searchWidth;
|
||||
let numberOfHiddenItems = hiddenFilterItems.length;
|
||||
|
||||
for (let i = currentFilterItems.length - 1; i >= 0; i--) {
|
||||
if (currentFilterItems[i].id === "styled-hide-filter") continue;
|
||||
const filterItemWidth = currentFilterItems[i].getBoundingClientRect()
|
||||
.width;
|
||||
newSearchWidth = newSearchWidth + filterItemWidth;
|
||||
numberOfHiddenItems++;
|
||||
if (numberOfHiddenItems === 1) newSearchWidth - itemsContainerWidth; // subtract the width of hidden block
|
||||
|
||||
if (newSearchWidth > minWidth) break;
|
||||
}
|
||||
|
||||
return numberOfHiddenItems;
|
||||
};
|
||||
|
||||
calcHiddenItems = (searchWidth, currentFilterItems) => {
|
||||
const { hiddenFilterItems } = this.state;
|
||||
|
||||
if (!searchWidth || currentFilterItems.length === 0)
|
||||
return hiddenFilterItems.length;
|
||||
const numberOfHiddenItems =
|
||||
searchWidth < minWidth
|
||||
? this.hideItems(searchWidth, currentFilterItems)
|
||||
: this.addItems(searchWidth);
|
||||
|
||||
return numberOfHiddenItems;
|
||||
};
|
||||
|
||||
updateFilter = (inputFilterItems) => {
|
||||
const { sectionWidth } = this.props;
|
||||
const currentFilterItems = inputFilterItems
|
||||
? cloneObjectsArray(inputFilterItems)
|
||||
: cloneObjectsArray(this.state.filterValues);
|
||||
const fullWidth = this.searchWrapper.current.getBoundingClientRect().width;
|
||||
const filterWidth = this.filterWrapper.current.getBoundingClientRect()
|
||||
.width;
|
||||
const comboBoxWidth = this.rectComboBoxRef.current.getBoundingClientRect()
|
||||
.width;
|
||||
|
||||
const searchWidth = sectionWidth
|
||||
? sectionWidth - filterWidth - comboBoxWidth - sectionPaddings
|
||||
: fullWidth - filterWidth;
|
||||
|
||||
const filterArr = Array.from(
|
||||
Array.from(this.filterWrapper.current.children).find(
|
||||
(x) => x.id === "filter-items-container"
|
||||
).children
|
||||
);
|
||||
const searchFilterButton = Array.from(
|
||||
this.filterWrapper.current.children
|
||||
).find((x) => x.id != "filter-items-container");
|
||||
|
||||
const filterButton = searchFilterButton
|
||||
? Array.from(searchFilterButton.children)[0]
|
||||
: null;
|
||||
|
||||
if (fullWidth <= this.minWidth && fullWidth > 0) {
|
||||
const numberOfHiddenItems = this.calcHiddenItems(searchWidth, filterArr);
|
||||
if (searchWidth !== 0 && currentFilterItems.length > 0) {
|
||||
this.setState({
|
||||
openFilterItems: [],
|
||||
hideFilterItems: cloneObjectsArray(currentFilterItems),
|
||||
});
|
||||
} else if (filterWidth > fullWidth / 2) {
|
||||
let newOpenFilterItems = cloneObjectsArray(currentFilterItems);
|
||||
let newHideFilterItems = [];
|
||||
|
||||
let elementsWidth = 0;
|
||||
Array.from(filterArr).forEach((element) => {
|
||||
elementsWidth = elementsWidth + element.getBoundingClientRect().width;
|
||||
});
|
||||
|
||||
if (
|
||||
filterButton !== null &&
|
||||
elementsWidth >=
|
||||
fullWidth / 3 - filterButton.getBoundingClientRect().width
|
||||
) {
|
||||
for (let i = 0; i < filterArr.length; i++) {
|
||||
if (
|
||||
elementsWidth >
|
||||
fullWidth / 3 - filterButton.getBoundingClientRect().width
|
||||
) {
|
||||
elementsWidth =
|
||||
elementsWidth - filterArr[i].getBoundingClientRect().width;
|
||||
const hiddenItem = currentFilterItems.find(
|
||||
(x) => x.key === filterArr[i].getAttribute("id")
|
||||
);
|
||||
if (hiddenItem) newHideFilterItems.push(hiddenItem);
|
||||
newOpenFilterItems.splice(
|
||||
newOpenFilterItems.findIndex(
|
||||
(x) => x.key === filterArr[i].getAttribute("id")
|
||||
),
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
openFilterItems: newOpenFilterItems,
|
||||
hideFilterItems: newHideFilterItems,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
openFilterItems: currentFilterItems.slice(),
|
||||
hideFilterItems: [],
|
||||
openFilterItems: numberOfHiddenItems
|
||||
? currentFilterItems.slice(
|
||||
0,
|
||||
currentFilterItems.length - numberOfHiddenItems
|
||||
)
|
||||
: currentFilterItems.slice(),
|
||||
hiddenFilterItems: numberOfHiddenItems
|
||||
? currentFilterItems.slice(-numberOfHiddenItems)
|
||||
: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
onDeleteFilterItem(key) {
|
||||
};
|
||||
|
||||
getItemLabel = (item) => {
|
||||
let label = "";
|
||||
|
||||
if (item.selectedItem) {
|
||||
label = item.selectedItem.label
|
||||
? item.selectedItem.label
|
||||
: item.defaultSelectLabel;
|
||||
} else {
|
||||
label = item.label;
|
||||
}
|
||||
return label;
|
||||
};
|
||||
|
||||
onDeleteFilterItem = (key) => {
|
||||
const currentFilterItems = this.state.filterValues.slice();
|
||||
const indexFilterItem = currentFilterItems.findIndex((x) => x.key === key);
|
||||
if (indexFilterItem != -1) {
|
||||
@ -506,7 +497,7 @@ class FilterInput extends React.Component {
|
||||
this.setState({
|
||||
filterValues: currentFilterItems,
|
||||
openFilterItems: currentFilterItems,
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
});
|
||||
let filterValues = cloneObjectsArray(currentFilterItems);
|
||||
filterValues = filterValues.map(function (item) {
|
||||
@ -518,8 +509,8 @@ class FilterInput extends React.Component {
|
||||
this.state.sortId,
|
||||
this.state.sortDirection ? "desc" : "asc"
|
||||
);
|
||||
}
|
||||
onFilter(filterValues, sortId, sortDirection, searchText) {
|
||||
};
|
||||
onFilter = (filterValues, sortId, sortDirection, searchText) => {
|
||||
let cloneFilterValues = cloneObjectsArray(filterValues);
|
||||
cloneFilterValues = cloneFilterValues.map(function (item) {
|
||||
item.key = item.key.replace(item.group + "_", "");
|
||||
@ -531,8 +522,8 @@ class FilterInput extends React.Component {
|
||||
sortId: sortId,
|
||||
sortDirection: sortDirection,
|
||||
});
|
||||
}
|
||||
onChangeFilter(result) {
|
||||
};
|
||||
onChangeFilter = (result) => {
|
||||
this.setState({
|
||||
searchText: result.inputValue,
|
||||
filterValues: result.filterValues,
|
||||
@ -543,24 +534,21 @@ class FilterInput extends React.Component {
|
||||
this.state.sortDirection ? "desc" : "asc",
|
||||
result.inputValue
|
||||
);
|
||||
}
|
||||
onFilterRender() {
|
||||
if (this.isResizeUpdate) {
|
||||
this.isResizeUpdate = false;
|
||||
}
|
||||
};
|
||||
onFilterRender = () => {
|
||||
this.setState({
|
||||
needUpdateFilter: false,
|
||||
});
|
||||
|
||||
if (this.searchWrapper.current && this.filterWrapper.current) {
|
||||
const fullWidth = this.searchWrapper.current.getBoundingClientRect()
|
||||
.width;
|
||||
const filterWidth = this.filterWrapper.current.getBoundingClientRect()
|
||||
.width;
|
||||
if (fullWidth <= this.minWidth || filterWidth > fullWidth / 2)
|
||||
this.updateFilter();
|
||||
}
|
||||
}
|
||||
onClickFilterItem(event, filterItem) {
|
||||
this.updateFilter();
|
||||
};
|
||||
onClickFilterItem = (event, filterItem) => {
|
||||
const currentFilterItems = cloneObjectsArray(this.state.filterValues);
|
||||
|
||||
this.setState({
|
||||
needUpdateFilter: true,
|
||||
});
|
||||
|
||||
if (filterItem.isSelector) {
|
||||
const indexFilterItem = currentFilterItems.findIndex(
|
||||
(x) => x.group === filterItem.group
|
||||
@ -601,7 +589,7 @@ class FilterInput extends React.Component {
|
||||
this.setState({
|
||||
filterValues: currentFilterItems,
|
||||
openFilterItems: currentFilterItems,
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
});
|
||||
|
||||
if (selectFilterItem.selectedItem.key) {
|
||||
@ -647,7 +635,7 @@ class FilterInput extends React.Component {
|
||||
this.setState({
|
||||
filterValues: currentFilterItems,
|
||||
openFilterItems: currentFilterItems,
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
});
|
||||
} else if (subgroupItems.length === 1) {
|
||||
const selectFilterItem = {
|
||||
@ -678,7 +666,7 @@ class FilterInput extends React.Component {
|
||||
this.setState({
|
||||
filterValues: currentFilterItems,
|
||||
openFilterItems: currentFilterItems,
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -705,7 +693,7 @@ class FilterInput extends React.Component {
|
||||
this.setState({
|
||||
filterValues: currentFilterItems,
|
||||
openFilterItems: currentFilterItems,
|
||||
hideFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
});
|
||||
|
||||
const clone = cloneObjectsArray(
|
||||
@ -721,7 +709,7 @@ class FilterInput extends React.Component {
|
||||
this.state.sortDirection ? "desc" : "asc"
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
/* eslint-disable react/prop-types */
|
||||
@ -741,6 +729,7 @@ class FilterInput extends React.Component {
|
||||
viewAs,
|
||||
contextMenuHeader,
|
||||
isMobile,
|
||||
sectionWidth,
|
||||
} = this.props;
|
||||
/* eslint-enable react/prop-types */
|
||||
|
||||
@ -748,12 +737,13 @@ class FilterInput extends React.Component {
|
||||
searchText,
|
||||
filterValues,
|
||||
openFilterItems,
|
||||
hideFilterItems,
|
||||
hiddenFilterItems,
|
||||
sortId,
|
||||
sortDirection,
|
||||
} = this.state;
|
||||
|
||||
// console.log("filter input render, openFilterItems", openFilterItems, 'hideFilterItems', hideFilterItems);
|
||||
const smallSectionWidth = sectionWidth ? sectionWidth < 900 : false;
|
||||
|
||||
let iconSize = 30;
|
||||
switch (size) {
|
||||
case "base":
|
||||
@ -769,13 +759,14 @@ class FilterInput extends React.Component {
|
||||
}
|
||||
return (
|
||||
<StyledFilterInput
|
||||
smallSectionWidth={smallSectionWidth}
|
||||
isMobile={isMobile}
|
||||
viewAs={viewAs}
|
||||
className={className}
|
||||
id={id}
|
||||
style={style}
|
||||
>
|
||||
<div className="styled-search-input" ref={this.searchWrapper}>
|
||||
<div className="styled-search-input test" ref={this.searchWrapper}>
|
||||
<SearchInput
|
||||
id={id}
|
||||
isDisabled={isDisabled}
|
||||
@ -796,37 +787,38 @@ class FilterInput extends React.Component {
|
||||
<FilterBlock
|
||||
contextMenuHeader={contextMenuHeader}
|
||||
openFilterItems={openFilterItems}
|
||||
hideFilterItems={hideFilterItems}
|
||||
hiddenFilterItems={hiddenFilterItems}
|
||||
iconSize={iconSize}
|
||||
getFilterData={getFilterData}
|
||||
onClickFilterItem={this.onClickFilterItem}
|
||||
onDeleteFilterItem={this.onDeleteFilterItem}
|
||||
isResizeUpdate={this.isResizeUpdate}
|
||||
onRender={this.onFilterRender}
|
||||
onFilterRender={this.onFilterRender}
|
||||
isDisabled={isDisabled}
|
||||
columnCount={filterColumnCount}
|
||||
needUpdateFilter={this.state.needUpdateFilter}
|
||||
/>
|
||||
</div>
|
||||
</SearchInput>
|
||||
</div>
|
||||
|
||||
<SortComboBox
|
||||
options={getSortData()}
|
||||
isDisabled={isDisabled}
|
||||
onChangeSortId={this.onClickSortItem}
|
||||
onChangeView={this.onClickViewSelector}
|
||||
onChangeSortDirection={this.onChangeSortDirection}
|
||||
selectedOption={
|
||||
getSortData().length > 0
|
||||
? getSortData().find((x) => x.key === sortId)
|
||||
: {}
|
||||
}
|
||||
onButtonClick={this.onSortDirectionClick}
|
||||
viewAs={viewAs}
|
||||
sortDirection={+sortDirection}
|
||||
directionAscLabel={directionAscLabel}
|
||||
directionDescLabel={directionDescLabel}
|
||||
/>
|
||||
<div ref={this.rectComboBoxRef}>
|
||||
<SortComboBox
|
||||
options={getSortData()}
|
||||
isDisabled={isDisabled}
|
||||
onChangeSortId={this.onClickSortItem}
|
||||
onChangeView={this.onClickViewSelector}
|
||||
onChangeSortDirection={this.onChangeSortDirection}
|
||||
selectedOption={
|
||||
getSortData().length > 0
|
||||
? getSortData().find((x) => x.key === sortId)
|
||||
: {}
|
||||
}
|
||||
onButtonClick={this.onSortDirectionClick}
|
||||
viewAs={viewAs}
|
||||
sortDirection={+sortDirection}
|
||||
directionAscLabel={directionAscLabel}
|
||||
directionDescLabel={directionDescLabel}
|
||||
/>
|
||||
</div>
|
||||
{viewAs && (
|
||||
<ViewSelector
|
||||
isDisabled={isDisabled}
|
||||
@ -853,6 +845,9 @@ FilterInput.protoTypes = {
|
||||
filterColumnCount: PropTypes.number,
|
||||
onChangeViewAs: PropTypes.func,
|
||||
contextMenuHeader: PropTypes.string,
|
||||
sectionWidth: PropTypes.number,
|
||||
getSortData: PropTypes.func,
|
||||
value: PropTypes.string,
|
||||
};
|
||||
|
||||
FilterInput.defaultProps = {
|
||||
|
@ -107,7 +107,7 @@ const StyledFilterInput = styled.div`
|
||||
margin-left: 8px;
|
||||
|
||||
${(props) =>
|
||||
props.isMobile &&
|
||||
(props.isMobile || props.smallSectionWidth) &&
|
||||
`
|
||||
width: 50px;
|
||||
.optionalBlock ~ div:first-child{
|
||||
|
@ -39,6 +39,7 @@ class FilterItem extends React.Component {
|
||||
isOpen: false,
|
||||
isOpenSelector: !isOpenSelector,
|
||||
selectedOption,
|
||||
needUpdate: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -48,7 +49,6 @@ class FilterItem extends React.Component {
|
||||
if (
|
||||
selectedItem &&
|
||||
selectedItem.key !== this.state.selectedOption.key &&
|
||||
selectedItem.key !== this.state.selectedOption.key &&
|
||||
selectedItem.key !== prevProps.selectedItem.key
|
||||
) {
|
||||
const selectedOption = selectedItem.key
|
||||
@ -67,6 +67,11 @@ class FilterItem extends React.Component {
|
||||
selectedOption,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.needUpdate) {
|
||||
this.props.onFilterRender();
|
||||
this.setNeedUpdate(false);
|
||||
}
|
||||
}
|
||||
|
||||
onSelect = (option) => {
|
||||
@ -85,6 +90,12 @@ class FilterItem extends React.Component {
|
||||
|
||||
toggleCombobox = (e, isOpen) => this.setState({ isOpen });
|
||||
|
||||
setNeedUpdate = (needUpdate) => {
|
||||
this.setState({
|
||||
needUpdate,
|
||||
});
|
||||
};
|
||||
|
||||
onCancelSelector = (e) => {
|
||||
if (
|
||||
this.state.isOpenSelector &&
|
||||
@ -260,47 +271,64 @@ class FilterBlock extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const { hideFilterItems, openFilterItems } = props;
|
||||
const { hiddenFilterItems, openFilterItems } = props;
|
||||
|
||||
this.state = {
|
||||
hideFilterItems: hideFilterItems || [],
|
||||
hiddenFilterItems: hiddenFilterItems || [],
|
||||
openFilterItems: openFilterItems || [],
|
||||
needUpdate: false,
|
||||
};
|
||||
|
||||
this.throttledRender = throttle(this.onRender, 100);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.throttledRender();
|
||||
componentDidMount() {
|
||||
this.setNeedUpdate(true);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { needUpdate } = this.state;
|
||||
const { needUpdateFilter } = this.props;
|
||||
if (
|
||||
(needUpdate || needUpdateFilter) &&
|
||||
(!isEqual(prevState.openFilterItems, this.state.openFilterItems) ||
|
||||
!isEqual(prevState.hiddenFilterItems, this.state.hiddenFilterItems))
|
||||
) {
|
||||
this.props.onFilterRender();
|
||||
this.setNeedUpdate(false);
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { hideFilterItems, openFilterItems } = nextProps;
|
||||
const { hiddenFilterItems, openFilterItems } = nextProps;
|
||||
|
||||
if (!isEqual(this.props, nextProps)) {
|
||||
if (
|
||||
!isEqual(this.props.hideFilterItems, hideFilterItems) ||
|
||||
!isEqual(this.props.hiddenFilterItems, hiddenFilterItems) ||
|
||||
!isEqual(this.props.openFilterItems, openFilterItems)
|
||||
) {
|
||||
this.setState({
|
||||
hideFilterItems,
|
||||
hiddenFilterItems,
|
||||
openFilterItems,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (this.props.isResizeUpdate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !isEqual(this.state, nextState);
|
||||
}
|
||||
|
||||
onDeleteFilterItem = (key) => {
|
||||
this.props.onDeleteFilterItem(key);
|
||||
this.setNeedUpdate(true);
|
||||
};
|
||||
|
||||
setNeedUpdate = (needUpdate) => {
|
||||
this.setState({
|
||||
needUpdate,
|
||||
});
|
||||
};
|
||||
getFilterItems = () => {
|
||||
const { openFilterItems, hideFilterItems } = this.state;
|
||||
const { openFilterItems, hiddenFilterItems } = this.state;
|
||||
const _this = this;
|
||||
let result = [];
|
||||
let openItems = [];
|
||||
@ -339,13 +367,14 @@ class FilterBlock extends React.Component {
|
||||
defaultOption={defaultOption}
|
||||
defaultSelectLabel={defaultSelectLabel}
|
||||
selectedItem={selectedItem}
|
||||
onFilterRender={_this.props.onFilterRender}
|
||||
></FilterItem>
|
||||
);
|
||||
});
|
||||
}
|
||||
if (hideFilterItems.length > 0) {
|
||||
if (hiddenFilterItems.length > 0) {
|
||||
let open = false;
|
||||
let hideFilterItemsList = hideFilterItems.map(function (item) {
|
||||
let hideFilterItemsList = hiddenFilterItems.map(function (item) {
|
||||
const {
|
||||
key,
|
||||
group,
|
||||
@ -379,13 +408,14 @@ class FilterBlock extends React.Component {
|
||||
defaultOption={defaultOption}
|
||||
defaultSelectLabel={defaultSelectLabel}
|
||||
selectedItem={selectedItem}
|
||||
onFilterRender={_this.props.onFilterRender}
|
||||
></FilterItem>
|
||||
);
|
||||
});
|
||||
hideItems.push(
|
||||
<HideFilter
|
||||
key="hide-filter"
|
||||
count={hideFilterItems.length}
|
||||
count={hiddenFilterItems.length}
|
||||
isDisabled={this.props.isDisabled}
|
||||
open={open}
|
||||
>
|
||||
@ -420,9 +450,6 @@ class FilterBlock extends React.Component {
|
||||
return result;
|
||||
};
|
||||
|
||||
onRender = () => {
|
||||
this.props.onRender();
|
||||
};
|
||||
render() {
|
||||
const _this = this;
|
||||
const filterItems = this.getFilterItems();
|
||||
@ -453,10 +480,9 @@ class FilterBlock extends React.Component {
|
||||
}
|
||||
FilterBlock.propTypes = {
|
||||
getFilterData: PropTypes.func,
|
||||
hideFilterItems: PropTypes.array,
|
||||
hiddenFilterItems: PropTypes.array,
|
||||
iconSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
isDisabled: PropTypes.bool,
|
||||
isResizeUpdate: PropTypes.bool,
|
||||
onDeleteFilterItem: PropTypes.func,
|
||||
onRender: PropTypes.func,
|
||||
openFilterItems: PropTypes.array,
|
||||
|
@ -39,6 +39,7 @@ class HideFilter extends React.Component {
|
||||
className="styled-hide-filter"
|
||||
onClick={this.onClick.bind(this, !popoverOpen)}
|
||||
ref={this.ref}
|
||||
id="styled-hide-filter"
|
||||
>
|
||||
<StyledHideFilterButton id="PopoverLegacy" isDisabled={isDisabled}>
|
||||
{count}
|
||||
|
@ -107,3 +107,5 @@ export function showLoader() {
|
||||
document.body.classList.add("loading");
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
export { withLayoutSize } from "./withLayoutSize";
|
||||
|
15
web/ASC.Web.Common/src/utils/withLayoutSize.js
Normal file
15
web/ASC.Web.Common/src/utils/withLayoutSize.js
Normal file
@ -0,0 +1,15 @@
|
||||
import * as React from "react";
|
||||
import { utils } from "asc-web-components";
|
||||
const { Consumer } = utils.context;
|
||||
|
||||
export function withLayoutSize(Component) {
|
||||
return function LayoutSizeComponent(props) {
|
||||
return (
|
||||
<Consumer>
|
||||
{(context) => {
|
||||
return <Component {...props} {...context} />;
|
||||
}}
|
||||
</Consumer>
|
||||
);
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user