diff --git a/components/Notebook/PublishingForm/components/AuthorsSection.tsx b/components/Notebook/PublishingForm/components/AuthorsSection.tsx index 4c5a49ee5..ec2bf36ff 100644 --- a/components/Notebook/PublishingForm/components/AuthorsSection.tsx +++ b/components/Notebook/PublishingForm/components/AuthorsSection.tsx @@ -21,6 +21,7 @@ export function AuthorsSection() { onChange={(newAuthors) => setValue('authors', newAuthors, { shouldValidate: true })} placeholder="Search for authors..." error={getFieldErrorMessage(errors.authors, 'Invalid authors')} + searchType="author" /> ); diff --git a/components/Notebook/PublishingForm/index.tsx b/components/Notebook/PublishingForm/index.tsx index 01473e16a..2fff26724 100644 --- a/components/Notebook/PublishingForm/index.tsx +++ b/components/Notebook/PublishingForm/index.tsx @@ -192,11 +192,15 @@ const autoAddCurrentUser = ( if (getValues(field).length === 0) { const profile = currentUser.authorProfile; + const authorId = profile?.id?.toString(); + + if (!isGrant && !authorId) { + return; + } + setValue(field, [ { - value: isGrant - ? currentUser.id.toString() - : profile?.id?.toString() || currentUser.id.toString(), + value: isGrant ? currentUser.id.toString() : authorId!, label: currentUser.fullName || currentUser.email || 'Unknown User', }, ]); @@ -472,7 +476,7 @@ export function PublishingForm({ const fallback = 'Error publishing. Please try again.'; if (error instanceof ApiError) { const errorData = error.errors as Record | undefined; - toast.error(errorData?.msg || errorData?.message || fallback); + toast.error(errorData?.msg || errorData?.message || error.message || fallback); } else { toast.error(fallback); } diff --git a/components/ui/form/SearchableUserSelect.tsx b/components/ui/form/SearchableUserSelect.tsx index a6869e391..a5d38274e 100644 --- a/components/ui/form/SearchableUserSelect.tsx +++ b/components/ui/form/SearchableUserSelect.tsx @@ -1,7 +1,7 @@ import { useCallback } from 'react'; import { SearchableMultiSelect, MultiSelectOption } from './SearchableMultiSelect'; import { SearchService } from '@/services/search.service'; -import { UserSuggestion } from '@/types/search'; +import { AuthorSuggestion, UserSuggestion } from '@/types/search'; import { Avatar } from '@/components/ui/Avatar'; import { VerifiedBadge } from '@/components/ui/VerifiedBadge'; import { Button } from '@/components/ui/Button'; @@ -62,6 +62,7 @@ export interface SearchableUserSelectProps { helperText?: string; debounceMs?: number; getOptionValue?: (user: UserSuggestion) => string; + searchType?: 'user' | 'author'; } export function SearchableUserSelect({ @@ -72,9 +73,29 @@ export function SearchableUserSelect({ helperText, debounceMs = 300, getOptionValue = defaultGetOptionValue, + searchType = 'user', }: Readonly) { const handleAsyncSearch = useCallback( async (query: string) => { + if (searchType === 'author') { + const suggestions = await SearchService.suggestPeople(query); + + return suggestions + .filter((author): author is AuthorSuggestion & { id: NonNullable } => + Boolean(author.id) + ) + .map((author) => ({ + value: author.id.toString(), + label: author.fullName || 'Unknown Author', + avatarUrl: author.profileImage, + description: author.headline, + profileUrl: + typeof author.id === 'number' || typeof author.id === 'string' + ? buildAuthorUrl(author.id) + : undefined, + })); + } + const suggestions = await SearchService.getSuggestions(query, 'user'); return suggestions @@ -91,7 +112,7 @@ export function SearchableUserSelect({ profileUrl: user.authorProfile?.id ? buildAuthorUrl(user.authorProfile.id) : undefined, })); }, - [getOptionValue] + [getOptionValue, searchType] ); return (