Square off the rail header and add a back button
The rail header now sits in the standard 64px row with a hairline under it, matching the pane headers, and shows the full logo off the chat pages instead of the bare stone. A back button joins the conversation and settings headers (workspace pages only for the conversation). The rail's own back link and the dividers around it are switched off for now. Also renames the bot and workspace Delete group to Danger Zone, lifts the step budget to 50, and lets Logo render without its home link.
This commit is contained in:
@@ -17,6 +17,8 @@ export default function RailBackLink({
|
||||
title = `Back to ${SiteData["SiteSlug"]}`,
|
||||
href = AdminHomePath,
|
||||
}: Props) {
|
||||
return null;
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
|
||||
@@ -3,6 +3,10 @@ import Link from "@moduletrace/twui/layout/Link";
|
||||
import Wordmark from "@/src/components/general/wordmark";
|
||||
import LogoIcon from "@/src/components/general/logo-icon";
|
||||
import RailAddButton from "./rail-add-button";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { useContext } from "react";
|
||||
import { AppContext } from "@/src/pages/__root";
|
||||
import Logo from "@/src/components/general/logo";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
@@ -12,14 +16,36 @@ type Props = {
|
||||
};
|
||||
|
||||
export default function RailHeader({ show_add = true }: Props) {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
|
||||
return (
|
||||
<Row className="h-[72px] shrink-0 gap-0! flex-nowrap items-start justify-center @rail:justify-between px-0 @rail:pl-5 @rail:pr-6 pt-5">
|
||||
<Row
|
||||
className={twMerge(
|
||||
"h-16 shrink-0 gap-0! flex-nowrap justify-center @rail:justify-between",
|
||||
"px-0 @rail:pl-5 @rail:pr-6 py-1 border-0 border-b border-solid border-hairline",
|
||||
"mb-6 w-full",
|
||||
)}
|
||||
>
|
||||
<Link
|
||||
href="/admin/bots"
|
||||
className="border-0 mt-1 rounded-default-xs hover:opacity-100 focus-visible:ring-2 focus-visible:ring-ink focus-visible:ring-offset-2 focus-visible:ring-offset-paper"
|
||||
className={twMerge(
|
||||
"border-0 mt-1 rounded-default-xs hover:opacity-100 focus-visible:ring-2",
|
||||
"focus-visible:ring-ink focus-visible:ring-offset-2 focus-visible:ring-offset-paper",
|
||||
)}
|
||||
>
|
||||
<Wordmark height={15} className="hidden @rail:block" />
|
||||
<LogoIcon icon_size={28} img_props={{ className: "@rail:hidden" }} />
|
||||
{pageProps?.url?.pathname.startsWith(`/admin/bots/`) ? (
|
||||
<>
|
||||
<Wordmark height={15} className="hidden @rail:block" />
|
||||
<LogoIcon
|
||||
icon_size={28}
|
||||
img_props={{ className: "@rail:hidden" }}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Logo icon_size={28} no_link />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
{show_add ? <RailAddButton /> : null}
|
||||
</Row>
|
||||
|
||||
@@ -17,17 +17,24 @@ type Props = {
|
||||
export default function RailPagesList({ pathname }: Props) {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
const current = pathname?.replace(/\/$/, "");
|
||||
const is_super_admin = isPassThroughUser({ user_types: pageProps?.user_types });
|
||||
const is_super_admin = isPassThroughUser({
|
||||
user_types: pageProps?.user_types,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<RailBackLink />
|
||||
<Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" />
|
||||
{RailPages.filter((page) => is_super_admin || !page.super_admin_only).map((page) => (
|
||||
{/* <Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" /> */}
|
||||
{RailPages.filter(
|
||||
(page) => is_super_admin || !page.super_admin_only,
|
||||
).map((page) => (
|
||||
<RailSettingsLink
|
||||
key={page.url}
|
||||
{...page}
|
||||
selected={current == page.url || Boolean(current?.startsWith(`${page.url}/`))}
|
||||
selected={
|
||||
current == page.url ||
|
||||
Boolean(current?.startsWith(`${page.url}/`))
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -64,7 +64,8 @@ export default function RailSettingsAside({ pathname }: Props) {
|
||||
? Boolean(pageProps?.bot_harness_overview?.harnesses?.length)
|
||||
: record.kind == "workspaces"
|
||||
? Boolean(
|
||||
pageProps?.workspace_harness_overview?.harnesses?.length,
|
||||
pageProps?.workspace_harness_overview?.harnesses
|
||||
?.length,
|
||||
)
|
||||
: true;
|
||||
}
|
||||
@@ -101,9 +102,7 @@ export default function RailSettingsAside({ pathname }: Props) {
|
||||
|
||||
title = workspace.name || `Workspace ${workspace.id}`;
|
||||
subtitle = workspace.description || "A workspace";
|
||||
avatar = (
|
||||
<WorkspaceAvatar image_media_id={workspace.image_media_id} />
|
||||
);
|
||||
avatar = <WorkspaceAvatar image_media_id={workspace.image_media_id} />;
|
||||
} else if (record.kind == "users") {
|
||||
const person = pageProps?.target_person;
|
||||
|
||||
@@ -139,7 +138,7 @@ export default function RailSettingsAside({ pathname }: Props) {
|
||||
return (
|
||||
<>
|
||||
<RailBackLink title={back.title} href={back.href} />
|
||||
<Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" />
|
||||
{/* <Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" /> */}
|
||||
<RailSettingsRecordRow
|
||||
avatar={avatar}
|
||||
title={title}
|
||||
|
||||
@@ -25,7 +25,7 @@ export default function RailSettingsList({ pathname }: Props) {
|
||||
return (
|
||||
<>
|
||||
<RailBackLink />
|
||||
<Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" />
|
||||
{/* <Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" /> */}
|
||||
{SettingsPages.filter((page) =>
|
||||
page.can_view
|
||||
? page.can_view({ user_types: pageProps?.user_types })
|
||||
|
||||
@@ -29,7 +29,12 @@ type Props = {
|
||||
* page), the coordinator working in it, then the workspace's bots. Every
|
||||
* conversation here runs with the workspace's context.
|
||||
*/
|
||||
export default function RailWorkspaceList({ workspace, bots, selected_id, on_workspace_page }: Props) {
|
||||
export default function RailWorkspaceList({
|
||||
workspace,
|
||||
bots,
|
||||
selected_id,
|
||||
on_workspace_page,
|
||||
}: Props) {
|
||||
const { openLinkBots } = useContext(AddFlowContext);
|
||||
const coordinator = bots.find((bot) => bot.kind === "coordinator");
|
||||
const workers = bots.filter((bot) => bot.kind !== "coordinator");
|
||||
@@ -38,11 +43,16 @@ export default function RailWorkspaceList({ workspace, bots, selected_id, on_wor
|
||||
return (
|
||||
<>
|
||||
<RailBackLink
|
||||
title={on_workspace_page ? "All bots" : `Back to ${workspace.name}`}
|
||||
title={
|
||||
on_workspace_page ? "All bots" : `Back to ${workspace.name}`
|
||||
}
|
||||
href={on_workspace_page ? undefined : base}
|
||||
/>
|
||||
<Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" />
|
||||
<WorkspaceRow workspace={{ ...workspace, unread: 0 }} selected={on_workspace_page} />
|
||||
{/* <Divider className="shrink-0 mx-1 @rail:mx-3 my-2 w-auto border-hairline dark:border-hairline" /> */}
|
||||
<WorkspaceRow
|
||||
workspace={{ ...workspace, unread: 0 }}
|
||||
selected={on_workspace_page}
|
||||
/>
|
||||
{coordinator ? (
|
||||
<RailBotCard selected={coordinator.id === selected_id}>
|
||||
<CoordinatorRow
|
||||
@@ -61,7 +71,12 @@ export default function RailWorkspaceList({ workspace, bots, selected_id, on_wor
|
||||
</RailBotCard>
|
||||
) : null}
|
||||
<RailBotsSection
|
||||
action={<RailSectionAddButton title="Add bots to this workspace" onClick={openLinkBots} />}
|
||||
action={
|
||||
<RailSectionAddButton
|
||||
title="Add bots to this workspace"
|
||||
onClick={openLinkBots}
|
||||
/>
|
||||
}
|
||||
title="Workspace bots"
|
||||
workers={workers}
|
||||
selected_id={on_workspace_page ? undefined : selected_id}
|
||||
|
||||
Reference in New Issue
Block a user