diff --git a/.gitignore b/.gitignore index e9931c6b..8b622f6a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ /static/*.bundle.js.*.txt /grist-sessions.db /landing.db +/docs/ +/sandbox_venv* # Build helper files. /.build* diff --git a/README.md b/README.md index 24bafba3..0a8e6be9 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,7 @@ GRIST_BACKUP_DELAY_SECS | wait this long after a doc change before making a back GRIST_DATA_DIR | directory in which to store document caches. GRIST_DEFAULT_EMAIL | if set, login as this user if no other credentials presented GRIST_DEFAULT_PRODUCT | if set, this controls enabled features and limits of new sites. See names of PRODUCTS in Product.ts. +GRIST_DEFAULT_LOCALE | Locale to use as fallback when Grist cannot honour the browser locale. GRIST_DOMAIN | in hosted Grist, Grist is served from subdomains of this domain. Defaults to "getgrist.com". GRIST_EXPERIMENTAL_PLUGINS | enables experimental plugins GRIST_HIDE_UI_ELEMENTS | comma-separated list of parts of the UI to hide. Allowed names of parts: `helpCenter,billing,templates,multiSite,multiAccounts` diff --git a/app/client/models/ColumnToMap.ts b/app/client/models/ColumnToMap.ts index a086f526..48638e53 100644 --- a/app/client/models/ColumnToMap.ts +++ b/app/client/models/ColumnToMap.ts @@ -9,6 +9,8 @@ export class ColumnToMapImpl implements Required { public name: string; // Label to show instead of the name. public title: string; + // Human description of the column. + public description: string; // If column is optional (used only on the UI). public optional: boolean; // Type of the column that widget expects. @@ -20,6 +22,7 @@ export class ColumnToMapImpl implements Required { constructor(def: string|ColumnToMap) { this.name = typeof def === 'string' ? def : def.name; this.title = typeof def === 'string' ? def : (def.title ?? def.name); + 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(); diff --git a/app/client/ui/CustomSectionConfig.ts b/app/client/ui/CustomSectionConfig.ts index c36c60dd..f8e4cd65 100644 --- a/app/client/ui/CustomSectionConfig.ts +++ b/app/client/ui/CustomSectionConfig.ts @@ -4,7 +4,7 @@ import * as kf from 'app/client/lib/koForm'; import {ColumnToMapImpl} from 'app/client/models/ColumnToMap'; import {ColumnRec, ViewSectionRec} from 'app/client/models/DocModel'; import {reportError} from 'app/client/models/errors'; -import {cssLabel, cssRow, cssSeparator} from 'app/client/ui/RightPanelStyles'; +import {cssHelp, cssLabel, cssRow, cssSeparator} from 'app/client/ui/RightPanelStyles'; import {cssDragRow, cssFieldEntry, cssFieldLabel} from 'app/client/ui/VisibleFieldsConfig'; import {basicButton, primaryButton, textButton} from 'app/client/ui2018/buttons'; import {colors, vars} from 'app/client/ui2018/cssVars'; @@ -61,6 +61,10 @@ class ColumnPicker extends Disposable { this._column.optional ? cssSubLabel(" (optional)") : null, testId('label-for-' + this._column.name), ), + this._column.description ? cssHelp( + this._column.description, + testId('help-for-' + this._column.name), + ) : null, cssRow( select( properValue, diff --git a/app/client/ui/PageWidgetPicker.ts b/app/client/ui/PageWidgetPicker.ts index 92618bf4..bc58ef3f 100644 --- a/app/client/ui/PageWidgetPicker.ts +++ b/app/client/ui/PageWidgetPicker.ts @@ -469,11 +469,13 @@ const cssEntry = styled('div', ` align-items: center; white-space: nowrap; overflow: hidden; + cursor: pointer; &-selected { background-color: ${colors.mediumGrey}; } &-disabled { color: ${colors.mediumGrey}; + cursor: default; } &-disabled&-selected { background-color: inherit; diff --git a/app/client/ui/RightPanelStyles.ts b/app/client/ui/RightPanelStyles.ts index bbd94022..184e8ff1 100644 --- a/app/client/ui/RightPanelStyles.ts +++ b/app/client/ui/RightPanelStyles.ts @@ -13,6 +13,12 @@ export const cssLabel = styled('div', ` font-size: ${vars.xsmallFontSize}; `); +export const cssHelp = styled('div', ` + margin: -8px 16px 12px 16px; + font-style: italic; + font-size: ${vars.xsmallFontSize}; +`); + export const cssRow = styled('div', ` display: flex; margin: 8px 16px; diff --git a/app/plugin/CustomSectionAPI.ts b/app/plugin/CustomSectionAPI.ts index 51bb7873..2d1b68b9 100644 --- a/app/plugin/CustomSectionAPI.ts +++ b/app/plugin/CustomSectionAPI.ts @@ -11,6 +11,10 @@ export interface ColumnToMap { * Title or short description of a column (used as a label in section mapping). */ title?: string|null, + /** + * Optional long description of a column (used as a help text in section mapping). + */ + description?: string|null, /** * Column type, by default ANY. */ diff --git a/app/server/lib/ActiveDoc.ts b/app/server/lib/ActiveDoc.ts index 2b8d968a..b0889f4b 100644 --- a/app/server/lib/ActiveDoc.ts +++ b/app/server/lib/ActiveDoc.ts @@ -129,7 +129,7 @@ bluebird.promisifyAll(tmp); const MAX_RECENT_ACTIONS = 100; const DEFAULT_TIMEZONE = (process.versions as any).electron ? moment.tz.guess() : "UTC"; -const DEFAULT_LOCALE = "en-US"; +const DEFAULT_LOCALE = process.env.GRIST_DEFAULT_LOCALE || "en-US"; // Number of seconds an ActiveDoc is retained without any clients. // In dev environment, it is convenient to keep this low for quick tests. diff --git a/sandbox/grist/functions/date.py b/sandbox/grist/functions/date.py index c38651d7..5a24340a 100644 --- a/sandbox/grist/functions/date.py +++ b/sandbox/grist/functions/date.py @@ -292,7 +292,7 @@ def DATEVALUE(date_string, tz=None): >>> DATEVALUE("asdf") Traceback (most recent call last): ... - ValueError: Unknown string format + dateutil.parser._parser.ParserError: Unknown string format: asdf """ return dateutil.parser.parse(date_string).replace(tzinfo=_get_tzinfo(tz)) diff --git a/sandbox/requirements3.txt b/sandbox/requirements3.txt index 38fb0a18..f0e39250 100644 --- a/sandbox/requirements3.txt +++ b/sandbox/requirements3.txt @@ -13,7 +13,7 @@ backports.functools-lru-cache==1.6.4 chardet==4.0.0 enum34==1.1.10 et-xmlfile==1.0.1 -html5lib==0.999999999 +html5lib==1.1 iso8601==0.1.12 jdcal==1.4.1 json_table_schema==0.2.1 @@ -21,12 +21,12 @@ lazy_object_proxy==1.6.0 lxml==4.6.3 # used in csv plugin only? messytables==0.15.2 openpyxl==2.6.4 -python_dateutil==2.6.0 +python_dateutil==2.8.2 python_magic==0.4.12 roman==2.0.0 singledispatch==3.6.2 six==1.16.0 -sortedcontainers==1.5.7 +sortedcontainers==2.4.0 webencodings==0.5 wrapt==1.12.1 xlrd==1.2.0