mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Extending widget
Summary: - Adding new option 'strictType' to widget mapping - Refreshing mappings when widget options are changed Test Plan: Updated Reviewers: JakubSerafin Reviewed By: JakubSerafin Differential Revision: https://phab.getgrist.com/D4061
This commit is contained in:
@@ -14,7 +14,10 @@ export class ColumnToMapImpl implements Required<ColumnToMap> {
|
||||
// If column is optional (used only on the UI).
|
||||
public optional: boolean;
|
||||
// Type of the column that widget expects. Might be a single or a comma separated list of types.
|
||||
// "Any" means that any type is allowed (unless strictType is true).
|
||||
public type: string;
|
||||
// If true, the column type is strict and cannot be any type.
|
||||
public strictType: boolean;
|
||||
// Description of the type (used to show a placeholder).
|
||||
public typeDesc: string;
|
||||
// Allow multiple column assignment (like Series in Charts).
|
||||
@@ -29,14 +32,26 @@ export class ColumnToMapImpl implements Required<ColumnToMap> {
|
||||
this.typeDesc = this.type.split(',')
|
||||
.map(t => String(UserType.typeDefs[t]?.label ?? "any").toLowerCase()).join(', ');
|
||||
this.allowMultiple = typeof def === 'string' ? false : (def.allowMultiple ?? false);
|
||||
this.strictType = typeof def === 'string' ? false : (def.strictType ?? false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the column type matches this definition.
|
||||
*
|
||||
* Here are use case examples, for better understanding (Any is treated as a star):
|
||||
* 1. Widget sets "Text", user can map to "Text" or "Any".
|
||||
* 2. Widget sets "Any", user can map to "Int", "Toggle", "Any" and any other type.
|
||||
* 3. Widget sets "Text,Int", user can map to "Text", "Int", "Any"
|
||||
*
|
||||
* With strictType, the Any in the widget is treated as Any, not a star.
|
||||
* 1. Widget sets "Text", user can map to "Text".
|
||||
* 2. Widget sets "Any", user can map to "Any". Not to "Text", "Int", etc. NOTICE: here Any in widget is not a star,
|
||||
* widget expects Any as a type so "Toggle" column won't be allowed.
|
||||
* 3. Widget sets "Text,Int", user can only map to "Text", "Int".
|
||||
* 4. Widget sets "Text,Any", user can only map to "Text", "Any".
|
||||
*/
|
||||
public canByMapped(pureType: string) {
|
||||
return this.type.split(',').includes(pureType)
|
||||
|| pureType === "Any"
|
||||
|| this.type === "Any";
|
||||
const isAny = pureType === "Any" || this.type === "Any";
|
||||
return this.type.split(',').includes(pureType) || (isAny && !this.strictType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,16 +714,23 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
|
||||
if (widgetCol.allowMultiple) {
|
||||
// We expect a list of colRefs be mapped;
|
||||
if (!Array.isArray(mappedCol)) { continue; }
|
||||
result[widgetCol.name] = mappedCol
|
||||
const columns = mappedCol
|
||||
// Remove all colRefs saved but deleted
|
||||
.filter(cId => colMap.has(cId))
|
||||
// And those with wrong type.
|
||||
.filter(cId => widgetCol.canByMapped(colMap.get(cId)!.pureType()))
|
||||
.map(cId => colMap.get(cId)!.colId());
|
||||
.map(cId => colMap.get(cId)!);
|
||||
|
||||
// Make a subscription to get notified when widget options are changed.
|
||||
columns.forEach(c => c.widgetOptions());
|
||||
|
||||
result[widgetCol.name] = columns.map(c => c.colId());
|
||||
} else {
|
||||
// Widget expects a single value and existing column
|
||||
if (Array.isArray(mappedCol) || !colMap.has(mappedCol)) { continue; }
|
||||
const selectedColumn = colMap.get(mappedCol)!;
|
||||
// Make a subscription to the column to get notified when it changes.
|
||||
void selectedColumn.widgetOptions();
|
||||
result[widgetCol.name] = widgetCol.canByMapped(selectedColumn.pureType()) ? selectedColumn.colId() : null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user