mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
Include the user who shared the task on the share landing page (#87)
* Include the user who shared the task on the share landing page * Add sharedAt
This commit is contained in:
parent
8101f2026d
commit
7b3d1ba23a
4 changed files with 55 additions and 14 deletions
|
|
@ -9,9 +9,10 @@ import {
|
|||
createTaskShareSchema,
|
||||
shareIdSchema,
|
||||
} from '@/types';
|
||||
import type { SharedByUser } from '@/types/task-sharing';
|
||||
import type { Message } from '@/types/analytics';
|
||||
import { type TaskShare, AuditLogTargetType } from '@/db';
|
||||
import { client as db, taskShares } from '@/db/server';
|
||||
import { client as db, taskShares, users } from '@/db/server';
|
||||
import { handleError, isAuthSuccess, generateShareToken } from '@/lib/server';
|
||||
import {
|
||||
isValidShareToken,
|
||||
|
|
@ -199,9 +200,12 @@ export async function createTaskShare(
|
|||
/**
|
||||
* Get task data by share token (for viewing shared tasks)
|
||||
*/
|
||||
export async function getTaskByShareToken(
|
||||
token: string,
|
||||
): Promise<{ task: TaskWithUser; messages: Message[] } | null> {
|
||||
export async function getTaskByShareToken(token: string): Promise<{
|
||||
task: TaskWithUser;
|
||||
messages: Message[];
|
||||
sharedBy: SharedByUser;
|
||||
sharedAt: Date;
|
||||
} | null> {
|
||||
try {
|
||||
const { userId, orgId } = await auth();
|
||||
|
||||
|
|
@ -213,16 +217,26 @@ export async function getTaskByShareToken(
|
|||
return null;
|
||||
}
|
||||
|
||||
const [share] = await db
|
||||
.select()
|
||||
const [shareWithUser] = await db
|
||||
.select({
|
||||
share: taskShares,
|
||||
sharedByUser: {
|
||||
id: users.id,
|
||||
name: users.name,
|
||||
email: users.email,
|
||||
},
|
||||
})
|
||||
.from(taskShares)
|
||||
.innerJoin(users, eq(taskShares.createdByUserId, users.id))
|
||||
.where(and(eq(taskShares.shareToken, token), eq(taskShares.orgId, orgId)))
|
||||
.limit(1);
|
||||
|
||||
if (!share) {
|
||||
if (!shareWithUser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { share, sharedByUser } = shareWithUser;
|
||||
|
||||
if (isShareExpired(share.expiresAt)) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -240,7 +254,12 @@ export async function getTaskByShareToken(
|
|||
|
||||
const messages = await getMessages(share.taskId);
|
||||
|
||||
return { task, messages };
|
||||
return {
|
||||
task,
|
||||
messages,
|
||||
sharedBy: sharedByUser,
|
||||
sharedAt: share.createdAt,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Error getting task by share token:',
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export default async function SharedTaskPage({ params }: SharedTaskPageProps) {
|
|||
notFound();
|
||||
}
|
||||
|
||||
const { task, messages } = result;
|
||||
const { task, messages, sharedBy, sharedAt } = result;
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-6">
|
||||
|
|
@ -35,7 +35,12 @@ export default async function SharedTaskPage({ params }: SharedTaskPageProps) {
|
|||
<span>Shared Task</span>
|
||||
</div>
|
||||
</div>
|
||||
<SharedTaskView task={task} messages={messages} />
|
||||
<SharedTaskView
|
||||
task={task}
|
||||
messages={messages}
|
||||
sharedBy={sharedBy}
|
||||
sharedAt={sharedAt}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { TaskWithUser } from '@/actions/analytics';
|
||||
import type { Message } from '@/types/analytics';
|
||||
import type { SharedByUser } from '@/types/task-sharing';
|
||||
import { formatCurrency, formatNumber } from '@/lib/formatters';
|
||||
import { generateFallbackTitle } from '@/lib/task-utils';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui';
|
||||
|
|
@ -9,9 +10,16 @@ import { Messages } from '@/app/(authenticated)/usage/Messages';
|
|||
type SharedTaskViewProps = {
|
||||
task: TaskWithUser;
|
||||
messages: Message[];
|
||||
sharedBy: SharedByUser;
|
||||
sharedAt: Date;
|
||||
};
|
||||
|
||||
export const SharedTaskView = ({ task, messages }: SharedTaskViewProps) => {
|
||||
export const SharedTaskView = ({
|
||||
task,
|
||||
messages,
|
||||
sharedBy,
|
||||
sharedAt,
|
||||
}: SharedTaskViewProps) => {
|
||||
const taskTitle = task.title || generateFallbackTitle(task);
|
||||
|
||||
return (
|
||||
|
|
@ -23,8 +31,7 @@ export const SharedTaskView = ({ task, messages }: SharedTaskViewProps) => {
|
|||
<div>
|
||||
<CardTitle className="text-xl">{taskTitle}</CardTitle>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
Shared by {task.user.name} •{' '}
|
||||
{new Date(task.timestamp * 1000).toLocaleDateString()}
|
||||
Shared by {sharedBy.name} • {sharedAt.toLocaleDateString()}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
@ -36,7 +43,11 @@ export const SharedTaskView = ({ task, messages }: SharedTaskViewProps) => {
|
|||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-4 text-sm">
|
||||
<div>
|
||||
<p className="text-muted-foreground">Developer</p>
|
||||
<p className="font-mono">{task.user.name}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-muted-foreground">Model</p>
|
||||
<p className="font-mono">{task.model}</p>
|
||||
|
|
|
|||
|
|
@ -10,3 +10,9 @@ export type CreateTaskShareRequest = z.infer<typeof createTaskShareSchema>;
|
|||
export const shareIdSchema = z.string().uuid('Invalid share ID format');
|
||||
|
||||
export type ShareId = z.infer<typeof shareIdSchema>;
|
||||
|
||||
export type SharedByUser = {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue