feat(03-03): replace display strings in page files A-D with VOCAB constants
- AgentDetail: hire verb uses VOCAB.hire - ApprovalDetail: Board identity uses VOCAB.board - CliAuth: appName and board uses VOCAB; client fallback uses 'nexus cli' - Companies: button labels use VOCAB.company - CompanyExport: CEO role label, README text, export header use VOCAB - CompanySettings: breadcrumb, Staffing section, approval labels, OpenClaw template use VOCAB - CompanySkills: paperclip skill source label uses VOCAB.appName - Dashboard: welcome and select messages use VOCAB.appName and VOCAB.company - Approvals: VOCAB imported (no string changes needed)
This commit is contained in:
parent
7344fd0dd9
commit
f812031c8d
9 changed files with 43 additions and 34 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useState, useRef } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { useParams, useNavigate, Link, Navigate, useBeforeUnload } from "@/lib/router";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
|
|
@ -1527,7 +1528,7 @@ function ConfigurationTab({
|
|||
<div className="space-y-1">
|
||||
<div>Can create new agents</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Lets this agent create or hire agents and implicitly assign tasks.
|
||||
Lets this agent create or {VOCAB.hire.toLowerCase()} agents and implicitly assign tasks.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { Link, useNavigate, useParams, useSearchParams } from "@/lib/router";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { approvalsApi } from "../api/approvals";
|
||||
|
|
@ -337,7 +338,7 @@ export function ApprovalDetail() {
|
|||
/>
|
||||
</Link>
|
||||
) : (
|
||||
<Identity name="Board" size="sm" />
|
||||
<Identity name={VOCAB.board} size="sm" />
|
||||
)}
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{new Date(comment.createdAt).toLocaleString()}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { useNavigate, useLocation } from "@/lib/router";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { approvalsApi } from "../api/approvals";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useMemo } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { Link, useParams, useSearchParams } from "@/lib/router";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -120,9 +121,9 @@ export function CliAuthPage() {
|
|||
return (
|
||||
<div className="mx-auto max-w-xl py-10">
|
||||
<div className="rounded-lg border border-border bg-card p-6">
|
||||
<h1 className="text-xl font-semibold">Approve Paperclip CLI access</h1>
|
||||
<h1 className="text-xl font-semibold">Approve {VOCAB.appName} CLI access</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
A local Paperclip CLI process is requesting board access to this instance.
|
||||
A local {VOCAB.appName} CLI process is requesting {VOCAB.board.toLowerCase()} access to this instance.
|
||||
</p>
|
||||
|
||||
<div className="mt-5 space-y-3 text-sm">
|
||||
|
|
@ -132,12 +133,12 @@ export function CliAuthPage() {
|
|||
</div>
|
||||
<div>
|
||||
<div className="text-muted-foreground">Client</div>
|
||||
<div className="text-foreground">{challenge.clientName ?? "paperclipai cli"}</div>
|
||||
<div className="text-foreground">{challenge.clientName ?? "nexus cli"}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-muted-foreground">Requested access</div>
|
||||
<div className="text-foreground">
|
||||
{challenge.requestedAccess === "instance_admin_required" ? "Instance admin" : "Board"}
|
||||
{challenge.requestedAccess === "instance_admin_required" ? "Instance admin" : VOCAB.board}
|
||||
</div>
|
||||
</div>
|
||||
{challenge.requestedCompanyName && (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useCompany } from "../context/CompanyContext";
|
||||
import { useDialog } from "../context/DialogContext";
|
||||
|
|
@ -92,7 +93,7 @@ export function Companies() {
|
|||
<div className="flex items-center justify-end">
|
||||
<Button size="sm" onClick={() => openOnboarding()}>
|
||||
<Plus className="h-3.5 w-3.5 mr-1.5" />
|
||||
New Company
|
||||
New {VOCAB.company}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
|
@ -223,7 +224,7 @@ export function Companies() {
|
|||
onClick={() => setConfirmDeleteId(company.id)}
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
Delete Company
|
||||
Delete {VOCAB.company}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import type {
|
||||
Agent,
|
||||
|
|
@ -390,7 +391,7 @@ function FrontmatterCard({
|
|||
// ── Client-side README generation ────────────────────────────────────
|
||||
|
||||
const ROLE_LABELS: Record<string, string> = {
|
||||
ceo: "CEO", cto: "CTO", cmo: "CMO", cfo: "CFO", coo: "COO",
|
||||
ceo: VOCAB.ceo, cto: "CTO", cmo: "CMO", cfo: "CFO", coo: "COO",
|
||||
vp: "VP", manager: "Manager", engineer: "Engineer", agent: "Agent",
|
||||
};
|
||||
|
||||
|
|
@ -429,7 +430,7 @@ function generateReadmeFromSelection(
|
|||
|
||||
lines.push("## What's Inside");
|
||||
lines.push("");
|
||||
lines.push("This is an [Agent Company](https://paperclip.ing) package.");
|
||||
lines.push("This is a Nexus workspace package.");
|
||||
lines.push("");
|
||||
|
||||
const counts: Array<[string, number]> = [];
|
||||
|
|
@ -476,10 +477,10 @@ function generateReadmeFromSelection(
|
|||
lines.push("pnpm paperclipai company import this-github-url-or-folder");
|
||||
lines.push("```");
|
||||
lines.push("");
|
||||
lines.push("See [Paperclip](https://paperclip.ing) for more information.");
|
||||
lines.push("See Nexus for more information.");
|
||||
lines.push("");
|
||||
lines.push("---");
|
||||
lines.push(`Exported from [Paperclip](https://paperclip.ing) on ${new Date().toISOString().split("T")[0]}`);
|
||||
lines.push(`Exported from ${VOCAB.appName} on ${new Date().toISOString().split("T")[0]}`);
|
||||
lines.push("");
|
||||
|
||||
return lines.join("\n");
|
||||
|
|
@ -789,7 +790,7 @@ export function CompanyExport() {
|
|||
|
||||
// Regenerate README.md based on checked selection
|
||||
if (typeof exportData.files["README.md"] === "string") {
|
||||
const companyName = exportData.manifest.company?.name ?? selectedCompany?.name ?? "Company";
|
||||
const companyName = exportData.manifest.company?.name ?? selectedCompany?.name ?? VOCAB.company;
|
||||
const companyDescription = exportData.manifest.company?.description ?? null;
|
||||
filtered["README.md"] = generateReadmeFromSelection(
|
||||
exportData.manifest,
|
||||
|
|
@ -935,7 +936,7 @@ export function CompanyExport() {
|
|||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-4 text-sm">
|
||||
<span className="font-medium">
|
||||
{selectedCompany?.name ?? "Company"} export
|
||||
{selectedCompany?.name ?? VOCAB.company} export
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
{selectedCount} / {totalFiles} file{totalFiles === 1 ? "" : "s"} selected
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { ChangeEvent, useEffect, useState } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { DEFAULT_FEEDBACK_DATA_SHARING_TERMS_VERSION } from "@paperclipai/shared";
|
||||
import { useCompany } from "../context/CompanyContext";
|
||||
|
|
@ -223,7 +224,7 @@ export function CompanySettings() {
|
|||
|
||||
useEffect(() => {
|
||||
setBreadcrumbs([
|
||||
{ label: selectedCompany?.name ?? "Company", href: "/dashboard" },
|
||||
{ label: selectedCompany?.name ?? VOCAB.company, href: "/dashboard" },
|
||||
{ label: "Settings" }
|
||||
]);
|
||||
}, [setBreadcrumbs, selectedCompany?.name]);
|
||||
|
|
@ -400,15 +401,15 @@ export function CompanySettings() {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Hiring */}
|
||||
{/* Staffing */}
|
||||
<div className="space-y-4" data-testid="company-settings-team-section">
|
||||
<div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
||||
Hiring
|
||||
Staffing
|
||||
</div>
|
||||
<div className="rounded-md border border-border px-4 py-3">
|
||||
<ToggleField
|
||||
label="Require board approval for new hires"
|
||||
hint="New agent hires stay pending until approved by board."
|
||||
label={`Require ${VOCAB.board.toLowerCase()} approval for new ${VOCAB.hire.toLowerCase()}s`}
|
||||
hint={`New agent additions stay pending until approved by ${VOCAB.board.toLowerCase()}.`}
|
||||
checked={!!selectedCompany.requireBoardApprovalForNewAgents}
|
||||
onChange={(v) => settingsMutation.mutate(v)}
|
||||
toggleTestId="company-settings-team-approval-toggle"
|
||||
|
|
@ -630,35 +631,35 @@ function buildAgentSnippet(input: AgentSnippetInput) {
|
|||
|
||||
const connectivityBlock =
|
||||
candidateUrls.length === 0
|
||||
? `No candidate URLs are available. Ask your user to configure a reachable hostname in Paperclip, then retry.
|
||||
? `No candidate URLs are available. Ask your user to configure a reachable hostname in ${VOCAB.appName}, then retry.
|
||||
Suggested steps:
|
||||
- choose a hostname that resolves to the Paperclip host from your runtime
|
||||
- choose a hostname that resolves to the ${VOCAB.appName} host from your runtime
|
||||
- run: pnpm paperclipai allowed-hostname <host>
|
||||
- restart Paperclip
|
||||
- restart ${VOCAB.appName}
|
||||
- verify with: curl -fsS http://<host>:3100/api/health
|
||||
- regenerate this invite snippet`
|
||||
: `If none are reachable, ask your user to add a reachable hostname in Paperclip, restart, and retry.
|
||||
: `If none are reachable, ask your user to add a reachable hostname in ${VOCAB.appName}, restart, and retry.
|
||||
Suggested command:
|
||||
- pnpm paperclipai allowed-hostname <host>
|
||||
Then verify with: curl -fsS <base-url>/api/health`;
|
||||
|
||||
const resolutionLine = resolutionTestUrl
|
||||
? `\nYou MUST test Paperclip-to-gateway reachability, call: ${resolutionTestUrl}?url=<urlencoded-gateway-url> (using the hostname that worked above). Do not assume your 172.x is necessarily reachable from Paperclip. Test it. `
|
||||
? `\nYou MUST test ${VOCAB.appName}-to-gateway reachability, call: ${resolutionTestUrl}?url=<urlencoded-gateway-url> (using the hostname that worked above). Do not assume your 172.x is necessarily reachable from ${VOCAB.appName}. Test it. `
|
||||
: "";
|
||||
|
||||
return `You're invited to join a Paperclip organization.
|
||||
return `You're invited to join a ${VOCAB.appName} workspace.
|
||||
|
||||
The URLs you should try are:
|
||||
${candidateList}
|
||||
|
||||
Connectivity guidance:
|
||||
If you are running on a different machine than Paperclip, Paperclip must be reachable at one of the hostnames used above.
|
||||
If you are running on a different machine than ${VOCAB.appName}, ${VOCAB.appName} must be reachable at one of the hostnames used above.
|
||||
Verify the hostname works from your runtime with: GET <base-url>/api/health
|
||||
|
||||
${connectivityBlock}
|
||||
|
||||
For your "agentName", just use your own agent name (OpenClaw or whatever your name is) and send it directly.
|
||||
You also need to send a gateway URL that Paperclip can access. Check your config and include that URL.${resolutionLine}
|
||||
You also need to send a gateway URL that ${VOCAB.appName} can access. Check your config and include that URL.${resolutionLine}
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -668,14 +669,14 @@ When you submit the join request, use:
|
|||
- \`agentDefaultsPayload.url\` as your \`ws://\` or \`wss://\` gateway URL
|
||||
- \`agentDefaultsPayload.headers["x-openclaw-token"]\` with your gateway token
|
||||
- (legacy accepted) \`agentDefaultsPayload.headers["x-openclaw-auth"]\`
|
||||
- Keep device auth enabled (recommended). If \`devicePrivateKeyPem\` is omitted, Paperclip will generate and persist one during join so pairing approvals remain stable.
|
||||
- Keep device auth enabled (recommended). If \`devicePrivateKeyPem\` is omitted, ${VOCAB.appName} will generate and persist one during join so pairing approvals remain stable.
|
||||
- Only use \`disableDeviceAuth=true\` for special environments where pairing cannot be completed.
|
||||
|
||||
Do NOT use \`/v1/responses\` or \`/hooks/*\` in this join flow.
|
||||
|
||||
Before you do anything, please respond to your user that you understand the instructions and you're going to work on them. Then do the step above in another session called "paperclip-onboarding" and then tell your user when you're done. Update your user in intermediate steps along the way so they know what's going on.
|
||||
Before you do anything, please respond to your user that you understand the instructions and you're going to work on them. Then do the step above in another session called "${VOCAB.appName.toLowerCase()}-onboarding" and then tell your user when you're done. Update your user in intermediate steps along the way so they know what's going on.
|
||||
|
||||
Then after you've connected to Paperclip (exchanged keys etc.) you MUST review and follow the onboarding instructions in onboarding.txt they give you.
|
||||
Then after you've connected to ${VOCAB.appName} (exchanged keys etc.) you MUST review and follow the onboarding instructions in onboarding.txt they give you.
|
||||
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect, useMemo, useState, type SVGProps } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { Link, useNavigate, useParams } from "@/lib/router";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import type {
|
||||
|
|
@ -159,7 +160,7 @@ function sourceMeta(sourceBadge: CompanySkillSourceBadge, sourceLabel: string |
|
|||
case "local":
|
||||
return { icon: Folder, label: sourceLabel ?? "Folder", managedLabel: "Folder managed" };
|
||||
case "paperclip":
|
||||
return { icon: Paperclip, label: sourceLabel ?? "Paperclip", managedLabel: "Paperclip managed" };
|
||||
return { icon: Paperclip, label: sourceLabel ?? VOCAB.appName, managedLabel: `${VOCAB.appName} managed` };
|
||||
default:
|
||||
return { icon: Boxes, label: sourceLabel ?? "Catalog", managedLabel: "Catalog managed" };
|
||||
}
|
||||
|
|
@ -881,7 +882,7 @@ export function CompanySkills() {
|
|||
pushToast({
|
||||
tone: "success",
|
||||
title: "Skill created",
|
||||
body: `${skill.name} is now editable in the Paperclip workspace.`,
|
||||
body: `${skill.name} is now editable in the ${VOCAB.appName} workspace.`,
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { VOCAB } from "@paperclipai/branding";
|
||||
import { Link } from "@/lib/router";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { dashboardApi } from "../api/dashboard";
|
||||
|
|
@ -168,14 +169,14 @@ export function Dashboard() {
|
|||
return (
|
||||
<EmptyState
|
||||
icon={LayoutDashboard}
|
||||
message="Welcome to Paperclip. Set up your first company and agent to get started."
|
||||
message={`Welcome to ${VOCAB.appName}. Set up your first ${VOCAB.company.toLowerCase()} and agent to get started.`}
|
||||
action="Get Started"
|
||||
onAction={openOnboarding}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<EmptyState icon={LayoutDashboard} message="Create or select a company to view the dashboard." />
|
||||
<EmptyState icon={LayoutDashboard} message={`Create or select a ${VOCAB.company.toLowerCase()} to view the dashboard.`} />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue