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/admin/users/user-search.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Functionality and UI to ensure a user with given email (or account_id) is sync'd with stripe.7*/89import { List } from "immutable";10import { DebounceInput } from "react-debounce-input";11import { Button, Col, Row } from "@cocalc/frontend/antd-bootstrap";12import {13Component,14rclass,15Rendered,16rtypes,17} from "@cocalc/frontend/app-framework";18import { User } from "@cocalc/frontend/frame-editors/generic/client";19import { actions } from "./actions";20import { User as UserMap } from "./store";21import { UserResult } from "./user";2223interface ReduxProps {24state?: "edit" | "running";25status?: string;26query?: string;27result?: List<UserMap>;28}2930class UserSearch extends Component<ReduxProps> {31static reduxProps() {32return {33"admin-users": {34state: rtypes.string,35status: rtypes.string,36query: rtypes.string,37result: rtypes.immutable.List,38},39};40}4142render_form(): Rendered {43return (44<Row style={{ marginBottom: "15px" }}>45<Col md={6}>46<DebounceInput47style={{48border: "1px solid lightgrey",49borderRadius: "3px",50padding: "5px",51width: "90%",52}}53value={this.props.query}54placeholder="Search for users by partial name, email, account id or project id..."55onChange={(e) => actions.set_query(e.target.value)}56onKeyDown={(e) => {57if (e.keyCode === 13) {58actions.search();59}60}}61/>62</Col>63<Col md={6}>64<Button65disabled={this.props.query == ""}66onClick={() => actions.search()}67>68Search for Users69</Button>70</Col>71</Row>72);73}7475render_status(): Rendered {76if (!this.props.status) {77return;78}79return (80<div>81<pre>{this.props.status}</pre>82<Button onClick={() => actions.clear_status()}>Clear</Button>83</div>84);85}8687render_user_header(): Rendered {88return (89<UserResult90key={"header"}91header={true}92first_name="First"93last_name="Last"94email_address="Email"95created="Created"96last_active="Active"97account_id="Account ID"98/>99);100}101102render_user(user: User): Rendered {103return <UserResult key={user.account_id} {...user} />;104}105106render_result() {107if (!this.props.result || this.props.result.size == 0) {108return null;109}110const v: Rendered[] = [this.render_user_header()];111this.props.result.forEach((user) => {112v.push(this.render_user(user.toJS()));113});114return v;115}116117render(): Rendered {118return (119<div style={{ margin: "0 30px" }}>120<div>121{this.render_form()}122{this.render_status()}123{this.render_result()}124</div>125</div>126);127}128}129130const c = rclass(UserSearch);131export { c as UserSearch };132133134