2025-01-21 15:31:05 +01:00
|
|
|
import { useCallback, useState, useMemo, useEffect } from 'react';
|
|
|
|
|
import { Link } from 'react-router-dom';
|
|
|
|
|
import debounce from 'lodash/debounce';
|
|
|
|
|
import { TrashIcon, MessageSquare, ArrowUpDown } from 'lucide-react';
|
|
|
|
|
import type { SharedLinkItem, SharedLinksListParams } from 'librechat-data-provider';
|
|
|
|
|
import {
|
|
|
|
|
OGDialog,
|
|
|
|
|
OGDialogTrigger,
|
|
|
|
|
OGDialogContent,
|
|
|
|
|
OGDialogHeader,
|
|
|
|
|
OGDialogTitle,
|
|
|
|
|
Button,
|
|
|
|
|
TooltipAnchor,
|
|
|
|
|
Label,
|
|
|
|
|
} from '~/components/ui';
|
|
|
|
|
import { useDeleteSharedLinkMutation, useSharedLinksQuery } from '~/data-provider';
|
2024-09-13 08:59:09 -04:00
|
|
|
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
2025-01-21 15:31:05 +01:00
|
|
|
import { useLocalize, useMediaQuery } from '~/hooks';
|
|
|
|
|
import DataTable from '~/components/ui/DataTable';
|
|
|
|
|
import { NotificationSeverity } from '~/common';
|
|
|
|
|
import { useToastContext } from '~/Providers';
|
|
|
|
|
import { formatDate } from '~/utils';
|
|
|
|
|
import { Spinner } from '~/components/svg';
|
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature
* ✨ feat: add shared links functions to data service
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
* ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId
Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
* ✨ feat: Add share schema and data access functions to API models
* ✨ feat: Add share endpoint to API
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
* ♻️ refactor(utils): generalize react-query cache manipulation functions
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.
- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
* ✨ feat(shared-link): add functions to manipulate shared link cache list
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
* ✨ feat: Add mutations and queries for shared links
* ✨ feat(shared-link): add `Share` button to conversation list
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
* ♻️ refactor(hooks): generalize useNavScrolling for broader use
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
* ✨ feat(settings): add shared links listing table with delete functionality in settings
- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
* ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use
* ♻️ refactor: update useGetSharedMessages to return TSharedLink
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
* ✨ feat(shared link): add UI for displaying shared conversations without authentication
- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
* 🔧 chore: Add translations
Translate labels only. Messages remain in English as they are possibly subject to change.
* ♻️ refactor: add icon and tooltip props to EditMenuButton component
* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* ♻️irefactor: added DropdownMenu for Export and Share
* ♻️ refactor: renamed component names more intuitive
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
* 🌍 chore: updated translations
* 🐞 Fix: OpenID Profile Image Download (#2757)
* Add fetch requirement
Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function
* Update openidStrategy.js
---------
Co-authored-by: Danny Avila <danacordially@gmail.com>
* 🚑 fix(export): Issue exporting Conversation with Assistants (#2769)
* 🚑 fix(export): use content as text if content is present in the message
If the endpoint is assistants, the text of the message goes into content, not message.text.
* refactor(ExportModel): TypeScript, remove unused code
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
* 📤style: export button icon (#2752)
* refactor(ShareDialog): logic and styling
* refactor(ExportAndShareMenu): imports order and icon update
* chore: imports
* chore: imports/render logic
* feat: message branching
* refactor: add optional config to useGetStartupConfig
* refactor: disable endpoints query
* chore: fix search view styling gradient in light mode
* style: ShareView gradient styling
* refactor(Share): use select queries
* style: shared link table buttons
* localization and dark text styling
* style: fix clipboard button layout shift app-wide and add localization for copy code
* support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages
* add localizations
* comparisons
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com>
Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2024-05-17 18:13:32 -04:00
|
|
|
|
2025-01-21 15:31:05 +01:00
|
|
|
const PAGE_SIZE = 25;
|
|
|
|
|
|
|
|
|
|
const DEFAULT_PARAMS: SharedLinksListParams = {
|
|
|
|
|
pageSize: PAGE_SIZE,
|
|
|
|
|
isPublic: true,
|
|
|
|
|
sortBy: 'createdAt',
|
|
|
|
|
sortDirection: 'desc',
|
|
|
|
|
search: '',
|
|
|
|
|
};
|
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature
* ✨ feat: add shared links functions to data service
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
* ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId
Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
* ✨ feat: Add share schema and data access functions to API models
* ✨ feat: Add share endpoint to API
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
* ♻️ refactor(utils): generalize react-query cache manipulation functions
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.
- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
* ✨ feat(shared-link): add functions to manipulate shared link cache list
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
* ✨ feat: Add mutations and queries for shared links
* ✨ feat(shared-link): add `Share` button to conversation list
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
* ♻️ refactor(hooks): generalize useNavScrolling for broader use
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
* ✨ feat(settings): add shared links listing table with delete functionality in settings
- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
* ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use
* ♻️ refactor: update useGetSharedMessages to return TSharedLink
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
* ✨ feat(shared link): add UI for displaying shared conversations without authentication
- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
* 🔧 chore: Add translations
Translate labels only. Messages remain in English as they are possibly subject to change.
* ♻️ refactor: add icon and tooltip props to EditMenuButton component
* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* ♻️irefactor: added DropdownMenu for Export and Share
* ♻️ refactor: renamed component names more intuitive
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
* 🌍 chore: updated translations
* 🐞 Fix: OpenID Profile Image Download (#2757)
* Add fetch requirement
Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function
* Update openidStrategy.js
---------
Co-authored-by: Danny Avila <danacordially@gmail.com>
* 🚑 fix(export): Issue exporting Conversation with Assistants (#2769)
* 🚑 fix(export): use content as text if content is present in the message
If the endpoint is assistants, the text of the message goes into content, not message.text.
* refactor(ExportModel): TypeScript, remove unused code
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
* 📤style: export button icon (#2752)
* refactor(ShareDialog): logic and styling
* refactor(ExportAndShareMenu): imports order and icon update
* chore: imports
* chore: imports/render logic
* feat: message branching
* refactor: add optional config to useGetStartupConfig
* refactor: disable endpoints query
* chore: fix search view styling gradient in light mode
* style: ShareView gradient styling
* refactor(Share): use select queries
* style: shared link table buttons
* localization and dark text styling
* style: fix clipboard button layout shift app-wide and add localization for copy code
* support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages
* add localizations
* comparisons
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com>
Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2024-05-17 18:13:32 -04:00
|
|
|
|
|
|
|
|
export default function SharedLinks() {
|
|
|
|
|
const localize = useLocalize();
|
2025-01-21 15:31:05 +01:00
|
|
|
const { showToast } = useToastContext();
|
|
|
|
|
const isSmallScreen = useMediaQuery('(max-width: 768px)');
|
|
|
|
|
const [queryParams, setQueryParams] = useState<SharedLinksListParams>(DEFAULT_PARAMS);
|
|
|
|
|
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
|
|
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
|
|
|
|
|
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, refetch, isLoading } =
|
|
|
|
|
useSharedLinksQuery(queryParams, {
|
|
|
|
|
enabled: isOpen,
|
|
|
|
|
staleTime: 0,
|
|
|
|
|
cacheTime: 5 * 60 * 1000,
|
|
|
|
|
refetchOnWindowFocus: false,
|
|
|
|
|
refetchOnMount: false,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const handleSort = useCallback((sortField: string, sortOrder: 'asc' | 'desc') => {
|
|
|
|
|
setQueryParams((prev) => ({
|
|
|
|
|
...prev,
|
|
|
|
|
sortBy: sortField as 'title' | 'createdAt',
|
|
|
|
|
sortDirection: sortOrder,
|
|
|
|
|
}));
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const handleFilterChange = useCallback((value: string) => {
|
|
|
|
|
const encodedValue = encodeURIComponent(value.trim());
|
|
|
|
|
setQueryParams((prev) => ({
|
|
|
|
|
...prev,
|
|
|
|
|
search: encodedValue,
|
|
|
|
|
}));
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const debouncedFilterChange = useMemo(
|
|
|
|
|
() => debounce(handleFilterChange, 300),
|
|
|
|
|
[handleFilterChange],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
return () => {
|
|
|
|
|
debouncedFilterChange.cancel();
|
|
|
|
|
};
|
|
|
|
|
}, [debouncedFilterChange]);
|
|
|
|
|
|
|
|
|
|
const allLinks = useMemo(() => {
|
|
|
|
|
if (!data?.pages) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data.pages.flatMap((page) => page.links.filter(Boolean));
|
|
|
|
|
}, [data?.pages]);
|
|
|
|
|
|
|
|
|
|
const deleteMutation = useDeleteSharedLinkMutation({
|
|
|
|
|
onSuccess: async () => {
|
|
|
|
|
setIsDeleteOpen(false);
|
|
|
|
|
setDeleteRow(null);
|
|
|
|
|
await refetch();
|
|
|
|
|
},
|
|
|
|
|
onError: (error) => {
|
|
|
|
|
console.error('Delete error:', error);
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize('com_ui_share_delete_error'),
|
|
|
|
|
severity: NotificationSeverity.ERROR,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const handleDelete = useCallback(
|
|
|
|
|
async (selectedRows: SharedLinkItem[]) => {
|
|
|
|
|
const validRows = selectedRows.filter(
|
|
|
|
|
(row) => typeof row.shareId === 'string' && row.shareId.length > 0,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (validRows.length === 0) {
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize('com_ui_no_valid_items'),
|
|
|
|
|
severity: NotificationSeverity.WARNING,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
for (const row of validRows) {
|
|
|
|
|
await deleteMutation.mutateAsync({ shareId: row.shareId });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize(
|
|
|
|
|
validRows.length === 1
|
|
|
|
|
? 'com_ui_shared_link_delete_success'
|
|
|
|
|
: 'com_ui_shared_link_bulk_delete_success',
|
|
|
|
|
),
|
|
|
|
|
severity: NotificationSeverity.SUCCESS,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to delete shared links:', error);
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize('com_ui_bulk_delete_error'),
|
|
|
|
|
severity: NotificationSeverity.ERROR,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[deleteMutation, showToast, localize],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const handleFetchNextPage = useCallback(async () => {
|
|
|
|
|
if (hasNextPage !== true || isFetchingNextPage) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await fetchNextPage();
|
|
|
|
|
}, [fetchNextPage, hasNextPage, isFetchingNextPage]);
|
|
|
|
|
|
|
|
|
|
const [deleteRow, setDeleteRow] = useState<SharedLinkItem | null>(null);
|
|
|
|
|
|
|
|
|
|
const confirmDelete = useCallback(() => {
|
|
|
|
|
if (deleteRow) {
|
|
|
|
|
handleDelete([deleteRow]);
|
|
|
|
|
}
|
|
|
|
|
setIsDeleteOpen(false);
|
|
|
|
|
}, [deleteRow, handleDelete]);
|
|
|
|
|
|
|
|
|
|
const columns = useMemo(
|
|
|
|
|
() => [
|
|
|
|
|
{
|
|
|
|
|
accessorKey: 'title',
|
|
|
|
|
header: ({ column }) => {
|
|
|
|
|
return (
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
className="px-2 py-0 text-xs hover:bg-surface-hover sm:px-2 sm:py-2 sm:text-sm"
|
|
|
|
|
onClick={() => handleSort('title', column.getIsSorted() === 'asc' ? 'desc' : 'asc')}
|
|
|
|
|
>
|
|
|
|
|
{localize('com_ui_name')}
|
|
|
|
|
<ArrowUpDown className="ml-2 h-3 w-4 sm:h-4 sm:w-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
cell: ({ row }) => {
|
|
|
|
|
const { title, shareId } = row.original;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<Link
|
|
|
|
|
to={`/share/${shareId}`}
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
className="block truncate text-blue-500 hover:underline"
|
|
|
|
|
title={title}
|
|
|
|
|
>
|
|
|
|
|
{title}
|
|
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
meta: {
|
|
|
|
|
size: '35%',
|
|
|
|
|
mobileSize: '50%',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
accessorKey: 'createdAt',
|
|
|
|
|
header: ({ column }) => {
|
|
|
|
|
return (
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
className="px-2 py-0 text-xs hover:bg-surface-hover sm:px-2 sm:py-2 sm:text-sm"
|
|
|
|
|
onClick={() =>
|
|
|
|
|
handleSort('createdAt', column.getIsSorted() === 'asc' ? 'desc' : 'asc')
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{localize('com_ui_date')}
|
|
|
|
|
<ArrowUpDown className="ml-2 h-3 w-4 sm:h-4 sm:w-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
cell: ({ row }) => formatDate(row.original.createdAt?.toString() ?? '', isSmallScreen),
|
|
|
|
|
meta: {
|
|
|
|
|
size: '10%',
|
|
|
|
|
mobileSize: '20%',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
accessorKey: 'actions',
|
|
|
|
|
header: () => (
|
|
|
|
|
<Label className="px-2 py-0 text-xs hover:bg-surface-hover sm:px-2 sm:py-2 sm:text-sm">
|
|
|
|
|
{localize('com_assistants_actions')}
|
|
|
|
|
</Label>
|
|
|
|
|
),
|
|
|
|
|
meta: {
|
|
|
|
|
size: '7%',
|
|
|
|
|
mobileSize: '25%',
|
|
|
|
|
},
|
|
|
|
|
cell: ({ row }) => (
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<TooltipAnchor
|
|
|
|
|
description={localize('com_ui_view_source')}
|
|
|
|
|
render={
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
className="h-8 w-8 p-0 hover:bg-surface-hover"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
window.open(`/c/${row.original.conversationId}`, '_blank');
|
|
|
|
|
}}
|
|
|
|
|
title={localize('com_ui_view_source')}
|
|
|
|
|
>
|
|
|
|
|
<MessageSquare className="size-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
}
|
|
|
|
|
></TooltipAnchor>
|
|
|
|
|
<TooltipAnchor
|
|
|
|
|
description={localize('com_ui_delete')}
|
|
|
|
|
render={
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
className="h-8 w-8 p-0 hover:bg-surface-hover"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setDeleteRow(row.original);
|
|
|
|
|
setIsDeleteOpen(true);
|
|
|
|
|
}}
|
|
|
|
|
title={localize('com_ui_delete')}
|
|
|
|
|
>
|
|
|
|
|
<TrashIcon className="size-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
}
|
|
|
|
|
></TooltipAnchor>
|
|
|
|
|
</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
[isSmallScreen, localize],
|
|
|
|
|
);
|
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature
* ✨ feat: add shared links functions to data service
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
* ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId
Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
* ✨ feat: Add share schema and data access functions to API models
* ✨ feat: Add share endpoint to API
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
* ♻️ refactor(utils): generalize react-query cache manipulation functions
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.
- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
* ✨ feat(shared-link): add functions to manipulate shared link cache list
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
* ✨ feat: Add mutations and queries for shared links
* ✨ feat(shared-link): add `Share` button to conversation list
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
* ♻️ refactor(hooks): generalize useNavScrolling for broader use
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
* ✨ feat(settings): add shared links listing table with delete functionality in settings
- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
* ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use
* ♻️ refactor: update useGetSharedMessages to return TSharedLink
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
* ✨ feat(shared link): add UI for displaying shared conversations without authentication
- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
* 🔧 chore: Add translations
Translate labels only. Messages remain in English as they are possibly subject to change.
* ♻️ refactor: add icon and tooltip props to EditMenuButton component
* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* ♻️irefactor: added DropdownMenu for Export and Share
* ♻️ refactor: renamed component names more intuitive
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
* 🌍 chore: updated translations
* 🐞 Fix: OpenID Profile Image Download (#2757)
* Add fetch requirement
Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function
* Update openidStrategy.js
---------
Co-authored-by: Danny Avila <danacordially@gmail.com>
* 🚑 fix(export): Issue exporting Conversation with Assistants (#2769)
* 🚑 fix(export): use content as text if content is present in the message
If the endpoint is assistants, the text of the message goes into content, not message.text.
* refactor(ExportModel): TypeScript, remove unused code
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
* 📤style: export button icon (#2752)
* refactor(ShareDialog): logic and styling
* refactor(ExportAndShareMenu): imports order and icon update
* chore: imports
* chore: imports/render logic
* feat: message branching
* refactor: add optional config to useGetStartupConfig
* refactor: disable endpoints query
* chore: fix search view styling gradient in light mode
* style: ShareView gradient styling
* refactor(Share): use select queries
* style: shared link table buttons
* localization and dark text styling
* style: fix clipboard button layout shift app-wide and add localization for copy code
* support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages
* add localizations
* comparisons
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com>
Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2024-05-17 18:13:32 -04:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex items-center justify-between">
|
2024-06-21 15:58:04 +02:00
|
|
|
<div>{localize('com_nav_shared_links')}</div>
|
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature
* ✨ feat: add shared links functions to data service
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
* ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId
Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
* ✨ feat: Add share schema and data access functions to API models
* ✨ feat: Add share endpoint to API
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
* ♻️ refactor(utils): generalize react-query cache manipulation functions
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.
- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
* ✨ feat(shared-link): add functions to manipulate shared link cache list
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
* ✨ feat: Add mutations and queries for shared links
* ✨ feat(shared-link): add `Share` button to conversation list
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
* ♻️ refactor(hooks): generalize useNavScrolling for broader use
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
* ✨ feat(settings): add shared links listing table with delete functionality in settings
- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
* ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use
* ♻️ refactor: update useGetSharedMessages to return TSharedLink
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
* ✨ feat(shared link): add UI for displaying shared conversations without authentication
- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
* 🔧 chore: Add translations
Translate labels only. Messages remain in English as they are possibly subject to change.
* ♻️ refactor: add icon and tooltip props to EditMenuButton component
* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* ♻️irefactor: added DropdownMenu for Export and Share
* ♻️ refactor: renamed component names more intuitive
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
* 🌍 chore: updated translations
* 🐞 Fix: OpenID Profile Image Download (#2757)
* Add fetch requirement
Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function
* Update openidStrategy.js
---------
Co-authored-by: Danny Avila <danacordially@gmail.com>
* 🚑 fix(export): Issue exporting Conversation with Assistants (#2769)
* 🚑 fix(export): use content as text if content is present in the message
If the endpoint is assistants, the text of the message goes into content, not message.text.
* refactor(ExportModel): TypeScript, remove unused code
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
* 📤style: export button icon (#2752)
* refactor(ShareDialog): logic and styling
* refactor(ExportAndShareMenu): imports order and icon update
* chore: imports
* chore: imports/render logic
* feat: message branching
* refactor: add optional config to useGetStartupConfig
* refactor: disable endpoints query
* chore: fix search view styling gradient in light mode
* style: ShareView gradient styling
* refactor(Share): use select queries
* style: shared link table buttons
* localization and dark text styling
* style: fix clipboard button layout shift app-wide and add localization for copy code
* support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages
* add localizations
* comparisons
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com>
Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2024-05-17 18:13:32 -04:00
|
|
|
|
2025-01-21 15:31:05 +01:00
|
|
|
<OGDialog open={isOpen} onOpenChange={setIsOpen}>
|
|
|
|
|
<OGDialogTrigger asChild onClick={() => setIsOpen(true)}>
|
2025-02-18 01:09:36 +01:00
|
|
|
<Button variant="outline">{localize('com_ui_manage')}</Button>
|
2024-09-13 08:59:09 -04:00
|
|
|
</OGDialogTrigger>
|
2025-01-21 15:31:05 +01:00
|
|
|
|
|
|
|
|
<OGDialogContent
|
|
|
|
|
title={localize('com_nav_my_files')}
|
|
|
|
|
className="w-11/12 max-w-5xl bg-background text-text-primary shadow-2xl"
|
|
|
|
|
>
|
|
|
|
|
<OGDialogHeader>
|
|
|
|
|
<OGDialogTitle>{localize('com_nav_shared_links')}</OGDialogTitle>
|
|
|
|
|
</OGDialogHeader>
|
|
|
|
|
<DataTable
|
|
|
|
|
columns={columns}
|
|
|
|
|
data={allLinks}
|
|
|
|
|
onDelete={handleDelete}
|
|
|
|
|
filterColumn="title"
|
|
|
|
|
hasNextPage={hasNextPage}
|
|
|
|
|
isFetchingNextPage={isFetchingNextPage}
|
|
|
|
|
fetchNextPage={handleFetchNextPage}
|
|
|
|
|
showCheckboxes={false}
|
|
|
|
|
onFilterChange={debouncedFilterChange}
|
|
|
|
|
filterValue={queryParams.search}
|
|
|
|
|
/>
|
|
|
|
|
</OGDialogContent>
|
|
|
|
|
</OGDialog>
|
|
|
|
|
<OGDialog open={isDeleteOpen} onOpenChange={setIsDeleteOpen}>
|
2024-09-13 08:59:09 -04:00
|
|
|
<OGDialogTemplate
|
2025-01-21 15:31:05 +01:00
|
|
|
showCloseButton={false}
|
|
|
|
|
title={localize('com_ui_delete_shared_link')}
|
|
|
|
|
className="max-w-[450px]"
|
|
|
|
|
main={
|
|
|
|
|
<>
|
|
|
|
|
<div className="flex w-full flex-col items-center gap-2">
|
|
|
|
|
<div className="grid w-full items-center gap-2">
|
|
|
|
|
<Label htmlFor="dialog-confirm-delete" className="text-left text-sm font-medium">
|
|
|
|
|
{localize('com_ui_delete_confirm')} <strong>{deleteRow?.title}</strong>
|
|
|
|
|
</Label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
selection={{
|
|
|
|
|
selectHandler: confirmDelete,
|
|
|
|
|
selectClasses: `bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 text-white ${
|
|
|
|
|
deleteMutation.isLoading ? 'cursor-not-allowed opacity-80' : ''
|
|
|
|
|
}`,
|
|
|
|
|
selectText: deleteMutation.isLoading ? <Spinner /> : localize('com_ui_delete'),
|
|
|
|
|
}}
|
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature
* ✨ feat: add shared links functions to data service
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
* ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId
Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
* ✨ feat: Add share schema and data access functions to API models
* ✨ feat: Add share endpoint to API
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
* ♻️ refactor(utils): generalize react-query cache manipulation functions
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.
- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
* ✨ feat(shared-link): add functions to manipulate shared link cache list
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
* ✨ feat: Add mutations and queries for shared links
* ✨ feat(shared-link): add `Share` button to conversation list
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
* ♻️ refactor(hooks): generalize useNavScrolling for broader use
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
* ✨ feat(settings): add shared links listing table with delete functionality in settings
- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
* ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use
* ♻️ refactor: update useGetSharedMessages to return TSharedLink
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
* ✨ feat(shared link): add UI for displaying shared conversations without authentication
- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
* 🔧 chore: Add translations
Translate labels only. Messages remain in English as they are possibly subject to change.
* ♻️ refactor: add icon and tooltip props to EditMenuButton component
* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* ♻️irefactor: added DropdownMenu for Export and Share
* ♻️ refactor: renamed component names more intuitive
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
* 🌍 chore: updated translations
* 🐞 Fix: OpenID Profile Image Download (#2757)
* Add fetch requirement
Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function
* Update openidStrategy.js
---------
Co-authored-by: Danny Avila <danacordially@gmail.com>
* 🚑 fix(export): Issue exporting Conversation with Assistants (#2769)
* 🚑 fix(export): use content as text if content is present in the message
If the endpoint is assistants, the text of the message goes into content, not message.text.
* refactor(ExportModel): TypeScript, remove unused code
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
* 📤style: export button icon (#2752)
* refactor(ShareDialog): logic and styling
* refactor(ExportAndShareMenu): imports order and icon update
* chore: imports
* chore: imports/render logic
* feat: message branching
* refactor: add optional config to useGetStartupConfig
* refactor: disable endpoints query
* chore: fix search view styling gradient in light mode
* style: ShareView gradient styling
* refactor(Share): use select queries
* style: shared link table buttons
* localization and dark text styling
* style: fix clipboard button layout shift app-wide and add localization for copy code
* support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages
* add localizations
* comparisons
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com>
Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2024-05-17 18:13:32 -04:00
|
|
|
/>
|
2024-09-13 08:59:09 -04:00
|
|
|
</OGDialog>
|
🚀 feat: Shared Links (#2772)
* ✨ feat(types): add necessary types for shared link feature
* ✨ feat: add shared links functions to data service
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
* ✨ feat: Add useGetSharedMessages hook to fetch shared messages by shareId
Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
* ✨ feat: Add share schema and data access functions to API models
* ✨ feat: Add share endpoint to API
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
* ♻️ refactor(utils): generalize react-query cache manipulation functions
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.
- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
* ✨ feat(shared-link): add functions to manipulate shared link cache list
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
* ✨ feat: Add mutations and queries for shared links
* ✨ feat(shared-link): add `Share` button to conversation list
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
* ♻️ refactor(hooks): generalize useNavScrolling for broader use
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
* ✨ feat(settings): add shared links listing table with delete functionality in settings
- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
* ♻️ refactor(components): separate `EndpointIcon` from `Icon` component for standalone use
* ♻️ refactor: update useGetSharedMessages to return TSharedLink
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
* ✨ feat(shared link): add UI for displaying shared conversations without authentication
- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
* 🔧 chore: Add translations
Translate labels only. Messages remain in English as they are possibly subject to change.
* ♻️ refactor: add icon and tooltip props to EditMenuButton component
* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* ♻️irefactor: added DropdownMenu for Export and Share
* ♻️ refactor: renamed component names more intuitive
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
* 🌍 chore: updated translations
* 🐞 Fix: OpenID Profile Image Download (#2757)
* Add fetch requirement
Fixes - error: [openidStrategy] downloadImage: Error downloading image at URL "https://graph.microsoft.com/v1.0/me/photo/$value": TypeError: response.buffer is not a function
* Update openidStrategy.js
---------
Co-authored-by: Danny Avila <danacordially@gmail.com>
* 🚑 fix(export): Issue exporting Conversation with Assistants (#2769)
* 🚑 fix(export): use content as text if content is present in the message
If the endpoint is assistants, the text of the message goes into content, not message.text.
* refactor(ExportModel): TypeScript, remove unused code
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
* 📤style: export button icon (#2752)
* refactor(ShareDialog): logic and styling
* refactor(ExportAndShareMenu): imports order and icon update
* chore: imports
* chore: imports/render logic
* feat: message branching
* refactor: add optional config to useGetStartupConfig
* refactor: disable endpoints query
* chore: fix search view styling gradient in light mode
* style: ShareView gradient styling
* refactor(Share): use select queries
* style: shared link table buttons
* localization and dark text styling
* style: fix clipboard button layout shift app-wide and add localization for copy code
* support assistants message content in shared links, add useCopyToClipboard, add copy buttons to Search Messages and Shared Link Messages
* add localizations
* comparisons
---------
Co-authored-by: Yuichi Ohneda <ohneda@gmail.com>
Co-authored-by: bsu3338 <bsu3338@users.noreply.github.com>
Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com>
2024-05-17 18:13:32 -04:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|