Skip to content

Org settings partial updates improvements #20626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ export function useOrgSettingsQuery() {
);
}

function getQueryKey(organizationId?: string) {
export function getQueryKey(organizationId?: string) {
return ["getOrganizationSettings", organizationId || "undefined"];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useCallback } from "react";
import { configurationClient, organizationClient } from "../../service/public-api";
import { configurationClient } from "../../service/public-api";
import { useCurrentOrg } from "./orgs-query";
import { SuggestedRepository } from "@gitpod/public-api/lib/gitpod/v1/scm_pb";
import { PlainMessage } from "@bufbuild/protobuf";
import { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
import { useOrgSettingsQuery } from "./org-settings-query";

export function useOrgRepoSuggestionsInvalidator() {
const organizationId = useCurrentOrg().data?.id;
Expand All @@ -27,13 +28,12 @@ export type SuggestedOrgRepository = PlainMessage<SuggestedRepository> & {

export function useOrgSuggestedRepos() {
const organizationId = useCurrentOrg().data?.id;
const orgSettings = useOrgSettingsQuery();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧡


const query = useQuery<SuggestedOrgRepository[], Error>(
getQueryKey(organizationId),
async () => {
const response = await organizationClient.getOrganizationSettings({
organizationId,
});
const repos = response.settings?.onboardingSettings?.recommendedRepositories ?? [];
const repos = orgSettings.data?.onboardingSettings?.recommendedRepositories ?? [];

const suggestions: SuggestedOrgRepository[] = [];
for (const configurationId of repos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* See License.AGPL.txt in the project root for license information.
*/

import { useMutation } from "@tanstack/react-query";
import { useOrgSettingsQueryInvalidator } from "./org-settings-query";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { getQueryKey, useOrgSettingsQueryInvalidator } from "./org-settings-query";
import { useCurrentOrg } from "./orgs-query";
import { organizationClient } from "../../service/public-api";
import {
Expand All @@ -24,6 +24,8 @@ export const useUpdateOrgSettingsMutation = () => {
const invalidateOrgSettings = useOrgSettingsQueryInvalidator();
const invalidateWorkspaceClasses = useOrgWorkspaceClassesQueryInvalidator();
const invalidateOrgRepoSuggestions = useOrgRepoSuggestionsInvalidator();

const queryClient = useQueryClient();
const organizationId = org?.id ?? "";

return useMutation<OrganizationSettings, Error, UpdateOrganizationSettingsArgs>({
Expand All @@ -44,13 +46,18 @@ export const useUpdateOrgSettingsMutation = () => {
}
}

const settings = await organizationClient.updateOrganizationSettings(update);
return settings.settings!;
const { settings } = await organizationClient.updateOrganizationSettings(update);
return settings!;
},
onSuccess: () => {
invalidateOrgSettings();
onSuccess: (settings) => {
invalidateWorkspaceClasses();
invalidateOrgRepoSuggestions();

if (settings) {
queryClient.setQueryData(getQueryKey(organizationId), settings);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this set's the query's data to not have to re-fetch data we have available to us. We do the same with updating Configurations

} else {
invalidateOrgSettings();
}
},
onError: (err) => {
if (!ErrorCode.isUserError((err as any)?.["code"])) {
Expand Down
4 changes: 1 addition & 3 deletions components/dashboard/src/teams/TeamOnboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ export default function TeamOnboardingPage() {
throw new Error("no organization settings change permission");
}
try {
await updateTeamSettings.mutateAsync({
...newSettings,
});
await updateTeamSettings.mutateAsync(newSettings);
toast("Organization settings updated");
} catch (error) {
if (options?.throwMutateError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const OrgMemberAvatarInput = ({ settings, setFeaturedMemberId }: Props) =
const handleSelectionChange = useCallback(
(selectedId: string) => {
const member = members?.find((m) => m.userId === selectedId);
setFeaturedMemberId(selectedId || undefined);
setFeaturedMemberId(selectedId);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was necessary to force the default value and not just make an empty update.

setAvatarUrl(member?.avatarUrl);
},
[members, setFeaturedMemberId],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
* See License.AGPL.txt in the project root for license information.
*/

import { PlainMessage } from "@bufbuild/protobuf";
import type { OnboardingSettings_WelcomeMessage } from "@gitpod/public-api/lib/gitpod/v1/organization_pb";
import { SwitchInputField } from "@podkit/switch/Switch";
import { Heading3, Subheading } from "@podkit/typography/Headings";
import { useCallback, useState } from "react";
Expand Down Expand Up @@ -40,20 +38,20 @@ export const WelcomeMessageConfigurationField = ({ handleUpdateTeamSettings }: P
const [welcomeMessageEditorOpen, setWelcomeMessageEditorOpen] = useState(false);

const handleUpdateWelcomeMessage = useCallback(
async (newSettings: PlainMessage<OnboardingSettings_WelcomeMessage>, options?: UpdateTeamSettingsOptions) => {
async (
newSettings: NonNullable<UpdateOrganizationSettingsArgs["onboardingSettings"]>["welcomeMessage"],
options?: UpdateTeamSettingsOptions,
) => {
await handleUpdateTeamSettings(
{
onboardingSettings: {
welcomeMessage: {
...settings?.onboardingSettings?.welcomeMessage,
...newSettings,
},
welcomeMessage: newSettings,
},
},
options,
);
},
[handleUpdateTeamSettings, settings?.onboardingSettings?.welcomeMessage],
[handleUpdateTeamSettings],
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* See License.AGPL.txt in the project root for license information.
*/

import { PlainMessage } from "@bufbuild/protobuf";
import type { OnboardingSettings_WelcomeMessage } from "@gitpod/public-api/lib/gitpod/v1/organization_pb";
import { Button } from "@podkit/buttons/Button";
import { LoadingButton } from "@podkit/buttons/LoadingButton";
Expand All @@ -17,14 +16,15 @@ import { TextInput } from "../../components/forms/TextInputField";
import { UpdateTeamSettingsOptions } from "../TeamOnboarding";
import { OrgMemberAvatarInput } from "./OrgMemberAvatarInput";
import { gitpodWelcomeSubheading } from "./WelcomeMessageConfigurationField";
import { UpdateOrganizationSettingsArgs } from "../../data/organizations/update-org-settings-mutation";

type Props = {
settings: OnboardingSettings_WelcomeMessage | undefined;
isLoading: boolean;
isOwner: boolean;
isOpen: boolean;
handleUpdateWelcomeMessage: (
newSettings: PlainMessage<OnboardingSettings_WelcomeMessage>,
newSettings: NonNullable<UpdateOrganizationSettingsArgs["onboardingSettings"]>["welcomeMessage"],
options?: UpdateTeamSettingsOptions,
) => Promise<void>;
setIsOpen: (isOpen: boolean) => void;
Expand All @@ -49,7 +49,6 @@ export const WelcomeMessageEditorModal = ({
{
message,
featuredMemberId,
enabled: settings?.enabled ?? false,
},
{
throwMutateError: true,
Expand All @@ -61,7 +60,7 @@ export const WelcomeMessageEditorModal = ({
setError(error.message);
}
},
[handleUpdateWelcomeMessage, message, featuredMemberId, settings?.enabled, setIsOpen],
[handleUpdateWelcomeMessage, message, featuredMemberId, setIsOpen],
);

return (
Expand Down
2 changes: 1 addition & 1 deletion components/public-api/gitpod/v1/organization.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ message RoleRestrictionEntry {
message OnboardingSettings {
message WelcomeMessage {
// enabled specifies whether the welcome message is enabled
bool enabled = 1;
optional bool enabled = 1;

// message is the welcome message for the organization
optional string message = 2;
Expand Down
Loading
Loading