Workspaces FE (#1733)

This commit is contained in:
Louis Knight-Webb
2026-01-08 22:14:38 +00:00
committed by GitHub
parent fe2215ba85
commit 527febdc52
291 changed files with 23770 additions and 880 deletions

View File

@@ -0,0 +1,143 @@
import { useMemo } from 'react';
import { useLayoutStore } from '@/stores/useLayoutStore';
import { useDiffViewStore, useDiffViewMode } from '@/stores/useDiffViewStore';
import { useUiPreferencesStore } from '@/stores/useUiPreferencesStore';
import { useWorkspaceContext } from '@/contexts/WorkspaceContext';
import type { Workspace } from 'shared/types';
import type {
ActionVisibilityContext,
ActionDefinition,
ActionIcon,
} from './index';
import { resolveLabel } from './index';
import type { CommandBarPage } from './pages';
/**
* Hook that builds the visibility context from stores/context.
* Used by both NavbarContainer and CommandBarDialog to evaluate
* action visibility and state conditions.
*/
export function useActionVisibilityContext(): ActionVisibilityContext {
const layout = useLayoutStore();
const { workspace, isCreateMode, repos } = useWorkspaceContext();
const diffPaths = useDiffViewStore((s) => s.diffPaths);
const diffViewMode = useDiffViewMode();
const expanded = useUiPreferencesStore((s) => s.expanded);
return useMemo(() => {
// Compute isAllDiffsExpanded
const diffKeys = diffPaths.map((p) => `diff:${p}`);
const isAllDiffsExpanded =
diffKeys.length > 0 && diffKeys.every((k) => expanded[k] !== false);
return {
isChangesMode: layout.isChangesMode,
isLogsMode: layout.isLogsMode,
isPreviewMode: layout.isPreviewMode,
isSidebarVisible: layout.isSidebarVisible,
isMainPanelVisible: layout.isMainPanelVisible,
isGitPanelVisible: layout.isGitPanelVisible,
isCreateMode,
hasWorkspace: !!workspace,
workspaceArchived: workspace?.archived ?? false,
hasDiffs: diffPaths.length > 0,
diffViewMode,
isAllDiffsExpanded,
hasGitRepos: repos.length > 0,
hasMultipleRepos: repos.length > 1,
};
}, [
layout.isChangesMode,
layout.isLogsMode,
layout.isPreviewMode,
layout.isSidebarVisible,
layout.isMainPanelVisible,
layout.isGitPanelVisible,
isCreateMode,
workspace,
repos,
diffPaths,
diffViewMode,
expanded,
]);
}
/**
* Helper to check if an action is visible given the current context.
* If the action has no isVisible condition, it's always visible.
*/
export function isActionVisible(
action: ActionDefinition,
ctx: ActionVisibilityContext
): boolean {
return action.isVisible ? action.isVisible(ctx) : true;
}
/**
* Helper to check if a page is visible given the current context.
* If the page has no isVisible condition, it's always visible.
*/
export function isPageVisible(
page: CommandBarPage,
ctx: ActionVisibilityContext
): boolean {
return page.isVisible ? page.isVisible(ctx) : true;
}
/**
* Helper to check if an action is active given the current context.
* If the action has no isActive callback, returns false.
*/
export function isActionActive(
action: ActionDefinition,
ctx: ActionVisibilityContext
): boolean {
return action.isActive ? action.isActive(ctx) : false;
}
/**
* Helper to check if an action is enabled given the current context.
* If the action has no isEnabled callback, returns true (enabled by default).
*/
export function isActionEnabled(
action: ActionDefinition,
ctx: ActionVisibilityContext
): boolean {
return action.isEnabled ? action.isEnabled(ctx) : true;
}
/**
* Get the icon for an action, considering dynamic icon callbacks.
* Falls back to the static icon property.
*/
export function getActionIcon(
action: ActionDefinition,
ctx: ActionVisibilityContext
): ActionIcon {
return action.getIcon ? action.getIcon(ctx) : action.icon;
}
/**
* Get the tooltip for an action, considering dynamic tooltip callbacks.
* Falls back to the resolved label.
*/
export function getActionTooltip(
action: ActionDefinition,
ctx: ActionVisibilityContext
): string {
return action.getTooltip ? action.getTooltip(ctx) : resolveLabel(action);
}
/**
* Get the label for an action, considering dynamic label callbacks.
* Falls back to the resolved static label.
*/
export function getActionLabel(
action: ActionDefinition,
ctx: ActionVisibilityContext,
workspace?: Workspace
): string {
return action.getLabel
? action.getLabel(ctx)
: resolveLabel(action, workspace);
}