Skip to content

Commit b0b0bb2

Browse files
committed
make it easier to create a folder
- based on user feedback and testing
1 parent 59f7649 commit b0b0bb2

File tree

5 files changed

+89
-73
lines changed

5 files changed

+89
-73
lines changed

src/packages/frontend/course/assignments/assignment.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ export function Assignment({
692692
to a backup file ending in a tilde, or possibly only be available in
693693
snapshots. Select "Replace student files!" in case you do <b>not</b>{" "}
694694
want to create any backups and also <b>delete</b> all other files in
695-
the assignment directory of their projects.{" "}
695+
the assignment folder of their projects.{" "}
696696
<a
697697
target="_blank"
698698
href="https://github.com/sagemathinc/cocalc/wiki/CourseCopy"

src/packages/frontend/course/common/multiple-add-search.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export function MultipleAddSearch({
5959
boxShadow: "8px 8px 4px #888",
6060
...selectorStyle,
6161
}}
62-
title={`Select one or more ${itemName} directories`}
62+
title={`Select one or more ${itemName} folders`}
6363
onMultiSelect={setSelectedItems}
6464
onClose={clear}
6565
isExcluded={(path) => {

src/packages/frontend/file-associations.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ Maybe that could be useful at some point.
1717
*/
1818

1919
import { IconName } from "./components/icon";
20-
2120
import imageExtensions from "image-extensions";
2221
import videoExtensions from "video-extensions";
2322
import audioExtensions from "audio-extensions";
@@ -27,6 +26,13 @@ export function filenameMode(path: string, fallback = "text"): string {
2726
return file_associations[filename_extension(path)]?.opts?.mode ?? fallback;
2827
}
2928

29+
export function filenameIcon(
30+
path: string,
31+
fallback = "file" as IconName,
32+
): IconName {
33+
return file_associations[filename_extension(path)]?.icon ?? fallback;
34+
}
35+
3036
const codemirror_associations: { [ext: string]: string } = {
3137
adb: "ada",
3238
asm: "text/x-gas",

src/packages/frontend/project/directory-selector.tsx

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Component that allows a user to select a directory in a project.
1010
*/
1111

1212
import { join } from "path";
13-
import { Button, Card, Checkbox, Input, InputRef, Modal, Tooltip } from "antd";
13+
import { Button, Card, Checkbox, Input, InputRef, Modal } from "antd";
1414
import {
1515
CSSProperties,
1616
ReactNode,
@@ -452,19 +452,20 @@ function Subdirs(props) {
452452
}
453453
paths.sort();
454454
newPaths.sort();
455+
const createProps = {
456+
project_id,
457+
path,
458+
computeServerId,
459+
directoryListings,
460+
toggleSelection,
461+
};
462+
w.push(<CreateDirectory key="create1" {...createProps} />);
455463
for (const name of paths.concat(newPaths)) {
456464
w.push(<Directory key={name} {...props} path={join(base, name)} />);
457465
}
458-
w.push(
459-
<CreateDirectory
460-
key="\\createdirectory\\"
461-
project_id={project_id}
462-
path={path}
463-
computeServerId={computeServerId}
464-
directoryListings={directoryListings}
465-
toggleSelection={toggleSelection}
466-
/>,
467-
);
466+
if (w.length > 10) {
467+
w.push(<CreateDirectory key="create2" {...createProps} />);
468+
}
468469
return (
469470
<div key={path} style={style}>
470471
{w}
@@ -517,15 +518,16 @@ function CreateDirectory({
517518
const target = path + (path != "" ? "/" : "") + value;
518519
(async () => {
519520
try {
520-
setValue(
521-
await getValidPath(
522-
project_id,
523-
target,
524-
directoryListings,
525-
computeServerId,
526-
),
521+
const path1 = await getValidPath(
522+
project_id,
523+
target,
524+
directoryListings,
525+
computeServerId,
527526
);
528-
input_ref.current?.select();
527+
setValue(path_split(path1).tail);
528+
setTimeout(() => {
529+
input_ref.current?.select();
530+
}, 1);
529531
} catch (err) {
530532
setError(`${err}`);
531533
}
@@ -539,6 +541,7 @@ function CreateDirectory({
539541
command: "mkdir",
540542
args: ["-p", value],
541543
project_id,
544+
path,
542545
compute_server_id: computeServerId,
543546
filesystem: true,
544547
});
@@ -550,35 +553,35 @@ function CreateDirectory({
550553

551554
return (
552555
<div style={{ color: "#666" }} key={"...-create-dir"}>
553-
<Tooltip
554-
title="Create a new directory (double click to rename)"
555-
placement="left"
556-
mouseEnterDelay={0.9}
556+
<Modal
557+
title={
558+
<>
559+
<Icon name="plus-circle" style={{ marginRight: "5px" }} /> New Folder
560+
</>
561+
}
562+
open={open}
563+
onOk={createFolder}
564+
onCancel={() => setOpen(false)}
557565
>
558-
<Modal open={open} onOk={createFolder} onCancel={() => setOpen(false)}>
559-
<Input
560-
ref={input_ref}
561-
title="Create Folder"
562-
style={{ marginTop: "30px" }}
563-
value={value}
564-
onChange={(e) => setValue(e.target.value)}
565-
onPressEnter={createFolder}
566-
autoFocus
567-
/>
568-
</Modal>
569-
<Button
570-
size="small"
571-
type="text"
572-
style={{ color: "#666" }}
573-
disabled={open}
574-
onClick={() => {
575-
setOpen(true);
576-
}}
577-
>
578-
<Icon name="plus" style={{ marginRight: "5px" }} /> Create{" "}
579-
{NEW_FOLDER}...
580-
</Button>
581-
</Tooltip>
566+
<Input
567+
ref={input_ref}
568+
title="New Folder"
569+
style={{ marginTop: "30px" }}
570+
value={value}
571+
onChange={(e) => setValue(e.target.value)}
572+
onPressEnter={createFolder}
573+
autoFocus
574+
/>
575+
</Modal>
576+
<Button
577+
disabled={open}
578+
onClick={() => {
579+
setOpen(true);
580+
}}
581+
style={{ margin: "5px 0" }}
582+
>
583+
<Icon name="plus-circle" style={{ marginRight: "5px" }} /> New Folder ...
584+
</Button>
582585
<ShowError error={error} setError={setError} />
583586
</div>
584587
);

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

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import { Button, Input, Modal, Space } from "antd";
77
import { useEffect, useRef, useState } from "react";
88
import { FormattedMessage, useIntl } from "react-intl";
9-
109
import { default_filename } from "@cocalc/frontend/account";
1110
import { Alert, Col, Row } from "@cocalc/frontend/antd-bootstrap";
11+
import { filenameIcon } from "@cocalc/frontend/file-associations";
1212
import {
1313
ProjectActions,
1414
useActions,
@@ -259,6 +259,7 @@ export default function NewFilePage(props: Props) {
259259

260260
const renderCreate = () => {
261261
let desc: string;
262+
const ext = filename_extension(filename);
262263
if (filename.endsWith("/")) {
263264
desc = intl.formatMessage(labels.folder);
264265
} else if (
@@ -267,20 +268,19 @@ export default function NewFilePage(props: Props) {
267268
) {
268269
desc = intl.formatMessage(labels.download);
269270
} else {
270-
const ext = filename_extension(filename);
271271
if (ext) {
272272
desc = intl.formatMessage(
273273
{
274274
id: "project.new.new-file-page.create.desc_file",
275275
defaultMessage: "{ext} file",
276-
description: "An extension-nameed file on a button",
276+
description: "An extension-named file on a button",
277277
},
278278
{ ext },
279279
);
280280
} else {
281281
desc = intl.formatMessage({
282282
id: "project.new.new-file-page.create.desc_no_ext",
283-
defaultMessage: "file with no extension",
283+
defaultMessage: "File with no extension",
284284
description: "A filename without an extension",
285285
});
286286
}
@@ -295,27 +295,34 @@ export default function NewFilePage(props: Props) {
295295
);
296296

297297
return (
298-
<Tip
299-
icon="file"
300-
title={title}
301-
tip={intl.formatMessage(
302-
{
303-
id: "project.new.new-file-page.create.tooltip",
304-
defaultMessage: `{title}. You can also press return.`,
305-
description:
306-
"Informing the user in this tooltip, that it is also possible to press the return key",
307-
},
308-
{ title },
298+
<Space>
299+
{!ext && !filename.endsWith("/") && (
300+
<Button size="large" onClick={() => createFolder()}>
301+
<Icon name="folder" /> Create Folder
302+
</Button>
309303
)}
310-
>
311-
<Button
312-
size="large"
313-
disabled={filename.trim() == ""}
314-
onClick={() => submit()}
304+
<Tip
305+
icon="file"
306+
title={title}
307+
tip={intl.formatMessage(
308+
{
309+
id: "project.new.new-file-page.create.tooltip",
310+
defaultMessage: `{title}. You can also press return.`,
311+
description:
312+
"Informing the user in this tooltip, that it is also possible to press the return key",
313+
},
314+
{ title },
315+
)}
315316
>
316-
Create {desc}
317-
</Button>
318-
</Tip>
317+
<Button
318+
size="large"
319+
disabled={filename.trim() == ""}
320+
onClick={() => submit()}
321+
>
322+
<Icon name={filenameIcon(filename)} /> Create {desc}
323+
</Button>
324+
</Tip>
325+
</Space>
319326
);
320327
};
321328

0 commit comments

Comments
 (0)