Connected Share object modal (#440)
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -282,6 +282,8 @@ const ObjectDetails = ({
|
||||
<ShareFile
|
||||
open={shareFileModalOpen}
|
||||
closeModalAndRefresh={closeShareModal}
|
||||
bucketName={bucketName}
|
||||
dataObject={actualInfo}
|
||||
/>
|
||||
)}
|
||||
{retentionModalOpen && (
|
||||
|
||||
@@ -115,6 +115,7 @@ const SetRetention = ({
|
||||
disableOptions={dateFieldDisabled()}
|
||||
ref={dateElement}
|
||||
borderBottom={true}
|
||||
onDateChange={() => {}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { useState } from "react";
|
||||
import CopyToClipboard from "react-copy-to-clipboard";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import CopyToClipboard from "react-copy-to-clipboard";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Snackbar from "@material-ui/core/Snackbar";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import {
|
||||
@@ -10,6 +12,9 @@ import {
|
||||
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
|
||||
import DateSelector from "../../../../Common/FormComponents/DateSelector/DateSelector";
|
||||
import { CopyIcon } from "../../../../../../icons";
|
||||
import api from "../../../../../../common/api";
|
||||
import get from "lodash/get";
|
||||
import { IFileInfo } from "./types";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -19,6 +24,9 @@ const styles = (theme: Theme) =>
|
||||
modalContent: {
|
||||
paddingBottom: 53,
|
||||
},
|
||||
errorBlock: {
|
||||
color: "red",
|
||||
},
|
||||
...modalBasic,
|
||||
...predefinedList,
|
||||
});
|
||||
@@ -26,6 +34,8 @@ const styles = (theme: Theme) =>
|
||||
interface IShareFileProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
bucketName: string;
|
||||
dataObject: IFileInfo;
|
||||
closeModalAndRefresh: () => void;
|
||||
}
|
||||
|
||||
@@ -33,45 +43,159 @@ const ShareFile = ({
|
||||
classes,
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
bucketName,
|
||||
dataObject,
|
||||
}: IShareFileProps) => {
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Share File"
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
closeModalAndRefresh();
|
||||
const [shareURL, setShareURL] = useState("");
|
||||
const [isLoadingFile, setIsLoadingFile] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [selectedDate, setSelectedDate] = useState("");
|
||||
const [dateValid, setDateValid] = useState(true);
|
||||
const [openSnack, setOpenSnack] = useState(false);
|
||||
const [snackBarMessage, setSnackbarMessage] = useState("");
|
||||
|
||||
const showSnackBarMessage = (text: string) => {
|
||||
setSnackbarMessage(text);
|
||||
setOpenSnack(true);
|
||||
};
|
||||
|
||||
const closeSnackBar = () => {
|
||||
setSnackbarMessage("");
|
||||
setOpenSnack(false);
|
||||
};
|
||||
|
||||
const dateChanged = (newDate: string, isValid: boolean) => {
|
||||
setDateValid(isValid);
|
||||
if (isValid) {
|
||||
setSelectedDate(newDate);
|
||||
return;
|
||||
}
|
||||
setShareURL("");
|
||||
setSelectedDate("");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (dateValid) {
|
||||
setIsLoadingFile(true);
|
||||
|
||||
const slDate = new Date(`${selectedDate}T23:59:59`);
|
||||
const currDate = new Date();
|
||||
|
||||
const diffDate = slDate.getTime() - currDate.getTime();
|
||||
|
||||
if (diffDate < 0) {
|
||||
setError("Selected date must be greater than current time.");
|
||||
setShareURL("");
|
||||
setIsLoadingFile(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (diffDate > 604800000) {
|
||||
setError("You can share a file only for less than 7 days.");
|
||||
setShareURL("");
|
||||
setIsLoadingFile(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/objects/share?prefix=${
|
||||
dataObject.name
|
||||
}&version_id=${dataObject.version_id}${
|
||||
selectedDate !== "" ? `&expires=${diffDate}ms` : ""
|
||||
}`
|
||||
)
|
||||
.then((res: string) => {
|
||||
setShareURL(res);
|
||||
setError("");
|
||||
setIsLoadingFile(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
setShareURL("");
|
||||
setIsLoadingFile(false);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setShareURL("");
|
||||
}, [dataObject, selectedDate]);
|
||||
|
||||
const snackBarAction = (
|
||||
<Button
|
||||
color="secondary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
closeSnackBar();
|
||||
}}
|
||||
>
|
||||
<Grid container className={classes.modalContent}>
|
||||
<Grid item xs={12} className={classes.dateContainer}>
|
||||
<DateSelector
|
||||
id="date"
|
||||
label="Active until"
|
||||
borderBottom={false}
|
||||
addSwitch={true}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={10} className={classes.predefinedList}>
|
||||
{"https://somelink.will/go/here"}
|
||||
</Grid>
|
||||
<Grid item xs={2} className={classes.copyButtonContainer}>
|
||||
<CopyToClipboard text={"https://somelink.will/go/here"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CopyIcon />}
|
||||
onClick={() => {
|
||||
console.log("copied!");
|
||||
}}
|
||||
Dismiss
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{openSnack && (
|
||||
<Snackbar
|
||||
open={openSnack}
|
||||
message={snackBarMessage}
|
||||
action={snackBarAction}
|
||||
/>
|
||||
)}
|
||||
<ModalWrapper
|
||||
title="Share File"
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
closeModalAndRefresh();
|
||||
}}
|
||||
>
|
||||
<Grid container className={classes.modalContent}>
|
||||
{error !== "" && (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
Copy
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
{error}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12} className={classes.dateContainer}>
|
||||
<DateSelector
|
||||
id="date"
|
||||
label="Active until"
|
||||
borderBottom={false}
|
||||
addSwitch={true}
|
||||
onDateChange={dateChanged}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={10} className={classes.predefinedList}>
|
||||
{shareURL}
|
||||
</Grid>
|
||||
<Grid item xs={2} className={classes.copyButtonContainer}>
|
||||
<CopyToClipboard text={shareURL}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CopyIcon />}
|
||||
onClick={() => {
|
||||
showSnackBarMessage("Share URL Copied to clipboard");
|
||||
}}
|
||||
disabled={shareURL === "" || isLoadingFile}
|
||||
>
|
||||
Copy
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ModalWrapper>
|
||||
</ModalWrapper>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,25 @@
|
||||
import React, { useState, forwardRef, useImperativeHandle } from "react";
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, {
|
||||
useState,
|
||||
forwardRef,
|
||||
useImperativeHandle,
|
||||
useEffect,
|
||||
} from "react";
|
||||
import clsx from "clsx";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
@@ -11,6 +32,7 @@ import MenuItem from "@material-ui/core/MenuItem";
|
||||
import InputBase from "@material-ui/core/InputBase";
|
||||
import { fieldBasic, tooltipHelper } from "../common/styleLibrary";
|
||||
import FormSwitchWrapper from "../FormSwitchWrapper/FormSwitchWrapper";
|
||||
import { days, months, validDate, years } from "./utils";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -64,6 +86,7 @@ interface IDateSelectorProps {
|
||||
addSwitch?: boolean;
|
||||
tooltip?: string;
|
||||
borderBottom?: boolean;
|
||||
onDateChange: (date: string, isValid: boolean) => any;
|
||||
}
|
||||
|
||||
const DateSelector = forwardRef(
|
||||
@@ -76,6 +99,7 @@ const DateSelector = forwardRef(
|
||||
addSwitch = false,
|
||||
tooltip = "",
|
||||
borderBottom = false,
|
||||
onDateChange,
|
||||
}: IDateSelectorProps,
|
||||
ref: any
|
||||
) => {
|
||||
@@ -86,6 +110,11 @@ const DateSelector = forwardRef(
|
||||
const [day, setDay] = useState<string>("");
|
||||
const [year, setYear] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
const [isValid, dateString] = validDate(year, month, day);
|
||||
onDateChange(dateString, isValid);
|
||||
}, [month, day, year]);
|
||||
|
||||
const resetDate = () => {
|
||||
setMonth("");
|
||||
setDay("");
|
||||
@@ -142,13 +171,16 @@ const DateSelector = forwardRef(
|
||||
</InputLabel>
|
||||
{addSwitch && (
|
||||
<FormSwitchWrapper
|
||||
indicatorLabels={["Specific Date", "Always active"]}
|
||||
indicatorLabels={["Specific Date", "Default (7 Days)"]}
|
||||
checked={dateEnabled}
|
||||
value={"date_enabled"}
|
||||
id="date-status"
|
||||
name="date-status"
|
||||
onChange={(e) => {
|
||||
setDateEnabled(e.target.checked);
|
||||
if (!e.target.checked) {
|
||||
onDateChange("", true);
|
||||
}
|
||||
}}
|
||||
switchOnly
|
||||
/>
|
||||
@@ -171,15 +203,14 @@ const DateSelector = forwardRef(
|
||||
<MenuItem value="" disabled>
|
||||
{"<Month>"}
|
||||
</MenuItem>
|
||||
<MenuItem value={"1"}>January</MenuItem>
|
||||
{/* {options.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${name}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))} */}
|
||||
{months.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${id}-monthOP-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
@@ -197,16 +228,14 @@ const DateSelector = forwardRef(
|
||||
<MenuItem value="" disabled>
|
||||
{"<Day>"}
|
||||
</MenuItem>
|
||||
<MenuItem value={"1"}>1</MenuItem>
|
||||
<MenuItem value={"2"}>2</MenuItem>
|
||||
{/* {options.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${name}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))} */}
|
||||
{days.map((dayNumber) => (
|
||||
<MenuItem
|
||||
value={dayNumber}
|
||||
key={`select-${id}-dayOP-${dayNumber}`}
|
||||
>
|
||||
{dayNumber}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
@@ -224,16 +253,11 @@ const DateSelector = forwardRef(
|
||||
<MenuItem value="" disabled>
|
||||
{"<Year>"}
|
||||
</MenuItem>
|
||||
<MenuItem value={"2020"}>2020</MenuItem>
|
||||
<MenuItem value={"2021"}>2021</MenuItem>
|
||||
{/* {options.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${name}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))} */}
|
||||
{years.map((year) => (
|
||||
<MenuItem value={year} key={`select-${id}-yearOP-${year}`}>
|
||||
{year}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export const months = [
|
||||
{ value: "01", label: "January" },
|
||||
{ value: "02", label: "February" },
|
||||
{ value: "03", label: "March" },
|
||||
{ value: "04", label: "April" },
|
||||
{ value: "05", label: "May" },
|
||||
{ value: "06", label: "June" },
|
||||
{ value: "07", label: "July" },
|
||||
{ value: "08", label: "August" },
|
||||
{ value: "09", label: "September" },
|
||||
{ value: "10", label: "October" },
|
||||
{ value: "11", label: "November" },
|
||||
{ value: "12", label: "December" },
|
||||
];
|
||||
|
||||
export const days = Array.from(Array(31), (_, num) => num + 1);
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
export const years = Array.from(
|
||||
Array(25),
|
||||
(_, numYear) => numYear + currentYear
|
||||
);
|
||||
|
||||
export const validDate = (
|
||||
year: string,
|
||||
month: string,
|
||||
day: string
|
||||
): [boolean, string] => {
|
||||
const currentDate = Date.parse(`${year}-${month}-${day}`);
|
||||
|
||||
if (isNaN(currentDate)) {
|
||||
return [false, ""];
|
||||
}
|
||||
|
||||
const parsedMonth = parseInt(month);
|
||||
const parsedDay = parseInt(day);
|
||||
|
||||
const monthForString = parsedMonth < 10 ? `0${parsedMonth}` : parsedMonth;
|
||||
const dayForString = parsedDay < 10 ? `0${parsedDay}` : parsedDay;
|
||||
|
||||
const parsedDate = new Date(currentDate).toISOString().split("T")[0];
|
||||
const dateString = `${year}-${monthForString}-${dayForString}`;
|
||||
|
||||
return [parsedDate === dateString, dateString];
|
||||
};
|
||||
@@ -184,6 +184,13 @@ export const predefinedList = {
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
minHeight: 41,
|
||||
height: 41,
|
||||
overflowX: "auto" as const,
|
||||
whiteSpace: "nowrap" as const,
|
||||
scrollbarWidth: "none" as const,
|
||||
"&::-webkit-scrollbar": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user