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/account/upgrades/project-upgrades-table.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Map } from "immutable";6import { webapp_client } from "../../webapp-client";7import { rclass, redux, rtypes, Component } from "../../app-framework";8import { ErrorDisplay, UpgradeAdjustor, r_join } from "../../components";9import { PROJECT_UPGRADES } from "@cocalc/util/schema";10import { ProjectTitle } from "../../projects/project-title";11import { Button, Row, Col, Panel } from "../../antd-bootstrap";12import { ResetProjectsConfirmation } from "./reset-projects";13import { plural, is_string, len, round1 } from "@cocalc/util/misc";1415interface reduxProps {16get_total_upgrades: Function;17help_email: string;18project_map: Map<string, any>;19get_total_upgrades_you_have_applied: Function;20get_upgrades_you_applied_to_project: Function;21get_total_project_quotas: Function;22get_upgrades_to_project: Function;23get_projects_upgraded_by: Function;24}2526interface State {27show_adjustor: Map<string, boolean>; // project_id : bool28expand_remove_all_upgrades: boolean;29remove_all_upgrades_error?: string;30}3132class ProjectUpgradesTable extends Component<reduxProps, State> {33static reduxProps() {34return {35account: {36get_total_upgrades: rtypes.func,37},38customize: {39help_email: rtypes.string,40},41projects: {42project_map: rtypes.immutable.Map,43get_total_upgrades_you_have_applied: rtypes.func,44get_upgrades_you_applied_to_project: rtypes.func,45get_total_project_quotas: rtypes.func,46get_upgrades_to_project: rtypes.func,47get_projects_upgraded_by: rtypes.func,48},49};50}5152constructor(props, state) {53super(props, state);54this.state = {55show_adjustor: Map({}),56expand_remove_all_upgrades: false,57remove_all_upgrades_error: undefined,58};59}6061open_project_settings(e, project_id: string) {62redux.getActions("projects").open_project({63project_id,64target: "settings",65switch_to: !(e.which === 2 || e.ctrlKey || e.metaKey),66});67e.preventDefault();68}6970submit_upgrade_quotas({ project_id, new_quotas }) {71redux72.getActions("projects")73.apply_upgrades_to_project(project_id, new_quotas);74this.toggle_adjustor(project_id);75}7677generate_on_click_adjust(project_id: string) {78return (e) => {79e.preventDefault();80return this.toggle_adjustor(project_id);81};82}8384toggle_adjustor(project_id: string) {85const status = this.state.show_adjustor.get(project_id);86const show_adjustor = this.state.show_adjustor.set(project_id, !status);87this.setState({ show_adjustor });88}8990private render_upgrades_to_project(project_id: string, upgrades) {91const v: JSX.Element[] = [];92for (let param in upgrades) {93const val = upgrades[param];94if (!val) {95continue;96}97const info = PROJECT_UPGRADES.params[param];98if (info == null) {99console.warn(100`Invalid upgrades database entry for project_id='${project_id}' -- if this problem persists, email ${this.props.help_email} with the project_id: ${param}`101);102continue;103}104const n = round1(val != null ? info.display_factor * val : 0);105v.push(106<span key={param}>107{info.display}: {n} {plural(n, info.display_unit)}108</span>109);110}111return r_join(v);112}113114private render_upgrade_adjustor(project_id: string) {115return (116<UpgradeAdjustor117key={`adjustor-${project_id}`}118total_project_quotas={this.props.get_total_project_quotas(project_id)}119upgrades_you_can_use={this.props.get_total_upgrades()}120upgrades_you_applied_to_all_projects={this.props.get_total_upgrades_you_have_applied()}121upgrades_you_applied_to_this_project={this.props.get_upgrades_you_applied_to_project(122project_id123)}124quota_params={PROJECT_UPGRADES.params}125submit_upgrade_quotas={(new_quotas) =>126this.submit_upgrade_quotas({ new_quotas, project_id })127}128cancel_upgrading={() => this.toggle_adjustor(project_id)}129style={{ margin: "25px 0px 0px 0px" }}130omit_header={true}131/>132);133}134135private render_upgraded_project(project_id: string, upgrades, darker) {136return (137<Row138key={project_id}139style={darker ? { backgroundColor: "#eee" } : undefined}140>141<Col sm={4}>142<ProjectTitle143project_id={project_id}144handle_click={(e) => this.open_project_settings(e, project_id)}145/>146</Col>147<Col sm={8}>148<a onClick={this.generate_on_click_adjust(project_id)} role="button">149{this.render_upgrades_to_project(project_id, upgrades)}150</a>151</Col>152{this.state.show_adjustor.get(project_id)153? this.render_upgrade_adjustor(project_id)154: undefined}155</Row>156);157}158159private render_upgraded_projects_rows(upgraded_projects): JSX.Element[] {160let i = -1;161const result: JSX.Element[] = [];162for (let project_id in upgraded_projects) {163const upgrades = upgraded_projects[project_id];164i += 1;165result.push(166this.render_upgraded_project(project_id, upgrades, i % 2 === 0)167);168}169return result;170}171172async confirm_reset(_e) {173try {174await webapp_client.project_client.remove_all_upgrades();175} catch (err) {176this.setState({177expand_remove_all_upgrades: false,178remove_all_upgrades_error: err?.toString(),179});180}181}182183private render_remove_all_upgrades_error() {184let err: any = this.state.remove_all_upgrades_error;185if (!is_string(err)) {186err = JSON.stringify(err);187}188return (189<Row>190<Col sm={12}>191<ErrorDisplay192title={"Error removing all upgrades"}193error={err}194onClose={() =>195this.setState({ remove_all_upgrades_error: undefined })196}197/>198</Col>199</Row>200);201}202203private render_remove_all_upgrades_conf() {204return (205<Row>206<Col sm={12}>207<ResetProjectsConfirmation208on_confirm={this.confirm_reset.bind(this)}209on_cancel={() =>210this.setState({ expand_remove_all_upgrades: false })211}212/>213</Col>214</Row>215);216}217218private render_header() {219return (220<div>221<Row>222<Col sm={12} style={{ display: "flex" }}>223<div style={{ flex: "1" }}>224Upgrades you have applied to projects225</div>226<Button227bsStyle={"warning"}228onClick={() =>229this.setState({ expand_remove_all_upgrades: true })230}231disabled={this.state.expand_remove_all_upgrades}232>233Remove All Upgrades You Applied to Projects...234</Button>235</Col>236</Row>237{this.state.remove_all_upgrades_error238? this.render_remove_all_upgrades_error()239: undefined}240{this.state.expand_remove_all_upgrades241? this.render_remove_all_upgrades_conf()242: undefined}243</div>244);245}246247render() {248const upgraded_projects = this.props.get_projects_upgraded_by();249if (!len(upgraded_projects)) {250return null;251}252return (253<Panel header={this.render_header()}>254<Row key="header">255<Col sm={4}>256<strong>Project</strong>257</Col>258<Col sm={8}>259<strong>260Upgrades you have applied to this project (click to edit)261</strong>262</Col>263</Row>264{this.render_upgraded_projects_rows(upgraded_projects)}265</Panel>266);267}268}269270const tmp = rclass(ProjectUpgradesTable);271export { tmp as ProjectUpgradesTable };272273274