Skip to content

Commit 81c5270

Browse files
committed
(core) updates from grist-core
2 parents 4fa78b6 + 64716e8 commit 81c5270

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+711
-421
lines changed

app/client/aclui/AccessRules.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {
4242
UserAttributeRule
4343
} from 'app/common/GranularAccessClause';
4444
import {getDefaultForType, isHiddenCol} from 'app/common/gristTypes';
45-
import {isNonNullish, unwrap} from 'app/common/gutil';
45+
import {isNonNullish, localeCompare, unwrap} from 'app/common/gutil';
4646
import {EmptyRecordView, InfoView, RecordView} from 'app/common/RecordView';
4747
import {
4848
getPredicateFormulaProperties,
@@ -129,6 +129,7 @@ export class AccessRules extends Disposable {
129129

130130
// Array of all per-table rules.
131131
private _tableRules = this.autoDispose(obsArray<TableRules>());
132+
private _sortedTableRules: Computed<TableRules[]>;
132133

133134
// The default rule set for the document (for "*:*").
134135
private _docDefaultRuleSet = Observable.create<DefaultObsRuleSet|null>(this, null);
@@ -184,6 +185,12 @@ export class AccessRules extends Disposable {
184185
);
185186
});
186187

188+
this._sortedTableRules = Computed.create(this, (use) =>
189+
[...use(this._tableRules)].sort((a, b) =>
190+
localeCompare(a.tableId, b.tableId)
191+
)
192+
);
193+
187194
this._savingEnabled = Computed.create(this, this._ruleStatus, (use, s) =>
188195
(s === RuleStatus.ChangedValid));
189196

@@ -253,7 +260,6 @@ export class AccessRules extends Disposable {
253260
this._tableRules.set(
254261
rules.getAllTableIds()
255262
.filter(tableId => (tableId !== SPECIAL_RULES_TABLE_ID))
256-
.sort((a, b) => a.localeCompare(b))
257263
.map(tableId => TableRules.create(this._tableRules,
258264
tableId, this, rules.getAllColumnRuleSets(tableId), rules.getTableDefaultRuleSet(tableId)))
259265
);
@@ -480,7 +486,7 @@ export class AccessRules extends Disposable {
480486
),
481487
),
482488
),
483-
dom.forEach(this._tableRules, (tableRules) => tableRules.buildDom()),
489+
dom.forEach(this._sortedTableRules, (tableRules) => tableRules.buildDom()),
484490
cssSection(
485491
cssSectionHeading(t("Default Rules"), testId('rule-table-header')),
486492
dom.maybe(this._specialRulesWithDefault, tableRules => cssSeedRule(

app/client/components/Forms/Field.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import {
1717
} from 'app/client/ui/FormAPI';
1818
import {autoGrow} from 'app/client/ui/forms';
1919
import {cssCheckboxSquare, cssLabel, squareCheckbox} from 'app/client/ui2018/checkbox';
20-
import {colors} from 'app/client/ui2018/cssVars';
2120
import {cssRadioInput} from 'app/client/ui2018/radio';
21+
import {toggleSwitch} from 'app/client/ui2018/toggleSwitch';
2222
import {isBlankValue} from 'app/common/gristTypes';
2323
import {Constructor, not} from 'app/common/gutil';
2424
import {
@@ -487,12 +487,7 @@ class BoolModel extends Question {
487487
}
488488

489489
private _renderSwitchInput() {
490-
return css.cssWidgetSwitch(
491-
dom.style('--grist-actual-cell-color', colors.lightGreen.toString()),
492-
dom.cls('switch_transition'),
493-
dom('div.switch_slider'),
494-
dom('div.switch_circle'),
495-
);
490+
return toggleSwitch();
496491
}
497492

498493
private _renderCheckboxInput() {

app/client/components/Forms/styles.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,6 @@ export const cssTextArea = styled('textarea', `
262262

263263
export const cssSpinner = styled(numericSpinner, `
264264
height: 29px;
265-
266-
&-hidden {
267-
color: ${theme.inputDisabledFg};
268-
background-color: ${theme.inputDisabledBg};
269-
}
270265
`);
271266

272267
export const cssSelect = styled('select', `
@@ -290,12 +285,6 @@ export const cssToggle = styled('div', `
290285
--grist-actual-cell-color: ${colors.lightGreen};
291286
`);
292287

293-
export const cssWidgetSwitch = styled('div.widget_switch', `
294-
&-hidden {
295-
opacity: 0.6;
296-
}
297-
`);
298-
299288
export const cssWarningMessage = styled('div', `
300289
margin-top: 8px;
301290
display: flex;

app/client/components/RegionFocusSwitcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ const isSpecialPage = (doc: GristDoc | null) => {
662662
return false;
663663
};
664664

665-
const cssFocusedPanel = styled('div', `
665+
export const cssFocusedPanel = styled('div', `
666666
&-focused:focus {
667667
outline: 3px solid ${components.kbFocusHighlight} !important;
668668
outline-offset: -3px !important;

app/client/formMain.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ import {createPage} from 'app/client/ui/createPage';
22
import {FormPage} from 'app/client/ui/FormPage';
33
import {dom} from 'grainjs';
44

5-
createPage(() => dom.create(FormPage), {disableTheme: true});
5+
createPage(() => {
6+
document.documentElement.setAttribute('data-grist-form', '');
7+
return dom.create(FormPage);
8+
}, {disableTheme: true});

app/client/ui/AccountWidget.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {createUserImage} from 'app/client/ui/UserImage';
77
import * as viewport from 'app/client/ui/viewport';
88
import {bigPrimaryButtonLink, primaryButtonLink} from 'app/client/ui2018/buttons';
99
import {mediaDeviceNotSmall, testId, theme, vars} from 'app/client/ui2018/cssVars';
10+
import {unstyledButton} from 'app/client/ui2018/unstyled';
1011
import {icon} from 'app/client/ui2018/icons';
1112
import {
1213
menu,
@@ -280,11 +281,12 @@ const cssAccountWidget = styled('div', `
280281
white-space: nowrap;
281282
`);
282283

283-
export const cssUserIcon = styled('div', `
284+
export const cssUserIcon = styled(unstyledButton, `
284285
height: 48px;
285286
width: 48px;
286287
padding: 8px;
287288
cursor: pointer;
289+
outline-offset: -3px;
288290
`);
289291

290292
const cssUserInfo = styled('div', `

app/client/ui/AddNewButton.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {theme, vars} from 'app/client/ui2018/cssVars';
22
import {makeT} from 'app/client/lib/localization';
33
import {icon} from 'app/client/ui2018/icons';
4+
import {unstyledButton} from 'app/client/ui2018/unstyled';
45
import {dom, DomElementArg, Observable, styled} from "grainjs";
56

67
const t = makeT(`AddNewButton`);
@@ -31,7 +32,7 @@ export function addNewButton(
3132
);
3233
}
3334

34-
export const cssAddNewButton = styled('div', `
35+
export const cssAddNewButton = styled(unstyledButton, `
3536
display: flex;
3637
align-items: center;
3738
margin: 22px 0px 22px 0px;
@@ -46,6 +47,10 @@ export const cssAddNewButton = styled('div', `
4647
font-weight: bold;
4748
overflow: hidden;
4849
50+
/* make sure keyboard highlight is not glued to the button,
51+
as it is the same color as the button background */
52+
outline-offset: 2px;
53+
4954
--circle-color: ${theme.addNewCircleSmallBg};
5055
5156
&:hover, &.weasel-popup-open {

app/client/ui/AdminPanel.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import {ToggleEnterpriseWidget} from 'app/client/ui/ToggleEnterpriseWidget';
1919
import {createTopBarHome} from 'app/client/ui/TopBar';
2020
import {cssBreadcrumbs, separator} from 'app/client/ui2018/breadcrumbs';
2121
import {basicButton} from 'app/client/ui2018/buttons';
22-
import {toggle} from 'app/client/ui2018/checkbox';
2322
import {mediaSmall, testId, theme, vars} from 'app/client/ui2018/cssVars';
2423
import {cssLink, makeLinks} from 'app/client/ui2018/links';
24+
import {toggleSwitch} from 'app/client/ui2018/toggleSwitch';
2525
import {BootProbeInfo, BootProbeResult, SandboxingBootProbeDetails} from 'app/common/BootProbe';
2626
import {AdminPanelPage, commonUrls, getPageTitleSuffix, LatestVersionAvailable} from 'app/common/gristUrls';
2727
import {InstallAPI, InstallAPIImpl} from 'app/common/InstallAPI';
@@ -148,7 +148,11 @@ Please log in as an administrator.`)),
148148
id: 'telemetry',
149149
name: t('Telemetry'),
150150
description: t('Help us make Grist better'),
151-
value: dom.create(HidableToggle, this._supportGrist.getTelemetryOptInObservable()),
151+
value: dom.create(
152+
HidableToggle,
153+
this._supportGrist.getTelemetryOptInObservable(),
154+
{labelId: 'admin-panel-item-description-telemetry'}
155+
),
152156
expandedContent: this._supportGrist.buildTelemetrySection(),
153157
}),
154158
dom.create(AdminSectionItem, {
@@ -218,7 +222,11 @@ Please log in as an administrator.`)),
218222
return null;
219223
}
220224

221-
let makeToggle = () => dom.create(HidableToggle, this._toggleEnterprise.getEnterpriseToggleObservable());
225+
let makeToggle = () => dom.create(
226+
HidableToggle,
227+
this._toggleEnterprise.getEnterpriseToggleObservable(),
228+
{labelId: 'admin-panel-item-description-enterprise'}
229+
);
222230

223231
// If the enterprise edition is forced, we don't show the toggle.
224232
if (getGristConfig().forceEnableEnterprise) {
@@ -527,8 +535,11 @@ in the future as session IDs generated since v1.1.16 are inherently cryptographi
527535
)),
528536
dom.domComputed(allowAutomaticVersionChecking, (allowAutomaticChecks) =>
529537
allowAutomaticChecks ? cssExpandedContent(
530-
dom('span', t('Auto-check weekly')),
531-
dom( 'div', toggle(enabledController, testId('admin-panel-updates-auto-check')))
538+
dom('label', t('Auto-check weekly'), {for: 'admin-panel-updates-auto-check-switch'}),
539+
dom('div', toggleSwitch(enabledController, {
540+
args: [testId('admin-panel-updates-auto-check')],
541+
inputArgs: [{id: 'admin-panel-updates-auto-check-switch'}],
542+
}))
532543
) :
533544
cssExpandedContent(
534545
dom('span', t('Automatic checks are disabled. \

app/client/ui/AdminPanelCss.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
import {hoverTooltip} from 'app/client/ui/tooltips';
22
import {transition} from 'app/client/ui/transitions';
3-
import {toggle} from 'app/client/ui2018/checkbox';
3+
import {toggleSwitch} from 'app/client/ui2018/toggleSwitch';
44
import {mediaSmall, testId, theme, vars} from 'app/client/ui2018/cssVars';
55
import {icon} from 'app/client/ui2018/icons';
66
import {dom, DomContents, DomElementArg, IDisposableOwner, Observable, styled} from 'grainjs';
77

8-
export function HidableToggle(owner: IDisposableOwner, value: Observable<boolean|null>) {
9-
return toggle(value, dom.hide((use) => use(value) === null));
8+
export function HidableToggle(
9+
owner: IDisposableOwner,
10+
value: Observable<boolean|null>,
11+
options: {labelId?: string} = {}
12+
) {
13+
return toggleSwitch(value, {
14+
args: [dom.hide((use) => use(value) === null)],
15+
inputArgs: [options.labelId ? {"aria-labelledby": options.labelId} : undefined],
16+
});
1017
}
1118

1219
export function AdminSection(owner: IDisposableOwner, title: DomContents, items: DomElementArg[]) {
@@ -51,7 +58,7 @@ export function AdminSectionItem(owner: IDisposableOwner, options: {
5158
}, 0);
5259
},
5360
),
54-
cssItemDescription(options.description),
61+
cssItemDescription(options.description, {id: `admin-panel-item-description-${options.id}`}),
5562
cssItemValue(options.value,
5663
testId(`admin-panel-item-value-${options.id}`),
5764
dom.on('click', ev => ev.stopPropagation())),

app/client/ui/AppHeader.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import {getWelcomeHomeUrl, urlState} from 'app/client/models/gristUrlState';
22
import {getTheme} from 'app/client/ui/CustomThemes';
33
import {cssLeftPane} from 'app/client/ui/PagePanels';
44
import {colors, theme, vars} from 'app/client/ui2018/cssVars';
5-
import * as version from 'app/common/version';
65
import {menu, menuItem, menuItemLink, menuSubHeader} from 'app/client/ui2018/menus';
76
import {commonUrls} from 'app/common/gristUrls';
87
import {getOrgName, isTemplatesOrg, Organization} from 'app/common/UserAPI';
98
import {AppModel} from 'app/client/models/AppModel';
109
import {icon} from 'app/client/ui2018/icons';
10+
import {unstyledButton} from 'app/client/ui2018/unstyled';
1111
import {DocPageModel} from 'app/client/models/DocPageModel';
1212
import * as roles from 'app/common/roles';
1313
import {manageTeamUsersApp} from 'app/client/ui/OpenUserManager';
@@ -81,7 +81,7 @@ export class AppHeader extends Disposable {
8181
// Check if we have a custom image.
8282
const customImage = this._appModel.currentOrg?.orgPrefs?.customLogoUrl;
8383

84-
const variant = () => [cssUserImage.cls('-border'), cssUserImage.cls('-square')];
84+
const variant = () => [cssUserImage.cls('-border'), cssUserImage.cls('-square'), cssUserImage.cls('-inAppLogo')];
8585

8686
// Personal avatar is shown only for logged in users.
8787
const personalAvatar = () => !this._appModel.currentValidUser
@@ -108,18 +108,13 @@ export class AppHeader extends Disposable {
108108
? null
109109
: image();
110110

111-
const title = `Version ${version.version}` +
112-
((version.gitcommit as string) !== 'unknown' ? ` (${version.gitcommit})` : '');
111+
const altText = t('{{ organizationName }} - Back to home', { organizationName: this._appLogoOrg.get().name });
113112

114113
return cssAppHeader(
115114
cssAppHeader.cls('-widelogo', productFlavor.wideLogo || false),
116115
cssAppHeaderBox(
117116
dom.domComputed(this._appLogoOrgLink, orgLink => cssAppLogo(
118-
// Show version when hovering over the application icon.
119-
// Include gitcommit when known. Cast version.gitcommit since, depending
120-
// on how Grist is compiled, tsc may believe it to be a constant and
121-
// believe that testing it is unnecessary.
122-
{title},
117+
{'aria-label': altText},
123118
this._setHomePageUrl(orgLink),
124119
content(),
125120
testId('logo'),
@@ -141,6 +136,7 @@ export class AppHeader extends Disposable {
141136
);
142137
} else {
143138
return cssOrg(
139+
dom.cls('_cssOrg'),
144140
cssOrgName(dom.text(this._appLogoOrgName), testId('orgname')),
145141
productPill(this._currentOrg),
146142
dom.maybe(this._appLogoOrgName, () => [
@@ -277,7 +273,7 @@ export function productPill(org: Organization|null, options: {large?: boolean} =
277273
}
278274

279275

280-
const cssAppHeader = styled('div._cssAppHeader', `
276+
const cssAppHeader = styled('header._cssAppHeader', `
281277
width: 100%;
282278
height: 100%;
283279
background-color: ${theme.leftPanelBg};
@@ -330,7 +326,11 @@ const cssAppLogo = styled('a._cssAppLogo', `
330326
overflow: hidden;
331327
border-right-color: var(--middle-border-color, ${theme.appHeaderBorder});
332328
333-
outline-offset: -1px;
329+
/* make sure keyboard highlight is visible
330+
(it wouldn't be without the offset because of the overflow: hidden) */
331+
outline-offset: -3px;
332+
position: relative;
333+
z-index: 1;
334334
335335
&-grist-logo {
336336
background-image: var(--icon-GristLogo);
@@ -361,7 +361,7 @@ const cssAppLogo = styled('a._cssAppLogo', `
361361
}
362362
`);
363363

364-
const cssOrg = styled('div._cssOrg', `
364+
const cssOrg = styled(unstyledButton, `
365365
display: none;
366366
flex-grow: 1;
367367
flex-basis: 0px;
@@ -377,6 +377,10 @@ const cssOrg = styled('div._cssOrg', `
377377
border-bottom-left-radius: 0;
378378
border-left: 0px;
379379
380+
/* make sure keyboard highlight is visible
381+
(it wouldn't be without the offset because of the overflow: hidden) */
382+
outline-offset: -3px;
383+
380384
&:hover {
381385
border-color: ${theme.appHeaderBorderHover};
382386
}

0 commit comments

Comments
 (0)