UNPKG

testeranto

Version:

the AI powered BDD test framework for typescript projects

320 lines (319 loc) 16 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.DratoPage = void 0; /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ const react_1 = __importStar(require("react")); const GenericXMLEditorPage_1 = require("./GenericXMLEditorPage"); const DratoPage = () => { const initialTree = { id: "root", type: "Container", attributes: { fluid: "true" }, children: [], }; const [bootstrapTree, setBootstrapTree] = (0, react_1.useState)(initialTree); const [selectedNodeId, setSelectedNodeId] = (0, react_1.useState)(null); const [activeTab, setActiveTab] = (0, react_1.useState)("preview"); const [history, setHistory] = (0, react_1.useState)([initialTree]); const [historyIndex, setHistoryIndex] = (0, react_1.useState)(0); const [hiddenNodes, setHiddenNodes] = (0, react_1.useState)(new Set()); // Find a node by ID const findNode = (0, react_1.useCallback)((node, id) => { if (node.id === id) return node; for (const child of node.children) { const found = findNode(child, id); if (found) return found; } return null; }, []); // Helper to update tree and manage history const updateTree = (0, react_1.useCallback)((newTree) => { setBootstrapTree(newTree); setHistory((prevHistory) => { const newHistory = prevHistory.slice(0, historyIndex + 1); newHistory.push(newTree); return newHistory; }); setHistoryIndex((prevIndex) => prevIndex + 1); }, [historyIndex]); // Update node attributes const updateNodeAttributes = (0, react_1.useCallback)((nodeId, attributes) => { setBootstrapTree((prevTree) => { const newTree = JSON.parse(JSON.stringify(prevTree)); const node = findNode(newTree, nodeId); if (node) { node.attributes = Object.assign(Object.assign({}, node.attributes), attributes); } updateTree(newTree); return newTree; }); }, [findNode, updateTree]); // Update node text content const updateNodeTextContent = (0, react_1.useCallback)((nodeId, textContent) => { setBootstrapTree((prevTree) => { const newTree = JSON.parse(JSON.stringify(prevTree)); const node = findNode(newTree, nodeId); if (node) { node.textContent = textContent; } updateTree(newTree); return newTree; }); }, [findNode, updateTree]); // Toggle node visibility const toggleNodeVisibility = (0, react_1.useCallback)((nodeId) => { setHiddenNodes((prev) => { const newHidden = new Set(prev); if (newHidden.has(nodeId)) { newHidden.delete(nodeId); } else { newHidden.add(nodeId); } return newHidden; }); }, []); // Add a new child node const addChildNode = (0, react_1.useCallback)((parentId, nodeType) => { setBootstrapTree((prevTree) => { const newTree = JSON.parse(JSON.stringify(prevTree)); const parent = findNode(newTree, parentId); if (parent) { // Default attributes based on node type let defaultAttributes = {}; switch (nodeType) { case "Container": defaultAttributes = { fluid: "true" }; break; case "Row": defaultAttributes = {}; break; case "Col": defaultAttributes = { xs: "12" }; break; case "Button": defaultAttributes = { variant: "primary" }; break; case "Card": defaultAttributes = {}; break; default: defaultAttributes = {}; } const newNode = { id: `${nodeType}-${Date.now()}`, type: nodeType, attributes: defaultAttributes, children: [], }; parent.children = [...parent.children, newNode]; setSelectedNodeId(newNode.id); updateTree(newTree); } return newTree; }); }, [findNode, updateTree]); // Remove a node const removeNode = (0, react_1.useCallback)((nodeId) => { setBootstrapTree((prevTree) => { const newTree = JSON.parse(JSON.stringify(prevTree)); const removeFromParent = (node, targetId) => { for (let i = 0; i < node.children.length; i++) { if (node.children[i].id === targetId) { node.children.splice(i, 1); return true; } if (removeFromParent(node.children[i], targetId)) { return true; } } return false; }; removeFromParent(newTree, nodeId); if (selectedNodeId === nodeId) { setSelectedNodeId(null); } updateTree(newTree); return newTree; }); }, [selectedNodeId, updateTree]); // Undo/Redo handlers const handleUndo = (0, react_1.useCallback)(() => { if (historyIndex > 0) { setHistoryIndex((prevIndex) => prevIndex - 1); setBootstrapTree(history[historyIndex - 1]); } }, [history, historyIndex]); const handleRedo = (0, react_1.useCallback)(() => { if (historyIndex < history.length - 1) { setHistoryIndex((prevIndex) => prevIndex + 1); setBootstrapTree(history[historyIndex + 1]); } }, [history, historyIndex]); const selectedNode = selectedNodeId ? findNode(bootstrapTree, selectedNodeId) : null; // Define node types for Bootstrap const bootstrapNodeTypes = [ { label: 'Container', type: 'Container' }, { label: 'Row', type: 'Row' }, { label: 'Column', type: 'Col' }, { label: 'Button', type: 'Button' }, { label: 'Card', type: 'Card' }, { label: 'Text', type: 'Text' } ]; // Function to create new Bootstrap nodes const createBootstrapNode = (parentId, nodeType) => { // Default attributes based on node type let defaultAttributes = {}; switch (nodeType) { case "Container": defaultAttributes = { fluid: "true" }; break; case "Row": defaultAttributes = {}; break; case "Col": defaultAttributes = { xs: "12" }; break; case "Button": defaultAttributes = { variant: "primary" }; break; case "Card": defaultAttributes = {}; break; case "Text": defaultAttributes = { class: "" }; break; default: defaultAttributes = {}; } return { id: `${nodeType}-${Date.now()}`, type: nodeType, attributes: defaultAttributes, children: [], }; }; // Render preview for Bootstrap const renderBootstrapPreview = (node, isSelected, eventHandlers) => { // Render Bootstrap components based on node type const { type, attributes, children, textContent } = node; const style = isSelected ? { outline: '2px dashed blue' } : {}; // Convert children to React elements const childElements = children.map(child => renderBootstrapPreview(child, selectedNodeId === child.id, {})); // Handle different Bootstrap component types switch (type) { case 'Container': return (react_1.default.createElement("div", Object.assign({ key: node.id, className: `container${attributes.fluid === 'true' ? '-fluid' : ''}`, style: style }, eventHandlers), childElements, textContent)); case 'Row': return (react_1.default.createElement("div", Object.assign({ key: node.id, className: "row", style: style }, eventHandlers), childElements, textContent)); case 'Col': // Generate column classes based on attributes const colClasses = Object.entries(attributes) .filter(([key]) => ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key)) .map(([breakpoint, size]) => `col-${breakpoint}-${size}`) .join(' '); return (react_1.default.createElement("div", Object.assign({ key: node.id, className: colClasses || 'col', style: style }, eventHandlers), childElements, textContent)); case 'Button': return (react_1.default.createElement("button", Object.assign({ key: node.id, className: `btn btn-${attributes.variant || 'primary'}`, style: style }, eventHandlers), textContent || 'Button')); case 'Card': return (react_1.default.createElement("div", Object.assign({ key: node.id, className: "card", style: style }, eventHandlers), react_1.default.createElement("div", { className: "card-body" }, childElements, textContent))); case 'Text': return (react_1.default.createElement("div", Object.assign({ key: node.id, className: attributes.class || '', style: style }, eventHandlers), textContent, childElements)); default: return (react_1.default.createElement("div", Object.assign({ key: node.id, style: style }, eventHandlers), type, " element", childElements, textContent)); } }; // Attribute editor for Bootstrap const renderBootstrapAttributeEditor = (node, onUpdateAttributes, onUpdateTextContent) => { const handleAttributeChange = (key, value) => { const newAttributes = Object.assign(Object.assign({}, node.attributes), { [key]: value }); onUpdateAttributes(newAttributes); }; const handleTextChange = (e) => { onUpdateTextContent(e.target.value); }; // Render different attribute editors based on node type return (react_1.default.createElement("div", null, (node.type === 'Button' || node.type === 'Card' || node.type === 'Text') && (react_1.default.createElement("div", { className: "mb-3" }, react_1.default.createElement("label", { className: "form-label" }, "Text Content"), react_1.default.createElement("input", { type: "text", className: "form-control", value: node.textContent || '', onChange: handleTextChange }))), node.type === 'Container' && (react_1.default.createElement("div", { className: "mb-3" }, react_1.default.createElement("label", { className: "form-label" }, "Fluid"), react_1.default.createElement("select", { className: "form-select", value: node.attributes.fluid || 'false', onChange: (e) => handleAttributeChange('fluid', e.target.value) }, react_1.default.createElement("option", { value: "true" }, "True"), react_1.default.createElement("option", { value: "false" }, "False")))), node.type === 'Col' && (react_1.default.createElement("div", null, ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].map(breakpoint => (react_1.default.createElement("div", { key: breakpoint, className: "mb-2" }, react_1.default.createElement("label", { className: "form-label" }, breakpoint.toUpperCase()), react_1.default.createElement("input", { type: "text", className: "form-control", value: node.attributes[breakpoint] || '', onChange: (e) => handleAttributeChange(breakpoint, e.target.value), placeholder: "1-12" })))))), node.type === 'Button' && (react_1.default.createElement("div", { className: "mb-3" }, react_1.default.createElement("label", { className: "form-label" }, "Variant"), react_1.default.createElement("select", { className: "form-select", value: node.attributes.variant || 'primary', onChange: (e) => handleAttributeChange('variant', e.target.value) }, ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'].map(variant => (react_1.default.createElement("option", { key: variant, value: variant }, variant)))))), node.type === 'Text' && (react_1.default.createElement("div", { className: "mb-3" }, react_1.default.createElement("label", { className: "form-label" }, "CSS Classes"), react_1.default.createElement("input", { type: "text", className: "form-control", value: node.attributes.class || '', onChange: (e) => handleAttributeChange('class', e.target.value), placeholder: "e.g., text-primary fs-4" }))), react_1.default.createElement("div", { className: "mb-3" }, react_1.default.createElement("label", { className: "form-label" }, "Other Attributes"), Object.entries(node.attributes) .filter(([key]) => !['fluid', 'variant'].includes(key) && !['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key)) .map(([key, value]) => (react_1.default.createElement("div", { key: key, className: "input-group mb-2" }, react_1.default.createElement("span", { className: "input-group-text" }, key), react_1.default.createElement("input", { type: "text", className: "form-control", value: value, onChange: (e) => handleAttributeChange(key, e.target.value) }))))))); }; return (react_1.default.createElement(GenericXMLEditorPage_1.GenericXMLEditorPage, { initialTree: initialTree, renderPreview: renderBootstrapPreview, attributeEditor: renderBootstrapAttributeEditor, nodeTypes: bootstrapNodeTypes, onAddNode: createBootstrapNode })); }; exports.DratoPage = DratoPage;