Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/admin/site-settings/row-entry-inner.tsx
1496 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { Input, Select, Switch } from "antd";
7
import { CSSProperties } from "react";
8
import { isEqual } from "lodash";
9
import { LanguageModelVendorAvatar } from "@cocalc/frontend/components/language-model-icon";
10
import Password, {
11
PasswordTextArea,
12
} from "@cocalc/frontend/components/password";
13
import { modelToName } from "@cocalc/frontend/frame-editors/llm/llm-selector";
14
import { LOCALIZATIONS } from "@cocalc/frontend/i18n";
15
import { LOCALE } from "@cocalc/util/consts/locale";
16
import { USER_SELECTABLE_LANGUAGE_MODELS } from "@cocalc/util/db-schema/llm-utils";
17
import {
18
ConfigValid,
19
to_list_of_llms,
20
to_list_of_locale,
21
} from "@cocalc/util/db-schema/site-defaults";
22
import { RowEntryInnerProps } from "./row-entry";
23
24
export function testIsInvalid(value, valid?: ConfigValid): boolean {
25
return (
26
(Array.isArray(valid) && !valid.includes(value)) ||
27
(typeof valid == "function" && !valid(value))
28
);
29
}
30
31
export function rowEntryStyle(value, valid?: ConfigValid): CSSProperties {
32
if (testIsInvalid(value, valid)) {
33
return { border: "2px solid red" };
34
}
35
return {};
36
}
37
38
export function RowEntryInner({
39
name,
40
value,
41
valid,
42
password,
43
multiline,
44
onChangeEntry,
45
isReadonly,
46
clearable,
47
update,
48
}: RowEntryInnerProps) {
49
if (isReadonly == null) return null; // typescript
50
const disabled = isReadonly[name] == true;
51
52
if (name === "selectable_llms") {
53
return (
54
<Select
55
mode="multiple"
56
style={{ width: "100%" }}
57
placeholder="Select user selectable LLMs"
58
optionLabelProp="label"
59
defaultValue={to_list_of_llms(value, false)}
60
onChange={(value: Array<string>) => {
61
onChangeEntry(name, value.join(","));
62
update();
63
}}
64
options={USER_SELECTABLE_LANGUAGE_MODELS.map((model) => {
65
return { label: modelToName(model), value: model };
66
})}
67
optionRender={(option) => (
68
<>
69
<LanguageModelVendorAvatar model={(option.value as string) ?? ""} />{" "}
70
{option.label}
71
</>
72
)}
73
/>
74
);
75
} else if (name === "i18n") {
76
return (
77
<Select
78
mode="multiple"
79
style={{ width: "100%" }}
80
placeholder="Select user selectable language locale"
81
optionLabelProp="label"
82
defaultValue={to_list_of_locale(value, false)}
83
onChange={(value: Array<string>) => {
84
onChangeEntry(name, value.join(","));
85
update();
86
}}
87
options={LOCALE.map((l) => {
88
return { label: LOCALIZATIONS[l].name, value: l };
89
})}
90
optionRender={(option) => (
91
<>
92
{option.value ? LOCALIZATIONS[option.value].flag : ""}{" "}
93
{option.label}
94
</>
95
)}
96
/>
97
);
98
} else if (isEqual(valid, ["yes", "no"])) {
99
return (
100
<Switch
101
defaultChecked={value == "yes"}
102
checkedChildren="yes"
103
unCheckedChildren="no"
104
onChange={(checked) => {
105
onChangeEntry(name, checked ? "yes" : "no");
106
update();
107
}}
108
/>
109
);
110
} else if (Array.isArray(valid)) {
111
return (
112
<Select
113
defaultValue={value}
114
disabled={disabled}
115
onChange={(value) => {
116
// should never happen, because this is not a "multiple" Select
117
if (Array.isArray(value)) {
118
console.warn(`Got array value for ${name}: ${value}`);
119
return;
120
}
121
onChangeEntry(name, value);
122
update();
123
}}
124
style={{ width: "100%" }}
125
options={valid.map((value) => {
126
const label = name === "default_llm" ? modelToName(value) : value;
127
return { value, label };
128
})}
129
/>
130
);
131
} else {
132
if (password) {
133
if (multiline != null) {
134
return (
135
<PasswordTextArea
136
rows={multiline}
137
autoComplete="off"
138
style={rowEntryStyle(value, valid)}
139
defaultValue={value}
140
visibilityToggle={true}
141
disabled={disabled}
142
onChange={(e) => onChangeEntry(name, e.target.value)}
143
/>
144
);
145
} else {
146
return (
147
<Password
148
autoComplete="off"
149
style={rowEntryStyle(value, valid)}
150
defaultValue={value}
151
visibilityToggle={true}
152
disabled={disabled}
153
onChange={(e) => onChangeEntry(name, e.target.value)}
154
/>
155
);
156
}
157
} else {
158
if (multiline != null) {
159
const style = {
160
...rowEntryStyle(value, valid),
161
fontFamily: "monospace",
162
fontSize: "80%",
163
} as CSSProperties;
164
return (
165
<Input.TextArea
166
autoComplete="off"
167
rows={multiline}
168
style={style}
169
defaultValue={value}
170
disabled={disabled}
171
onChange={(e) => onChangeEntry(name, e.target.value)}
172
/>
173
);
174
} else {
175
return (
176
<Input
177
autoComplete="off"
178
style={rowEntryStyle(value, valid)}
179
defaultValue={value}
180
disabled={disabled}
181
onChange={(e) => onChangeEntry(name, e.target.value)}
182
allowClear={clearable}
183
/>
184
);
185
}
186
}
187
}
188
}
189
190