Skip to content
Snippets Groups Projects
Commit 439d17db authored by Jose Manuel Serrano Amaut's avatar Jose Manuel Serrano Amaut
Browse files

[WIP]: Add FileCard Component, add upload layer, info layer, improve the close...

[WIP]: Add FileCard Component, add upload layer, info layer, improve the close info button and tooltip for file card. Refactor FIle CardDemoPage darkmode section to wrap flex forw and minwidth
parent c4ace6da
No related branches found
No related tags found
No related merge requests found
Showing
with 318 additions and 132 deletions
......@@ -6,6 +6,7 @@ const sampleFileProps: ExtFile = {
size: 28 * 1024 * 1024,
type: "text/plain",
name: "file created from props.jsx",
valid: true,
};
const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
const removeFile = (id: string | number | undefined) => {
......@@ -18,9 +19,10 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
style={{
display: "flex",
justifyContent: "center",
width: "50%",
minWidth: "50%",
backgroundColor: "white",
padding: "15px 0",
flexGrow:1
}}
>
<FileCard {...sampleFileProps} info onDelete={removeFile} />
......@@ -29,9 +31,10 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
style={{
display: "flex",
justifyContent: "center",
width: "50%",
minWidth: "50%",
backgroundColor: "#121212",
padding: "15px 0",
flexGrow: 1,
}}
>
<FileCard {...sampleFileProps} info darkMode onDelete={removeFile} />
......@@ -44,9 +47,10 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
style={{
display: "flex",
justifyContent: "center",
width: "50%",
minWidth: "50%",
backgroundColor: "white",
padding: "15px 0",
flexGrow: 1,
}}
>
<FileMosaic {...sampleFileProps} info onDelete={removeFile} />
......@@ -55,9 +59,11 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
style={{
display: "flex",
justifyContent: "center",
width: "50%",
minWidth: "50%",
backgroundColor: "#121212",
padding: "15px 0",
flexGrow: 1,
}}
>
<FileMosaic {...sampleFileProps} info darkMode onDelete={removeFile} />
......
@import url(https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700,900);
.files-ui-file-card-main-container {
border-radius: 8px;
overflow: hidden;
//overflow: hidden;
color: rgba(0, 0, 0, 0.858);
display: flex;
flex-direction: row;
......@@ -14,6 +14,8 @@
font-weight: 400;
width: 350px;
.files-ui-file-card-main-layer-container {
border-radius: 8px;
overflow: hidden;
width: 380px;
box-sizing: border-box;
height: 100px;
......@@ -74,6 +76,13 @@
}
}
}
.file-card-status-layer {
display: flex;
align-items: flex-end;
justify-content: flex-start;
padding: 5px;
box-sizing: border-box;
}
}
.file-card-data {
line-height: 18px;
......@@ -124,7 +133,7 @@
//background-color: aquamarine;
height: 100%;
}
.file-card-upload-layer {
.file-card-upload-layer-container {
display: flex;
box-sizing: border-box;
//background-color: rgba(0, 0, 0, 0.5);
......@@ -147,6 +156,7 @@
overflow: hidden;
align-items: center;
justify-content: flex-end;
height: 100%;
}
.file-card-info-layer-container {
display: flex;
......@@ -178,6 +188,7 @@
scrollbar-width: thin;
overflow: auto;
scrollbar-color: #646c7fa9 transparent;
// position: relative;
&::-webkit-scrollbar {
width: 9px;
......@@ -196,6 +207,9 @@
flex-direction: row;
align-items: center;
justify-content: flex-end;
/* position: absolute;
top: 5;
right: 5; */
}
.heading {
font-weight: 600;
......
......@@ -12,6 +12,9 @@ import Layer from "../file-mosaic/components/file-mosaic-layer/Layer";
import FileMosaicImageLayer from "../file-mosaic/components/FIleMosaicImageLayer/FileMosaicImageLayer";
import FileCardRightLayer from "./components/FileCardRightLayer";
import FileCardInfoLayer from "./components/FileCardInfoLayer";
import FileMosaicStatus from "../file-mosaic/components/FileMosaicStatus/FileMosaicStatus";
import FileCardUploadLayer from "./components/FileCardUploadLayer";
import { Tooltip } from "../tooltip";
const setFinalElevation = (elevation: string | number): number => {
// let finalElevation: number = "";
......@@ -35,7 +38,8 @@ const makeFileCardClassName = (
className: string | undefined
): string => {
console.log("FileCard makeFileCardClassName", elevation, darkMode, className);
let finalClassName: string = "files-ui-file-card-main-container";
let finalClassName: string = "files-ui-file-card-main-container files-ui-tooltip card";
if (elevation) {
finalClassName += " elevation-" + setFinalElevation(elevation);
}
......@@ -247,6 +251,7 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
>
<Layer className="file-card-main-layer" visible={true}>
<div className="file-card-icon-plus-data">
{/** ICON + STATUS */}
<div className="file-card-icon-container">
<LayerContainer className="file-card-icon-layer">
{/** IMAGE LAYER BLUR */}
......@@ -270,19 +275,22 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
isBlur={false}
/>
</Layer>
<Layer className="file-card-status-layer" visible={true}>
<FileMosaicStatus
valid={valid}
uploadStatus={uploadStatus}
localization={localization}
/>
</Layer>
</LayerContainer>
</div>
{/** DATA */}
<div
className={
darkMode ? "file-card-data dark-mode" : "file-card-data"
}
>
<div className={"file-card-name"}>
{/* {shrinkWord(localName, true)} */}
{localName}
</div>
<div className={"file-card-name"}>{localName}</div>
<div className={"file-card-size"}>{sizeFormatted}</div>
<div className={"file-card-size"}>{shrinkWord(localType)}</div>
</div>
......@@ -313,6 +321,7 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
isActive={alwaysActive || hovering}
/>
</Layer>
<Layer className="file-card-info-layer-container" visible={showInfo}>
<FileCardInfoLayer
onCloseInfo={handleCloseInfo}
......@@ -323,47 +332,43 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
localType={localType}
/>
</Layer>
<Layer className="file-card-upload-layer" visible={isUploading}>
Upload Layer
</Layer>
</LayerContainer>
{/* <FileItemImage
imageSource={imageSource}
url={url}
fileName={localName}
backgroundBlurImage={backgroundBlurImage as boolean}
card={true}
/>
<div
className={darkMode ? "file-card-data dark-mode" : "file-card-data"}
{/** UPLOAD LAYER */}
<Layer
className="file-card-upload-layer-container"
visible={isUploading}
>
<div className={"file-card-name"}>{shrinkWord(localName, true)}</div>
<div className={"file-card-size"}>{sizeFormatted}</div>
<div className={"file-card-size"}>{shrinkWord(localType)}</div>
<div className="files-ui-file-card-upload-layer">
<FileCardUploadLayer
uploadStatus={uploadStatus}
progress={localProgress}
onCancel={onCancel ? () => onCancel?.(id) : undefined}
onAbort={
onAbort
? () => {
xhr?.abort();
onAbort?.(id);
}
: undefined
}
localization={localization}
/>
</div>
</Layer>
</LayerContainer>
<div className="files-ui-file-card-right">
<Clear
style={{ position: "absolute", right: 0, top: 0 }}
className="dui-file-item-icon"
color="rgba(255,255,255,0.851)"
onClick={handleDelete}
size="small"
colorFill="transparent"
/>
<MainLayerBodyNeo
hide={false}
<Tooltip
open={resultOnTooltip}
uploadStatus={uploadStatus}
localization={localization}
progress={progress}
onAbort={onAbort}
valid={valid}
hovering={true}
onCancel={onCancel}
errors={errors}
uploadMessage={uploadMessage}
/>
</div> */}
{downloadUrl && (
<a ref={downloadRef} href={downloadUrl} download={localName} hidden>
download_file
</a>
)}
</div>
);
}
......
......@@ -17,19 +17,18 @@ const FileCardInfoLayer: React.FC<FileCardInfoLayerProps> = (
} = props;
return (
<div className="file-card-file-info">
<div className="files-ui-file-card-info-layer-header">
{/* <FileMosaicStatus
style={{ margin: 0, right: 5, bottom: 0, position:"absolute" }}
valid={valid}
uploadStatus={uploadStatus}
localization={localization}
/> */}
<Cancel
style={{ margin: 0, right: 0, top: 0 }}
style={{ margin: 0, right: 5, top: 0, position:"absolute" }}
color="rgba(255,255,255,0.8)"
onClick={onCloseInfo}
colorFill="black"
/>
<FileMosaicStatus
valid={valid}
uploadStatus={uploadStatus}
localization={localization}
/>
</div>
<div className="heading">Name:</div>
<div className="label">{localName}</div>
<div className="heading">Size:</div>
......
.files-ui-file-card-upload-layer {
width: 100px;
height: 100%;
//background-color: rgba(0, 0, 0, 0.5);
color: rgba(255, 255, 255, 0.8);
font-weight: 500;
font-size: 1em;
position: relative;
overflow: hidden;
.elevation-list-card {
transition: all 1.5s ease;
position: absolute;
top: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.elevation-item-card {
width: 100%;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 10px;
box-sizing: border-box;
span {
text-align: center;
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; /* number of lines to show */
line-clamp: 2;
-webkit-box-orient: vertical;
}
}
}
}
import * as React from "react";
import { Localization, UPLOADSTATUS } from "../../../core";
import {
AbortedStatus,
EmptyStatus,
ErrorStatus,
PreparingStatus,
SuccessStatus,
UploadingStatus,
} from "../../file-status";
import "./FileCardUploadLayer.scss";
export interface FileCardUploadLayerPropsMap {
visible?: boolean;
uploadStatus?: UPLOADSTATUS;
onCancel?: Function;
onAbort?: Function;
progress?: number;
localization?: Localization;
}
export type FileCardUploadLayerProps = {
[T in keyof FileCardUploadLayerPropsMap]: FileCardUploadLayerPropsMap[T];
};
const FileCardUploadLayer: React.FC<FileCardUploadLayerProps> = (
props: FileCardUploadLayerProps
) => {
const { uploadStatus, onCancel, onAbort, progress, localization } = props;
const elevationContainerRef = React.useRef<HTMLDivElement | null>(null);
const listContainerStoryRef = React.useRef<HTMLDivElement | null>(null);
const [statusHistory, setStatusHistory] = React.useState<
Array<UPLOADSTATUS | undefined>
>([undefined]);
React.useEffect(() => {
setStatusHistory((statusHistory: Array<UPLOADSTATUS | undefined>) => {
if (
statusHistory[statusHistory.length - 1] === "preparing" &&
uploadStatus === "uploading"
) {
const tempStatusHistory = [...statusHistory];
tempStatusHistory[statusHistory.length - 1] = uploadStatus;
//replace
return [...tempStatusHistory];
}
return [...statusHistory, uploadStatus];
});
}, [uploadStatus]);
const elevate = () => {
const currentElevationContainer = elevationContainerRef.current;
const currentElevationList = listContainerStoryRef.current;
if (currentElevationContainer === null || currentElevationList === null)
return;
currentElevationList.style.top =
0 - (statusHistory.length - 1) * 100 + "px";
};
React.useEffect(() => {
if (statusHistory.length > 1) elevate();
// eslint-disable-next-line
}, [statusHistory.length]);
return (
<div className={"elevation-layer-container"} ref={elevationContainerRef}>
<div className="elevation-list-card" ref={listContainerStoryRef}>
{statusHistory.map((status, index) => {
switch (status) {
case "preparing":
return (
<div className="elevation-item-card" key={index + 1}>
<PreparingStatus
onCancel={onCancel}
localization={localization}
/>
</div>
);
case "uploading":
return (
<div className="elevation-item-card" key={index + 1}>
<UploadingStatus
onAbort={onAbort}
progress={progress}
localization={localization}
/>
</div>
);
case "error":
return (
<div className="elevation-item-card" key={index + 1}>
<ErrorStatus size={60} localization={localization} />
</div>
);
case "success":
return (
<div className="elevation-item-card" key={index + 1}>
<SuccessStatus localization={localization} />
</div>
);
case "aborted":
return (
<div className="elevation-item-card" key={index + 1}>
<AbortedStatus localization={localization} />
</div>
);
default:
return (
<div className="elevation-item-card" key={index + 1}>
<EmptyStatus />
</div>
);
}
})}
</div>
</div>
);
};
export default FileCardUploadLayer;
......@@ -19,7 +19,7 @@ const FileMosaicInfoLayer: React.FC<FileMosaicInfoLayerProps> = (
<React.Fragment>
<div className="files-ui-file-mosaic-info-layer-header">
<Cancel
style={{ margin: 0, right: 0, top: 0 }}
//style={{ margin: 0, right: 0, top: 0 }}
color="rgba(255,255,255,0.8)"
onClick={onCloseInfo}
colorFill="black"
......
......@@ -8,7 +8,7 @@ import { FileItemLocalizerSelector, LocalLabels } from "../../../../core";
const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
props: FileMosaicStatusProps
) => {
const { valid, uploadStatus, localization } = props;
const { valid, uploadStatus, localization, style } = props;
const FileItemStatusLocalizer: LocalLabels = FileItemLocalizerSelector(
localization
......@@ -16,7 +16,7 @@ const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
if (uploadStatus === "success") {
return (
<div className="files-ui-file-item-status-container file-status-ok">
<div className="files-ui-file-item-status-container file-status-ok" style={style}>
<CloudDone color="#4caf50" size="small" className="status-icon" />
{FileItemStatusLocalizer.success as string}
</div>
......@@ -24,7 +24,7 @@ const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
}
if (uploadStatus === "error" || uploadStatus === "aborted") {
return (
<div className="files-ui-file-item-status-container file-status-error">
<div className="files-ui-file-item-status-container file-status-error" style={style}>
<UploadError
color="#f44336"
size="semi-medium"
......@@ -37,14 +37,14 @@ const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
if (valid !== undefined && valid !== null) {
if (valid) {
return (
<div className="files-ui-file-item-status-container file-status-ok">
<div className="files-ui-file-item-status-container file-status-ok" style={style}>
<CheckCircle color="#4caf50" size="small" className="status-icon" />
{FileItemStatusLocalizer.valid as string}
</div>
);
} else {
return (
<div className="files-ui-file-item-status-container file-status-error">
<div className="files-ui-file-item-status-container file-status-error" style={style}>
<DoDisturb color="#f44336" size="small" className="status-icon" />
{FileItemStatusLocalizer.denied as string}
</div>
......
......@@ -22,4 +22,7 @@ export interface FileMosaicStatusProps {
*/
localization?: Localization;
style?:React.CSSProperties;
}
\ No newline at end of file
......@@ -163,73 +163,7 @@
}
}
/* &.files-ui-tooltip {
cursor: default;
position: relative;
display: inline-block;
box-sizing: border-box;
// border-bottom: 1px dotted black;
&:hover {
z-index: 2;
.files-ui-tooltip-tooltiptext {
visibility: visible;
opacity: 1;
z-index: 2;
}
}
.files-ui-tooltip-tooltiptext {
box-sizing: border-box;
font-family: "Poppins", sans-serif;
font-size: 0.8rem;
visibility: hidden;
width: 132px;
// background-color: green;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 2px 2px;
position: absolute;
//z-index: 2;
//top: 190px;
top: 180px;
left: 66px;
margin-left: -60px;
// Fade in tooltip - takes 1 second to go from 0% to 100% opac:
opacity: 0;
transition: opacity 1s;
&.not-valid-error {
background: linear-gradient(to top, #c62828, #d32f2f);
&::after {
border-color: transparent transparent #d32f2f transparent;
}
}
&.success {
//background-color: green;
background: linear-gradient(to top, #1b5e20, #2e7d32);
&::after {
border-color: transparent transparent #2e7d32 transparent;
}
}
&::after {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
//border-color: transparent transparent green transparent;
}
}
} */
}
//// ICONS
......
......@@ -4,6 +4,15 @@
position: relative;
//display: inline-block;
// border-bottom: 1px dotted black;
&:hover {
z-index: 2;
.files-ui-tooltiptext {
visibility: visible;
opacity: 1;
z-index: 2;
}
}
&.card {
&:hover {
z-index: 2;
.files-ui-tooltiptext {
......@@ -12,6 +21,57 @@
z-index: 2;
}
}
.files-ui-tooltiptext {
box-sizing: border-box;
font-family: "Poppins", sans-serif;
font-size: 0.8rem;
font-weight: 400;
visibility: hidden;
width: 200px;
// background-color: green;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 2px 2px;
position: absolute;
z-index: 2;
left: calc(50% - 100px);
left: 0;
margin-top: 5px;
//top: calc(100% + 5px);
top: 100%;
// Fade in tooltip - takes 1 second to go from 0% to 100% opac:
opacity: 0;
transition: opacity 1s;
&.not-valid-error {
background: linear-gradient(to top, #c62828, #d32f2f);
&::after {
border-color: transparent transparent #d32f2f transparent;
}
}
&.success {
//background-color: green;
background: linear-gradient(to top, #1b5e20, #2e7d32);
&::after {
border-color: transparent transparent #2e7d32 transparent;
}
}
&::after {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
//border-color: transparent transparent green transparent;
}
}
}
.files-ui-tooltiptext {
box-sizing: border-box;
font-family: "Poppins", sans-serif;
......@@ -46,6 +106,7 @@
border-color: transparent transparent #2e7d32 transparent;
}
}
&::after {
content: "";
position: absolute;
......
......@@ -235,6 +235,7 @@ const FileCardDemoPage = (props) => {
alignItems: "center",
justifyContent: "center",
width: "100%",
flexWrap:"wrap"
}}
>
<DemoFileMosaicDarkMode card />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment