CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/course/common/folders-tool-bar.tsx
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { Input, Space } from "antd";
7
import type { Map as iMap } from "immutable";
8
import { useCallback, useMemo } from "react";
9
10
import { SEARCH_STYLE } from "./consts";
11
import { MultipleAddSearch } from "./multiple-add-search";
12
import { ItemName } from "./types";
13
14
interface FoldersToolbarProps {
15
search?: string;
16
search_change: (search_value: string) => void; // search_change(current_search_value)
17
num_omitted?: number;
18
project_id: string;
19
items: iMap<string, any>;
20
add_folders: (folders: string[]) => void; // add_folders (Iterable<T>)
21
item_name: ItemName;
22
plural_item_name: string;
23
}
24
25
export function FoldersToolbar({
26
search_change,
27
num_omitted,
28
items,
29
add_folders,
30
search: propsSearch,
31
item_name = "assignment",
32
plural_item_name = "item",
33
}: FoldersToolbarProps) {
34
return (
35
<Space>
36
<Input.Search
37
allowClear
38
placeholder={`Filter ${plural_item_name}...`}
39
value={propsSearch}
40
onChange={(e) => search_change(e.target.value)}
41
style={SEARCH_STYLE}
42
/>
43
{num_omitted ? (
44
<h5
45
style={{
46
textAlign: "center",
47
marginTop: "5px",
48
}}
49
>
50
(Omitting {num_omitted}{" "}
51
{num_omitted > 1 ? plural_item_name : item_name})
52
</h5>
53
) : undefined}
54
<AddItems addItems={add_folders} itemName={item_name} items={items} />
55
</Space>
56
);
57
}
58
59
export function AddItems({
60
addItems,
61
itemName,
62
items,
63
defaultOpen,
64
selectorStyle,
65
closable = true,
66
}: {
67
addItems;
68
itemName: ItemName;
69
items;
70
defaultOpen?;
71
selectorStyle?;
72
closable?;
73
}) {
74
// Omits any -collect directory (unless explicitly searched for).
75
// Omits any currently assigned directory or subdirectories.
76
const pathsToOmit = useMemo(() => {
77
const omit: Set<string> = new Set([]);
78
items
79
.filter((val) => !val.get("deleted"))
80
.map((val) => {
81
const path = val.get("path");
82
if (path != null) {
83
// path might not be set in case something went wrong
84
// (this has been hit in production)
85
omit.add(path);
86
}
87
});
88
return omit;
89
}, [items]);
90
91
const isExcluded = useCallback(
92
(path) => {
93
if (!path) return true;
94
if (path.includes("-collect")) {
95
return true;
96
}
97
if (pathsToOmit.has(path)) {
98
return true;
99
}
100
// finally check if path is contained in any ommited path.
101
for (const omit of pathsToOmit) {
102
if (path.startsWith(omit + "/")) return true;
103
if (omit.startsWith(path + "/")) return true;
104
}
105
106
return false;
107
},
108
[pathsToOmit],
109
);
110
111
return (
112
<MultipleAddSearch
113
isExcluded={isExcluded}
114
addSelected={(paths) => {
115
if (paths != null) {
116
addItems(paths);
117
}
118
}}
119
itemName={itemName}
120
defaultOpen={defaultOpen}
121
selectorStyle={selectorStyle}
122
closable={closable}
123
/>
124
);
125
}
126
127