Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/file-info-dropdown.tsx
1678 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
// info button inside the editor when editing a file. links you back to the file listing with the action prompted
7
8
import { createRoot } from "react-dom/client";
9
10
import { CSS, React, useActions } from "@cocalc/frontend/app-framework";
11
import { DropdownMenu, Icon, IconName } from "@cocalc/frontend/components";
12
import { MenuItems } from "@cocalc/frontend/components/dropdown-menu";
13
import { useStudentProjectFunctionality } from "@cocalc/frontend/course";
14
import { file_actions } from "@cocalc/frontend/project_store";
15
import { capitalize, filename_extension } from "@cocalc/util/misc";
16
17
interface Props {
18
filename: string; // expects the full path name
19
project_id: string;
20
is_public?: boolean;
21
style?: CSS;
22
button?: boolean;
23
mode?: "explorer" | "flyout";
24
}
25
26
const EditorFileInfoDropdown: React.FC<Props> = React.memo(
27
(props: Props) => {
28
const {
29
filename,
30
project_id,
31
is_public,
32
style,
33
button,
34
mode = "explorer",
35
} = props;
36
const actions = useActions({ project_id });
37
const student_project_functionality =
38
useStudentProjectFunctionality(project_id);
39
if (student_project_functionality.disableActions) {
40
return <span></span>;
41
}
42
43
function handle_click(name) {
44
if (actions == null) {
45
console.warn("file click -- actions not available");
46
return;
47
}
48
if (name === "new") {
49
let new_ext: string | undefined = filename_extension(filename);
50
if (new_ext == "") {
51
// otherwise 'foo' leads to 'random.'
52
new_ext = undefined;
53
}
54
// Special calse -- not an action on this one file
55
actions.set_active_tab("new", { new_ext });
56
return;
57
}
58
for (const key in file_actions) {
59
if (key === name) {
60
actions.show_file_action_panel({
61
path: filename,
62
action: key,
63
});
64
break;
65
}
66
}
67
}
68
69
function render_menu_item(key: string, icon: IconName): MenuItems[0] {
70
return {
71
key,
72
onClick: () => handle_click(key),
73
label: (
74
<>
75
<Icon name={icon} style={{ width: "25px" }} /> {capitalize(key)}
76
</>
77
),
78
};
79
}
80
81
function render_menu_items(): MenuItems {
82
let items: { [key: string]: IconName };
83
const v: MenuItems = [];
84
if (is_public) {
85
// Fewer options when viewing the action dropdown in public mode:
86
items = {
87
download: "cloud-download",
88
copy: "files",
89
};
90
} else {
91
if (mode !== "flyout") {
92
v.push(render_menu_item("new", "plus-circle"));
93
}
94
// create a map from name to icon
95
items = {};
96
for (const key in file_actions) {
97
const { icon, hideFlyout } = file_actions[key];
98
if (mode === "flyout" && hideFlyout) continue;
99
items[key] = icon;
100
}
101
}
102
103
for (let key in items) {
104
const icon = items[key];
105
v.push(render_menu_item(key, icon));
106
}
107
return v;
108
}
109
110
return (
111
<DropdownMenu
112
button={button}
113
style={{ ...{ height: "100%" }, ...style }}
114
id="file_info_button"
115
title={"File"}
116
items={render_menu_items()}
117
/>
118
);
119
},
120
(prev, next) =>
121
prev.filename == next.filename && prev.is_public == next.is_public,
122
);
123
124
// This is for sage worksheets...
125
export function render_file_info_dropdown(
126
filename: string,
127
project_id: string,
128
dom_node,
129
is_public?,
130
) {
131
const root = createRoot(dom_node);
132
root.render(
133
<EditorFileInfoDropdown
134
filename={filename}
135
project_id={project_id}
136
is_public={is_public}
137
style={{ height: "34px" }}
138
/>,
139
);
140
}
141
142