Skip to content

Commit

Permalink
Merge branch 'master' into license
Browse files Browse the repository at this point in the history
  • Loading branch information
anjalshireesh authored Dec 15, 2023
2 parents bc23862 + 044e570 commit 71f2c89
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 20 deletions.
31 changes: 31 additions & 0 deletions portal-ui/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,44 @@ export const erasureCodeCalc = (
};
};

// 92400 seconds -> 1 day, 1 hour, 40 minutes.
export const niceTimeFromSeconds = (seconds: number): string => {
const days = Math.floor(seconds / (3600 * 24));
const hours = Math.floor((seconds % (3600 * 24)) / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;

const parts = [];

if (days > 0) {
parts.push(`${days} day${days !== 1 ? "s" : ""}`);
}

if (hours > 0) {
parts.push(`${hours} hour${hours !== 1 ? "s" : ""}`);
}

if (minutes > 0) {
parts.push(`${minutes} minute${minutes !== 1 ? "s" : ""}`);
}

if (remainingSeconds > 0) {
parts.push(
`${remainingSeconds} second${remainingSeconds !== 1 ? "s" : ""}`,
);
}

return parts.join(" and ");
};

// seconds / minutes /hours / Days / Years calculator
export const niceDays = (secondsValue: string, timeVariant: string = "s") => {
let seconds = parseFloat(secondsValue);

return niceDaysInt(seconds, timeVariant);
};

// niceDaysInt returns the string in the max unit found e.g. 92400 seconds -> 1 day
export const niceDaysInt = (seconds: number, timeVariant: string = "s") => {
switch (timeVariant) {
case "ns":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const initialState: BucketDetailsState = {
};

export const bucketDetailsSlice = createSlice({
name: "trace",
name: "bucketDetails",
initialState,
reducers: {
setBucketDetailsTab: (state, action: PayloadAction<string>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,22 @@

import React, { Fragment, useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { Button, CopyIcon, ReadBox, ShareIcon, Grid, ProgressBar } from "mds";
import {
Button,
CopyIcon,
ReadBox,
ShareIcon,
Grid,
ProgressBar,
Tooltip,
} from "mds";
import CopyToClipboard from "react-copy-to-clipboard";
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
import DaysSelector from "../../../../Common/FormComponents/DaysSelector/DaysSelector";
import { encodeURLString } from "../../../../../../common/utils";
import {
encodeURLString,
niceTimeFromSeconds,
} from "../../../../../../common/utils";
import {
selDistSet,
setModalErrorSnackMessage,
Expand All @@ -30,6 +41,8 @@ import { useAppDispatch } from "../../../../../../store";
import { BucketObject } from "api/consoleApi";
import { api } from "api";
import { errorToHandler } from "api/errors";
import { getMaxShareLinkExpTime } from "screens/Console/ObjectBrowser/objectBrowserThunks";
import { maxShareLinkExpTime } from "screens/Console/ObjectBrowser/objectBrowserSlice";

interface IShareFileProps {
open: boolean;
Expand All @@ -46,6 +59,7 @@ const ShareFile = ({
}: IShareFileProps) => {
const dispatch = useAppDispatch();
const distributedSetup = useSelector(selDistSet);
const maxshareLinkExpTimeVal = useSelector(maxShareLinkExpTime);
const [shareURL, setShareURL] = useState<string>("");
const [isLoadingVersion, setIsLoadingVersion] = useState<boolean>(true);
const [isLoadingFile, setIsLoadingFile] = useState<boolean>(false);
Expand All @@ -65,6 +79,10 @@ const ShareFile = ({
setShareURL("");
};

useEffect(() => {
dispatch(getMaxShareLinkExpTime());
}, [dispatch]);

useEffect(() => {
// In case version is undefined, we get the latest version of the object
if (dataObject.version_id === undefined) {
Expand Down Expand Up @@ -172,19 +190,36 @@ const ShareFile = ({
fontWeight: 400,
}}
>
This is a temporary URL with integrated access credentials for
sharing objects valid for up to 7 days.
<br />
<br />
The temporary URL expires after the configured time limit.
<Tooltip
placement="right"
tooltip={
<span>
You can reset your session by logging out and logging back
in to the web UI. <br /> <br />
You can increase the maximum configuration time by setting
the MINIO_STS_DURATION environment variable on all your
nodes. <br /> <br />
You can use <b>mc share</b> as an alternative to this UI,
where the session length does not limit the URL validity.
</span>
}
>
<span>
The following URL lets you share this object without requiring
a login. <br />
The URL expires automatically at the earlier of your
configured time ({niceTimeFromSeconds(maxshareLinkExpTimeVal)}
) or the expiration of your current web session.
</span>
</Tooltip>
</Grid>
<br />
<Grid item xs={12}>
<DaysSelector
initialDate={initialDate}
id="date"
label="Active for"
maxDays={7}
maxSeconds={maxshareLinkExpTimeVal}
onChange={dateChanged}
entity="Link"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@ import React, { useEffect, useState } from "react";
import { DateTime } from "luxon";
import { Box, InputBox, InputLabel, LinkIcon } from "mds";

const DAY_SECONDS = 86400;
const HOUR_SECONDS = 3600;
const HOUR_MINUTES = 60;

interface IDaysSelector {
id: string;
initialDate: Date;
maxDays?: number;
maxSeconds: number;
label: string;
entity: string;
onChange: (newDate: string, isValid: boolean) => void;
Expand All @@ -43,16 +47,27 @@ const DaysSelector = ({
id,
initialDate,
label,
maxDays,
maxSeconds,
entity,
onChange,
}: IDaysSelector) => {
const [selectedDays, setSelectedDays] = useState<number>(7);
const maxDays = Math.floor(maxSeconds / DAY_SECONDS);
const maxHours = Math.floor((maxSeconds % DAY_SECONDS) / HOUR_SECONDS);
const maxMinutes = Math.floor((maxSeconds % HOUR_SECONDS) / HOUR_MINUTES);

const [selectedDays, setSelectedDays] = useState<number>(0);
const [selectedHours, setSelectedHours] = useState<number>(0);
const [selectedMinutes, setSelectedMinutes] = useState<number>(0);
const [validDate, setValidDate] = useState<boolean>(true);
const [dateSelected, setDateSelected] = useState<DateTime>(DateTime.now());

// Set initial values
useEffect(() => {
setSelectedDays(maxDays);
setSelectedHours(maxHours);
setSelectedMinutes(maxMinutes);
}, [maxDays, maxHours, maxMinutes]);

useEffect(() => {
if (
!isNaN(selectedHours) &&
Expand Down Expand Up @@ -82,9 +97,11 @@ const DaysSelector = ({
// Basic validation for inputs
useEffect(() => {
let valid = true;

if (
selectedDays < 0 ||
(maxDays && selectedDays > maxDays) ||
selectedDays > 7 ||
selectedDays > maxDays ||
isNaN(selectedDays)
) {
valid = false;
Expand All @@ -98,12 +115,16 @@ const DaysSelector = ({
valid = false;
}

if (
maxDays &&
selectedDays === maxDays &&
(selectedHours !== 0 || selectedMinutes !== 0)
) {
valid = false;
if (selectedDays === maxDays) {
if (selectedHours > maxHours) {
valid = false;
}

if (selectedHours === maxHours) {
if (selectedMinutes > maxMinutes) {
valid = false;
}
}
}

if (selectedDays <= 0 && selectedHours <= 0 && selectedMinutes <= 0) {
Expand All @@ -114,6 +135,8 @@ const DaysSelector = ({
}, [
dateSelected,
maxDays,
maxHours,
maxMinutes,
onChange,
selectedDays,
selectedHours,
Expand Down Expand Up @@ -165,7 +188,7 @@ const DaysSelector = ({
className={`reverseInput removeArrows`}
type="number"
min="0"
max={maxDays ? maxDays.toString() : "999"}
max="7"
label="Days"
name={id}
onChange={(e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
BucketVersioningResponse,
GetBucketRetentionConfig,
} from "api/consoleApi";
import { AppState } from "store";

const defaultRewind = {
rewindEnabled: false,
Expand Down Expand Up @@ -76,6 +77,7 @@ const initialState: ObjectBrowserState = {
validity: 0,
},
longFileOpen: false,
maxShareLinkExpTime: 0,
};

export const objectBrowserSlice = createSlice({
Expand Down Expand Up @@ -371,6 +373,9 @@ export const objectBrowserSlice = createSlice({
setAnonymousAccessOpen: (state, action: PayloadAction<boolean>) => {
state.anonymousAccessOpen = action.payload;
},
setMaxShareLinkExpTime: (state, action: PayloadAction<number>) => {
state.maxShareLinkExpTime = action.payload;
},
errorInConnection: (state, action: PayloadAction<boolean>) => {
state.connectionError = action.payload;
if (action.payload) {
Expand Down Expand Up @@ -425,7 +430,11 @@ export const {
setSelectedBucket,
setLongFileOpen,
setAnonymousAccessOpen,
setMaxShareLinkExpTime,
errorInConnection,
} = objectBrowserSlice.actions;

export const maxShareLinkExpTime = (state: AppState) =>
state.objectBrowser.maxShareLinkExpTime;

export default objectBrowserSlice.reducer;
16 changes: 16 additions & 0 deletions portal-ui/src/screens/Console/ObjectBrowser/objectBrowserThunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
failObject,
setAnonymousAccessOpen,
setDownloadRenameModal,
setMaxShareLinkExpTime,
setNewObject,
setPreviewOpen,
setSelectedPreview,
Expand All @@ -37,6 +38,7 @@ import {
} from "./objectBrowserSlice";
import { setSnackBarMessage } from "../../../systemSlice";
import { DateTime } from "luxon";
import { api } from "api";

export const downloadSelected = createAsyncThunk(
"objectBrowser/downloadSelected",
Expand Down Expand Up @@ -203,3 +205,17 @@ export const openAnonymousAccess = createAsyncThunk(
}
},
);

export const getMaxShareLinkExpTime = createAsyncThunk(
"objectBrowser/maxShareLinkExpTime",
async (_, { rejectWithValue, dispatch }) => {
return api.buckets
.getMaxShareLinkExp()
.then((res) => {
dispatch(setMaxShareLinkExpTime(res.data.exp));
})
.catch(async (res) => {
return rejectWithValue(res.error);
});
},
);
1 change: 1 addition & 0 deletions portal-ui/src/screens/Console/ObjectBrowser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface ObjectBrowserState {
longFileOpen: boolean;
anonymousAccessOpen: boolean;
connectionError: boolean;
maxShareLinkExpTime: number;
}

export interface ObjectManager {
Expand Down

0 comments on commit 71f2c89

Please sign in to comment.