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/admin/site-settings/render-row.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Alert, Button, Popover } from "antd";6import { CSSProperties } from "react";7import { Icon, LabeledRow, Markdown } from "@cocalc/frontend/components";8import StaticMarkdown from "@cocalc/frontend/editors/slate/static-markdown";9import { Config, RowType, Tag } from "@cocalc/util/db-schema/site-defaults";10import { COLORS } from "@cocalc/util/theme";11import { Data, IsReadonly } from "./types";12import { RowEntry } from "./row-entry";13import { RefreshImagesButton } from "@cocalc/frontend/compute/select-version";1415interface RenderRowProps {16name: string;17conf: Config;18data: Data | null;19update: () => void;20isReadonly: IsReadonly | null;21onChangeEntry: (name: string, value: string) => void;22onJsonEntryChange: (name: string, value: string) => void;23filterStr: string;24filterTag: Tag | null;25isModified: (name: string) => boolean;26isHeader: boolean;27saveSingleSetting: (name: string) => void;28}2930export function RenderRow({31name,32conf,33data,34update,35isReadonly,36onChangeEntry,37onJsonEntryChange,38filterStr,39filterTag,40isModified,41isHeader,42saveSingleSetting,43}: RenderRowProps) {44if (data == null) return null;4546// if tags are used, we're strictly filtering by them47if (filterTag) {48if (!conf.tags) return null;49if (!conf.tags.includes(filterTag)) {50return null;51}52}53// otherwise we're (additionally) filtering by the search string54if (filterStr) {55const { tags, name: title, desc } = conf;56const f = filterStr.toLowerCase();57const match_any_tag = tags && tags.includes(f as any);58const x = [name, title, desc]59.join(" ")60.toLowerCase()61.replace(/-/g, " ")62.replace(/_/g, " ");63if (!x.includes(f) && !match_any_tag) {64return null;65}66}67if (conf.cocalc_only) {68if (!document.location.host.endsWith("cocalc.com")) {69return null;70}71}72// don't show certain fields, i.e. where show evals to false73if (typeof conf.show == "function" && !conf.show(data)) {74return null;75}7677const rawValue = data[name] ?? conf.default;78const rowType: RowType = conf.type ?? "setting";7980// fallbacks: to_display? → to_val? → undefined81const parsed_value: string | undefined =82typeof conf.to_display == "function"83? `${conf.to_display(rawValue)}`84: typeof conf.to_val == "function"85? `${conf.to_val(rawValue, data)}`86: undefined;8788// not currently supported.89// const clearable = conf.clearable ?? false;9091const label = (92<div style={{ paddingRight: "15px" }}>93<strong>{conf.name}</strong> <RowHelp help={conf.help} />94<br />95<StaticMarkdown style={{ color: COLORS.GRAY_M }} value={conf.desc} />96</div>97);9899const hint = <RowHint conf={conf} rawValue={rawValue} />;100101let style = { marginTop: "15px", paddingLeft: "10px" } as CSSProperties;102// indent optional fields103if (typeof conf.show == "function" && rowType == "setting") {104style = {105...style,106borderLeft: `2px solid ${COLORS.GRAY}`,107marginLeft: "0px",108marginTop: "0px",109} as CSSProperties;110}111112function renderRowExtra() {113if (isHeader) return null;114const modified = isModified(name);115return (116<Button117type={modified ? "primary" : "default"}118disabled={!modified}119size="middle"120icon={<Icon name="save" />}121onClick={() => saveSingleSetting(name)}122/>123);124}125126return (127<LabeledRow128label={label}129key={name}130style={style}131label_cols={6}132extra={renderRowExtra()}133>134<RowEntry135name={name}136value={rawValue}137password={conf.password ?? false}138displayed_val={parsed_value}139valid={conf.valid}140hint={hint}141rowType={rowType}142multiline={conf.multiline}143isReadonly={isReadonly}144onJsonEntryChange={onJsonEntryChange}145onChangeEntry={onChangeEntry}146clearable={conf.clearable}147update={update}148/>149{name == "compute_servers_images_spec_url" && (150<div>151<RefreshImagesButton />152<Alert153showIcon154style={{ margin: "15px" }}155type="info"156message="Click the above button after updating the images spec URL to clear the cache."157/>158</div>159)}160</LabeledRow>161);162}163164function RowHint({ conf, rawValue }: { conf: Config; rawValue: string }) {165if (typeof conf.hint == "function") {166return <Markdown value={conf.hint(rawValue)} />;167} else {168return null;169}170}171172function RowHelp({ help }: { help?: string }) {173if (typeof help !== "string") return null;174return (175<Popover176content={177<StaticMarkdown178className={"admin-site-setting-popover-help"}179style={{ fontSize: "90%" }}180value={help}181/>182}183trigger={["hover", "click"]}184placement="right"185overlayStyle={{ maxWidth: "500px" }}186>187<Icon style={{ color: COLORS.GRAY }} name="question-circle" />188</Popover>189);190}191192193