feat(ui): theme & layout improvements
- Dark-blue theme background assets and styling integration - Appearance settings with layoutMode (full/compact) preference - Settings dialog and auth context updates - AI writing form and panel refinements - Open Canvas context updates - Roundtable planning styling and dashboard enhancements - Strategy components and header updates - Light app management and routing improvements - Global style enhancements for dark theme - Various page layout and workspace routing optimizations
This commit is contained in:
1 parent
da2864f422
commit
56449ed129
33 files changed
+1133
-491
No files matched your search
@@ -22,6 +22,7 @@ import {
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Select } from "tdesign-react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -52,6 +53,18 @@ interface FormState {
|
||||
routeParams: LightAppRouteParam[];
|
||||
}
|
||||
|
||||
const APP_TYPE_OPTIONS: { label: string; value: LightAppType }[] = [
|
||||
{ label: "iframe 嵌套 (挂载到菜单)", value: "iframe" },
|
||||
{ label: "window.open (新页跳转)", value: "window_open" },
|
||||
];
|
||||
|
||||
const PARAM_TYPE_OPTIONS: { label: string; value: "login" | "theme" }[] = [
|
||||
{ label: "登录参数", value: "login" },
|
||||
{ label: "主题参数", value: "theme" },
|
||||
];
|
||||
|
||||
const DIALOG_SELECT_POPUP = { attach: () => document.body };
|
||||
|
||||
const emptyForm = (): FormState => ({
|
||||
name: "",
|
||||
description: "",
|
||||
@@ -209,11 +222,11 @@ export default function LightAppManagementPage() {
|
||||
</h1>
|
||||
<p className="max-w-2xl text-xs leading-relaxed text-neutral-500">
|
||||
注册轻应用。
|
||||
<code className="mx-1 rounded bg-neutral-100 px-1.5 py-0.5 font-mono text-[11px] text-neutral-600">
|
||||
<code className="mx-1 rounded-[5px] bg-neutral-100 px-1.5 py-0.5 font-mono text-[11px] text-neutral-600">
|
||||
window.open
|
||||
</code>
|
||||
类型在「应用列表」以卡片展示;
|
||||
<code className="mx-1 rounded bg-neutral-100 px-1.5 py-0.5 font-mono text-[11px] text-neutral-600">
|
||||
<code className="mx-1 rounded-[5px] bg-neutral-100 px-1.5 py-0.5 font-mono text-[11px] text-neutral-600">
|
||||
iframe
|
||||
</code>
|
||||
类型挂载到所选菜单下并注入侧栏。
|
||||
@@ -222,14 +235,14 @@ export default function LightAppManagementPage() {
|
||||
|
||||
<button
|
||||
onClick={openCreate}
|
||||
className="flex cursor-pointer items-center justify-center space-x-1.5 rounded-lg bg-[#A8071A] px-5 py-2.5 text-xs font-semibold text-white shadow-md shadow-rose-950/10 transition-all hover:bg-[#BC0D1E] hover:shadow-lg hover:shadow-rose-900/15 active:bg-[#820014]"
|
||||
className="flex cursor-pointer items-center justify-center space-x-1.5 rounded-[5px] bg-[#A8071A] px-5 py-2.5 text-xs font-semibold text-white shadow-md shadow-rose-950/10 transition-all hover:bg-[#BC0D1E] hover:shadow-lg hover:shadow-rose-900/15 active:bg-[#820014]"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
<span>注册应用</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center gap-3.5 rounded-xl border border-neutral-100 bg-white p-3 shadow-[0_1px_3px_rgba(0,0,0,0.01)] md:flex-row">
|
||||
<div className="flex flex-col items-center gap-3.5 rounded-[5px] bg-white p-3 shadow-[0_1px_3px_rgba(0,0,0,0.01)] md:flex-row">
|
||||
<div className="relative w-full flex-1">
|
||||
<Search className="absolute left-3.5 top-1/2 h-4 w-4 -translate-y-1/2 text-neutral-400" />
|
||||
<input
|
||||
@@ -237,7 +250,7 @@ export default function LightAppManagementPage() {
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder="搜索应用名称 / 描述..."
|
||||
className="w-full rounded-lg border border-neutral-100 bg-neutral-50/60 py-2 pl-10 pr-10 text-xs text-neutral-800 placeholder-neutral-400 transition-all hover:bg-white focus:border-[#F5222D]/40 focus:outline-none focus:ring-4 focus:ring-[#F5222D]/10"
|
||||
className="w-full rounded-[5px] border border-neutral-100 bg-neutral-50/60 py-2 pl-10 pr-10 text-xs text-neutral-800 placeholder-neutral-400 transition-all hover:bg-white focus:border-[#F5222D]/40 focus:outline-none focus:ring-4 focus:ring-[#F5222D]/10"
|
||||
/>
|
||||
{search && (
|
||||
<button
|
||||
@@ -249,10 +262,10 @@ export default function LightAppManagementPage() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center space-x-0.5 self-end rounded-lg border border-neutral-200/50 bg-neutral-100/60 p-0.5 md:self-auto">
|
||||
<div className="flex shrink-0 items-center space-x-0.5 self-end rounded-[5px] border border-neutral-200/50 bg-neutral-100/60 p-0.5 md:self-auto">
|
||||
<button
|
||||
onClick={() => setViewMode("table")}
|
||||
className={`cursor-pointer rounded-md px-4 py-1.5 text-xs font-bold transition-all ${
|
||||
className={`cursor-pointer rounded-[5px] px-4 py-1.5 text-xs font-bold transition-all ${
|
||||
viewMode === "table"
|
||||
? "bg-white text-[#F5222D] shadow-sm"
|
||||
: "text-neutral-500 hover:text-neutral-700"
|
||||
@@ -262,7 +275,7 @@ export default function LightAppManagementPage() {
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setViewMode("cards")}
|
||||
className={`cursor-pointer rounded-md px-4 py-1.5 text-xs font-bold transition-all ${
|
||||
className={`cursor-pointer rounded-[5px] px-4 py-1.5 text-xs font-bold transition-all ${
|
||||
viewMode === "cards"
|
||||
? "bg-white text-[#F5222D] shadow-sm"
|
||||
: "text-neutral-500 hover:text-neutral-700"
|
||||
@@ -280,7 +293,7 @@ export default function LightAppManagementPage() {
|
||||
</div>
|
||||
|
||||
{viewMode === "table" ? (
|
||||
<div className="overflow-visible rounded-xl border border-neutral-100 bg-white shadow-[0_1px_3px_0_rgba(0,0,0,0.01)]">
|
||||
<div className="overflow-visible rounded-[5px] bg-white shadow-[0_1px_3px_0_rgba(0,0,0,0.01)]">
|
||||
<table className="w-full table-fixed border-collapse text-left">
|
||||
<thead>
|
||||
<tr className="select-none border-b border-neutral-100/80 bg-neutral-50/40 text-[12.5px] font-semibold text-neutral-500">
|
||||
@@ -304,12 +317,12 @@ export default function LightAppManagementPage() {
|
||||
|
||||
<td className="px-4 py-[18px]">
|
||||
{app.appType === "window_open" ? (
|
||||
<span className="inline-flex select-none items-center space-x-1.5 rounded-lg border border-rose-100 bg-rose-50 px-3 py-1 text-[12px] font-semibold text-rose-800">
|
||||
<span className="inline-flex select-none items-center space-x-1.5 rounded-[5px] border border-rose-100 bg-rose-50 px-3 py-1 text-[12px] font-semibold text-rose-800">
|
||||
<ExternalLink className="h-3.5 w-3.5" />
|
||||
<span>新页跳转</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex select-none items-center space-x-1.5 rounded-lg border border-sky-100 bg-sky-50 px-3 py-1 text-[12px] font-semibold text-sky-800">
|
||||
<span className="inline-flex select-none items-center space-x-1.5 rounded-[5px] border border-sky-100 bg-sky-50 px-3 py-1 text-[12px] font-semibold text-sky-800">
|
||||
<Monitor className="h-3.5 w-3.5" />
|
||||
<span>iframe 嵌套</span>
|
||||
</span>
|
||||
@@ -329,7 +342,7 @@ export default function LightAppManagementPage() {
|
||||
</a>
|
||||
<button
|
||||
onClick={() => handleCopyUrl(app.url)}
|
||||
className="shrink-0 rounded p-1 text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-neutral-600"
|
||||
className="shrink-0 rounded-[5px] p-1 text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-neutral-600"
|
||||
title="复制网址"
|
||||
>
|
||||
<Copy className="h-3 w-3" />
|
||||
@@ -339,7 +352,7 @@ export default function LightAppManagementPage() {
|
||||
|
||||
<td className="px-4 py-[18px]">
|
||||
{app.appType === "iframe" && app.mountLocation ? (
|
||||
<span className="inline-flex max-w-full items-center space-x-1.5 rounded bg-sky-50 px-2 py-0.5 text-[11px] font-medium text-sky-700">
|
||||
<span className="inline-flex max-w-full items-center space-x-1.5 rounded-[5px] bg-sky-50 px-2 py-0.5 text-[11px] font-medium text-sky-700">
|
||||
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-sky-500" />
|
||||
<span className="truncate">{mountLabel(app.mountLocation)}</span>
|
||||
</span>
|
||||
@@ -357,7 +370,7 @@ export default function LightAppManagementPage() {
|
||||
activeParamPopover === app.appId ? null : app.appId
|
||||
)
|
||||
}
|
||||
className="inline-flex cursor-pointer items-center space-x-1.5 rounded border border-neutral-200/60 bg-neutral-50/60 px-2.5 py-1 text-xs font-medium text-neutral-500 transition-colors hover:bg-neutral-100"
|
||||
className="inline-flex cursor-pointer items-center space-x-1.5 rounded-[5px] border border-neutral-200/60 bg-neutral-50/60 px-2.5 py-1 text-xs font-medium text-neutral-500 transition-colors hover:bg-neutral-100"
|
||||
>
|
||||
<span>{app.routeParams.length}个</span>
|
||||
{activeParamPopover === app.appId ? (
|
||||
@@ -376,7 +389,7 @@ export default function LightAppManagementPage() {
|
||||
className="fixed inset-0 z-40"
|
||||
onClick={() => setActiveParamPopover(null)}
|
||||
/>
|
||||
<div className="absolute left-4 top-12 z-50 w-[280px] animate-in fade-in rounded-xl border border-neutral-100 bg-white p-3.5 text-[12px] shadow-[0_8px_32px_rgba(34,34,34,0.16)]">
|
||||
<div className="absolute left-4 top-12 z-50 w-[280px] animate-in fade-in rounded-[5px] border border-neutral-100 bg-white p-3.5 text-[12px] shadow-[0_8px_32px_rgba(34,34,34,0.16)]">
|
||||
<div className="mb-2.5 flex items-center justify-between border-b border-neutral-100 pb-2">
|
||||
<span className="text-[11px] font-bold uppercase tracking-wider text-neutral-400">
|
||||
注入的路由参数
|
||||
@@ -392,7 +405,7 @@ export default function LightAppManagementPage() {
|
||||
{app.routeParams.map((p, idx) => (
|
||||
<div
|
||||
key={`${app.appId}-${idx}`}
|
||||
className="rounded-lg border border-neutral-100 bg-neutral-50/60 p-2 text-[11px] leading-relaxed"
|
||||
className="rounded-[5px] border border-neutral-100 bg-neutral-50/60 p-2 text-[11px] leading-relaxed"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-1 font-mono">
|
||||
<span className="truncate font-bold text-rose-700">{p.key}</span>
|
||||
@@ -432,14 +445,14 @@ export default function LightAppManagementPage() {
|
||||
<div className="flex items-center justify-center space-x-1">
|
||||
<button
|
||||
onClick={() => openEdit(app)}
|
||||
className="cursor-pointer rounded-lg p-1.5 text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-emerald-600"
|
||||
className="cursor-pointer rounded-[5px] p-1.5 text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-emerald-600"
|
||||
title="编辑配置"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDelete(app)}
|
||||
className="cursor-pointer rounded-lg p-1.5 text-neutral-400 transition-colors hover:bg-rose-50 hover:text-rose-600"
|
||||
className="cursor-pointer rounded-[5px] p-1.5 text-neutral-400 transition-colors hover:bg-rose-50 hover:text-rose-600"
|
||||
title="删除配置"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
@@ -474,7 +487,7 @@ export default function LightAppManagementPage() {
|
||||
</table>
|
||||
</div>
|
||||
) : tableApps.length === 0 ? (
|
||||
<div className="rounded-xl border border-dashed border-neutral-200 bg-white py-20 text-center">
|
||||
<div className="rounded-[5px] bg-white py-20 text-center">
|
||||
<div className="mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-neutral-100 text-neutral-300">
|
||||
<Info className="h-6 w-6" />
|
||||
</div>
|
||||
@@ -492,7 +505,7 @@ export default function LightAppManagementPage() {
|
||||
{tableApps.map((app) => (
|
||||
<div
|
||||
key={app.appId}
|
||||
className="group flex flex-col justify-between overflow-hidden rounded-xl border border-neutral-100 bg-white shadow-[0_1px_3px_0_rgba(0,0,0,0.01)] transition-all hover:border-[#F5222D]/20 hover:shadow-md"
|
||||
className="group flex flex-col justify-between overflow-hidden rounded-[5px] bg-white shadow-[0_1px_3px_0_rgba(0,0,0,0.01)] transition-all hover:shadow-md"
|
||||
>
|
||||
<div
|
||||
className={`h-1.5 w-full bg-gradient-to-r ${
|
||||
@@ -505,12 +518,12 @@ export default function LightAppManagementPage() {
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0 flex-1 space-y-1.5">
|
||||
{app.appType === "window_open" ? (
|
||||
<span className="inline-flex items-center space-x-1 rounded border border-rose-100 bg-rose-50 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-rose-700">
|
||||
<span className="inline-flex items-center space-x-1 rounded-[5px] border border-rose-100 bg-rose-50 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-rose-700">
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
<span>新页跳转</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center space-x-1 rounded border border-sky-100 bg-sky-50 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-sky-700">
|
||||
<span className="inline-flex items-center space-x-1 rounded-[5px] border border-sky-100 bg-sky-50 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-sky-700">
|
||||
<Monitor className="h-3 w-3" />
|
||||
<span>iframe 嵌套</span>
|
||||
</span>
|
||||
@@ -536,14 +549,14 @@ export default function LightAppManagementPage() {
|
||||
{app.description || "暂无应用详细描述说明。"}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center space-x-1.5 rounded-lg border border-neutral-200/40 bg-neutral-50/60 p-2 font-mono text-[11px] text-neutral-600">
|
||||
<div className="flex items-center space-x-1.5 rounded-[5px] bg-neutral-50/60 p-2 font-mono text-[11px] text-neutral-600">
|
||||
<Globe className="h-3.5 w-3.5 shrink-0 text-neutral-400" />
|
||||
<span className="flex-1 truncate" title={app.url}>
|
||||
{app.url}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => handleCopyUrl(app.url)}
|
||||
className="shrink-0 rounded p-1 text-neutral-400 transition-colors hover:bg-neutral-200 hover:text-neutral-600"
|
||||
className="shrink-0 rounded-[5px] p-1 text-neutral-400 transition-colors hover:bg-neutral-200 hover:text-neutral-600"
|
||||
title="复制网址"
|
||||
>
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
@@ -555,7 +568,7 @@ export default function LightAppManagementPage() {
|
||||
{app.routeParams.map((p, idx) => (
|
||||
<span
|
||||
key={`${app.appId}-card-${idx}`}
|
||||
className="rounded border border-neutral-200/40 bg-neutral-100 px-1.5 py-0.5 font-mono text-[10px] text-neutral-500"
|
||||
className="rounded-[5px] border border-neutral-200/40 bg-neutral-100 px-1.5 py-0.5 font-mono text-[10px] text-neutral-500"
|
||||
>
|
||||
{p.key}
|
||||
</span>
|
||||
@@ -564,7 +577,7 @@ export default function LightAppManagementPage() {
|
||||
)}
|
||||
|
||||
{app.appType === "iframe" && app.mountLocation && (
|
||||
<div className="inline-flex items-center gap-1.5 rounded-lg border border-sky-100/60 bg-sky-50/60 p-2 text-[11px] font-medium leading-none text-sky-700">
|
||||
<div className="inline-flex items-center gap-1.5 rounded-[5px] bg-sky-50/60 p-2 text-[11px] font-medium leading-none text-sky-700">
|
||||
<span>挂载分类:</span>
|
||||
<code className="font-semibold">{mountLabel(app.mountLocation)}</code>
|
||||
</div>
|
||||
@@ -574,14 +587,14 @@ export default function LightAppManagementPage() {
|
||||
<div className="flex items-center justify-end space-x-1 border-t border-neutral-100/60 bg-neutral-50/30 px-5 py-3">
|
||||
<button
|
||||
onClick={() => openEdit(app)}
|
||||
className="cursor-pointer rounded-lg p-1.5 text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-emerald-600"
|
||||
className="cursor-pointer rounded-[5px] p-1.5 text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-emerald-600"
|
||||
title="编辑配置"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDelete(app)}
|
||||
className="cursor-pointer rounded-lg p-1.5 text-neutral-400 transition-colors hover:bg-rose-50 hover:text-rose-600"
|
||||
className="cursor-pointer rounded-[5px] p-1.5 text-neutral-400 transition-colors hover:bg-rose-50 hover:text-rose-600"
|
||||
title="删除配置"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
@@ -594,7 +607,7 @@ export default function LightAppManagementPage() {
|
||||
</div>
|
||||
|
||||
{viewMode === "table" && (
|
||||
<div className="select-none rounded-xl border border-amber-200/40 bg-amber-50/40 p-5 shadow-[0_1px_2px_rgba(0,0,0,0.005)]">
|
||||
<div className="select-none rounded-[5px] bg-amber-50/40 p-5 shadow-[0_1px_2px_rgba(0,0,0,0.005)]">
|
||||
<div className="flex items-center space-x-2 border-b border-amber-100/50 pb-3 text-amber-800">
|
||||
<AlertCircle className="h-4 w-4 shrink-0 text-amber-600" />
|
||||
<h4 className="text-[13px] font-bold tracking-tight">智能多维挂载规则:</h4>
|
||||
@@ -627,10 +640,10 @@ export default function LightAppManagementPage() {
|
||||
onClick={() => setDialogOpen(false)}
|
||||
/>
|
||||
|
||||
<div className="relative z-[110] m-4 flex max-h-[90vh] w-full max-w-[580px] flex-col rounded-[4px] border border-[#E8E8E8] bg-white p-6 shadow-[0_8px_32px_rgba(34,34,34,0.16)]">
|
||||
<div className="relative z-[110] m-4 flex max-h-[90vh] w-full max-w-[580px] flex-col rounded-[5px] border border-[#E8E8E8] bg-white p-6 shadow-[0_8px_32px_rgba(34,34,34,0.16)]">
|
||||
<div className="flex flex-shrink-0 items-center justify-between border-b border-[#E8E8E8] pb-4">
|
||||
<div className="flex items-center space-x-2.5">
|
||||
<span className="rounded-lg bg-rose-50 p-1.5 text-[#A8071A]">
|
||||
<span className="rounded-[5px] bg-rose-50 p-1.5 text-[#A8071A]">
|
||||
<Layers className="h-5 w-5" />
|
||||
</span>
|
||||
<h2 className="text-[17px] font-bold text-[#222222]">
|
||||
@@ -639,7 +652,7 @@ export default function LightAppManagementPage() {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setDialogOpen(false)}
|
||||
className="cursor-pointer rounded-sm p-1 text-[#A6A6A6] transition-colors hover:bg-[#FAFAFA] hover:text-[#F5222D]"
|
||||
className="cursor-pointer rounded-[5px] p-1 text-[#A6A6A6] transition-colors hover:bg-[#FAFAFA] hover:text-[#F5222D]"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
</button>
|
||||
@@ -652,14 +665,13 @@ export default function LightAppManagementPage() {
|
||||
<Layers className="h-4 w-4 text-[#A6A6A6]" />
|
||||
<span>应用类型</span>
|
||||
</label>
|
||||
<select
|
||||
<Select
|
||||
className="w-full"
|
||||
value={form.appType}
|
||||
onChange={(e) => patchForm({ appType: e.target.value as LightAppType })}
|
||||
className="h-9 w-full cursor-pointer rounded-[2px] border border-[#DBDBDB] bg-white px-3 text-[14px] focus:border-[#F5222D] focus:outline-none focus:ring-1 focus:ring-[#F5222D]"
|
||||
>
|
||||
<option value="iframe">iframe 嵌套 (挂载到菜单)</option>
|
||||
<option value="window_open">window.open (新页跳转)</option>
|
||||
</select>
|
||||
options={APP_TYPE_OPTIONS}
|
||||
popupProps={DIALOG_SELECT_POPUP}
|
||||
onChange={(v) => patchForm({ appType: v as LightAppType })}
|
||||
/>
|
||||
<p className="text-[11.5px] leading-relaxed text-[#A6A6A6]">
|
||||
{form.appType === "window_open"
|
||||
? "在新标签页或卡片式路由容器打开。多用于外部高度复杂的系统跳转。"
|
||||
@@ -677,7 +689,7 @@ export default function LightAppManagementPage() {
|
||||
value={form.name}
|
||||
onChange={(e) => patchForm({ name: e.target.value })}
|
||||
placeholder="如: 舆情看板"
|
||||
className="h-9 rounded-[2px] border-[#DBDBDB] text-[14px]"
|
||||
className="h-9 rounded-[5px] border-[#DBDBDB] text-[14px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -691,7 +703,7 @@ export default function LightAppManagementPage() {
|
||||
value={form.url}
|
||||
onChange={(e) => patchForm({ url: e.target.value })}
|
||||
placeholder="https://example.com/page 或 http://47.88.25.99:3000/"
|
||||
className="h-9 rounded-[2px] border-[#DBDBDB] font-mono text-[14px]"
|
||||
className="h-9 rounded-[5px] border-[#DBDBDB] font-mono text-[14px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -702,18 +714,14 @@ export default function LightAppManagementPage() {
|
||||
<FolderTree className="h-4 w-4 text-[#A6A6A6]" />
|
||||
<span>挂载菜单</span>
|
||||
</label>
|
||||
<select
|
||||
value={form.mountLocation}
|
||||
onChange={(e) => patchForm({ mountLocation: e.target.value })}
|
||||
className="h-9 w-full cursor-pointer rounded-[2px] border border-[#DBDBDB] bg-white px-3 text-[14px] focus:border-[#F5222D] focus:outline-none focus:ring-1 focus:ring-[#F5222D]"
|
||||
>
|
||||
<option value="">请选择挂载菜单</option>
|
||||
{MOUNT_OPTIONS.map((o) => (
|
||||
<option key={o.value} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<Select
|
||||
className="w-full"
|
||||
value={form.mountLocation || undefined}
|
||||
placeholder="请选择挂载菜单"
|
||||
options={MOUNT_OPTIONS}
|
||||
popupProps={DIALOG_SELECT_POPUP}
|
||||
onChange={(v) => patchForm({ mountLocation: (v as string) ?? "" })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -728,7 +736,7 @@ export default function LightAppManagementPage() {
|
||||
onChange={(e) => patchForm({ description: e.target.value })}
|
||||
placeholder="简要说明该应用的用途"
|
||||
rows={2}
|
||||
className="resize-none rounded-[2px] border-[#DBDBDB] text-[14px]"
|
||||
className="resize-none rounded-[5px] border-[#DBDBDB] text-[14px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -747,7 +755,7 @@ export default function LightAppManagementPage() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={addParam}
|
||||
className="flex h-7 cursor-pointer items-center space-x-1 rounded-[2px] border border-[#DBDBDB] bg-white px-2.5 text-[12px] font-bold text-[#575757] transition-colors hover:border-[#F5222D] hover:text-[#F5222D]"
|
||||
className="flex h-7 cursor-pointer items-center space-x-1 rounded-[5px] border border-[#DBDBDB] bg-white px-2.5 text-[12px] font-bold text-[#575757] transition-colors hover:border-[#F5222D] hover:text-[#F5222D]"
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
<span>添加路由参数</span>
|
||||
@@ -755,14 +763,14 @@ export default function LightAppManagementPage() {
|
||||
</div>
|
||||
|
||||
{form.routeParams.length > 0 ? (
|
||||
<div className="max-h-[220px] space-y-2 overflow-y-auto rounded-sm border border-[#E8E8E8] bg-[#FAFAFA] p-1">
|
||||
<div className="max-h-[220px] space-y-2 overflow-y-auto rounded-[5px] border border-[#E8E8E8] bg-[#FAFAFA] p-1">
|
||||
{form.routeParams.map((p, idx) => {
|
||||
const themeMap =
|
||||
p.paramType === "theme" ? parseThemeMap(p.themeValue) : {};
|
||||
return (
|
||||
<div
|
||||
key={idx}
|
||||
className="relative rounded-sm border border-[#E8E8E8] bg-white p-2"
|
||||
className="relative rounded-[5px] border border-[#E8E8E8] bg-white p-2"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex-1">
|
||||
@@ -771,40 +779,36 @@ export default function LightAppManagementPage() {
|
||||
value={p.key}
|
||||
onChange={(e) => patchParam(idx, { key: e.target.value })}
|
||||
placeholder="参数名 key"
|
||||
className="h-8 w-full rounded-[2px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
|
||||
className="h-8 w-full rounded-[5px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-[110px]">
|
||||
<select
|
||||
<Select
|
||||
className="w-full"
|
||||
size="small"
|
||||
value={p.paramType}
|
||||
onChange={(e) =>
|
||||
options={PARAM_TYPE_OPTIONS}
|
||||
popupProps={DIALOG_SELECT_POPUP}
|
||||
onChange={(v) =>
|
||||
patchParam(idx, {
|
||||
paramType: e.target.value as "login" | "theme",
|
||||
source:
|
||||
e.target.value === "login" ? (p.source || "accessToken") : undefined,
|
||||
paramType: v as "login" | "theme",
|
||||
source: v === "login" ? (p.source || "accessToken") : undefined,
|
||||
})
|
||||
}
|
||||
className="h-8 w-full rounded-[2px] border border-[#DBDBDB] bg-[#FAFAFA] px-1 text-[12px] focus:border-[#F5222D] focus:outline-none"
|
||||
>
|
||||
<option value="login">登录参数</option>
|
||||
<option value="theme">主题参数</option>
|
||||
</select>
|
||||
/>
|
||||
</div>
|
||||
|
||||
{p.paramType === "login" && (
|
||||
<div className="flex flex-[1.2] items-center gap-2 text-[11px]">
|
||||
<select
|
||||
<Select
|
||||
className="w-full"
|
||||
size="small"
|
||||
value={p.source || "accessToken"}
|
||||
onChange={(e) => patchParam(idx, { source: e.target.value })}
|
||||
className="h-8 w-full rounded-[2px] border border-[#DBDBDB] bg-white px-1 text-[12px] focus:border-[#F5222D] focus:outline-none"
|
||||
>
|
||||
{LOGIN_SOURCE_OPTIONS.map((o) => (
|
||||
<option key={o.value} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
options={LOGIN_SOURCE_OPTIONS}
|
||||
popupProps={DIALOG_SELECT_POPUP}
|
||||
onChange={(v) => patchParam(idx, { source: v as string })}
|
||||
/>
|
||||
{p.source === "other" && (
|
||||
<input
|
||||
type="text"
|
||||
@@ -813,7 +817,7 @@ export default function LightAppManagementPage() {
|
||||
patchParam(idx, { customValue: e.target.value })
|
||||
}
|
||||
placeholder="自定义值"
|
||||
className="h-8 w-[120px] rounded-[2px] border border-[#DBDBDB] px-2 text-[12px] focus:border-[#F5222D] focus:outline-none"
|
||||
className="h-8 w-[120px] rounded-[5px] border border-[#DBDBDB] px-2 text-[12px] focus:border-[#F5222D] focus:outline-none"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -822,7 +826,7 @@ export default function LightAppManagementPage() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => removeParam(idx)}
|
||||
className="cursor-pointer rounded-sm p-1 text-[#A6A6A6] transition-colors hover:bg-[#FEEDED] hover:text-[#F5222D]"
|
||||
className="cursor-pointer rounded-[5px] p-1 text-[#A6A6A6] transition-colors hover:bg-[#FEEDED] hover:text-[#F5222D]"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -830,7 +834,7 @@ export default function LightAppManagementPage() {
|
||||
|
||||
{/* 主题参数:逐主题色配置传给目标应用的值(左=系统主题色,右=目标应用值,可改) */}
|
||||
{p.paramType === "theme" && (
|
||||
<div className="mt-2 space-y-1.5 rounded-sm bg-[#FAFAFA] p-2">
|
||||
<div className="mt-2 space-y-1.5 rounded-[5px] bg-[#FAFAFA] p-2">
|
||||
<p className="text-[11px] leading-relaxed text-[#A6A6A6]">
|
||||
各系统主题色跳转/嵌套时传给该应用的值(默认同名,可按对方命名修改)
|
||||
</p>
|
||||
@@ -858,7 +862,7 @@ export default function LightAppManagementPage() {
|
||||
})
|
||||
}
|
||||
placeholder={c.key}
|
||||
className="h-7 flex-1 rounded-[2px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
|
||||
className="h-7 flex-1 rounded-[5px] border border-[#DBDBDB] bg-white px-2 font-mono text-[12px] focus:border-[#F5222D] focus:outline-none focus:ring-px focus:ring-[#F5222D]"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
@@ -869,7 +873,7 @@ export default function LightAppManagementPage() {
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="rounded-sm border border-dashed border-[#E8E8E8] bg-[#FAFAFA] p-4 text-center text-[12px] text-[#A6A6A6]">
|
||||
<div className="rounded-[5px] border border-dashed border-[#E8E8E8] bg-[#FAFAFA] p-4 text-center text-[12px] text-[#A6A6A6]">
|
||||
暂无注入的路由参数,加载地址时不传递多余拼接。
|
||||
</div>
|
||||
)}
|
||||
@@ -898,7 +902,7 @@ export default function LightAppManagementPage() {
|
||||
variant="outline"
|
||||
disabled={saving}
|
||||
onClick={() => setDialogOpen(false)}
|
||||
className="h-9 rounded-[2px] border-[#DBDBDB] px-[18px] text-[14px] font-semibold"
|
||||
className="h-9 rounded-[5px] border-[#DBDBDB] px-[18px] text-[14px] font-semibold"
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
@@ -906,7 +910,7 @@ export default function LightAppManagementPage() {
|
||||
type="button"
|
||||
disabled={saving}
|
||||
onClick={handleSave}
|
||||
className="h-9 cursor-pointer rounded-[2px] bg-[#F5222D] px-[18px] text-[14px] font-bold text-white shadow-[0_2px_8px_rgba(34,34,34,0.08)] transition-colors hover:bg-[#CF1322] active:bg-[#A8071A] disabled:cursor-not-allowed disabled:opacity-70"
|
||||
className="h-9 cursor-pointer rounded-[5px] bg-[#F5222D] px-[18px] text-[14px] font-bold text-white shadow-[0_2px_8px_rgba(34,34,34,0.08)] transition-colors hover:bg-[#CF1322] active:bg-[#A8071A] disabled:cursor-not-allowed disabled:opacity-70"
|
||||
>
|
||||
{saving ? "保存中..." : editing ? "保存修改" : "立即注册"}
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user