@isthatuzii/create-nano-app
Version:
Desktop application scaffolding tool for the Nano Framework
136 lines (122 loc) • 3.72 kB
JSX
import { createSignal, onMount, For } from "solid-js";
import {
ChevronRight,
ChevronDown,
Folder,
FolderOpen,
File,
FileText,
Package,
Database,
Search,
Filter
} from "lucide-solid";
import "./DataBrowser.css";
import { createDataBrowserFunctions } from "./DataBrowser.functions.js";
function DataBrowser(props) {
const [state, setState] = createSignal({
expandedItems: new Set(['datacore', 'entities']),
selectedItem: 'drak_caterpillar',
searchTerm: '',
filterType: 'all'
});
const functions = createDataBrowserFunctions(
state,
setState,
props
);
onMount(() => {
functions.initialize();
});
const TreeItem = ({ item, depth = 0 }) => {
const isExpanded = () => state().expandedItems.has(item.id);
const isSelected = () => state().selectedItem === item.id;
const hasChildren = () => item.children && item.children.length > 0;
const getIcon = () => {
if (hasChildren()) {
return isExpanded() ? FolderOpen : Folder;
}
switch (item.type) {
case 'EntityClassDefinition':
return Package;
case 'file':
return FileText;
case 'database':
return Database;
default:
return File;
}
};
const IconComponent = getIcon();
return (
<div class="tree-item-container">
<div
class="tree-item"
classList={{
selected: isSelected(),
expanded: isExpanded()
}}
style={{ 'padding-left': `${depth * 12 + 8}px` }}
onClick={() => functions.handleItemClick(item)}
>
<div class="tree-item-content">
{hasChildren() && (
<div
class="expand-toggle"
onClick={(e) => {
e.stopPropagation();
functions.toggleExpand(item.id);
}}
>
{isExpanded() ?
<ChevronDown class="icon size-sm" /> :
<ChevronRight class="icon size-sm" />
}
</div>
)}
<IconComponent class="icon size-sm item-icon" />
<span class="item-name">{item.name}</span>
{item.type && (
<span class="item-type">{item.type}</span>
)}
</div>
</div>
{hasChildren() && isExpanded() && (
<div class="tree-children">
<For each={item.children}>
{(child) => <TreeItem item={child} depth={depth + 1} />}
</For>
</div>
)}
</div>
);
};
return (
<div class="data-browser">
<div class="browser-header">
<div class="header-title">Datacore Browser</div>
<div class="header-controls">
<div class="search-box">
<Search class="icon size-sm search-icon" />
<input
type="text"
placeholder="Search..."
value={state().searchTerm}
onInput={(e) => functions.handleSearch(e.target.value)}
class="search-input"
/>
</div>
<button class="filter-button" title="Filter">
<Filter class="icon size-sm" />
</button>
</div>
</div>
<div class="browser-content">
<For each={functions.getFilteredData()}>
{(item) => <TreeItem item={item} />}
</For>
</div>
</div>
);
}
export default DataBrowser;