Skip to content

Commit

Permalink
Merge pull request #134 from hypertool/feat/console/close-tabs
Browse files Browse the repository at this point in the history
Update App Builder Tabs to Implement Tab Closing
  • Loading branch information
itssamuelrowe committed Mar 7, 2022
2 parents 3b625c9 + 82caad3 commit ca39f1d
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 16 deletions.
12 changes: 6 additions & 6 deletions packages/console/src/contexts/BuilderActionsContext.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { createContext } from "react";

import { IBuilderActionsContext, TBundleType, TTabType } from "../types";
Expand All @@ -6,7 +7,6 @@ const BuilderActionsContext = createContext<IBuilderActionsContext>({
tabs: [],
activeTab: null,

// eslint-disable-next-line @typescript-eslint/no-unused-vars
insertTab: (
_index: number,
_replace: boolean,
Expand All @@ -16,12 +16,10 @@ const BuilderActionsContext = createContext<IBuilderActionsContext>({
throw new Error("Implementation for this operation is missing.");
},

// eslint-disable-next-line @typescript-eslint/no-unused-vars
createTab: (_type: TTabType, _bundle?: TBundleType): void => {
throw new Error("Implementation for this operation is missing.");
},

// eslint-disable-next-line @typescript-eslint/no-unused-vars
replaceTab: (
_index: number,
_type: TTabType,
Expand All @@ -30,13 +28,15 @@ const BuilderActionsContext = createContext<IBuilderActionsContext>({
throw new Error("Implementation for this operation is missing.");
},

// eslint-disable-next-line @typescript-eslint/no-unused-vars
setTabTitle: (_index: number, _title: string): void => {
throw new Error("Implementation for this operation is missing.");
},

// eslint-disable-next-line @typescript-eslint/no-unused-vars
setActiveTab: (_activeTab: string) => {
setActiveTab: (_activeTab: string): void => {
throw new Error("Implementation for this operation is missing.");
},

closeTab: (_index: number): void => {
throw new Error("Implementation for this operation is missing.");
},
});
Expand Down
24 changes: 20 additions & 4 deletions packages/console/src/screens/app-builder/AppBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const AppBuilder: FunctionComponent = (): ReactElement => {
const artifacts = useInflateArtifacts(deflatedArtifacts);
const monaco = useMonaco();

const { type: activeTabType, bundle: activeTabBundle } = useMemo(
const { type: activeTabType } = useMemo(
() =>
tabs.find((tab) => tab.id === activeTab) || {
type: undefined,
Expand Down Expand Up @@ -182,7 +182,8 @@ const AppBuilder: FunctionComponent = (): ReactElement => {
const newCount = oldCount[type] + 1;

setTabs((oldTabs) => {
/* Edit tabs will be reactivated if they were previously
/*
* Edit tabs will be reactivated if they were previously
* created.
*/
const oldTab = oldTabs.find((oldTab) => {
Expand All @@ -205,7 +206,8 @@ const AppBuilder: FunctionComponent = (): ReactElement => {
return false;
});
if (oldTab) {
/* At this point, for the first time, `newCount` will be
/*
* At this point, for the first time, `newCount` will be
* off by one. On repeating `x` times, `newCount` will be
* off by `x`. However, we need not worry because `newCount`
* is temporarily used for `edit-*` tab types.
Expand Down Expand Up @@ -256,7 +258,8 @@ const AppBuilder: FunctionComponent = (): ReactElement => {

setTabTitle: (index: number, title: string): void => {
setTabs((oldTabs) => {
/* Do not update the title, if the specified title is already
/*
* Do not update the title, if the specified title is already
* equal to the current title. Otherwise, an infinite loop will
* be triggered.
*/
Expand All @@ -273,6 +276,19 @@ const AppBuilder: FunctionComponent = (): ReactElement => {
return result;
});
},

closeTab: (index: number): void => {
setTabs((oldTabs) => {
const result = [...oldTabs];
result.splice(index, 1);

if (result.length > 0) {
setActiveTab(result[result.length - 1].id);
}

return result;
});
},
};

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ const TabTitleText = styled("span")({
});

const BuilderTabs: FunctionComponent = (): ReactElement => {
const { tabs, activeTab, setActiveTab } = useContext(BuilderActionsContext);
const { tabs, activeTab, setActiveTab, closeTab } = useContext(
BuilderActionsContext,
);

const handleChange = (_event: SyntheticEvent, newActiveTab: string) => {
setActiveTab(newActiveTab);
};

const renderTab = (tab: ITab) => (
const handleClose = (index: number) => () => {
closeTab(index);
};

const renderTab = (tab: ITab, index: number) => (
<Tab
key={tab.id}
value={tab.id}
Expand All @@ -40,7 +46,7 @@ const BuilderTabs: FunctionComponent = (): ReactElement => {
label={
<div>
<TabTitleText>{tab.title}</TabTitleText>
<IconButton size="small">
<IconButton size="small" onClick={handleClose(index)}>
<Icon fontSize="small" style={{ fontSize: 14 }}>
close
</Icon>
Expand All @@ -54,7 +60,8 @@ const BuilderTabs: FunctionComponent = (): ReactElement => {
<StyledTabs
value={activeTab}
onChange={handleChange}
variant="scrollable">
variant="scrollable"
>
{tabs.map(renderTab)}
</StyledTabs>
);
Expand Down
5 changes: 3 additions & 2 deletions packages/console/src/types/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ export interface ITab {
}

export interface IBuilderActionsContext {
tabs: ITab[];
activeTab: string | null;
insertTab: (
index: number,
replace: boolean,
Expand All @@ -182,9 +184,8 @@ export interface IBuilderActionsContext {
createTab: (type: TTabType, bundle?: TBundleType) => void;
replaceTab: (index: number, type: TTabType, bundle?: TBundleType) => void;
setTabTitle: (index: number, title: string) => void;
tabs: ITab[];
activeTab: string | null;
setActiveTab: (activeTab: string) => void;
closeTab: (index: number) => void;
}

export interface ISessionContext {
Expand Down

0 comments on commit ca39f1d

Please sign in to comment.