diff --git a/src/packages/frontend/project/new/add-ai-gen-btn.tsx b/src/packages/frontend/project/new/add-ai-gen-btn.tsx index ebea01cab6..c122d55176 100644 --- a/src/packages/frontend/project/new/add-ai-gen-btn.tsx +++ b/src/packages/frontend/project/new/add-ai-gen-btn.tsx @@ -3,10 +3,10 @@ * License: MS-RSL – see LICENSE.md for details */ -import { Col, Flex } from "antd"; +import { Col, Flex, Space } from "antd"; +import { AIGenerateDocumentButton } from "@cocalc/frontend/project/page/home-page/ai-generate-document"; import { Ext } from "@cocalc/frontend/project/page/home-page/ai-generate-examples"; -import { AIGenerateDocumentButton } from "../page/home-page/ai-generate-document"; interface Props { btn: JSX.Element; @@ -38,10 +38,10 @@ export function AiDocGenerateBtn({ btn, grid, ext, filename, mode }: Props) { ); } else { return ( - + {btn} - + ); } } diff --git a/src/packages/frontend/project/new/file-type-selector.tsx b/src/packages/frontend/project/new/file-type-selector.tsx index d9266eb80b..4782f1b1b0 100644 --- a/src/packages/frontend/project/new/file-type-selector.tsx +++ b/src/packages/frontend/project/new/file-type-selector.tsx @@ -3,13 +3,18 @@ * License: MS-RSL – see LICENSE.md for details */ -import { Col, Modal, Row, Tag } from "antd"; +import { Col, Flex, Modal, Row, Space, Tag } from "antd"; import { Gutter } from "antd/es/grid/row"; import type { ReactNode } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { Available } from "@cocalc/comm/project-configuration"; -import { CSS } from "@cocalc/frontend/app-framework"; +import { + CSS, + useEffect, + useRef, + useState, +} from "@cocalc/frontend/app-framework"; import { A } from "@cocalc/frontend/components/A"; import { Icon } from "@cocalc/frontend/components/icon"; import { Tip } from "@cocalc/frontend/components/tip"; @@ -20,6 +25,7 @@ import { AiDocGenerateBtn } from "./add-ai-gen-btn"; import { DELAY_SHOW_MS, NEW_FILETYPE_ICONS } from "./consts"; import { JupyterNotebookButtons } from "./jupyter-buttons"; import { NewFileButton } from "./new-file-button"; +import { throttle } from "lodash"; interface DisabledFeatures { linux?: boolean; @@ -53,13 +59,36 @@ export function FileTypeSelector({ disabledFeatures, mode = "full", selectedExt, - children, filename, makeNewFilename, filenameChanged, }: Props) { const intl = useIntl(); + const mainDivRef = useRef(null); + const [width, setWidth] = useState(0); + const btnWidth = Math.max(100, (width - 25) / 5); + + useEffect(() => { + const main = mainDivRef.current; + if (main == null) return; + const resizeObserver = new ResizeObserver( + throttle( + (entries) => { + if (entries.length > 0) { + setWidth(entries[0].contentRect.width); + } + }, + 10, + { leading: false, trailing: true }, + ), + ); + resizeObserver.observe(main); + return () => { + resizeObserver.disconnect(); + }; + }, []); + if (!create_file) { return null; } @@ -77,28 +106,47 @@ export function FileTypeSelector({ const doubleSm = isFlyout ? 24 : base(4); const y: Gutter = isFlyout ? 15 : 30; const gutter: [Gutter, Gutter] = [20, y / 2]; - const newRowStyle = { marginTop: `${y}px` }; + const newRowStyle: CSS = { marginTop: `${y}px` } as const; function btnActive(ext: string): boolean { if (!isFlyout) return false; return ext === selectedExt; } - function renderJupyterNotebook() { - if ( - !availableFeatures.jupyter_notebook && - !availableFeatures.sage && - !availableFeatures.latex - ) { - return; - } + function wrapBtn(btn: ReactNode) { + //return {btn} + return ( +
+ {btn} +
+ ); + } + function makeRow(btns: ReactNode) { + // + return ( + // + // {btns} + // + + {btns} + + ); + } + + function renderPopular() { return ( <>
Popular
- + {makeRow( - + />, + )} ); } function renderLinuxTerminal() { - return ( - - - - - + return wrapBtn( + + + , ); } function renderX11() { if (!availableFeatures.x11) return null; - return ( - - - - - + return wrapBtn( + + + , ); } function renderUtilities() { if (disabledFeatures?.linux) return; + return ( <>
Utilities
- - {renderChat()} - {renderX11()} - {renderStopwatchTimer()} - {renderTaskList()} - - {children} - - + {makeRow( + <> + {renderChat()} + {renderX11()} + {renderStopwatchTimer()} + {renderTaskList()} + {/* {children} */} + , + )} ); } @@ -256,76 +301,72 @@ export function FileTypeSelector({ "short label on a button to create a course management environment", }); - return ( - - documentation to learn more.`} - values={{ - A: (c) => ( - - {c} - - ), - }} - /> - } - > - ( + + {c} + + ), + }} /> - - + } + > + + , ); } function renderChat() { if (disabledFeatures?.chat) return; - return ( - - documentation to learn more.`} - values={{ - A: (c) => {c}, - }} - /> - } - > - {c}, + }} /> - - + } + > + + , ); } @@ -356,27 +397,25 @@ export function FileTypeSelector({ }); } - return ( - - - - - + return wrapBtn( + + + , ); } @@ -436,14 +475,14 @@ export function FileTypeSelector({ } function addAiDocGenerate(btn, ext) { - return ( + return wrapBtn( + />, ); } @@ -497,70 +536,78 @@ export function FileTypeSelector({ ); } - function renderMiscellaneous() { - if (disabledFeatures?.md) return; + function renderWhiteboard() { + return wrapBtn( + + + , + ); + } + function renderSlides() { const labelSlides = intl.formatMessage({ id: "new.file-type-selector.slides.title", defaultMessage: "Slides", description: "Short label on a buton to create a new slideshow file", }); + return wrapBtn( + + + , + ); + } + + function renderMiscellaneous() { + if (disabledFeatures?.md) return; + return ( <>
Miscellaneous
- - {renderMarkdown()} - {renderRMarkdown()} - - - - - - - - - - - - {renderSageWS()} - + {makeRow( + <> + {renderMarkdown()} + {renderRMarkdown()} + {renderWhiteboard()} + {renderSlides()} + {renderSageWS()} + , + )} ); } @@ -573,27 +620,25 @@ export function FileTypeSelector({ defaultMessage: "Stopwatch and Timer", }); - return ( - - - - - + return wrapBtn( + + + , ); } @@ -603,33 +648,31 @@ export function FileTypeSelector({ defaultMessage: "Task List", }); - return ( - - - - - + return wrapBtn( + + + , ); } return ( -
- {renderJupyterNotebook()} +
+ {renderPopular()} {renderUtilities()} {renderMiscellaneous()} {renderServers()} diff --git a/src/packages/frontend/project/new/jupyter-buttons.tsx b/src/packages/frontend/project/new/jupyter-buttons.tsx index a6010da67b..3ad74ef11e 100644 --- a/src/packages/frontend/project/new/jupyter-buttons.tsx +++ b/src/packages/frontend/project/new/jupyter-buttons.tsx @@ -260,23 +260,24 @@ export function JupyterNotebookButtons({ btns.push({ lang, btn: ( - - handleClick(kernelName)} - ext={ext} - size={btnSize} - active={btnActive("ipynb-sagemath")} - // mode={isFlyout ? "secondary" : undefined} - /> - +
+ + handleClick(kernelName)} + ext={ext} + size={btnSize} + active={btnActive("ipynb-sagemath")} + // mode={isFlyout ? "secondary" : undefined} + /> + +
), }); } diff --git a/src/packages/frontend/project/new/new-file-page.tsx b/src/packages/frontend/project/new/new-file-page.tsx index ae2158bc1a..3be80853bf 100644 --- a/src/packages/frontend/project/new/new-file-page.tsx +++ b/src/packages/frontend/project/new/new-file-page.tsx @@ -6,13 +6,14 @@ import { Button, Input, Modal, Space } from "antd"; import { useEffect, useRef, useState } from "react"; import { defineMessage, FormattedMessage, useIntl } from "react-intl"; + import { default_filename } from "@cocalc/frontend/account"; import { Alert, Col, Row } from "@cocalc/frontend/antd-bootstrap"; import { filenameIcon } from "@cocalc/frontend/file-associations"; import { ProjectActions, useActions, - useRedux, + // useRedux, useTypedRedux, } from "@cocalc/frontend/app-framework"; import { @@ -29,13 +30,13 @@ import ComputeServer from "@cocalc/frontend/compute/inline"; import { FileUpload, UploadLink } from "@cocalc/frontend/file-upload"; import { labels } from "@cocalc/frontend/i18n"; import { special_filenames_with_no_extension } from "@cocalc/frontend/project-file"; -import { ProjectMap } from "@cocalc/frontend/todo-types"; +// import { ProjectMap } from "@cocalc/frontend/todo-types"; import { filename_extension, is_only_downloadable } from "@cocalc/util/misc"; import { COLORS } from "@cocalc/util/theme"; import { PathNavigator } from "../explorer/path-navigator"; import { useAvailableFeatures } from "../use-available-features"; import { FileTypeSelector } from "./file-type-selector"; -import { NewFileButton } from "./new-file-button"; +// import { NewFileButton } from "./new-file-button"; import { NewFileDropdown } from "./new-file-dropdown"; const CREATE_MSG = defineMessage({ @@ -84,15 +85,15 @@ export default function NewFilePage(props: Props) { { project_id }, "file_creation_error", ); - const downloading_file = useTypedRedux({ project_id }, "downloading_file"); - const project_map: ProjectMap | undefined = useRedux([ - "projects", - "project_map", - ]); - const get_total_project_quotas = useRedux([ - "projects", - "get_total_project_quotas", - ]); + // const downloading_file = useTypedRedux({ project_id }, "downloading_file"); + // const project_map: ProjectMap | undefined = useRedux([ + // "projects", + // "project_map", + // ]); + // const get_total_project_quotas = useRedux([ + // "projects", + // "get_total_project_quotas", + // ]); if (actions == null) { return ; @@ -164,16 +165,16 @@ export default function NewFilePage(props: Props) { ); } - function blocked() { - if (project_map == null) { - return ""; - } - if (get_total_project_quotas(project_id)?.network) { - return ""; - } else { - return " (access blocked -- see project settings)"; - } - } + // function blocked() { + // if (project_map == null) { + // return ""; + // } + // if (get_total_project_quotas(project_id)?.network) { + // return ""; + // } else { + // return " (access blocked -- see project settings)"; + // } + // } function createFolder() { getActions().create_folder({ @@ -506,8 +507,8 @@ export default function NewFilePage(props: Props) { availableFeatures={availableFeatures} filename={filename} filenameChanged={filenameChanged} - > - + {/* createFile()} loading={downloading_file} /> - - + */} {renderUpload()}