Web: Files: created download panel
This commit is contained in:
parent
a82ade029d
commit
2b2b195954
@ -0,0 +1,243 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import {
|
||||
IconButton,
|
||||
Row,
|
||||
Text,
|
||||
Icons,
|
||||
Tooltip,
|
||||
Link,
|
||||
} from "asc-web-components";
|
||||
|
||||
import LoadingButton from "./LoadingButton";
|
||||
import { connect } from "react-redux";
|
||||
import {
|
||||
getLoadingFile,
|
||||
getFileByFileId,
|
||||
} from "../../../store/files/selectors";
|
||||
|
||||
const StyledFileRow = styled(Row)`
|
||||
margin: 0 16px;
|
||||
width: calc(100% - 16px);
|
||||
box-sizing: border-box;
|
||||
font-weight: 600;
|
||||
|
||||
.download_panel-icon {
|
||||
margin-left: auto;
|
||||
line-height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.__react_component_tooltip.type-light {
|
||||
background-color: #f8f7bf !important;
|
||||
}
|
||||
.__react_component_tooltip.place-left::after {
|
||||
border-left: 6px solid #f8f7bf !important;
|
||||
}
|
||||
|
||||
.__react_component_tooltip.place-right::after {
|
||||
border-right: 6px solid #f8f7bf !important;
|
||||
}
|
||||
|
||||
.__react_component_tooltip.place-top::after {
|
||||
border-top: 6px solid #f8f7bf !important;
|
||||
}
|
||||
|
||||
.__react_component_tooltip.place-bottom::after {
|
||||
border-bottom: 6px solid #f8f7bf !important;
|
||||
}
|
||||
`;
|
||||
|
||||
const checkExt = (ext) => {
|
||||
const extArray = [
|
||||
"avi",
|
||||
"csv",
|
||||
"djvu",
|
||||
"doc",
|
||||
"docx",
|
||||
"dvd",
|
||||
"ebook",
|
||||
"file_archive",
|
||||
"flv",
|
||||
"html",
|
||||
"iaf",
|
||||
"image",
|
||||
"m2ts",
|
||||
"mkv",
|
||||
"mov",
|
||||
"mp4",
|
||||
"mpg",
|
||||
"odp",
|
||||
"ods",
|
||||
"odt",
|
||||
"pdf",
|
||||
"pps",
|
||||
"ppsx",
|
||||
"ppt",
|
||||
"pptx",
|
||||
"rtf",
|
||||
"sound",
|
||||
"svg",
|
||||
"txt",
|
||||
"xls",
|
||||
"xlsx",
|
||||
"xps",
|
||||
];
|
||||
return extArray.includes(ext);
|
||||
};
|
||||
|
||||
const FileRow = (props) => {
|
||||
const {
|
||||
t,
|
||||
item,
|
||||
index,
|
||||
archiveFormats,
|
||||
imageFormats,
|
||||
soundFormats,
|
||||
uploaded,
|
||||
onOpenSharingPanel,
|
||||
cancelCurrentUpload,
|
||||
mediaViewerImageFormats,
|
||||
mediaViewerMediaFormats,
|
||||
onMediaClick,
|
||||
currentFileUploadProgress,
|
||||
currentFile,
|
||||
} = props;
|
||||
const name = item.file.name.split(".");
|
||||
let ext = name.length > 1 ? name.pop() : "";
|
||||
let originalExt = null;
|
||||
|
||||
if (archiveFormats.includes(`.${ext}`)) {
|
||||
originalExt = ext;
|
||||
ext = "file_archive";
|
||||
}
|
||||
|
||||
if (imageFormats.includes(`.${ext}`)) {
|
||||
originalExt = ext;
|
||||
ext = "image";
|
||||
}
|
||||
|
||||
if (soundFormats.includes(`.${ext}`)) {
|
||||
originalExt = ext;
|
||||
ext = "sound";
|
||||
}
|
||||
|
||||
const fileIcon = checkExt(ext) ? (
|
||||
<img src={`images/icons/24/${ext}.svg`} alt={`${ext}`} />
|
||||
) : (
|
||||
<img src="images/icons/24/file.svg" alt="file" />
|
||||
);
|
||||
|
||||
const color =
|
||||
item.fileId && currentFile(item.fileId) && currentFile(item.fileId).shared
|
||||
? "#657077"
|
||||
: "#A3A9AE";
|
||||
|
||||
return (
|
||||
<>
|
||||
{item.cancel ? (
|
||||
<></>
|
||||
) : (
|
||||
<StyledFileRow
|
||||
className="download-row"
|
||||
key={item.uniqueId}
|
||||
checkbox={false}
|
||||
element={fileIcon}
|
||||
>
|
||||
<>
|
||||
{item.fileId ? (
|
||||
mediaViewerImageFormats.includes(`.${ext}`) ||
|
||||
mediaViewerMediaFormats.includes(`.${ext}`) ||
|
||||
mediaViewerImageFormats.includes(`.${originalExt}`) ||
|
||||
mediaViewerMediaFormats.includes(`.${originalExt}`) ? (
|
||||
<Text
|
||||
fontWeight="600"
|
||||
// MediaViewer doesn't work
|
||||
/*onClick={() => onMediaClick(item.fileId)}*/
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
) : (
|
||||
<Link
|
||||
fontWeight="600"
|
||||
href={item.fileInfo ? item.fileInfo.webUrl : ""}
|
||||
target="_blank"
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
)
|
||||
) : (
|
||||
<Text fontWeight="600">{name}</Text>
|
||||
)}
|
||||
{originalExt || ext ? (
|
||||
<Text fontWeight="600" color="#A3A9AE">
|
||||
.{originalExt ? originalExt : ext}
|
||||
</Text>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{item.fileId ? (
|
||||
<IconButton
|
||||
iconName="CatalogSharedIcon"
|
||||
className="download_panel-icon"
|
||||
color={color}
|
||||
isClickable={true}
|
||||
onClick={() =>
|
||||
onOpenSharingPanel(item.fileInfo ? item.fileInfo : "")
|
||||
}
|
||||
/>
|
||||
) : item.error || (!item.fileId && uploaded) ? (
|
||||
<div className="download_panel-icon">
|
||||
{" "}
|
||||
<Icons.LoadErrorIcon
|
||||
size="medium"
|
||||
data-for="errorTooltip"
|
||||
data-tip={item.error || t("UnknownError")}
|
||||
/>
|
||||
<Tooltip
|
||||
id="errorTooltip"
|
||||
className="tooltip-custom"
|
||||
getContent={(dataTip) => (
|
||||
<Text fontSize="13px">{dataTip}</Text>
|
||||
)}
|
||||
effect="float"
|
||||
place="left"
|
||||
maxWidth={320}
|
||||
color="#f8f7bf"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="download_panel-icon">
|
||||
<LoadingButton
|
||||
percent={currentFileUploadProgress}
|
||||
onClick={() => cancelCurrentUpload(index)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</StyledFileRow>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const loadingFile = getLoadingFile(state);
|
||||
|
||||
const { item } = ownProps;
|
||||
const { uniqueId } = item;
|
||||
return {
|
||||
currentFile: (fileId) => getFileByFileId(state, fileId),
|
||||
currentFileUploadProgress:
|
||||
loadingFile && loadingFile.uniqueId === uniqueId
|
||||
? loadingFile.percent
|
||||
: null,
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(FileRow);
|
@ -0,0 +1,91 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
const backgroundColor = "none";
|
||||
const color = "#2DA7DB";
|
||||
|
||||
const StyledCircleWrap = styled.div`
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: ${backgroundColor};
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const StyledCircle = styled.div`
|
||||
.circle__mask,
|
||||
.circle__fill {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.circle__mask {
|
||||
clip: rect(0px, 16px, 16px, 8px);
|
||||
}
|
||||
|
||||
.circle__fill {
|
||||
animation: fill-rotate ease-in-out none;
|
||||
transform: rotate(${(props) => props.percent * 1.8}deg);
|
||||
}
|
||||
|
||||
.circle__mask .circle__fill {
|
||||
clip: rect(0px, 8px, 16px, 0px);
|
||||
background-color: ${color};
|
||||
}
|
||||
|
||||
.circle__mask.circle__full {
|
||||
animation: fill-rotate ease-in-out none;
|
||||
transform: rotate(${(props) => props.percent * 1.8}deg);
|
||||
}
|
||||
|
||||
@keyframes fill-rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(${(props) => props.percent * 1.8}deg);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledLoadingButton = styled.div`
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 12px;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
margin: 2px;
|
||||
color: #2da7db;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
const LoadingButton = ({ id, className, style, ...rest }) => {
|
||||
const { percent, onClick } = rest;
|
||||
|
||||
return (
|
||||
<StyledCircleWrap
|
||||
id={id}
|
||||
className={className}
|
||||
style={style}
|
||||
onClick={onClick}
|
||||
>
|
||||
<StyledCircle percent={percent}>
|
||||
<div className="circle__mask circle__full">
|
||||
<div className="circle__fill"></div>
|
||||
</div>
|
||||
<div className="circle__mask">
|
||||
<div className="circle__fill"></div>
|
||||
</div>
|
||||
|
||||
<StyledLoadingButton>×</StyledLoadingButton>
|
||||
</StyledCircle>
|
||||
</StyledCircleWrap>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadingButton;
|
@ -0,0 +1,245 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Backdrop,
|
||||
Heading,
|
||||
Aside,
|
||||
IconButton,
|
||||
Icons,
|
||||
} from "asc-web-components";
|
||||
import { connect } from "react-redux";
|
||||
import { withRouter } from "react-router";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { utils as commonUtils, store } from "asc-web-common";
|
||||
import {
|
||||
setDownloadPanelVisible,
|
||||
setSharingPanelVisible,
|
||||
cancelUpload,
|
||||
cancelCurrentUpload,
|
||||
setMediaViewerData,
|
||||
setSelection,
|
||||
setSelected,
|
||||
} from "../../../store/files/actions";
|
||||
import {
|
||||
getDownloadPanelVisible,
|
||||
getUploadDataFiles,
|
||||
getArchiveFormats,
|
||||
getImageFormats,
|
||||
getSoundFormats,
|
||||
getSharePanelVisible,
|
||||
getMediaViewerImageFormats,
|
||||
getMediaViewerMediaFormats,
|
||||
getSelected,
|
||||
} from "../../../store/files/selectors";
|
||||
import SharingPanel from "../SharingPanel";
|
||||
import {
|
||||
StyledAsidePanel,
|
||||
StyledContent,
|
||||
StyledHeaderContent,
|
||||
StyledBody,
|
||||
} from "../StyledPanels";
|
||||
import FileRow from "./FileRow";
|
||||
import { createI18N } from "../../../helpers/i18n";
|
||||
const i18n = createI18N({
|
||||
page: "DownloadPanel",
|
||||
localesPath: "panels/DownloadPanel",
|
||||
});
|
||||
const { changeLanguage } = commonUtils;
|
||||
|
||||
const { getCurrentUserId } = store.auth.selectors;
|
||||
|
||||
const DownloadBodyStyle = { height: `calc(100vh - 156px)` };
|
||||
|
||||
class DownloadPanelComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
changeLanguage(i18n);
|
||||
|
||||
this.state = {
|
||||
uploadData: [],
|
||||
};
|
||||
this.ref = React.createRef();
|
||||
this.scrollRef = React.createRef();
|
||||
}
|
||||
|
||||
onClose = () => {
|
||||
this.props.setDownloadPanelVisible(!this.props.downloadPanelVisible);
|
||||
};
|
||||
componentDidMount() {
|
||||
document.addEventListener("keyup", this.onKeyPress);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener("keyup", this.onKeyPress);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { uploadDataFiles } = this.props;
|
||||
if (
|
||||
prevState.uploadData !== uploadDataFiles &&
|
||||
uploadDataFiles.length > 0
|
||||
) {
|
||||
this.setState({
|
||||
uploadData: prevProps.uploadDataFiles,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onKeyPress = (event) => {
|
||||
if (event.key === "Esc" || event.key === "Escape") {
|
||||
this.onClose();
|
||||
}
|
||||
};
|
||||
|
||||
clearDownloadPanel = () => {
|
||||
this.setState({
|
||||
uploadData: [],
|
||||
uploaded: false,
|
||||
});
|
||||
this.onClose();
|
||||
};
|
||||
|
||||
cancelCurrentUpload = (index) => {
|
||||
this.props.cancelCurrentUpload(index);
|
||||
console.log("cancel upload ", index);
|
||||
};
|
||||
|
||||
onOpenSharingPanel = (item) => {
|
||||
console.log(item);
|
||||
const {
|
||||
selected,
|
||||
setSelected,
|
||||
setSelection,
|
||||
setSharingPanelVisible,
|
||||
sharingPanelVisible,
|
||||
} = this.props;
|
||||
selected === "close" && setSelected("none");
|
||||
setSelection([item]);
|
||||
setSharingPanelVisible(!sharingPanelVisible);
|
||||
};
|
||||
|
||||
onMediaClick = (id) => {
|
||||
console.log("id", id);
|
||||
const item = { visible: true, id: id };
|
||||
this.props.setMediaViewerData(item);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
t,
|
||||
downloadPanelVisible,
|
||||
sharingPanelVisible,
|
||||
uploadDataFiles,
|
||||
archiveFormats,
|
||||
imageFormats,
|
||||
soundFormats,
|
||||
mediaViewerImageFormats,
|
||||
mediaViewerMediaFormats,
|
||||
} = this.props;
|
||||
|
||||
const { uploadData } = this.state;
|
||||
const uploaded = uploadDataFiles.length === 0;
|
||||
|
||||
const visible = downloadPanelVisible;
|
||||
const zIndex = 310;
|
||||
return (
|
||||
<StyledAsidePanel visible={visible}>
|
||||
<Backdrop
|
||||
onClick={this.onClose}
|
||||
visible={visible}
|
||||
zIndex={zIndex}
|
||||
isAside={true}
|
||||
/>
|
||||
<Aside className="header_aside-panel" visible={visible}>
|
||||
<StyledContent>
|
||||
<StyledHeaderContent>
|
||||
<Heading className="download_panel-header" size="medium" truncate>
|
||||
{t("Uploads")}
|
||||
</Heading>
|
||||
<div className="download_panel-icons-container">
|
||||
<div className="download_panel-remove-icon">
|
||||
{uploaded ? (
|
||||
<IconButton
|
||||
size="20"
|
||||
iconName="ClearActiveIcon"
|
||||
color="#A3A9AE"
|
||||
isClickable={true}
|
||||
onClick={this.clearDownloadPanel}
|
||||
/>
|
||||
) : (
|
||||
<IconButton
|
||||
size="20"
|
||||
iconName="ButtonCancelIcon"
|
||||
color="#A3A9AE"
|
||||
isClickable={true}
|
||||
onClick={this.props.cancelUpload}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{/*<div className="download_panel-vertical-dots-icon">
|
||||
<IconButton
|
||||
size="20"
|
||||
iconName="VerticalDotsIcon"
|
||||
color="#A3A9AE"
|
||||
/>
|
||||
</div>*/}
|
||||
</div>
|
||||
</StyledHeaderContent>
|
||||
<StyledBody stype="mediumBlack" style={DownloadBodyStyle}>
|
||||
{uploadData.map((item, index) => (
|
||||
<FileRow
|
||||
t={t}
|
||||
item={item}
|
||||
key={index}
|
||||
index={index}
|
||||
archiveFormats={archiveFormats}
|
||||
imageFormats={imageFormats}
|
||||
soundFormats={soundFormats}
|
||||
uploaded={uploaded}
|
||||
cancelCurrentUpload={this.cancelCurrentUpload}
|
||||
onOpenSharingPanel={this.onOpenSharingPanel}
|
||||
mediaViewerImageFormats={mediaViewerImageFormats}
|
||||
mediaViewerMediaFormats={mediaViewerMediaFormats}
|
||||
onMediaClick={this.onMediaClick}
|
||||
/>
|
||||
))}
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</Aside>
|
||||
{sharingPanelVisible && <SharingPanel />}
|
||||
</StyledAsidePanel>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const DownloadPanelContainerTranslated = withTranslation()(
|
||||
DownloadPanelComponent
|
||||
);
|
||||
|
||||
const DownloadPanel = (props) => (
|
||||
<DownloadPanelContainerTranslated i18n={i18n} {...props} />
|
||||
);
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
isMyId: getCurrentUserId(state),
|
||||
downloadPanelVisible: getDownloadPanelVisible(state),
|
||||
uploadDataFiles: getUploadDataFiles(state),
|
||||
archiveFormats: getArchiveFormats(state),
|
||||
imageFormats: getImageFormats(state),
|
||||
soundFormats: getSoundFormats(state),
|
||||
sharingPanelVisible: getSharePanelVisible(state),
|
||||
mediaViewerImageFormats: getMediaViewerImageFormats(state),
|
||||
mediaViewerMediaFormats: getMediaViewerMediaFormats(state),
|
||||
selected: getSelected(state),
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
setDownloadPanelVisible,
|
||||
setSharingPanelVisible,
|
||||
cancelUpload,
|
||||
cancelCurrentUpload,
|
||||
setMediaViewerData,
|
||||
setSelection,
|
||||
setSelected,
|
||||
})(withRouter(DownloadPanel));
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"Uploads":"Uploads",
|
||||
"UnknownError ":"Unknown Error "
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"Uploads":"Загрузки",
|
||||
"UnknownError ":"Неопределенная ошибка"
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import OperationsPanel from "./OperationsPanel";
|
||||
import NewFilesPanel from "./NewFilesPanel";
|
||||
import VersionHistoryPanel from "./VersionHistoryPanel";
|
||||
import ChangeOwnerPanel from "./ChangeOwnerPanel";
|
||||
import DownloadPanel from "./DownloadPanel";
|
||||
|
||||
export {
|
||||
SharingPanel,
|
||||
@ -16,4 +17,5 @@ export {
|
||||
NewFilesPanel,
|
||||
VersionHistoryPanel,
|
||||
ChangeOwnerPanel,
|
||||
DownloadPanel,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user