Merge branch 'develop' into feature/action-buttons-hints

# Conflicts:
#	packages/client/public/locales/en/Files.json
#	packages/client/public/locales/ru/Files.json
#	packages/client/src/pages/Home/InfoPanel/Header/index.js
This commit is contained in:
Nikita Gopienko 2023-04-20 15:39:46 +03:00
commit 190fb7e5e7
27 changed files with 343 additions and 289 deletions

View File

@ -118,4 +118,6 @@
"MarkAsVersion": "Mark as version",
"MarkAsRevision": "Mark as revision",
"TableSettingsTitle": "Manage displayed columns"
"WithSubfolders": "With subfolders",
"DocumentEdited": "Cannot perform the action because the document is being edited."
}

View File

@ -117,4 +117,6 @@
"WithSubfolders": "С подпапками",
"MarkAsVersion": "Отметить как версию",
"MarkAsRevision": "Отметить как ревизию"
"WithSubfolders": "С подпапками",
"DocumentEdited": "Невозможно выполнить действие, так как документ редактируется."
}

View File

@ -101,3 +101,19 @@ export const DEFAULT_SELECT_LANGUAGE = {
label: "English (United States)",
icon: EnUSReactSvgUrl,
};
/**
* Enum for sort by field name
* @readonly
*/
export const SortByFieldName = Object.freeze({
Name: "AZ",
ModifiedDate: "DateAndTime",
CreationDate: "DateAndTimeCreation",
Author: "Author",
Size: "Size",
Type: "Type",
Room: "Room",
Tags: "Tags",
RoomType: "roomType",
});

View File

@ -16,28 +16,28 @@ import i18n from "./i18n";
import { request } from "@docspace/common/api/client";
export const getFileTypeName = (fileType, t) => {
export const getFileTypeName = (fileType) => {
switch (fileType) {
case FileType.Unknown:
return t("Common:Unknown");
return i18n.t("Common:Unknown");
case FileType.Archive:
return t("Common:Archive");
return i18n.t("Common:Archive");
case FileType.Video:
return t("Common:Video");
return i18n.t("Common:Video");
case FileType.Audio:
return t("Common:Audio");
return i18n.t("Common:Audio");
case FileType.Image:
return t("Common:Image");
return i18n.t("Common:Image");
case FileType.Spreadsheet:
return t("Files:Spreadsheet");
return i18n.t("Files:Spreadsheet");
case FileType.Presentation:
return t("Files:Presentation");
return i18n.t("Files:Presentation");
case FileType.Document:
case FileType.OFormTemplate:
case FileType.OForm:
return t("Files:Document");
return i18n.t("Files:Document");
default:
return t("Files:Folder");
return i18n.t("Files:Folder");
}
};

View File

@ -103,11 +103,14 @@ const PeopleRowContainer = ({
isLoading,
}) => {
useEffect(() => {
const width = window.innerWidth;
if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return;
// 400 - it is desktop info panel width
if (
(sectionWidth < 1025 && !infoPanelVisible) ||
((sectionWidth < 625 || (viewAs === "row" && sectionWidth < 1025)) &&
(width < 1025 && !infoPanelVisible) ||
((width < 625 || (viewAs === "row" && width < 1025)) &&
infoPanelVisible) ||
isMobile
) {

View File

@ -111,13 +111,16 @@ const Table = ({
canChangeUserType,
}) => {
const ref = useRef(null);
const [hideColumns, setHideColumns] = React.useState(false);
useEffect(() => {
const width = window.innerWidth;
if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return;
// 400 - it is desktop info panel width
if (
(sectionWidth < 1025 && !infoPanelVisible) ||
((sectionWidth < 625 || (viewAs === "row" && sectionWidth < 1025)) &&
(width < 1025 && !infoPanelVisible) ||
((width < 625 || (viewAs === "row" && width < 1025)) &&
infoPanelVisible) ||
isMobile
) {
@ -139,6 +142,7 @@ const Table = ({
columnInfoPanelStorageName={columnInfoPanelStorageName}
sectionWidth={sectionWidth}
containerRef={ref}
setHideColumns={setHideColumns}
/>
<TableBody
infoPanelVisible={infoPanelVisible}
@ -161,6 +165,7 @@ const Table = ({
changeUserType={changeType}
userId={userId}
canChangeUserType={canChangeUserType}
hideColumns={hideColumns}
/>
))}
</TableBody>

View File

@ -140,6 +140,7 @@ class PeopleTableHeader extends React.Component {
columnStorageName,
columnInfoPanelStorageName,
withPaging,
setHideColumns
} = this.props;
const { sortOrder } = filter;
@ -161,6 +162,7 @@ class PeopleTableHeader extends React.Component {
checkboxMargin="12px"
infoPanelVisible={infoPanelVisible}
useReactWindow={!withPaging}
setHideColumns={setHideColumns}
/>
);
}

View File

@ -76,6 +76,15 @@ const StyledPeopleRow = styled(TableRow)`
margin-left: -8px;
}
.type-combobox {
visibility: ${(props) => (props.hideColumns ? "hidden" : "visible")};
opacity: ${(props) => (props.hideColumns ? 0 : 1)};
& > div {
max-width: fit-content;
}
}
.type-combobox,
.room-combobox {
padding-left: 8px;
@ -129,6 +138,7 @@ const PeopleTableRow = (props) => {
isActive,
isSeveralSelection,
canChangeUserType,
hideColumns,
} = props;
const {
@ -257,7 +267,7 @@ const PeopleTableRow = (props) => {
}
options={typesOptions}
onSelect={onTypeChange}
scaled={false}
scaled
size="content"
displaySelectedOption
modernView
@ -330,6 +340,7 @@ const PeopleTableRow = (props) => {
isActive={isActive}
onClick={onRowClick}
fileContextClick={onRowContextClick}
hideColumns={hideColumns}
{...contextOptionsProps}
>
<TableCell className={"table-container_user-name-cell"}>

View File

@ -29,6 +29,9 @@ import toastr from "@docspace/components/toast/toastr";
import withPeopleLoader from "SRC_DIR/HOCs/withPeopleLoader";
import { EmployeeType } from "@docspace/common/constants";
import { resendInvitesAgain } from "@docspace/common/api/people";
import { ColorTheme, ThemeType } from "@docspace/common/components/ColorTheme";
const StyledContainer = styled.div`
width: 100%;
@ -48,7 +51,7 @@ const StyledContainer = styled.div`
}
${isMobile &&
css`
css`
height: 60px;
margin: 0 0 0 -16px;
width: calc(100% + 32px);
@ -61,7 +64,7 @@ const StyledContainer = styled.div`
}
${isMobileOnly &&
css`
css`
height: 52px;
margin: 0 0 0 -16px;
width: calc(100% + 32px);
@ -86,7 +89,7 @@ const StyledContainer = styled.div`
}
${isMobile &&
css`
css`
grid-template-columns: 1fr auto;
`}
@ -99,7 +102,7 @@ const StyledContainer = styled.div`
}
${isMobile &&
css`
css`
line-height: 28px;
`}
@ -108,7 +111,7 @@ const StyledContainer = styled.div`
}
${isMobile &&
css`
css`
line-height: 24px;
`}
}
@ -121,7 +124,7 @@ const StyledContainer = styled.div`
}
${isMobile &&
css`
css`
display: none;
`}
}
@ -130,27 +133,9 @@ const StyledContainer = styled.div`
StyledContainer.defaultProps = { theme: Base };
const StyledInfoPanelToggleWrapper = styled.div`
display: flex;
const StyledInfoPanelToggleColorThemeWrapper = styled(ColorTheme)`
margin-left: auto;
@media ${tablet} {
display: none;
}
align-items: center;
justify-content: center;
.info-panel-toggle-bg {
height: 32px;
width: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
margin-bottom: 1px;
}
padding: 0;
`;
const SectionHeaderContent = (props) => {
@ -235,8 +220,8 @@ const SectionHeaderContent = (props) => {
.catch((err) => toastr.error(err));
}, [resendInvitesAgain]);
const onSetInfoPanelVisible = () => {
setInfoPanelIsVisible(true);
const infoPanelVisibleToggle = () => {
setInfoPanelIsVisible(!isInfoPanelVisible);
};
const getContextOptions = () => {
@ -306,7 +291,7 @@ const SectionHeaderContent = (props) => {
isIndeterminate={isHeaderIndeterminate}
headerMenu={headerMenu}
isInfoPanelVisible={isInfoPanelVisible}
toggleInfoPanel={onSetInfoPanelVisible}
toggleInfoPanel={infoPanelVisibleToggle}
withoutInfoPanelToggler={false}
/>
</div>
@ -330,22 +315,23 @@ const SectionHeaderContent = (props) => {
getData={getContextOptions}
isDisabled={false}
/>
{!isInfoPanelVisible && (
<StyledInfoPanelToggleWrapper>
{!(isTablet() || isSmallTablet() || !isDesktop()) && (
<div className="info-panel-toggle-bg">
<IconButton
id="info-panel-toggle--open"
className="info-panel-toggle"
iconName={PanelReactSvgUrl}
size="16"
isFill={true}
onClick={onSetInfoPanelVisible}
/>
</div>
)}
</StyledInfoPanelToggleWrapper>
)}
<StyledInfoPanelToggleColorThemeWrapper
themeId={ThemeType.InfoPanelToggle}
isInfoPanelVisible={isInfoPanelVisible}
>
{!(isTablet() || isSmallTablet() || !isDesktop()) && (
<div className="info-panel-toggle-bg">
<IconButton
id="info-panel-toggle"
className="info-panel-toggle"
iconName={PanelReactSvgUrl}
size="16"
isFill={true}
onClick={infoPanelVisibleToggle}
/>
</div>
)}
</StyledInfoPanelToggleColorThemeWrapper>
</>
</div>
)}

View File

@ -241,7 +241,7 @@ class DetailsHelper {
return text(
this.item.isRoom
? getDefaultRoomName(this.item.roomType, this.t)
: getFileTypeName(this.item.fileType, this.t)
: getFileTypeName(this.item.fileType)
);
};

View File

@ -1,4 +1,4 @@
import PanelReactSvgUrl from "PUBLIC_DIR/images/panel.react.svg?url";
import CrossReactSvgUrl from "PUBLIC_DIR/images/cross.react.svg?url";
import React, { useState, useEffect } from "react";
import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
@ -106,26 +106,19 @@ const InfoPanelHeaderContent = (props) => {
{t("Common:Info")}
</Text>
<ColorTheme
{...props}
themeId={ThemeType.InfoPanelToggle}
isRootFolder={true}
isInfoPanelVisible={true}
>
{!isTablet && (
<div className="info-panel-toggle-bg">
<IconButton
id="info-panel-toggle--close"
className="info-panel-toggle"
iconName={PanelReactSvgUrl}
size="16"
isFill={true}
onClick={closeInfoPanel}
title={t("Common:InfoPanel")}
/>
</div>
)}
</ColorTheme>
{!isTablet && (
<div className="info-panel-toggle-bg">
<IconButton
id="info-panel-toggle--close"
className="info-panel-toggle"
iconName={CrossReactSvgUrl}
size="16"
isFill={true}
onClick={closeInfoPanel}
title={t("Common:InfoPanel")}
/>
</div>
)}
</div>
{withSubmenu && (

View File

@ -46,6 +46,11 @@ const StyledInfoPanelHeader = styled.div`
margin-left: 20px;
}
}
.info-panel-toggle-bg{
padding-right: 20px;
}
.submenu {
display: flex;
width: 100%;

View File

@ -13,7 +13,7 @@ const StyledRowContainer = styled(RowContainer)`
.row-selected {
.files-row {
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
margin-top: -1px;
padding-top: 0px;
padding-bottom: 1px;
@ -24,7 +24,7 @@ const StyledRowContainer = styled(RowContainer)`
.row-selected + .row-wrapper:not(.row-selected) {
.files-row {
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
margin-top: -3px;
${marginStyles}
}
@ -35,7 +35,7 @@ const StyledRowContainer = styled(RowContainer)`
+ .row-selected {
.files-row {
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
margin-top: -3px;
${marginStyles}
}
@ -50,7 +50,7 @@ const StyledRowContainer = styled(RowContainer)`
.row-selected:last-child {
.files-row {
border-bottom: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
${marginStyles}
}
.files-row::after {
@ -60,7 +60,7 @@ const StyledRowContainer = styled(RowContainer)`
.row-selected:first-child {
.files-row {
border-top: ${(props) =>
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
`1px ${props.theme.filesSection.tableView.row.borderColor} solid`};
margin-top: -2px;
padding-top: 1px;
padding-bottom: 1px;
@ -86,11 +86,14 @@ const FilesRowContainer = ({
highlightFile,
}) => {
useEffect(() => {
const width = window.innerWidth;
if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return;
// 400 - it is desktop info panel width
if (
(sectionWidth < 1025 && !infoPanelVisible) ||
((sectionWidth < 625 || (viewAs === "row" && sectionWidth < 1025)) &&
(width < 1025 && !infoPanelVisible) ||
((width < 625 || (viewAs === "row" && width < 1025)) &&
infoPanelVisible) ||
isMobile
) {

View File

@ -1,9 +1,8 @@
import React, { useCallback } from "react";
import React from "react";
import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
import styled, { css } from "styled-components";
import { isMobile, isTablet, isMobileOnly } from "react-device-detect";
import moment from "moment";
import Link from "@docspace/components/link";
import Text from "@docspace/components/text";
@ -14,6 +13,8 @@ import withBadges from "../../../../../HOCs/withBadges";
import { Base } from "@docspace/components/themes";
import { RoomsTypeTranslations } from "@docspace/common/constants";
import { desktop } from "@docspace/components/utils/device";
import { getFileTypeName } from "../../../../../helpers/filesUtils";
import { SortByFieldName } from "../../../../../helpers/constants";
const SimpleFilesRowContent = styled(RowContent)`
.row-main-container-wrapper {
@ -100,21 +101,53 @@ const FilesRowContent = ({
theme,
isRooms,
isTrashFolder,
filterSortBy,
createdDate,
fileOwner,
}) => {
const {
contentLength,
fileExst,
filesCount,
foldersCount,
autoDelete,
providerKey,
title,
isRoom,
daysRemaining,
viewAccessability,
fileType,
tags,
} = item;
const isMedia = viewAccessability?.ImageView || viewAccessability?.MediaView;
const contentComponent = () => {
switch (filterSortBy) {
case SortByFieldName.Size:
if (!contentLength) return "—";
return contentLength;
case SortByFieldName.CreationDate:
return createdDate;
case SortByFieldName.Author:
return fileOwner;
case SortByFieldName.Type:
return getFileTypeName(fileType);
case SortByFieldName.Tags:
if (tags?.length === 0) return "—";
return tags?.map((elem) => {
return elem;
});
default:
if (isTrashFolder)
return t("Files:DaysRemaining", {
daysRemaining,
});
return updatedDate;
}
};
return (
<>
@ -122,6 +155,7 @@ const FilesRowContent = ({
sectionWidth={sectionWidth}
isMobile={isMobile}
isFile={fileExst || contentLength}
sideColor={theme.filesSection.rowView.sideColor}
>
<Link
className="row-content-link"
@ -146,14 +180,9 @@ const FilesRowContent = ({
containerWidth="15%"
fontSize="12px"
fontWeight={400}
// color={sideColor}
className="row_update-text"
>
{isTrashFolder
? t("Files:DaysRemaining", {
daysRemaining,
})
: updatedDate && updatedDate}
{contentComponent()}
</Text>
<Text
@ -180,9 +209,19 @@ const FilesRowContent = ({
);
};
export default inject(({ auth, treeFoldersStore }) => {
const { isRecycleBinFolder } = treeFoldersStore;
return { theme: auth.settingsStore.theme, isTrashFolder: isRecycleBinFolder };
export default inject(({ auth, treeFoldersStore, filesStore }) => {
const { filter, roomsFilter } = filesStore;
const { isRecycleBinFolder, isRoomsFolder, isArchiveFolder } =
treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
const filterSortBy = isRooms ? roomsFilter.sortBy : filter.sortBy;
return {
filterSortBy,
theme: auth.settingsStore.theme,
isTrashFolder: isRecycleBinFolder,
};
})(
observer(
withTranslation(["Files", "Translations"])(

View File

@ -90,7 +90,7 @@ const StyledTableContainer = styled(TableContainer)`
.table-container_file-name-cell,
.table-container_row-context-menu-wrapper {
border-bottom: ${(props) =>
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
}
}
}
@ -129,11 +129,14 @@ const Table = ({
const tagRef = useRef(null);
useEffect(() => {
const width = window.innerWidth;
if ((viewAs !== "table" && viewAs !== "row") || !setViewAs) return;
// 400 - it is desktop info panel width
if (
(sectionWidth < 1025 && !infoPanelVisible) ||
((sectionWidth < 625 || (viewAs === "row" && sectionWidth < 1025)) &&
(width < 1025 && !infoPanelVisible) ||
((width < 625 || (viewAs === "row" && width < 1025)) &&
infoPanelVisible) ||
isMobile
) {

View File

@ -3,6 +3,7 @@ import TableHeader from "@docspace/components/table-container/TableHeader";
import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
import { Events } from "@docspace/common/constants";
import { SortByFieldName } from "../../../../../helpers/constants";
class FilesTableHeader extends React.Component {
constructor(props) {
@ -33,7 +34,7 @@ class FilesTableHeader extends React.Component {
resizable: true,
enable: this.props.roomColumnNameIsEnabled,
default: true,
sortBy: "AZ",
sortBy: SortByFieldName.Name,
minWidth: 210,
onClick: this.onRoomsFilter,
},
@ -42,7 +43,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Type"),
enable: this.props.roomColumnTypeIsEnabled,
resizable: true,
sortBy: "roomType",
sortBy: SortByFieldName.RoomType,
onChange: this.onColumnChange,
onClick: this.onRoomsFilter,
},
@ -51,7 +52,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Tags"),
enable: this.props.roomColumnTagsIsEnabled,
resizable: true,
sortBy: "Tags",
sortBy: SortByFieldName.Tags,
withTagRef: true,
onChange: this.onColumnChange,
onClick: this.onRoomsFilter,
@ -61,7 +62,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Owner"),
enable: this.props.roomColumnOwnerIsEnabled,
resizable: true,
sortBy: "Author",
sortBy: SortByFieldName.Author,
onChange: this.onColumnChange,
onClick: this.onRoomsFilter,
},
@ -70,7 +71,7 @@ class FilesTableHeader extends React.Component {
title: t("ByLastModified"),
enable: this.props.roomColumnActivityIsEnabled,
resizable: true,
sortBy: "DateAndTime",
sortBy: SortByFieldName.ModifiedDate,
onChange: this.onColumnChange,
onClick: this.onRoomsFilter,
},
@ -84,7 +85,7 @@ class FilesTableHeader extends React.Component {
resizable: true,
enable: this.props.nameColumnIsEnabled,
default: true,
sortBy: "AZ",
sortBy: SortByFieldName.Name,
minWidth: 210,
onClick: this.onFilter,
},
@ -93,7 +94,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Room"),
enable: this.props.roomColumnIsEnabled,
resizable: true,
sortBy: "Room",
sortBy: SortByFieldName.Room,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -102,7 +103,7 @@ class FilesTableHeader extends React.Component {
title: t("ByAuthor"),
enable: this.props.authorTrashColumnIsEnabled,
resizable: true,
sortBy: "Author",
sortBy: SortByFieldName.Author,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -111,7 +112,7 @@ class FilesTableHeader extends React.Component {
title: t("ByCreation"),
enable: this.props.createdTrashColumnIsEnabled,
resizable: true,
sortBy: "DateAndTimeCreation",
sortBy: SortByFieldName.CreationDate,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -120,7 +121,7 @@ class FilesTableHeader extends React.Component {
title: t("ByErasure"),
enable: this.props.erasureColumnIsEnabled,
resizable: true,
sortBy: "DateAndTime",
sortBy: SortByFieldName.ModifiedDate,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -129,7 +130,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Size"),
enable: this.props.sizeTrashColumnIsEnabled,
resizable: true,
sortBy: "Size",
sortBy: SortByFieldName.Size,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -138,7 +139,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Type"),
enable: this.props.typeTrashColumnIsEnabled,
resizable: true,
sortBy: "Type",
sortBy: SortByFieldName.Type,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -159,7 +160,7 @@ class FilesTableHeader extends React.Component {
resizable: true,
enable: this.props.nameColumnIsEnabled,
default: true,
sortBy: "AZ",
sortBy: SortByFieldName.Name,
minWidth: 210,
onClick: this.onFilter,
},
@ -168,7 +169,7 @@ class FilesTableHeader extends React.Component {
title: t("ByAuthor"),
enable: this.props.authorColumnIsEnabled,
resizable: true,
sortBy: "Author",
sortBy: SortByFieldName.Author,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -177,7 +178,7 @@ class FilesTableHeader extends React.Component {
title: t("ByCreation"),
enable: this.props.createdColumnIsEnabled,
resizable: true,
sortBy: "DateAndTimeCreation",
sortBy: SortByFieldName.CreationDate,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -186,7 +187,7 @@ class FilesTableHeader extends React.Component {
title: t("ByLastModified"),
enable: this.props.modifiedColumnIsEnabled,
resizable: true,
sortBy: "DateAndTime",
sortBy: SortByFieldName.ModifiedDate,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -195,7 +196,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Size"),
enable: this.props.sizeColumnIsEnabled,
resizable: true,
sortBy: "Size",
sortBy: SortByFieldName.Size,
onClick: this.onFilter,
onChange: this.onColumnChange,
},
@ -204,7 +205,7 @@ class FilesTableHeader extends React.Component {
title: t("Common:Type"),
enable: this.props.typeColumnIsEnabled,
resizable: true,
sortBy: "Type",
sortBy: SortByFieldName.Type,
onClick: this.onFilter,
onChange: this.onColumnChange,
},

View File

@ -27,6 +27,8 @@ import { getDefaultRoomName } from "@docspace/client/src/helpers/filesUtils";
import withLoader from "../../../../HOCs/withLoader";
import { TableVersions } from "SRC_DIR/helpers/constants";
import { SortByFieldName } from "../../../../helpers/constants";
import { showLoader, hideLoader } from "./FilterUtils";
const getFilterType = (filterValues) => {
@ -1078,67 +1080,67 @@ const SectionFilterContent = ({
const name = {
id: "sort-by_name",
key: "AZ",
key: SortByFieldName.Name,
label: t("Common:Name"),
default: true,
};
const modifiedDate = {
id: "sort-by_modified",
key: "DateAndTime",
key: SortByFieldName.ModifiedDate,
label: t("Common:LastModifiedDate"),
default: true,
};
const room = {
id: "sort-by_room",
key: "Room",
key: SortByFieldName.Room,
label: t("Common:Room"),
default: true,
};
const authorOption = {
id: "sort-by_author",
key: "Author",
key: SortByFieldName.Author,
label: t("ByAuthor"),
default: true,
};
const creationDate = {
id: "sort-by_created",
key: "DateAndTimeCreation",
key: SortByFieldName.CreationDate,
label: t("InfoPanel:CreationDate"),
default: true,
};
const owner = {
id: "sort-by_owner",
key: "Author",
key: SortByFieldName.Author,
label: t("Common:Owner"),
default: true,
};
const erasure = {
id: "sort-by_erasure",
key: "DateAndTime",
key: SortByFieldName.ModifiedDate,
label: t("ByErasure"),
default: true,
};
const tags = {
id: "sort-by_tags",
key: "Tags",
key: SortByFieldName.Tags,
label: t("Common:Tags"),
default: true,
};
const size = {
id: "sort-by_size",
key: "Size",
key: SortByFieldName.Size,
label: t("Common:Size"),
default: true,
};
const type = {
id: "sort-by_type",
key: "Type",
key: SortByFieldName.Type,
label: t("Common:Type"),
default: true,
};
const roomType = {
id: "sort-by_room-type",
key: "roomType",
key: SortByFieldName.RoomType,
label: t("Common:Type"),
default: true,
};

View File

@ -332,7 +332,7 @@ const SectionHeaderContent = (props) => {
)}
</div>
</Headline>
{addUsers && (
{props.addUsers && (
<div className="action-wrapper">
<IconButton
iconName={ActionsHeaderTouchReactSvgUrl}

View File

@ -14,6 +14,7 @@ import { objectToGetParams, loadScript } from "@docspace/common/utils";
import { inject, observer } from "mobx-react";
import { isMobile } from "react-device-detect";
import BreakpointWarning from "SRC_DIR/components/BreakpointWarning";
import { SortByFieldName } from "../../../../helpers/constants";
const Controls = styled(Box)`
width: 500px;
@ -81,12 +82,16 @@ const PortalIntegration = (props) => {
const scriptUrl = `${window.location.origin}/static/scripts/api.js`;
const dataSortBy = [
{ key: "DateAndTime", label: t("Common:LastModifiedDate"), default: true },
{ key: "AZ", label: t("Common:Title") },
{ key: "Type", label: t("Common:Type") },
{ key: "Size", label: t("Common:Size") },
{ key: "DateAndTimeCreation", label: t("Files:ByCreation") },
{ key: "Author", label: t("Files:ByAuthor") },
{
key: SortByFieldName.ModifiedDate,
label: t("Common:LastModifiedDate"),
default: true,
},
{ key: SortByFieldName.Name, label: t("Common:Title") },
{ key: SortByFieldName.Type, label: t("Common:Type") },
{ key: SortByFieldName.Size, label: t("Common:Size") },
{ key: SortByFieldName.CreationDate, label: t("Files:ByCreation") },
{ key: SortByFieldName.Author, label: t("Files:ByAuthor") },
];
const dataSortOrder = [

View File

@ -1,4 +1,4 @@
import HistoryReactSvgUrl from "PUBLIC_DIR/images/history.react.svg?url";
import HistoryReactSvgUrl from "PUBLIC_DIR/images/history.react.svg?url";
import HistoryFinalizedReactSvgUrl from "PUBLIC_DIR/images/history-finalized.react.svg?url";
import MoveReactSvgUrl from "PUBLIC_DIR/images/move.react.svg?url";
import CheckBoxReactSvgUrl from "PUBLIC_DIR/images/check-box.react.svg?url";
@ -608,6 +608,10 @@ class ContextOptionsStore {
onSelectItem({ id: item.id, isFolder: item.isFolder }, true, false);
};
onShowEditingToast = (t) => {
toastr.error(t("Files:DocumentEdited"));
};
onClickMute = (e, item, t) => {
const data = (e.currentTarget && e.currentTarget.dataset) || e;
const { action } = data;
@ -670,7 +674,7 @@ class ContextOptionsStore {
return { pinOptions, muteOptions };
};
getFilesContextOptions = (item, t, isInfoPanel) => {
const { contextOptions } = item;
const { contextOptions, isEditing } = item;
const { enablePlugins } = this.authStore.settingsStore;
@ -723,7 +727,10 @@ class ContextOptionsStore {
key: "finalize-version",
label: t("FinalizeVersion"),
icon: HistoryFinalizedReactSvgUrl,
onClick: () => this.finalizeVersion(item.id, item.security),
onClick: () =>
isEditing
? this.onShowEditingToast(t)
: this.finalizeVersion(item.id, item.security),
disabled: false,
},
{
@ -744,7 +751,10 @@ class ContextOptionsStore {
key: "finalize-version",
label: t("FinalizeVersion"),
icon: HistoryFinalizedReactSvgUrl,
onClick: () => this.finalizeVersion(item.id),
onClick: () =>
isEditing
? this.onShowEditingToast(t)
: this.finalizeVersion(item.id),
disabled: false,
},
{
@ -770,7 +780,9 @@ class ContextOptionsStore {
key: "move-to",
label: t("MoveTo"),
icon: MoveReactSvgUrl,
onClick: this.onMoveAction,
onClick: isEditing
? () => this.onShowEditingToast(t)
: this.onMoveAction,
disabled: false,
},
{
@ -798,7 +810,9 @@ class ContextOptionsStore {
key: "move-to",
label: t("MoveTo"),
icon: MoveReactSvgUrl,
onClick: this.onMoveAction,
onClick: isEditing
? () => this.onShowEditingToast(t)
: this.onMoveAction,
disabled: false,
},
{
@ -1093,7 +1107,8 @@ class ContextOptionsStore {
? t("Common:Disconnect")
: t("Common:Delete"),
icon: TrashReactSvgUrl,
onClick: () => this.onClickDelete(item, t),
onClick: () =>
isEditing ? this.onShowEditingToast(t) : this.onClickDelete(item, t),
disabled: false,
},
];
@ -1138,7 +1153,7 @@ class ContextOptionsStore {
getGroupContextOptions = (t) => {
const { personal } = this.authStore.settingsStore;
const { selection } = this.filesStore;
const { selection, allFilesIsEditing } = this.filesStore;
const { setDeleteDialogVisible } = this.dialogsStore;
const {
isRecycleBinFolder,
@ -1146,12 +1161,7 @@ class ContextOptionsStore {
isArchiveFolder,
} = this.treeFoldersStore;
const {
pinRooms,
unpinRooms,
deleteRooms,
} = this.filesActionsStore;
const { pinRooms, unpinRooms, deleteRooms } = this.filesActionsStore;
if (isRoomsFolder || isArchiveFolder) {
const isPinOption = selection.filter((item) => !item.pinned).length > 0;
@ -1330,7 +1340,9 @@ class ContextOptionsStore {
key: "move-to",
label: t("MoveTo"),
icon: MoveReactSvgUrl,
onClick: this.onMoveAction,
onClick: allFilesIsEditing
? () => this.onShowEditingToast(t)
: this.onMoveAction,
disabled: isRecycleBinFolder || !moveItems,
},
{
@ -1356,23 +1368,25 @@ class ContextOptionsStore {
key: "delete",
label: t("Common:Delete"),
icon: TrashReactSvgUrl,
onClick: () => {
if (this.settingsStore.confirmDelete) {
setDeleteDialogVisible(true);
} else {
const translations = {
deleteOperation: t("Translations:DeleteOperation"),
deleteFromTrash: t("Translations:DeleteFromTrash"),
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
FileRemoved: t("Files:FileRemoved"),
FolderRemoved: t("Files:FolderRemoved"),
};
onClick: allFilesIsEditing
? () => this.onShowEditingToast(t)
: () => {
if (this.settingsStore.confirmDelete) {
setDeleteDialogVisible(true);
} else {
const translations = {
deleteOperation: t("Translations:DeleteOperation"),
deleteFromTrash: t("Translations:DeleteFromTrash"),
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
FileRemoved: t("Files:FileRemoved"),
FolderRemoved: t("Files:FolderRemoved"),
};
this.filesActionsStore
.deleteAction(translations)
.catch((err) => toastr.error(err));
}
},
this.filesActionsStore
.deleteAction(translations)
.catch((err) => toastr.error(err));
}
},
disabled: !deleteItems || isRootThirdPartyFolder,
},
];

View File

@ -1530,10 +1530,7 @@ class FilesStore {
const canConvert = this.filesSettingsStore.extsConvertible[item.fileExst];
const isEncrypted = item.encrypted;
const isDocuSign = false; //TODO: need this prop;
const isEditing =
(item.fileStatus & FileStatus.IsEditing) === FileStatus.IsEditing;
// const isFileOwner =
// item.createdBy?.id === this.authStore.userStore.user?.id;
const isEditing = false; // (item.fileStatus & FileStatus.IsEditing) === FileStatus.IsEditing;
const { isRecycleBinFolder, isMy, isArchiveFolder } = this.treeFoldersStore;

View File

@ -2,8 +2,8 @@ import styled, { css } from "styled-components";
import StyledInfoPanelToggleWrapper from "../../StyledInfoPanelToggleWrapper";
import Base from "@docspace/components/themes/base";
const getDefaultStyles = ({ $currentColorScheme }) =>
$currentColorScheme &&
const getDefaultStyles = ({ $currentColorScheme, isInfoPanelVisible }) =>
$currentColorScheme && isInfoPanelVisible &&
css`
.info-panel-toggle-bg {
path {

View File

@ -2,48 +2,24 @@ import React from "react";
import styled, { css } from "styled-components";
import PanelReactSvgUrl from "PUBLIC_DIR/images/panel.react.svg?url";
import IconButton from "@docspace/components/icon-button";
import { isMobile } from "react-device-detect";
import { tablet } from "@docspace/components/utils/device";
import { Base } from "@docspace/components/themes";
import { ColorTheme, ThemeType } from "../../ColorTheme";
const StyledInfoPanelToggleWrapper = styled.div`
display: ${(props) => (props.isInfoPanelVisible ? "none" : "flex")};
const StyledInfoPanelToggleColorThemeWrapper = styled(ColorTheme)`
align-items: center;
align-self: center;
justify-content: center;
margin-left: auto;
margin-bottom: 1px;
padding: 0;
@media ${tablet} {
display: none;
margin-left: ${(props) => (props.isRootFolder ? "auto" : "0")};
}
.info-panel-toggle-bg {
height: 32px;
width: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: ${(props) =>
props.isInfoPanelVisible
? props.theme.infoPanel.sectionHeaderToggleBgActive
: props.theme.infoPanel.sectionHeaderToggleBg};
path {
fill: ${(props) =>
props.isInfoPanelVisible
? props.theme.infoPanel.sectionHeaderToggleIconActive
: props.theme.infoPanel.sectionHeaderToggleIcon};
}
}
`;
StyledInfoPanelToggleWrapper.defaultProps = { theme: Base };
StyledInfoPanelToggleColorThemeWrapper.defaultProps = { theme: Base };
const ToggleInfoPanelButton = ({
isRootFolder,
@ -53,8 +29,9 @@ const ToggleInfoPanelButton = ({
titles,
}) => {
return (
<StyledInfoPanelToggleWrapper
<StyledInfoPanelToggleColorThemeWrapper
isRootFolder={isRootFolder}
themeId={ThemeType.InfoPanelToggle}
isInfoPanelVisible={isInfoPanelVisible}
>
<div className="info-panel-toggle-bg">
@ -68,7 +45,7 @@ const ToggleInfoPanelButton = ({
title={titles?.infoPanel}
/>
</div>
</StyledInfoPanelToggleWrapper>
</StyledInfoPanelToggleColorThemeWrapper>
);
};

View File

@ -19,8 +19,9 @@ const StyledInfoPanelToggleWrapper = styled.div`
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: ${(props) =>
props.theme.infoPanel.sectionHeaderToggleBgActive};
background-color: ${(props) => !props.isInfoPanelVisible
? "none"
: props.theme.infoPanel.sectionHeaderToggleBgActive};
path {
fill: ${(props) => props.theme.infoPanel.sectionHeaderToggleIconActive};

View File

@ -4,6 +4,7 @@ import { mobile, tablet, hugeMobile } from "../utils/device";
import IconButton from "../icon-button";
import Scrollbar from "../scrollbar";
import { isMobile, isMobileOnly } from "react-device-detect";
import { ColorTheme } from "@docspace/common/components/ColorTheme";
const reactWindowContainerStyles = css`
height: 100%;
@ -50,7 +51,7 @@ const StyledTableContainer = styled.div`
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: ${(props) =>
props.theme.tableContainer.header.borderImageSource};
props.theme.tableContainer.header.borderImageSource};
border-top: 0;
border-left: 0;
}
@ -58,12 +59,12 @@ const StyledTableContainer = styled.div`
.lengthen-header {
border-image-slice: 1;
border-image-source: ${(props) =>
props.theme.tableContainer.header.lengthenBorderImageSource};
props.theme.tableContainer.header.lengthenBorderImageSource};
}
.hotkeys-lengthen-header {
border-bottom: ${(props) =>
props.theme.tableContainer.header.hotkeyBorderBottom};
props.theme.tableContainer.header.hotkeyBorderBottom};
border-image-source: none;
}
@ -121,14 +122,14 @@ const StyledTableGroupMenu = styled.div`
}
${isMobile &&
css`
css`
margin-left: 24px;
`}
}
.table-container_group-menu-separator {
border-right: ${(props) =>
props.theme.tableContainer.groupMenu.borderRight};
props.theme.tableContainer.groupMenu.borderRight};
width: 1px;
height: 21px;
margin: 0 16px 0 20px;
@ -138,7 +139,7 @@ const StyledTableGroupMenu = styled.div`
}
${isMobile &&
css`
css`
height: 36px;
`}
@ -147,7 +148,7 @@ const StyledTableGroupMenu = styled.div`
}
${isMobileOnly &&
css`
css`
height: 20px;
`}
}
@ -172,8 +173,8 @@ const StyledTableGroupMenu = styled.div`
StyledTableGroupMenu.defaultProps = { theme: Base };
const StyledInfoPanelToggleWrapper = styled.div`
display: ${(props) => (props.isInfoPanelVisible ? "none" : "flex")};
const StyledInfoPanelToggleColorThemeWrapper = styled(ColorTheme)`
display: flex;
align-items: center;
align-self: center;
@ -182,6 +183,7 @@ const StyledInfoPanelToggleWrapper = styled.div`
height: 100%;
width: auto;
padding-left: 20px;
padding-right: 0;
@media ${tablet} {
display: none;
@ -191,30 +193,10 @@ const StyledInfoPanelToggleWrapper = styled.div`
margin-top: 1px;
.info-panel-toggle-bg {
height: 32px;
width: 32px;
display: flex;
align-items: center;
align-self: center;
justify-content: center;
border-radius: 50%;
background-color: ${(props) =>
props.isInfoPanelVisible
? props.theme.infoPanel.sectionHeaderToggleBgActive
: props.theme.infoPanel.sectionHeaderToggleBg};
path {
fill: ${(props) =>
props.isInfoPanelVisible
? props.theme.infoPanel.sectionHeaderToggleIconActive
: props.theme.infoPanel.sectionHeaderToggleIcon};
}
margin-bottom: 1px;
}
`;
StyledInfoPanelToggleWrapper.defaultProps = { theme: Base };
StyledInfoPanelToggleColorThemeWrapper.defaultProps = { theme: Base };
const StyledTableHeader = styled.div`
position: fixed;
@ -245,10 +227,10 @@ const StyledTableHeaderCell = styled.div`
padding: 13px 0 0 4px;
display: ${(props) =>
props.isActive && props.showIcon ? "block" : "none"};
props.isActive && props.showIcon ? "block" : "none"};
${(props) =>
props.sorted &&
css`
props.sorted &&
css`
transform: scale(1, -1);
padding: 14px 0 14px 4px;
`}
@ -258,16 +240,16 @@ const StyledTableHeaderCell = styled.div`
height: 12px;
path {
fill: ${(props) =>
props.isActive
? props.theme.tableContainer.header.activeIconColor
: props.theme.tableContainer.header.iconColor} !important;
props.isActive
? props.theme.tableContainer.header.activeIconColor
: props.theme.tableContainer.header.iconColor} !important;
}
}
&:hover {
path {
fill: ${(props) =>
props.theme.tableContainer.header.hoverIconColor} !important;
props.theme.tableContainer.header.hoverIconColor} !important;
}
}
}
@ -275,8 +257,8 @@ const StyledTableHeaderCell = styled.div`
:hover {
.header-container-text-icon {
${(props) =>
props.showIcon &&
css`
props.showIcon &&
css`
display: block;
`};
}
@ -300,13 +282,13 @@ const StyledTableHeaderCell = styled.div`
display: flex;
align-items: center;
color: ${(props) =>
props.isActive
? props.theme.tableContainer.header.activeTextColor
: props.theme.tableContainer.header.textColor};
props.isActive
? props.theme.tableContainer.header.activeTextColor
: props.theme.tableContainer.header.textColor};
&:hover {
color: ${(props) =>
props.theme.tableContainer.header.hoverTextColor} !important;
props.theme.tableContainer.header.hoverTextColor} !important;
}
}
`;
@ -330,9 +312,9 @@ const StyledTableRow = styled.div`
.droppable-hover {
background: ${(props) =>
props.dragging
? `${props.theme.dragAndDrop.acceptBackground} !important`
: "none"};
props.dragging
? `${props.theme.dragAndDrop.acceptBackground} !important`
: "none"};
}
.table-container_row-loader {
@ -420,7 +402,7 @@ const StyledSettingsIcon = styled(IconButton)`
svg {
path {
fill: ${props.theme.tableContainer.header
.settingsIconDisableColor} !important;
.settingsIconDisableColor} !important;
}
}
`}
@ -437,7 +419,7 @@ export {
StyledTableCell,
StyledTableSettings,
StyledTableGroupMenu,
StyledInfoPanelToggleWrapper,
StyledInfoPanelToggleColorThemeWrapper,
StyledEmptyTableContainer,
StyledScrollbar,
StyledSettingsIcon,

View File

@ -4,7 +4,7 @@ import Checkbox from "../checkbox";
import {
StyledTableGroupMenu,
StyledScrollbar,
StyledInfoPanelToggleWrapper,
StyledInfoPanelToggleColorThemeWrapper,
} from "./StyledTableContainer";
import ComboBox from "../combobox";
import GroupMenuItem from "./GroupMenuItem";
@ -12,6 +12,7 @@ import { useTranslation } from "react-i18next";
import IconButton from "../icon-button";
import TriangleNavigationDownReactSvgUrl from "PUBLIC_DIR/images/triangle.navigation.down.react.svg?url";
import PanelReactSvgUrl from "PUBLIC_DIR/images/panel.react.svg?url";
import { ThemeType } from "@docspace/common/components/ColorTheme";
const TableGroupMenu = (props) => {
const {
@ -67,7 +68,10 @@ const TableGroupMenu = (props) => {
))}
</StyledScrollbar>
{!withoutInfoPanelToggler && (
<StyledInfoPanelToggleWrapper isInfoPanelVisible={isInfoPanelVisible}>
<StyledInfoPanelToggleColorThemeWrapper
themeId={ThemeType.InfoPanelToggle}
isInfoPanelVisible={isInfoPanelVisible}
>
<div className="info-panel-toggle-bg">
<IconButton
id="info-panel-toggle--open"
@ -78,7 +82,7 @@ const TableGroupMenu = (props) => {
onClick={toggleInfoPanel}
/>
</div>
</StyledInfoPanelToggleWrapper>
</StyledInfoPanelToggleColorThemeWrapper>
)}
</StyledTableGroupMenu>
</>

View File

@ -201,13 +201,13 @@ class TableHeader extends React.Component {
onMouseUp = () => {
!this.props.infoPanelVisible
? localStorage.setItem(
this.props.columnStorageName,
this.props.containerRef.current.style.gridTemplateColumns
)
this.props.columnStorageName,
this.props.containerRef.current.style.gridTemplateColumns
)
: localStorage.setItem(
this.props.columnInfoPanelStorageName,
this.props.containerRef.current.style.gridTemplateColumns
);
this.props.columnInfoPanelStorageName,
this.props.containerRef.current.style.gridTemplateColumns
);
window.removeEventListener("mousemove", this.onMouseMove);
window.removeEventListener("mouseup", this.onMouseUp);
@ -243,15 +243,15 @@ class TableHeader extends React.Component {
? containerRef.current
: document.getElementById("table-container");
// 400 - it is desktop info panel width
const minSize = infoPanelVisible ? size.tablet - 400 : size.tablet;
// // 400 - it is desktop info panel width
// const minSize = infoPanelVisible ? size.tablet - 400 : size.tablet;
if (
!container ||
+container.clientWidth + containerMargin <= minSize ||
sectionWidth <= minSize
)
return;
// if (
// !container ||
// +container.clientWidth + containerMargin <= minSize ||
// sectionWidth <= minSize
// )
// return;
const storageSize =
!resetColumnsSize && localStorage.getItem(columnStorageName);
@ -285,6 +285,9 @@ class TableHeader extends React.Component {
return this.resetColumns(true);
}
if (!container) return
const containerWidth = +container.clientWidth;
const oldWidth =
@ -414,12 +417,12 @@ class TableHeader extends React.Component {
? `${defaultColumnSize}px`
: (currentContentWidth * percent) / 100 >
defaultMinColumnSize
? (currentContentWidth * percent) / 100 + "px"
: defaultMinColumnSize + "px";
? (currentContentWidth * percent) / 100 + "px"
: defaultMinColumnSize + "px";
if (
(currentContentWidth * percent) / 100 <
defaultMinColumnSize &&
defaultMinColumnSize &&
!defaultColumnSize
) {
overWidth +=
@ -478,10 +481,9 @@ class TableHeader extends React.Component {
const newItemWidth = defaultColumnSize
? `${defaultColumnSize}px`
: index == 0
? `${
contentWidth - enabledColumnsCount * defaultMinColumnSize
? `${contentWidth - enabledColumnsCount * defaultMinColumnSize
}px`
: `${defaultMinColumnSize}px`;
: `${defaultMinColumnSize}px`;
gridTemplateColumns.push(newItemWidth);
} else {
@ -524,9 +526,9 @@ class TableHeader extends React.Component {
const newItemWidth = defaultColumnSize
? `${defaultColumnSize}px`
: percent === 0
? `${minColumnSize}px`
: ((containerWidth - defaultSize - settingsSize) * percent) /
100 +
? `${minColumnSize}px`
: ((containerWidth - defaultSize - settingsSize) * percent) /
100 +
"px";
gridTemplateColumns.push(newItemWidth);
@ -676,9 +678,8 @@ class TableHeader extends React.Component {
<>
<StyledTableHeader
id="table-container_caption-header"
className={`${
isLengthenHeader ? "lengthen-header" : ""
} table-container_header`}
className={`${isLengthenHeader ? "lengthen-header" : ""
} table-container_header`}
ref={this.headerRef}
{...rest}
>