Skip to content

Commit 1b6be59

Browse files
Merge pull request #8752 from sagemathinc/filter-filebar-context-recent
frontend/project: improve file tabs recent-files menu
2 parents 23b101e + 81f0ada commit 1b6be59

File tree

1 file changed

+73
-4
lines changed

1 file changed

+73
-4
lines changed

src/packages/frontend/project/page/file-tabs.tsx

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ Tabs for the open files in a project.
88
*/
99

1010
import type { MenuProps, TabsProps } from "antd";
11-
import { Dropdown, Tabs } from "antd";
11+
import { Button, Dropdown, Tabs } from "antd";
12+
import { useState } from "react";
1213
import { useIntl } from "react-intl";
1314

1415
import {
@@ -30,8 +31,9 @@ import {
3031
type OpenedFile,
3132
} from "@cocalc/frontend/projects/util";
3233
import { EDITOR_PREFIX, path_to_tab } from "@cocalc/util/misc";
34+
import { COLORS } from "@cocalc/util/theme";
3335
import { file_tab_labels } from "../file-tab-labels";
34-
import { FileTab } from "./file-tab";
36+
import { FileTab, FIXED_PROJECT_TABS } from "./file-tab";
3537

3638
const MIN_WIDTH = 48;
3739

@@ -76,6 +78,7 @@ function keyToPath(s: string): string {
7678
export default function FileTabs({ openFiles, project_id, activeTab }) {
7779
const intl = useIntl();
7880
const actions = useActions({ project_id });
81+
const [recentFilesMenuOpen, setRecentFilesMenuOpen] = useState(false);
7982
const project_log = useTypedRedux({ project_id }, "project_log");
8083
const directory_listings = useTypedRedux(
8184
{ project_id },
@@ -105,6 +108,7 @@ export default function FileTabs({ openFiles, project_id, activeTab }) {
105108
paths.push(path);
106109
keys.push(pathToKey(path));
107110
});
111+
const openPathSet = new Set(paths);
108112

109113
const labels = file_tab_labels(paths);
110114
const items: TabsProps["items"] = [];
@@ -170,7 +174,31 @@ export default function FileTabs({ openFiles, project_id, activeTab }) {
170174
}
171175

172176
function getRecentFilesMenu(): MenuProps {
173-
const menuItems: MenuProps["items"] = recentFiles.map(
177+
const closedRecentFiles = recentFiles.filter(
178+
(entry: OpenedFile) => !openPathSet.has(entry.filename),
179+
);
180+
const actionItems: MenuProps["items"] = [
181+
{
182+
key: "browse-existing-files",
183+
icon: <Icon name={FIXED_PROJECT_TABS.files.icon} />,
184+
label: intl.formatMessage(i18nLabels.file_explorer),
185+
onClick: () => actions?.set_active_tab("files"),
186+
},
187+
{
188+
key: "create-new-file",
189+
icon: <Icon name={FIXED_PROJECT_TABS.new.icon} />,
190+
label: intl.formatMessage(i18nLabels.new_tooltip),
191+
onClick: () => actions?.set_active_tab("new"),
192+
},
193+
];
194+
195+
if (closedRecentFiles.length === 0) {
196+
return {
197+
items: actionItems,
198+
};
199+
}
200+
201+
const menuItems: MenuProps["items"] = closedRecentFiles.map(
174202
(entry: OpenedFile) => {
175203
const icon = file_options(entry.filename)?.icon ?? "file";
176204
return {
@@ -196,13 +224,53 @@ export default function FileTabs({ openFiles, project_id, activeTab }) {
196224
label: intl.formatMessage(i18nLabels.recent_files),
197225
children: menuItems,
198226
},
227+
{
228+
key: "recent-files-divider",
229+
type: "divider",
230+
},
231+
...actionItems,
199232
],
200233
style: { maxHeight: "min(500px, 50vh)", overflowY: "auto" },
201234
};
202235
}
203236

237+
const recentFilesMenu = getRecentFilesMenu();
238+
239+
function renderExtra() {
240+
return {
241+
right: (
242+
<div
243+
style={{
244+
display: "flex",
245+
alignItems: "center",
246+
marginRight: "10px",
247+
marginLeft: "10px",
248+
}}
249+
>
250+
<Dropdown
251+
trigger={["click"]}
252+
menu={recentFilesMenu}
253+
onOpenChange={setRecentFilesMenuOpen}
254+
>
255+
<Button
256+
type="text"
257+
size="small"
258+
icon={<Icon name="down-circle-o" />}
259+
style={{
260+
paddingInline: "10px",
261+
...(recentFilesMenuOpen
262+
? { backgroundColor: COLORS.GRAY_LL }
263+
: {}),
264+
}}
265+
/>
266+
</Dropdown>
267+
</div>
268+
),
269+
};
270+
}
271+
204272
return (
205-
<Dropdown trigger={["contextMenu"]} menu={getRecentFilesMenu()}>
273+
<Dropdown trigger={["contextMenu"]} menu={recentFilesMenu}>
206274
<div style={{ width: "100%" }}>
207275
<SortableTabs
208276
items={keys}
@@ -223,6 +291,7 @@ export default function FileTabs({ openFiles, project_id, activeTab }) {
223291
items={items}
224292
activeKey={activeKey}
225293
type={"editable-card"}
294+
tabBarExtraContent={renderExtra()}
226295
onChange={(key) => {
227296
if (actions == null) return;
228297
actions.set_active_tab(path_to_tab(keyToPath(key)));

0 commit comments

Comments
 (0)