(core) Implement UI for trigger formulas.

Summary:
- Implement UI with "Apply to new records" and "Apply on record changes"
  checkboxes, and options for selecting which changes to recalculate on.
- For consistency, always represent empty RefList as None
- Fix up generated SchemaTypes to remember that values are encoded.

Included test cases for the main planned use cases:
- Auto-filled UUID column
- Data cleaning
- NOW() formula for record's last-updated timestamp.
- Updates that depend on other columns.

Test Plan: Added a browser test.

Reviewers: jarek

Reviewed By: jarek

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D2885
This commit is contained in:
Dmitry S
2021-06-29 00:47:59 -04:00
parent e180641c7d
commit b537539b73
12 changed files with 372 additions and 53 deletions

View File

@@ -3,6 +3,7 @@ import { colors, testId, vars } from 'app/client/ui2018/cssVars';
import { textInput } from "app/client/ui2018/editableLabel";
import { icon } from "app/client/ui2018/icons";
import { isValidHex } from "app/common/gutil";
import { cssSelectBtn } from 'app/client/ui2018/select';
import { Computed, Disposable, dom, DomArg, Observable, onKeyDown, styled } from "grainjs";
import { defaultMenuOptions, IOpenController, setPopupToCreateDom } from "popweasel";
@@ -315,17 +316,5 @@ const cssColorSquare = styled('div', `
const cssButtonIcon = styled(cssColorSquare, `
margin-right: 6px;
`);
const cssSelectBtn = styled('div', `
display: flex;
width: 100%;
height: 30px;
justify-content: space-between;
border-radius: 3px;
border: 1px solid #D9D9D9;
padding: 5px 9px;
user-select: none;
cursor: pointer;
background-color: white;
margin-left: 4px;
`);

View File

@@ -120,7 +120,7 @@ export const cssLabelText = styled('span', `
type CheckboxArg = DomArg<HTMLInputElement>;
function checkbox(
obs: Observable<boolean>, cssCheckbox: typeof cssCheckboxSquare, label: string = '', ...domArgs: CheckboxArg[]
obs: Observable<boolean>, cssCheckbox: typeof cssCheckboxSquare, label: DomArg = '', ...domArgs: CheckboxArg[]
) {
return cssLabel(
cssCheckbox(
@@ -141,11 +141,11 @@ export function circleCheckbox(obs: Observable<boolean>, ...domArgs: CheckboxArg
return checkbox(obs, cssCheckboxCircle, '', ...domArgs);
}
export function labeledSquareCheckbox(obs: Observable<boolean>, label: string, ...domArgs: CheckboxArg[]) {
export function labeledSquareCheckbox(obs: Observable<boolean>, label: DomArg, ...domArgs: CheckboxArg[]) {
return checkbox(obs, cssCheckboxSquare, label, ...domArgs);
}
export function labeledCircleCheckbox(obs: Observable<boolean>, label: string, ...domArgs: CheckboxArg[]) {
export function labeledCircleCheckbox(obs: Observable<boolean>, label: DomArg, ...domArgs: CheckboxArg[]) {
return checkbox(obs, cssCheckboxCircle, label, ...domArgs);
}

View File

@@ -1,6 +1,7 @@
import {Command} from 'app/client/components/commands';
import {NeedUpgradeError, reportError} from 'app/client/models/errors';
import {colors, testId, vars} from 'app/client/ui2018/cssVars';
import {cssSelectBtn} from 'app/client/ui2018/select';
import {IconName} from 'app/client/ui2018/IconList';
import {icon} from 'app/client/ui2018/icons';
import {commonUrls} from 'app/common/gristUrls';
@@ -280,24 +281,6 @@ const cssSelectBtnContainer = styled('div', `
width: 100%;
`);
const cssSelectBtn = styled('div', `
width: 100%;
height: 30px;
line-height: 16px;
background-color: white;
font-size: ${vars.mediumFontSize};
padding: 5px;
border: 1px solid ${colors.darkGrey};
color: ${colors.dark};
--icon-color: ${colors.dark};
border-radius: 3px;
cursor: pointer;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
display: flex;
`);
const cssSelectBtnLink = styled('div', `
display: flex;
align-items: center;

View File

@@ -0,0 +1,48 @@
import {colors, vars} from 'app/client/ui2018/cssVars';
import {styled} from 'grainjs';
// Import popweasel so that the styles we define here are included later in CSS, and take priority
// over popweasel styles, when used together.
import 'popweasel';
/**
* Style for a select dropdown button.
*
* This incorporates styling from popweasel's select, so that it can be used to style buttons that
* don't use it.
*/
export const cssSelectBtn = styled('div', `
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 30px;
line-height: 16px;
background-color: white;
color: ${colors.dark};
--icon-color: ${colors.dark};
font-size: ${vars.mediumFontSize};
padding: 5px;
border: 1px solid ${colors.darkGrey};
border-radius: 3px;
cursor: pointer;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-webkit-appearance: none;
-moz-appearance: none;
user-select: none;
-moz-user-select: none;
outline: none;
&:focus {
outline: none;
box-shadow: 0px 0px 2px 2px #5E9ED6;
}
&.disabled {
color: grey;
cursor: pointer;
}
`);