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/next/components/statistics/opened-files.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2021 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Switch, Table } from "antd";6import { useMemo, useState } from "react";78import { Icon } from "@cocalc/frontend/components/icon";9import { file_associations } from "@cocalc/frontend/file-associations";10import { cmp, field_cmp } from "@cocalc/util/cmp";11import { Stats } from "@cocalc/util/db-schema/stats";12import { Paragraph, Title } from "components/misc";13import A from "components/misc/A";1415const openedFilesColumns = [16{17title: "Type of File",18dataIndex: "ext",19key: "ext",20render: (ext) => {21const icon = (22<Icon23style={{ marginRight: "10px", fontSize: "14pt" }}24name={file_associations[ext]?.icon ?? file_associations[""]?.icon}25/>26);27const info = extensionToInfo[ext];28if (info == null)29return (30<>31{icon} {ext}32</>33);34const x = (35<>36{icon} {info.desc} (.{ext})37</>38);39if (info.link == null) return x;40return <A href={info.link}>{x}</A>;41},42sorter: (a, b) =>43cmp(44extensionToInfo[a.ext]?.desc ?? a.ext,45extensionToInfo[b.ext]?.desc ?? b.ext,46),47},48{49title: "Hour",50dataIndex: "1h",51key: "1h",52sorter: field_cmp("1h"),53defaultSortOrder: "descend" as any,54},55{ title: "Day", dataIndex: "1d", key: "1d", sorter: field_cmp("1d") },56{ title: "Week", dataIndex: "7d", key: "7d", sorter: field_cmp("7d") },57{58title: "Month",59dataIndex: "30d",60key: "30d",61sorter: field_cmp("30d"),62},63];6465const extensionToInfo: { [ext: string]: { desc: string; link?: string } } = {66md: { desc: "Markdown" },67py: { desc: "Python", link: "/features/python" },68jpg: { desc: "Image" },69pdf: { desc: "PDF" },70png: { desc: "Image" },71rmd: { desc: "RMarkdown", link: "/features/r" },72rnw: { desc: "Knitr" },73rst: { desc: "ReST" },74svg: { desc: "Image" },75tex: { desc: "LaTeX", link: "/features/latex-editor" },76txt: { desc: "Plain Text" },77x11: { desc: "X11 Linux Desktop", link: "/features/x11" },78jpeg: { desc: "Image" },79lean: { desc: "LEAN theorem prover" },80rtex: { desc: "Knitr" },81sage: {82desc: "SageMath",83link: "https://www.sagemath.org/",84},85term: { desc: "Linux Terminal", link: "/features/terminal" },86ipynb: { desc: "Jupyter Notebook", link: "/features/jupyter-notebook" },87tasks: { desc: "Task List", link: "https://doc.cocalc.com/tasks.html" },88course: {89desc: "Course Management",90link: "https://doc.cocalc.com/teaching-instructors.html",91},92sagews: {93desc: "Sage Worksheet",94link: "https://doc.cocalc.com/sagews.html",95},96"sage-chat": { desc: "Chatroom" },97board: { desc: "Whiteboard", link: "/features/whiteboard" },98slides: { desc: "Slides", link: "/features/slides" },99} as const;100101function processFilesOpened(102filesOpened,103distinct: boolean,104): {105rows: {106ext: string;107"1h": number;108"1d": number;109"7d": number;110"30d": number;111}[];112lastHour: number;113} {114let lastHour = 0;115const counts = distinct ? filesOpened.distinct : filesOpened.total;116const byExtension: {117[ext: string]: {118"1h": number;119"1d": number;120"7d": number;121"30d": number;122};123} = {};124125for (const time in counts) {126const extToCount = counts[time];127for (const ext in extToCount) {128const cnt = parseInt(extToCount[ext]);129if (byExtension[ext] == null) {130byExtension[ext] = { "1h": 0, "1d": 0, "7d": 0, "30d": 0 };131}132byExtension[ext][time] += cnt;133if (time == "1h") {134lastHour += cnt;135}136}137}138139const rows: {140ext: string;141"1h": number;142"1d": number;143"7d": number;144"30d": number;145}[] = [];146for (const ext in byExtension) {147const counts = byExtension[ext];148rows.push({ ext, ...counts });149}150return { rows, lastHour };151}152153export default function OpenedFiles({154filesOpened,155style,156}: {157filesOpened: Stats["files_opened"];158style?: React.CSSProperties;159}) {160const [distinct, setDistinct] = useState<boolean>(true);161const { rows, lastHour } = useMemo(162() => processFilesOpened(filesOpened, distinct),163[distinct, filesOpened],164);165166return (167<div style={style}>168<Paragraph style={{ float: "right" }}>169<Switch checked={distinct} onChange={setDistinct} /> Distinct170</Paragraph>171<Title level={2}>172{distinct ? "Distinct " : ""}Files Used in the Last Hour: {lastHour}{" "}173</Title>174<Paragraph>175Track the number of {distinct ? "distinct" : ""} files of each type that176people opened during the last hour, day, week and month.177</Paragraph>178<Table179dataSource={rows}180columns={openedFilesColumns}181bordered182pagination={false}183rowKey={"ext"}184/>185</div>186);187}188189190