Skip to content

Commit

Permalink
feat: Adding more informations on My Shares page (table and modal) (#174
Browse files Browse the repository at this point in the history
)

* Adding an information button to the shares and corrected MyShare interface

* Adding other informations and disk usage

* Adding description, disk usage

* Add case if the expiration is never

* Adding file size and better UI

* UI changes to Information Modal

* Adding description to the My Shares page

* Ran format

* Remove string type

Co-authored-by: Elias Schneider <[email protected]>

* Remove string type check

Co-authored-by: Elias Schneider <[email protected]>

* Remove string type conversion

Co-authored-by: Elias Schneider <[email protected]>

* Variable name changes

Co-authored-by: Elias Schneider <[email protected]>

* Remove color

Co-authored-by: Elias Schneider <[email protected]>

* Requested changes made

* Ran format

* Adding MediaQuery

---------

Co-authored-by: Elias Schneider <[email protected]>
  • Loading branch information
pierrbt and stonith404 committed Jun 26, 2023
1 parent 348852c commit 1466240
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 6 deletions.
16 changes: 13 additions & 3 deletions backend/src/share/dto/myShare.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Expose, plainToClass } from "class-transformer";
import { Expose, plainToClass, Type } from "class-transformer";
import { ShareDTO } from "./share.dto";
import {FileDTO} from "../../file/dto/file.dto";
import {OmitType} from "@nestjs/swagger";

export class MyShareDTO extends ShareDTO {
export class MyShareDTO extends OmitType(ShareDTO, [
"files",
"from",
"fromList",
] as const) {
@Expose()
views: number;

Expand All @@ -11,6 +17,10 @@ export class MyShareDTO extends ShareDTO {
@Expose()
recipients: string[];

@Expose()
@Type(() => OmitType(FileDTO, ["share", "from"] as const))
files: Omit<FileDTO, "share" | "from">[];

from(partial: Partial<MyShareDTO>) {
return plainToClass(MyShareDTO, partial, { excludeExtraneousValues: true });
}
Expand All @@ -20,4 +30,4 @@ export class MyShareDTO extends ShareDTO {
plainToClass(MyShareDTO, part, { excludeExtraneousValues: true })
);
}
}
}
2 changes: 1 addition & 1 deletion backend/src/share/share.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export class ShareService {
orderBy: {
expiration: "desc",
},
include: { recipients: true },
include: { recipients: true, files: true },
});

return shares.map((share) => {
Expand Down
85 changes: 85 additions & 0 deletions frontend/src/components/account/showShareInformationsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Text, Divider, Progress, Stack, Group, Flex } from "@mantine/core";
import { ModalsContextProps } from "@mantine/modals/lib/context";
import { MyShare } from "../../types/share.type";
import moment from "moment";
import { byteToHumanSizeString } from "../../utils/fileSize.util";
import CopyTextField from "../upload/CopyTextField";
import { FileMetaData } from "../../types/File.type";

const showShareInformationsModal = (
modals: ModalsContextProps,
share: MyShare,
appUrl: string,
maxShareSize: number
) => {
const link = `${appUrl}/share/${share.id}`;

let shareSize: number = 0;
for (let file of share.files as FileMetaData[])
shareSize += parseInt(file.size);

const formattedShareSize = byteToHumanSizeString(shareSize);
const formattedMaxShareSize = byteToHumanSizeString(maxShareSize);
const shareSizeProgress = (shareSize / maxShareSize) * 100;

const formattedCreatedAt = moment(share.createdAt).format("LLL");
const formattedExpiration =
moment(share.expiration).unix() === 0
? "Never"
: moment(share.expiration).format("LLL");

return modals.openModal({
title: "Share informations",

children: (
<Stack align="stretch" spacing="md">
<Text size="sm" color="lightgray">
<b>ID:</b> {share.id}
</Text>

<Text size="sm" color="lightgray">
<b>Description:</b> {share.description || "No description"}
</Text>

<Text size="sm" color="lightgray">
<b>Created at:</b> {formattedCreatedAt}
</Text>

<Text size="sm" color="lightgray">
<b>Expires at:</b> {formattedExpiration}
</Text>

<Divider />

<CopyTextField link={link} />

<Divider />

<Text size="sm" color="lightgray">
<b>Size:</b> {formattedShareSize} / {formattedMaxShareSize} (
{shareSizeProgress.toFixed(1)}%)
</Text>

<Flex align="center" justify="center">
{shareSize / maxShareSize < 0.1 && (
<Text size="xs" color="lightgray" style={{ marginRight: "4px" }}>
{formattedShareSize}
</Text>
)}
<Progress
value={shareSizeProgress}
label={shareSize / maxShareSize >= 0.1 ? formattedShareSize : ""}
style={{ width: shareSize / maxShareSize < 0.1 ? "70%" : "80%" }}
size="xl"
radius="xl"
/>
<Text size="xs" color="lightgray" style={{ marginLeft: "4px" }}>
{formattedMaxShareSize}
</Text>
</Flex>
</Stack>
),
});
};

export default showShareInformationsModal;
35 changes: 34 additions & 1 deletion frontend/src/pages/account/shares.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Button,
Center,
Group,
MediaQuery,
Space,
Stack,
Table,
Expand All @@ -15,14 +16,15 @@ import { useModals } from "@mantine/modals";
import moment from "moment";
import Link from "next/link";
import { useEffect, useState } from "react";
import { TbLink, TbTrash } from "react-icons/tb";
import { TbLink, TbTrash, TbInfoCircle } from "react-icons/tb";
import showShareLinkModal from "../../components/account/showShareLinkModal";
import CenterLoader from "../../components/core/CenterLoader";
import Meta from "../../components/Meta";
import useConfig from "../../hooks/config.hook";
import shareService from "../../services/share.service";
import { MyShare } from "../../types/share.type";
import toast from "../../utils/toast.util";
import showShareInformationsModal from "../../components/account/showShareInformationsModal";

const MyShares = () => {
const modals = useModals();
Expand Down Expand Up @@ -60,6 +62,10 @@ const MyShares = () => {
<thead>
<tr>
<th>Name</th>
<MediaQuery smallerThan="md" styles={{ display: "none" }}>
<th>Description</th>
</MediaQuery>

<th>Visitors</th>
<th>Expires at</th>
<th></th>
Expand All @@ -69,6 +75,18 @@ const MyShares = () => {
{shares.map((share) => (
<tr key={share.id}>
<td>{share.id}</td>
<MediaQuery smallerThan="sm" styles={{ display: "none" }}>
<td
style={{
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
maxWidth: "300px",
}}
>
{share.description || ""}
</td>
</MediaQuery>
<td>{share.views}</td>
<td>
{moment(share.expiration).unix() === 0
Expand All @@ -77,6 +95,21 @@ const MyShares = () => {
</td>
<td>
<Group position="right">
<ActionIcon
color="blue"
variant="light"
size={25}
onClick={() => {
showShareInformationsModal(
modals,
share,
config.get("general.appUrl"),
parseInt(config.get("share.maxSize"))
);
}}
>
<TbInfoCircle />
</ActionIcon>
<ActionIcon
color="victoria"
variant="light"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/types/share.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export type ShareMetaData = {

export type MyShare = Share & {
views: number;
cratedAt: Date;
createdAt: Date;
};

export type MyReverseShare = {
Expand Down

0 comments on commit 1466240

Please sign in to comment.