- {!!org?.data?.invitationId && (
+ {!!orgInvitation?.data?.invitationId && (
diff --git a/components/dashboard/src/teams/OrgSettingsPage.tsx b/components/dashboard/src/teams/OrgSettingsPage.tsx
index 6ac480cc412ba9..24ff1804aa348d 100644
--- a/components/dashboard/src/teams/OrgSettingsPage.tsx
+++ b/components/dashboard/src/teams/OrgSettingsPage.tsx
@@ -4,7 +4,6 @@
* See License.AGPL.txt in the project root for license information.
*/
-import { Team } from "@gitpod/gitpod-protocol";
import { BillingMode } from "@gitpod/gitpod-protocol/lib/billing-mode";
import { useMemo } from "react";
import { Redirect } from "react-router";
@@ -12,15 +11,15 @@ import Header from "../components/Header";
import { SpinnerLoader } from "../components/Loader";
import { PageWithSubMenu } from "../components/PageWithSubMenu";
import { useOrgBillingMode } from "../data/billing-mode/org-billing-mode-query";
-import { useCurrentOrg } from "../data/organizations/orgs-query";
import { useFeatureFlag } from "../data/featureflag-query";
+import { useOrgMembersInfoQuery } from "../data/organizations/org-members-info-query";
export interface OrgSettingsPageProps {
children: React.ReactNode;
}
export function OrgSettingsPage({ children }: OrgSettingsPageProps) {
- const org = useCurrentOrg();
+ const orgMembersInfo = useOrgMembersInfoQuery();
const orgBillingMode = useOrgBillingMode();
const oidcServiceEnabled = useFeatureFlag("oidcServiceEnabled");
const orgGitAuthProviders = useFeatureFlag("orgGitAuthProviders");
@@ -28,20 +27,19 @@ export function OrgSettingsPage({ children }: OrgSettingsPageProps) {
const menu = useMemo(
() =>
getTeamSettingsMenu({
- team: org.data,
billingMode: orgBillingMode.data,
ssoEnabled: oidcServiceEnabled,
orgGitAuthProviders,
- isOwner: org.data?.isOwner,
+ isOwner: orgMembersInfo.data?.isOwner,
}),
- [org.data, orgBillingMode.data, oidcServiceEnabled, orgGitAuthProviders],
+ [orgMembersInfo.data, orgBillingMode.data, oidcServiceEnabled, orgGitAuthProviders],
);
const title = "Organization Settings";
const subtitle = "Manage your organization's settings.";
// Render as much of the page as we can in a loading state to avoid content shift
- if (org.isLoading || orgBillingMode.isLoading) {
+ if (orgMembersInfo.isLoading || orgBillingMode.isLoading) {
return (
@@ -56,7 +54,7 @@ export function OrgSettingsPage({ children }: OrgSettingsPageProps) {
const onlyForOwner = false;
// After we've loaded, ensure user is an owner, if not, redirect
- if (onlyForOwner && !org.data?.isOwner) {
+ if (onlyForOwner && !orgMembersInfo.data?.isOwner) {
return
;
}
@@ -68,7 +66,6 @@ export function OrgSettingsPage({ children }: OrgSettingsPageProps) {
}
function getTeamSettingsMenu(params: {
- team?: Team;
billingMode?: BillingMode;
ssoEnabled?: boolean;
orgGitAuthProviders: boolean;
diff --git a/components/dashboard/src/teams/TeamSettings.tsx b/components/dashboard/src/teams/TeamSettings.tsx
index f67711a39f916e..cdd2ab578b852a 100644
--- a/components/dashboard/src/teams/TeamSettings.tsx
+++ b/components/dashboard/src/teams/TeamSettings.tsx
@@ -26,10 +26,12 @@ import Modal, { ModalBody, ModalFooter, ModalHeader } from "../components/Modal"
import { InputField } from "../components/forms/InputField";
import { InputWithCopy } from "../components/InputWithCopy";
import { ReactComponent as Stack } from "../icons/Stack.svg";
+import { OrgMembersInfo, useOrgMembersInfoQuery } from "../data/organizations/org-members-info-query";
export default function TeamSettingsPage() {
const user = useCurrentUser();
const org = useCurrentOrg().data;
+ const orgMembersInfo = useOrgMembersInfoQuery().data;
const invalidateOrgs = useOrganizationsInvalidator();
const [modal, setModal] = useState(false);
const [teamNameToDelete, setTeamNameToDelete] = useState("");
@@ -50,7 +52,7 @@ export default function TeamSettingsPage() {
const updateTeamInformation = useCallback(
async (e: React.FormEvent) => {
- if (!org?.isOwner) {
+ if (!orgMembersInfo?.isOwner) {
return;
}
e.preventDefault();
@@ -67,7 +69,7 @@ export default function TeamSettingsPage() {
console.error(error);
}
},
- [orgFormIsValid, updateOrg, teamName, org],
+ [orgFormIsValid, updateOrg, teamName, orgMembersInfo?.isOwner],
);
const deleteTeam = useCallback(async () => {
@@ -104,11 +106,11 @@ export default function TeamSettingsPage() {
value={teamName}
error={teamNameError.message}
onChange={setTeamName}
- disabled={!org?.isOwner}
+ disabled={!orgMembersInfo?.isOwner}
onBlur={teamNameError.onBlur}
/>
- {org?.isOwner && (
+ {orgMembersInfo?.isOwner && (
@@ -117,7 +119,7 @@ export default function TeamSettingsPage() {
- {user?.organizationId !== org?.id && org?.isOwner && (
+ {user?.organizationId !== org?.id && orgMembersInfo?.isOwner && (
<>
Delete Organization
@@ -170,8 +172,8 @@ export default function TeamSettingsPage() {
);
}
-function OrgSettingsForm(props: { org?: OrganizationInfo }) {
- const { org } = props;
+function OrgSettingsForm(props: { org?: OrganizationInfo; orgMembersInfo?: OrgMembersInfo }) {
+ const { org, orgMembersInfo } = props;
const { data: settings, isLoading } = useOrgSettingsQuery();
const { data: imageInfo } = useDefaultWorkspaceImageQuery();
const updateTeamSettings = useUpdateOrgSettingsMutation();
@@ -183,7 +185,7 @@ function OrgSettingsForm(props: { org?: OrganizationInfo }) {
if (!org?.id) {
throw new Error("no organization selected");
}
- if (!org.isOwner) {
+ if (!orgMembersInfo?.isOwner) {
throw new Error("no organization settings change permission");
}
try {
@@ -195,7 +197,7 @@ function OrgSettingsForm(props: { org?: OrganizationInfo }) {
console.error(error);
}
},
- [updateTeamSettings, org?.id, org?.isOwner, settings],
+ [updateTeamSettings, org?.id, orgMembersInfo?.isOwner, settings],
);
return (
@@ -225,7 +227,7 @@ function OrgSettingsForm(props: { org?: OrganizationInfo }) {
hint="Allow workspaces created within an Organization to share the workspace with any authenticated user."
checked={!settings?.workspaceSharingDisabled}
onChange={(checked) => handleUpdateTeamSettings({ workspaceSharingDisabled: !checked })}
- disabled={isLoading || !org?.isOwner}
+ disabled={isLoading || !orgMembersInfo?.isOwner}
/>
Workspace Images
@@ -234,7 +236,7 @@ function OrgSettingsForm(props: { org?: OrganizationInfo }) {
setShowImageEditModal(true)}
diff --git a/components/dashboard/src/teams/git-integrations/GitIntegrationListItem.tsx b/components/dashboard/src/teams/git-integrations/GitIntegrationListItem.tsx
index 352f536d5d19c9..5008a1bd596d36 100644
--- a/components/dashboard/src/teams/git-integrations/GitIntegrationListItem.tsx
+++ b/components/dashboard/src/teams/git-integrations/GitIntegrationListItem.tsx
@@ -11,9 +11,9 @@ import { ContextMenuEntry } from "../../components/ContextMenu";
import { Item, ItemField, ItemFieldContextMenu, ItemFieldIcon } from "../../components/ItemsList";
import { useDeleteOrgAuthProviderMutation } from "../../data/auth-providers/delete-org-auth-provider-mutation";
import { GitIntegrationModal } from "./GitIntegrationModal";
-import { useCurrentOrg } from "../../data/organizations/orgs-query";
import { ModalFooterAlert } from "../../components/Modal";
import { useToast } from "../../components/toasts/Toasts";
+import { useOrgMembersInfoQuery } from "../../data/organizations/org-members-info-query";
type Props = {
provider: AuthProviderEntry;
@@ -22,10 +22,10 @@ export const GitIntegrationListItem: FunctionComponent = ({ provider }) =
const [showEditModal, setShowEditModal] = useState(false);
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
const deleteAuthProvider = useDeleteOrgAuthProviderMutation();
- const { data: org } = useCurrentOrg();
+ const orgMembersInfo = useOrgMembersInfoQuery().data;
const { toast } = useToast();
- const memberCount = org?.members.length ?? 1;
+ const memberCount = orgMembersInfo?.members.length ?? 1;
const menuEntries = useMemo(() => {
const result: ContextMenuEntry[] = [];
diff --git a/components/dashboard/src/usage/UsageSummary.tsx b/components/dashboard/src/usage/UsageSummary.tsx
index cea828a7bff793..f2d390d46bbe23 100644
--- a/components/dashboard/src/usage/UsageSummary.tsx
+++ b/components/dashboard/src/usage/UsageSummary.tsx
@@ -5,16 +5,16 @@
*/
import { FC } from "react";
-import { useCurrentOrg } from "../data/organizations/orgs-query";
import { Subheading } from "../components/typography/headings";
import { Link } from "react-router-dom";
import { useOrgBillingMode } from "../data/billing-mode/org-billing-mode-query";
+import { useOrgMembersInfoQuery } from "../data/organizations/org-members-info-query";
type Props = {
creditsUsed?: number;
};
export const UsageSummaryData: FC = ({ creditsUsed }) => {
- const currentOrg = useCurrentOrg();
+ const orgMembersInfo = useOrgMembersInfoQuery().data;
const { data: billingMode } = useOrgBillingMode();
return (
@@ -26,7 +26,7 @@ export const UsageSummaryData: FC = ({ creditsUsed }) => {
{creditsUsed !== undefined ? creditsUsed.toLocaleString() : "-"}
- {currentOrg.data && currentOrg.data.isOwner && billingMode?.mode === "usage-based" && (
+ {orgMembersInfo && orgMembersInfo.isOwner && billingMode?.mode === "usage-based" && (
diff --git a/components/gitpod-protocol/src/attribution.ts b/components/gitpod-protocol/src/attribution.ts
index 71ded9b6fe4557..094f3d13babfca 100644
--- a/components/gitpod-protocol/src/attribution.ts
+++ b/components/gitpod-protocol/src/attribution.ts
@@ -21,7 +21,7 @@ export namespace AttributionId {
return { kind: "team", teamId: organizationId };
}
- export function create(organization: Organization): AttributionId {
+ export function create(organization: Pick): AttributionId {
return createFromOrganizationId(organization.id);
}
diff --git a/components/server/src/api/teams.spec.db.ts b/components/server/src/api/teams.spec.db.ts
index 710317697e0e66..87cf71988dafcc 100644
--- a/components/server/src/api/teams.spec.db.ts
+++ b/components/server/src/api/teams.spec.db.ts
@@ -5,11 +5,10 @@
*/
import { Code, ConnectError, PromiseClient, createPromiseClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-node";
-import { Timestamp } from "@bufbuild/protobuf";
import { TeamDB, TypeORM, UserDB, testContainer } from "@gitpod/gitpod-db/lib";
import { DBTeam } from "@gitpod/gitpod-db/lib/typeorm/entity/db-team";
import { TeamsService as TeamsServiceDefinition } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_connect";
-import { GetTeamRequest, Team, TeamMember, TeamRole } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_pb";
+import { GetTeamRequest, Team } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_pb";
import { suite, test, timeout } from "@testdeck/mocha";
import * as chai from "chai";
import * as http from "http";
@@ -109,7 +108,6 @@ export class APITeamsServiceSpec {
const userDB = this.container.get(UserDB);
const user = await userDB.storeUser(await userDB.newUser());
const team = await teamDB.createTeam(user.id, "myteam");
- const invite = await teamDB.resetGenericInvite(team.id);
const response = await this.client.getTeam(
new GetTeamRequest({
@@ -121,18 +119,6 @@ export class APITeamsServiceSpec {
id: team.id,
slug: team.slug,
name: team.name,
- members: [
- new TeamMember({
- userId: user.id,
- avatarUrl: user.avatarUrl,
- fullName: user.fullName,
- role: TeamRole.OWNER,
- memberSince: Timestamp.fromDate(new Date(team.creationTime)),
- }),
- ],
- teamInvitation: {
- id: invite.id,
- },
}),
);
}
diff --git a/components/server/src/api/teams.ts b/components/server/src/api/teams.ts
index c36ecc798b4c57..2e4948450c06da 100644
--- a/components/server/src/api/teams.ts
+++ b/components/server/src/api/teams.ts
@@ -14,16 +14,19 @@ import {
DeleteTeamMemberResponse,
DeleteTeamRequest,
DeleteTeamResponse,
+ GetTeamInvitationRequest,
+ GetTeamInvitationResponse,
GetTeamRequest,
GetTeamResponse,
JoinTeamRequest,
JoinTeamResponse,
+ ListTeamMembersRequest,
+ ListTeamMembersResponse,
ListTeamsRequest,
ListTeamsResponse,
ResetTeamInvitationRequest,
ResetTeamInvitationResponse,
Team,
- TeamInvitation,
TeamMember,
TeamRole,
UpdateTeamMemberRequest,
@@ -33,6 +36,7 @@ import { TeamDB } from "@gitpod/gitpod-db/lib";
import { validate } from "uuid";
import { OrgMemberInfo, Organization, TeamMembershipInvite } from "@gitpod/gitpod-protocol";
import { Timestamp } from "@bufbuild/protobuf";
+import { UnaryImpl } from "@connectrpc/connect/dist/cjs/implementation";
@injectable()
export class APITeamsService implements ServiceImpl {
@@ -81,6 +85,13 @@ export class APITeamsService implements ServiceImpl
public async deleteTeamMember(req: DeleteTeamMemberRequest): Promise {
throw new ConnectError("unimplemented", Code.Unimplemented);
}
+ public async getTeamInvitation(req: GetTeamInvitationRequest): Promise {
+ throw new ConnectError("unimplemented", Code.Unimplemented);
+ }
+
+ public async listTeamMembers(req: ListTeamMembersRequest): Promise {
+ throw new ConnectError("unimplemented", Code.Unimplemented);
+ }
}
export function toAPITeam(team: Organization, members: OrgMemberInfo[], invite: TeamMembershipInvite): Team {
@@ -88,10 +99,6 @@ export function toAPITeam(team: Organization, members: OrgMemberInfo[], invite:
id: team.id,
name: team.name,
slug: team.slug,
- teamInvitation: new TeamInvitation({
- id: invite.id,
- }),
- members: members.map(memberToAPI),
});
}