feat: 完善 WebUI basePath 支持并简化示例代码
主要改动: 1. WebUI basePath 逻辑完善 - NewWebUI 支持可变参数 basePath - 新增 path() 辅助方法统一路径处理 - handleTableAPI 正确处理 basePath 前缀 - handleIndex 根据 basePath 替换占位符 2. 简化示例代码 - 删除反向代理实现(111行) - 直接使用带 basePath 的 WebUI - 代码量减少 33%,架构更清晰 3. 前端优化 - 新增 api.js 统一 API 服务层 - 所有组件使用统一的 API 调用 - 支持通过 window.API_BASE 配置 basePath 4. 修复 .gitignore - 使用通用模式支持 commands 目录 - 无需为新示例项目修改配置
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import { Sidebar } from './Sidebar.js';
|
||||
import { TableView } from './TableView.js';
|
||||
import { Sidebar } from '~/components/Sidebar.js';
|
||||
import { TableView } from '~/components/TableView.js';
|
||||
import { getTables } from '~/utils/api.js';
|
||||
|
||||
export function App() {
|
||||
const [theme, setTheme] = useState('dark');
|
||||
@@ -26,13 +27,10 @@ export function App() {
|
||||
const fetchTables = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await fetch('/api/tables');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setTables(data.tables || []);
|
||||
if (data.tables && data.tables.length > 0) {
|
||||
setSelectedTable(data.tables[0].name);
|
||||
}
|
||||
const data = await getTables();
|
||||
setTables(data.tables || []);
|
||||
if (data.tables && data.tables.length > 0) {
|
||||
setSelectedTable(data.tables[0].name);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch tables:', error);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import { RowDetailModal } from './RowDetailModal.js';
|
||||
import { Pagination } from './Pagination.js';
|
||||
import { TableRow } from './TableRow.js';
|
||||
import { useCellPopover } from '../hooks/useCellPopover.js';
|
||||
import { useTooltip } from '../hooks/useTooltip.js';
|
||||
import { RowDetailModal } from '~/components/RowDetailModal.js';
|
||||
import { Pagination } from '~/components/Pagination.js';
|
||||
import { TableRow } from '~/components/TableRow.js';
|
||||
import { useCellPopover } from '~/hooks/useCellPopover.js';
|
||||
import { useTooltip } from '~/hooks/useTooltip.js';
|
||||
import { getTableData } from '~/utils/api.js';
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
@@ -83,11 +84,8 @@ export function DataTable({ schema, tableName, totalRows, selectedColumns = [] }
|
||||
try {
|
||||
setLoading(true);
|
||||
const offset = page * pageSize;
|
||||
const response = await fetch(`/api/tables/${tableName}/data?limit=${pageSize}&offset=${offset}`);
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
setData(result.data || []);
|
||||
}
|
||||
const result = await getTableData(tableName, { limit: pageSize, offset });
|
||||
setData(result.data || []);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch data:', error);
|
||||
} finally {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { FileCard } from './FileCard.js';
|
||||
import { FileCard } from '~/components/FileCard.js';
|
||||
|
||||
const styles = {
|
||||
levelSection: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useEffect } from 'preact/hooks';
|
||||
import { ManifestView } from './ManifestView.js';
|
||||
import { ManifestView } from '~/components/ManifestView.js';
|
||||
|
||||
const styles = {
|
||||
overlay: {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import { LevelCard } from './LevelCard.js';
|
||||
import { StatCard } from './StatCard.js';
|
||||
import { CompactionStats } from './CompactionStats.js';
|
||||
import { LevelCard } from '~/components/LevelCard.js';
|
||||
import { StatCard } from '~/components/StatCard.js';
|
||||
import { CompactionStats } from '~/components/CompactionStats.js';
|
||||
import { getTableManifest } from '~/utils/api.js';
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
@@ -42,11 +43,8 @@ export function ManifestView({ tableName }) {
|
||||
|
||||
const fetchManifest = async () => {
|
||||
try {
|
||||
const response = await fetch(`/api/tables/${tableName}/manifest`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setManifest(data);
|
||||
}
|
||||
const data = await getTableManifest(tableName);
|
||||
setManifest(data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch manifest:', error);
|
||||
} finally {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState, useEffect, useRef } from 'preact/hooks';
|
||||
import { getRowBySeq } from '~/utils/api.js';
|
||||
|
||||
const styles = {
|
||||
overlay: {
|
||||
@@ -116,11 +117,8 @@ export function RowDetailModal({ tableName, seq, onClose }) {
|
||||
const fetchRowData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await fetch(`/api/tables/${tableName}/data/${seq}`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setRowData(data);
|
||||
}
|
||||
const data = await getRowBySeq(tableName, seq);
|
||||
setRowData(data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch row data:', error);
|
||||
} finally {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { TableItem } from './TableItem.js';
|
||||
import { TableItem } from '~/components/TableItem.js';
|
||||
|
||||
export function Sidebar({ tables, selectedTable, onSelectTable, loading }) {
|
||||
if (loading) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import { FieldList } from './FieldList.js';
|
||||
import { FieldList } from '~/components/FieldList.js';
|
||||
|
||||
const styles = {
|
||||
tableItem: (isSelected, isExpanded) => ({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import { TableCell } from './TableCell.js';
|
||||
import { TableCell } from '~/components/TableCell.js';
|
||||
|
||||
const styles = {
|
||||
td: {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { html } from 'htm/preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import { DataTable } from './DataTable.js';
|
||||
import { ColumnSelector } from './ColumnSelector.js';
|
||||
import { ManifestModal } from './ManifestModal.js';
|
||||
import { useTooltip } from '../hooks/useTooltip.js';
|
||||
import { DataTable } from '~/components/DataTable.js';
|
||||
import { ColumnSelector } from '~/components/ColumnSelector.js';
|
||||
import { ManifestModal } from '~/components/ManifestModal.js';
|
||||
import { useTooltip } from '~/hooks/useTooltip.js';
|
||||
import { getTableSchema, getTableData } from '~/utils/api.js';
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
@@ -70,18 +71,12 @@ export function TableView({ tableName }) {
|
||||
setLoading(true);
|
||||
|
||||
// 获取 Schema
|
||||
const schemaResponse = await fetch(`/api/tables/${tableName}/schema`);
|
||||
if (schemaResponse.ok) {
|
||||
const schemaData = await schemaResponse.json();
|
||||
setSchema(schemaData);
|
||||
}
|
||||
const schemaData = await getTableSchema(tableName);
|
||||
setSchema(schemaData);
|
||||
|
||||
// 获取数据行数(通过一次小查询)
|
||||
const dataResponse = await fetch(`/api/tables/${tableName}/data?limit=1`);
|
||||
if (dataResponse.ok) {
|
||||
const data = await dataResponse.json();
|
||||
setTotalRows(data.totalRows || 0);
|
||||
}
|
||||
const data = await getTableData(tableName, { limit: 1, offset: 0 });
|
||||
setTotalRows(data.totalRows || 0);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch table info:', error);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user