Skip to content

Commit

Permalink
fix(Scope/Workspace/Lanes UI): Override useLanes hook (#6936)
Browse files Browse the repository at this point in the history
* fix compare version picker

* override use lanes

* clean up  scopes/scope/scope/get-scope-options.ts

* fix side-bar.tsx
  • Loading branch information
luvkapur authored Jan 20, 2023
1 parent 5361d81 commit 12dcac0
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 25 deletions.
5 changes: 4 additions & 1 deletion scopes/component/component-drawer/component-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type TransformTreeFn = (host?: WorkspaceModel | ScopeModel) => (rootNode:

export type ComponentsDrawerProps = Omit<DrawerType, 'render'> & {
useComponents: () => { components: ComponentModel[]; loading?: boolean };
useLanes?: () => { lanesModel?: LanesModel; loading?: boolean };
emptyMessage?: ReactNode;
plugins?: ComponentsDrawerPlugins;
transformTree?: TransformTreeFn;
Expand All @@ -54,6 +55,7 @@ export type ComponentsDrawerPlugins = {
export class ComponentsDrawer implements DrawerType {
readonly id: string;
readonly useComponents: () => { components: ComponentModel[]; loading?: boolean };
readonly useLanes: () => { lanesModel?: LanesModel; loading?: boolean };
name: ReactNode;
tooltip?: string;
order?: number;
Expand All @@ -68,6 +70,7 @@ export class ComponentsDrawer implements DrawerType {
constructor(props: ComponentsDrawerProps) {
Object.assign(this, props);
this.useComponents = props.useComponents;
this.useLanes = props.useLanes || useLanes;
this.emptyMessage = props.emptyMessage;
this.plugins = props.plugins || {};
this.setWidgets(props.plugins?.drawerWidgets);
Expand Down Expand Up @@ -144,7 +147,7 @@ export class ComponentsDrawer implements DrawerType {

render = () => {
const { loading, components } = this.useComponents();
const { lanesModel: lanes } = useLanes();
const { lanesModel: lanes } = this.useLanes();
const componentFiltersContext = useContext(ComponentFilterContext);

const filters = componentFiltersContext?.filters || [];
Expand Down
5 changes: 4 additions & 1 deletion scopes/lanes/hooks/use-lanes/lanes-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type LanesProviderProps = {
children: ReactNode;
viewedLaneId?: LaneId;
targetLanes?: LanesModel;
skipNetworkCall?: boolean;
ignoreDerivingFromUrl?: IgnoreDerivingFromUrl[];
};

Expand All @@ -20,8 +21,10 @@ export function LanesProvider({
viewedLaneId: viewedIdFromProps,
targetLanes,
ignoreDerivingFromUrl: ignoreDerivingFromUrlFromProps,
skipNetworkCall,
}: LanesProviderProps) {
const { lanesModel, loading } = useLanes(targetLanes);
const { lanesModel, loading } = useLanes(targetLanes, skipNetworkCall);

const [lanesState, setLanesState] = useState<LanesModel | undefined>(lanesModel);
const [viewedLaneId, setViewedLaneId] = useState<LaneId | undefined>(viewedIdFromProps);

Expand Down
5 changes: 3 additions & 2 deletions scopes/lanes/hooks/use-lanes/use-lanes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ const GET_LANES = gql`
`;

export function useLanes(
targetLanes?: LanesModel
targetLanes?: LanesModel,
skip?: boolean
): LanesContextModel & Omit<QueryResult<LanesQuery & { getHost: { id: string } }>, 'data'> {
const lanesContext = useLanesContext();
const shouldSkip = !!targetLanes || !!lanesContext;
const shouldSkip = skip || !!targetLanes || !!lanesContext;

const { data, loading, ...rest } = useDataQuery<LanesQuery & { getHost: { id: string } }>(GET_LANES, {
skip: shouldSkip,
Expand Down
2 changes: 2 additions & 0 deletions scopes/scope/scope/get-scope-options.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DrawerType } from '@teambit/ui-foundation.ui.tree.drawer';
import { ComponentType, ReactNode } from 'react';
import { ScopeModel } from '.';

Expand All @@ -8,4 +9,5 @@ export type GetScopeOptions = {
scopeClassName?: string;
TargetScopeOverview?: ComponentType;
PaneWrapper?: ComponentType<{ children: ReactNode }>;
overrideDrawers?: DrawerType[];
};
11 changes: 8 additions & 3 deletions scopes/scope/scope/scope.ui.drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
ScopeTreeNode,
} from '@teambit/ui-foundation.ui.side-bar';
import { TreeNode as TreeNodeType, TreeNodeProps } from '@teambit/design.ui.tree';
import { useLanes } from '@teambit/lanes.hooks.use-lanes';
import { useLanes as defaultUseLanesHook } from '@teambit/lanes.hooks.use-lanes';
import { useLaneComponents } from '@teambit/lanes.hooks.use-lane-components';
import { ComponentModel } from '@teambit/component';
import { useScope, ScopeContext } from '@teambit/scope.ui.hooks.scope-context';
// import { WorkspaceModel } from '@teambit/workspace';
import { LanesModel } from '@teambit/lanes.ui.models.lanes-model';
import { SidebarSlot } from './scope.ui.runtime';

export type ScopeDrawerProps = {
Expand All @@ -21,6 +21,7 @@ export type ScopeDrawerProps = {
drawerWidgetSlot: DrawerWidgetSlot;
assumeScopeInUrl?: boolean;
overrideUseComponents?: () => { components: ComponentModel[] };
overrideUseLanes?: () => { lanesModel?: LanesModel; loading?: boolean };
};

export const scopeDrawer = ({
Expand All @@ -29,12 +30,15 @@ export const scopeDrawer = ({
drawerWidgetSlot,
assumeScopeInUrl = false,
overrideUseComponents,
overrideUseLanes: useLanesFromProps,
}: ScopeDrawerProps) => {
const useLanes = useLanesFromProps || defaultUseLanesHook;

const customScopeTreeNodeRenderer = (treeNodeSlot, host?: any) =>
function TreeNode(props: TreeNodeProps<PayloadType>) {
const children = props.node.children;

if (!children) return <ComponentView {...props} treeNodeSlot={treeNodeSlot} />;
if (!children) return <ComponentView {...props} treeNodeSlot={treeNodeSlot} useLanes={useLanes} />;

// skip over scope node and render only children
if (props.node.payload instanceof ScopePayload) {
Expand Down Expand Up @@ -76,6 +80,7 @@ export const scopeDrawer = ({
drawerWidgets: drawerWidgetSlot,
},
useHost: () => useScope(),
useLanes,
emptyMessage: 'Scope is empty',
// TODO: create an interface for Component host.
transformTree: (host?: any) => {
Expand Down
34 changes: 23 additions & 11 deletions scopes/scope/scope/scope.ui.runtime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { MenuLinkItem } from '@teambit/design.ui.surfaces.menu.link-item';
import CommandBarAspect, { CommandBarUI, CommandHandler } from '@teambit/command-bar';
import { ScopeModel } from '@teambit/scope.models.scope-model';
import { DrawerType } from '@teambit/ui-foundation.ui.tree.drawer';
import { LanesModel } from '@teambit/lanes.ui.models.lanes-model';
import {
DrawerWidgetSlot,
FilterWidget,
Expand Down Expand Up @@ -131,7 +132,7 @@ export class ScopeUI {
TargetCorner={options.Corner}
routeSlot={this.routeSlot}
menuSlot={this.menuSlot}
sidebar={<this.sidebar.render items={this.listSidebarLinks()} />}
sidebar={<this.sidebar.render items={this.listSidebarLinks()} overrideDrawerSlot={options.overrideDrawers} />}
scopeUi={this}
userUseScopeQuery={options.useScope}
badgeSlot={this.scopeBadgeSlot}
Expand Down Expand Up @@ -286,16 +287,27 @@ export class ScopeUI {
this.drawerWidgetSlot.register(widgets);
};

registerDefaultDrawers(assumeScopeInUrl = false, overrideUseComponents?: () => { components: ComponentModel[] }) {
this.sidebar.registerDrawer(
scopeDrawer({
treeWidgets: this.sidebarSlot,
filtersSlot: this.drawerComponentsFiltersSlot,
drawerWidgetSlot: this.drawerWidgetSlot,
assumeScopeInUrl,
overrideUseComponents,
})
);
registerDefaultDrawers(
assumeScopeInUrl = false,
overrideUseComponents?: () => { components: ComponentModel[] },
overrideUseLanes?: () => { lanesModel: LanesModel }
) {
this.sidebar.registerDrawer(this.getDefaultDrawer(assumeScopeInUrl, overrideUseComponents, overrideUseLanes));
}

getDefaultDrawer(
assumeScopeInUrl = false,
overrideUseComponents?: () => { components: ComponentModel[] },
overrideUseLanes?: () => { lanesModel: LanesModel }
) {
return scopeDrawer({
treeWidgets: this.sidebarSlot,
filtersSlot: this.drawerComponentsFiltersSlot,
drawerWidgetSlot: this.drawerWidgetSlot,
assumeScopeInUrl,
overrideUseComponents,
overrideUseLanes,
});
}

uiRoot(): UIRoot {
Expand Down
8 changes: 6 additions & 2 deletions scopes/ui-foundation/sidebar/ui/side-bar/side-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ export type SideBarProps = {
* slot of registered items to the main section at the top.
*/
items?: ComponentType[];
/**
* override register drawers from the slot
*/
overrideDrawerSlot?: DrawerType[];
} & React.HTMLAttributes<HTMLDivElement>;

/**
* side bar component.
*/
export function SideBar({ drawerSlot, items = [], ...rest }: SideBarProps) {
const drawers = flatten(drawerSlot.values())
export function SideBar({ drawerSlot, items = [], overrideDrawerSlot, ...rest }: SideBarProps) {
const drawers = (overrideDrawerSlot || flatten(drawerSlot.values()))
.filter((drawer) => !drawer?.isHidden?.())
.sort(sortFn);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ import { TreeContext } from '@teambit/base-ui.graph.tree.tree-context';
import { indentClass } from '@teambit/base-ui.graph.tree.indent';
import { TreeNodeProps } from '@teambit/base-ui.graph.tree.recursive-tree';
import { useLanes } from '@teambit/lanes.hooks.use-lanes';
import { LanesModel } from '@teambit/lanes.ui.models.lanes-model';
import { PayloadType } from '../payload-type';
import { getName } from '../utils/get-name';
import styles from './component-view.module.scss';

export type ComponentViewProps<Payload = any> = {
treeNodeSlot?: ComponentTreeSlot;
useLanes?: () => { lanesModel?: LanesModel };
} & TreeNodeProps<Payload>;

export function ComponentView(props: ComponentViewProps<PayloadType>) {
const { node } = props;
const component = node.payload;

const { onSelect } = useContext(TreeContext);
const { lanesModel } = useLanes();
const { lanesModel } = (props.useLanes || useLanes)();

const handleClick = useCallback(
(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
onSelect && onSelect(node.id, event);
Expand Down
19 changes: 15 additions & 4 deletions scopes/workspace/workspace/workspace.ui.drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,29 @@ import {
ScopePayload,
ScopeTreeNode,
} from '@teambit/ui-foundation.ui.side-bar';
import { useLanes } from '@teambit/lanes.hooks.use-lanes';
import { useLanes as defaultUseLanesHook } from '@teambit/lanes.hooks.use-lanes';
import { useLaneComponents } from '@teambit/lanes.hooks.use-lane-components';
import { TreeNodeProps } from '@teambit/design.ui.tree';
import { ComponentModel } from '@teambit/component';
import { LanesModel } from '@teambit/lanes.ui.models.lanes-model';
import { SidebarWidgetSlot } from './workspace.ui.runtime';

export type WorkspaceDrawerProps = {
treeWidgets: SidebarWidgetSlot;
filtersSlot: ComponentFiltersSlot;
drawerWidgetSlot: DrawerWidgetSlot;
overrideUseLanes?: () => { lanesModel?: LanesModel; loading?: boolean };
};

export const workspaceDrawer = ({ treeWidgets, filtersSlot, drawerWidgetSlot }: WorkspaceDrawerProps) =>
new ComponentsDrawer({
export const workspaceDrawer = ({
treeWidgets,
filtersSlot,
drawerWidgetSlot,
overrideUseLanes: useLanesFromProps,
}: WorkspaceDrawerProps) => {
const useLanes = useLanesFromProps || defaultUseLanesHook;

return new ComponentsDrawer({
order: 0,
id: 'workspace-components-drawer',
name: 'COMPONENTS',
Expand All @@ -31,7 +40,7 @@ export const workspaceDrawer = ({ treeWidgets, filtersSlot, drawerWidgetSlot }:
function TreeNode(props: TreeNodeProps<PayloadType>) {
const children = props.node.children;

if (!children) return <ComponentView {...props} treeNodeSlot={treeNodeSlot} />; // non collapse
if (!children) return <ComponentView {...props} treeNodeSlot={treeNodeSlot} useLanes={useLanes} />; // non collapse

if (props.node.payload instanceof ScopePayload) return <ScopeTreeNode {...props} />;

Expand All @@ -42,6 +51,7 @@ export const workspaceDrawer = ({ treeWidgets, filtersSlot, drawerWidgetSlot }:
drawerWidgets: drawerWidgetSlot,
},
emptyMessage: 'Workspace is empty',
useLanes,
useComponents: () => {
const { lanesModel, loading: lanesLoading } = useLanes();
const viewedLaneId = lanesModel?.viewedLane?.id;
Expand All @@ -62,6 +72,7 @@ export const workspaceDrawer = ({ treeWidgets, filtersSlot, drawerWidgetSlot }:
};
},
});
};

function mergeComponents(mainComponents: ComponentModel[], laneComponents: ComponentModel[]): ComponentModel[] {
const mainComponentsThatAreNotOnLane = mainComponents.filter((mainComponent) => {
Expand Down

0 comments on commit 12dcac0

Please sign in to comment.