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/row-entry.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import humanizeList from "humanize-list";6import { CopyToClipBoard } from "@cocalc/frontend/components";7import { SERVER_SETTINGS_ENV_PREFIX } from "@cocalc/util/consts";8import { ConfigValid, RowType } from "@cocalc/util/db-schema/site-defaults";9import { version } from "@cocalc/util/smc-version";10import { ON_PREM_DEFAULT_QUOTAS, upgrades } from "@cocalc/util/upgrade-spec";11import { JsonEditor } from "../json-editor";12import { RowEntryInner, testIsInvalid } from "./row-entry-inner";13import { IsReadonly } from "./types";1415const MAX_UPGRADES = upgrades.max_per_project;1617const FIELD_DEFAULTS = {18default_quotas: ON_PREM_DEFAULT_QUOTAS,19max_upgrades: MAX_UPGRADES,20} as const;2122export interface RowEntryInnerProps {23name: string;24value: string; // value is the rawValue (a string)25valid?: ConfigValid;26password: boolean;27multiline?: number;28isReadonly: IsReadonly | null;29onChangeEntry: (name: string, value: string) => void;30clearable?: boolean;31update: () => void;32}3334interface RowEntryProps extends RowEntryInnerProps {35displayed_val?: string; // the processed rawValue36hint?: JSX.Element;37rowType?: RowType;38onJsonEntryChange: (name: string, value?: string) => void;39onChangeEntry: (name: string, value: string) => void;40}4142export function RowEntry({43name,44value,45password,46displayed_val,47valid,48hint,49rowType,50multiline,51isReadonly,52onJsonEntryChange,53onChangeEntry,54clearable,55update,56}: RowEntryProps) {57if (isReadonly == null) return null; // typescript5859function ReadOnly({ readonly }) {60if (readonly) {61return (62<>63Value controlled via{" "}64<code>65${SERVER_SETTINGS_ENV_PREFIX}_{name.toUpperCase()}66</code>67.68</>69);70} else {71return null;72}73}7475if (rowType == "header") {76return <div />;77} else {78switch (name) {79case "default_quotas":80case "max_upgrades":81const ro: boolean = isReadonly[name];82return (83<>84<JsonEntry85name={name}86data={value}87readonly={ro}88onJsonEntryChange={onJsonEntryChange}89/>90<ReadOnly readonly={ro} />91</>92);93default:94const is_valid = !testIsInvalid(value, valid);95return (96<div>97<RowEntryInner98name={name}99value={value}100valid={valid}101password={password}102multiline={multiline}103onChangeEntry={onChangeEntry}104isReadonly={isReadonly}105clearable={clearable}106update={update}107/>108<div style={{ fontSize: "90%", display: "inlineBlock" }}>109{!Array.isArray(value) &&110name === "version_recommended_browser" ? (111<VersionHint value={value} />112) : undefined}113{hint}114<ReadOnly readonly={isReadonly[name]} />115{displayed_val != null && (116<span>117{" "}118{is_valid ? "Interpreted as" : "Invalid:"}{" "}119<code>{displayed_val}</code>.{" "}120</span>121)}122{valid != null && Array.isArray(valid) && (123<span>Valid values: {humanizeList(valid)}.</span>124)}125</div>126</div>127);128}129}130}131132function VersionHint({ value }: { value: string }) {133let error;134if (new Date(parseInt(value) * 1000) > new Date()) {135error = (136<div137style={{138background: "red",139color: "white",140margin: "15px",141padding: "15px",142}}143>144INVALID version - it is in the future!!145</div>146);147} else {148error = undefined;149}150return (151<div style={{ marginTop: "15px", color: "#666" }}>152Your browser version:{" "}153<CopyToClipBoard154style={{155display: "inline-block",156width: "50ex",157margin: 0,158}}159value={`${version}`}160/>{" "}161{error}162</div>163);164}165166// This is specific to on-premises kubernetes setups.167// The production site works differently.168// TODO: make this a more sophisticated data editor.169function JsonEntry({ name, data, readonly, onJsonEntryChange }) {170const jval = JSON.parse(data ?? "{}") ?? {};171const dflt = FIELD_DEFAULTS[name];172const quotas = { ...dflt, ...jval };173const value = JSON.stringify(quotas);174return (175<JsonEditor176value={value}177readonly={readonly}178rows={10}179onSave={(value) => onJsonEntryChange(name, value)}180/>181);182}183184185