mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add API endpoint to get site usage summary
Summary: The summary includes a count of documents that are approaching limits, in grace period, or delete-only. The endpoint is only accessible to site owners, and is currently unused. A follow-up diff will add usage banners to the site home page, which will use the response from the endpoint to communicate usage information to owners. Test Plan: Browser and server tests. Reviewers: alexmojaki Reviewed By: alexmojaki Differential Revision: https://phab.getgrist.com/D3420
This commit is contained in:
@@ -17,7 +17,7 @@ import {confirmModal} from 'app/client/ui2018/modals';
|
||||
import {AsyncFlow, CancelledError, FlowRunner} from 'app/common/AsyncFlow';
|
||||
import {delay} from 'app/common/delay';
|
||||
import {OpenDocMode, UserOverride} from 'app/common/DocListAPI';
|
||||
import {AttachmentsSize, DataLimitStatus, DataSize, DocUsage, RowCount} from 'app/common/DocUsage';
|
||||
import {FilteredDocUsageSummary} from 'app/common/DocUsage';
|
||||
import {IGristUrlState, parseUrlId, UrlIdParts} from 'app/common/gristUrls';
|
||||
import {getReconnectTimeout} from 'app/common/gutil';
|
||||
import {canEdit} from 'app/common/roles';
|
||||
@@ -44,6 +44,7 @@ export interface DocPageModel {
|
||||
|
||||
appModel: AppModel;
|
||||
currentDoc: Observable<DocInfo|null>;
|
||||
currentDocUsage: Observable<FilteredDocUsageSummary|null>;
|
||||
|
||||
// This block is to satisfy previous interface, but usable as this.currentDoc.get().id, etc.
|
||||
currentDocId: Observable<string|undefined>;
|
||||
@@ -66,16 +67,11 @@ export interface DocPageModel {
|
||||
|
||||
gristDoc: Observable<GristDoc|null>; // Instance of GristDoc once it exists.
|
||||
|
||||
dataLimitStatus: Observable<DataLimitStatus>;
|
||||
rowCount: Observable<RowCount>;
|
||||
dataSizeBytes: Observable<DataSize>;
|
||||
attachmentsSizeBytes: Observable<AttachmentsSize>;
|
||||
|
||||
createLeftPane(leftPanelOpen: Observable<boolean>): DomArg;
|
||||
renameDoc(value: string): Promise<void>;
|
||||
updateCurrentDoc(urlId: string, openMode: OpenDocMode): Promise<Document>;
|
||||
refreshCurrentDoc(doc: DocInfo): Promise<Document>;
|
||||
updateDocUsage(docUsage: DocUsage): void;
|
||||
updateCurrentDocUsage(docUsage: FilteredDocUsageSummary): void;
|
||||
}
|
||||
|
||||
export interface ImportSource {
|
||||
@@ -88,6 +84,7 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
public readonly pageType = "doc";
|
||||
|
||||
public readonly currentDoc = Observable.create<DocInfo|null>(this, null);
|
||||
public readonly currentDocUsage = Observable.create<FilteredDocUsageSummary|null>(this, null);
|
||||
|
||||
public readonly currentUrlId = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.urlId : undefined);
|
||||
public readonly currentDocId = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.id : undefined);
|
||||
@@ -112,11 +109,6 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
// Observable set to the instance of GristDoc once it's created.
|
||||
public readonly gristDoc = Observable.create<GristDoc|null>(this, null);
|
||||
|
||||
public readonly dataLimitStatus = Observable.create<DataLimitStatus>(this, null);
|
||||
public readonly rowCount = Observable.create<RowCount>(this, 'pending');
|
||||
public readonly dataSizeBytes = Observable.create<DataSize>(this, 'pending');
|
||||
public readonly attachmentsSizeBytes = Observable.create<AttachmentsSize>(this, 'pending');
|
||||
|
||||
// Combination of arguments needed to open a doc (docOrUrlId + openMod). It's obtained from the
|
||||
// URL, and when it changes, we need to re-open.
|
||||
// If making a comparison, the id of the document we are comparing with is also included
|
||||
@@ -199,6 +191,10 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
return this.updateCurrentDoc(doc.urlId || doc.id, doc.openMode);
|
||||
}
|
||||
|
||||
public updateCurrentDocUsage(docUsage: FilteredDocUsageSummary) {
|
||||
this.currentDocUsage.set(docUsage);
|
||||
}
|
||||
|
||||
// Replace the URL without reloading the doc.
|
||||
public updateUrlNoReload(urlId: string, urlOpenMode: OpenDocMode, options: {replace: boolean}) {
|
||||
const state = urlState().state.get();
|
||||
@@ -208,13 +204,6 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
return urlState().pushUrl(nextState, {avoidReload: true, ...options});
|
||||
}
|
||||
|
||||
public updateDocUsage(docUsage: DocUsage) {
|
||||
this.rowCount.set(docUsage.rowCount);
|
||||
this.dataLimitStatus.set(docUsage.dataLimitStatus);
|
||||
this.dataSizeBytes.set(docUsage.dataSizeBytes);
|
||||
this.attachmentsSizeBytes.set(docUsage.attachmentsSizeBytes);
|
||||
}
|
||||
|
||||
private _onOpenError(err: Error) {
|
||||
if (err instanceof CancelledError) {
|
||||
// This means that we started loading a new doc before the previous one finished loading.
|
||||
@@ -273,7 +262,7 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
this.currentDoc.set({...doc});
|
||||
}
|
||||
if (openDocResponse.docUsage) {
|
||||
this.updateDocUsage(openDocResponse.docUsage);
|
||||
this.updateCurrentDocUsage(openDocResponse.docUsage);
|
||||
}
|
||||
const gdModule = await gristDocModulePromise;
|
||||
const docComm = gdModule.DocComm.create(flow, comm, openDocResponse, doc.id, this.appModel.notifier);
|
||||
|
||||
Reference in New Issue
Block a user