Path: blob/main/components/dashboard/src/teams/policies/EditorOptions.tsx
2501 views
/**1* Copyright (c) 2025 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { OrganizationSettings } from "@gitpod/public-api/lib/gitpod/v1/organization_pb";7import { Button } from "@podkit/buttons/Button";8import { useMutation } from "@tanstack/react-query";9import { useState } from "react";10import { IdeOptionsModifyModalProps, IdeOptions, IdeOptionsModifyModal } from "../../components/IdeOptions";11import { Heading3, Subheading } from "../../components/typography/headings";12import { useAllowedWorkspaceEditorsMemo } from "../../data/ide-options/ide-options-query";13import { ConfigurationSettingsField } from "../../repositories/detail/ConfigurationSettingsField";1415type Props = {16settings: OrganizationSettings | undefined;17isOwner: boolean;18handleUpdateTeamSettings: (19newSettings: Partial<OrganizationSettings>,20options?: { throwMutateError?: boolean },21) => Promise<void>;22};23export const EditorOptions = ({ isOwner, settings, handleUpdateTeamSettings }: Props) => {24const [showModal, setShowModal] = useState(false);25const { data: installationOptions, isLoading: installationOptionsIsLoading } = useAllowedWorkspaceEditorsMemo(26undefined,27{28filterOutDisabled: true,29ignoreScope: ["organization", "configuration"],30},31);32const { data: orgOptions, isLoading: orgOptionsIsLoading } = useAllowedWorkspaceEditorsMemo(undefined, {33filterOutDisabled: true,34ignoreScope: ["configuration"],35});3637const updateMutation: IdeOptionsModifyModalProps["updateMutation"] = useMutation({38mutationFn: async ({ restrictedEditors, pinnedEditorVersions }) => {39const updatedRestrictedEditors = [...restrictedEditors.keys()];40const updatedPinnedEditorVersions = Object.fromEntries(pinnedEditorVersions.entries());4142await handleUpdateTeamSettings(43{ restrictedEditorNames: updatedRestrictedEditors, pinnedEditorVersions: updatedPinnedEditorVersions },44{ throwMutateError: true },45);46},47});4849const restrictedEditors = new Set<string>(settings?.restrictedEditorNames || []);50const pinnedEditorVersions = new Map<string, string>(Object.entries(settings?.pinnedEditorVersions || {}));5152return (53<ConfigurationSettingsField>54<Heading3>Available editors</Heading3>55<Subheading>56Limit the available editors in your organization. Requires <span className="font-medium">Owner</span>{" "}57permissions to change.58</Subheading>5960<IdeOptions61isLoading={orgOptionsIsLoading}62className="mt-4"63ideOptions={orgOptions}64pinnedEditorVersions={pinnedEditorVersions}65/>6667{isOwner && (68<Button className="mt-6" onClick={() => setShowModal(true)}>69Manage Editors70</Button>71)}7273{showModal && (74<IdeOptionsModifyModal75isLoading={installationOptionsIsLoading}76ideOptions={installationOptions}77restrictedEditors={restrictedEditors}78pinnedEditorVersions={pinnedEditorVersions}79updateMutation={updateMutation}80onClose={() => setShowModal(false)}81/>82)}83</ConfigurationSettingsField>84);85};868788