Path: blob/master/src/packages/frontend/collaborators/collaborators-setting.tsx
5819 views
/*1* This file is part of CoCalc: Copyright © 2025 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Alert } from "antd";6import { useState } from "react";7import { FormattedMessage, useIntl } from "react-intl";89import { Switch } from "@cocalc/frontend/antd-bootstrap";10import { SettingBox, Tip } from "@cocalc/frontend/components";11import { useTypedRedux } from "@cocalc/frontend/app-framework";12import { webapp_client } from "@cocalc/frontend/webapp-client";13import type { Project } from "@cocalc/frontend/project/settings/types";1415interface Props {16project: Project;17withSettingBox?: boolean;18}1920export function CollaboratorsSetting({21project,22withSettingBox = true,23}: Readonly<Props>) {24const intl = useIntl();25const [error, setError] = useState<string>("");26const [saving, setSaving] = useState<boolean>(false);2728const project_id = project.get("project_id");29const siteEnforced =30useTypedRedux("customize", "strict_collaborator_management") ?? false;31const manage_users_owner_only =32siteEnforced || project.get("manage_users_owner_only") || false;3334// Check if current user is an owner35const account_id = webapp_client.account_id;36const userGroup = project.getIn(["users", account_id, "group"]);37const isOwner = userGroup === "owner";3839async function handleChange(checked: boolean): Promise<void> {40if (siteEnforced) return;41if (!isOwner) return;4243setError("");44setSaving(true);4546try {47await webapp_client.async_query({48query: {49projects: {50project_id,51manage_users_owner_only: checked,52},53},54});55} catch (err) {56setError(`Error updating setting: ${err}`);57} finally {58setSaving(false);59}60}6162const switchComponent = (63<Switch64checked={manage_users_owner_only}65onChange={(e) => handleChange(e.target.checked)}66disabled={siteEnforced || !isOwner || saving}67>68<FormattedMessage69id="project.settings.manage_users_owner_only"70defaultMessage="Only allow owners to manage collaborators."71/>72</Switch>73);7475const content = (76<>77{!isOwner ? (78<Tip79title={intl.formatMessage({80id: "project.settings.manage_users_owner_only.note",81defaultMessage:82"This setting can only be changed by project owners.",83})}84>85{switchComponent}86</Tip>87) : (88switchComponent89)}9091{siteEnforced && (92<Alert93type="info"94showIcon95style={{ marginTop: 10 }}96message={97<FormattedMessage98id="project.settings.manage_users_owner_only.site_enforced"99defaultMessage="This setting is enforced by the site administrator for all projects."100/>101}102/>103)}104105{error && (106<Alert107type="error"108style={{ marginTop: 10 }}109closable110onClose={() => setError("")}111message={error}112/>113)}114</>115);116117if (!withSettingBox) {118return content;119}120121return (122<SettingBox123title={intl.formatMessage({124id: "project.settings.collaborators.title",125defaultMessage: "Collaborator Management",126})}127icon="users"128>129{content}130</SettingBox>131);132}133134135