mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-07 19:28:44 +01:00
75c9e211d9
Adds resizability to the layout system. Hovering in the margins of a block will highlight the available resize handle and show a cursor indicating its resize direction. Dragging will cause the resizing nodes to blur out and be replaced by an outline. Releasing the handle will commit the new resize operation and cause the underlying nodes to update to their new sizes. We'll want to refactor this in the future to move all layout and resize logic into a shared model that the TileLayout code can talk to, but that's a future improvement. For now, this makes some compromises, mainly that the logic is kind of distributed around. --------- Co-authored-by: sawka <mike.sawka@gmail.com>
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
// Copyright 2023, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { Block, BlockFrame } from "@/app/block/block";
|
|
import { getApi } from "@/store/global";
|
|
import * as services from "@/store/services";
|
|
import * as WOS from "@/store/wos";
|
|
import * as React from "react";
|
|
|
|
import { CenteredDiv, CenteredLoadingDiv } from "@/element/quickelems";
|
|
import { TileLayout } from "@/faraday/index";
|
|
import { getLayoutStateAtomForTab } from "@/faraday/lib/layoutAtom";
|
|
import { useAtomValue } from "jotai";
|
|
import { useMemo } from "react";
|
|
import "./tabcontent.less";
|
|
|
|
const TabContent = React.memo(({ tabId }: { tabId: string }) => {
|
|
const oref = useMemo(() => WOS.makeORef("tab", tabId), [tabId]);
|
|
const loadingAtom = useMemo(() => WOS.getWaveObjectLoadingAtom(oref), [oref]);
|
|
const tabLoading = useAtomValue(loadingAtom);
|
|
const tabAtom = useMemo(() => WOS.getWaveObjectAtom<Tab>(oref), [oref]);
|
|
const layoutStateAtom = useMemo(() => getLayoutStateAtomForTab(tabId, tabAtom), [tabAtom, tabId]);
|
|
const tabData = useAtomValue(tabAtom);
|
|
|
|
const tileLayoutContents = useMemo(() => {
|
|
function renderBlock(
|
|
tabData: TabLayoutData,
|
|
ready: boolean,
|
|
onClose: () => void,
|
|
dragHandleRef: React.RefObject<HTMLDivElement>
|
|
) {
|
|
if (!tabData.blockId || !ready) {
|
|
return null;
|
|
}
|
|
return (
|
|
<Block
|
|
key={tabData.blockId}
|
|
blockId={tabData.blockId}
|
|
onClose={onClose}
|
|
dragHandleRef={dragHandleRef}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function renderPreview(tabData: TabLayoutData) {
|
|
return <BlockFrame key={tabData.blockId} blockId={tabData.blockId} preview={true} />;
|
|
}
|
|
|
|
function onNodeDelete(data: TabLayoutData) {
|
|
return services.ObjectService.DeleteBlock(data.blockId);
|
|
}
|
|
|
|
return {
|
|
renderContent: renderBlock,
|
|
renderPreview: renderPreview,
|
|
tabId: tabId,
|
|
onNodeDelete: onNodeDelete,
|
|
};
|
|
}, []);
|
|
|
|
if (tabLoading) {
|
|
return <CenteredLoadingDiv />;
|
|
}
|
|
|
|
if (!tabData) {
|
|
return (
|
|
<div className="tabcontent">
|
|
<CenteredDiv>Tab Not Found</CenteredDiv>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (tabData?.blockids?.length == 0) {
|
|
return <div className="tabcontent tabcontent-empty"></div>;
|
|
}
|
|
|
|
return (
|
|
<div className="tabcontent">
|
|
<TileLayout
|
|
key={tabId}
|
|
contents={tileLayoutContents}
|
|
layoutTreeStateAtom={layoutStateAtom}
|
|
getCursorPoint={getApi().getCursorPoint}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export { TabContent };
|