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-inner.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Input, Select } from "antd";6import { CSSProperties } from "react";78import { LanguageModelVendorAvatar } from "@cocalc/frontend/components/language-model-icon";9import Password, {10PasswordTextArea,11} from "@cocalc/frontend/components/password";12import { modelToName } from "@cocalc/frontend/frame-editors/llm/llm-selector";13import { LOCALIZATIONS } from "@cocalc/frontend/i18n";14import { LOCALE } from "@cocalc/util/consts/locale";15import { USER_SELECTABLE_LANGUAGE_MODELS } from "@cocalc/util/db-schema/llm-utils";16import {17ConfigValid,18to_list_of_llms,19to_list_of_locale,20} from "@cocalc/util/db-schema/site-defaults";21import { RowEntryInnerProps } from "./row-entry";2223export function testIsInvalid(value, valid?: ConfigValid): boolean {24return (25(Array.isArray(valid) && !valid.includes(value)) ||26(typeof valid == "function" && !valid(value))27);28}2930export function rowEntryStyle(value, valid?: ConfigValid): CSSProperties {31if (testIsInvalid(value, valid)) {32return { border: "2px solid red" };33}34return {};35}3637export function RowEntryInner({38name,39value,40valid,41password,42multiline,43onChangeEntry,44isReadonly,45clearable,46update,47}: RowEntryInnerProps) {48if (isReadonly == null) return null; // typescript49const disabled = isReadonly[name] == true;5051if (name === "selectable_llms") {52return (53<Select54mode="multiple"55style={{ width: "100%" }}56placeholder="Select user selectable LLMs"57optionLabelProp="label"58defaultValue={to_list_of_llms(value, false)}59onChange={(value: Array<string>) => {60onChangeEntry(name, value.join(","));61update();62}}63options={USER_SELECTABLE_LANGUAGE_MODELS.map((model) => {64return { label: modelToName(model), value: model };65})}66optionRender={(option) => (67<>68<LanguageModelVendorAvatar model={(option.value as string) ?? ""} />{" "}69{option.label}70</>71)}72/>73);74} else if (name === "i18n") {75return (76<Select77mode="multiple"78style={{ width: "100%" }}79placeholder="Select user selectable language locale"80optionLabelProp="label"81defaultValue={to_list_of_locale(value, false)}82onChange={(value: Array<string>) => {83onChangeEntry(name, value.join(","));84update();85}}86options={LOCALE.map((l) => {87return { label: LOCALIZATIONS[l].name, value: l };88})}89optionRender={(option) => (90<>91{option.value ? LOCALIZATIONS[option.value].flag : ""}{" "}92{option.label}93</>94)}95/>96);97} else if (Array.isArray(valid)) {98return (99<Select100defaultValue={value}101disabled={disabled}102onChange={(value) => {103// should never happen, because this is not a "multiple" Select104if (Array.isArray(value)) {105console.warn(`Got array value for ${name}: ${value}`);106return;107}108onChangeEntry(name, value);109update();110}}111style={{ width: "100%" }}112options={valid.map((value) => {113const label = name === "default_llm" ? modelToName(value) : value;114return { value, label };115})}116/>117);118} else {119if (password) {120if (multiline != null) {121return (122<PasswordTextArea123rows={multiline}124autoComplete="off"125style={rowEntryStyle(value, valid)}126defaultValue={value}127visibilityToggle={true}128disabled={disabled}129onChange={(e) => onChangeEntry(name, e.target.value)}130/>131);132} else {133return (134<Password135autoComplete="off"136style={rowEntryStyle(value, valid)}137defaultValue={value}138visibilityToggle={true}139disabled={disabled}140onChange={(e) => onChangeEntry(name, e.target.value)}141/>142);143}144} else {145if (multiline != null) {146const style = {147...rowEntryStyle(value, valid),148fontFamily: "monospace",149fontSize: "80%",150} as CSSProperties;151return (152<Input.TextArea153autoComplete="off"154rows={multiline}155style={style}156defaultValue={value}157disabled={disabled}158onChange={(e) => onChangeEntry(name, e.target.value)}159/>160);161} else {162return (163<Input164autoComplete="off"165style={rowEntryStyle(value, valid)}166defaultValue={value}167disabled={disabled}168onChange={(e) => onChangeEntry(name, e.target.value)}169allowClear={clearable}170/>171);172}173}174}175}176177178