(core) New Grist Forms styling and field options

Summary:
 - New styling for forms.
 - New field options for various field types (spinner, checkbox, radio buttons, alignment, sort).
 - Improved alignment of form fields in columns.
 - Support for additional select input keyboard shortcuts (Enter and Backspace).
 - Prevent submitting form on Enter if an input has focus.
 - Fix for changing form field type causing the field to disappear.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D4223
This commit is contained in:
George Gevoian
2024-04-10 23:50:30 -07:00
parent 661f1c1804
commit 86062a8c28
35 changed files with 2037 additions and 716 deletions

View File

@@ -12,7 +12,13 @@ import {
UserAction
} from 'app/common/DocActions';
import {DocData} from 'app/common/DocData';
import {extractTypeFromColType, isBlankValue, isFullReferencingType, isRaisedException} from "app/common/gristTypes";
import {
extractTypeFromColType,
getReferencedTableId,
isBlankValue,
isFullReferencingType,
isRaisedException,
} from "app/common/gristTypes";
import {INITIAL_FIELDS_COUNT} from "app/common/Forms";
import {buildUrlId, parseUrlId, SHARE_KEY_PREFIX} from "app/common/gristUrls";
import {isAffirmative, safeJsonParse, timeoutReached} from "app/common/gutil";
@@ -260,9 +266,15 @@ export class DocWorkerApi {
}
function asRecords(
columnData: TableColValues, opts?: { optTableId?: string; includeHidden?: boolean }): TableRecordValue[] {
columnData: TableColValues,
opts?: {
optTableId?: string;
includeHidden?: boolean;
includeId?: boolean;
}
): TableRecordValue[] {
const fieldNames = Object.keys(columnData).filter((k) => {
if (k === "id") {
if (!opts?.includeId && k === "id") {
return false;
}
if (
@@ -1451,9 +1463,8 @@ export class DocWorkerApi {
}
// Cache the table reads based on tableId. We are caching only the promise, not the result.
const table = _.memoize(
(tableId: string) => readTable(req, activeDoc, tableId, {}, {}).then(r => asRecords(r))
);
const table = _.memoize((tableId: string) =>
readTable(req, activeDoc, tableId, {}, {}).then(r => asRecords(r, {includeId: true})));
const getTableValues = async (tableId: string, colId: string) => {
const records = await table(tableId);
@@ -1463,19 +1474,17 @@ export class DocWorkerApi {
const Tables = activeDoc.docData.getMetaTable('_grist_Tables');
const getRefTableValues = async (col: MetaRowRecord<'_grist_Tables_column'>) => {
const refId = col.visibleCol;
if (!refId) { return [] as any; }
const refTableId = getReferencedTableId(col.type);
let refColId: string;
if (col.visibleCol) {
const refCol = Tables_column.getRecord(col.visibleCol);
if (!refCol) { return []; }
const refCol = Tables_column.getRecord(refId);
if (!refCol) { return []; }
const refTable = Tables.getRecord(refCol.parentId);
if (!refTable) { return []; }
const refTableId = refTable.tableId as string;
const refColId = refCol.colId as string;
if (!refTableId || !refColId) { return () => []; }
if (typeof refTableId !== 'string' || typeof refColId !== 'string') { return []; }
refColId = refCol.colId as string;
} else {
refColId = 'id';
}
if (!refTableId || typeof refTableId !== 'string' || !refColId) { return []; }
const values = await getTableValues(refTableId, refColId);
return values.filter(([_id, value]) => !isBlankValue(value));