mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Show usage banners in doc menu of free team sites
Summary: Also fixes a minor CSS regression in UserManager where the link to add a team member wasn't shown on a separate row. Test Plan: Browser tests. Reviewers: jarek Reviewed By: jarek Differential Revision: https://phab.getgrist.com/D3444
This commit is contained in:
@@ -3,6 +3,12 @@ export interface SnapshotWindow {
|
||||
unit: 'days' | 'month' | 'year';
|
||||
}
|
||||
|
||||
// Information about the product associated with an org or orgs.
|
||||
export interface Product {
|
||||
name: string;
|
||||
features: Features;
|
||||
}
|
||||
|
||||
// A product is essentially a list of flags and limits that we may enforce/support.
|
||||
export interface Features {
|
||||
vanityDomain?: boolean; // are user-selected domains allowed (unenforced) (default: true)
|
||||
@@ -60,3 +66,8 @@ export interface Features {
|
||||
export function canAddOrgMembers(features: Features): boolean {
|
||||
return features.maxWorkspacesPerOrg !== 1;
|
||||
}
|
||||
|
||||
// Returns true if `product` is free.
|
||||
export function isFreeProduct(product: Product): boolean {
|
||||
return ['starter', 'teamFree'].includes(product.name);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {BrowserSettings} from 'app/common/BrowserSettings';
|
||||
import {BulkColValues, TableColValues, TableRecordValue, TableRecordValues, UserAction} from 'app/common/DocActions';
|
||||
import {DocCreationInfo, OpenDocMode} from 'app/common/DocListAPI';
|
||||
import {OrgUsageSummary} from 'app/common/DocUsage';
|
||||
import {Features} from 'app/common/Features';
|
||||
import {Product} from 'app/common/Features';
|
||||
import {ICustomWidget} from 'app/common/CustomWidget';
|
||||
import {isClient} from 'app/common/gristUrls';
|
||||
import {FullUser} from 'app/common/LoginSessionAPI';
|
||||
@@ -73,12 +73,6 @@ export interface BillingAccount {
|
||||
};
|
||||
}
|
||||
|
||||
// Information about the product associated with an org or orgs.
|
||||
export interface Product {
|
||||
name: string;
|
||||
features: Features;
|
||||
}
|
||||
|
||||
// The upload types vary based on which fetch implementation is in use. This is
|
||||
// an incomplete list. For example, node streaming types are supported by node-fetch.
|
||||
export type UploadType = string | Blob | Buffer;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {isOwner} from 'app/common/roles';
|
||||
import {ManagerDelta, PermissionDelta, UserAPI} from 'app/common/UserAPI';
|
||||
|
||||
/**
|
||||
@@ -7,7 +8,7 @@ import {ManagerDelta, PermissionDelta, UserAPI} from 'app/common/UserAPI';
|
||||
*/
|
||||
export async function resetOrg(api: UserAPI, org: string|number) {
|
||||
const session = await api.getSessionActive();
|
||||
if (!(session.org && session.org.access === 'owners')) {
|
||||
if (!isOwner(session.org)) {
|
||||
throw new Error('user must be an owner of the org to be reset');
|
||||
}
|
||||
const billing = api.getBillingAPI();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import {Organization} from 'app/common/UserAPI';
|
||||
|
||||
export const OWNER = 'owners';
|
||||
export const EDITOR = 'editors';
|
||||
export const VIEWER = 'viewers';
|
||||
@@ -39,6 +41,15 @@ export function canView(role: string|null): boolean {
|
||||
return role !== null;
|
||||
}
|
||||
|
||||
export function isOwner(resource: {access: Role}|null): resource is {access: Role} {
|
||||
return resource?.access === OWNER;
|
||||
}
|
||||
|
||||
export function canUpgradeOrg(org: Organization|null): org is Organization {
|
||||
// TODO: Need to consider billing managers and support user.
|
||||
return isOwner(org);
|
||||
}
|
||||
|
||||
// Returns true if the role string is a valid role or null.
|
||||
export function isValidRole(role: string|null): role is Role|null {
|
||||
return (roleOrder as Array<string|null>).includes(role);
|
||||
|
||||
Reference in New Issue
Block a user