+ {t( + "shareAssociateUserDescription" + )} +
++ {t( + "sharePersistSessionDescription" + )} +
+{t("shareExpireDescription")}
diff --git a/src/components/ShareLinksTable.tsx b/src/components/ShareLinksTable.tsx index 8394edf89..b4df1966f 100644 --- a/src/components/ShareLinksTable.tsx +++ b/src/components/ShareLinksTable.tsx @@ -35,6 +35,7 @@ import moment from "moment"; import CreateShareLinkForm from "@app/components/CreateShareLinkForm"; import { constructShareLink } from "@app/lib/shareLinks"; import { useTranslations } from "next-intl"; +import { getUserDisplayName } from "@app/lib/getUserDisplayName"; export type ShareLinkRow = { accessTokenId: string; @@ -44,6 +45,10 @@ export type ShareLinkRow = { title: string | null; createdAt: number; expiresAt: number | null; + userId?: string | null; + userName?: string | null; + username?: string | null; + userEmail?: string | null; }; type ShareLinksTableProps = { @@ -155,6 +160,41 @@ export default function ShareLinksTable({ ); } }, + { + accessorKey: "userId", + friendlyName: t("user"), + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const r = row.original; + if (!r.userId) { + return -; + } + return ( + + + + ); + } + }, // { // accessorKey: "domain", // header: "Link", diff --git a/src/components/user-selector.tsx b/src/components/user-selector.tsx new file mode 100644 index 000000000..f8ad85eea --- /dev/null +++ b/src/components/user-selector.tsx @@ -0,0 +1,106 @@ +import { orgQueries } from "@app/lib/queries"; +import { getUserDisplayName } from "@app/lib/getUserDisplayName"; +import { useQuery } from "@tanstack/react-query"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList +} from "./ui/command"; +import { useMemo, useState } from "react"; +import { useTranslations } from "next-intl"; +import { CheckIcon } from "lucide-react"; +import { cn } from "@app/lib/cn"; +import { useDebounce } from "use-debounce"; +import type { SelectedUser } from "./users-selector"; + +export type { SelectedUser }; + +export type UserSelectorProps = { + orgId: string; + selectedUser?: SelectedUser | null; + onSelectUser: (user: SelectedUser | null) => void; + allowClear?: boolean; +}; + +export function UserSelector({ + orgId, + selectedUser, + onSelectUser, + allowClear = true +}: UserSelectorProps) { + const t = useTranslations(); + const [userSearchQuery, setUserSearchQuery] = useState(""); + const [debouncedValue] = useDebounce(userSearchQuery, 150); + + const { data: users = [] } = useQuery( + orgQueries.users({ orgId, perPage: 10, query: debouncedValue }) + ); + + const usersShown = useMemo(() => { + const allUsers: Array