Path: blob/master/src/packages/frontend/admin/site-settings/row-entry-inner.tsx
1496 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Input, Select, Switch } from "antd";6import { CSSProperties } from "react";7import { isEqual } from "lodash";8import { 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 (isEqual(valid, ["yes", "no"])) {98return (99<Switch100defaultChecked={value == "yes"}101checkedChildren="yes"102unCheckedChildren="no"103onChange={(checked) => {104onChangeEntry(name, checked ? "yes" : "no");105update();106}}107/>108);109} else if (Array.isArray(valid)) {110return (111<Select112defaultValue={value}113disabled={disabled}114onChange={(value) => {115// should never happen, because this is not a "multiple" Select116if (Array.isArray(value)) {117console.warn(`Got array value for ${name}: ${value}`);118return;119}120onChangeEntry(name, value);121update();122}}123style={{ width: "100%" }}124options={valid.map((value) => {125const label = name === "default_llm" ? modelToName(value) : value;126return { value, label };127})}128/>129);130} else {131if (password) {132if (multiline != null) {133return (134<PasswordTextArea135rows={multiline}136autoComplete="off"137style={rowEntryStyle(value, valid)}138defaultValue={value}139visibilityToggle={true}140disabled={disabled}141onChange={(e) => onChangeEntry(name, e.target.value)}142/>143);144} else {145return (146<Password147autoComplete="off"148style={rowEntryStyle(value, valid)}149defaultValue={value}150visibilityToggle={true}151disabled={disabled}152onChange={(e) => onChangeEntry(name, e.target.value)}153/>154);155}156} else {157if (multiline != null) {158const style = {159...rowEntryStyle(value, valid),160fontFamily: "monospace",161fontSize: "80%",162} as CSSProperties;163return (164<Input.TextArea165autoComplete="off"166rows={multiline}167style={style}168defaultValue={value}169disabled={disabled}170onChange={(e) => onChangeEntry(name, e.target.value)}171/>172);173} else {174return (175<Input176autoComplete="off"177style={rowEntryStyle(value, valid)}178defaultValue={value}179disabled={disabled}180onChange={(e) => onChangeEntry(name, e.target.value)}181allowClear={clearable}182/>183);184}185}186}187}188189190