remove wrong deploy btn

This commit is contained in:
2026-03-17 22:16:13 +08:00
parent 23a4e1e8cb
commit 0f9f1a94fa
12 changed files with 106 additions and 760 deletions

View File

@@ -5,18 +5,12 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import { Layout, Typography, Space, Modal } from "antd";
Layout,
Typography,
Space,
Modal,
} from "antd";
import { Button, Tooltip } from "@lobehub/ui"; import { Button, Tooltip } from "@lobehub/ui";
import { import {
Cloud, Cloud,
CloudUpload,
History, History,
PanelLeftClose, PanelLeftClose,
PanelLeftOpen, PanelLeftOpen,
@@ -29,7 +23,6 @@ import { useUIStore } from "@renderer/stores";
import { DomainManager } from "@renderer/components/DomainManager"; import { DomainManager } from "@renderer/components/DomainManager";
import { AppList } from "@renderer/components/AppList"; import { AppList } from "@renderer/components/AppList";
import { AppDetail } from "@renderer/components/AppDetail"; import { AppDetail } from "@renderer/components/AppDetail";
import { DeployDialog } from "@renderer/components/DeployDialog";
import { Settings } from "@renderer/components/Settings"; import { Settings } from "@renderer/components/Settings";
const { Header, Content, Sider } = Layout; const { Header, Content, Sider } = Layout;
const { Title } = Typography; const { Title } = Typography;
@@ -173,7 +166,6 @@ const App: React.FC = () => {
setSiderCollapsed, setSiderCollapsed,
setDomainExpanded, setDomainExpanded,
} = useUIStore(); } = useUIStore();
const [deployDialogOpen, setDeployDialogOpen] = React.useState(false);
const [settingsOpen, setSettingsOpen] = React.useState(false); const [settingsOpen, setSettingsOpen] = React.useState(false);
const [isResizing, setIsResizing] = React.useState(false); const [isResizing, setIsResizing] = React.useState(false);
@@ -216,134 +208,114 @@ const App: React.FC = () => {
}; };
return ( return (
<Layout className={styles.layout}> <Layout className={styles.layout}>
{/* Left Sider - Domain List & App List */} {/* Left Sider - Domain List & App List */}
<Sider <Sider
width={sidebarWidth} width={sidebarWidth}
className={`${styles.sider} ${siderCollapsed ? styles.siderCollapsed : ""}`} className={`${styles.sider} ${siderCollapsed ? styles.siderCollapsed : ""}`}
style={{ width: siderCollapsed ? 0 : sidebarWidth }} style={{ width: siderCollapsed ? 0 : sidebarWidth }}
> >
{!siderCollapsed && ( {!siderCollapsed && (
<> <>
<div className={styles.logo}> <div className={styles.logo}>
<div <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
style={{ display: "flex", alignItems: "center", gap: 8 }} <Cloud size={24} style={{ color: token.colorPrimary }} />
> <span className={styles.logoText}>Kintone JS/CSS Manager</span>
<Cloud size={24} style={{ color: token.colorPrimary }} />
<span className={styles.logoText}>Kintone JS/CSS Manager</span>
</div>
<Tooltip title={t("collapseSidebar")} mouseEnterDelay={0.5}>
<Button
type="text"
icon={<PanelLeftClose size={16} />}
onClick={toggleSider}
className={styles.siderCloseButton}
size="small"
/>
</Tooltip>
</div>
<div className={styles.siderContent}>
<div
className={styles.domainSection}
style={{ height: domainSectionHeight }}
>
<DomainManager
collapsed={!domainExpanded}
onToggleCollapse={() =>
setDomainExpanded(!domainExpanded)
}
/>
</div>
<div
className={styles.appSection}
style={{ height: `calc(100% - ${domainSectionHeight}px)` }}
>
<AppList />
</div>
</div>
{/* Resize handle */}
<div
className={styles.resizeHandle}
onMouseDown={handleResizeStart}
style={{ background: isResizing ? token.colorPrimary : undefined }}
/>
</>
)}
</Sider>
{/* Main Content */}
<Layout
className={`${styles.mainLayout} ${siderCollapsed ? styles.mainLayoutCollapsed : ""}`}
style={{ marginLeft: siderCollapsed ? 0 : sidebarWidth }}
>
<Header className={styles.header}>
<div className={styles.headerLeft}>
{siderCollapsed && (
<Tooltip title={t("expandSidebar")} mouseEnterDelay={0.5}>
<Button
type="text"
icon={<PanelLeftOpen size={16} />}
onClick={toggleSider}
size="small"
/>
</Tooltip>
)}
<Title level={5} style={{ margin: 0 }}>
{currentDomain
? currentDomain.name
: "Kintone Customize Manager"}
</Title>
</div> </div>
<Space> <Tooltip title={t("collapseSidebar")} mouseEnterDelay={0.5}>
<Button <Button
type="primary" type="text"
icon={<CloudUpload size={16} />} icon={<PanelLeftClose size={16} />}
onClick={() => setDeployDialogOpen(true)} onClick={toggleSider}
disabled={!currentDomain} className={styles.siderCloseButton}
> size="small"
{t("deployFiles")} />
</Button> </Tooltip>
<Button icon={<History size={16} />} disabled={!currentDomain}> </div>
{t("versionHistory")} <div className={styles.siderContent}>
</Button> <div
<Tooltip title={t("settings")}> className={styles.domainSection}
<Button style={{ height: domainSectionHeight }}
icon={<SettingsIcon size={16} />} >
onClick={() => setSettingsOpen(true)} <DomainManager
/> collapsed={!domainExpanded}
</Tooltip> onToggleCollapse={() => setDomainExpanded(!domainExpanded)}
/>
</Space>
</Header>
<Content className={styles.content}>
<div className={styles.mainContent}>
<div className={styles.rightPanel}>
<AppDetail />
</div>
</div> </div>
</Content> <div
</Layout> className={styles.appSection}
style={{ height: `calc(100% - ${domainSectionHeight}px)` }}
>
<AppList />
</div>
</div>
{/* Resize handle */}
<div
className={styles.resizeHandle}
onMouseDown={handleResizeStart}
style={{
background: isResizing ? token.colorPrimary : undefined,
}}
/>
</>
)}
</Sider>
{/* Deploy Dialog */} {/* Main Content */}
<DeployDialog <Layout
open={deployDialogOpen} className={`${styles.mainLayout} ${siderCollapsed ? styles.mainLayoutCollapsed : ""}`}
onClose={() => setDeployDialogOpen(false)} style={{ marginLeft: siderCollapsed ? 0 : sidebarWidth }}
/> >
<Header className={styles.header}>
<div className={styles.headerLeft}>
{siderCollapsed && (
<Tooltip title={t("expandSidebar")} mouseEnterDelay={0.5}>
<Button
type="text"
icon={<PanelLeftOpen size={16} />}
onClick={toggleSider}
size="small"
/>
</Tooltip>
)}
<Title level={5} style={{ margin: 0 }}>
{currentDomain ? currentDomain.name : "Kintone Customize Manager"}
</Title>
</div>
<Space>
<Button icon={<History size={16} />} disabled={!currentDomain}>
{t("versionHistory")}
</Button>
<Tooltip title={t("settings")}>
<Button
icon={<SettingsIcon size={16} />}
onClick={() => setSettingsOpen(true)}
/>
</Tooltip>
</Space>
</Header>
{/* Settings Modal */} <Content className={styles.content}>
<Modal <div className={styles.mainContent}>
title={t("settings")} <div className={styles.rightPanel}>
open={settingsOpen} <AppDetail />
onCancel={() => setSettingsOpen(false)} </div>
footer={null} </div>
width={480} </Content>
mask={{ closable: false }} </Layout>
>
<Settings />
</Modal>
</Layout> {/* Settings Modal */}
<Modal
title={t("settings")}
open={settingsOpen}
onCancel={() => setSettingsOpen(false)}
footer={null}
width={480}
mask={{ closable: false }}
>
<Settings />
</Modal>
</Layout>
); );
}; };

View File

@@ -1,426 +0,0 @@
/**
* DeployDialog Component
* Dialog for confirming and executing deployment
*/
import React from "react";
import { useTranslation } from "react-i18next";
import {
Steps,
Space,
Alert,
Spin,
Result,
Table,
Tag,
Typography,
Divider,
} from "antd";
import { Button, Modal, Select } from "@lobehub/ui";
import {
CloudUpload,
CheckCircle,
XCircle,
Loader2,
} from "lucide-react";
import { createStyles } from "antd-style";
import { FileUploader } from "../FileUploader";
import { useDeployStore } from "@renderer/stores";
import { useDomainStore } from "@renderer/stores";
import { useAppStore } from "@renderer/stores";
import type { DeployFile } from "@shared/types/ipc";
const { Text } = Typography;
const useStyles = createStyles(({ token, css }) => ({
container: css`
min-height: 400px;
`,
stepContent: css`
margin-top: ${token.marginMD}px;
`,
positionSelector: css`
margin-bottom: ${token.marginMD}px;
`,
positionItem: css`
display: flex;
align-items: center;
justify-content: space-between;
padding: ${token.paddingSM}px ${token.paddingMD}px;
border: 1px solid ${token.colorBorderSecondary};
border-radius: ${token.borderRadiusLG}px;
margin-bottom: ${token.marginSM}px;
`,
summary: css`
padding: ${token.paddingMD}px;
background: ${token.colorBgLayout};
border-radius: ${token.borderRadiusLG}px;
`,
summaryItem: css`
display: flex;
justify-content: space-between;
padding: ${token.paddingXS}px 0;
`,
}));
interface DeployDialogProps {
open: boolean;
onClose: () => void;
onSuccess?: () => void;
}
const DeployDialog: React.FC<DeployDialogProps> = ({
open,
onClose,
onSuccess,
}) => {
const { t } = useTranslation("deploy");
const { styles } = useStyles();
const { currentDomain } = useDomainStore();
const { currentApp } = useAppStore();
const {
step,
files,
setStep,
setFiles,
setTargetAppId,
setDeploying,
setResult,
setError,
reset,
} = useDeployStore();
// Reset when dialog opens
React.useEffect(() => {
if (open) {
reset();
if (currentApp) {
setTargetAppId(currentApp.appId);
}
}
}, [open]);
const handleDeploy = async () => {
if (!currentDomain || !currentApp) return;
setStep("deploying");
setDeploying(true);
try {
const result = await window.api.deploy({
domainId: currentDomain.id,
appId: currentApp.appId,
files,
});
if (result.success) {
setResult(result);
setStep("success");
onSuccess?.();
} else {
setError(result.error || t("deployFailed"));
setStep("error");
}
} catch (error) {
setError(error instanceof Error ? error.message : t("deployFailed"));
setStep("error");
} finally {
setDeploying(false);
}
};
const handleClose = () => {
reset();
onClose();
};
const handleFilesChange = (newFiles: DeployFile[]) => {
setFiles(newFiles);
};
const handlePositionChange = (
index: number,
position: DeployFile["position"],
) => {
const newFiles = [...files];
newFiles[index] = { ...newFiles[index], position };
setFiles(newFiles);
};
const canProceedToConfigure = files.length > 0;
const canProceedToConfirm = files.every((f) => f.position);
// Position options for JS files
const jsPositionOptions = [
{ value: "pc_header", label: t("pcHeader") },
{ value: "pc_body", label: t("pcBody") },
{ value: "pc_footer", label: t("pcFooter") },
{ value: "mobile_header", label: t("mobileHeader") },
{ value: "mobile_body", label: t("mobileBody") },
{ value: "mobile_footer", label: t("mobileFooter") },
];
// Position options for CSS files
const cssPositionOptions = [
{ value: "pc_css", label: t("pc") },
{ value: "mobile_css", label: t("mobile") },
];
const renderStepContent = () => {
switch (step) {
case "select":
return (
<div className={styles.stepContent}>
<Alert
message={t("selectFiles")}
description={t("selectFilesDesc")}
type="info"
showIcon
style={{ marginBottom: 16 }}
/>
<FileUploader files={files} onChange={handleFilesChange} />
</div>
);
case "configure":
return (
<div className={styles.stepContent}>
<Alert
message={t("configurePosition")}
description={t("configurePositionDesc")}
type="info"
showIcon
style={{ marginBottom: 16 }}
/>
{files.map((file, index) => (
<div key={index} className={styles.positionItem}>
<Space>
<Tag color={file.fileType === "js" ? "gold" : "blue"}>
{file.fileType.toUpperCase()}
</Tag>
<Text>{file.fileName}</Text>
</Space>
<Select
value={file.position}
onChange={(value) => handlePositionChange(index, value)}
options={
file.fileType === "js"
? jsPositionOptions
: cssPositionOptions
}
style={{ width: 200 }}
/>
</div>
))}
</div>
);
case "confirm":
return (
<div className={styles.stepContent}>
<Alert
message={t("confirmDeployment")}
description={t("confirmDeploymentDesc")}
type="warning"
showIcon
style={{ marginBottom: 16 }}
/>
<div className={styles.summary}>
<div className={styles.summaryItem}>
<Text strong>{t("targetDomain")}</Text>
<Text>{currentDomain?.name}</Text>
</div>
<div className={styles.summaryItem}>
<Text strong>{t("targetApp")}</Text>
<Text>
{currentApp?.name} ({currentApp?.appId})
</Text>
</div>
<Divider style={{ margin: "12px 0" }} />
<Text strong>{t("deployFiles")}</Text>
<Table
size="small"
dataSource={files.map((f, i) => ({ ...f, key: i }))}
columns={[
{
title: t("fileName"),
dataIndex: "fileName",
key: "fileName",
},
{
title: t("type"),
dataIndex: "fileType",
key: "fileType",
render: (type) => (
<Tag color={type === "js" ? "gold" : "blue"}>
{type.toUpperCase()}
</Tag>
),
},
{
title: t("position"),
dataIndex: "position",
key: "position",
render: (pos) => {
const labels: Record<string, string> = {
pc_header: t("pcHeader"),
pc_body: t("pcBody"),
pc_footer: t("pcFooter"),
mobile_header: t("mobileHeader"),
mobile_body: t("mobileBody"),
mobile_footer: t("mobileFooter"),
pc_css: t("pc"),
mobile_css: t("mobile"),
};
return labels[pos] || pos;
},
},
]}
pagination={false}
/>
</div>
</div>
);
case "deploying":
return (
<div
className={styles.stepContent}
style={{ textAlign: "center", padding: 48 }}
>
<Spin
indicator={<Loader2 size={48} className="animate-spin" />}
/>
<div style={{ marginTop: 24 }}>
<Text>{t("deploying")}</Text>
</div>
</div>
);
case "success":
return (
<div className={styles.stepContent}>
<Result
status="success"
title={t("deploySuccess")}
subTitle={t("deploySuccessDesc")}
extra={[
<Button type="primary" key="close" onClick={handleClose}>
{t("done")}
</Button>,
]}
/>
</div>
);
case "error":
return (
<div className={styles.stepContent}>
<Result
status="error"
title={t("deployFailed")}
subTitle={t("deployFailedDesc")}
extra={[
<Button key="retry" onClick={() => setStep("confirm")}>
{t("retry")}
</Button>,
<Button key="close" onClick={handleClose}>
{t("close", { ns: "common" })}
</Button>,
]}
/>
</div>
);
default:
return null;
}
};
const currentStepIndex = [
"select",
"configure",
"confirm",
"deploying",
"success",
"error",
].indexOf(step);
return (
<Modal
title={
<Space>
<CloudUpload size={16} />
{t("title")}
</Space>
}
open={open}
onCancel={step === "deploying" ? undefined : handleClose}
width={640}
footer={
step === "deploying" ||
step === "success" ||
step === "error" ? null : (
<Space>
<Button onClick={handleClose}>
{t("cancel", { ns: "common" })}
</Button>
{step === "select" && (
<Button
type="primary"
disabled={!canProceedToConfigure}
onClick={() => setStep("configure")}
>
{t("next", { ns: "common" })}
</Button>
)}
{step === "configure" && (
<>
<Button onClick={() => setStep("select")}>
{t("back", { ns: "common" })}
</Button>
<Button
type="primary"
disabled={!canProceedToConfirm}
onClick={() => setStep("confirm")}
>
{t("next", { ns: "common" })}
</Button>
</>
)}
{step === "confirm" && (
<>
<Button onClick={() => setStep("configure")}>
{t("back", { ns: "common" })}
</Button>
<Button type="primary" onClick={handleDeploy}>
{t("confirmDeploy")}
</Button>
</>
)}
</Space>
)
}
destroyOnHidden
mask={{ closable: false }}
>
<div className={styles.container}>
{step !== "success" && step !== "error" && step !== "deploying" && (
<Steps
size="small"
current={currentStepIndex}
items={[
{ title: t("selectFile") },
{ title: t("configurePos") },
{ title: t("confirmDeployment") },
]}
/>
)}
{renderStepContent()}
</div>
</Modal>
);
};
export default DeployDialog;

View File

@@ -1,6 +0,0 @@
/**
* DeployDialog Components
* Export all deploy dialog components
*/
export { default as DeployDialog } from "./DeployDialog";

View File

@@ -8,7 +8,6 @@ import domainZHCN from "./locales/zh-CN/domain.json";
import settingsZHCN from "./locales/zh-CN/settings.json"; import settingsZHCN from "./locales/zh-CN/settings.json";
import errorsZHCN from "./locales/zh-CN/errors.json"; import errorsZHCN from "./locales/zh-CN/errors.json";
import appZHCN from "./locales/zh-CN/app.json"; import appZHCN from "./locales/zh-CN/app.json";
import deployZHCN from "./locales/zh-CN/deploy.json";
import fileZHCN from "./locales/zh-CN/file.json"; import fileZHCN from "./locales/zh-CN/file.json";
import versionZHCN from "./locales/zh-CN/version.json"; import versionZHCN from "./locales/zh-CN/version.json";
import commonJAJP from "./locales/ja-JP/common.json"; import commonJAJP from "./locales/ja-JP/common.json";
@@ -16,7 +15,6 @@ import domainJAJP from "./locales/ja-JP/domain.json";
import settingsJAJP from "./locales/ja-JP/settings.json"; import settingsJAJP from "./locales/ja-JP/settings.json";
import errorsJAJP from "./locales/ja-JP/errors.json"; import errorsJAJP from "./locales/ja-JP/errors.json";
import appJAJP from "./locales/ja-JP/app.json"; import appJAJP from "./locales/ja-JP/app.json";
import deployJAJP from "./locales/ja-JP/deploy.json";
import fileJAJP from "./locales/ja-JP/file.json"; import fileJAJP from "./locales/ja-JP/file.json";
import versionJAJP from "./locales/ja-JP/version.json"; import versionJAJP from "./locales/ja-JP/version.json";
import commonENUS from "./locales/en-US/common.json"; import commonENUS from "./locales/en-US/common.json";
@@ -24,7 +22,6 @@ import domainENUS from "./locales/en-US/domain.json";
import settingsENUS from "./locales/en-US/settings.json"; import settingsENUS from "./locales/en-US/settings.json";
import errorsENUS from "./locales/en-US/errors.json"; import errorsENUS from "./locales/en-US/errors.json";
import appENUS from "./locales/en-US/app.json"; import appENUS from "./locales/en-US/app.json";
import deployENUS from "./locales/en-US/deploy.json";
import fileENUS from "./locales/en-US/file.json"; import fileENUS from "./locales/en-US/file.json";
import versionENUS from "./locales/en-US/version.json"; import versionENUS from "./locales/en-US/version.json";
// Define resources with namespaces // Define resources with namespaces
@@ -35,7 +32,6 @@ const resources = {
settings: settingsZHCN, settings: settingsZHCN,
errors: errorsZHCN, errors: errorsZHCN,
app: appZHCN, app: appZHCN,
deploy: deployZHCN,
file: fileZHCN, file: fileZHCN,
version: versionZHCN, version: versionZHCN,
}, },
@@ -45,7 +41,6 @@ const resources = {
settings: settingsJAJP, settings: settingsJAJP,
errors: errorsJAJP, errors: errorsJAJP,
app: appJAJP, app: appJAJP,
deploy: deployJAJP,
file: fileJAJP, file: fileJAJP,
version: versionJAJP, version: versionJAJP,
}, },
@@ -55,7 +50,6 @@ const resources = {
settings: settingsENUS, settings: settingsENUS,
errors: errorsENUS, errors: errorsENUS,
app: appENUS, app: appENUS,
deploy: deployENUS,
file: fileENUS, file: fileENUS,
version: versionENUS, version: versionENUS,
}, },
@@ -68,7 +62,7 @@ i18next
.init({ .init({
resources, resources,
fallbackLng: "ja-JP", fallbackLng: "ja-JP",
ns: ["common", "domain", "settings", "errors", "app", "deploy", "file", "version"], ns: ["common", "domain", "settings", "errors", "app", "file", "version"],
interpolation: { interpolation: {
escapeValue: false, // React already handles escaping escapeValue: false, // React already handles escaping
}, },
@@ -79,4 +73,4 @@ i18next
}, },
}); });
export default i18next; export default i18next;

View File

@@ -30,7 +30,6 @@
"paste": "Paste", "paste": "Paste",
"cut": "Cut", "cut": "Cut",
"selectAll": "Select all", "selectAll": "Select all",
"deployFiles": "Deploy Files",
"versionHistory": "Version History", "versionHistory": "Version History",
"settings": "Settings", "settings": "Settings",
"downloadSuccess": "Download successful", "downloadSuccess": "Download successful",

View File

@@ -1,33 +0,0 @@
{
"title": "Deploy Files",
"selectFiles": "Select files to deploy",
"selectFilesDesc": "Drag and drop or select JavaScript or CSS files to deploy",
"configurePosition": "Configure deployment position",
"configurePositionDesc": "Select deployment position for each file",
"confirmDeployment": "Confirm deployment",
"confirmDeploymentDesc": "Please confirm the following deployment information",
"targetDomain": "Target Domain",
"targetApp": "Target App",
"deployFiles": "Files to deploy:",
"fileName": "File Name",
"type": "Type",
"position": "Position",
"deploying": "Deploying to Kintone...",
"deploySuccess": "Deployment Successful",
"deploySuccessDesc": "Files have been successfully deployed to Kintone",
"deployFailed": "Deployment Failed",
"deployFailedDesc": "An error occurred during deployment",
"done": "Done",
"retry": "Retry",
"confirmDeploy": "Confirm Deploy",
"selectFile": "Select Files",
"configurePos": "Configure Position",
"pcHeader": "PC - Header",
"pcBody": "PC - Body",
"pcFooter": "PC - Footer",
"mobileHeader": "Mobile - Header",
"mobileBody": "Mobile - Body",
"mobileFooter": "Mobile - Footer",
"pc": "PC",
"mobile": "Mobile"
}

View File

@@ -30,7 +30,6 @@
"paste": "貼り付け", "paste": "貼り付け",
"cut": "切り取り", "cut": "切り取り",
"selectAll": "すべて選択", "selectAll": "すべて選択",
"deployFiles": "ファイルをデプロイ",
"versionHistory": "バージョン履歴", "versionHistory": "バージョン履歴",
"settings": "設定", "settings": "設定",
"downloadSuccess": "ダウンロード成功", "downloadSuccess": "ダウンロード成功",

View File

@@ -1,33 +0,0 @@
{
"title": "ファイルをデプロイ",
"selectFiles": "デプロイするファイルを選択",
"selectFilesDesc": "デプロイするJavaScriptまたはCSSファイルをドラッグドロップまたは選択してください",
"configurePosition": "デプロイ位置を設定",
"configurePositionDesc": "各ファイルのデプロイ位置を選択してください",
"confirmDeployment": "デプロイ確認",
"confirmDeploymentDesc": "以下のデプロイ情報を確認してください",
"targetDomain": "ターゲットドメイン",
"targetApp": "ターゲットアプリ",
"deployFiles": "デプロイファイル:",
"fileName": "ファイル名",
"type": "タイプ",
"position": "位置",
"deploying": "Kintoneにデプロイ中...",
"deploySuccess": "デプロイ成功",
"deploySuccessDesc": "ファイルがKintoneに正常にデプロイされました",
"deployFailed": "デプロイ失敗",
"deployFailedDesc": "デプロイ中にエラーが発生しました",
"done": "完了",
"retry": "再試行",
"confirmDeploy": "デプロイ確認",
"selectFile": "ファイル選択",
"configurePos": "位置設定",
"pcHeader": "PC - ヘッダー",
"pcBody": "PC - ボディ",
"pcFooter": "PC - フッター",
"mobileHeader": "モバイル - ヘッダー",
"mobileBody": "モバイル - ボディ",
"mobileFooter": "モバイル - フッター",
"pc": "PC",
"mobile": "モバイル"
}

View File

@@ -30,7 +30,6 @@
"paste": "粘贴", "paste": "粘贴",
"cut": "剪切", "cut": "剪切",
"selectAll": "全选", "selectAll": "全选",
"deployFiles": "部署文件",
"versionHistory": "版本历史", "versionHistory": "版本历史",
"settings": "设置", "settings": "设置",
"downloadSuccess": "下载成功", "downloadSuccess": "下载成功",

View File

@@ -1,33 +0,0 @@
{
"title": "部署文件",
"selectFiles": "选择要部署的文件",
"selectFilesDesc": "请拖拽或选择要部署的 JavaScript 或 CSS 文件",
"configurePosition": "配置部署位置",
"configurePositionDesc": "为每个文件选择部署位置",
"confirmDeployment": "确认部署",
"confirmDeploymentDesc": "请确认以下部署信息",
"targetDomain": "目标Domain",
"targetApp": "目标应用",
"deployFiles": "部署文件:",
"fileName": "文件名",
"type": "类型",
"position": "部署位置",
"deploying": "正在部署到 Kintone...",
"deploySuccess": "部署成功",
"deploySuccessDesc": "文件已成功部署到 Kintone",
"deployFailed": "部署失败",
"deployFailedDesc": "部署过程中发生错误",
"done": "完成",
"retry": "重试",
"confirmDeploy": "确认部署",
"selectFile": "选择文件",
"configurePos": "配置位置",
"pcHeader": "PC端 - Header",
"pcBody": "PC端 - Body",
"pcFooter": "PC端 - Footer",
"mobileHeader": "移动端 - Header",
"mobileBody": "移动端 - Body",
"mobileFooter": "移动端 - Footer",
"pc": "PC端",
"mobile": "移动端"
}

View File

@@ -1,85 +0,0 @@
/**
* Deploy Store
* Manages deployment state and parameters
*/
import { create } from "zustand";
import type { DeployFile, DeployResult } from "@shared/types/ipc";
export type DeployStep =
| "select"
| "configure"
| "confirm"
| "deploying"
| "success"
| "error";
interface DeployState {
// State
step: DeployStep;
files: DeployFile[];
targetAppId: string | null;
deploying: boolean;
result: DeployResult | null;
error: string | null;
// Actions
setStep: (step: DeployStep) => void;
setFiles: (files: DeployFile[]) => void;
addFile: (file: DeployFile) => void;
removeFile: (index: number) => void;
updateFile: (index: number, file: Partial<DeployFile>) => void;
setTargetAppId: (appId: string | null) => void;
setDeploying: (deploying: boolean) => void;
setResult: (result: DeployResult | null) => void;
setError: (error: string | null) => void;
clear: () => void;
reset: () => void;
}
const initialState = {
step: "select" as DeployStep,
files: [],
targetAppId: null,
deploying: false,
result: null,
error: null,
};
export const useDeployStore = create<DeployState>()((set) => ({
...initialState,
// Actions
setStep: (step) => set({ step }),
setFiles: (files) => set({ files }),
addFile: (file) =>
set((state) => ({
files: [...state.files, file],
})),
removeFile: (index) =>
set((state) => ({
files: state.files.filter((_, i) => i !== index),
})),
updateFile: (index, updates) =>
set((state) => ({
files: state.files.map((file, i) =>
i === index ? { ...file, ...updates } : file,
),
})),
setTargetAppId: (appId) => set({ targetAppId: appId }),
setDeploying: (deploying) => set({ deploying }),
setResult: (result) => set({ result }),
setError: (error) => set({ error }),
clear: () => set(initialState),
reset: () => set(initialState),
}));

View File

@@ -5,7 +5,6 @@
export { useDomainStore } from "./domainStore"; export { useDomainStore } from "./domainStore";
export { useAppStore } from "./appStore"; export { useAppStore } from "./appStore";
export { useDeployStore } from "./deployStore";
export { useVersionStore } from "./versionStore"; export { useVersionStore } from "./versionStore";
export { useUIStore } from "./uiStore"; export { useUIStore } from "./uiStore";
export { useSessionStore } from "./sessionStore"; export { useSessionStore } from "./sessionStore";
@@ -13,4 +12,4 @@ export type { ViewMode, SelectedFile } from "./sessionStore";
export { useThemeStore } from "./themeStore"; export { useThemeStore } from "./themeStore";
export type { ThemeMode } from "./themeStore"; export type { ThemeMode } from "./themeStore";
export { useFileChangeStore } from "./fileChangeStore"; export { useFileChangeStore } from "./fileChangeStore";
export type { FileEntry, FileStatus } from "./fileChangeStore"; export type { FileEntry, FileStatus } from "./fileChangeStore";