update: replace Icon with lucide-react
This commit is contained in:
@@ -1,7 +1,14 @@
|
|||||||
import { memo, useMemo, useState } from "react";
|
import { memo, useMemo, useState } from "react";
|
||||||
|
|
||||||
import { type ScheduleArtifact } from "../../services/api";
|
import { type ScheduleArtifact } from "~/services/api";
|
||||||
import Icon from "../../components/common/Icon";
|
import {
|
||||||
|
BookText,
|
||||||
|
ChevronRight,
|
||||||
|
ExternalLink,
|
||||||
|
FileCode2,
|
||||||
|
GripVertical,
|
||||||
|
Search,
|
||||||
|
} from "lucide-react";
|
||||||
import { shortHash } from "./utils";
|
import { shortHash } from "./utils";
|
||||||
|
|
||||||
// 包裹 memo 让父级 SchedulePage 在画布交互(setSelectedNodeId /
|
// 包裹 memo 让父级 SchedulePage 在画布交互(setSelectedNodeId /
|
||||||
@@ -68,7 +75,7 @@ function ArtifactListImpl({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label className="mx-[10px] mb-[7px] flex min-h-[35px] items-center gap-[7px] rounded-[6px] border border-[#dce5ed] bg-white px-[9px] text-[#95a3b2] focus-within:border-[#8db9e8] focus-within:shadow-[0_0_0_3px_rgb(38_124_216_/_8%)]">
|
<label className="mx-[10px] mb-[7px] flex min-h-[35px] items-center gap-[7px] rounded-[6px] border border-[#dce5ed] bg-white px-[9px] text-[#95a3b2] focus-within:border-[#8db9e8] focus-within:shadow-[0_0_0_3px_rgb(38_124_216_/_8%)]">
|
||||||
<Icon name="search" size={15} />
|
<Search size={15} />
|
||||||
<input
|
<input
|
||||||
className="min-w-0 flex-1 border-0 bg-transparent text-[12px] text-[#33475d] outline-none placeholder:text-[#a6b2be]"
|
className="min-w-0 flex-1 border-0 bg-transparent text-[12px] text-[#33475d] outline-none placeholder:text-[#a6b2be]"
|
||||||
value={keyword}
|
value={keyword}
|
||||||
@@ -85,7 +92,6 @@ function ArtifactListImpl({
|
|||||||
groups.map(([scriptName, items]) => {
|
groups.map(([scriptName, items]) => {
|
||||||
const isExpanded = expandedScriptNames.has(scriptName);
|
const isExpanded = expandedScriptNames.has(scriptName);
|
||||||
const scriptType = items[0].script_type;
|
const scriptType = items[0].script_type;
|
||||||
const iconName = scriptType === "notebook" ? "notebook" : "python";
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={scriptName}
|
key={scriptName}
|
||||||
@@ -102,7 +108,7 @@ function ArtifactListImpl({
|
|||||||
data-state={isExpanded ? "open" : "closed"}
|
data-state={isExpanded ? "open" : "closed"}
|
||||||
className="h-[14px] w-[14px] flex-none text-[#9aa7b5] transition-transform duration-[180ms] data-[state=open]:rotate-90"
|
className="h-[14px] w-[14px] flex-none text-[#9aa7b5] transition-transform duration-[180ms] data-[state=open]:rotate-90"
|
||||||
>
|
>
|
||||||
<Icon name="chevron" size={14} />
|
<ChevronRight size={14} />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className={`grid h-[27px] w-[27px] flex-none place-items-center rounded-[6px] ${
|
className={`grid h-[27px] w-[27px] flex-none place-items-center rounded-[6px] ${
|
||||||
@@ -111,7 +117,11 @@ function ArtifactListImpl({
|
|||||||
: "bg-[#eaf3ff] text-[#326fc1]"
|
: "bg-[#eaf3ff] text-[#326fc1]"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Icon name={iconName} size={14} />
|
{scriptType === "notebook" ? (
|
||||||
|
<BookText size={14} />
|
||||||
|
) : (
|
||||||
|
<FileCode2 size={14} />
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="max-w-[125px] min-w-0 truncate text-[11px] font-semibold text-[#33465a] min-[1281px]:max-w-none"
|
className="max-w-[125px] min-w-0 truncate text-[11px] font-semibold text-[#33465a] min-[1281px]:max-w-none"
|
||||||
@@ -146,7 +156,7 @@ function ArtifactListImpl({
|
|||||||
>
|
>
|
||||||
<span className="flex min-w-0 items-center gap-[5px]">
|
<span className="flex min-w-0 items-center gap-[5px]">
|
||||||
<span className="h-[13px] w-[13px] flex-none text-[#c4cdd6] group-hover:text-[#7e8d9d]">
|
<span className="h-[13px] w-[13px] flex-none text-[#c4cdd6] group-hover:text-[#7e8d9d]">
|
||||||
<Icon name="grip-vertical" size={13} />
|
<GripVertical size={13} />
|
||||||
</span>
|
</span>
|
||||||
<span className="flex-none text-[10px] font-semibold text-[#526477]">
|
<span className="flex-none text-[10px] font-semibold text-[#526477]">
|
||||||
{artifact.version_label}
|
{artifact.version_label}
|
||||||
@@ -156,7 +166,7 @@ function ArtifactListImpl({
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="grid h-[18px] w-[18px] flex-none place-items-center rounded-[4px] text-[#c1cad3] group-hover:bg-[#eef6ff] group-hover:text-[#287ac5]">
|
<span className="grid h-[18px] w-[18px] flex-none place-items-center rounded-[4px] text-[#c1cad3] group-hover:bg-[#eef6ff] group-hover:text-[#287ac5]">
|
||||||
<Icon name="external" size={12} />
|
<ExternalLink size={12} />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -170,7 +180,7 @@ function ArtifactListImpl({
|
|||||||
<p className="mx-[10px] mb-[9px] mt-[3px] flex items-center justify-center gap-1 rounded-[6px] border border-line-soft bg-[#f8fafc] p-[7px_8px] text-center text-[9px] leading-[1.45] text-[#8795a4]">
|
<p className="mx-[10px] mb-[9px] mt-[3px] flex items-center justify-center gap-1 rounded-[6px] border border-line-soft bg-[#f8fafc] p-[7px_8px] text-center text-[9px] leading-[1.45] text-[#8795a4]">
|
||||||
<span>按住</span>
|
<span>按住</span>
|
||||||
<span className="inline-flex items-center justify-center text-[#9eabb8]">
|
<span className="inline-flex items-center justify-center text-[#9eabb8]">
|
||||||
<Icon name="grip-vertical" size={12} />
|
<GripVertical size={12} />
|
||||||
</span>
|
</span>
|
||||||
<span>拖拽卡片到画布即可绑定节点</span>
|
<span>拖拽卡片到画布即可绑定节点</span>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type ScheduleNode } from "../../services/api";
|
import { type ScheduleNode } from "../../services/api";
|
||||||
import Icon from "../../components/common/Icon";
|
import { BookText, FileCode2 } from "lucide-react";
|
||||||
import { shortHash } from "./utils";
|
import { shortHash } from "./utils";
|
||||||
import { PYTHON_VERSION_OPTIONS, type NodeForm } from "./state/schedulesStore";
|
import { PYTHON_VERSION_OPTIONS, type NodeForm } from "./state/schedulesStore";
|
||||||
|
|
||||||
@@ -28,10 +28,11 @@ export function NodeInspector({
|
|||||||
: "bg-[#eaf3ff] text-[#326fc1]"
|
: "bg-[#eaf3ff] text-[#326fc1]"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Icon
|
{node.version.script_type === "notebook" ? (
|
||||||
name={node.version.script_type === "notebook" ? "notebook" : "python"}
|
<BookText size={17} />
|
||||||
size={17}
|
) : (
|
||||||
/>
|
<FileCode2 size={17} />
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex min-w-0 flex-col gap-[3px]">
|
<div className="flex min-w-0 flex-col gap-[3px]">
|
||||||
<small className="text-[9px] text-[#96a2af]">节点配置</small>
|
<small className="text-[9px] text-[#96a2af]">节点配置</small>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
} from "../../services/api";
|
} from "../../services/api";
|
||||||
|
|
||||||
import { useApi } from "../../context/AuthContext";
|
import { useApi } from "../../context/AuthContext";
|
||||||
import Icon from "../../components/common/Icon";
|
import { RefreshCw, X } from "lucide-react";
|
||||||
import { useSchedulesStore } from "./state/schedulesStore";
|
import { useSchedulesStore } from "./state/schedulesStore";
|
||||||
import {
|
import {
|
||||||
formatDuration,
|
formatDuration,
|
||||||
@@ -231,7 +231,7 @@ export function RunHistory({
|
|||||||
disabled={disabled || loading}
|
disabled={disabled || loading}
|
||||||
onClick={onRefresh}
|
onClick={onRefresh}
|
||||||
>
|
>
|
||||||
<Icon name="refresh" size={13} />
|
<RefreshCw size={13} />
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div className="flex min-h-0 flex-1 flex-col gap-[7px] overflow-auto p-[9px]">
|
<div className="flex min-h-0 flex-1 flex-col gap-[7px] overflow-auto p-[9px]">
|
||||||
@@ -316,7 +316,7 @@ export function RunHistory({
|
|||||||
aria-label="关闭运行结果"
|
aria-label="关闭运行结果"
|
||||||
onClick={() => toggleRun(run.run_id)}
|
onClick={() => toggleRun(run.run_id)}
|
||||||
>
|
>
|
||||||
<Icon name="close" size={16} />
|
<X size={16} />
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div className="min-h-0 overflow-auto bg-[#f8fbfe] p-[18px]">
|
<div className="min-h-0 overflow-auto bg-[#f8fbfe] p-[18px]">
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import Icon from "../../components/common/Icon";
|
|
||||||
|
|
||||||
export function ScheduleCanvasHeader({
|
export function ScheduleCanvasHeader({
|
||||||
linkSourceId,
|
linkSourceId,
|
||||||
onCancelLink,
|
onCancelLink,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type Schedule, type CronPreview } from "../../services/api";
|
import { type Schedule, type CronPreview } from "../../services/api";
|
||||||
import Icon from "../../components/common/Icon";
|
import { Settings } from "lucide-react";
|
||||||
import { formatTime } from "./utils";
|
import { formatTime } from "./utils";
|
||||||
|
|
||||||
type ScheduleForm = {
|
type ScheduleForm = {
|
||||||
@@ -33,7 +33,7 @@ export function ScheduleInspector({
|
|||||||
if (!schedule) {
|
if (!schedule) {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-full flex-col items-center justify-center p-[30px] text-center text-[#9aa8b6] [&>svg]:mb-[10px] [&>svg]:text-[#93b4d6]">
|
<div className="flex min-h-full flex-col items-center justify-center p-[30px] text-center text-[#9aa8b6] [&>svg]:mb-[10px] [&>svg]:text-[#93b4d6]">
|
||||||
<Icon name="settings" size={28} />
|
<Settings size={28} />
|
||||||
<strong className="text-[14px] text-[#516a82]">调度属性</strong>
|
<strong className="text-[14px] text-[#516a82]">调度属性</strong>
|
||||||
<p className="text-[11px] leading-[1.6]">
|
<p className="text-[11px] leading-[1.6]">
|
||||||
选中调度方案后可配置触发方式、Cron 和执行策略。
|
选中调度方案后可配置触发方式、Cron 和执行策略。
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type Schedule } from "../../services/api";
|
import { type Schedule } from "../../services/api";
|
||||||
import Icon from "../../components/common/Icon";
|
import { Search } from "lucide-react";
|
||||||
|
|
||||||
export function ScheduleList({
|
export function ScheduleList({
|
||||||
schedules,
|
schedules,
|
||||||
@@ -36,7 +36,7 @@ export function ScheduleList({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label className="mx-[10px] mb-[7px] flex min-h-[35px] items-center gap-[7px] rounded-[6px] border border-[#dce5ed] bg-white px-[9px] text-[#95a3b2] focus-within:border-[#8db9e8] focus-within:shadow-[0_0_0_3px_rgb(38_124_216_/_8%)]">
|
<label className="mx-[10px] mb-[7px] flex min-h-[35px] items-center gap-[7px] rounded-[6px] border border-[#dce5ed] bg-white px-[9px] text-[#95a3b2] focus-within:border-[#8db9e8] focus-within:shadow-[0_0_0_3px_rgb(38_124_216_/_8%)]">
|
||||||
<Icon name="search" size={15} />
|
<Search size={15} />
|
||||||
<input
|
<input
|
||||||
className="min-w-0 flex-1 border-0 bg-transparent text-[12px] text-[#33475d] outline-none placeholder:text-[#a6b2be]"
|
className="min-w-0 flex-1 border-0 bg-transparent text-[12px] text-[#33475d] outline-none placeholder:text-[#a6b2be]"
|
||||||
value={keyword}
|
value={keyword}
|
||||||
|
|||||||
@@ -9,7 +9,17 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { Plus } from 'lucide-react';
|
import {
|
||||||
|
BookText,
|
||||||
|
CalendarClock,
|
||||||
|
Check,
|
||||||
|
FileCode2,
|
||||||
|
PackageOpen,
|
||||||
|
Play,
|
||||||
|
Plus,
|
||||||
|
Settings,
|
||||||
|
X,
|
||||||
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
type Schedule,
|
type Schedule,
|
||||||
type ScheduleArtifact,
|
type ScheduleArtifact,
|
||||||
@@ -18,7 +28,6 @@ import {
|
|||||||
} from "~/services/api";
|
} from "~/services/api";
|
||||||
|
|
||||||
import { useApi, useAuth } from "~/context/AuthContext";
|
import { useApi, useAuth } from "~/context/AuthContext";
|
||||||
import Icon from "../../components/common/Icon";
|
|
||||||
import { NodeInspector } from "./NodeInspector";
|
import { NodeInspector } from "./NodeInspector";
|
||||||
import { RunHistory } from "./RunHistory";
|
import { RunHistory } from "./RunHistory";
|
||||||
import { ScheduleInspector } from "./ScheduleInspector";
|
import { ScheduleInspector } from "./ScheduleInspector";
|
||||||
@@ -92,7 +101,7 @@ function RunNowButton({
|
|||||||
}
|
}
|
||||||
onClick={() => useSchedulesStore.getState().runNow()}
|
onClick={() => useSchedulesStore.getState().runNow()}
|
||||||
>
|
>
|
||||||
<Icon name="play" size={14} />立即运行
|
<Play size={14} />立即运行
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -370,7 +379,7 @@ export default function SchedulePage({
|
|||||||
disabled={!schedule || Boolean(busy)}
|
disabled={!schedule || Boolean(busy)}
|
||||||
onClick={() => useSchedulesStore.getState().saveSchedule()}
|
onClick={() => useSchedulesStore.getState().saveSchedule()}
|
||||||
>
|
>
|
||||||
<Icon name="check" size={15} />保存配置
|
<Check size={15} />保存配置
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="inline-flex min-h-[32px] cursor-pointer items-center justify-center gap-[5px] rounded-[6px] border border-[#dce5ee] bg-white px-2 text-[12px] font-semibold text-[#526477] enabled:hover:border-[#aac6e5] enabled:hover:bg-[#f6faff] enabled:hover:text-[#126aca] disabled:cursor-not-allowed disabled:opacity-50 min-[1281px]:px-3"
|
className="inline-flex min-h-[32px] cursor-pointer items-center justify-center gap-[5px] rounded-[6px] border border-[#dce5ee] bg-white px-2 text-[12px] font-semibold text-[#526477] enabled:hover:border-[#aac6e5] enabled:hover:bg-[#f6faff] enabled:hover:text-[#126aca] disabled:cursor-not-allowed disabled:opacity-50 min-[1281px]:px-3"
|
||||||
@@ -517,10 +526,11 @@ export default function SchedulePage({
|
|||||||
: "bg-[#eaf3ff] text-[#316fbf]"
|
: "bg-[#eaf3ff] text-[#316fbf]"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Icon
|
{node.version.script_type === "notebook" ? (
|
||||||
name={node.version.script_type === "notebook" ? "notebook" : "python"}
|
<BookText size={14} />
|
||||||
size={14}
|
) : (
|
||||||
/>
|
<FileCode2 size={14} />
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<strong className="min-w-0 flex-1 truncate text-[12px] text-[#243b53]">
|
<strong className="min-w-0 flex-1 truncate text-[12px] text-[#243b53]">
|
||||||
{node.node_name}
|
{node.node_name}
|
||||||
@@ -536,7 +546,7 @@ export default function SchedulePage({
|
|||||||
setSelectedEdgeId(null);
|
setSelectedEdgeId(null);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="settings" size={14} />
|
<Settings size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-2 mb-1.5 truncate text-[10px] text-[#7e8d9d]">
|
<p className="mt-2 mb-1.5 truncate text-[10px] text-[#7e8d9d]">
|
||||||
@@ -571,7 +581,7 @@ export default function SchedulePage({
|
|||||||
|
|
||||||
{!schedule ? (
|
{!schedule ? (
|
||||||
<div className="sticky left-1/2 top-[46%] z-0 mx-auto mt-[190px] flex w-[350px] flex-col items-center text-center text-[#9aa8b6] [&>svg]:mb-3 [&>svg]:text-[#8cb4de]">
|
<div className="sticky left-1/2 top-[46%] z-0 mx-auto mt-[190px] flex w-[350px] flex-col items-center text-center text-[#9aa8b6] [&>svg]:mb-3 [&>svg]:text-[#8cb4de]">
|
||||||
<Icon name="schedule" size={34} />
|
<CalendarClock size={34} />
|
||||||
<strong className="text-[14px] text-[#567089]">还没有选中调度方案</strong>
|
<strong className="text-[14px] text-[#567089]">还没有选中调度方案</strong>
|
||||||
<p className="my-[7px_13px] text-[11px]">点击"新建"创建一个调度,然后拖入稳定版本脚本。</p>
|
<p className="my-[7px_13px] text-[11px]">点击"新建"创建一个调度,然后拖入稳定版本脚本。</p>
|
||||||
<button
|
<button
|
||||||
@@ -584,7 +594,7 @@ export default function SchedulePage({
|
|||||||
</div>
|
</div>
|
||||||
) : schedule.nodes.length === 0 ? (
|
) : schedule.nodes.length === 0 ? (
|
||||||
<div className="sticky left-1/2 top-[46%] z-0 mx-auto mt-[190px] flex w-[350px] flex-col items-center text-center text-[#9aa8b6] [&>svg]:mb-3 [&>svg]:text-[#8cb4de]">
|
<div className="sticky left-1/2 top-[46%] z-0 mx-auto mt-[190px] flex w-[350px] flex-col items-center text-center text-[#9aa8b6] [&>svg]:mb-3 [&>svg]:text-[#8cb4de]">
|
||||||
<Icon name="release" size={34} />
|
<PackageOpen size={34} />
|
||||||
<strong className="text-[14px] text-[#567089]">从稳定版本开始编排</strong>
|
<strong className="text-[14px] text-[#567089]">从稳定版本开始编排</strong>
|
||||||
<p className="my-[7px_13px] text-[11px]">把左侧脚本卡片拖到这里,或双击卡片快速加入。</p>
|
<p className="my-[7px_13px] text-[11px]">把左侧脚本卡片拖到这里,或双击卡片快速加入。</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -680,7 +690,7 @@ export default function SchedulePage({
|
|||||||
role="menuitem"
|
role="menuitem"
|
||||||
onClick={() => useSchedulesStore.getState().renameSchedule(contextMenu.schedule)}
|
onClick={() => useSchedulesStore.getState().renameSchedule(contextMenu.schedule)}
|
||||||
>
|
>
|
||||||
<Icon name="settings" size={14} />
|
<Settings size={14} />
|
||||||
改名
|
改名
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -689,7 +699,7 @@ export default function SchedulePage({
|
|||||||
role="menuitem"
|
role="menuitem"
|
||||||
onClick={() => useSchedulesStore.getState().removeSchedule(contextMenu.schedule)}
|
onClick={() => useSchedulesStore.getState().removeSchedule(contextMenu.schedule)}
|
||||||
>
|
>
|
||||||
<Icon name="close" size={14} />
|
<X size={14} />
|
||||||
删除调度方案
|
删除调度方案
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
@@ -702,7 +712,7 @@ export default function SchedulePage({
|
|||||||
role="menuitem"
|
role="menuitem"
|
||||||
onClick={() => useSchedulesStore.getState().removeNode(contextMenu.node)}
|
onClick={() => useSchedulesStore.getState().removeNode(contextMenu.node)}
|
||||||
>
|
>
|
||||||
<Icon name="close" size={14} />
|
<X size={14} />
|
||||||
删除画布节点
|
删除画布节点
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@@ -713,7 +723,7 @@ export default function SchedulePage({
|
|||||||
role="menuitem"
|
role="menuitem"
|
||||||
onClick={() => useSchedulesStore.getState().removeEdge(contextMenu.edge)}
|
onClick={() => useSchedulesStore.getState().removeEdge(contextMenu.edge)}
|
||||||
>
|
>
|
||||||
<Icon name="close" size={14} />
|
<X size={14} />
|
||||||
删除画布连线
|
删除画布连线
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@@ -740,7 +750,7 @@ export default function SchedulePage({
|
|||||||
disabled={Boolean(busy)}
|
disabled={Boolean(busy)}
|
||||||
onClick={() => setCreateDialogOpen(false)}
|
onClick={() => setCreateDialogOpen(false)}
|
||||||
>
|
>
|
||||||
<Icon name="close" />
|
<X size={14} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form onSubmit={handleCreateScheduleSubmit}>
|
<form onSubmit={handleCreateScheduleSubmit}>
|
||||||
|
|||||||
Reference in New Issue
Block a user