MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / OrgPage

Function OrgPage

packages/react/src/pages/org.tsx:136–438  ·  view source on GitHub ↗
(props: {
  domainsSection?: React.ReactNode;
  // Cloud injects the plan-upgrade call to action (a link to billing/plans).
  // When set and the org is at its seat limit, clicking "Invite member" opens
  // an upgrade prompt instead of the invite form. Self-host has no seat limit,
  // so it never reaches this and can omit it.
  upgradeAction?: React.ReactNode;
  // Cloud injects a destructive "delete organization" section here. It hangs
  // off the cloud-only `/auth/delete-organization` endpoint (WorkOS + billing
  // teardown), so self-host omits it. Rendered last, below members.
  dangerZoneSection?: React.ReactNode;
})

Source from the content-addressed store, hash-verified

134}
135
136export function OrgPage(props: {
137 domainsSection?: React.ReactNode;
138 // Cloud injects the plan-upgrade call to action (a link to billing/plans).
139 // When set and the org is at its seat limit, clicking "Invite member" opens
140 // an upgrade prompt instead of the invite form. Self-host has no seat limit,
141 // so it never reaches this and can omit it.
142 upgradeAction?: React.ReactNode;
143 // Cloud injects a destructive "delete organization" section here. It hangs
144 // off the cloud-only `/auth/delete-organization` endpoint (WorkOS + billing
145 // teardown), so self-host omits it. Rendered last, below members.
146 dangerZoneSection?: React.ReactNode;
147}) {
148 useExecutorDocumentTitle("Organization");
149 const auth = useAuth();
150 const organizationName =
151 auth.status === "authenticated" ? (auth.organization?.name ?? "Organization") : "Organization";
152 const membersResult = useAtomValue(orgMembersAtom);
153 const refreshMembers = useAtomRefresh(orgMembersAtom);
154 const rolesResult = useAtomValue(orgRolesAtom);
155 const doRemove = useAtomSet(removeMember, { mode: "promiseExit" });
156 const doUpdateRole = useAtomSet(updateMemberRole, { mode: "promiseExit" });
157 const doUpdateOrgName = useAtomSet(updateOrgName, { mode: "promiseExit" });
158 const [inviteOpen, setInviteOpen] = useState(false);
159 const [upgradeOpen, setUpgradeOpen] = useState(false);
160 const [editName, setEditName] = useState(organizationName);
161 const [savingName, setSavingName] = useState(false);
162 const [search, setSearch] = useState("");
163
164 const roles = AsyncResult.match(rolesResult, {
165 onInitial: () => [] as readonly RoleData[],
166 onFailure: () => [] as readonly RoleData[],
167 onSuccess: ({ value }) => value.roles,
168 });
169
170 const seats = AsyncResult.match(membersResult, {
171 onInitial: () => undefined,
172 onFailure: () => undefined,
173 onSuccess: ({ value }) => value.seats,
174 });
175 // At the plan's member-seat limit, "Invite member" opens an upgrade prompt
176 // (when cloud provided one) instead of the invite form, so the admin gets a
177 // clear next step rather than a refused invite.
178 const atSeatLimit = !!seats && !seats.unlimited && seats.used >= seats.granted;
179 const showUpgradeOnInvite = atSeatLimit && !!props.upgradeAction;
180
181 const handleRemove = async (membershipId: string, name: string) => {
182 const exit = await doRemove({
183 params: { membershipId },
184 reactivityKeys: orgMemberWriteKeys,
185 });
186 trackEvent("org_member_removed", { success: Exit.isSuccess(exit) });
187 toast[Exit.isSuccess(exit) ? "success" : "error"](
188 Exit.isSuccess(exit) ? `Removed ${name}` : "Failed to remove member",
189 );
190 };
191
192 const handleChangeRole = async (membershipId: string, roleSlug: string, roleName: string) => {
193 const exit = await doUpdateRole({

Callers

nothing calls this directly

Calls 7

useExecutorDocumentTitleFunction · 0.90
useAuthFunction · 0.90
isAsyncResultLoadingFunction · 0.90
handleSaveNameFunction · 0.85
formatLastActiveFunction · 0.85
handleChangeRoleFunction · 0.85
handleRemoveFunction · 0.70

Tested by

no test coverage detected