Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/collaborators/current-collabs.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Button, Card, Popconfirm } from "antd";6import React from "react";7import { FormattedMessage, useIntl } from "react-intl";8import { CSS, redux, useRedux } from "@cocalc/frontend/app-framework";9import {10Gap,11Icon,12Paragraph,13SettingBox,14Title,15} from "@cocalc/frontend/components";16import { useStudentProjectFunctionality } from "@cocalc/frontend/course";17import { labels } from "@cocalc/frontend/i18n";18import { CancelText } from "@cocalc/frontend/i18n/components";19import { Project } from "@cocalc/frontend/project/settings/types";20import { COLORS } from "@cocalc/util/theme";21import { FIX_BORDER } from "../project/page/common";22import { User } from "../users";2324interface Props {25project: Project;26user_map?: any;27mode?: "project" | "flyout";28}2930export const CurrentCollaboratorsPanel: React.FC<Props> = (props: Props) => {31const { project, user_map, mode = "project" } = props;32const isFlyout = mode === "flyout";33const intl = useIntl();34const get_account_id = useRedux("account", "get_account_id");35const sort_by_activity = useRedux("projects", "sort_by_activity");36const student = useStudentProjectFunctionality(project.get("project_id"));3738function remove_collaborator(account_id: string) {39const project_id = project.get("project_id");40redux.getActions("projects").remove_collaborator(project_id, account_id);41if (account_id === get_account_id()) {42return (redux.getActions("page") as any).close_project_tab(project_id); // TODO: better types43}44}4546function user_remove_confirm_text(account_id: string) {47const style: CSS = { maxWidth: "300px" };48if (account_id === get_account_id()) {49return (50<div style={style}>51<FormattedMessage52id="collaborators.current-collabs.remove_self"53defaultMessage={`Are you sure you want to remove <b>yourself</b> from this project?54You will no longer have access to this project and cannot add yourself back.`}55/>56</div>57);58} else {59return (60<div style={style}>61<FormattedMessage62id="collaborators.current-collabs.remove_other"63defaultMessage={`Are you sure you want to remove {user} from this project?64They will no longer have access to this project.`}65values={{66user: <User account_id={account_id} user_map={user_map} />,67}}68/>69</div>70);71}72}7374function user_remove_button(account_id: string, group?: string) {75if (student.disableCollaborators) return;76const text = user_remove_confirm_text(account_id);77const isOwner = group === "owner";78return (79<Popconfirm80title={text}81onConfirm={() => remove_collaborator(account_id)}82okText={"Yes, remove collaborator"}83cancelText={<CancelText />}84disabled={isOwner}85>86<Button87disabled={isOwner}88type={isFlyout ? "link" : "default"}89style={{90marginBottom: "0",91float: "right",92...(isFlyout ? { color: COLORS.ANTD_RED_WARN } : {}),93}}94>95<Icon name="user-times" /> {intl.formatMessage(labels.remove)} ...96</Button>97</Popconfirm>98);99}100101function render_user(user: any, is_last?: boolean) {102const style = {103width: "100%",104flex: "1 1 auto",105...(!is_last ? { marginBottom: "20px" } : {}),106};107return (108<div key={user.account_id} style={style}>109<User110account_id={user.account_id}111user_map={user_map}112last_active={user.last_active}113show_avatar={true}114/>115<span>116<Gap />({user.group})117</span>118{user_remove_button(user.account_id, user.group)}119</div>120);121}122123function render_users() {124const u = project.get("users");125if (u === undefined) {126return;127}128const users = u129.map((v, k) => ({ account_id: k, group: v.get("group") }))130.toList()131.toJS();132return sort_by_activity(users, project.get("project_id")).map((u, i) =>133render_user(u, i === users.length - 1),134);135}136137function render_collaborators_list() {138const style: CSS = {139maxHeight: "20em",140overflowY: "auto",141overflowX: "hidden",142marginBottom: "0",143display: "flex",144flexDirection: "column",145};146if (isFlyout) {147return (148<div style={{ ...style, borderBottom: FIX_BORDER }}>149{render_users()}150</div>151);152} else {153return (154<Card style={{ ...style, backgroundColor: COLORS.GRAY_LLL }}>155{render_users()}156</Card>157);158}159}160161const introText = intl.formatMessage({162id: "collaborators.current-collabs.intro",163defaultMessage:164"Everybody listed below can collaboratively work with you on any Jupyter Notebook, Linux Terminal or file in this project, and add or remove other collaborators.",165});166167switch (mode) {168case "project":169return (170<SettingBox title="Current Collaborators" icon="user">171{introText}172<hr />173{render_collaborators_list()}174</SettingBox>175);176case "flyout":177return (178<div style={{ paddingLeft: "5px" }}>179<Title level={3}>180<Icon name="user" />{" "}181<FormattedMessage182id="collaborators.current-collabs.title"183defaultMessage={"Current Collaborators"}184description={185"Title of a table listing users collaborating on that project"186}187/>188</Title>189<Paragraph190type="secondary"191ellipsis={{ rows: 1, expandable: true, symbol: "more" }}192>193{introText}194</Paragraph>195{render_collaborators_list()}196</div>197);198}199};200201202