Add more fields to shared links management screen

This commit is contained in:
Tom Moor
2023-11-05 13:39:34 -05:00
parent 9be180d44d
commit 7b88547051
6 changed files with 70 additions and 30 deletions

View File

@@ -5,12 +5,21 @@ import Header from "~/components/Header";
import PageTitle from "~/components/PageTitle";
type Props = {
/** An icon to display in the header when content has scrolled past the title */
icon?: React.ReactNode;
/** The title of the scene */
title?: React.ReactNode;
/** The title of the scene, as text only required if the title prop is not plain text */
textTitle?: string;
/** A component to display on the left side of the header */
left?: React.ReactNode;
/** A component to display on the right side of the header */
actions?: React.ReactNode;
/** Whether to center the content horizontally with the standard maximum width (default: true) */
centered?: boolean;
/** Whether to use the full width of the screen (default: false) */
wide?: boolean;
/** The content of the scene */
children?: React.ReactNode;
};
@@ -22,8 +31,9 @@ const Scene: React.FC<Props> = ({
left,
children,
centered,
wide,
}: Props) => (
<FillWidth>
<FillWidth $wide={wide}>
<PageTitle title={textTitle || title} />
<Header
hasSidebar
@@ -39,7 +49,7 @@ const Scene: React.FC<Props> = ({
actions={actions}
left={left}
/>
{centered !== false ? (
{centered !== false && wide !== true ? (
<CenteredContent withStickyHeader>{children}</CenteredContent>
) : (
children
@@ -47,8 +57,9 @@ const Scene: React.FC<Props> = ({
</FillWidth>
);
const FillWidth = styled.div`
const FillWidth = styled.div<{ $wide?: boolean }>`
width: 100%;
${(props) => props.$wide && `padding: 0px 32px 16px;`}
`;
export default Scene;

View File

@@ -27,6 +27,10 @@ class Share extends Model {
@observable
urlId: string;
@Field
@observable
domain: string;
@observable
documentTitle: string;

View File

@@ -6,6 +6,7 @@ import { useTranslation, Trans } from "react-i18next";
import { Link } from "react-router-dom";
import { PAGINATION_SYMBOL } from "~/stores/base/Store";
import Share from "~/models/Share";
import Fade from "~/components/Fade";
import Heading from "~/components/Heading";
import Notice from "~/components/Notice";
import Scene from "~/components/Scene";
@@ -67,7 +68,7 @@ function Shares() {
}, [shares.orderedData, shareIds]);
return (
<Scene title={t("Shared Links")} icon={<LinkIcon />}>
<Scene title={t("Shared Links")} icon={<LinkIcon />} wide>
<Heading>{t("Shared Links")}</Heading>
{can.update && !canShareDocuments && (
@@ -93,15 +94,19 @@ function Shares() {
</Trans>
</Text>
<SharesTable
data={data}
canManage={can.update}
isLoading={isLoading}
page={page}
pageSize={limit}
totalPages={totalPages}
defaultSortDirection="ASC"
/>
{data.length ? (
<Fade>
<SharesTable
data={data}
canManage={can.update}
isLoading={isLoading}
page={page}
pageSize={limit}
totalPages={totalPages}
defaultSortDirection="ASC"
/>
</Fade>
) : null}
</Scene>
);
}

View File

@@ -8,6 +8,7 @@ import Avatar from "~/components/Avatar";
import Flex from "~/components/Flex";
import TableFromParams from "~/components/TableFromParams";
import Time from "~/components/Time";
import Tooltip from "~/components/Tooltip";
import ShareMenu from "~/menus/ShareMenu";
type Props = Omit<React.ComponentProps<typeof TableFromParams>, "columns"> & {
@@ -15,9 +16,10 @@ type Props = Omit<React.ComponentProps<typeof TableFromParams>, "columns"> & {
canManage: boolean;
};
function SharesTable({ canManage, ...rest }: Props) {
function SharesTable({ canManage, data, ...rest }: Props) {
const { t } = useTranslation();
const theme = useTheme();
const hasDomain = data.some((share) => share.domain);
const columns = React.useMemo(
() =>
@@ -29,23 +31,28 @@ function SharesTable({ canManage, ...rest }: Props) {
disableSortBy: true,
Cell: observer(({ value }: { value: string }) => <>{value}</>),
},
{
id: "who",
Header: t("Shared by"),
accessor: "createdById",
disableSortBy: true,
Cell: observer(
({ row }: { value: string; row: { original: Share } }) => (
<Flex align="center" gap={4}>
{row.original.createdBy && (
<Avatar model={row.original.createdBy} />
)}
{row.original.createdBy.name}
</Flex>
)
),
},
{
id: "createdAt",
Header: t("Date shared"),
accessor: "createdAt",
Cell: observer(
({ value, row }: { value: string; row: { original: Share } }) =>
value ? (
<Flex align="center" gap={4}>
{row.original.createdBy && (
<Avatar
model={row.original.createdBy}
alt={row.original.createdBy.name}
/>
)}
<Time dateTime={value} addSuffix />
</Flex>
) : null
Cell: observer(({ value }: { value: string }) =>
value ? <Time dateTime={value} addSuffix /> : null
),
},
{
@@ -63,11 +70,21 @@ function SharesTable({ canManage, ...rest }: Props) {
Cell: observer(({ value }: { value: string }) =>
value ? (
<Flex align="center">
<CheckmarkIcon color={theme.accent} />
<Tooltip tooltip={t("Nested documents are publicly available")}>
<CheckmarkIcon color={theme.accent} />
</Tooltip>
</Flex>
) : null
),
},
hasDomain
? {
id: "domain",
Header: t("Domain"),
accessor: "domain",
disableSortBy: true,
}
: undefined,
{
id: "views",
Header: t("Views"),
@@ -89,10 +106,10 @@ function SharesTable({ canManage, ...rest }: Props) {
}
: undefined,
].filter((i) => i),
[t, theme.accent, canManage]
[t, theme.accent, hasDomain, canManage]
);
return <TableFromParams columns={columns} {...rest} />;
return <TableFromParams columns={columns} data={data} {...rest} />;
}
export default SharesTable;

View File

@@ -14,6 +14,7 @@ export default function presentShare(share: Share, isAdmin = false) {
includeChildDocuments: share.includeChildDocuments,
lastAccessedAt: share.lastAccessedAt || undefined,
views: share.views || 0,
domain: share.domain,
createdAt: share.createdAt,
updatedAt: share.updatedAt,
};

View File

@@ -764,8 +764,10 @@
"Shared": "Shared",
"by {{ name }}": "by {{ name }}",
"Last accessed": "Last accessed",
"Shared by": "Shared by",
"Date shared": "Date shared",
"Shared nested": "Shared nested",
"Domain": "Domain",
"Everyone": "Everyone",
"Admins": "Admins",
"Settings saved": "Settings saved",