diff --git a/packages/asc-web-components/table-container/TableHeader.js b/packages/asc-web-components/table-container/TableHeader.js
index f2ba984836..6fdc7b12d8 100644
--- a/packages/asc-web-components/table-container/TableHeader.js
+++ b/packages/asc-web-components/table-container/TableHeader.js
@@ -14,6 +14,7 @@ import TableGroupMenu from "./TableGroupMenu";
const minColumnSize = 150;
const settingsSize = 24;
+const containerMargin = 25;
class TableHeader extends React.Component {
constructor(props) {
@@ -131,6 +132,8 @@ class TableHeader extends React.Component {
.filter((x) => x.key !== this.props.columns[columnIndex - 1].key)
.filter((x) => !x.defaultSize);
+ const defaultSize = this.props.columns[columnIndex - 1]?.defaultSize;
+
let index = this.props.columns.length;
while (index !== 0) {
index--;
@@ -140,7 +143,9 @@ class TableHeader extends React.Component {
if (isFind) {
const someItemById = document.getElementById("column_" + (index + 1));
- const columnSize = someItemById.clientWidth - minColumnSize;
+ const columnSize =
+ someItemById.clientWidth -
+ (defaultSize ? defaultSize : minColumnSize);
if (columnSize >= minColumnSize) {
return (gridTemplateColumns[index + 1] = columnSize + "px");
@@ -211,7 +216,6 @@ class TableHeader extends React.Component {
: document.getElementById("table-container");
const minSize = size.tablet;
- const containerMargin = 25;
if (
!container ||
@@ -227,8 +231,7 @@ class TableHeader extends React.Component {
: container.style.gridTemplateColumns.split(" ");
const containerWidth = +container.clientWidth;
- const newContainerWidth =
- containerWidth - this.getSubstring(checkboxSize) - 80 - settingsSize; // TODO: 80
+ const newContainerWidth = containerWidth - this.getSubstring(checkboxSize);
const oldWidth = tableContainer
.map((column) => this.getSubstring(column))
@@ -242,7 +245,6 @@ class TableHeader extends React.Component {
const isSingleTable = enableColumns.length > 0;
let str = "";
- let disableColumnWidth = 0;
if (tableContainer.length > 1) {
const gridTemplateColumns = [];
@@ -255,6 +257,7 @@ class TableHeader extends React.Component {
index == 0 ||
index == tableContainer.length - 1 ||
(column ? column.dataset.enable === "true" : item !== "0px");
+ const defaultSize = column && column.dataset.defaultSize;
const isActiveNow = item === "0px" && enable;
if (isActiveNow && column) activeColumnIndex = index;
@@ -265,21 +268,18 @@ class TableHeader extends React.Component {
this.getSubstring(gridTemplateColumns[1]) +
this.getSubstring(item) +
"px";
- } else if (
- item !== `${settingsSize}px` &&
- item !== checkboxSize &&
- item !== "80px"
- ) {
+ } else if (item !== `${settingsSize}px` && item !== checkboxSize) {
const percent = (this.getSubstring(item) / oldWidth) * 100;
if (index == 1) {
- const newItemWidth =
- (containerWidth * percent) / 100 + disableColumnWidth + "px";
+ const newItemWidth = (containerWidth * percent) / 100 + "px";
gridTemplateColumns.push(newItemWidth);
} else {
const newItemWidth =
percent === 0
- ? `${minColumnSize}px`
+ ? defaultSize
+ ? `${defaultSize}px`
+ : `${minColumnSize}px`
: (containerWidth * percent) / 100 + "px";
gridTemplateColumns.push(newItemWidth);
@@ -295,8 +295,14 @@ class TableHeader extends React.Component {
str = gridTemplateColumns.join(" ");
} else {
+ const defaultSize = this.props.columns.find((col) => col.defaultSize)
+ ?.defaultSize;
+
const column =
- (newContainerWidth * (isSingleTable ? 60 : 100)) / 100 + "px";
+ (newContainerWidth * (isSingleTable ? 60 : 100)) / 100 -
+ (defaultSize || 0) -
+ containerMargin +
+ "px";
const percent = 40 / enableColumns.length;
const otherColumns = (newContainerWidth * percent) / 100 + "px";
@@ -387,6 +393,7 @@ class TableHeader extends React.Component {
sorted={sorted}
sortBy={sortBy}
resizable={resizable}
+ defaultSize={column.defaultSize}
onMouseDown={this.onMouseDown}
/>
);
diff --git a/packages/asc-web-components/table-container/TableHeaderCell.js b/packages/asc-web-components/table-container/TableHeaderCell.js
index a79a8a61bd..1389d84f98 100644
--- a/packages/asc-web-components/table-container/TableHeaderCell.js
+++ b/packages/asc-web-components/table-container/TableHeaderCell.js
@@ -12,6 +12,7 @@ const TableHeaderCell = ({
resizable,
sortBy,
sorted,
+ defaultSize,
}) => {
const { title, enable, active, minWidth } = column;
@@ -35,6 +36,7 @@ const TableHeaderCell = ({
id={`column_${index + 1}`}
data-enable={enable}
data-min-width={minWidth}
+ data-default-size={defaultSize}
onClick={onClick}
>
@@ -73,6 +75,7 @@ TableHeaderCell.propTypes = {
resizable: PropTypes.bool,
sorted: PropTypes.bool,
sortBy: PropTypes.string,
+ defaultSize: PropTypes.number,
};
export default TableHeaderCell;
diff --git a/products/ASC.Files/Client/src/HOCs/withContent.js b/products/ASC.Files/Client/src/HOCs/withContent.js
index 4141012c3d..56724880f2 100644
--- a/products/ASC.Files/Client/src/HOCs/withContent.js
+++ b/products/ASC.Files/Client/src/HOCs/withContent.js
@@ -233,8 +233,17 @@ export default function withContent(WrappedContent) {
onFilesClick,
viewAs,
element,
+ isDesktop,
} = this.props;
- const { id, fileExst, updated, createdBy, access, fileStatus } = item;
+ const {
+ id,
+ fileExst,
+ updated,
+ createdBy,
+ access,
+ fileStatus,
+ href,
+ } = item;
const titleWithoutExt = getTitleWithoutExst(item);
@@ -259,6 +268,10 @@ export default function withContent(WrappedContent) {
? { noHover: true }
: { onClick: onFilesClick };
+ if (!isDesktop && !isTrashFolder) {
+ linkStyles.href = item.href;
+ }
+
const newItems = item.new || fileStatus === 2;
const showNew = !!newItems;
diff --git a/products/ASC.Files/Client/src/components/Article/Body/TreeFolders.js b/products/ASC.Files/Client/src/components/Article/Body/TreeFolders.js
index 09af6f6e9c..3d9bf6d76a 100644
--- a/products/ASC.Files/Client/src/components/Article/Body/TreeFolders.js
+++ b/products/ASC.Files/Client/src/components/Article/Body/TreeFolders.js
@@ -122,10 +122,10 @@ class TreeFolders extends React.Component {
iconUrl = "/static/images/cloud.services.onedrive.react.svg";
break;
case "kDrive":
- iconUrl = "/static/images/catalog.folder.react.svg";
+ iconUrl = "/static/images/cloud.services.kdrive.react.svg";
break;
case "Yandex":
- iconUrl = "/static/images/catalog.folder.react.svg";
+ iconUrl = "/static/images/cloud.services.yandex.react.svg";
break;
case "NextCloud":
iconUrl = "/static/images/cloud.services.nextcloud.react.svg";
@@ -134,7 +134,7 @@ class TreeFolders extends React.Component {
iconUrl = "/static/images/catalog.folder.react.svg";
break;
case "WebDav":
- iconUrl = "/static/images/catalog.folder.react.svg";
+ iconUrl = "/static/images/cloud.services.webdav.react.svg";
break;
default:
break;
diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js
index 316da0b9d3..acbeec583f 100644
--- a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js
+++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js
@@ -59,7 +59,6 @@ const FilesRowContent = ({
updatedDate,
fileOwner,
linkStyles,
- //onFilesClick,
badgesComponent,
isAdmin,
}) => {
@@ -90,7 +89,6 @@ const FilesRowContent = ({
fontWeight="600"
fontSize="15px"
target="_blank"
- href={item.href}
{...linkStyles}
color="#333"
isTextOverflow={true}
diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js
index bb8c55d288..1434f4a1d2 100644
--- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js
+++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js
@@ -10,7 +10,6 @@ const FileNameCell = ({ item, titleWithoutExt, linkStyles }) => {
title={titleWithoutExt}
fontWeight="600"
fontSize="13px"
- href={item.href}
{...linkStyles}
color="#333"
isTextOverflow
diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js
index 1ee4986a8f..39128fd3d8 100644
--- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js
+++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js
@@ -77,7 +77,6 @@ const FilesTileContent = ({
item,
titleWithoutExt,
linkStyles,
- onFilesClick,
badgesComponent,
}) => {
const { fileExst } = item;
@@ -97,7 +96,6 @@ const FilesTileContent = ({
fontWeight="600"
fontSize="14px"
target="_blank"
- href={item.href}
{...linkStyles}
color="#333"
isTextOverflow
diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js
index 8e6e910841..499e4ff712 100644
--- a/products/ASC.Files/Client/src/store/FilesStore.js
+++ b/products/ASC.Files/Client/src/store/FilesStore.js
@@ -339,7 +339,7 @@ class FilesStore {
if (!requestCounter) return;
requestCounter--;
- if (folderId === "@my" && !this.isInit) {
+ if (folderId === "@my" /* && !this.isInit */) {
setTimeout(() => {
return request();
}, 5000);
diff --git a/products/ASC.Files/Core/Model/BatchModel.cs b/products/ASC.Files/Core/Model/BatchModel.cs
index 0232ade5f1..453811461f 100644
--- a/products/ASC.Files/Core/Model/BatchModel.cs
+++ b/products/ASC.Files/Core/Model/BatchModel.cs
@@ -1,15 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.Generic;
using System.Text.Json;
-using System.Threading.Tasks;
using ASC.Api.Collections;
using ASC.Web.Files.Services.WCFService.FileOperations;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
-
namespace ASC.Files.Model
{
public class BaseBatchModel
@@ -37,88 +31,6 @@ namespace ASC.Files.Model
public bool DeleteAfter { get; set; }
public bool Immediately { get; set; }
}
-
-
- public class DeleteBatchModelBinder : BaseBatchModelBinder
- {
- public override Task BindModelAsync(ModelBindingContext bindingContext)
- {
- base.BindModelAsync(bindingContext);
- if (bindingContext == null)
- {
- throw new ArgumentNullException(nameof(bindingContext));
- }
-
- var baseResult = bindingContext.Result.Model as BaseBatchModel;
-
- var result = new DeleteBatchModel();
-
- result.FileIds = baseResult.FileIds;
- result.FolderIds = baseResult.FolderIds;
-
- var modelName = nameof(result.DeleteAfter);
- var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
-
- if (valueProviderResult != ValueProviderResult.None)
- {
- bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
- if (bool.TryParse(valueProviderResult.FirstValue, out var deleteAfter))
- {
- result.DeleteAfter = deleteAfter;
- }
- }
-
- modelName = nameof(result.Immediately);
- valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
-
- if (valueProviderResult != ValueProviderResult.None)
- {
- bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
- if (bool.TryParse(valueProviderResult.FirstValue, out var immediately))
- {
- result.Immediately = immediately;
- }
- }
-
- bindingContext.Result = ModelBindingResult.Success(result);
-
- return Task.CompletedTask;
- }
- }
-
- public class BaseBatchModelBinder : IModelBinder
- {
- public virtual Task BindModelAsync(ModelBindingContext bindingContext)
- {
- if (bindingContext == null)
- {
- throw new ArgumentNullException(nameof(bindingContext));
- }
-
- var result = new BaseBatchModel();
-
- result.FileIds = ParseQuery(bindingContext, nameof(result.FileIds));
- result.FolderIds = ParseQuery(bindingContext, nameof(result.FolderIds));
-
- bindingContext.Result = ModelBindingResult.Success(result);
-
- return Task.CompletedTask;
- }
-
- internal List
ParseQuery(ModelBindingContext bindingContext, string modelName)
- {
- var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
-
- if (valueProviderResult != ValueProviderResult.None)
- {
- bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
-
- return valueProviderResult.Select(BatchModel.ParseQueryParam).ToList();
- }
-
- return new List();
- }
- }
public class DeleteModel
{
@@ -130,74 +42,6 @@ namespace ASC.Files.Model
{
public JsonElement DestFolderId { get; set; }
public FileConflictResolveType ConflictResolveType { get; set; }
- public bool DeleteAfter { get; set; }
-
- public static BatchModel FromQuery(HttpContext httpContext)
- {
- var result = new BatchModel();
- var query = httpContext.Request.Query;
-
- var destId = query["DestFolderId"];
- if (destId.Any())
- {
- result.DestFolderId = ParseQueryParam(destId.First());
- }
-
- var conflictResolveType = query["ConflictResolveType"];
- if (conflictResolveType.Any())
- {
- if (Enum.TryParse(conflictResolveType.First(), out var crf))
- {
- result.ConflictResolveType = crf;
- }
- }
-
- var deleteAfter = query["DeleteAfter"];
- if (deleteAfter.Any())
- {
- if (bool.TryParse(deleteAfter.First(), out var d))
- {
- result.DeleteAfter = d;
- }
- }
-
- var fileIdsQuery = query["FileIds"];
- if (fileIdsQuery.Any())
- {
- var fileIds = new List();
-
- foreach (var f in fileIdsQuery)
- {
- fileIds.Add(ParseQueryParam(f));
- }
-
- result.FileIds = fileIds;
- }
-
- var folderIdsQuery = query["FolderIds"];
- if (folderIdsQuery.Any())
- {
- var folderIds = new List();
-
- foreach (var f in folderIdsQuery)
- {
- folderIds.Add(ParseQueryParam(f));
- }
-
- result.FolderIds = folderIds;
- }
-
- return result;
- }
-
- public static JsonElement ParseQueryParam(string data)
- {
- if (int.TryParse(data, out _))
- {
- return JsonSerializer.Deserialize(data);
- }
-
- return JsonSerializer.Deserialize($"\"{data}\"");
- }
+ public bool DeleteAfter { get; set; }
}
}
diff --git a/products/ASC.Files/Core/Model/Binders.cs b/products/ASC.Files/Core/Model/Binders.cs
new file mode 100644
index 0000000000..a0e908b1c2
--- /dev/null
+++ b/products/ASC.Files/Core/Model/Binders.cs
@@ -0,0 +1,159 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+using ASC.Web.Files.Services.WCFService.FileOperations;
+
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+
+namespace ASC.Files.Model
+{
+ public class BaseBatchModelBinder : IModelBinder
+ {
+ public virtual Task BindModelAsync(ModelBindingContext bindingContext)
+ {
+ if (bindingContext == null)
+ {
+ throw new ArgumentNullException(nameof(bindingContext));
+ }
+
+ var result = new BaseBatchModel();
+
+ result.FileIds = ParseQuery(bindingContext, nameof(result.FileIds));
+ result.FolderIds = ParseQuery(bindingContext, nameof(result.FolderIds));
+
+ bindingContext.Result = ModelBindingResult.Success(result);
+
+ return Task.CompletedTask;
+ }
+
+ internal List ParseQuery(ModelBindingContext bindingContext, string modelName)
+ {
+ var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
+
+ if (valueProviderResult != ValueProviderResult.None)
+ {
+ bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
+
+ return valueProviderResult.Select(ParseQueryParam).ToList();
+ }
+
+ return new List();
+ }
+
+ public static JsonElement ParseQueryParam(string data)
+ {
+ if (int.TryParse(data, out _))
+ {
+ return JsonSerializer.Deserialize(data);
+ }
+
+ return JsonSerializer.Deserialize($"\"{data}\"");
+ }
+ }
+
+ public class DeleteBatchModelBinder : BaseBatchModelBinder
+ {
+ public override Task BindModelAsync(ModelBindingContext bindingContext)
+ {
+ base.BindModelAsync(bindingContext);
+ if (bindingContext == null)
+ {
+ throw new ArgumentNullException(nameof(bindingContext));
+ }
+
+ var baseResult = bindingContext.Result.Model as BaseBatchModel;
+
+ var result = new DeleteBatchModel();
+
+ result.FileIds = baseResult.FileIds;
+ result.FolderIds = baseResult.FolderIds;
+
+ var modelName = nameof(result.DeleteAfter);
+ var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
+
+ if (valueProviderResult != ValueProviderResult.None)
+ {
+ bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
+ if (bool.TryParse(valueProviderResult.FirstValue, out var deleteAfter))
+ {
+ result.DeleteAfter = deleteAfter;
+ }
+ }
+
+ modelName = nameof(result.Immediately);
+ valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
+
+ if (valueProviderResult != ValueProviderResult.None)
+ {
+ bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
+ if (bool.TryParse(valueProviderResult.FirstValue, out var immediately))
+ {
+ result.Immediately = immediately;
+ }
+ }
+
+ bindingContext.Result = ModelBindingResult.Success(result);
+
+ return Task.CompletedTask;
+ }
+ }
+
+ public class BatchModelBinder : BaseBatchModelBinder
+ {
+ public override Task BindModelAsync(ModelBindingContext bindingContext)
+ {
+ base.BindModelAsync(bindingContext);
+ if (bindingContext == null)
+ {
+ throw new ArgumentNullException(nameof(bindingContext));
+ }
+
+ var baseResult = bindingContext.Result.Model as BaseBatchModel;
+
+ var result = new BatchModel();
+
+ result.FileIds = baseResult.FileIds;
+ result.FolderIds = baseResult.FolderIds;
+
+ var modelName = nameof(result.DeleteAfter);
+ var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
+
+ if (valueProviderResult != ValueProviderResult.None)
+ {
+ bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
+ if (bool.TryParse(valueProviderResult.FirstValue, out var deleteAfter))
+ {
+ result.DeleteAfter = deleteAfter;
+ }
+ }
+
+ modelName = nameof(result.ConflictResolveType);
+ valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
+
+ if (valueProviderResult != ValueProviderResult.None)
+ {
+ bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
+ if (Enum.TryParse(valueProviderResult.FirstValue, out var conflictResolveType))
+ {
+ result.ConflictResolveType = conflictResolveType;
+ }
+ }
+
+ modelName = nameof(result.DestFolderId);
+ valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
+
+ if (valueProviderResult != ValueProviderResult.None)
+ {
+ bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
+ result.DestFolderId = BaseBatchModelBinder.ParseQueryParam(valueProviderResult.FirstValue);
+ }
+
+ bindingContext.Result = ModelBindingResult.Success(result);
+
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/products/ASC.Files/Server/Controllers/FilesController.cs b/products/ASC.Files/Server/Controllers/FilesController.cs
index 2e3a8c13f4..78ed9900c9 100644
--- a/products/ASC.Files/Server/Controllers/FilesController.cs
+++ b/products/ASC.Files/Server/Controllers/FilesController.cs
@@ -1237,9 +1237,9 @@ namespace ASC.Api.Documents
/// File ID list
/// Conflicts file ids
[Read("fileops/move")]
- public IEnumerable MoveOrCopyBatchCheck()
+ public IEnumerable MoveOrCopyBatchCheck([ModelBinder(BinderType = typeof(BatchModelBinder))] BatchModel batchModel)
{
- return FilesControllerHelperString.MoveOrCopyBatchCheck(BatchModel.FromQuery(HttpContext));
+ return FilesControllerHelperString.MoveOrCopyBatchCheck(batchModel);
}
///
@@ -1261,7 +1261,7 @@ namespace ASC.Api.Documents
[Update("fileops/move")]
[Consumes("application/x-www-form-urlencoded")]
- public IEnumerable MoveBatchItemsFromForm([FromForm] BatchModel batchModel)
+ public IEnumerable MoveBatchItemsFromForm([FromForm][ModelBinder(BinderType = typeof(BatchModelBinder))] BatchModel batchModel)
{
return FilesControllerHelperString.MoveBatchItems(batchModel);
}
@@ -1285,7 +1285,7 @@ namespace ASC.Api.Documents
[Update("fileops/copy")]
[Consumes("application/x-www-form-urlencoded")]
- public IEnumerable CopyBatchItemsFromForm([FromForm] BatchModel batchModel)
+ public IEnumerable CopyBatchItemsFromForm([FromForm][ModelBinder(BinderType = typeof(BatchModelBinder))] BatchModel batchModel)
{
return FilesControllerHelperString.CopyBatchItems(batchModel);
}
diff --git a/public/images/cloud.services.kdrive.react.svg b/public/images/cloud.services.kdrive.react.svg
new file mode 100644
index 0000000000..503b279d03
--- /dev/null
+++ b/public/images/cloud.services.kdrive.react.svg
@@ -0,0 +1,10 @@
+
diff --git a/public/images/cloud.services.webdav.react.svg b/public/images/cloud.services.webdav.react.svg
new file mode 100644
index 0000000000..29a483bf19
--- /dev/null
+++ b/public/images/cloud.services.webdav.react.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/images/cloud.services.yandex.react.svg b/public/images/cloud.services.yandex.react.svg
new file mode 100644
index 0000000000..b411a8175b
--- /dev/null
+++ b/public/images/cloud.services.yandex.react.svg
@@ -0,0 +1,3 @@
+