DSH 0.1.5 owns the right column (its native Sidebar hosts every tab type this plugin registers), so the plugin's own right panel, its width drag / new-session seed prefs, and the free-window feature are gone. The bottom workbench is the only plugin-owned surface left, and its expand/collapse control is registered into DSH's session-header utilities list slot (the header's corner seat belongs to the native sidebar's own control). - state: one `bottomSplits` tree; `makeDefaultState()` takes no arguments; `toggleBottomPanel` / `openTabInBottomPane` are the only landing reducers; `setBottomHeight` and `sanitizeState` share the `CONVERSATION_MIN` cap (a persisted tall height no longer snaps on the first drag). - service: every landing in the workbench (creation or focus) expands it; `SIDEBAR_FEATURES` drops `'floatWindows'`; the open/close/activate tab pools cover the single tree. - shell: `Sidebar.tsx` renders only the bottom workbench; the toggle lives in `sidebar/bottom-toggle.tsx`; layout-push pushes height only (no width, no `--dsh-sidebar-width`). - prefs: `openByDefault` / `defaultWidthPercent` / `changesDiffFloat` removed from the schema, defaults, client parser, settings page, and all 20 dictionaries; the retired keys in stored documents are ignored. - tests: free-window specs deleted, panel/float assertions dropped, remaining suites adapted (124 files / 1287 tests); the mount lane asserts the header toggle and sweeps the native sidebar's guide page. - docs: README / README_EN / guide §0,§11 / AGENTS test map.
50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
/**
|
|
* The generic render error boundary for the sidebar tree: a render error in
|
|
* the wrapped subtree shows a dismissible error strip (retry re-renders the
|
|
* children) instead of blanking the shell. Used at two scopes:
|
|
*
|
|
* - ROOT (index.tsx, `css.boundaryError`): last-resort containment for
|
|
* errors in the sidebar shell itself (Workbench, drag layout, …) — a full
|
|
* swap keeps the page alive.
|
|
* - PER-TAB (Sidebar.tsx TabContent, `css.tabBoundaryError`): a crashing
|
|
* viewer/editor shows a strip inside ITS OWN pane; the workbench shell, the
|
|
* other tabs, and the panel itself stay alive (issue #31 — a tab crash
|
|
* must never take down the whole sidebar).
|
|
*
|
|
* The className prop selects the strip's geometry: the root's full-height
|
|
* fixed rail vs. the tab's pane-filling block.
|
|
*/
|
|
import { Component, type ErrorInfo, type ReactNode } from 'react'
|
|
import { t } from './locales.ts'
|
|
import css from './sidebar.module.css'
|
|
|
|
export class RenderBoundary extends Component<{ children?: ReactNode; className?: string }, { error: string | null }> {
|
|
state = { error: null as string | null }
|
|
|
|
static getDerivedStateFromError(error: unknown): { error: string } {
|
|
return { error: error instanceof Error ? error.message : String(error) }
|
|
}
|
|
|
|
componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
console.error('[dsh-better-sidebar] render error:', error, info.componentStack)
|
|
}
|
|
|
|
render(): ReactNode {
|
|
if (this.state.error !== null) {
|
|
return (
|
|
<div className={this.props.className}>
|
|
<span>dsh-better-sidebar: {this.state.error}</span>
|
|
<button
|
|
type="button"
|
|
className={css.terminalRetry}
|
|
onClick={() => { this.setState({ error: null }) }}
|
|
>
|
|
{t('terminalRetry')}
|
|
</button>
|
|
</div>
|
|
)
|
|
}
|
|
return this.props.children
|
|
}
|
|
}
|