Web: Files : RowContent : Auto formatting, disable file actions inside recycle

This commit is contained in:
Ilya Oleshko 2020-10-16 16:12:37 +03:00
parent 5c4df62c77
commit 312856acf1

View File

@ -1,11 +1,17 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { withTranslation } from "react-i18next"; import { withTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
import { RowContent, Link, Text, Icons, IconButton, Badge } from "asc-web-components"; import {
import { constants, api, toastr, store as initStore } from 'asc-web-common'; RowContent,
Link,
Text,
Icons,
IconButton,
Badge,
} from "asc-web-components";
import { constants, api, toastr, store as initStore } from "asc-web-common";
import { import {
clearProgressData, clearProgressData,
createFile, createFile,
@ -18,7 +24,7 @@ import {
setTreeFolders, setTreeFolders,
setUpdateTree, setUpdateTree,
updateFile, updateFile,
} from '../../../../../store/files/actions'; } from "../../../../../store/files/actions";
import { import {
canConvert, canConvert,
canWebEdit, canWebEdit,
@ -38,59 +44,62 @@ import {
isImage, isImage,
isSound, isSound,
isVideo, isVideo,
} from '../../../../../store/files/selectors'; } from "../../../../../store/files/selectors";
import { NewFilesPanel } from "../../../../panels"; import { NewFilesPanel } from "../../../../panels";
import { ConvertDialog } from "../../../../dialogs"; import { ConvertDialog } from "../../../../dialogs";
import EditingWrapperComponent from "./EditingWrapperComponent"; import EditingWrapperComponent from "./EditingWrapperComponent";
const { FileAction } = constants; const { FileAction } = constants;
const sideColor = '#A3A9AE'; const sideColor = "#A3A9AE";
const { getSettings } = initStore.auth.selectors; const { getSettings } = initStore.auth.selectors;
const SimpleFilesRowContent = styled(RowContent)` const SimpleFilesRowContent = styled(RowContent)`
.badge-ext { .badge-ext {
margin-left: -8px; margin-left: -8px;
margin-right: 8px; margin-right: 8px;
} }
.badge { .badge {
height: 14px; height: 14px;
width: 14px; width: 14px;
margin-right: 8px; margin-right: 8px;
} }
.badges { .badges {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.share-icon { .share-icon {
margin-top: -4px; margin-top: -4px;
padding-right: 8px; padding-right: 8px;
} }
.row_update-text { .row_update-text {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
`; `;
const okIcon = <Icons.CheckIcon const okIcon = (
className='edit-ok-icon' <Icons.CheckIcon
size='scale' className="edit-ok-icon"
isfill={true} size="scale"
color='#A3A9AE' isfill={true}
/>; color="#A3A9AE"
/>
);
const cancelIcon = <Icons.CrossIcon const cancelIcon = (
className='edit-cancel-icon' <Icons.CrossIcon
size='scale' className="edit-cancel-icon"
isfill={true} size="scale"
color='#A3A9AE' isfill={true}
/>; color="#A3A9AE"
/>
);
class FilesRowContent extends React.PureComponent { class FilesRowContent extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
let titleWithoutExt = getTitleWithoutExst(props.item); let titleWithoutExt = getTitleWithoutExst(props.item);
@ -105,30 +114,37 @@ class FilesRowContent extends React.PureComponent {
showNewFilesPanel: false, showNewFilesPanel: false,
newFolderId: [], newFolderId: [],
newItems: props.item.new || props.item.fileStatus === 2, newItems: props.item.new || props.item.fileStatus === 2,
showConvertDialog: false showConvertDialog: false,
//loading: false //loading: false
}; };
} }
completeAction = (id) => { completeAction = (id) => {
this.props.onEditComplete(id, !this.props.item.fileExst); this.props.onEditComplete(id, !this.props.item.fileExst);
} };
updateItem = (e) => { updateItem = (e) => {
const { fileAction, updateFile, renameFolder, item, setIsLoading } = this.props; const {
fileAction,
updateFile,
renameFolder,
item,
setIsLoading,
} = this.props;
const { itemTitle } = this.state; const { itemTitle } = this.state;
const originalTitle = getTitleWithoutExst(item); const originalTitle = getTitleWithoutExst(item);
setIsLoading(true); setIsLoading(true);
if (originalTitle === itemTitle) if (originalTitle === itemTitle) return this.completeAction(fileAction.id);
return this.completeAction(fileAction.id);
item.fileExst item.fileExst
? updateFile(fileAction.id, itemTitle) ? updateFile(fileAction.id, itemTitle)
.then(() => this.completeAction(fileAction.id)).finally(() => setIsLoading(false)) .then(() => this.completeAction(fileAction.id))
.finally(() => setIsLoading(false))
: renameFolder(fileAction.id, itemTitle) : renameFolder(fileAction.id, itemTitle)
.then(() => this.completeAction(fileAction.id)).finally(() => setIsLoading(false)); .then(() => this.completeAction(fileAction.id))
.finally(() => setIsLoading(false));
}; };
createItem = (e) => { createItem = (e) => {
@ -139,29 +155,28 @@ class FilesRowContent extends React.PureComponent {
const itemId = e.currentTarget.dataset.itemid; const itemId = e.currentTarget.dataset.itemid;
if (itemTitle.trim() === '') if (itemTitle.trim() === "") return this.completeAction(itemId);
return this.completeAction(itemId);
let newTab = item.fileExst let newTab = item.fileExst ? window.open("about:blank", "_blank") : null;
? window.open('about:blank', '_blank')
: null;
!item.fileExst !item.fileExst
? createFolder(item.parentId, itemTitle) ? createFolder(item.parentId, itemTitle)
.then(() => this.completeAction(itemId)).finally(() => setIsLoading(false)) .then(() => this.completeAction(itemId))
.finally(() => setIsLoading(false))
: createFile(item.parentId, `${itemTitle}.${item.fileExst}`) : createFile(item.parentId, `${itemTitle}.${item.fileExst}`)
.then((file) => { .then((file) => {
newTab.location = file.webUrl; newTab.location = file.webUrl;
this.completeAction(itemId); this.completeAction(itemId);
}).finally(() => setIsLoading(false)) })
} .finally(() => setIsLoading(false));
};
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
const { fileAction, item, newRowItems, setNewRowItems } = this.props; const { fileAction, item, newRowItems, setNewRowItems } = this.props;
const itemId = item.id.toString(); const itemId = item.id.toString();
if (newRowItems.length && newRowItems.includes(itemId)) { if (newRowItems.length && newRowItems.includes(itemId)) {
const rowItems = newRowItems.filter(x => x !== itemId) const rowItems = newRowItems.filter((x) => x !== itemId);
if (this.state.newItems !== 0) { if (this.state.newItems !== 0) {
this.setState({ newItems: 0 }, () => setNewRowItems(rowItems)); this.setState({ newItems: 0 }, () => setNewRowItems(rowItems));
} }
@ -169,27 +184,38 @@ class FilesRowContent extends React.PureComponent {
if (fileAction) { if (fileAction) {
if (fileAction.id !== prevProps.fileAction.id) { if (fileAction.id !== prevProps.fileAction.id) {
this.setState({ editingId: fileAction.id }) this.setState({ editingId: fileAction.id });
} }
} }
} }
renameTitle = e => { renameTitle = (e) => {
this.setState({ itemTitle: e.target.value }); this.setState({ itemTitle: e.target.value });
} };
cancelUpdateItem = e => { cancelUpdateItem = (e) => {
this.completeAction(e); this.completeAction(e);
} };
onClickUpdateItem = e => { onClickUpdateItem = (e) => {
(this.props.fileAction.type === FileAction.Create) this.props.fileAction.type === FileAction.Create
? this.createItem(e) ? this.createItem(e)
: this.updateItem(e); : this.updateItem(e);
} };
onFilesClick = () => { onFilesClick = () => {
const { filter, parentFolder, setIsLoading, onMediaFileClick, fetchFiles, isImage, isSound, isVideo, canWebEdit, item } = this.props; const {
filter,
parentFolder,
setIsLoading,
onMediaFileClick,
fetchFiles,
isImage,
isSound,
isVideo,
canWebEdit,
item,
} = this.props;
const { id, fileExst, viewUrl } = item; const { id, fileExst, viewUrl } = item;
if (!fileExst) { if (!fileExst) {
@ -201,7 +227,7 @@ class FilesRowContent extends React.PureComponent {
} }
fetchFiles(id, newFilter) fetchFiles(id, newFilter)
.catch(err => { .catch((err) => {
toastr.error(err); toastr.error(err);
setIsLoading(false); setIsLoading(false);
}) })
@ -221,19 +247,21 @@ class FilesRowContent extends React.PureComponent {
}; };
onMobileRowClick = (e) => { onMobileRowClick = (e) => {
if (window.innerWidth > 1024) const { isTrashFolder } = this.props;
return;
if (isTrashFolder || window.innerWidth > 1024) return;
this.onFilesClick(); this.onFilesClick();
} };
getStatusByDate = () => { getStatusByDate = () => {
const { culture, t, item } = this.props; const { culture, t, item } = this.props;
const { created, updated, version, fileExst } = item; const { created, updated, version, fileExst } = item;
const title = version > 1 const title =
? t("TitleModified") version > 1
: fileExst ? t("TitleModified")
: fileExst
? t("TitleUploaded") ? t("TitleUploaded")
: t("TitleCreated"); : t("TitleCreated");
@ -247,11 +275,11 @@ class FilesRowContent extends React.PureComponent {
const { t } = this.props; const { t } = this.props;
switch (format) { switch (format) {
case 'docx': case "docx":
return t("NewDocument"); return t("NewDocument");
case 'xlsx': case "xlsx":
return t("NewSpreadsheet"); return t("NewSpreadsheet");
case 'pptx': case "pptx":
return t("NewPresentation"); return t("NewPresentation");
default: default:
return t("NewFolder"); return t("NewFolder");
@ -263,11 +291,19 @@ class FilesRowContent extends React.PureComponent {
const fileId = e.currentTarget.dataset.id; const fileId = e.currentTarget.dataset.id;
history.push(`${settings.homepage}/${fileId}/history`); history.push(`${settings.homepage}/${fileId}/history`);
} };
onBadgeClick = () => { onBadgeClick = () => {
const { showNewFilesPanel } = this.state; const { showNewFilesPanel } = this.state;
const { item, treeFolders, setTreeFolders, rootFolderId, newItems, setNewRowItems, setUpdateTree } = this.props; const {
item,
treeFolders,
setTreeFolders,
rootFolderId,
newItems,
setNewRowItems,
setUpdateTree,
} = this.props;
if (item.fileExst) { if (item.fileExst) {
api.files api.files
.markAsRead([], [item.id]) .markAsRead([], [item.id])
@ -279,7 +315,7 @@ class FilesRowContent extends React.PureComponent {
setTreeFolders(data); setTreeFolders(data);
setNewRowItems([`${item.id}`]); setNewRowItems([`${item.id}`]);
}) })
.catch((err) => toastr.error(err)) .catch((err) => toastr.error(err));
} else { } else {
const newFolderId = this.props.selectedFolder.pathParts; const newFolderId = this.props.selectedFolder.pathParts;
newFolderId.push(item.id); newFolderId.push(item.id);
@ -288,7 +324,7 @@ class FilesRowContent extends React.PureComponent {
newFolderId, newFolderId,
}); });
} }
} };
onShowNewFilesPanel = () => { onShowNewFilesPanel = () => {
const { showNewFilesPanel } = this.state; const { showNewFilesPanel } = this.state;
@ -298,39 +334,55 @@ class FilesRowContent extends React.PureComponent {
setConvertDialogVisible = () => setConvertDialogVisible = () =>
this.setState({ showConvertDialog: !this.state.showConvertDialog }); this.setState({ showConvertDialog: !this.state.showConvertDialog });
getConvertProgress = fileId => { getConvertProgress = (fileId) => {
const { selectedFolder, filter, setIsLoading, setProgressBarData, t, clearProgressData, fetchFiles } = this.props; const {
api.files.getConvertFile(fileId).then(res => { selectedFolder,
filter,
setIsLoading,
setProgressBarData,
t,
clearProgressData,
fetchFiles,
} = this.props;
api.files.getConvertFile(fileId).then((res) => {
if (res && res[0] && res[0].progress !== 100) { if (res && res[0] && res[0].progress !== 100) {
setProgressBarData({ visible: true, percent: res[0].progress, label: t("Convert") }); setProgressBarData({
visible: true,
percent: res[0].progress,
label: t("Convert"),
});
setTimeout(() => this.getConvertProgress(fileId), 1000); setTimeout(() => this.getConvertProgress(fileId), 1000);
} else { } else {
if (res[0].error) { if (res[0].error) {
toastr.error(res[0].error); toastr.error(res[0].error);
clearProgressData(); clearProgressData();
} else { } else {
setProgressBarData({ visible: true, percent: 100, label: t("Convert") }); setProgressBarData({
setTimeout(() => clearProgressData(), 5000) visible: true,
percent: 100,
label: t("Convert"),
});
setTimeout(() => clearProgressData(), 5000);
const newFilter = filter.clone(); const newFilter = filter.clone();
fetchFiles(selectedFolder.id, newFilter) fetchFiles(selectedFolder.id, newFilter)
.catch(err => toastr.error(err)) .catch((err) => toastr.error(err))
.finally(() => setIsLoading(false)); .finally(() => setIsLoading(false));
} }
} }
}); });
} };
onConvert = () => { onConvert = () => {
const { item, t, setProgressBarData } = this.props; const { item, t, setProgressBarData } = this.props;
setProgressBarData({ visible: true, percent: 0, label: t("Convert") }); setProgressBarData({ visible: true, percent: 0, label: t("Convert") });
this.setState({ showConvertDialog: false }, () => this.setState({ showConvertDialog: false }, () =>
api.files.convertFile(item.id).then(convertRes => { api.files.convertFile(item.id).then((convertRes) => {
if (convertRes && convertRes[0] && convertRes[0].progress !== 100) { if (convertRes && convertRes[0] && convertRes[0].progress !== 100) {
this.getConvertProgress(item.id); this.getConvertProgress(item.id);
} }
}) })
); );
} };
render() { render() {
const { const {
@ -343,7 +395,7 @@ class FilesRowContent extends React.PureComponent {
isLoading, isLoading,
isMobile, isMobile,
canWebEdit, canWebEdit,
canConvert canConvert,
} = this.props; } = this.props;
const { const {
itemTitle, itemTitle,
@ -351,7 +403,7 @@ class FilesRowContent extends React.PureComponent {
showNewFilesPanel, showNewFilesPanel,
newItems, newItems,
newFolderId, newFolderId,
showConvertDialog showConvertDialog,
} = this.state; } = this.state;
const { const {
contentLength, contentLength,
@ -363,18 +415,23 @@ class FilesRowContent extends React.PureComponent {
fileStatus, fileStatus,
id, id,
versionGroup, versionGroup,
locked locked,
} = item; } = item;
const titleWithoutExt = getTitleWithoutExst(item); const titleWithoutExt = getTitleWithoutExst(item);
const fileOwner = createdBy && ((this.props.viewer.id === createdBy.id && t("AuthorMe")) || createdBy.displayName); const fileOwner =
createdBy &&
((this.props.viewer.id === createdBy.id && t("AuthorMe")) ||
createdBy.displayName);
const updatedDate = updated && this.getStatusByDate(); const updatedDate = updated && this.getStatusByDate();
const isEdit = (id === editingId) && (fileExst === fileAction.extension); const isEdit = id === editingId && fileExst === fileAction.extension;
const linkStyles = isTrashFolder ? { noHover: true } : { onClick: this.onFilesClick }; const linkStyles = isTrashFolder
? { noHover: true }
: { onClick: this.onMobileRowClick };
const showNew = !!newItems; const showNew = !!newItems;
return isEdit return isEdit ? (
? <EditingWrapperComponent <EditingWrapperComponent
itemTitle={itemTitle} itemTitle={itemTitle}
okIcon={okIcon} okIcon={okIcon}
cancelIcon={cancelIcon} cancelIcon={cancelIcon}
@ -384,183 +441,185 @@ class FilesRowContent extends React.PureComponent {
itemId={id} itemId={id}
isLoading={isLoading} isLoading={isLoading}
/> />
: ( ) : (
<> <>
{showConvertDialog && ( {showConvertDialog && (
<ConvertDialog <ConvertDialog
visible={showConvertDialog} visible={showConvertDialog}
onClose={this.setConvertDialogVisible} onClose={this.setConvertDialogVisible}
onConvert={this.onConvert} onConvert={this.onConvert}
/> />
)} )}
{showNewFilesPanel && ( {showNewFilesPanel && (
<NewFilesPanel <NewFilesPanel
visible={showNewFilesPanel} visible={showNewFilesPanel}
onClose={this.onShowNewFilesPanel} onClose={this.onShowNewFilesPanel}
folderId={newFolderId} folderId={newFolderId}
folders={folders} folders={folders}
/> />
)} )}
<SimpleFilesRowContent <SimpleFilesRowContent
widthProp={widthProp} widthProp={widthProp}
isMobile={isMobile} isMobile={isMobile}
sideColor={sideColor} sideColor={sideColor}
isFile={fileExst} isFile={fileExst}
onClick={this.onMobileRowClick} onClick={this.onMobileRowClick}
>
<Link
containerWidth="55%"
type="page"
title={titleWithoutExt}
fontWeight="600"
fontSize="15px"
{...linkStyles}
color="#333"
isTextOverflow
> >
<Link {titleWithoutExt}
containerWidth='55%' </Link>
type='page' <>
title={titleWithoutExt} {fileExst ? (
fontWeight="600" <div className="badges">
fontSize='15px' <Text
{...linkStyles} className="badge-ext"
color="#333" as="span"
isTextOverflow color="#A3A9AE"
> fontSize="15px"
{titleWithoutExt} fontWeight={600}
</Link> title={fileExst}
<> truncate={true}
{fileExst ? >
<div className='badges'> {fileExst}
<Text </Text>
className='badge-ext' {canConvert && (
as="span" <IconButton
onClick={this.setConvertDialogVisible}
iconName="FileActionsConvertIcon"
className="badge"
size="small"
isfill={true}
color="#A3A9AE" color="#A3A9AE"
fontSize='15px' />
fontWeight={600} )}
title={fileExst} {canWebEdit && (
truncate={true} <Icons.AccessEditIcon
> className="badge"
{fileExst} size="small"
</Text> isfill={true}
{canConvert && color="#A3A9AE"
<IconButton />
onClick={this.setConvertDialogVisible} )}
iconName="FileActionsConvertIcon" {fileStatus === 1 && (
className='badge' <Icons.FileActionsConvertEditDocIcon
size='small' className="badge"
isfill={true} size="small"
color='#A3A9AE' isfill={true}
/> color="#3B72A7"
} />
{canWebEdit && )}
<Icons.AccessEditIcon {locked && (
className='badge' <Icons.FileActionsLockedIcon
size='small' className="badge"
isfill={true} size="small"
color='#A3A9AE' isfill={true}
/> color="#3B72A7"
} />
{fileStatus === 1 && )}
<Icons.FileActionsConvertEditDocIcon {versionGroup > 1 && (
className='badge' <Badge
size='small' className="badge-version"
isfill={true} backgroundColor="#A3A9AE"
color='#3B72A7' borderRadius="11px"
/> color="#FFFFFF"
} fontSize="10px"
{locked && fontWeight={800}
<Icons.FileActionsLockedIcon label={`Ver.${versionGroup}`}
className='badge' maxWidth="50px"
size='small' onClick={this.onShowVersionHistory}
isfill={true} padding="0 5px"
color='#3B72A7' data-id={id}
/> />
} )}
{versionGroup > 1 && {showNew && (
<Badge <Badge
className='badge-version' className="badge-version"
backgroundColor="#A3A9AE" backgroundColor="#ED7309"
borderRadius="11px" borderRadius="11px"
color="#FFFFFF" color="#FFFFFF"
fontSize="10px" fontSize="10px"
fontWeight={800} fontWeight={800}
label={`Ver.${versionGroup}`} label={`New`}
maxWidth="50px" maxWidth="50px"
onClick={this.onShowVersionHistory} onClick={this.onBadgeClick}
padding="0 5px" padding="0 5px"
data-id={id} data-id={id}
/> />
} )}
{showNew && </div>
<Badge ) : (
className='badge-version' <div className="badges">
backgroundColor="#ED7309" {showNew && (
borderRadius="11px" <Badge
color="#FFFFFF" className="badge-version"
fontSize="10px" backgroundColor="#ED7309"
fontWeight={800} borderRadius="11px"
label={`New`} color="#FFFFFF"
maxWidth="50px" fontSize="10px"
onClick={this.onBadgeClick} fontWeight={800}
padding="0 5px" label={newItems}
data-id={id} maxWidth="50px"
/> onClick={this.onBadgeClick}
} padding="0 5px"
</div> data-id={id}
: />
<div className='badges'> )}
{showNew && </div>
<Badge )}
className='badge-version' </>
backgroundColor="#ED7309" <Text
borderRadius="11px" containerMinWidth="120px"
color="#FFFFFF" containerWidth="15%"
fontSize="10px" as="div"
fontWeight={800} color={sideColor}
label={newItems} fontSize="12px"
maxWidth="50px" fontWeight={400}
onClick={this.onBadgeClick} title={fileOwner}
padding="0 5px" truncate={true}
data-id={id} >
/> {fileOwner}
} </Text>
</div> <Text
} containerMinWidth="200px"
</> containerWidth="15%"
<Text title={updatedDate}
containerMinWidth='120px' fontSize="12px"
containerWidth='15%' fontWeight={400}
as="div" color={sideColor}
color={sideColor} className="row_update-text"
fontSize='12px' >
fontWeight={400} {updatedDate && updatedDate}
title={fileOwner} </Text>
truncate={true} <Text
> containerMinWidth="90px"
{fileOwner} containerWidth="10%"
</Text> as="div"
<Text color={sideColor}
containerMinWidth='200px' fontSize="12px"
containerWidth='15%' fontWeight={400}
title={updatedDate} title=""
fontSize='12px' truncate={true}
fontWeight={400} >
color={sideColor} {fileExst
className="row_update-text" ? contentLength
> : `${t("TitleDocuments")}: ${filesCount} | ${t(
{updatedDate && updatedDate} "TitleSubfolders"
</Text> )}: ${foldersCount}`}
<Text </Text>
containerMinWidth='90px' </SimpleFilesRowContent>
containerWidth='10%' </>
as="div" );
color={sideColor}
fontSize='12px'
fontWeight={400}
title=''
truncate={true}
>
{fileExst
? contentLength
: `${t("TitleDocuments")}: ${filesCount} | ${t("TitleSubfolders")}: ${foldersCount}`}
</Text>
</SimpleFilesRowContent>
</>
)
} }
}; }
function mapStateToProps(state, props) { function mapStateToProps(state, props) {
return { return {
@ -583,7 +642,7 @@ function mapStateToProps(state, props) {
isImage: isImage(props.item.fileExst)(state), isImage: isImage(props.item.fileExst)(state),
isSound: isSound(props.item.fileExst)(state), isSound: isSound(props.item.fileExst)(state),
isVideo: isVideo(props.item.fileExst)(state), isVideo: isVideo(props.item.fileExst)(state),
} };
} }
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
@ -597,5 +656,5 @@ export default connect(mapStateToProps, {
setNewRowItems, setNewRowItems,
setIsLoading, setIsLoading,
clearProgressData, clearProgressData,
fetchFiles fetchFiles,
})(withRouter(withTranslation()(FilesRowContent))); })(withRouter(withTranslation()(FilesRowContent)));