Skip to content

g1t/apps/web/app/routes/workspace/pins.ts

38 lines1,771 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Navigation: the workspace's own page with tabs, pins and recent in the sidebar1/**
2 * Pinning a workspace's projects, for the person signed in: `intent` pin
3 * (with `slug`, and `position` to put it somewhere other than the end),
4 * unpin (with `slug`), or reorder (with every pinned `slug`, in order).
5 * Posted by the pin buttons on a project's header and the Projects page,
6 * and by dragging pins in the sidebar (lib/pins.ts). The projects service
7 * keeps them; the sidebar and pages reload after.
8 */
9import { data, redirect } from "react-router";
10
11import type { Route } from "./+types/pins";
12import { pinFromForm } from "../../lib/pins";
13import { projects } from "../../lib/services.server";
14import { assertSameOrigin, requireUser } from "../../lib/session.server";
15
16/** Nothing to see here: the workspace's projects are. */
17export function loader({ params }: Route.LoaderArgs) {
18 return redirect(`/${params.owner}/-/projects`);
19}
20
21export async function action({ request, params, context }: Route.ActionArgs) {
22 assertSameOrigin(request);
23 const user = requireUser(context, request);
24 const change = pinFromForm(await request.formData());
25 if (!change) return data({ error: "Nothing to do." }, { status: 400 });
26 try {
27 const result =
28 change.intent === "pin"
29 ? await projects.pin(user, params.owner, change.slug, change.position)
30 : change.intent === "unpin"
31 ? await projects.unpin(user, params.owner, change.slug)
32 : await projects.reorderPins(user, params.owner, change.slugs);
33 if (!result.ok) return data({ error: result.error.message }, { status: result.error.code === "not_found" ? 404 : 400 });
34 return { error: null, pinned: result.value.map((project) => project.slug) };
35 } catch {
36 return data({ error: "That did not save. Try again in a moment." }, { status: 503 });
37 }
38}