feat: add total users to people management screen (#1878)

* feat: add total users to pagination

* move this.total in runInAction callback

* add total counts + counts to people tabs

* progress: use raw pg query

* progress: add test

* fix: SQL interpolation

* Styling and translation of People page

Co-authored-by: Tim <timothychang94@gmail.com>
This commit is contained in:
Tom Moor
2021-02-09 20:13:09 -08:00
committed by GitHub
parent 097359bf7c
commit df472ac391
12 changed files with 215 additions and 31 deletions

View File

@@ -7,7 +7,7 @@ import BaseModel from "../models/BaseModel";
import type { PaginationParams } from "types";
import { client } from "utils/ApiClient";
type Action = "list" | "info" | "create" | "update" | "delete";
type Action = "list" | "info" | "create" | "update" | "delete" | "count";
function modelNameFromClassName(string) {
return string.charAt(0).toLowerCase() + string.slice(1);
@@ -24,7 +24,7 @@ export default class BaseStore<T: BaseModel> {
model: Class<T>;
modelName: string;
rootStore: RootStore;
actions: Action[] = ["list", "info", "create", "update", "delete"];
actions: Action[] = ["list", "info", "create", "update", "delete", "count"];
constructor(rootStore: RootStore, model: Class<T>) {
this.rootStore = rootStore;

View File

@@ -1,13 +1,21 @@
// @flow
import invariant from "invariant";
import { filter, orderBy } from "lodash";
import { computed, action, runInAction } from "mobx";
import { observable, computed, action, runInAction } from "mobx";
import User from "models/User";
import BaseStore from "./BaseStore";
import RootStore from "./RootStore";
import { client } from "utils/ApiClient";
export default class UsersStore extends BaseStore<User> {
@observable counts: {
active: number,
admins: number,
all: number,
invited: number,
suspended: number,
} = {};
constructor(rootStore: RootStore) {
super(rootStore, User);
}
@@ -52,21 +60,25 @@ export default class UsersStore extends BaseStore<User> {
@action
promote = (user: User) => {
this.counts.admins += 1;
return this.actionOnUser("promote", user);
};
@action
demote = (user: User) => {
this.counts.admins -= 1;
return this.actionOnUser("demote", user);
};
@action
suspend = (user: User) => {
this.counts.suspended += 1;
return this.actionOnUser("suspend", user);
};
@action
activate = (user: User) => {
this.counts.suspended -= 1;
return this.actionOnUser("activate", user);
};
@@ -76,10 +88,39 @@ export default class UsersStore extends BaseStore<User> {
invariant(res && res.data, "Data should be available");
runInAction(`invite`, () => {
res.data.users.forEach(this.add);
this.counts.invited += res.data.sent.length;
this.counts.all += res.data.sent.length;
});
return res.data;
};
@action
fetchCounts = async (teamId: string): Promise<*> => {
const res = await client.post(`/users.count`, { teamId });
invariant(res && res.data, "Data should be available");
this.counts = res.data.counts;
return res.data;
};
@action
async delete(user: User, options: Object = {}) {
super.delete(user, options);
if (!user.isSuspended && user.lastActiveAt) {
this.counts.active -= 1;
}
if (user.isInvited) {
this.counts.invited -= 1;
}
if (user.isAdmin) {
this.counts.admins -= 1;
}
if (user.isSuspended) {
this.counts.suspended -= 1;
}
this.counts.all -= 1;
}
notInCollection = (collectionId: string, query: string = "") => {
const memberships = filter(
this.rootStore.memberships.orderedData,