mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-17 16:00:59 +00:00
yaml
This commit is contained in:
Generated
+2135
-155
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.2.7",
|
"@radix-ui/react-tooltip": "^1.2.7",
|
||||||
"@tailwindcss/postcss": "^4.1.5",
|
"@tailwindcss/postcss": "^4.1.5",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
"@xyflow/react": "^12.10.2",
|
"@xyflow/react": "^12.10.2",
|
||||||
"axios": "^1.15.0",
|
"axios": "^1.15.0",
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
"i18next": "^25.1.2",
|
"i18next": "^25.1.2",
|
||||||
"i18next-browser-languagedetector": "^8.1.0",
|
"i18next-browser-languagedetector": "^8.1.0",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
|
"js-yaml": "^4.1.1",
|
||||||
"lodash": "^4.18.0",
|
"lodash": "^4.18.0",
|
||||||
"lucide-react": "^0.507.0",
|
"lucide-react": "^0.507.0",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import { Workflow } from '@/app/infra/entities/api';
|
|||||||
import { useWorkflowStore } from './store/useWorkflowStore';
|
import { useWorkflowStore } from './store/useWorkflowStore';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import EmojiPicker from '@/components/ui/emoji-picker';
|
import EmojiPicker from '@/components/ui/emoji-picker';
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
|
||||||
export default function WorkflowDetailContent({ id }: { id: string }) {
|
export default function WorkflowDetailContent({ id }: { id: string }) {
|
||||||
const isCreateMode = id === 'new';
|
const isCreateMode = id === 'new';
|
||||||
@@ -174,7 +175,7 @@ export default function WorkflowDetailContent({ id }: { id: string }) {
|
|||||||
basicInfo,
|
basicInfo,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Export workflow handler
|
// Export workflow handler - exports as YAML
|
||||||
const handleExport = useCallback(() => {
|
const handleExport = useCallback(() => {
|
||||||
const { nodes, edges } = toWorkflowDefinition();
|
const { nodes, edges } = toWorkflowDefinition();
|
||||||
|
|
||||||
@@ -190,13 +191,12 @@ export default function WorkflowDetailContent({ id }: { id: string }) {
|
|||||||
exportedAt: new Date().toISOString(),
|
exportedAt: new Date().toISOString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const blob = new Blob([JSON.stringify(exportData, null, 2)], {
|
const yamlStr = yaml.dump(exportData, { indent: 2, lineWidth: -1 });
|
||||||
type: 'application/json',
|
const blob = new Blob([yamlStr], { type: 'text/yaml' });
|
||||||
});
|
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
a.download = `${workflow?.name || 'workflow'}.json`;
|
a.download = `${workflow?.name || 'workflow'}.yaml`;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
@@ -205,13 +205,21 @@ export default function WorkflowDetailContent({ id }: { id: string }) {
|
|||||||
toast.success(t('workflows.exportSuccess'));
|
toast.success(t('workflows.exportSuccess'));
|
||||||
}, [workflow, toWorkflowDefinition, t]);
|
}, [workflow, toWorkflowDefinition, t]);
|
||||||
|
|
||||||
// Import workflow handler
|
// Import workflow handler - supports both JSON and YAML
|
||||||
const handleImport = useCallback(
|
const handleImport = useCallback(
|
||||||
(file: File) => {
|
(file: File) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
try {
|
try {
|
||||||
const importData = JSON.parse(e.target?.result as string);
|
const content = e.target?.result as string;
|
||||||
|
let importData: any;
|
||||||
|
|
||||||
|
// Try YAML first, then JSON
|
||||||
|
try {
|
||||||
|
importData = yaml.load(content);
|
||||||
|
} catch {
|
||||||
|
importData = JSON.parse(content);
|
||||||
|
}
|
||||||
|
|
||||||
// Validate imported data structure
|
// Validate imported data structure
|
||||||
if (!importData.nodes || !Array.isArray(importData.nodes)) {
|
if (!importData.nodes || !Array.isArray(importData.nodes)) {
|
||||||
@@ -339,7 +347,7 @@ export default function WorkflowDetailContent({ id }: { id: string }) {
|
|||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
accept=".json"
|
accept=".yaml,.yml,.json"
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
@@ -419,7 +427,7 @@ export default function WorkflowDetailContent({ id }: { id: string }) {
|
|||||||
{/* Hidden file input for import */}
|
{/* Hidden file input for import */}
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
accept=".json"
|
accept=".yaml,.yml,.json"
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
|
|||||||
Reference in New Issue
Block a user