Skip to content

Commit a889e9e

Browse files
gschierclaude
andcommitted
feat(settings): add the HTTP version row to the settings editor
The UI half was lost to a stray git checkout while cleaning up formatter collateral before the first commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 888fd4e commit a889e9e

2 files changed

Lines changed: 129 additions & 105 deletions

File tree

apps/yaak-client/components/ModelSettingsEditor.tsx

Lines changed: 115 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import type {
22
Folder,
33
GrpcRequest,
44
HttpRequest,
5+
HttpVersion,
56
InheritedBoolSetting,
7+
InheritedHttpVersionSetting,
68
InheritedIntSetting,
79
WebsocketRequest,
810
Workspace,
@@ -13,6 +15,7 @@ import {
1315
modelSupportsSetting,
1416
type RequestSettingDefinition,
1517
SETTING_FOLLOW_REDIRECTS,
18+
SETTING_HTTP_VERSION,
1619
SETTING_REQUEST_MESSAGE_SIZE,
1720
SETTING_REQUEST_TIMEOUT,
1821
SETTING_SEND_COOKIES,
@@ -21,6 +24,7 @@ import {
2124
} from "../lib/requestSettings";
2225
import { Checkbox } from "./core/Checkbox";
2326
import { PlainInput } from "./core/PlainInput";
27+
import { Select } from "./core/Select";
2428
import {
2529
SettingOverrideRow,
2630
SettingRow,
@@ -38,37 +42,21 @@ interface Props {
3842
model: ModelWithSettings;
3943
}
4044

41-
type ModelWithSettings =
42-
| Workspace
43-
| Folder
44-
| HttpRequest
45-
| WebsocketRequest
46-
| GrpcRequest;
45+
type ModelWithSettings = Workspace | Folder | HttpRequest | WebsocketRequest | GrpcRequest;
4746
type ModelWithHttpSettings = Workspace | Folder | HttpRequest;
48-
type ModelWithTlsSettings =
49-
| Workspace
50-
| Folder
51-
| HttpRequest
52-
| WebsocketRequest
53-
| GrpcRequest;
54-
type ModelWithCookieSettings =
55-
| Workspace
56-
| Folder
57-
| HttpRequest
58-
| WebsocketRequest;
59-
type ModelWithMessageSizeSettings =
60-
| Workspace
61-
| Folder
62-
| WebsocketRequest
63-
| GrpcRequest;
47+
type ModelWithTlsSettings = Workspace | Folder | HttpRequest | WebsocketRequest | GrpcRequest;
48+
type ModelWithCookieSettings = Workspace | Folder | HttpRequest | WebsocketRequest;
49+
type ModelWithMessageSizeSettings = Workspace | Folder | WebsocketRequest | GrpcRequest;
6450
type BooleanSetting = boolean | InheritedBoolSetting;
6551
type IntegerSetting = number | InheritedIntSetting;
52+
type HttpVersionSetting = HttpVersion | InheritedHttpVersionSetting;
6653
type CookieSettingsPatch = {
6754
settingSendCookies?: ModelWithCookieSettings["settingSendCookies"];
6855
settingStoreCookies?: ModelWithCookieSettings["settingStoreCookies"];
6956
};
7057
type HttpSettingsPatch = {
7158
settingFollowRedirects?: ModelWithHttpSettings["settingFollowRedirects"];
59+
settingHttpVersion?: ModelWithHttpSettings["settingHttpVersion"];
7260
settingRequestTimeout?: ModelWithHttpSettings["settingRequestTimeout"];
7361
};
7462
type TlsSettingsPatch = {
@@ -78,10 +66,7 @@ type MessageSizeSettingsPatch = {
7866
settingRequestMessageSize?: ModelWithMessageSizeSettings["settingRequestMessageSize"];
7967
};
8068

81-
export function ModelSettingsEditor({
82-
model,
83-
showSectionTitles = false,
84-
}: Props) {
69+
export function ModelSettingsEditor({ model, showSectionTitles = false }: Props) {
8570
const ancestors = useModelAncestors(model);
8671
const supportsHttpSettings = modelSupportsHttpSettings(model);
8772
const supportsCookieSettings = modelSupportsCookieSettings(model);
@@ -154,12 +139,26 @@ export function ModelSettingsEditor({
154139
}
155140
/>
156141
)}
142+
{supportsHttpSettings && (
143+
<HttpVersionSettingRow
144+
settingDefinition={SETTING_HTTP_VERSION}
145+
setting={model.settingHttpVersion}
146+
inheritedValue={resolveInheritedValue(
147+
ancestors,
148+
SETTING_HTTP_VERSION.modelKey,
149+
model.settingHttpVersion,
150+
)}
151+
onChange={(settingHttpVersion) =>
152+
patchHttpSettings(model, {
153+
settingHttpVersion,
154+
})
155+
}
156+
/>
157+
)}
157158
</SettingsSection>
158159
)}
159160
{supportsCookieSettings && (
160-
<SettingsSection
161-
title={supportsTlsSettings || showSectionTitles ? "Cookies" : null}
162-
>
161+
<SettingsSection title={supportsTlsSettings || showSectionTitles ? "Cookies" : null}>
163162
<BooleanSettingRow
164163
settingDefinition={SETTING_SEND_COOKIES}
165164
setting={model.settingSendCookies}
@@ -195,7 +194,7 @@ export function ModelSettingsEditor({
195194
}
196195

197196
export function countOverriddenSettings(model: ModelWithSettings) {
198-
const settings: (BooleanSetting | IntegerSetting)[] = [];
197+
const settings: (BooleanSetting | IntegerSetting | HttpVersionSetting)[] = [];
199198

200199
if (modelSupportsCookieSettings(model)) {
201200
settings.push(model.settingSendCookies, model.settingStoreCookies);
@@ -204,22 +203,22 @@ export function countOverriddenSettings(model: ModelWithSettings) {
204203
settings.push(model.settingValidateCertificates);
205204

206205
if (modelSupportsHttpSettings(model)) {
207-
settings.push(model.settingFollowRedirects, model.settingRequestTimeout);
206+
settings.push(
207+
model.settingFollowRedirects,
208+
model.settingRequestTimeout,
209+
model.settingHttpVersion,
210+
);
208211
}
209212

210213
if (modelSupportsMessageSizeSettings(model)) {
211214
settings.push(model.settingRequestMessageSize);
212215
}
213216

214-
return settings.filter(
215-
(setting) => isInheritedSetting(setting) && setting.enabled === true,
216-
).length;
217+
return settings.filter((setting) => isInheritedSetting(setting) && setting.enabled === true)
218+
.length;
217219
}
218220

219-
function patchCookieSettings(
220-
model: ModelWithCookieSettings,
221-
patch: Partial<CookieSettingsPatch>,
222-
) {
221+
function patchCookieSettings(model: ModelWithCookieSettings, patch: Partial<CookieSettingsPatch>) {
223222
switch (model.model) {
224223
case "workspace":
225224
return patchModel(model, patch as Partial<Workspace>);
@@ -232,10 +231,7 @@ function patchCookieSettings(
232231
}
233232
}
234233

235-
function patchHttpSettings(
236-
model: ModelWithHttpSettings,
237-
patch: Partial<HttpSettingsPatch>,
238-
) {
234+
function patchHttpSettings(model: ModelWithHttpSettings, patch: Partial<HttpSettingsPatch>) {
239235
switch (model.model) {
240236
case "workspace":
241237
return patchModel(model, patch as Partial<Workspace>);
@@ -246,10 +242,7 @@ function patchHttpSettings(
246242
}
247243
}
248244

249-
function patchTlsSettings(
250-
model: ModelWithTlsSettings,
251-
patch: Partial<TlsSettingsPatch>,
252-
) {
245+
function patchTlsSettings(model: ModelWithTlsSettings, patch: Partial<TlsSettingsPatch>) {
253246
switch (model.model) {
254247
case "workspace":
255248
return patchModel(model, patch as Partial<Workspace>);
@@ -280,21 +273,15 @@ function patchMessageSizeSettings(
280273
}
281274
}
282275

283-
function modelSupportsHttpSettings(
284-
model: ModelWithSettings,
285-
): model is ModelWithHttpSettings {
276+
function modelSupportsHttpSettings(model: ModelWithSettings): model is ModelWithHttpSettings {
286277
return modelSupportsSetting(model, SETTING_REQUEST_TIMEOUT);
287278
}
288279

289-
function modelSupportsCookieSettings(
290-
model: ModelWithSettings,
291-
): model is ModelWithCookieSettings {
280+
function modelSupportsCookieSettings(model: ModelWithSettings): model is ModelWithCookieSettings {
292281
return modelSupportsSetting(model, SETTING_SEND_COOKIES);
293282
}
294283

295-
function modelSupportsTlsSettings(
296-
model: ModelWithSettings,
297-
): model is ModelWithTlsSettings {
284+
function modelSupportsTlsSettings(model: ModelWithSettings): model is ModelWithTlsSettings {
298285
return modelSupportsSetting(model, SETTING_VALIDATE_CERTIFICATES);
299286
}
300287

@@ -317,11 +304,7 @@ function BooleanSettingRow({
317304
}) {
318305
const inherited = isInheritedSetting(setting);
319306
const overridden = inherited ? setting.enabled === true : false;
320-
const value = inherited
321-
? overridden
322-
? setting.value
323-
: inheritedValue
324-
: setting;
307+
const value = inherited ? (overridden ? setting.value : inheritedValue) : setting;
325308

326309
if (!inherited) {
327310
return (
@@ -352,6 +335,63 @@ function BooleanSettingRow({
352335
);
353336
}
354337

338+
const HTTP_VERSION_OPTIONS: { label: string; value: HttpVersion }[] = [
339+
{ label: "Automatic", value: "auto" },
340+
{ label: "HTTP/1.1", value: "http1" },
341+
{ label: "HTTP/2", value: "http2" },
342+
];
343+
344+
function HttpVersionSettingRow({
345+
inheritedValue,
346+
setting,
347+
settingDefinition,
348+
onChange,
349+
}: {
350+
inheritedValue: HttpVersion;
351+
setting: HttpVersionSetting;
352+
settingDefinition: RequestSettingDefinition<"settingHttpVersion">;
353+
onChange: (setting: HttpVersionSetting) => void;
354+
}) {
355+
const inherited = isInheritedSetting(setting);
356+
const overridden = inherited ? setting.enabled === true : false;
357+
const value = inherited ? (overridden ? setting.value : inheritedValue) : setting;
358+
359+
if (!inherited) {
360+
return (
361+
<SettingRow title={settingDefinition.title} description={settingDefinition.description}>
362+
<Select
363+
hideLabel
364+
name={settingDefinition.modelKey}
365+
label={settingDefinition.title}
366+
size="sm"
367+
value={value}
368+
options={HTTP_VERSION_OPTIONS}
369+
onChange={(value) => onChange(value)}
370+
/>
371+
</SettingRow>
372+
);
373+
}
374+
375+
return (
376+
<SettingOverrideRow
377+
title={settingDefinition.title}
378+
description={settingDefinition.description}
379+
overridden={overridden}
380+
onResetOverride={() => onChange({ ...setting, enabled: false })}
381+
>
382+
<Select
383+
hideLabel
384+
name={settingDefinition.modelKey}
385+
label={settingDefinition.title}
386+
size="sm"
387+
value={value}
388+
options={HTTP_VERSION_OPTIONS}
389+
onChange={(value) => onChange({ ...setting, enabled: true, value })}
390+
/>
391+
</SettingOverrideRow>
392+
);
393+
}
394+
355395
function IntegerSettingRow({
356396
inheritedValue,
357397
setting,
@@ -365,18 +405,11 @@ function IntegerSettingRow({
365405
}) {
366406
const inherited = isInheritedSetting(setting);
367407
const overridden = inherited ? setting.enabled === true : false;
368-
const value = inherited
369-
? overridden
370-
? setting.value
371-
: inheritedValue
372-
: setting;
408+
const value = inherited ? (overridden ? setting.value : inheritedValue) : setting;
373409

374410
if (!inherited) {
375411
return (
376-
<SettingRow
377-
title={settingDefinition.title}
378-
description={settingDefinition.description}
379-
>
412+
<SettingRow title={settingDefinition.title} description={settingDefinition.description}>
380413
<NumberUnitInput
381414
name={settingDefinition.modelKey}
382415
label={settingDefinition.title}
@@ -429,20 +462,13 @@ function MessageSizeSettingRow({
429462
}) {
430463
const inherited = isInheritedSetting(setting);
431464
const overridden = inherited ? setting.enabled === true : false;
432-
const value = inherited
433-
? overridden
434-
? setting.value
435-
: inheritedValue
436-
: setting;
465+
const value = inherited ? (overridden ? setting.value : inheritedValue) : setting;
437466
const displayValue = formatMegabytes(value);
438467
const placeholder = "0";
439468

440469
if (!inherited) {
441470
return (
442-
<SettingRow
443-
title={settingDefinition.title}
444-
description={settingDefinition.description}
445-
>
471+
<SettingRow title={settingDefinition.title} description={settingDefinition.description}>
446472
<MessageSizeInput
447473
name={settingDefinition.modelKey}
448474
label={settingDefinition.title}
@@ -567,13 +593,18 @@ function resolveInheritedValue(
567593
key: BooleanWorkspaceSettingKey,
568594
fallback: BooleanSetting,
569595
): boolean;
596+
function resolveInheritedValue(
597+
ancestors: (Folder | Workspace)[],
598+
key: "settingHttpVersion",
599+
fallback: HttpVersionSetting,
600+
): HttpVersion;
570601
function resolveInheritedValue(
571602
ancestors: (Folder | Workspace)[],
572603
key: keyof WorkspaceSettings,
573-
fallback: BooleanSetting | IntegerSetting,
604+
fallback: BooleanSetting | IntegerSetting | HttpVersionSetting,
574605
) {
575606
for (const ancestor of ancestors) {
576-
const setting = ancestor[key] as BooleanSetting | IntegerSetting;
607+
const setting = ancestor[key] as BooleanSetting | IntegerSetting | HttpVersionSetting;
577608
if (isInheritedSetting(setting)) {
578609
if (setting.enabled === true) {
579610
return setting.value;
@@ -589,6 +620,7 @@ function resolveInheritedValue(
589620
type WorkspaceSettings = Pick<
590621
Workspace,
591622
| "settingFollowRedirects"
623+
| "settingHttpVersion"
592624
| "settingRequestMessageSize"
593625
| "settingRequestTimeout"
594626
| "settingSendCookies"
@@ -598,14 +630,12 @@ type WorkspaceSettings = Pick<
598630

599631
type BooleanWorkspaceSettingKey = Exclude<
600632
keyof WorkspaceSettings,
601-
"settingRequestTimeout" | "settingRequestMessageSize"
633+
"settingRequestTimeout" | "settingRequestMessageSize" | "settingHttpVersion"
602634
>;
603635

604636
function formatMegabytes(bytes: number) {
605637
const megabytes = bytes / BYTES_PER_MB;
606-
return Number.isInteger(megabytes)
607-
? `${megabytes}`
608-
: megabytes.toFixed(3).replace(/\.?0+$/, "");
638+
return Number.isInteger(megabytes) ? `${megabytes}` : megabytes.toFixed(3).replace(/\.?0+$/, "");
609639
}
610640

611641
function parseMegabytes(value: string) {
@@ -626,9 +656,5 @@ function isValidInteger(value: string) {
626656
function isValidMegabytes(value: string) {
627657
if (value === "") return true;
628658
const megabytes = Number(value);
629-
return (
630-
Number.isFinite(megabytes) &&
631-
megabytes >= 0 &&
632-
megabytes <= MAX_MESSAGE_SIZE_MB
633-
);
659+
return Number.isFinite(megabytes) && megabytes >= 0 && megabytes <= MAX_MESSAGE_SIZE_MB;
634660
}

0 commit comments

Comments
 (0)