From a493725d4fb45ee1731492d65bbfa71b72c4abfa Mon Sep 17 00:00:00 2001 From: Emmanuel Pelletier Date: Mon, 3 Feb 2025 17:18:15 +0100 Subject: [PATCH 1/5] (i18n) add locale strings for the "view as" banner --- app/client/components/ViewAsBanner.ts | 6 +++--- static/locales/en.client.json | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/client/components/ViewAsBanner.ts b/app/client/components/ViewAsBanner.ts index b02bc087cb..18fc78fd9e 100644 --- a/app/client/components/ViewAsBanner.ts +++ b/app/client/components/ViewAsBanner.ts @@ -16,7 +16,7 @@ import { ACLUsersPopup } from 'app/client/aclui/ACLUsers'; import { UserOverride } from 'app/common/DocListAPI'; import { makeT } from 'app/client/lib/localization'; -const t = makeT('components.ViewAsBanner'); +const t = makeT('ViewAsBanner'); export class ViewAsBanner extends Disposable { @@ -45,7 +45,7 @@ export class ViewAsBanner extends Disposable { return cssContent( cssMessageText( cssMessageIcon('EyeShow'), - 'You are viewing this document as', + t('You are viewing this document as'), ), cssSelectBtn( {tabIndex: '0'}, @@ -63,7 +63,7 @@ export class ViewAsBanner extends Disposable { testId('select-open'), ), cssPrimaryButtonLink( - 'View as Yourself', cssIcon('Convert'), + t('View as Yourself'), cssIcon('Convert'), urlState().setHref(userOverrideParams(null)), testId('revert'), ), diff --git a/static/locales/en.client.json b/static/locales/en.client.json index 0a6b5762f4..f02953ff84 100644 --- a/static/locales/en.client.json +++ b/static/locales/en.client.json @@ -850,7 +850,9 @@ "Update formula (Shift+Enter)": "Update formula (Shift+Enter)" }, "ViewAsBanner": { - "UnknownUser": "Unknown User" + "UnknownUser": "Unknown User", + "View as Yourself": "View as Yourself", + "You are viewing this document as": "You are viewing this document as" }, "ViewConfigTab": { "Advanced settings": "Advanced settings", From 8393b1af76d364a9205d6d1a3e89d6656ce1897d Mon Sep 17 00:00:00 2001 From: Emmanuel Pelletier Date: Mon, 3 Feb 2025 17:20:08 +0100 Subject: [PATCH 2/5] (i18n) use existing translation strings for acl roles in the "view as" banner, the role strings (owner, editor, viewer) were not translated and we can re-use the ones defined in the UserManagerModel (i guess?). --- app/client/aclui/ACLUsers.ts | 3 ++- app/client/components/ViewAsBanner.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/client/aclui/ACLUsers.ts b/app/client/aclui/ACLUsers.ts index 3131de5d5d..ff9359923c 100644 --- a/app/client/aclui/ACLUsers.ts +++ b/app/client/aclui/ACLUsers.ts @@ -18,6 +18,7 @@ import {waitGrainObs} from 'app/common/gutil'; import noop from 'lodash/noop'; const t = makeT("ViewAsDropdown"); +const userT = makeT('UserManagerModel'); function isSpecialEmail(email: string) { return email === ANONYMOUS_USER_EMAIL || email === EVERYONE_EMAIL; @@ -127,7 +128,7 @@ export class ACLUsersPopup extends Disposable { ), cssMemberText( cssMemberPrimary(user.name || dom('span', user.email), - cssRole('(', getUserRoleText(user), ')', testId('acl-user-access')), + cssRole('(', userT(getUserRoleText(user)), ')', testId('acl-user-access')), ), user.name ? cssMemberSecondary(user.email) : null ), diff --git a/app/client/components/ViewAsBanner.ts b/app/client/components/ViewAsBanner.ts index 18fc78fd9e..cf7d9063ad 100644 --- a/app/client/components/ViewAsBanner.ts +++ b/app/client/components/ViewAsBanner.ts @@ -17,6 +17,7 @@ import { UserOverride } from 'app/common/DocListAPI'; import { makeT } from 'app/client/lib/localization'; const t = makeT('ViewAsBanner'); +const userT = makeT('UserManagerModel'); export class ViewAsBanner extends Disposable { @@ -52,7 +53,7 @@ export class ViewAsBanner extends Disposable { cssBtnText( user ? cssMember( user.name || user.email, - cssRole('(', getUserRoleText({...user, access}), ')', dom.show(Boolean(access))), + cssRole('(', userT(getUserRoleText({...user, access})), ')', dom.show(Boolean(access))), ) : t('UnknownUser'), ), dom( From 8ecfe3c76c72672aa938afe455b1bb9637869b90 Mon Sep 17 00:00:00 2001 From: Emmanuel Pelletier Date: Mon, 3 Feb 2025 18:41:15 +0100 Subject: [PATCH 3/5] (acl) adding a tooltip helping user understand the "view as" screen --- app/client/components/ViewAsBanner.ts | 18 ++++++++++++++---- app/client/ui/GristTooltips.ts | 7 ++++++- app/client/ui/tooltips.ts | 16 +++++++++++++--- static/locales/en.client.json | 3 ++- test/nbrowser/AccessRules2.ts | 1 + 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/app/client/components/ViewAsBanner.ts b/app/client/components/ViewAsBanner.ts index cf7d9063ad..1f8a710498 100644 --- a/app/client/components/ViewAsBanner.ts +++ b/app/client/components/ViewAsBanner.ts @@ -15,6 +15,7 @@ import { cssSelectBtn } from 'app/client/ui2018/select'; import { ACLUsersPopup } from 'app/client/aclui/ACLUsers'; import { UserOverride } from 'app/common/DocListAPI'; import { makeT } from 'app/client/lib/localization'; +import { cssInfoTooltipButton, withInfoTooltip } from 'app/client/ui/tooltips'; const t = makeT('ViewAsBanner'); const userT = makeT('UserManagerModel'); @@ -63,10 +64,19 @@ export class ViewAsBanner extends Disposable { elem => this._usersPopup.attachPopup(elem, {}), testId('select-open'), ), - cssPrimaryButtonLink( - t('View as Yourself'), cssIcon('Convert'), - urlState().setHref(userOverrideParams(null)), - testId('revert'), + withInfoTooltip( + cssPrimaryButtonLink( + t('View as Yourself'), cssIcon('Convert'), + urlState().setHref(userOverrideParams(null)), + testId('revert'), + ), + 'viewAsBanner', + { + iconDomArgs: [ + cssInfoTooltipButton.cls('-in-banner'), + testId('view-as-help-tooltip'), + ], + }, ), testId('view-as-banner'), ); diff --git a/app/client/ui/GristTooltips.ts b/app/client/ui/GristTooltips.ts index 651ef4f1cb..be6cb0c93a 100644 --- a/app/client/ui/GristTooltips.ts +++ b/app/client/ui/GristTooltips.ts @@ -46,7 +46,8 @@ export type Tooltip = | 'communityWidgets' | 'twoWayReferences' | 'twoWayReferencesDisabled' - | 'reasignTwoWayReference'; + | 'reasignTwoWayReference' + | 'viewAsBanner'; export type TooltipContentFunc = (...domArgs: DomElementArg[]) => DomContents; @@ -187,6 +188,10 @@ see or edit which parts of your document.') ), ...args, ), + viewAsBanner: (...args: DomElementArg[]) => cssTooltipContent( + dom('div', t('The preview below this header shows how the selected user will see this document')), + ...args, + ), }; export interface BehavioralPromptContent { diff --git a/app/client/ui/tooltips.ts b/app/client/ui/tooltips.ts index 5b92f310cf..cf807b94f2 100644 --- a/app/client/ui/tooltips.ts +++ b/app/client/ui/tooltips.ts @@ -8,7 +8,7 @@ import {logTelemetryEvent} from 'app/client/lib/telemetry'; import {GristTooltips, Tooltip} from 'app/client/ui/GristTooltips'; import {prepareForTransition} from 'app/client/ui/transitions'; -import {testId, theme, vars} from 'app/client/ui2018/cssVars'; +import {colors, testId, theme, vars} from 'app/client/ui2018/cssVars'; import {icon} from 'app/client/ui2018/icons'; import {makeLinks} from 'app/client/ui2018/links'; import {menuCssClass} from 'app/client/ui2018/menus'; @@ -401,7 +401,7 @@ function buildHoverableInfoTooltip( tooltip: BindableValue, ...domArgs: DomElementArg[] ) { - return cssInfoTooltipIcon('?', + return cssInfoTooltipButton('?', hoverTooltip(() => cssInfoTooltipTransientPopup( dom.domComputed(tooltip, (tip) => GristTooltips[tip]()), cssTooltipCorner(testId('tooltip-origin')), @@ -587,13 +587,23 @@ const cssInfoTooltipIcon = styled('div', ` } `); -const cssInfoTooltipButton = styled(cssInfoTooltipIcon, ` +export const cssInfoTooltipButton = styled(cssInfoTooltipIcon, ` cursor: pointer; &:hover { border: 1px solid ${theme.controlSecondaryHoverFg}; color: ${theme.controlSecondaryHoverFg}; } + + &-in-banner { + color: ${colors.dark}; + border-color: ${colors.dark}; + } + + &-in-banner:hover { + border-color: ${colors.lightGreen}; + color: ${colors.lightGreen}; + } `); const cssInfoTooltipPopup = styled('div', ` diff --git a/static/locales/en.client.json b/static/locales/en.client.json index f02953ff84..d7708a90ca 100644 --- a/static/locales/en.client.json +++ b/static/locales/en.client.json @@ -1239,7 +1239,8 @@ "To allow multiple assignments, change the type of the Reference column to Reference List.": "To allow multiple assignments, change the type of the Reference column to Reference List.", "This limitation occurs when one column in a two-way reference has the Reference type.": "This limitation occurs when one column in a two-way reference has the Reference type.", "To allow multiple assignments, change the referenced column's type to Reference List.": "To allow multiple assignments, change the referenced column's type to Reference List.", - "Two-way references are not currently supported for Formula or Trigger Formula columns": "Two-way references are not currently supported for Formula or Trigger Formula columns" + "Two-way references are not currently supported for Formula or Trigger Formula columns": "Two-way references are not currently supported for Formula or Trigger Formula columns", + "The preview below this header shows how the selected user will see this document": "The preview below this header shows how the selected user will see this document" }, "DescriptionConfig": { "DESCRIPTION": "DESCRIPTION" diff --git a/test/nbrowser/AccessRules2.ts b/test/nbrowser/AccessRules2.ts index a19065a660..1086584f3d 100644 --- a/test/nbrowser/AccessRules2.ts +++ b/test/nbrowser/AccessRules2.ts @@ -109,6 +109,7 @@ describe("AccessRules2", function() { assert.equal(await driver.findWait('.test-view-as-banner', 2000).isPresent(), true); assert.match(await driver.find('.test-view-as-banner .test-select-open').getText(), new RegExp(gu.translateUser('user3').name, 'i')); + assert.equal(await driver.find('.test-info-tooltip.test-view-as-help-tooltip').isDisplayed(), true); // check the aclAsUser parameter on the url persists after navigating to another page await gu.getPageItem('FinancialsTable').click(); From 0d7b3fb43c042df637aeee897c235ccc10396817 Mon Sep 17 00:00:00 2001 From: Emmanuel Pelletier Date: Mon, 3 Feb 2025 19:26:35 +0100 Subject: [PATCH 4/5] (i18n) adding french translations for ViewAsBanner --- static/locales/fr.client.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/static/locales/fr.client.json b/static/locales/fr.client.json index f542e36ec6..092a0ad098 100644 --- a/static/locales/fr.client.json +++ b/static/locales/fr.client.json @@ -1009,7 +1009,9 @@ "Users from table": "Utilisateurs de la table" }, "ViewAsBanner": { - "UnknownUser": "Utilisateur inconnu" + "UnknownUser": "Utilisateur inconnu", + "View as Yourself": "Voir en tant que vous-même", + "You are viewing this document as": "Vous voyez ce document en tant que" }, "CellStyle": { "Open row styles": "Ouvrir les styles de ligne", @@ -1220,7 +1222,8 @@ "To allow multiple assignments, change the referenced column's type to Reference List.": "Pour permettre plusieurs assignations, modifiez le type de la colonne référencée en Référence Multiple.", "To allow multiple assignments, change the type of the Reference column to Reference List.": "Pour permettre des assignations multiples, modifiez le type de la colonne Référence en Référence Multiple.", "This limitation occurs when one end of a two-way reference is configured as a single Reference.": "Cette limitation se produit lorsque l'une des extrémités d'une référence bidirectionnelle est configurée comme une référence unique.", - "Two-way references are not currently supported for Formula or Trigger Formula columns": "Les références bidirectionnelles ne peuvent pas contenir des formules ou des formules d'initialisation" + "Two-way references are not currently supported for Formula or Trigger Formula columns": "Les références bidirectionnelles ne peuvent pas contenir des formules ou des formules d'initialisation", + "The preview below this header shows how the selected user will see this document": "L'aperçu sous cette entête montre ce que l'utilisateur sélectionné peut voir" }, "ColumnTitle": { "Add description": "Ajouter une description", From cbd281348e1f1759ce74da5cc6ffb8a452f46e4d Mon Sep 17 00:00:00 2001 From: Emmanuel Pelletier Date: Tue, 4 Feb 2025 11:16:29 +0100 Subject: [PATCH 5/5] (acl) in "view as" banner, fix eye icon color in dark theme eye icon was light grey on yellow in dark theme, making it basically invisible, forcing dark color all the time --- app/client/components/Banner.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/client/components/Banner.ts b/app/client/components/Banner.ts index 880a550ab2..eb4d86295b 100644 --- a/app/client/components/Banner.ts +++ b/app/client/components/Banner.ts @@ -121,7 +121,8 @@ const cssBanner = styled('div', ` color: white; &-info { - color: black; + color: ${colors.dark}; + --icon-color: ${colors.dark}; background: #FFFACD; }