Compare commits

..

1 Commits

Author SHA1 Message Date
f5cf13f1da feat: display user email below name in multi-member-select dropdown
- Added email field to user items mapping
- Updated renderMultiSelectOption to show email in smaller, dimmed text
- Email only displays for user type options, not groups
2025-07-09 22:29:56 -07:00
3 changed files with 13 additions and 30 deletions

View File

@ -1,5 +1,10 @@
import "@/features/editor/styles/index.css"; import "@/features/editor/styles/index.css";
import React, { useEffect, useMemo, useRef, useState } from "react"; import React, {
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { IndexeddbPersistence } from "y-indexeddb"; import { IndexeddbPersistence } from "y-indexeddb";
import * as Y from "yjs"; import * as Y from "yjs";
import { import {
@ -126,15 +131,7 @@ export default function PageEditor({
const now = Date.now().valueOf() / 1000; const now = Date.now().valueOf() / 1000;
const isTokenExpired = now >= payload.exp; const isTokenExpired = now >= payload.exp;
if (isTokenExpired) { if (isTokenExpired) {
refetchCollabToken().then((result) => { refetchCollabToken();
if (result.data?.token) {
remote.disconnect();
setTimeout(() => {
remote.configuration.token = result.data.token;
remote.connect();
}, 100);
}
});
} }
}, },
onStatus: (status) => { onStatus: (status) => {
@ -160,21 +157,6 @@ export default function PageEditor({
}; };
}, [pageId]); }, [pageId]);
/*
useEffect(() => {
// Handle token updates by reconnecting with new token
if (providersRef.current?.remote && collabQuery?.token) {
const currentToken = providersRef.current.remote.configuration.token;
if (currentToken !== collabQuery.token) {
// Token has changed, need to reconnect with new token
providersRef.current.remote.disconnect();
providersRef.current.remote.configuration.token = collabQuery.token;
providersRef.current.remote.connect();
}
}
}, [collabQuery?.token]);
*/
// Only connect/disconnect on tab/idle, not destroy // Only connect/disconnect on tab/idle, not destroy
useEffect(() => { useEffect(() => {
if (!providersReady || !providersRef.current) return; if (!providersReady || !providersRef.current) return;
@ -369,10 +351,7 @@ export default function PageEditor({
<div style={{ position: "relative" }}> <div style={{ position: "relative" }}>
<div ref={menuContainerRef}> <div ref={menuContainerRef}>
<EditorContent editor={editor} /> <EditorContent editor={editor} />
<SearchAndReplaceDialog editor={editor} editable={editable} />
{editor && (
<SearchAndReplaceDialog editor={editor} editable={editable} />
)}
{editor && editor.isEditable && ( {editor && editor.isEditable && (
<div> <div>

View File

@ -26,6 +26,9 @@ const renderMultiSelectOption: MultiSelectProps["renderOption"] = ({
{option["type"] === "group" && <IconGroupCircle />} {option["type"] === "group" && <IconGroupCircle />}
<div> <div>
<Text size="sm" lineClamp={1}>{option.label}</Text> <Text size="sm" lineClamp={1}>{option.label}</Text>
{option["type"] === "user" && option["email"] && (
<Text size="xs" c="dimmed" lineClamp={1}>{option["email"]}</Text>
)}
</div> </div>
</Group> </Group>
); );
@ -47,6 +50,7 @@ export function MultiMemberSelect({ onChange }: MultiMemberSelectProps) {
const userItems = suggestion?.users.map((user: IUser) => ({ const userItems = suggestion?.users.map((user: IUser) => ({
value: `user-${user.id}`, value: `user-${user.id}`,
label: user.name, label: user.name,
email: user.email,
avatarUrl: user.avatarUrl, avatarUrl: user.avatarUrl,
type: "user", type: "user",
})); }));

View File

@ -140,7 +140,7 @@ export class SearchService {
if (suggestion.includeUsers) { if (suggestion.includeUsers) {
users = await this.db users = await this.db
.selectFrom('users') .selectFrom('users')
.select(['id', 'name', 'avatarUrl']) .select(['id', 'name', 'email', 'avatarUrl'])
.where((eb) => eb(sql`LOWER(users.name)`, 'like', `%${query}%`)) .where((eb) => eb(sql`LOWER(users.name)`, 'like', `%${query}%`))
.where('workspaceId', '=', workspaceId) .where('workspaceId', '=', workspaceId)
.where('deletedAt', 'is', null) .where('deletedAt', 'is', null)