diff --git a/.gitignore b/.gitignore index 48663300..cc60d2eb 100644 --- a/.gitignore +++ b/.gitignore @@ -74,4 +74,8 @@ jspm_packages/ # dotenv environment variables file .env +# Test +timings.txt +xunit.xml + **/_build diff --git a/app/client/components/DetailView.js b/app/client/components/DetailView.js index b908f8aa..a869c6bb 100644 --- a/app/client/components/DetailView.js +++ b/app/client/components/DetailView.js @@ -5,6 +5,7 @@ const dom = require('app/client/lib/dom'); const kd = require('app/client/lib/koDom'); const koDomScrolly = require('app/client/lib/koDomScrolly'); const {renderAllRows} = require('app/client/components/Printing'); +const {isNarrowScreen} = require('app/client/ui2018/cssVars'); require('app/client/lib/koUtil'); // Needed for subscribeInit. @@ -17,6 +18,7 @@ const {RowContextMenu} = require('../ui/RowContextMenu'); const {parsePasteForView} = require("./BaseView2"); const {columnInfoTooltip} = require("../ui/tooltips"); + /** * DetailView component implements a list of record layouts. */ @@ -75,6 +77,7 @@ function DetailView(gristDoc, viewSectionModel) { //-------------------------------------------------- // Set up DOM event handling. + this._twoLastFieldIdsSelected = [null, null]; // Clicking on a detail field selects that field. this.onEvent(this.viewPane, 'mousedown', '.g_record_detail_el', function(elem, event) { @@ -82,6 +85,8 @@ function DetailView(gristDoc, viewSectionModel) { var rowModel = this.recordLayout.getContainingRow(elem, this.viewPane); var field = this.recordLayout.getContainingField(elem, this.viewPane); commands.allCommands.setCursor.run(rowModel, field); + this._twoLastFieldIdsSelected.unshift(field.id()); + this._twoLastFieldIdsSelected.pop(); }); // Double-clicking on a field also starts editing the field. @@ -89,6 +94,18 @@ function DetailView(gristDoc, viewSectionModel) { this.activateEditorAtCursor(); }); + // We authorize single click only on the value to avoid conflict with tooltip + this.onEvent(this.viewPane, 'click', '.g_record_detail_value', function(elem, event) { + var field = this.recordLayout.getContainingField(elem, this.viewPane); + if ( + this._twoLastFieldIdsSelected[0] === this._twoLastFieldIdsSelected[1] + && !isNarrowScreen() + && this._canSingleClick(field) + ) { + this.activateEditorAtCursor(); + } + }); + //-------------------------------------------------- // Instantiate CommandGroups for the different modes. this.autoDispose(commands.createGroup(DetailView.generalCommands, this, this.viewSection.hasFocus)); @@ -430,4 +447,20 @@ DetailView.prototype._duplicateRows = async function() { this.setCursorPos({rowId: addRowIds[0]}) } +DetailView.prototype._canSingleClick = function(field) { + // we can't simple click if : + // - the field is a formula + // - the field is toggle (switch or checkbox) + if ( + field.column().isRealFormula() || field.column().hasTriggerFormula() + || ( + field.column().pureType() === "Bool" + && ["Switch", "CheckBox"].includes(field.column().visibleColFormatter().widgetOpts.widget) + ) + ) { + return false; + } + return true; +}; + module.exports = DetailView; diff --git a/app/client/components/GristDoc.ts b/app/client/components/GristDoc.ts index 0009a207..48bdb311 100644 --- a/app/client/components/GristDoc.ts +++ b/app/client/components/GristDoc.ts @@ -46,7 +46,7 @@ import {DocTutorial} from 'app/client/ui/DocTutorial'; import {isTourActive} from "app/client/ui/OnBoardingPopups"; import {IPageWidget, toPageWidget} from 'app/client/ui/PageWidgetPicker'; import {linkFromId, selectBy} from 'app/client/ui/selectBy'; -import {startWelcomeTour} from 'app/client/ui/welcomeTour'; +import {startWelcomeTour} from 'app/client/ui/WelcomeTour'; import {IWidgetType} from 'app/client/ui/widgetTypes'; import {PlayerState, YouTubePlayer} from 'app/client/ui/YouTubePlayer'; import {isNarrowScreen, mediaSmall, mediaXSmall, testId, theme} from 'app/client/ui2018/cssVars'; diff --git a/app/client/ui/welcomeTour.ts b/app/client/ui/WelcomeTour.ts similarity index 100% rename from app/client/ui/welcomeTour.ts rename to app/client/ui/WelcomeTour.ts diff --git a/static/locales/de.client.json b/static/locales/de.client.json index f1b7fe51..96a8de93 100644 --- a/static/locales/de.client.json +++ b/static/locales/de.client.json @@ -951,7 +951,7 @@ "HyperLinkEditor": { "[link label] url": "[Linkbezeichnung] URL" }, - "welcomeTour": { + "WelcomeTour": { "Add New": "Neu hinzufügen", "Building up": "Zubauend", "Configuring your document": "Konfigurieren Ihres Dokuments", diff --git a/static/locales/en.client.json b/static/locales/en.client.json index 55d5e389..0801d8f9 100644 --- a/static/locales/en.client.json +++ b/static/locales/en.client.json @@ -897,7 +897,7 @@ "Row ID": "Row ID", "SHOW COLUMN": "SHOW COLUMN" }, - "welcomeTour": { + "WelcomeTour": { "Add New": "Add New", "Browse our {{templateLibrary}} to discover what's possible and get inspired.": "Browse our {{templateLibrary}} to discover what's possible and get inspired.", "Building up": "Building up", @@ -965,7 +965,8 @@ "Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.", "Add New": "Add New", "Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.", - "Anchor Links": "Anchor Links" + "Anchor Links": "Anchor Links", + "Custom Widgets": "Custom Widgets" }, "DescriptionConfig": { "DESCRIPTION": "DESCRIPTION" diff --git a/static/locales/es.client.json b/static/locales/es.client.json index 77bd6d1f..12dea8d2 100644 --- a/static/locales/es.client.json +++ b/static/locales/es.client.json @@ -919,7 +919,7 @@ "Errors in all {{numErrors}} cells": "Errores en todas las {{numErrors}} celdas", "editingFormula is required": "ediciónFórmula es necesaria" }, - "welcomeTour": { + "WelcomeTour": { "Add New": "Agregar Nuevo", "Configuring your document": "Configurando tu documento", "Enter": "Intro", diff --git a/static/locales/fr.client.json b/static/locales/fr.client.json index 2bbbd3de..f645f0fc 100644 --- a/static/locales/fr.client.json +++ b/static/locales/fr.client.json @@ -811,7 +811,7 @@ "Save field settings for {{colId}} as common": "Sauvegarder les paramètres pour {{colId}}", "Use separate field settings for {{colId}}": "Utiliser des paramètres spécifiques pour {{colId}}" }, - "welcomeTour": { + "WelcomeTour": { "Customizing columns": "Personnaliser les colonnes", "template library": "Bibliothèque de modèles", "Share": "Partager", diff --git a/static/locales/it.client.json b/static/locales/it.client.json index a149623f..d7424f8a 100644 --- a/static/locales/it.client.json +++ b/static/locales/it.client.json @@ -307,7 +307,7 @@ "HyperLinkEditor": { "[link label] url": "[testo link] URL" }, - "welcomeTour": { + "WelcomeTour": { "Editing Data": "Modificare i dati", "Sharing": "Condividendo", "Browse our {{templateLibrary}} to discover what's possible and get inspired.": "Sfoglia la nostra {{templateLibrary}} per scoprire che cosa è possibile fare e farti ispirare.", diff --git a/static/locales/nb_NO.client.json b/static/locales/nb_NO.client.json index 0fc05b29..28a8bd0d 100644 --- a/static/locales/nb_NO.client.json +++ b/static/locales/nb_NO.client.json @@ -761,7 +761,7 @@ "Row ID": "Rad-ID", "SHOW COLUMN": "Vis kolonne" }, - "welcomeTour": { + "WelcomeTour": { "Configuring your document": "Oppsett av dokumentet ditt", "Customizing columns": "Oppsett av kolonner", "Building up": "Oppbygging", diff --git a/static/locales/pl.client.json b/static/locales/pl.client.json index 711dcb77..67d963c9 100644 --- a/static/locales/pl.client.json +++ b/static/locales/pl.client.json @@ -892,7 +892,7 @@ "Row ID": "Identyfikator wiersza", "SHOW COLUMN": "POKAŻ KOLUMNĘ" }, - "welcomeTour": { + "WelcomeTour": { "Add New": "Dodaj nowy", "Building up": "Budowanie", "Flying higher": "Latanie wyżej", diff --git a/static/locales/pt_BR.client.json b/static/locales/pt_BR.client.json index d37153fa..29dfccef 100644 --- a/static/locales/pt_BR.client.json +++ b/static/locales/pt_BR.client.json @@ -866,7 +866,7 @@ "View As": "Ver como", "Example Users": "Usuários de exemplo" }, - "welcomeTour": { + "WelcomeTour": { "Use {{helpCenter}} for documentation or questions.": "Use {{helpCenter}} para documentação ou perguntas.", "convert to card view, select data, and more.": "converta para a visualização de cartão, selecione dados e muito mais.", "Start with {{equal}} to enter a formula.": "Comece com {{equal}} para inserir uma fórmula.", diff --git a/static/locales/ru.client.json b/static/locales/ru.client.json index bb024d46..d945f098 100644 --- a/static/locales/ru.client.json +++ b/static/locales/ru.client.json @@ -765,7 +765,7 @@ "Default currency ({{defaultCurrency}})": "Валюта по умолчанию ({{defaultCurrency}})", "Decimals": "Десятичные" }, - "welcomeTour": { + "WelcomeTour": { "convert to card view, select data, and more.": "преобразовать в представление карточки, выбрать данные, и более.", "creator panel": "панель создателя", "template library": "библиотека шаблонов", diff --git a/static/locales/uk.client.json b/static/locales/uk.client.json index 56370da3..15105db5 100644 --- a/static/locales/uk.client.json +++ b/static/locales/uk.client.json @@ -889,7 +889,7 @@ "Row ID": "ID рядка", "SHOW COLUMN": "ПОКАЗАТИ СТОВПЕЦЬ" }, - "welcomeTour": { + "WelcomeTour": { "Add New": "Додати", "Building up": "Створюйте", "Configuring your document": "Налаштування вашого документа", diff --git a/static/locales/zh_Hans.client.json b/static/locales/zh_Hans.client.json index 9f421b29..cd48ab41 100644 --- a/static/locales/zh_Hans.client.json +++ b/static/locales/zh_Hans.client.json @@ -263,7 +263,7 @@ "Open Snapshot": "打开快照", "Snapshots are unavailable.": "快照不可用。" }, - "welcomeTour": { + "WelcomeTour": { "Share": "分享", "Reference": "参考", "Flying higher": "飞得更高", diff --git a/test/nbrowser/homeUtil.ts b/test/nbrowser/homeUtil.ts index 672fc550..9a444a7f 100644 --- a/test/nbrowser/homeUtil.ts +++ b/test/nbrowser/homeUtil.ts @@ -8,7 +8,7 @@ import {WebElement} from 'mocha-webdriver'; import fetch from 'node-fetch'; import {authenticator} from 'otplib'; import * as path from 'path'; -import {WebDriver} from 'selenium-webdriver'; +import { Key, WebDriver } from 'selenium-webdriver'; import {UserProfile} from 'app/common/LoginSessionAPI'; import {BehavioralPrompt, UserPrefs, WelcomePopup} from 'app/common/Prefs'; @@ -146,6 +146,8 @@ export class HomeUtil { * to be more nuanced. */ public async removeLogin(org: string = "") { + // If cursor is on field editor, escape before remove login + await this.driver.sendKeys(Key.ESCAPE); if (!this.server.isExternalServer()) { const testingHooks = await this.server.getTestingHooks(); const sid = await this.getGristSid();