Skip to content

Commit

Permalink
Merge branch 'main' into api-with-technical-id-for-col-id
Browse files Browse the repository at this point in the history
  • Loading branch information
CamilleLegeron committed Oct 16, 2023
2 parents 1d7c807 + eb55afc commit 07ad756
Show file tree
Hide file tree
Showing 53 changed files with 3,446 additions and 984 deletions.
9 changes: 9 additions & 0 deletions app/client/components/CustomView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {UserError} from 'app/client/models/errors';
import {SortedRowSet} from 'app/client/models/rowset';
import {closeRegisteredMenu} from 'app/client/ui2018/menus';
import {AccessLevel} from 'app/common/CustomWidget';
import {defaultLocale} from 'app/common/gutil';
import {PluginInstance} from 'app/common/PluginInstance';
import {getGristConfig} from 'app/common/urlUtils';
import {Events as BackboneEvents} from 'backbone';
Expand Down Expand Up @@ -213,9 +214,17 @@ export class CustomView extends Disposable {
showAfterReady?: boolean,
}) {
const {baseUrl, access, showAfterReady} = options;
const documentSettings = this.gristDoc.docData.docSettings();
return grains.create(WidgetFrame, {
url: baseUrl || this.getEmptyWidgetPage(),
access,
preferences:
{
culture: documentSettings.locale?? defaultLocale,
language: this.gristDoc.appModel.currentUser?.locale ?? defaultLocale,
timeZone: this.gristDoc.docInfo.timezone() ?? "UTC",
currency: documentSettings.currency?? "USD",
},
readonly: this.gristDoc.isReadonly.get(),
showAfterReady,
onSettingsInitialized: async () => {
Expand Down
2 changes: 1 addition & 1 deletion app/client/components/LinkingState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export class LinkingState extends Disposable {

// Get previous linkingstate's info, if applicable (2 or more hops back)
const prevLink = this._srcSection.linkingState?.();
const prevLinkHasCursor = prevLink &&
const prevLinkHasCursor = prevLink?.incomingCursorPos &&
(prevLink.linkTypeDescription() === "Cursor:Same-Table" ||
prevLink.linkTypeDescription() === "Cursor:Reference");
const [prevLinkedPos, prevLinkedVersion] = prevLinkHasCursor ? prevLink.incomingCursorPos() :
Expand Down
4 changes: 3 additions & 1 deletion app/client/components/TypeConversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {csvDecodeRow} from 'app/common/csvFormat';
import * as gristTypes from 'app/common/gristTypes';
import {isFullReferencingType} from 'app/common/gristTypes';
import * as gutil from 'app/common/gutil';
import {isNonNullish} from 'app/common/gutil';
import NumberParse from 'app/common/NumberParse';
import {dateTimeWidgetOptions, guessDateFormat, timeFormatOptions} from 'app/common/parseDate';
import {TableData} from 'app/common/TableData';
Expand Down Expand Up @@ -134,7 +135,8 @@ export async function prepTransformColInfo(docModel: DocModel, origCol: ColumnRe
if (!dateFormat) {
// Guess date and time format if there aren't any already
const colValues = tableData.getColValues(sourceCol.colId()) || [];
dateFormat = guessDateFormat(colValues.map(String));
const strValues = colValues.map(v => isNonNullish(v) ? String(v) : null);
dateFormat = guessDateFormat(strValues);
widgetOptions = {...widgetOptions, ...(dateTimeWidgetOptions(dateFormat, true))};
}
if (toType === 'DateTime' && !widgetOptions.timeFormat) {
Expand Down
7 changes: 7 additions & 0 deletions app/client/components/WidgetFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export interface WidgetFrameOptions {
* Optional handler to modify the iframe.
*/
onElem?: (iframe: HTMLIFrameElement) => void;
/**
* Optional language to use for the widget.
*/
preferences: {language?: string, timeZone?: any, currency?: string, culture?: string};
}

/**
Expand Down Expand Up @@ -175,6 +179,9 @@ export class WidgetFrame extends DisposableWithEvents {
const urlObj = new URL(url);
urlObj.searchParams.append('access', this._options.access);
urlObj.searchParams.append('readonly', String(this._options.readonly));
// Append user and document preferences to query string.
const settingsParams = new URLSearchParams(this._options.preferences);
settingsParams.forEach((value, key) => urlObj.searchParams.append(key, value));
return urlObj.href;
};
const fullUrl = urlWithAccess(this._options.url);
Expand Down
25 changes: 21 additions & 4 deletions app/client/models/ColumnToMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -25,16 +28,30 @@ export class ColumnToMapImpl implements Required<ColumnToMap> {
this.description = typeof def === 'string' ? '' : (def.description ?? '');
this.optional = typeof def === 'string' ? false : (def.optional ?? false);
this.type = typeof def === 'string' ? 'Any' : (def.type ?? 'Any');
this.typeDesc = String(UserType.typeDefs[this.type]?.label ?? "any").toLowerCase();
this.type = this.type.split(',').map(t => t.trim()).filter(Boolean).join(',');
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);
}
}
11 changes: 9 additions & 2 deletions app/client/models/entities/ViewSectionRec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
Loading

0 comments on commit 07ad756

Please sign in to comment.