(core) Exposing custom widgets on the UI

Summary:
Exposing custom widgets as a dropdown menu in custom section configuration panel.

Adding new environmental variable GRIST_WIDGET_LIST_URL that points to a
json file with an array of available widgets. When not present, custom widget menu is
hidden, exposing only Custom URL option.

Available widget list can be fetched from:
https://github.com/gristlabs/grist-widget/releases/download/latest/manifest.json

Test Plan: New tests, and updated old ones.

Reviewers: paulfitz, dsagal

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D3127
This commit is contained in:
Jarosław Sadziński
2021-11-26 11:43:55 +01:00
parent be96db4689
commit 1425461cd8
16 changed files with 482 additions and 25 deletions

View File

@@ -1,6 +1,7 @@
import * as BaseView from 'app/client/components/BaseView';
import { ColumnRec, FilterRec, TableRec, ViewFieldRec, ViewRec } from 'app/client/models/DocModel';
import * as modelUtil from 'app/client/models/modelUtil';
import {ICustomWidget} from 'app/common/CustomWidget';
import * as ko from 'knockout';
import { CursorPos, } from 'app/client/components/Cursor';
import { KoArray, } from 'app/client/lib/koArray';
@@ -131,29 +132,36 @@ export interface ViewSectionRec extends IRowModel<"_grist_Views_section"> {
// Apply `filter` to the field or column identified by `colRef`.
setFilter(colRef: number, filter: string): void;
// Saves custom definition (bundles change)
saveCustomDef(): Promise<void>;
}
export interface CustomViewSectionDef {
/**
* The mode.
*/
mode: ko.Observable<"url"|"plugin">;
mode: modelUtil.KoSaveableObservable<"url"|"plugin">;
/**
* The url.
*/
url: ko.Observable<string>;
url: modelUtil.KoSaveableObservable<string|null>;
/**
* Custom widget information.
*/
widgetDef: modelUtil.KoSaveableObservable<ICustomWidget|null>;
/**
* Access granted to url.
*/
access: ko.Observable<string>;
access: modelUtil.KoSaveableObservable<string>;
/**
* The plugin id.
*/
pluginId: ko.Observable<string>;
pluginId: modelUtil.KoSaveableObservable<string>;
/**
* The section id.
*/
sectionId: ko.Observable<string>;
sectionId: modelUtil.KoSaveableObservable<string>;
}
// Information about filters for a field or hidden column.
@@ -185,7 +193,8 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
const customViewDefaults = {
mode: 'url',
url: '',
url: null,
widgetDef: null,
access: '',
pluginId: '',
sectionId: ''
@@ -196,11 +205,16 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
this.customDef = {
mode: customDefObj.prop('mode'),
url: customDefObj.prop('url'),
widgetDef: customDefObj.prop('widgetDef'),
access: customDefObj.prop('access'),
pluginId: customDefObj.prop('pluginId'),
sectionId: customDefObj.prop('sectionId')
};
this.saveCustomDef = () => {
return customDefObj.save();
};
this.themeDef = modelUtil.fieldWithDefault(this.theme, 'form');
this.chartTypeDef = modelUtil.fieldWithDefault(this.chartType, 'bar');
this.view = refRecord(docModel.views, this.parentId);

View File

@@ -123,7 +123,12 @@ export function reportError(err: Error|string): void {
} else {
// If we don't recognize it, consider it an application error (bug) that the user should be
// able to report.
_notifier.createAppError(err);
if (details?.userError) {
// If we have user friendly error, show it instead.
_notifier.createAppError(Error(details.userError));
} else {
_notifier.createAppError(err);
}
}
}
}