mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Forms post-release fixes and improvements
Summary: Fixes misc. bugs with forms, updates Grist URLs on static form pages to link to the new forms marketing page, and adds a forms announcement popup that's shown next to the Add New button within a document. Test Plan: Browser tests. Reviewers: jarek Reviewed By: jarek Differential Revision: https://phab.getgrist.com/D4185
This commit is contained in:
@@ -45,4 +45,12 @@ AbstractWidget.prototype.buildColorConfigDom = function(gristDoc) {
|
||||
return dom.create(CellStyle, this.field, gristDoc, this.defaultTextColor);
|
||||
};
|
||||
|
||||
AbstractWidget.prototype.buildFormConfigDom = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
AbstractWidget.prototype.buildFormTransformConfigDom = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports = AbstractWidget;
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SingleCell } from 'app/common/TableData';
|
||||
import {KoSaveableObservable} from 'app/client/models/modelUtil';
|
||||
import {UploadResult} from 'app/common/uploads';
|
||||
import { GristObjCode } from 'app/plugin/GristData';
|
||||
import {Computed, dom, fromKo, input, onElem, styled} from 'grainjs';
|
||||
import {Computed, dom, DomContents, fromKo, input, onElem, styled} from 'grainjs';
|
||||
import {extname} from 'path';
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ export class AttachmentsWidget extends NewAbstractWidget {
|
||||
);
|
||||
}
|
||||
|
||||
public buildConfigDom(): Element {
|
||||
public buildConfigDom(): DomContents {
|
||||
const options = this.field.config.options;
|
||||
const height = options.prop('height');
|
||||
const inputRange = input(
|
||||
|
||||
@@ -9,8 +9,7 @@ import {icon} from 'app/client/ui2018/icons';
|
||||
import {ChoiceListEntry} from 'app/client/widgets/ChoiceListEntry';
|
||||
import {choiceToken, DEFAULT_BACKGROUND_COLOR, DEFAULT_COLOR} from 'app/client/widgets/ChoiceToken';
|
||||
import {NTextBox} from 'app/client/widgets/NTextBox';
|
||||
import {WidgetType} from 'app/common/widgetTypes';
|
||||
import {Computed, dom, styled, UseCB} from 'grainjs';
|
||||
import {Computed, dom, styled} from 'grainjs';
|
||||
|
||||
export type IChoiceOptions = Style
|
||||
export type ChoiceOptions = Record<string, IChoiceOptions | undefined>;
|
||||
@@ -75,37 +74,9 @@ export class ChoiceTextBox extends NTextBox {
|
||||
}
|
||||
|
||||
public buildConfigDom() {
|
||||
const disabled = Computed.create(null,
|
||||
use => use(this.field.disableModify)
|
||||
|| use(use(this.field.column).disableEditData)
|
||||
|| use(this.field.config.options.disabled('choices'))
|
||||
);
|
||||
|
||||
const mixed = Computed.create(null,
|
||||
use => !use(disabled)
|
||||
&& (use(this.field.config.options.mixed('choices')) || use(this.field.config.options.mixed('choiceOptions')))
|
||||
);
|
||||
|
||||
// If we are on forms, we don't want to show alignment options.
|
||||
const notForm = (use: UseCB) => {
|
||||
return use(use(this.field.viewSection).parentKey) !== WidgetType.Form;
|
||||
};
|
||||
|
||||
return [
|
||||
dom.maybe(notForm, () => super.buildConfigDom()),
|
||||
cssLabel(t('CHOICES')),
|
||||
cssRow(
|
||||
dom.autoDispose(disabled),
|
||||
dom.autoDispose(mixed),
|
||||
dom.create(
|
||||
ChoiceListEntry,
|
||||
this._choiceValues,
|
||||
this._choiceOptionsByName,
|
||||
this.save.bind(this),
|
||||
disabled,
|
||||
mixed
|
||||
)
|
||||
)
|
||||
super.buildConfigDom(),
|
||||
this._buildChoicesConfigDom(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -113,6 +84,19 @@ export class ChoiceTextBox extends NTextBox {
|
||||
return this.buildConfigDom();
|
||||
}
|
||||
|
||||
public buildFormConfigDom() {
|
||||
return [
|
||||
this._buildChoicesConfigDom(),
|
||||
super.buildFormConfigDom(),
|
||||
];
|
||||
}
|
||||
|
||||
public buildFormTransformConfigDom() {
|
||||
return [
|
||||
this._buildChoicesConfigDom(),
|
||||
];
|
||||
}
|
||||
|
||||
protected getChoiceValuesSet(): Computed<Set<string>> {
|
||||
return this._choiceValuesSet;
|
||||
}
|
||||
@@ -128,6 +112,35 @@ export class ChoiceTextBox extends NTextBox {
|
||||
};
|
||||
return this.field.config.updateChoices(renames, options);
|
||||
}
|
||||
|
||||
private _buildChoicesConfigDom() {
|
||||
const disabled = Computed.create(null,
|
||||
use => use(this.field.disableModify)
|
||||
|| use(use(this.field.column).disableEditData)
|
||||
|| use(this.field.config.options.disabled('choices'))
|
||||
);
|
||||
|
||||
const mixed = Computed.create(null,
|
||||
use => !use(disabled)
|
||||
&& (use(this.field.config.options.mixed('choices')) || use(this.field.config.options.mixed('choiceOptions')))
|
||||
);
|
||||
|
||||
return [
|
||||
cssLabel(t('CHOICES')),
|
||||
cssRow(
|
||||
dom.autoDispose(disabled),
|
||||
dom.autoDispose(mixed),
|
||||
dom.create(
|
||||
ChoiceListEntry,
|
||||
this._choiceValues,
|
||||
this._choiceOptionsByName,
|
||||
this.save.bind(this),
|
||||
disabled,
|
||||
mixed
|
||||
)
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a POJO containing choice options to an ES6 Map
|
||||
|
||||
@@ -6,11 +6,12 @@ var kd = require('../lib/koDom');
|
||||
var kf = require('../lib/koForm');
|
||||
var AbstractWidget = require('./AbstractWidget');
|
||||
|
||||
const {FieldRulesConfig} = require('app/client/components/Forms/FormConfig');
|
||||
const {fromKoSave} = require('app/client/lib/fromKoSave');
|
||||
const {alignmentSelect, cssButtonSelect} = require('app/client/ui2018/buttonSelect');
|
||||
const {cssRow, cssLabel} = require('app/client/ui/RightPanelStyles');
|
||||
const {cssLabel, cssRow} = require('app/client/ui/RightPanelStyles');
|
||||
const {cssTextInput} = require("app/client/ui2018/editableLabel");
|
||||
const {styled, fromKo} = require('grainjs');
|
||||
const {dom: gdom, styled, fromKo} = require('grainjs');
|
||||
const {select} = require('app/client/ui2018/menus');
|
||||
const {dateFormatOptions} = require('app/common/parseDate');
|
||||
|
||||
@@ -79,6 +80,12 @@ DateTextBox.prototype.buildTransformConfigDom = function() {
|
||||
return this.buildDateConfigDom();
|
||||
};
|
||||
|
||||
DateTextBox.prototype.buildFormConfigDom = function() {
|
||||
return [
|
||||
gdom.create(FieldRulesConfig, this.field),
|
||||
];
|
||||
};
|
||||
|
||||
DateTextBox.prototype.buildDom = function(row) {
|
||||
let value = row[this.field.colId()];
|
||||
return dom('div.field_clip',
|
||||
|
||||
@@ -305,7 +305,7 @@ export class FieldBuilder extends Disposable {
|
||||
}
|
||||
|
||||
if (op.label === 'Reference') {
|
||||
return this.gristDoc.behavioralPromptsManager.attachTip('referenceColumns', {
|
||||
return this.gristDoc.behavioralPromptsManager.attachPopup('referenceColumns', {
|
||||
popupOptions: {
|
||||
attach: `.${cssTypeSelectMenu.className}`,
|
||||
placement: 'left-start',
|
||||
@@ -412,7 +412,7 @@ export class FieldBuilder extends Disposable {
|
||||
return [
|
||||
cssLabel(t('DATA FROM TABLE'),
|
||||
kd.maybe(this._showRefConfigPopup, () => {
|
||||
return dom('div', this.gristDoc.behavioralPromptsManager.attachTip(
|
||||
return dom('div', this.gristDoc.behavioralPromptsManager.attachPopup(
|
||||
'referenceColumnsConfig',
|
||||
{
|
||||
onDispose: () => this._showRefConfigPopup(false),
|
||||
@@ -501,6 +501,14 @@ export class FieldBuilder extends Disposable {
|
||||
);
|
||||
}
|
||||
|
||||
public buildFormConfigDom() {
|
||||
return dom('div',
|
||||
kd.maybe(() => !this._isTransformingType() && this.widgetImpl(), (widget: NewAbstractWidget) =>
|
||||
dom('div', widget.buildFormConfigDom())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the FieldBuilder Options Config DOM. Calls the buildConfigDom function of its widgetImpl.
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FieldRulesConfig } from 'app/client/components/Forms/FormConfig';
|
||||
import { fromKoSave } from 'app/client/lib/fromKoSave';
|
||||
import { DataRowModel } from 'app/client/models/DataRowModel';
|
||||
import { ViewFieldRec } from 'app/client/models/entities/ViewFieldRec';
|
||||
@@ -51,10 +52,16 @@ export class NTextBox extends NewAbstractWidget {
|
||||
[{value: true, icon: 'Wrap'}],
|
||||
toggle,
|
||||
cssButtonSelect.cls('-disabled', wrapDisabled),
|
||||
),
|
||||
testId('tb-wrap-text')
|
||||
)
|
||||
)
|
||||
),
|
||||
testId('tb-wrap-text'),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
public buildFormConfigDom(): DomContents {
|
||||
return [
|
||||
dom.create(FieldRulesConfig, this.field),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,14 @@ export abstract class NewAbstractWidget extends Disposable {
|
||||
return dom.create(CellStyle, this.field, gristDoc, this.defaultTextColor);
|
||||
}
|
||||
|
||||
public buildFormConfigDom(): DomContents {
|
||||
return null;
|
||||
}
|
||||
|
||||
public buildFormTransformConfigDom(): DomContents {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the data cell DOM.
|
||||
* @param {DataRowModel} row - The rowModel object.
|
||||
|
||||
@@ -9,9 +9,8 @@ import {icon} from 'app/client/ui2018/icons';
|
||||
import {IOptionFull, select} from 'app/client/ui2018/menus';
|
||||
import {NTextBox} from 'app/client/widgets/NTextBox';
|
||||
import {isFullReferencingType, isVersions} from 'app/common/gristTypes';
|
||||
import {WidgetType} from 'app/common/widgetTypes';
|
||||
import {UIRowId} from 'app/plugin/GristAPI';
|
||||
import {Computed, dom, styled, UseCB} from 'grainjs';
|
||||
import {Computed, dom, styled} from 'grainjs';
|
||||
|
||||
|
||||
const t = makeT('Reference');
|
||||
@@ -49,16 +48,10 @@ export class Reference extends NTextBox {
|
||||
}
|
||||
|
||||
public buildConfigDom() {
|
||||
// If we are on forms, we don't want to show alignment options.
|
||||
const notForm = (use: UseCB) => {
|
||||
return use(use(this.field.viewSection).parentKey) !== WidgetType.Form;
|
||||
};
|
||||
return [
|
||||
this.buildTransformConfigDom(),
|
||||
dom.maybe(notForm, () => [
|
||||
cssLabel(t('CELL FORMAT')),
|
||||
super.buildConfigDom()
|
||||
])
|
||||
cssLabel(t('CELL FORMAT')),
|
||||
super.buildConfigDom(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -76,6 +69,17 @@ export class Reference extends NTextBox {
|
||||
];
|
||||
}
|
||||
|
||||
public buildFormConfigDom() {
|
||||
return [
|
||||
this.buildTransformConfigDom(),
|
||||
super.buildFormConfigDom(),
|
||||
];
|
||||
}
|
||||
|
||||
public buildFormTransformConfigDom() {
|
||||
return this.buildTransformConfigDom();
|
||||
}
|
||||
|
||||
public buildDom(row: DataRowModel) {
|
||||
// Note: we require 2 observables here because changes to the cell value (reference id)
|
||||
// and the display value (display column) are not bundled. This can cause `formattedValue`
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
import * as commands from 'app/client/components/commands';
|
||||
import { FieldRulesConfig } from 'app/client/components/Forms/FormConfig';
|
||||
import { DataRowModel } from 'app/client/models/DataRowModel';
|
||||
import { ViewFieldRec } from 'app/client/models/entities/ViewFieldRec';
|
||||
import { KoSaveableObservable } from 'app/client/models/modelUtil';
|
||||
import { NewAbstractWidget, Options } from 'app/client/widgets/NewAbstractWidget';
|
||||
import { theme } from 'app/client/ui2018/cssVars';
|
||||
import { dom } from 'grainjs';
|
||||
import { dom, DomContents } from 'grainjs';
|
||||
|
||||
/**
|
||||
* ToggleBase - The base class for toggle widgets, such as a checkbox or a switch.
|
||||
*/
|
||||
abstract class ToggleBase extends NewAbstractWidget {
|
||||
public buildFormConfigDom(): DomContents {
|
||||
return [
|
||||
dom.create(FieldRulesConfig, this.field),
|
||||
];
|
||||
}
|
||||
|
||||
protected _addClickEventHandlers(row: DataRowModel) {
|
||||
return [
|
||||
dom.on('click', (event) => {
|
||||
|
||||
Reference in New Issue
Block a user