Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/course/common/multiple-add-search.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Button } from "antd";6import { useState } from "react";7import { FormattedMessage, useIntl } from "react-intl";89import { Icon } from "@cocalc/frontend/components";10import { course } from "@cocalc/frontend/i18n";11import DirectorySelector from "@cocalc/frontend/project/directory-selector";12import { capitalize, plural } from "@cocalc/util/misc";13import { ItemName } from "./types";1415interface MultipleAddSearchProps {16addSelected: (keys: string[]) => void; // Submit user selected results add_selected(['paths', 'of', 'folders'])17itemName: ItemName;18err?: string;19isExcluded: (path: string) => boolean;20defaultOpen?;21selectorStyle?;22closable: boolean;23}2425// Multiple result selector26// use on_change and search to control the search bar.27// Coupled with Assignments Panel and Handouts Panel28export function MultipleAddSearch({29addSelected,30itemName = "assignment",31isExcluded,32defaultOpen,33selectorStyle,34closable,35}: MultipleAddSearchProps) {36const intl = useIntl();37const [selecting, setSelecting] = useState<boolean>(defaultOpen);38const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set([]));39const n = selectedItems.size;4041function clear() {42setSelecting(false);43setSelectedItems(new Set([]));44}4546function label(): string {47switch (itemName) {48case "assignment":49return intl.formatMessage(course.assignment);50case "handout":51return intl.formatMessage(course.handout);52default:53return itemName;54}55}5657function labelPlural(): string {58if (n === 1) return label();59switch (itemName) {60case "assignment":61return intl.formatMessage(course.assignments);62case "handout":63return intl.formatMessage(course.handouts);64default:65return plural(n, label());66}67}6869const title = intl.formatMessage(70{71id: "course.multiple-add-search.directory-selector.title",72defaultMessage: `Select one or more {name} folders`,73},74{ name: label() },75);7677return (78<div>79<Button80style={{ marginRight: "5px" }}81disabled={selecting}82onClick={() => setSelecting(true)}83>84<FormattedMessage85id="course.multiple-add-search.directory-selector.button"86defaultMessage={`Add {name}...`}87values={{ name: capitalize(label()) }}88/>89</Button>90{selecting && (91<DirectorySelector92multi93closable={closable}94style={{95width: "500px",96margin: "10px 0",97position: "absolute",98zIndex: 1,99boxShadow: "8px 8px 4px #888",100...selectorStyle,101}}102title={title}103onMultiSelect={setSelectedItems}104onClose={clear}105isExcluded={(path) => {106for (const cur of selectedItems) {107if (path.startsWith(cur + "/")) return true;108if (cur.startsWith(path + "/")) return true;109}110return isExcluded(path);111}}112/>113)}114{selecting && (115<Button116type="primary"117disabled={n == 0}118onClick={() => {119addSelected(Array.from(selectedItems));120clear();121}}122>123<Icon name="plus" />124<FormattedMessage125id="course.multiple-add-search.directory-selector.add_button"126defaultMessage={`{n, select,1270 {Select one or more directories}128other {Add {n} {name}}}`}129values={{130n,131name: labelPlural(),132}}133/>134</Button>135)}136</div>137);138}139140141