feat: allow simple click on certain cases for editing field in Widget Card (#446)

* feat: allow simple click on certain cases for editing field in cardView

* remove empty line

* test fix : add trick to limit the context of event

* desable the simple click behavior on widget card in mobile

* Delete timings.txt

* Delete xunit.xml

* clean-feat(Simple click on Card): use field type and id

* ignore local testing files

* codeStyle(single click on card): rename var + move util function in DetailView.prototype

* remove unused var

* CIFix(SingleClickOnCard): escape of field editor before close test
This commit is contained in:
CamilleLegeron 2023-04-17 17:14:25 +02:00 committed by GitHub
parent 3047bde1e4
commit 3775317eec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 1 deletions

4
.gitignore vendored
View File

@ -74,4 +74,8 @@ jspm_packages/
# dotenv environment variables file # dotenv environment variables file
.env .env
# Test
timings.txt
xunit.xml
**/_build **/_build

View File

@ -5,6 +5,7 @@ const dom = require('app/client/lib/dom');
const kd = require('app/client/lib/koDom'); const kd = require('app/client/lib/koDom');
const koDomScrolly = require('app/client/lib/koDomScrolly'); const koDomScrolly = require('app/client/lib/koDomScrolly');
const {renderAllRows} = require('app/client/components/Printing'); const {renderAllRows} = require('app/client/components/Printing');
const {isNarrowScreen} = require('app/client/ui2018/cssVars');
require('app/client/lib/koUtil'); // Needed for subscribeInit. require('app/client/lib/koUtil'); // Needed for subscribeInit.
@ -17,6 +18,7 @@ const {RowContextMenu} = require('../ui/RowContextMenu');
const {parsePasteForView} = require("./BaseView2"); const {parsePasteForView} = require("./BaseView2");
const {columnInfoTooltip} = require("../ui/tooltips"); const {columnInfoTooltip} = require("../ui/tooltips");
/** /**
* DetailView component implements a list of record layouts. * DetailView component implements a list of record layouts.
*/ */
@ -75,6 +77,7 @@ function DetailView(gristDoc, viewSectionModel) {
//-------------------------------------------------- //--------------------------------------------------
// Set up DOM event handling. // Set up DOM event handling.
this._twoLastFieldIdsSelected = [null, null];
// Clicking on a detail field selects that field. // Clicking on a detail field selects that field.
this.onEvent(this.viewPane, 'mousedown', '.g_record_detail_el', function(elem, event) { 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 rowModel = this.recordLayout.getContainingRow(elem, this.viewPane);
var field = this.recordLayout.getContainingField(elem, this.viewPane); var field = this.recordLayout.getContainingField(elem, this.viewPane);
commands.allCommands.setCursor.run(rowModel, field); commands.allCommands.setCursor.run(rowModel, field);
this._twoLastFieldIdsSelected.unshift(field.id());
this._twoLastFieldIdsSelected.pop();
}); });
// Double-clicking on a field also starts editing the field. // Double-clicking on a field also starts editing the field.
@ -89,6 +94,18 @@ function DetailView(gristDoc, viewSectionModel) {
this.activateEditorAtCursor(); 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. // Instantiate CommandGroups for the different modes.
this.autoDispose(commands.createGroup(DetailView.generalCommands, this, this.viewSection.hasFocus)); this.autoDispose(commands.createGroup(DetailView.generalCommands, this, this.viewSection.hasFocus));
@ -430,4 +447,20 @@ DetailView.prototype._duplicateRows = async function() {
this.setCursorPos({rowId: addRowIds[0]}) 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; module.exports = DetailView;

View File

@ -8,7 +8,7 @@ import {WebElement} from 'mocha-webdriver';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import {authenticator} from 'otplib'; import {authenticator} from 'otplib';
import * as path from 'path'; import * as path from 'path';
import {WebDriver} from 'selenium-webdriver'; import { Key, WebDriver } from 'selenium-webdriver';
import {UserProfile} from 'app/common/LoginSessionAPI'; import {UserProfile} from 'app/common/LoginSessionAPI';
import {BehavioralPrompt, UserPrefs, WelcomePopup} from 'app/common/Prefs'; import {BehavioralPrompt, UserPrefs, WelcomePopup} from 'app/common/Prefs';
@ -146,6 +146,8 @@ export class HomeUtil {
* to be more nuanced. * to be more nuanced.
*/ */
public async removeLogin(org: string = "") { 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()) { if (!this.server.isExternalServer()) {
const testingHooks = await this.server.getTestingHooks(); const testingHooks = await this.server.getTestingHooks();
const sid = await this.getGristSid(); const sid = await this.getGristSid();