From d9db9265dab3f00b8875bb1603c09f3d7658e8af Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Thu, 16 Feb 2023 12:57:36 -0600 Subject: [PATCH 01/23] updated snapshot version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index da00493..6896f0e 100755 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ jar - 0.12.0-SNAPSHOT + 0.13.0-SNAPSHOT UTF-8 UTF-8 From 3eb831b30e8390daddf51215fd6c7ab18f760fea Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Thu, 16 Feb 2023 17:34:41 -0600 Subject: [PATCH 02/23] SPRINT-21: updated page titles to 'ColdTrack Live' --- src/qqq/components/horseshoe/Breadcrumbs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qqq/components/horseshoe/Breadcrumbs.tsx b/src/qqq/components/horseshoe/Breadcrumbs.tsx index d116d06..16afa88 100644 --- a/src/qqq/components/horseshoe/Breadcrumbs.tsx +++ b/src/qqq/components/horseshoe/Breadcrumbs.tsx @@ -62,7 +62,7 @@ function QBreadcrumbs({icon, title, route, light}: Props): JSX.Element const routes: string[] | any = route.slice(0, -1); const {pageHeader, setPageHeader} = useContext(QContext); - let pageTitle = "Nutrifresh One"; + let pageTitle = "ColdTrack Live"; const fullRoutes: string[] = []; let accumulatedPath = ""; for (let i = 0; i < routes.length; i++) From 32711098c1c09f8b31ba7c04a60415246fcd6bea Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 17 Feb 2023 12:03:55 -0600 Subject: [PATCH 03/23] new test on audits; selenium upgrade to make usable by team hopefully --- .gitignore | 1 + pom.xml | 12 + .../lib/QBaseSeleniumTest.java | 4 +- .../lib/QQQMaterialDashboardSelectors.java | 2 +- .../lib/QSeleniumLib.java | 87 +++++-- .../lib/javalin/CapturedContext.java | 2 +- .../lib/javalin/CapturingHandler.java | 10 +- .../lib/javalin/QSeleniumJavalin.java | 54 ++-- .../lib/javalin/RouteFromFileHandler.java | 8 +- .../lib/javalin/RouteFromStringHandler.java | 8 +- .../tests/AppPageNavTest.java | 8 +- .../materialdashboard/tests/AuditTest.java | 160 ++++++++++++ .../tests/QueryScreenTest.java | 10 +- .../fixtures/data/audit/query-empty.json | 3 + .../resources/fixtures/data/audit/query.json | 245 ++++++++++++++++++ .../resources/fixtures/data/person/1701.json | 16 ++ .../resources/fixtures/metaData/index.json | 15 ++ src/test/resources/log4j2.xml | 21 ++ 18 files changed, 610 insertions(+), 56 deletions(-) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/QBaseSeleniumTest.java (96%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/QQQMaterialDashboardSelectors.java (92%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/QSeleniumLib.java (79%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/javalin/CapturedContext.java (97%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/javalin/CapturingHandler.java (76%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/javalin/QSeleniumJavalin.java (80%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/javalin/RouteFromFileHandler.java (85%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/lib/javalin/RouteFromStringHandler.java (82%) rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/tests/AppPageNavTest.java (92%) create mode 100755 src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java rename src/test/java/com/kingsrook/qqq/{materialdashbaord => materialdashboard}/tests/QueryScreenTest.java (96%) create mode 100644 src/test/resources/fixtures/data/audit/query-empty.json create mode 100644 src/test/resources/fixtures/data/audit/query.json create mode 100644 src/test/resources/fixtures/data/person/1701.json create mode 100644 src/test/resources/log4j2.xml diff --git a/.gitignore b/.gitignore index 367a0b4..be24dee 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ yalc.lock /build /lib /target +/log # misc .DS_Store diff --git a/pom.xml b/pom.xml index 6896f0e..bd435b8 100755 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,18 @@ 20220924 test + + org.apache.logging.log4j + log4j-api + 2.17.1 + test + + + org.apache.logging.log4j + log4j-core + 2.17.1 + test + diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QBaseSeleniumTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java similarity index 96% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QBaseSeleniumTest.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java index 45b0068..e1965b8 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QBaseSeleniumTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java @@ -1,7 +1,7 @@ -package com.kingsrook.qqq.materialdashbaord.lib; +package com.kingsrook.qqq.materialdashboard.lib; -import com.kingsrook.qqq.materialdashbaord.lib.javalin.QSeleniumJavalin; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; import io.github.bonigarcia.wdm.WebDriverManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QQQMaterialDashboardSelectors.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QQQMaterialDashboardSelectors.java similarity index 92% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QQQMaterialDashboardSelectors.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/QQQMaterialDashboardSelectors.java index 8a10812..3fbea4a 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QQQMaterialDashboardSelectors.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QQQMaterialDashboardSelectors.java @@ -1,4 +1,4 @@ -package com.kingsrook.qqq.materialdashbaord.lib; +package com.kingsrook.qqq.materialdashboard.lib; /******************************************************************************* diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QSeleniumLib.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java similarity index 79% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QSeleniumLib.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java index 6958a01..8b86fd4 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/QSeleniumLib.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java @@ -1,4 +1,4 @@ -package com.kingsrook.qqq.materialdashbaord.lib; +package com.kingsrook.qqq.materialdashboard.lib; import java.io.File; @@ -6,6 +6,8 @@ import java.time.Duration; import java.util.List; import java.util.Objects; import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; import org.openqa.selenium.StaleElementReferenceException; @@ -23,6 +25,8 @@ import static org.junit.jupiter.api.Assertions.fail; *******************************************************************************/ public class QSeleniumLib { + Logger LOG = LogManager.getLogger(QSeleniumLib.class); + public final WebDriver driver; private long WAIT_SECONDS = 10; @@ -118,7 +122,7 @@ public class QSeleniumLib { // todo - if env says we're in CIRCLECI, then... just do a hard fail (or just not wait forever?) - System.out.println("Going into a waitForever..."); + LOG.warn("Going into a waitForever..."); new WebDriverWait(driver, Duration.ofHours(1)) .until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".wontEverBePresent"))); } @@ -131,13 +135,11 @@ public class QSeleniumLib public void gotoAndWaitForBreadcrumbHeader(String path, String headerText) { driver.get(BASE_URL + path); - String title = driver.getTitle(); - System.out.println("Page Title: " + title); WebElement header = new WebDriverWait(driver, Duration.ofSeconds(WAIT_SECONDS)) .until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(QQQMaterialDashboardSelectors.BREADCRUMB_HEADER))); - System.out.println("Breadcrumb Header: " + header.getText()); + LOG.debug("Navigated to [" + path + "]. Breadcrumb Header: " + header.getText()); assertEquals(headerText, header.getText()); } @@ -158,7 +160,7 @@ public class QSeleniumLib *******************************************************************************/ public List waitForSelectorAll(String cssSelector, int minCount) { - System.out.println("Waiting for element matching selector [" + cssSelector + "]"); + LOG.debug("Waiting for element matching selector [" + cssSelector + "]"); long start = System.currentTimeMillis(); do @@ -166,7 +168,7 @@ public class QSeleniumLib List elements = driver.findElements(By.cssSelector(cssSelector)); if(elements.size() >= minCount) { - System.out.println("Found [" + elements.size() + "] element(s) matching selector [" + cssSelector + "]"); + LOG.debug("Found [" + elements.size() + "] element(s) matching selector [" + cssSelector + "]"); return (elements); } @@ -180,6 +182,32 @@ public class QSeleniumLib + /******************************************************************************* + ** + *******************************************************************************/ + public void waitForSelectorToNotExist(String cssSelector) + { + LOG.debug("Waiting for non-existence of element matching selector [" + cssSelector + "]"); + long start = System.currentTimeMillis(); + + do + { + List elements = driver.findElements(By.cssSelector(cssSelector)); + if(elements.size() == 0) + { + LOG.debug("Found non-existence of element(s) matching selector [" + cssSelector + "]"); + return; + } + + sleepABit(); + } + while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); + + fail("Failed for non-existence of element matching selector [" + cssSelector + "] after [" + WAIT_SECONDS + "] seconds."); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -205,26 +233,51 @@ public class QSeleniumLib + /******************************************************************************* + ** + *******************************************************************************/ + public boolean waitForCondition(String message, Code c) + { + LOG.debug("Waiting for condition: " + message); + long start = System.currentTimeMillis(); + do + { + Boolean b = c.run(); + if(b != null && b) + { + LOG.debug("Condition became true: " + message); + return (true); + } + + sleepABit(); + } + while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); + LOG.warn("Failed for condition to become true: " + message); + return (false); + } + + + /******************************************************************************* ** *******************************************************************************/ public T waitLoop(String message, Code c) { - System.out.println("Waiting for: " + message); + LOG.debug("Waiting for: " + message); long start = System.currentTimeMillis(); do { T t = c.run(); if(t != null) { - System.out.println("Found: " + message); + LOG.debug("Found: " + message); return (t); } sleepABit(); } while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); - System.out.println("Failed to match while waiting for: " + message); + LOG.warn("Failed to match while waiting for: " + message); return (null); } @@ -235,7 +288,7 @@ public class QSeleniumLib *******************************************************************************/ public WebElement waitForSelectorContaining(String cssSelector, String textContains) { - System.out.println("Waiting for element matching selector [" + cssSelector + "] containing text [" + textContains + "]."); + LOG.debug("Waiting for element matching selector [" + cssSelector + "] containing text [" + textContains + "]."); long start = System.currentTimeMillis(); do @@ -247,7 +300,7 @@ public class QSeleniumLib { if(element.getText() != null && element.getText().toLowerCase().contains(textContains.toLowerCase())) { - System.out.println("Found element matching selector [" + cssSelector + "] containing text [" + textContains + "]."); + LOG.debug("Found element matching selector [" + cssSelector + "] containing text [" + textContains + "]."); Actions actions = new Actions(driver); actions.moveToElement(element); return (element); @@ -255,7 +308,7 @@ public class QSeleniumLib } catch(StaleElementReferenceException sere) { - System.err.println("Caught a StaleElementReferenceException - will retry."); + LOG.debug("Caught a StaleElementReferenceException - will retry."); } } @@ -289,7 +342,7 @@ public class QSeleniumLib } catch(StaleElementReferenceException sere) { - System.err.println("Caught a StaleElementReferenceException - will retry."); + LOG.debug("Caught a StaleElementReferenceException - will retry."); } } return (null); @@ -329,11 +382,11 @@ public class QSeleniumLib destFile.delete(); } FileUtils.moveFile(outputFile, destFile); - System.out.println("Made screenshot at: " + destFile); + LOG.info("Made screenshot at: " + destFile); } catch(Exception e) { - System.err.println("Error taking screenshot to file: " + e.getMessage()); + LOG.warn("Error taking screenshot to file: " + e.getMessage()); } } } @@ -391,7 +444,7 @@ public class QSeleniumLib { if(i < noOfTries - 1) { - System.out.println("On try [" + i + " of " + noOfTries + "] caught: " + e.getMessage()); + LOG.debug("On try [" + i + " of " + noOfTries + "] caught: " + e.getMessage()); } else { diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/CapturedContext.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/CapturedContext.java similarity index 97% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/CapturedContext.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/CapturedContext.java index 1270c95..4a8836d 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/CapturedContext.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/CapturedContext.java @@ -1,4 +1,4 @@ -package com.kingsrook.qqq.materialdashbaord.lib.javalin; +package com.kingsrook.qqq.materialdashboard.lib.javalin; import io.javalin.http.Context; diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/CapturingHandler.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/CapturingHandler.java similarity index 76% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/CapturingHandler.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/CapturingHandler.java index 210fff7..ea0f555 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/CapturingHandler.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/CapturingHandler.java @@ -1,8 +1,10 @@ -package com.kingsrook.qqq.materialdashbaord.lib.javalin; +package com.kingsrook.qqq.materialdashboard.lib.javalin; import io.javalin.http.Context; import io.javalin.http.Handler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /******************************************************************************* @@ -11,6 +13,8 @@ import io.javalin.http.Handler; *******************************************************************************/ public class CapturingHandler implements Handler { + Logger LOG = LogManager.getLogger(CapturingHandler.class); + private final QSeleniumJavalin qSeleniumJavalin; @@ -34,12 +38,12 @@ public class CapturingHandler implements Handler { if(qSeleniumJavalin.capturing) { - System.out.println("Capturing request for path [" + context.path() + "]"); + LOG.info("Capturing request for path [" + context.path() + "]"); qSeleniumJavalin.captured.add(new CapturedContext(context)); } else { - System.out.println("Not capturing request for path [" + context.path() + "]"); + LOG.trace("Not capturing request for path [" + context.path() + "]"); } } } diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/QSeleniumJavalin.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java similarity index 80% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/QSeleniumJavalin.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java index 6ce9d91..8e81b00 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/QSeleniumJavalin.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java @@ -1,12 +1,14 @@ -package com.kingsrook.qqq.materialdashbaord.lib.javalin; +package com.kingsrook.qqq.materialdashboard.lib.javalin; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.kingsrook.qqq.materialdashbaord.lib.QSeleniumLib; +import com.kingsrook.qqq.materialdashboard.lib.QSeleniumLib; import io.javalin.Javalin; import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConnectionFactory; import static io.javalin.apibuilder.ApiBuilder.get; @@ -19,6 +21,8 @@ import static org.junit.jupiter.api.Assertions.fail; *******************************************************************************/ public class QSeleniumJavalin { + Logger LOG = LogManager.getLogger(QSeleniumJavalin.class); + private long WAIT_SECONDS = 10; private List> routesToFiles; @@ -52,13 +56,13 @@ public class QSeleniumJavalin ** Fluent setter for routeToFile ** *******************************************************************************/ - public QSeleniumJavalin withRouteToFile(String path, String file) + public QSeleniumJavalin withRouteToFile(String path, String fixtureFilePath) { if(this.routesToFiles == null) { this.routesToFiles = new ArrayList<>(); } - this.routesToFiles.add(Pair.of(path, file)); + this.routesToFiles.add(Pair.of(path, fixtureFilePath)); return (this); } @@ -92,7 +96,7 @@ public class QSeleniumJavalin { for(Pair routeToFile : routesToFiles) { - System.out.println("Setting up route for [" + routeToFile.getKey() + "] => [" + routeToFile.getValue() + "]"); + LOG.debug("Setting up route for [" + routeToFile.getKey() + "] => [" + routeToFile.getValue() + "]"); get(routeToFile.getKey(), new RouteFromFileHandler(this, routeToFile)); post(routeToFile.getKey(), new RouteFromFileHandler(this, routeToFile)); } @@ -105,7 +109,7 @@ public class QSeleniumJavalin { for(Pair routeToString : routesToStrings) { - System.out.println("Setting up route for [" + routeToString.getKey() + "] => [" + routeToString.getValue() + "]"); + LOG.debug("Setting up route for [" + routeToString.getKey() + "] => [" + routeToString.getValue() + "]"); get(routeToString.getKey(), new RouteFromStringHandler(this, routeToString)); post(routeToString.getKey(), new RouteFromStringHandler(this, routeToString)); } @@ -115,7 +119,7 @@ public class QSeleniumJavalin javalin.before(new CapturingHandler(this)); javalin.error(404, context -> { - System.out.println("Returning 404 for [" + context.method() + " " + context.path() + "]"); + LOG.warn("Returning 404 for [" + context.method() + " " + context.path() + "]"); pathsThat404ed.add(context.path()); }); @@ -143,21 +147,33 @@ public class QSeleniumJavalin if(javalin != null) { javalin.stop(); + javalin = null; } } + /******************************************************************************* + ** + *******************************************************************************/ + public void restart() + { + stop(); + start(); + } + + + /******************************************************************************* ** *******************************************************************************/ public void report() { - System.out.println("Paths that 404'ed:"); - pathsThat404ed.forEach(s -> System.out.println(" - " + s)); + LOG.info("Paths that 404'ed:"); + pathsThat404ed.forEach(s -> LOG.info(" - " + s)); - System.out.println("Routes served as static files:"); - routeFilesServed.forEach(s -> System.out.println(" - " + s)); + LOG.info("Routes served as static files:"); + routeFilesServed.forEach(s -> LOG.info(" - " + s)); } @@ -167,7 +183,7 @@ public class QSeleniumJavalin *******************************************************************************/ public void beginCapture() { - System.out.println("Beginning to capture requests now"); + LOG.info("Beginning to capture requests now"); capturing = true; captured.clear(); } @@ -179,7 +195,7 @@ public class QSeleniumJavalin *******************************************************************************/ public void endCapture() { - System.out.println("Ending capturing of requests now"); + LOG.info("Ending capturing of requests now"); capturing = false; } @@ -200,17 +216,17 @@ public class QSeleniumJavalin *******************************************************************************/ public CapturedContext waitForCapturedPath(String path) { - System.out.println("Waiting for captured request for path [" + path + "]"); + LOG.debug("Waiting for captured request for path [" + path + "]"); long start = System.currentTimeMillis(); do { - // System.out.println(" captured paths: " + captured.stream().map(CapturedContext::getPath).collect(Collectors.joining(","))); + // LOG.debug(" captured paths: " + captured.stream().map(CapturedContext::getPath).collect(Collectors.joining(","))); for(CapturedContext context : captured) { if(context.getPath().equals(path)) { - System.out.println("Found captured request for path [" + path + "]"); + LOG.debug("Found captured request for path [" + path + "]"); return (context); } } @@ -230,19 +246,19 @@ public class QSeleniumJavalin *******************************************************************************/ public CapturedContext waitForCapturedPathWithBodyContaining(String path, String bodyContaining) { - System.out.println("Waiting for captured request for path [" + path + "] with body containing [" + bodyContaining + "]"); + LOG.debug("Waiting for captured request for path [" + path + "] with body containing [" + bodyContaining + "]"); long start = System.currentTimeMillis(); do { - // System.out.println(" captured paths: " + captured.stream().map(CapturedContext::getPath).collect(Collectors.joining(","))); + // LOG.debug(" captured paths: " + captured.stream().map(CapturedContext::getPath).collect(Collectors.joining(","))); for(CapturedContext context : captured) { if(context.getPath().equals(path)) { if(context.getBody() != null && context.getBody().contains(bodyContaining)) { - System.out.println("Found captured request for path [" + path + "] with body containing [" + bodyContaining + "]"); + LOG.debug("Found captured request for path [" + path + "] with body containing [" + bodyContaining + "]"); return (context); } } diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/RouteFromFileHandler.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/RouteFromFileHandler.java similarity index 85% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/RouteFromFileHandler.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/RouteFromFileHandler.java index 3ebe24d..364664c 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/RouteFromFileHandler.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/RouteFromFileHandler.java @@ -1,4 +1,4 @@ -package com.kingsrook.qqq.materialdashbaord.lib.javalin; +package com.kingsrook.qqq.materialdashboard.lib.javalin; import java.nio.charset.StandardCharsets; @@ -7,6 +7,8 @@ import io.javalin.http.Context; import io.javalin.http.Handler; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /******************************************************************************* @@ -14,6 +16,8 @@ import org.apache.commons.lang3.tuple.Pair; *******************************************************************************/ public class RouteFromFileHandler implements Handler { + Logger LOG = LogManager.getLogger(RouteFromFileHandler.class); + private final String route; private final String filePath; private final QSeleniumJavalin qSeleniumJavalin; @@ -42,7 +46,7 @@ public class RouteFromFileHandler implements Handler try { qSeleniumJavalin.routeFilesServed.add(this.route); - System.out.println("Serving route [" + this.route + "] via file [" + this.filePath + "]"); + LOG.debug("Serving route [" + this.route + "] via file [" + this.filePath + "]"); List lines = IOUtils.readLines(getClass().getResourceAsStream("/fixtures/" + this.filePath), StandardCharsets.UTF_8); context.result(String.join("\n", lines)); } diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/RouteFromStringHandler.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/RouteFromStringHandler.java similarity index 82% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/RouteFromStringHandler.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/RouteFromStringHandler.java index 30f8a01..3dc7e93 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/lib/javalin/RouteFromStringHandler.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/RouteFromStringHandler.java @@ -1,9 +1,11 @@ -package com.kingsrook.qqq.materialdashbaord.lib.javalin; +package com.kingsrook.qqq.materialdashboard.lib.javalin; import io.javalin.http.Context; import io.javalin.http.Handler; import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /******************************************************************************* @@ -11,6 +13,8 @@ import org.apache.commons.lang3.tuple.Pair; *******************************************************************************/ public class RouteFromStringHandler implements Handler { + Logger LOG = LogManager.getLogger(RouteFromStringHandler.class); + private final String route; private final String responseString; private final QSeleniumJavalin qSeleniumJavalin; @@ -37,7 +41,7 @@ public class RouteFromStringHandler implements Handler public void handle(Context context) { qSeleniumJavalin.routeFilesServed.add(this.route); - System.out.println("Serving route [" + this.route + "] via static String"); + LOG.debug("Serving route [" + this.route + "] via static String"); context.result(this.responseString); } } diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/tests/AppPageNavTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java similarity index 92% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/tests/AppPageNavTest.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java index be6fb2d..2660a02 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/tests/AppPageNavTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java @@ -19,12 +19,12 @@ * along with this program. If not, see . */ -package com.kingsrook.qqq.materialdashbaord.tests; +package com.kingsrook.qqq.materialdashboard.tests; -import com.kingsrook.qqq.materialdashbaord.lib.QBaseSeleniumTest; -import com.kingsrook.qqq.materialdashbaord.lib.QQQMaterialDashboardSelectors; -import com.kingsrook.qqq.materialdashbaord.lib.javalin.QSeleniumJavalin; +import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; +import com.kingsrook.qqq.materialdashboard.lib.QQQMaterialDashboardSelectors; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java new file mode 100755 index 0000000..45b2616 --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java @@ -0,0 +1,160 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.materialdashboard.tests; + + +import java.util.List; +import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; +import com.kingsrook.qqq.materialdashboard.lib.javalin.CapturedContext; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.WebElement; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +/******************************************************************************* + ** Test for the audit screen (e.g., modal) + *******************************************************************************/ +public class AuditTest extends QBaseSeleniumTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + protected void addJavalinRoutes(QSeleniumJavalin qSeleniumJavalin) + { + super.addJavalinRoutes(qSeleniumJavalin); + qSeleniumJavalin + .withRouteToFile("/data/person/1701", "data/person/1701.json"); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testOpenAuditsFromRecordWithNoAuditsFoundThenClose() + { + ///////////////////////////////////////////////////////////////////// + // setup route for empty audits - then assert we show such message // + ///////////////////////////////////////////////////////////////////// + qSeleniumJavalin.withRouteToFile("/data/audit/query", "data/audit/query-empty.json"); + qSeleniumJavalin.restart(); + + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person/1701", "John Doe"); + + qSeleniumLib.waitForSelectorContaining("BUTTON", "Actions").click(); + qSeleniumLib.waitForSelectorContaining("LI", "Audit").click(); + qSeleniumLib.waitForSelector(".audit"); + qSeleniumLib.waitForSelectorContaining("DIV", "Audit for Person: John Doe"); + qSeleniumLib.waitForSelectorContaining("DIV", "No audits were found for this record"); + + /////////////////////////////////////// + // make sure we can close the dialog // + /////////////////////////////////////// + qSeleniumLib.waitForSelectorContaining("BUTTON", "Close").click(); + qSeleniumLib.waitForSelectorToNotExist(".audit"); + + qSeleniumLib.takeScreenshotToFile(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testOpenAuditsFromRecordWithSomeAuditsFound() + { + String auditQueryPath = "/data/audit/query"; + qSeleniumJavalin.withRouteToFile(auditQueryPath, "data/audit/query.json"); + qSeleniumJavalin.restart(); + + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person/1701", "John Doe"); + + qSeleniumLib.waitForSelectorContaining("BUTTON", "Actions").click(); + qSeleniumLib.waitForSelectorContaining("LI", "Audit").click(); + qSeleniumLib.waitForSelectorContaining("DIV", "Audit for Person: John Doe"); + qSeleniumLib.waitForSelectorContaining("DIV", "Showing all 5 audits for this record"); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // assertions about the different styles of detail messages (set a value, cleared a value, etc) // + ////////////////////////////////////////////////////////////////////////////////////////////////// + qSeleniumLib.waitForSelectorContaining("LI", "First Name: Set to John"); + qSeleniumLib.waitForSelectorContaining("B", "John"); + qSeleniumLib.waitForSelectorContaining("LI", "Last Name: Removed value Doe"); + qSeleniumLib.waitForSelectorContaining("LI", "clientId: Changed from BetaMax to ACME"); + qSeleniumLib.waitForSelectorContaining("B", "ACME"); + qSeleniumLib.waitForSelectorContaining("DIV", "Audit message here"); + qSeleniumLib.waitForSelectorContaining("LI", "This is a detail message"); + } + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testOpenAuditsFromRecordReSortList() + { + String auditQueryPath = "/data/audit/query"; + qSeleniumJavalin.withRouteToFile(auditQueryPath, "data/audit/query.json"); + qSeleniumJavalin.restart(); + + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person/1701", "John Doe"); + + qSeleniumLib.waitForSelectorContaining("BUTTON", "Actions").click(); + qSeleniumLib.waitForSelectorContaining("LI", "Audit").click(); + qSeleniumLib.waitForSelectorContaining("DIV", "Audit for Person: John Doe"); + + ///////////////////////////////////////////////////////////////////////////////////////// + // make sure clicking the re-sort buttons works (fires a new request w/ opposite sort) // + ///////////////////////////////////////////////////////////////////////////////////////// + qSeleniumJavalin.beginCapture(); + WebElement sortAscButton = qSeleniumLib.waitForSelectorContaining("BUTTON", "arrow_upward"); + assertEquals("false", sortAscButton.getAttribute("aria-pressed")); + sortAscButton.click(); + qSeleniumJavalin.waitForCapturedPath(auditQueryPath); + qSeleniumJavalin.endCapture(); + List captured = qSeleniumJavalin.getCaptured(); + captured = captured.stream().filter(cc -> cc.getPath().equals(auditQueryPath)).toList(); + assertEquals(1, captured.size()); + assertThat(captured.get(0).getBody()).contains("\"isAscending\":true"); + + sortAscButton = qSeleniumLib.waitForSelectorContaining("BUTTON", "arrow_upward"); + assertEquals("true", sortAscButton.getAttribute("aria-pressed")); + + qSeleniumJavalin.beginCapture(); + qSeleniumLib.waitForSelectorContaining("BUTTON", "arrow_downward").click(); + qSeleniumJavalin.waitForCapturedPath(auditQueryPath); + qSeleniumJavalin.endCapture(); + captured = qSeleniumJavalin.getCaptured(); + captured = captured.stream().filter(cc -> cc.getPath().equals(auditQueryPath)).toList(); + assertEquals(1, captured.size()); + assertThat(captured.get(0).getBody()).contains("\"isAscending\":false"); + + qSeleniumLib.takeScreenshotToFile(); + } + +} diff --git a/src/test/java/com/kingsrook/qqq/materialdashbaord/tests/QueryScreenTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java similarity index 96% rename from src/test/java/com/kingsrook/qqq/materialdashbaord/tests/QueryScreenTest.java rename to src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java index fb64dde..bd182c1 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashbaord/tests/QueryScreenTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java @@ -19,13 +19,13 @@ * along with this program. If not, see . */ -package com.kingsrook.qqq.materialdashbaord.tests; +package com.kingsrook.qqq.materialdashboard.tests; -import com.kingsrook.qqq.materialdashbaord.lib.QBaseSeleniumTest; -import com.kingsrook.qqq.materialdashbaord.lib.QQQMaterialDashboardSelectors; -import com.kingsrook.qqq.materialdashbaord.lib.javalin.CapturedContext; -import com.kingsrook.qqq.materialdashbaord.lib.javalin.QSeleniumJavalin; +import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; +import com.kingsrook.qqq.materialdashboard.lib.QQQMaterialDashboardSelectors; +import com.kingsrook.qqq.materialdashboard.lib.javalin.CapturedContext; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; diff --git a/src/test/resources/fixtures/data/audit/query-empty.json b/src/test/resources/fixtures/data/audit/query-empty.json new file mode 100644 index 0000000..efde9b0 --- /dev/null +++ b/src/test/resources/fixtures/data/audit/query-empty.json @@ -0,0 +1,3 @@ +{ + "records": [] +} diff --git a/src/test/resources/fixtures/data/audit/query.json b/src/test/resources/fixtures/data/audit/query.json new file mode 100644 index 0000000..f40206f --- /dev/null +++ b/src/test/resources/fixtures/data/audit/query.json @@ -0,0 +1,245 @@ +{ + "records": [ + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 623577, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Inserted", + "timestamp": "2023-02-17T14:11:16Z", + "clientId": 107, + "auditDetail.id": 278660, + "auditDetail.auditId": 623577, + "auditDetail.message": "Set First Name to John", + "auditDetail.fieldName": "firstName", + "auditDetail.newValue": "John" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "623577", + "recordId": "1191682", + "message": "Record was Inserted", + "timestamp": "2023-02-17T14:11:16Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 623577, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Inserted", + "timestamp": "2023-02-17T14:11:16Z", + "clientId": 107, + "auditDetail.id": 278661, + "auditDetail.auditId": 623577, + "auditDetail.message": "Removed Doe from Last Name", + "auditDetail.fieldName": "lastName", + "auditDetail.oldValue": "Doe" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "623577", + "recordId": "1191682", + "message": "Record was Inserted", + "timestamp": "2023-02-17T14:11:16Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 623577, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Inserted", + "timestamp": "2023-02-17T14:11:16Z", + "clientId": 107, + "auditDetail.id": 278662, + "auditDetail.auditId": 623577, + "auditDetail.message": "Set Client to ACME", + "auditDetail.fieldName": "clientId", + "auditDetail.oldValue": "BetaMax", + "auditDetail.newValue": "ACME" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "623577", + "recordId": "1191682", + "message": "Record was Inserted", + "timestamp": "2023-02-17T14:11:16Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 624804, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Edited", + "timestamp": "2023-02-17T14:13:16Z", + "clientId": 107, + "auditDetail.id": 278990, + "auditDetail.auditId": 624804, + "auditDetail.message": "Set SLA Expected Service Days to 2", + "auditDetail.fieldName": "slaExpectedServiceDays", + "auditDetail.newValue": "2" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "624804", + "recordId": "1191682", + "message": "Record was Edited", + "timestamp": "2023-02-17T14:13:16Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 624804, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Edited", + "timestamp": "2023-02-17T14:13:16Z", + "clientId": 107, + "auditDetail.id": 278991, + "auditDetail.auditId": 624804, + "auditDetail.message": "Set SLA Status to \"Pending\"", + "auditDetail.fieldName": "slaStatusId", + "auditDetail.newValue": "Pending" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "624804", + "recordId": "1191682", + "message": "Record was Edited", + "timestamp": "2023-02-17T14:13:16Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 624809, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Audit message here", + "timestamp": "2023-02-17T14:13:16Z", + "clientId": 107, + "auditDetail.id": 279000, + "auditDetail.auditId": 624809, + "auditDetail.message": "This is a detail message" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "624809", + "recordId": "1191682", + "message": "Audit message here", + "timestamp": "2023-02-17T14:13:16Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 737694, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Edited", + "timestamp": "2023-02-17T17:22:08Z", + "clientId": 107, + "auditDetail.id": 299222, + "auditDetail.auditId": 737694, + "auditDetail.message": "Set Estimated Delivery Date Time to 2023-02-18 07:00:00 PM EST", + "auditDetail.fieldName": "estimatedDeliveryDateTime", + "auditDetail.newValue": "2023-02-18 07:00:00 PM EST" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "737694", + "recordId": "1191682", + "message": "Record was Edited", + "timestamp": "2023-02-17T17:22:08Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 737694, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Record was Edited", + "timestamp": "2023-02-17T17:22:08Z", + "clientId": 107, + "auditDetail.id": 299223, + "auditDetail.auditId": 737694, + "auditDetail.message": "Changed Parcel Tracking Status from \"Unknown\" to \"Pre Transit\"", + "auditDetail.fieldName": "parcelTrackingStatusId", + "auditDetail.oldValue": "Unknown", + "auditDetail.newValue": "Pre Transit" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "737694", + "recordId": "1191682", + "message": "Record was Edited", + "timestamp": "2023-02-17T17:22:08Z" + } + }, + { + "tableName": "audit", + "recordLabel": "Parcel 1191682", + "values": { + "id": 737695, + "auditTableId": 4, + "auditUserId": 2, + "recordId": 1191682, + "message": "Updating Parcel based on updated tracking details", + "timestamp": "2023-02-17T17:22:09Z", + "clientId": 107, + "auditDetail.id": 299224, + "auditDetail.auditId": 737695, + "auditDetail.message": "Set Parcel Tracking Status to Pre Transit based on most recent tracking update: Shipment information sent to FedEx" + }, + "displayValues": { + "auditTableId": "Parcel", + "auditUserId": "QQQ User", + "clientId": "ACME", + "id": "737695", + "recordId": "1191682", + "message": "Updating Parcel based on updated tracking details", + "timestamp": "2023-02-17T17:22:09Z" + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/fixtures/data/person/1701.json b/src/test/resources/fixtures/data/person/1701.json new file mode 100644 index 0000000..54ceece --- /dev/null +++ b/src/test/resources/fixtures/data/person/1701.json @@ -0,0 +1,16 @@ +{ + "tableName": "person", + "recordLabel": "John Doe", + "values": { + "name": "John Doe", + "id": 1710, + "createDate": "2022-08-30T00:31:00Z", + "modifyDate": "2022-08-30T00:31:00Z" + }, + "displayValues": { + "name": "John Doe", + "id": 1710, + "createDate": "2022-08-30T00:31:00Z", + "modifyDate": "2022-08-30T00:31:00Z" + } +} \ No newline at end of file diff --git a/src/test/resources/fixtures/metaData/index.json b/src/test/resources/fixtures/metaData/index.json index 947343b..1968683 100644 --- a/src/test/resources/fixtures/metaData/index.json +++ b/src/test/resources/fixtures/metaData/index.json @@ -53,6 +53,21 @@ "TABLE_INSERT", "TABLE_DELETE" ] + }, + "audit": { + "name": "audit", + "label": "Audits", + "isHidden": true, + "iconName": "location_city", + "deletePermission": false, + "editPermission": false, + "insertPermission": false, + "readPermission": true, + "capabilities": [ + "TABLE_COUNT", + "TABLE_GET", + "TABLE_QUERY" + ] } }, "processes": { diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml new file mode 100644 index 0000000..870d61f --- /dev/null +++ b/src/test/resources/log4j2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + From a13ec1adc3b55c73628baecd6c951b5d6e891d9d Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 20 Feb 2023 10:09:56 -0600 Subject: [PATCH 04/23] Don't try to show more than 5 values in a filter preview; invert colors of tags in filter control --- .../records/query/GridFilterOperators.tsx | 67 +++++++++++++++++-- src/qqq/styles/qqq-override-styles.css | 11 +++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/qqq/pages/records/query/GridFilterOperators.tsx b/src/qqq/pages/records/query/GridFilterOperators.tsx index 726aa17..3be3c4f 100644 --- a/src/qqq/pages/records/query/GridFilterOperators.tsx +++ b/src/qqq/pages/records/query/GridFilterOperators.tsx @@ -486,9 +486,46 @@ const stringNotEndWithOperator: GridFilterOperator = { InputComponent: GridFilterInputValue, }; +const getListValueString = (value: GridFilterItem["value"]): string => +{ + if (value && value.length) + { + let labels = [] as string[]; + + let maxLoops = value.length; + if(maxLoops > 5) + { + maxLoops = 3; + } + + for (let i = 0; i < maxLoops; i++) + { + labels.push(value[i]); + } + + if(maxLoops < value.length) + { + labels.push(" and " + (value.length - maxLoops) + " other values."); + } + + return (labels.join(", ")); + } + return (value); +}; + const stringIsAnyOfOperator: GridFilterOperator = { label: "is any of", value: "isAnyOf", + getValueAsString: getListValueString, + getApplyFilterFn: () => null, + // @ts-ignore + InputComponent: (props: GridFilterInputMultipleValueProps) => CustomIsAnyInput("text", props) +}; + +const stringIsNoneOfOperator: GridFilterOperator = { + label: "is none of", + value: "isNone", + getValueAsString: getListValueString, getApplyFilterFn: () => null, // @ts-ignore InputComponent: (props: GridFilterInputMultipleValueProps) => CustomIsAnyInput("text", props) @@ -504,7 +541,7 @@ let endsWith = gridStringOperators.splice(0, 1)[0]; // remove default isany operator // /////////////////////////////////// gridStringOperators.splice(2, 1)[0]; -gridStringOperators = [equals, stringNotEqualsOperator, contains, stringNotContainsOperator, startsWith, stringNotStartsWithOperator, endsWith, stringNotEndWithOperator, ...gridStringOperators, stringIsAnyOfOperator]; +gridStringOperators = [equals, stringNotEqualsOperator, contains, stringNotContainsOperator, startsWith, stringNotStartsWithOperator, endsWith, stringNotEndWithOperator, ...gridStringOperators, stringIsAnyOfOperator, stringIsNoneOfOperator]; export const QGridStringOperators = gridStringOperators; @@ -620,6 +657,16 @@ const numericIsAnyOfOperator: GridFilterOperator = { label: "is any of", value: "isAnyOf", getApplyFilterFn: () => null, + getValueAsString: getListValueString, + // @ts-ignore + InputComponent: (props: GridFilterInputMultipleValueProps) => CustomIsAnyInput("number", props) +}; + +const numericIsNoneOfOperator: GridFilterOperator = { + label: "is none of", + value: "isNone", + getApplyFilterFn: () => null, + getValueAsString: getListValueString, // @ts-ignore InputComponent: (props: GridFilterInputMultipleValueProps) => CustomIsAnyInput("number", props) }; @@ -629,7 +676,7 @@ const numericIsAnyOfOperator: GridFilterOperator = { ////////////////////////////// let gridNumericOperators = getGridNumericOperators(); gridNumericOperators.splice(8, 1)[0]; -export const QGridNumericOperators = [...gridNumericOperators, betweenOperator, notBetweenOperator, numericIsAnyOfOperator]; +export const QGridNumericOperators = [...gridNumericOperators, betweenOperator, notBetweenOperator, numericIsAnyOfOperator, numericIsNoneOfOperator]; /////////////////////// // boolean operators // @@ -800,11 +847,17 @@ function InputPossibleValueSourceMultiple(tableName: string, field: QFieldMetaDa const getPvsValueString = (value: GridFilterItem["value"]): string => { - console.log("get pvs value", value); if (value && value.length) { let labels = [] as string[]; - for (let i = 0; i < value.length; i++) + + let maxLoops = value.length; + if(maxLoops > 5) + { + maxLoops = 3; + } + + for (let i = 0; i < maxLoops; i++) { if(value[i] && value[i].label) { @@ -815,6 +868,12 @@ const getPvsValueString = (value: GridFilterItem["value"]): string => labels.push(value); } } + + if(maxLoops < value.length) + { + labels.push(" and " + (value.length - maxLoops) + " other values."); + } + return (labels.join(", ")); } else if (value && value.label) diff --git a/src/qqq/styles/qqq-override-styles.css b/src/qqq/styles/qqq-override-styles.css index 68f864b..0932668 100644 --- a/src/qqq/styles/qqq-override-styles.css +++ b/src/qqq/styles/qqq-override-styles.css @@ -254,6 +254,17 @@ input[type="search"]::-webkit-search-results-decoration { display: none; } background: orange; } +/* make tags in filter forms not be black bg w/ white text */ +.MuiDataGrid-filterForm .MuiAutocomplete-tag +{ + background-color: initial !important; + color: initial !important; +} +.MuiDataGrid-filterForm .MuiAutocomplete-tag .MuiSvgIcon-root +{ + color: initial !important; +} + .MuiTablePagination-root .MuiTablePagination-toolbar .MuiTablePagination-select { padding-right: 1.125rem !important; From 07b71afa832544d079de5338db6dcb8e4f016480 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Tue, 21 Feb 2023 15:20:58 -0600 Subject: [PATCH 05/23] SPRINT-21: added minheights to widgets for stability, attempt to stop multiple requests (again) --- .../components/widgets/DashboardWidgets.tsx | 27 +++++++++---------- .../widgets/charts/piechart/PieChart.tsx | 2 +- .../widgets/statistics/StatisticsCard.tsx | 8 ++++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index 6faf189..94ce913 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -174,7 +174,8 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit widgetIndex={i} widgetMetaData={widgetMetaData} data={widgetData[i]} - reloadWidgetCallback={reloadWidget} + reloadWidgetCallback={() => + {}} storeDropdownSelections={widgetMetaData.storeDropdownSelections} /> ) @@ -271,20 +272,18 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit } { widgetMetaData.type === "statistics" && ( - widgetData && widgetData[i] && ( - reloadWidget(i, data)} - > - - - ) + // reloadWidgetCallback={(data) => reloadWidget(i, data)} + > + + ) } { diff --git a/src/qqq/components/widgets/charts/piechart/PieChart.tsx b/src/qqq/components/widgets/charts/piechart/PieChart.tsx index f97647e..877749a 100644 --- a/src/qqq/components/widgets/charts/piechart/PieChart.tsx +++ b/src/qqq/components/widgets/charts/piechart/PieChart.tsx @@ -85,7 +85,7 @@ function PieChart({description, chartData}: Props): JSX.Element } return ( - + diff --git a/src/qqq/components/widgets/statistics/StatisticsCard.tsx b/src/qqq/components/widgets/statistics/StatisticsCard.tsx index 8a02038..ac728dd 100644 --- a/src/qqq/components/widgets/statistics/StatisticsCard.tsx +++ b/src/qqq/components/widgets/statistics/StatisticsCard.tsx @@ -55,6 +55,10 @@ StatisticsCard.defaultProps = { function StatisticsCard({data, increaseIsGood}: Props): JSX.Element { + if(! data) + { + return null; + } const {count, percentageAmount, percentageLabel} = data; let percentageString = ""; @@ -82,7 +86,7 @@ function StatisticsCard({data, increaseIsGood}: Props): JSX.Element return ( - + { count !== undefined ? ( @@ -96,7 +100,7 @@ function StatisticsCard({data, increaseIsGood}: Props): JSX.Element } ) : ( - + ) } From bf0fc495bfb972f9f74456a3ffcb90397403e2aa Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 22 Feb 2023 17:58:13 -0600 Subject: [PATCH 06/23] add html (process) component type and make PVS's work in processes; fix some nav-back-and-forth wierdness on query screen --- package.json | 2 +- src/qqq/components/forms/DynamicForm.tsx | 1 + src/qqq/components/forms/DynamicFormUtils.ts | 26 ++++-- src/qqq/components/forms/DynamicSelect.tsx | 15 ++-- src/qqq/components/forms/EntityForm.tsx | 4 +- .../components/widgets/DashboardWidgets.tsx | 2 +- src/qqq/components/widgets/Widget.tsx | 2 +- src/qqq/pages/processes/ProcessRun.tsx | 84 ++++++++++++------- src/qqq/pages/records/query/RecordQuery.tsx | 7 +- src/qqq/utils/qqq/FilterUtils.ts | 14 +++- 10 files changed, 103 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 0a1a82b..e1ed165 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.52", + "@kingsrook/qqq-frontend-core": "1.0.53", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", diff --git a/src/qqq/components/forms/DynamicForm.tsx b/src/qqq/components/forms/DynamicForm.tsx index 88400c4..e1159c8 100644 --- a/src/qqq/components/forms/DynamicForm.tsx +++ b/src/qqq/components/forms/DynamicForm.tsx @@ -131,6 +131,7 @@ function QDynamicForm(props: Props): JSX.Element ) + public static addPossibleValueProps(dynamicFormFields: any, qFields: QFieldMetaData[], tableName: string, processName: string, displayValues: Map) { for (let i = 0; i < qFields.length; i++) { @@ -126,12 +126,24 @@ class DynamicFormUtils initialDisplayValue = displayValues.get(field.name); } - dynamicFormFields[field.name].possibleValueProps = - { - isPossibleValue: true, - tableName: tableName, - initialDisplayValue: initialDisplayValue, - }; + if (tableName) + { + dynamicFormFields[field.name].possibleValueProps = + { + isPossibleValue: true, + tableName: tableName, + initialDisplayValue: initialDisplayValue, + }; + } + else + { + dynamicFormFields[field.name].possibleValueProps = + { + isPossibleValue: true, + processName: processName, + initialDisplayValue: initialDisplayValue, + }; + } } } } diff --git a/src/qqq/components/forms/DynamicSelect.tsx b/src/qqq/components/forms/DynamicSelect.tsx index 054d23c..a562b64 100644 --- a/src/qqq/components/forms/DynamicSelect.tsx +++ b/src/qqq/components/forms/DynamicSelect.tsx @@ -35,7 +35,8 @@ import Client from "qqq/utils/qqq/Client"; interface Props { - tableName: string; + tableName?: string; + processName?: string; fieldName: string; fieldLabel: string; inForm: boolean; @@ -50,6 +51,8 @@ interface Props } DynamicSelect.defaultProps = { + tableName: null, + processName: null, inForm: true, initialValue: null, initialDisplayValue: null, @@ -65,7 +68,7 @@ DynamicSelect.defaultProps = { const qController = Client.getInstance(); -function DynamicSelect({tableName, fieldName, fieldLabel, inForm, initialValue, initialDisplayValue, initialValues, onChange, isEditable, isMultiple, bulkEditMode, bulkEditSwitchChangeHandler}: Props) +function DynamicSelect({tableName, processName, fieldName, fieldLabel, inForm, initialValue, initialDisplayValue, initialValues, onChange, isEditable, isMultiple, bulkEditMode, bulkEditSwitchChangeHandler}: Props) { const [ open, setOpen ] = useState(false); const [ options, setOptions ] = useState([]); @@ -109,9 +112,9 @@ function DynamicSelect({tableName, fieldName, fieldLabel, inForm, initialValue, (async () => { // console.log(`doing a search with ${searchTerm}`); - const results: QPossibleValue[] = await qController.possibleValues(tableName, fieldName, searchTerm ?? ""); + const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, fieldName, searchTerm ?? ""); - if(tableMetaData == null) + if(tableMetaData == null && tableName) { let tableMetaData: QTableMetaData = await qController.loadTableMetaData(tableName); setTableMetaData(tableMetaData); @@ -134,7 +137,7 @@ function DynamicSelect({tableName, fieldName, fieldLabel, inForm, initialValue, const inputChanged = (event: React.SyntheticEvent, value: string, reason: string) => { - console.log(`input changed. Reason: ${reason}, setting search term to ${value}`); + // console.log(`input changed. Reason: ${reason}, setting search term to ${value}`); if(reason !== "reset") { // console.log(` -> setting search term to ${value}`); @@ -186,7 +189,7 @@ function DynamicSelect({tableName, fieldName, fieldLabel, inForm, initialValue, try { - const field = tableMetaData.fields.get(fieldName) + const field = tableMetaData?.fields.get(fieldName) if(field) { const adornment = field.getAdornment(AdornmentType.CHIP); diff --git a/src/qqq/components/forms/EntityForm.tsx b/src/qqq/components/forms/EntityForm.tsx index 311ed30..7f9ddf1 100644 --- a/src/qqq/components/forms/EntityForm.tsx +++ b/src/qqq/components/forms/EntityForm.tsx @@ -236,7 +236,7 @@ function EntityForm(props: Props): JSX.Element /////////////////////////////////////////////////////////////////////////////////////////// if (fieldMetaData.possibleValueSourceName) { - const results: QPossibleValue[] = await qController.possibleValues(tableName, fieldName, null, [initialValues[fieldName]]); + const results: QPossibleValue[] = await qController.possibleValues(tableName, null, fieldName, null, [initialValues[fieldName]]); if (results && results.length > 0) { defaultDisplayValues.set(fieldName, results[0].label); @@ -268,7 +268,7 @@ function EntityForm(props: Props): JSX.Element dynamicFormFields, formValidations, } = DynamicFormUtils.getFormData(fieldArray); - DynamicFormUtils.addPossibleValueProps(dynamicFormFields, fieldArray, tableName, record ? record.displayValues : defaultDisplayValues); + DynamicFormUtils.addPossibleValueProps(dynamicFormFields, fieldArray, tableName, null, record ? record.displayValues : defaultDisplayValues); if(disabledFields) { diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index 94ce913..3630f02 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -225,7 +225,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit widgetMetaData={widgetMetaData} widgetData={widgetData[i]} reloadWidgetCallback={(data) => reloadWidget(i, data)}> -
+
diff --git a/src/qqq/components/widgets/Widget.tsx b/src/qqq/components/widgets/Widget.tsx index 320b916..747653a 100644 --- a/src/qqq/components/widgets/Widget.tsx +++ b/src/qqq/components/widgets/Widget.tsx @@ -285,7 +285,7 @@ function Widget(props: React.PropsWithChildren): JSX.Element const hasPermission = props.widgetData?.hasPermission === undefined || props.widgetData?.hasPermission === true; const widgetContent = - + { diff --git a/src/qqq/pages/processes/ProcessRun.tsx b/src/qqq/pages/processes/ProcessRun.tsx index 35d9a62..506784d 100644 --- a/src/qqq/pages/processes/ProcessRun.tsx +++ b/src/qqq/pages/processes/ProcessRun.tsx @@ -38,7 +38,6 @@ import {Alert, Button, CircularProgress, Icon, TablePagination} from "@mui/mater import Box from "@mui/material/Box"; import Card from "@mui/material/Card"; import Grid from "@mui/material/Grid"; -import Link from "@mui/material/Link"; import Step from "@mui/material/Step"; import StepLabel from "@mui/material/StepLabel"; import Stepper from "@mui/material/Stepper"; @@ -46,6 +45,7 @@ import Typography from "@mui/material/Typography"; import {DataGridPro, GridColDef} from "@mui/x-data-grid-pro"; import FormData from "form-data"; import {Form, Formik} from "formik"; +import parse from "html-react-parser"; import React, {useContext, useEffect, useState} from "react"; import {useLocation, useNavigate, useParams} from "react-router-dom"; import * as Yup from "yup"; @@ -75,7 +75,7 @@ interface Props recordIds?: string | QQueryFilter; closeModalHandler?: (event: object, reason: string) => void; forceReInit?: number; - overrideLabel?: string + overrideLabel?: string; } const INITIAL_RETRY_MILLIS = 1_500; @@ -225,12 +225,12 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, xhr.open("POST", url); xhr.responseType = "blob"; let formData = new FormData(); - formData.append("Authorization", qController.getAuthorizationHeaderValue()) + formData.append("Authorization", qController.getAuthorizationHeaderValue()); // @ts-ignore xhr.send(formData); - xhr.onload = function(e) + xhr.onload = function (e) { if (this.status == 200) { @@ -247,7 +247,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, } else { - setProcessError("Error downloading file", true) + setProcessError("Error downloading file", true); } }; }; @@ -299,7 +299,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, {isModal ? - : + : !isWidget && } @@ -350,7 +350,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, const {formFields, values, errors, touched} = formData; let localTableSections = tableSections; - if(localTableSections == null) + if (localTableSections == null) { ////////////////////////////////////////////////////////////////////////////////////////////////////// // if the table sections (ones that actually have fields to edit) haven't been built yet, do so now // @@ -359,6 +359,23 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, setTableSections(localTableSections); } + //////////////////////////////////////////////////////////////////////////////////// + // if there are any fields that are possible values, they need to know what their // + // initial value to display should be. // + // this **needs to be** the actual PVS LABEL - not the raw value (e.g, PVS ID) // + // but our first use case, they're the same, so... this needs fixed. // + //////////////////////////////////////////////////////////////////////////////////// + if(formFields && processValues) + { + Object.keys(formFields).forEach((key) => + { + if(formFields[key].possibleValueProps && processValues[key]) + { + formFields[key].possibleValueProps.initialDisplayValue = processValues[key] + } + }) + } + return ( <> { @@ -420,25 +437,25 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, {localTableSections.map((section: QTableSection, index: number) => { - const name = section.name + const name = section.name; - if(section.isHidden) + if (section.isHidden) { - return ; + return; } const sectionFormFields = {}; - for(let i = 0; i 0) + if (Object.keys(sectionFormFields).length > 0) { const sectionFormData = { formFields: sectionFormFields, @@ -589,6 +606,14 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport,
) } + { + component.type === QComponentType.HTML && ( + processValues[`${step.name}.html`] && + + {parse(processValues[`${step.name}.html`])} + + ) + } )))} @@ -655,7 +680,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, return; } - if(! isWidget) + if (!isWidget) { setPageHeader(overrideLabel ?? processMetaData.label); } @@ -701,10 +726,9 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, { let fullFieldList = getFullFieldList(activeStep, processValues); const formData = DynamicFormUtils.getFormData(fullFieldList); - if(tableMetaData) - { - DynamicFormUtils.addPossibleValueProps(formData.dynamicFormFields, fullFieldList, tableMetaData.name, null); - } + + const possibleValueDisplayValues = new Map(); + DynamicFormUtils.addPossibleValueProps(formData.dynamicFormFields, fullFieldList, tableMetaData?.name, processName, possibleValueDisplayValues); dynamicFormFields = formData.dynamicFormFields; formValidations = formData.formValidations; @@ -819,7 +843,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, } }); - DynamicFormUtils.addPossibleValueProps(newDynamicFormFields, fullFieldList, tableMetaData.name, null); + DynamicFormUtils.addPossibleValueProps(newDynamicFormFields, fullFieldList, tableMetaData.name, null, null); setFormFields(newDynamicFormFields); setValidationScheme(Yup.object().shape(newFormValidations)); @@ -981,11 +1005,11 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, { if ((e as QException).status === "403") { - setProcessError(`You do not have permission to run this ${isReport ? "report" : "process"}.`, true) + setProcessError(`You do not have permission to run this ${isReport ? "report" : "process"}.`, true); return (true); } return (false); - } + }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -1175,7 +1199,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, mainCardStyles.background = "none"; mainCardStyles.boxShadow = "none"; } - if(isWidget) + if (isWidget) { mainCardStyles.background = "none"; mainCardStyles.boxShadow = "none"; @@ -1231,10 +1255,10 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, } - + {/*************************************************************************** - ** step content - e.g., the appropriate form or other screen for the step ** - ***************************************************************************/} + ** step content - e.g., the appropriate form or other screen for the step ** + ***************************************************************************/} {getDynamicStepContent( activeStepIndex, activeStep, @@ -1250,9 +1274,9 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, setFieldValue, )} {/******************************** - ** back &| next/submit buttons ** - ********************************/} - + ** back &| next/submit buttons ** + ********************************/} + {true || activeStepIndex === 0 ? ( ) : ( @@ -1279,7 +1303,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, { - ! isWidget && ( + !isWidget && ( ) } @@ -1320,7 +1344,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, else if (isWidget) { return ( - + {form} ); diff --git a/src/qqq/pages/records/query/RecordQuery.tsx b/src/qqq/pages/records/query/RecordQuery.tsx index 58eb69a..bb6e2f2 100644 --- a/src/qqq/pages/records/query/RecordQuery.tsx +++ b/src/qqq/pages/records/query/RecordQuery.tsx @@ -221,7 +221,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element const parts = location.pathname.split("/"); currentSavedFilterId = Number.parseInt(parts[parts.length - 1]); } - else + else if(!searchParams.has("filter")) { if (localStorage.getItem(currentSavedFilterLocalStorageKey)) { @@ -573,10 +573,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element setFilterModel(filterModel); if (filterLocalStorageKey) { - localStorage.setItem( - filterLocalStorageKey, - JSON.stringify(filterModel), - ); + localStorage.setItem(filterLocalStorageKey, JSON.stringify(filterModel)); } }; diff --git a/src/qqq/utils/qqq/FilterUtils.ts b/src/qqq/utils/qqq/FilterUtils.ts index dbfb055..c79e10c 100644 --- a/src/qqq/utils/qqq/FilterUtils.ts +++ b/src/qqq/utils/qqq/FilterUtils.ts @@ -30,6 +30,8 @@ import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryF import {GridFilterModel, GridLinkOperator, GridSortItem} from "@mui/x-data-grid-pro"; import ValueUtils from "qqq/utils/qqq/ValueUtils"; +const CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedFilterId"; + /******************************************************************************* ** Utility class for working with QQQ Filters ** @@ -366,7 +368,7 @@ class FilterUtils ////////////////////////////////////////////////////////////////////////////////// if (values && values.length > 0) { - values = await qController.possibleValues(tableMetaData.name, field.name, "", values); + values = await qController.possibleValues(tableMetaData.name, null, field.name, "", values); } //////////////////////////////////////////// @@ -454,6 +456,16 @@ class FilterUtils } } + if (searchParams && searchParams.has("filter")) + { + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // if we're setting the filter based on a filter query-string param, then make sure we don't have a currentSavedFilter in local storage. // + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + localStorage.removeItem(`${CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT}.${tableMetaData.name}`); + localStorage.setItem(filterLocalStorageKey, JSON.stringify(defaultFilter)); + localStorage.setItem(sortLocalStorageKey, JSON.stringify(defaultSort)); + } + return ({filter: defaultFilter, sort: defaultSort}); } catch (e) From 9244e8c90fe7c5d07fd643b8b34669dec1a1d621 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Thu, 23 Feb 2023 09:35:21 -0600 Subject: [PATCH 07/23] SPRINT-21: added omitReloadWidgetCallback option to parent widget data --- src/qqq/components/widgets/DashboardWidgets.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index 3630f02..63565b1 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -174,8 +174,8 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit widgetIndex={i} widgetMetaData={widgetMetaData} data={widgetData[i]} - reloadWidgetCallback={() => - {}} + reloadWidgetCallback={widgetData[i].omitReloadWidgetCallback ? () => + {} : reloadWidget} storeDropdownSelections={widgetMetaData.storeDropdownSelections} /> ) From 83c5e725c3b6e9e1b794fc193d126c9791943a93 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Thu, 23 Feb 2023 11:09:26 -0600 Subject: [PATCH 08/23] SPRINT-21: added minheight, updated frontend core version --- package-lock.json | 1261 +++++++++++++------------ package.json | 2 +- src/qqq/components/widgets/Widget.tsx | 2 +- 3 files changed, 670 insertions(+), 595 deletions(-) diff --git a/package-lock.json b/package-lock.json index 11f580f..55f44f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.52", + "@kingsrook/qqq-frontend-core": "1.0.54", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", "@mui/system": "5.11.1", - "@mui/x-data-grid": "5.17.6", - "@mui/x-data-grid-pro": "5.17.6", + "@mui/x-data-grid": "5.17.23", + "@mui/x-data-grid-pro": "5.17.23", "@mui/x-license-pro": "5.12.3", "@react-jvectormap/core": "1.0.1", "@react-jvectormap/unitedstates": "1.0.1", @@ -70,6 +70,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "devOptional": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -116,28 +117,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", - "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "devOptional": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", + "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "devOptional": true, "dependencies": { - "@ampproject/remapping": "^2.1.0", + "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.0", "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.0", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.0", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -180,12 +183,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", - "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "version": "7.21.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", + "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "devOptional": true, "dependencies": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.21.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -196,6 +201,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "devOptional": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -234,6 +240,7 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "devOptional": true, "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", @@ -249,15 +256,15 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", - "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", + "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -271,13 +278,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", + "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" + "regexpu-core": "^5.3.1" }, "engines": { "node": ">=6.9.0" @@ -307,6 +314,7 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -324,12 +332,13 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "devOptional": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -339,6 +348,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "devOptional": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -347,12 +357,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", - "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", "dev": true, "dependencies": { - "@babel/types": "^7.20.7" + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -370,9 +380,10 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "devOptional": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", @@ -380,8 +391,8 @@ "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" }, "engines": { "node": ">=6.9.0" @@ -403,6 +414,7 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -446,6 +458,7 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "devOptional": true, "dependencies": { "@babel/types": "^7.20.2" }, @@ -469,6 +482,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "devOptional": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -493,9 +507,10 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -516,13 +531,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", - "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "devOptional": true, "dependencies": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.13", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -542,9 +558,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "devOptional": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -619,12 +636,12 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", - "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, @@ -636,16 +653,16 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz", - "integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz", + "integrity": "sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.12", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" + "@babel/plugin-syntax-decorators": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -786,9 +803,9 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", - "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", @@ -819,13 +836,13 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, @@ -904,12 +921,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz", + "integrity": "sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1000,6 +1017,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1175,9 +1193,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.15.tgz", - "integrity": "sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" @@ -1190,15 +1208,15 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", - "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", @@ -1291,12 +1309,12 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", + "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-flow": "^7.18.6" }, "engines": { @@ -1307,12 +1325,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1385,12 +1403,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", - "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", + "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-module-transforms": "^7.21.2", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-simple-access": "^7.20.2" }, @@ -1543,16 +1561,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.13.tgz", - "integrity": "sha512-MmTZx/bkUrfJhhYAYt3Urjm+h8DQGrPrnKQ94jLo7NLuOU+T89a7IByhKmrb8SKhrIYIQ0FN0CHMbnFRen4qNw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", + "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.20.7" + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -1624,13 +1642,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz", + "integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1720,12 +1738,12 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.13.tgz", - "integrity": "sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz", + "integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.12", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" }, @@ -1893,14 +1911,14 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz", + "integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-transform-typescript": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -1916,9 +1934,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -1930,6 +1948,7 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.20.7", @@ -1940,18 +1959,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", - "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", + "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.1", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.13", - "@babel/types": "^7.20.7", + "@babel/parser": "^7.21.2", + "@babel/types": "^7.21.2", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1960,9 +1980,9 @@ } }, "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", + "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", "dependencies": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -2338,12 +2358,11 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -2354,9 +2373,6 @@ "find-root": "^1.1.0", "source-map": "^0.5.7", "stylis": "4.1.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@emotion/cache": { @@ -3297,6 +3313,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "devOptional": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3309,6 +3326,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -3317,6 +3335,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -3348,21 +3367,23 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@kingsrook/qqq-frontend-core": { - "version": "1.0.52", - "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.52/b9f1292a2262e07e202738c41a10753c1eaa8877", - "integrity": "sha512-lL37n9+zvmSZHDigpZv+RGsxVfApC+MvUK5aNvmOHh+oD+H4IpaatDlILWAc1gRE49Ln3Ib/EbZH5lEUfGpOdA==", + "version": "1.0.54", + "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.54/84d9578cd18ba8c659b52e85c472835d0461093f", + "integrity": "sha512-WOdhHFTdSjQyMuDEiHYlAdtKeE5O6a6l+hbSJ+fiJVchdJ8RCF3qnusbe39nUPbrTiobyculm/ejEfYg9aFmWw==", "license": "ISC", "dependencies": { "axios": "0.27.2", @@ -3408,9 +3429,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.11.8", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.8.tgz", - "integrity": "sha512-n/uJRIwZAaJaROaOA4VzycxDo27cusnrRzfycnAkAP5gBndwOJQ1CXjd1Y7hJe5eorj/ukixC7IZD+qCClMCMg==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.9.tgz", + "integrity": "sha512-YGEtucQ/Nl91VZkzYaLad47Cdui51n/hW+OQm4210g4N3/nZzBxmGeKfubEalf+ShKH4aYDS86XTO6q/TpZnjQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" @@ -3486,12 +3507,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz", - "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.9.tgz", + "integrity": "sha512-XMyVIFGomVCmCm92EvYlgq3zrC9K+J6r7IKl/rBJT2/xVYoRY6uM7jeB+Wxh7kXxnW9Dbqsr2yL3cx6wSD1sAg==", "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/utils": "^5.11.7", + "@babel/runtime": "^7.20.13", + "@mui/utils": "^5.11.9", "prop-types": "^15.8.1" }, "engines": { @@ -3512,11 +3533,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.11.8", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.8.tgz", - "integrity": "sha512-iSpZp9AoeictsDi5xAQ4PGXu7mKtQyzMl7ZaWpHIGMFpsNnfY3NQNg+wkj/gpsAZ+Zg+IIyD+t+ig71Kr9fa0w==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.9.tgz", + "integrity": "sha512-bkh2CjHKOMy98HyOc8wQXEZvhOmDa/bhxMUekFX5IG0/w4f5HJ8R6+K6nakUUYNEgjOWPYzNPrvGB8EcGbhahQ==", "dependencies": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@emotion/cache": "^11.10.5", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -3635,11 +3656,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz", - "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz", + "integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==", "dependencies": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -3657,9 +3678,9 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "5.17.6", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-5.17.6.tgz", - "integrity": "sha512-+JvXyFEOhJGr53QgiuObR6ZOeV3qLoYoJi5LALiYGrvv2Fk+amQqPdfkf4t68yRhyJjT+praKNXebUjHrSLZcA==", + "version": "5.17.23", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-5.17.23.tgz", + "integrity": "sha512-vCGHiwUp479S/5Le+8zpeJ6hBRVYcP/F0Wbai2rk0VoP6q5ZKPcJ08jdlax62QsIAkmGY67jhXMEQeq43lobqw==", "dependencies": { "@babel/runtime": "^7.18.9", "@mui/utils": "^5.10.3", @@ -3682,14 +3703,14 @@ } }, "node_modules/@mui/x-data-grid-pro": { - "version": "5.17.6", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-5.17.6.tgz", - "integrity": "sha512-69+9ZiUqOr7EfOkZgBqHJoe2kEaT2xIP5NEUb/Cz5Ktfq0q8Sp4b7974Gexbz1coqfadm6C4VLhYLaLBeSWusA==", + "version": "5.17.23", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-5.17.23.tgz", + "integrity": "sha512-JKM1DtLq86VQcyHRA7mbjGjACfpApQoASKYhSFSCS3llzhCCBxiIC0i0ZPnXkPZC/aW9Ir9wUsUSDjcD5NSe1Q==", "dependencies": { "@babel/runtime": "^7.18.9", "@mui/utils": "^5.10.3", - "@mui/x-data-grid": "5.17.6", - "@mui/x-license-pro": "5.17.0", + "@mui/x-data-grid": "5.17.23", + "@mui/x-license-pro": "5.17.12", "@types/format-util": "^1.0.2", "clsx": "^1.2.1", "prop-types": "^15.8.1", @@ -3706,12 +3727,12 @@ } }, "node_modules/@mui/x-data-grid-pro/node_modules/@mui/x-license-pro": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-5.17.0.tgz", - "integrity": "sha512-SVn0E1sUSjuvT79mvfFnW1BtwfiQ+yg6hZpTNwS13a9hJLRJYDI+GiEypArsXRHHvs5XL5PVMmfmHs5voQF9Iw==", + "version": "5.17.12", + "resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-5.17.12.tgz", + "integrity": "sha512-UzFaE+9A30kfguCuME0D5zqsItqbHZ3xZwmyrJr8MvZOEoqiJWF4NT4Pvlg2nqaPYt/h81j7sjVFa3KiwT0vbg==", "dependencies": { "@babel/runtime": "^7.18.9", - "@mui/utils": "^5.9.3" + "@mui/utils": "^5.10.3" }, "engines": { "node": ">=12.0.0" @@ -4384,9 +4405,9 @@ "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" }, "node_modules/@types/eslint": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz", - "integrity": "sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==", + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.1.tgz", + "integrity": "sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ==", "dev": true, "dependencies": { "@types/estree": "*", @@ -4473,9 +4494,9 @@ "dev": true }, "node_modules/@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", + "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", "dependencies": { "@types/node": "*" } @@ -4705,9 +4726,9 @@ "dev": true }, "node_modules/@types/trusted-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", - "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", "dev": true }, "node_modules/@types/ws": { @@ -4811,12 +4832,12 @@ "dev": true }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.52.0.tgz", - "integrity": "sha512-kd8CRr04mNE3hw4et6+0T0NI5vli2H6dJCGzjX1r12s/FXUehLVadmvo2Nl3DN80YqAh1cVC6zYZAkpmGiVJ5g==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.53.0.tgz", + "integrity": "sha512-4SklZEwRn0jqkhtW+pPZpbKFXprwGneBndRM0TGzJu/LWdb9QV2hBgFIVU9AREo02BzqFvyG/ypd+xAW5YGhXw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.52.0" + "@typescript-eslint/utils": "5.53.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4830,13 +4851,13 @@ } }, "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", + "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4847,9 +4868,9 @@ } }, "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", + "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4860,13 +4881,13 @@ } }, "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", + "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4887,16 +4908,16 @@ } }, "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", + "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/typescript-estree": "5.53.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -4913,12 +4934,12 @@ } }, "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", + "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.53.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -6363,6 +6384,7 @@ "version": "4.21.5", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "devOptional": true, "funding": [ { "type": "opencollective", @@ -6535,9 +6557,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001451", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", - "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", + "version": "1.0.30001457", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz", + "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==", + "devOptional": true, "funding": [ { "type": "opencollective", @@ -6987,9 +7010,9 @@ "dev": true }, "node_modules/core-js": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz", - "integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz", + "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -6997,12 +7020,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", - "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.28.0.tgz", + "integrity": "sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg==", "dev": true, "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.21.5" }, "funding": { "type": "opencollective", @@ -7010,9 +7033,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.2.tgz", - "integrity": "sha512-Cf2jqAbXgWH3VVzjyaaFkY1EBazxugUepGymDoeteyYr9ByX51kD2jdHZlsEF/xnJMyN3Prua7mQuzwMg6Zc9A==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.28.0.tgz", + "integrity": "sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ==", "dev": true, "hasInstallScript": true, "funding": { @@ -7383,12 +7406,12 @@ } }, "node_modules/cssnano": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", - "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", "dev": true, "dependencies": { - "cssnano-preset-default": "^5.2.13", + "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, @@ -7404,22 +7427,22 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", - "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", "dev": true, "dependencies": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", + "postcss-colormin": "^5.3.1", "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.3", + "postcss-merge-rules": "^5.1.4", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", "postcss-minify-params": "^5.1.4", @@ -7434,7 +7457,7 @@ "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.1", + "postcss-reduce-initial": "^5.1.2", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -7730,6 +7753,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "devOptional": true, "dependencies": { "ms": "2.1.2" }, @@ -8232,9 +8256,10 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.295", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", - "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==" + "version": "1.4.308", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz", + "integrity": "sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ==", + "devOptional": true }, "node_modules/emittery": { "version": "0.8.1", @@ -8903,9 +8928,9 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.1.tgz", - "integrity": "sha512-GRy87AqUi2Ij69pe0YnOXm3oGBCgnFwfIv+Hu9q/kT3jL0pX1cXA7aO+oJnvdpbJy2+riOPqGsa3iAkL888NLg==", + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.2.tgz", + "integrity": "sha512-f1DmDWcz5SDM+IpCkEX0lbFqrrTs8HRsEElzDEqN/EBI0hpRj8Cns5+IVANXswE8/LeybIJqPAOQIFu2j5Y5sw==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.43.0" @@ -8919,13 +8944,13 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", + "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8936,9 +8961,9 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", + "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8949,13 +8974,13 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", + "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8976,16 +9001,16 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", + "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/typescript-estree": "5.53.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -9002,12 +9027,12 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", + "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.53.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -9373,9 +9398,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -10301,6 +10326,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -10392,9 +10418,9 @@ } }, "node_modules/github-buttons": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.23.0.tgz", - "integrity": "sha512-2REUOV3ue6NmT0QThhfzfYmeSoYpCG73+tL7Ir2C7P+gshRerI05WuIQuhDkE2Zlg5Wc39hc2DHj+pE23mGJvw==" + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.24.0.tgz", + "integrity": "sha512-dHpEno4S2JHjsEKPLSTGDTV50q1d08n3H7VDfNNA1m8cz5DMqLCZDdKWQxy4zyvd6M3tKvlVYLs+/H0BF3DggA==" }, "node_modules/glob": { "version": "7.2.3", @@ -10497,6 +10523,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "devOptional": true, "engines": { "node": ">=4" } @@ -10718,9 +10745,9 @@ "dev": true }, "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", @@ -14140,6 +14167,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "devOptional": true, "bin": { "jsesc": "bin/jsesc" }, @@ -14180,6 +14208,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "devOptional": true, "bin": { "json5": "lib/cli.js" }, @@ -14724,6 +14753,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "devOptional": true, "dependencies": { "yallist": "^3.0.2" } @@ -14972,7 +15002,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -15059,7 +15090,8 @@ "node_modules/node-releases": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "devOptional": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -15303,9 +15335,9 @@ } }, "node_modules/open": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.1.tgz", - "integrity": "sha512-/4b7qZNhv6Uhd7jjnREh1NjnPxlTq+XNWPG88Ydkj5AILcA5m3ajvcg57pB24EQjKv0dK62XnDqk9c/hkIG5Kg==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", @@ -15545,7 +15577,8 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "devOptional": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -15855,12 +15888,12 @@ } }, "node_modules/postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", "dev": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" @@ -16320,9 +16353,9 @@ } }, "node_modules/postcss-merge-rules": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", - "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", "dev": true, "dependencies": { "browserslist": "^4.21.4", @@ -16823,9 +16856,9 @@ } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", - "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", "dev": true, "dependencies": { "browserslist": "^4.21.4", @@ -17653,9 +17686,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", + "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -17758,9 +17791,9 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.0.tgz", - "integrity": "sha512-ZdhUQlng0RoscyW7jADnUZ25F5eVtHdMyXSb2PiwafvteRAOJUjFoUPEYZSIfP99fBIs3maLIRfpEddT78wAAQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.1.tgz", + "integrity": "sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==", "dev": true, "dependencies": { "@babel/regjsgen": "^0.8.0", @@ -18306,6 +18339,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "devOptional": true, "bin": { "semver": "bin/semver.js" } @@ -19081,9 +19115,9 @@ "dev": true }, "node_modules/tailwindcss": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.6.tgz", - "integrity": "sha512-BfgQWZrtqowOQMC2bwaSNe7xcIjdDEgixWGYOd6AL0CbKHJlvhfdbINeAW76l1sO+1ov/MJ93ODJ9yluRituIw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz", + "integrity": "sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==", "dev": true, "dependencies": { "arg": "^5.0.2", @@ -19192,9 +19226,9 @@ } }, "node_modules/terser": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", - "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.5.tgz", + "integrity": "sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -19660,6 +19694,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "devOptional": true, "funding": [ { "type": "opencollective", @@ -20076,9 +20111,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.1.tgz", + "integrity": "sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==", "dev": true, "engines": { "node": ">=10.0.0" @@ -20717,7 +20752,8 @@ "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "devOptional": true }, "node_modules/yaml": { "version": "1.10.2", @@ -20728,9 +20764,9 @@ } }, "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -20797,6 +20833,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "devOptional": true, "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -20833,25 +20870,27 @@ } }, "@babel/compat-data": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", - "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==" + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "devOptional": true }, "@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", + "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "devOptional": true, "requires": { - "@ampproject/remapping": "^2.1.0", + "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.0", "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.0", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.0", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -20879,12 +20918,14 @@ } }, "@babel/generator": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", - "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "version": "7.21.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", + "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "devOptional": true, "requires": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.21.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -20892,6 +20933,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "devOptional": true, "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -20923,6 +20965,7 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "devOptional": true, "requires": { "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", @@ -20932,15 +20975,15 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", - "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", + "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -20948,13 +20991,13 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", + "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" + "regexpu-core": "^5.3.1" } }, "@babel/helper-define-polyfill-provider": { @@ -20974,7 +21017,8 @@ "@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "devOptional": true }, "@babel/helper-explode-assignable-expression": { "version": "7.18.6", @@ -20986,29 +21030,31 @@ } }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "devOptional": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" } }, "@babel/helper-hoist-variables": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "devOptional": true, "requires": { "@babel/types": "^7.18.6" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", - "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", "dev": true, "requires": { - "@babel/types": "^7.20.7" + "@babel/types": "^7.21.0" } }, "@babel/helper-module-imports": { @@ -21020,9 +21066,10 @@ } }, "@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "devOptional": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", @@ -21030,8 +21077,8 @@ "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" } }, "@babel/helper-optimise-call-expression": { @@ -21046,7 +21093,8 @@ "@babel/helper-plugin-utils": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true }, "@babel/helper-remap-async-to-generator": { "version": "7.18.9", @@ -21078,6 +21126,7 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "devOptional": true, "requires": { "@babel/types": "^7.20.2" } @@ -21095,6 +21144,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "devOptional": true, "requires": { "@babel/types": "^7.18.6" } @@ -21110,9 +21160,10 @@ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "devOptional": true }, "@babel/helper-wrap-function": { "version": "7.20.5", @@ -21127,13 +21178,14 @@ } }, "@babel/helpers": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", - "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "devOptional": true, "requires": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.13", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" } }, "@babel/highlight": { @@ -21147,9 +21199,10 @@ } }, "@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==" + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "devOptional": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -21194,27 +21247,27 @@ } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", - "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz", - "integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz", + "integrity": "sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.12", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" + "@babel/plugin-syntax-decorators": "^7.21.0" } }, "@babel/plugin-proposal-dynamic-import": { @@ -21301,9 +21354,9 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", - "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.20.2", @@ -21322,13 +21375,13 @@ } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } @@ -21380,12 +21433,12 @@ } }, "@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz", + "integrity": "sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-dynamic-import": { @@ -21446,6 +21499,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -21561,24 +21615,24 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.15.tgz", - "integrity": "sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-classes": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", - "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", @@ -21635,22 +21689,22 @@ } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", + "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-flow": "^7.18.6" } }, "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-function-name": { @@ -21693,12 +21747,12 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", - "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", + "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-module-transforms": "^7.21.2", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-simple-access": "^7.20.2" } @@ -21791,16 +21845,16 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.13.tgz", - "integrity": "sha512-MmTZx/bkUrfJhhYAYt3Urjm+h8DQGrPrnKQ94jLo7NLuOU+T89a7IByhKmrb8SKhrIYIQ0FN0CHMbnFRen4qNw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", + "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.20.7" + "@babel/types": "^7.21.0" } }, "@babel/plugin-transform-react-jsx-development": { @@ -21842,13 +21896,13 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz", + "integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -21902,12 +21956,12 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.13.tgz", - "integrity": "sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz", + "integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.12", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" } @@ -22042,14 +22096,14 @@ } }, "@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz", + "integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-transform-typescript": "^7.21.0" } }, "@babel/regjsgen": { @@ -22059,9 +22113,9 @@ "dev": true }, "@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "requires": { "regenerator-runtime": "^0.13.11" } @@ -22070,6 +22124,7 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "devOptional": true, "requires": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.20.7", @@ -22077,26 +22132,27 @@ } }, "@babel/traverse": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", - "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", + "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", + "devOptional": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.1", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.13", - "@babel/types": "^7.20.7", + "@babel/parser": "^7.21.2", + "@babel/types": "^7.21.2", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", + "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", "requires": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -22319,12 +22375,11 @@ } }, "@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", "requires": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -23051,6 +23106,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "devOptional": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -23059,12 +23115,14 @@ "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "devOptional": true }, "@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "devOptional": true }, "@jridgewell/source-map": { "version": "0.3.2", @@ -23092,21 +23150,23 @@ "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "devOptional": true }, "@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, "@kingsrook/qqq-frontend-core": { - "version": "1.0.52", - "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.52/b9f1292a2262e07e202738c41a10753c1eaa8877", - "integrity": "sha512-lL37n9+zvmSZHDigpZv+RGsxVfApC+MvUK5aNvmOHh+oD+H4IpaatDlILWAc1gRE49Ln3Ib/EbZH5lEUfGpOdA==", + "version": "1.0.54", + "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.54/84d9578cd18ba8c659b52e85c472835d0461093f", + "integrity": "sha512-WOdhHFTdSjQyMuDEiHYlAdtKeE5O6a6l+hbSJ+fiJVchdJ8RCF3qnusbe39nUPbrTiobyculm/ejEfYg9aFmWw==", "requires": { "axios": "0.27.2", "form-data": "4.0.0" @@ -23134,9 +23194,9 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.11.8", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.8.tgz", - "integrity": "sha512-n/uJRIwZAaJaROaOA4VzycxDo27cusnrRzfycnAkAP5gBndwOJQ1CXjd1Y7hJe5eorj/ukixC7IZD+qCClMCMg==" + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.9.tgz", + "integrity": "sha512-YGEtucQ/Nl91VZkzYaLad47Cdui51n/hW+OQm4210g4N3/nZzBxmGeKfubEalf+ShKH4aYDS86XTO6q/TpZnjQ==" }, "@mui/icons-material": { "version": "5.4.1", @@ -23166,21 +23226,21 @@ } }, "@mui/private-theming": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz", - "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.9.tgz", + "integrity": "sha512-XMyVIFGomVCmCm92EvYlgq3zrC9K+J6r7IKl/rBJT2/xVYoRY6uM7jeB+Wxh7kXxnW9Dbqsr2yL3cx6wSD1sAg==", "requires": { - "@babel/runtime": "^7.20.7", - "@mui/utils": "^5.11.7", + "@babel/runtime": "^7.20.13", + "@mui/utils": "^5.11.9", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.11.8", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.8.tgz", - "integrity": "sha512-iSpZp9AoeictsDi5xAQ4PGXu7mKtQyzMl7ZaWpHIGMFpsNnfY3NQNg+wkj/gpsAZ+Zg+IIyD+t+ig71Kr9fa0w==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.9.tgz", + "integrity": "sha512-bkh2CjHKOMy98HyOc8wQXEZvhOmDa/bhxMUekFX5IG0/w4f5HJ8R6+K6nakUUYNEgjOWPYzNPrvGB8EcGbhahQ==", "requires": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@emotion/cache": "^11.10.5", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -23232,11 +23292,11 @@ "requires": {} }, "@mui/utils": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz", - "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz", + "integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==", "requires": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -23244,9 +23304,9 @@ } }, "@mui/x-data-grid": { - "version": "5.17.6", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-5.17.6.tgz", - "integrity": "sha512-+JvXyFEOhJGr53QgiuObR6ZOeV3qLoYoJi5LALiYGrvv2Fk+amQqPdfkf4t68yRhyJjT+praKNXebUjHrSLZcA==", + "version": "5.17.23", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-5.17.23.tgz", + "integrity": "sha512-vCGHiwUp479S/5Le+8zpeJ6hBRVYcP/F0Wbai2rk0VoP6q5ZKPcJ08jdlax62QsIAkmGY67jhXMEQeq43lobqw==", "requires": { "@babel/runtime": "^7.18.9", "@mui/utils": "^5.10.3", @@ -23256,14 +23316,14 @@ } }, "@mui/x-data-grid-pro": { - "version": "5.17.6", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-5.17.6.tgz", - "integrity": "sha512-69+9ZiUqOr7EfOkZgBqHJoe2kEaT2xIP5NEUb/Cz5Ktfq0q8Sp4b7974Gexbz1coqfadm6C4VLhYLaLBeSWusA==", + "version": "5.17.23", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-5.17.23.tgz", + "integrity": "sha512-JKM1DtLq86VQcyHRA7mbjGjACfpApQoASKYhSFSCS3llzhCCBxiIC0i0ZPnXkPZC/aW9Ir9wUsUSDjcD5NSe1Q==", "requires": { "@babel/runtime": "^7.18.9", "@mui/utils": "^5.10.3", - "@mui/x-data-grid": "5.17.6", - "@mui/x-license-pro": "5.17.0", + "@mui/x-data-grid": "5.17.23", + "@mui/x-license-pro": "5.17.12", "@types/format-util": "^1.0.2", "clsx": "^1.2.1", "prop-types": "^15.8.1", @@ -23271,12 +23331,12 @@ }, "dependencies": { "@mui/x-license-pro": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-5.17.0.tgz", - "integrity": "sha512-SVn0E1sUSjuvT79mvfFnW1BtwfiQ+yg6hZpTNwS13a9hJLRJYDI+GiEypArsXRHHvs5XL5PVMmfmHs5voQF9Iw==", + "version": "5.17.12", + "resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-5.17.12.tgz", + "integrity": "sha512-UzFaE+9A30kfguCuME0D5zqsItqbHZ3xZwmyrJr8MvZOEoqiJWF4NT4Pvlg2nqaPYt/h81j7sjVFa3KiwT0vbg==", "requires": { "@babel/runtime": "^7.18.9", - "@mui/utils": "^5.9.3" + "@mui/utils": "^5.10.3" } } } @@ -23725,9 +23785,9 @@ "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" }, "@types/eslint": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz", - "integrity": "sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==", + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.1.tgz", + "integrity": "sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ==", "dev": true, "requires": { "@types/estree": "*", @@ -23814,9 +23874,9 @@ "dev": true }, "@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", + "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", "requires": { "@types/node": "*" } @@ -24046,9 +24106,9 @@ "dev": true }, "@types/trusted-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", - "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", "dev": true }, "@types/ws": { @@ -24129,38 +24189,38 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.52.0.tgz", - "integrity": "sha512-kd8CRr04mNE3hw4et6+0T0NI5vli2H6dJCGzjX1r12s/FXUehLVadmvo2Nl3DN80YqAh1cVC6zYZAkpmGiVJ5g==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.53.0.tgz", + "integrity": "sha512-4SklZEwRn0jqkhtW+pPZpbKFXprwGneBndRM0TGzJu/LWdb9QV2hBgFIVU9AREo02BzqFvyG/ypd+xAW5YGhXw==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.52.0" + "@typescript-eslint/utils": "5.53.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", + "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0" } }, "@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", + "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", + "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -24169,28 +24229,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", + "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/typescript-estree": "5.53.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", + "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.53.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -25282,6 +25342,7 @@ "version": "4.21.5", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "devOptional": true, "requires": { "caniuse-lite": "^1.0.30001449", "electron-to-chromium": "^1.4.284", @@ -25396,9 +25457,10 @@ } }, "caniuse-lite": { - "version": "1.0.30001451", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", - "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==" + "version": "1.0.30001457", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz", + "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==", + "devOptional": true }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -25745,23 +25807,23 @@ "dev": true }, "core-js": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz", - "integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==" + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz", + "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==" }, "core-js-compat": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", - "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.28.0.tgz", + "integrity": "sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg==", "dev": true, "requires": { - "browserslist": "^4.21.4" + "browserslist": "^4.21.5" } }, "core-js-pure": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.2.tgz", - "integrity": "sha512-Cf2jqAbXgWH3VVzjyaaFkY1EBazxugUepGymDoeteyYr9ByX51kD2jdHZlsEF/xnJMyN3Prua7mQuzwMg6Zc9A==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.28.0.tgz", + "integrity": "sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ==", "dev": true }, "core-util-is": { @@ -26004,33 +26066,33 @@ "dev": true }, "cssnano": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", - "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", "dev": true, "requires": { - "cssnano-preset-default": "^5.2.13", + "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", "yaml": "^1.10.2" } }, "cssnano-preset-default": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", - "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", "dev": true, "requires": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", + "postcss-colormin": "^5.3.1", "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.3", + "postcss-merge-rules": "^5.1.4", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", "postcss-minify-params": "^5.1.4", @@ -26045,7 +26107,7 @@ "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.1", + "postcss-reduce-initial": "^5.1.2", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -26278,6 +26340,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "devOptional": true, "requires": { "ms": "2.1.2" } @@ -26671,9 +26734,10 @@ } }, "electron-to-chromium": { - "version": "1.4.295", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", - "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==" + "version": "1.4.308", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz", + "integrity": "sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ==", + "devOptional": true }, "emittery": { "version": "0.8.1", @@ -27265,38 +27329,38 @@ "requires": {} }, "eslint-plugin-testing-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.1.tgz", - "integrity": "sha512-GRy87AqUi2Ij69pe0YnOXm3oGBCgnFwfIv+Hu9q/kT3jL0pX1cXA7aO+oJnvdpbJy2+riOPqGsa3iAkL888NLg==", + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.2.tgz", + "integrity": "sha512-f1DmDWcz5SDM+IpCkEX0lbFqrrTs8HRsEElzDEqN/EBI0hpRj8Cns5+IVANXswE8/LeybIJqPAOQIFu2j5Y5sw==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.43.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", + "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0" } }, "@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", + "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", + "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -27305,28 +27369,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", + "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/typescript-estree": "5.53.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", + "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.53.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -27500,9 +27564,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -28202,7 +28266,8 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "devOptional": true }, "get-caller-file": { "version": "2.0.5", @@ -28270,9 +28335,9 @@ } }, "github-buttons": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.23.0.tgz", - "integrity": "sha512-2REUOV3ue6NmT0QThhfzfYmeSoYpCG73+tL7Ir2C7P+gshRerI05WuIQuhDkE2Zlg5Wc39hc2DHj+pE23mGJvw==" + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.24.0.tgz", + "integrity": "sha512-dHpEno4S2JHjsEKPLSTGDTV50q1d08n3H7VDfNNA1m8cz5DMqLCZDdKWQxy4zyvd6M3tKvlVYLs+/H0BF3DggA==" }, "glob": { "version": "7.2.3", @@ -28352,7 +28417,8 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "devOptional": true }, "globalthis": { "version": "1.0.3", @@ -28516,9 +28582,9 @@ "dev": true }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -31043,7 +31109,8 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "devOptional": true }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -31077,7 +31144,8 @@ "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "devOptional": true }, "jsonfile": { "version": "6.1.0", @@ -31509,6 +31577,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "devOptional": true, "requires": { "yallist": "^3.0.2" } @@ -31693,7 +31762,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true }, "multicast-dns": { "version": "7.2.5", @@ -31767,7 +31837,8 @@ "node-releases": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "devOptional": true }, "normalize-path": { "version": "3.0.0", @@ -31939,9 +32010,9 @@ } }, "open": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.1.tgz", - "integrity": "sha512-/4b7qZNhv6Uhd7jjnREh1NjnPxlTq+XNWPG88Ydkj5AILcA5m3ajvcg57pB24EQjKv0dK62XnDqk9c/hkIG5Kg==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "requires": { "define-lazy-prop": "^2.0.0", @@ -32128,7 +32199,8 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "devOptional": true }, "picomatch": { "version": "2.3.1", @@ -32323,12 +32395,12 @@ } }, "postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", "dev": true, "requires": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" @@ -32584,9 +32656,9 @@ } }, "postcss-merge-rules": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", - "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", "dev": true, "requires": { "browserslist": "^4.21.4", @@ -32891,9 +32963,9 @@ } }, "postcss-reduce-initial": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", - "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", "dev": true, "requires": { "browserslist": "^4.21.4", @@ -33523,9 +33595,9 @@ } }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", + "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -33604,9 +33676,9 @@ "dev": true }, "regexpu-core": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.0.tgz", - "integrity": "sha512-ZdhUQlng0RoscyW7jADnUZ25F5eVtHdMyXSb2PiwafvteRAOJUjFoUPEYZSIfP99fBIs3maLIRfpEddT78wAAQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.1.tgz", + "integrity": "sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==", "dev": true, "requires": { "@babel/regjsgen": "^0.8.0", @@ -33985,7 +34057,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "devOptional": true }, "send": { "version": "0.18.0", @@ -34609,9 +34682,9 @@ "dev": true }, "tailwindcss": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.6.tgz", - "integrity": "sha512-BfgQWZrtqowOQMC2bwaSNe7xcIjdDEgixWGYOd6AL0CbKHJlvhfdbINeAW76l1sO+1ov/MJ93ODJ9yluRituIw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz", + "integrity": "sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==", "dev": true, "requires": { "arg": "^5.0.2", @@ -34690,9 +34763,9 @@ } }, "terser": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", - "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.5.tgz", + "integrity": "sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", @@ -35043,6 +35116,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "devOptional": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -35356,9 +35430,9 @@ } }, "ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.1.tgz", + "integrity": "sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==", "dev": true, "requires": {} } @@ -35881,7 +35955,8 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "devOptional": true }, "yaml": { "version": "1.10.2", @@ -35889,9 +35964,9 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", diff --git a/package.json b/package.json index e1ed165..8ffd372 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.53", + "@kingsrook/qqq-frontend-core": "1.0.54", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", diff --git a/src/qqq/components/widgets/Widget.tsx b/src/qqq/components/widgets/Widget.tsx index 747653a..cd24a89 100644 --- a/src/qqq/components/widgets/Widget.tsx +++ b/src/qqq/components/widgets/Widget.tsx @@ -285,7 +285,7 @@ function Widget(props: React.PropsWithChildren): JSX.Element const hasPermission = props.widgetData?.hasPermission === undefined || props.widgetData?.hasPermission === true; const widgetContent = - + { From b996b1a67f09c6ce85ca9db086eda47ca3d3d581 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Thu, 23 Feb 2023 17:02:33 -0600 Subject: [PATCH 09/23] SPRINT-21: attempt to fix weird widget behavior when widget data is not cleared out/async updates --- src/qqq/components/widgets/DashboardWidgets.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index 63565b1..e92e3cc 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -85,6 +85,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit useEffect(() => { + setWidgetData([]); for (let i = 0; i < widgetMetaDataList.length; i++) { const widgetMetaData = widgetMetaDataList[i]; @@ -96,17 +97,21 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit (async () => { widgetData[i] = await qController.widget(widgetMetaData.name, urlParams); + setWidgetData(widgetData); setWidgetCounter(widgetCounter + 1); forceUpdate(); })(); } - setWidgetData(widgetData); }, [widgetMetaDataList]); const reloadWidget = async (index: number, data: string) => { - widgetData[index] = await qController.widget(widgetMetaDataList[index].name, getQueryParams(null, data)); - forceUpdate(); + (async() => + { + widgetData[index] = await qController.widget(widgetMetaDataList[index].name, getQueryParams(null, data)); + setWidgetData(widgetData); + forceUpdate(); + })(); }; function getQueryParams(widgetMetaData: QWidgetMetaData, extraParams: string): string @@ -174,7 +179,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit widgetIndex={i} widgetMetaData={widgetMetaData} data={widgetData[i]} - reloadWidgetCallback={widgetData[i].omitReloadWidgetCallback ? () => + reloadWidgetCallback={widgetData[i]?.omitReloadWidgetCallback ? () => {} : reloadWidget} storeDropdownSelections={widgetMetaData.storeDropdownSelections} /> From 858392c286e85d298190cf985c59f83cce735ea6 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 15:20:50 -0600 Subject: [PATCH 10/23] Test improvements --- .../lib/QBaseSeleniumTest.java | 4 +- .../materialdashboard/lib/QSeleniumLib.java | 92 ++++----- .../lib/javalin/QSeleniumJavalin.java | 16 +- .../tests/AppPageNavTest.java | 2 - .../materialdashboard/tests/AuditTest.java | 5 +- .../tests/QueryScreenTest.java | 20 +- .../tests/SavedFiltersTest.java | 178 ++++++++++++++++++ .../resources/fixtures/metaData/index.json | 21 ++- .../processes/querySavedFilter/init-id=2.json | 21 +++ .../processes/querySavedFilter/init.json | 33 ++++ 10 files changed, 310 insertions(+), 82 deletions(-) create mode 100755 src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java create mode 100644 src/test/resources/fixtures/processes/querySavedFilter/init-id=2.json create mode 100644 src/test/resources/fixtures/processes/querySavedFilter/init.json diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java index e1965b8..d21a7c5 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java @@ -19,7 +19,7 @@ public class QBaseSeleniumTest { private static ChromeOptions chromeOptions; - private WebDriver driver; + protected WebDriver driver; protected QSeleniumJavalin qSeleniumJavalin; protected QSeleniumLib qSeleniumLib; @@ -83,6 +83,8 @@ public class QBaseSeleniumTest @AfterEach void afterEach() { + qSeleniumLib.takeScreenshotToFile(); + if(driver != null) { driver.quit(); diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java index 8b86fd4..5fd3330 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java @@ -208,6 +208,38 @@ public class QSeleniumLib + /******************************************************************************* + ** + *******************************************************************************/ + public void waitForSelectorContainingToNotExist(String cssSelector, String textContains) + { + LOG.debug("Waiting for non-existence of element matching selector [" + cssSelector + "] containing text [" + textContains + "]"); + long start = System.currentTimeMillis(); + + do + { + List elements = driver.findElements(By.cssSelector(cssSelector)); + if(elements.size() == 0) + { + LOG.debug("Found non-existence of element(s) matching selector [" + cssSelector + "]"); + return; + } + + if(elements.stream().noneMatch(e -> e.getText().toLowerCase().contains(textContains))) + { + LOG.debug("Found non-existence of element(s) matching selector [" + cssSelector + "] containing text [" + textContains + "]"); + return; + } + + sleepABit(); + } + while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); + + fail("Failed for non-existence of element matching selector [" + cssSelector + "] after [" + WAIT_SECONDS + "] seconds."); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -258,31 +290,6 @@ public class QSeleniumLib - /******************************************************************************* - ** - *******************************************************************************/ - public T waitLoop(String message, Code c) - { - LOG.debug("Waiting for: " + message); - long start = System.currentTimeMillis(); - do - { - T t = c.run(); - if(t != null) - { - LOG.debug("Found: " + message); - return (t); - } - - sleepABit(); - } - while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); - LOG.warn("Failed to match while waiting for: " + message); - return (null); - } - - - /******************************************************************************* ** *******************************************************************************/ @@ -313,7 +320,6 @@ public class QSeleniumLib } sleepABit(); - } while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); @@ -323,34 +329,6 @@ public class QSeleniumLib - /******************************************************************************* - ** - *******************************************************************************/ - public WebElement waitForSelectorContainingV2(String cssSelector, String textContains) - { - return (waitLoop("element matching selector [" + cssSelector + "] containing text [" + textContains + "].", () -> - { - List elements = driver.findElements(By.cssSelector(cssSelector)); - for(WebElement element : elements) - { - try - { - if(element.getText() != null && element.getText().toLowerCase().contains(textContains.toLowerCase())) - { - return (element); - } - } - catch(StaleElementReferenceException sere) - { - LOG.debug("Caught a StaleElementReferenceException - will retry."); - } - } - return (null); - })); - } - - - /******************************************************************************* ** Take a screenshot, putting it in the SCREENSHOTS_PATH, with a subdirectory ** for the test class simple name, filename = methodName.png. @@ -396,20 +374,22 @@ public class QSeleniumLib /******************************************************************************* ** *******************************************************************************/ - public void assertElementHasFocus(WebElement element) + public void waitForElementToHaveFocus(WebElement element) { + LOG.debug("Waiting for element [" + element + "] to have focus."); long start = System.currentTimeMillis(); do { if(Objects.equals(driver.switchTo().activeElement(), element)) { + LOG.debug("Element [" + element + "] has focus."); return; } sleepABit(); } while(start + (1000 * WAIT_SECONDS) > System.currentTimeMillis()); - fail("Failed to see that element [" + element + "] has focus."); + fail("Failed to see that element [" + element + "] has focus after [" + WAIT_SECONDS + "] seconds."); } diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java index 8e81b00..65c62ec 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/javalin/QSeleniumJavalin.java @@ -25,8 +25,8 @@ public class QSeleniumJavalin private long WAIT_SECONDS = 10; - private List> routesToFiles; - private List> routesToStrings; + private List> routesToFiles = new ArrayList<>(); + private List> routesToStrings = new ArrayList<>(); private Javalin javalin; @@ -52,6 +52,17 @@ public class QSeleniumJavalin + /******************************************************************************* + ** + *******************************************************************************/ + public void clearRoutes() + { + this.routesToFiles.clear(); + this.routesToStrings.clear(); + } + + + /******************************************************************************* ** Fluent setter for routeToFile ** @@ -271,4 +282,5 @@ public class QSeleniumJavalin fail("Failed to capture a request for path [" + path + "] with body containing [" + bodyContaining + "] after [" + WAIT_SECONDS + "] seconds."); return (null); } + } diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java index 2660a02..1a3c6c3 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AppPageNavTest.java @@ -60,7 +60,6 @@ public class AppPageNavTest extends QBaseSeleniumTest qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/", "Greetings App"); qSeleniumLib.waitForSelectorContaining(QQQMaterialDashboardSelectors.SIDEBAR_ITEM, "People App").click(); qSeleniumLib.waitForSelectorContaining(QQQMaterialDashboardSelectors.SIDEBAR_ITEM, "Greetings App").click(); - qSeleniumLib.takeScreenshotToFile(); } @@ -74,7 +73,6 @@ public class AppPageNavTest extends QBaseSeleniumTest qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp", "Greetings App"); qSeleniumLib.tryMultiple(3, () -> qSeleniumLib.waitForSelectorContaining("a", "Person").click()); qSeleniumLib.waitForSelectorContaining(QQQMaterialDashboardSelectors.BREADCRUMB_HEADER, "Person"); - qSeleniumLib.takeScreenshotToFile(); } } diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java index 45b2616..907d34b 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AuditTest.java @@ -76,8 +76,6 @@ public class AuditTest extends QBaseSeleniumTest /////////////////////////////////////// qSeleniumLib.waitForSelectorContaining("BUTTON", "Close").click(); qSeleniumLib.waitForSelectorToNotExist(".audit"); - - qSeleniumLib.takeScreenshotToFile(); } @@ -112,6 +110,7 @@ public class AuditTest extends QBaseSeleniumTest } + /******************************************************************************* ** *******************************************************************************/ @@ -153,8 +152,6 @@ public class AuditTest extends QBaseSeleniumTest captured = captured.stream().filter(cc -> cc.getPath().equals(auditQueryPath)).toList(); assertEquals(1, captured.size()); assertThat(captured.get(0).getBody()).contains("\"isAscending\":false"); - - qSeleniumLib.takeScreenshotToFile(); } } diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java index bd182c1..16fd153 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java @@ -24,6 +24,7 @@ package com.kingsrook.qqq.materialdashboard.tests; import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; import com.kingsrook.qqq.materialdashboard.lib.QQQMaterialDashboardSelectors; +import com.kingsrook.qqq.materialdashboard.lib.QSeleniumLib; import com.kingsrook.qqq.materialdashboard.lib.javalin.CapturedContext; import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; import org.junit.jupiter.api.Test; @@ -56,7 +57,6 @@ public class QueryScreenTest extends QBaseSeleniumTest /******************************************************************************* ** *******************************************************************************/ - // @RepeatedTest(10) @Test void testBasicQueryAndClearFilters() { @@ -68,7 +68,7 @@ public class QueryScreenTest extends QBaseSeleniumTest // open the filter window, enter a value, wait for query to re-run // ///////////////////////////////////////////////////////////////////// WebElement filterInput = qSeleniumLib.waitForSelector(QQQMaterialDashboardSelectors.QUERY_FILTER_INPUT); - qSeleniumLib.assertElementHasFocus(filterInput); + qSeleniumLib.waitForElementToHaveFocus(filterInput); qSeleniumJavalin.beginCapture(); filterInput.sendKeys("1"); @@ -105,9 +105,6 @@ public class QueryScreenTest extends QBaseSeleniumTest assertThat(capturedCount).extracting("body").asString().doesNotContain(idEquals1FilterSubstring); assertThat(capturedQuery).extracting("body").asString().doesNotContain(idEquals1FilterSubstring); qSeleniumJavalin.endCapture(); - - qSeleniumLib.takeScreenshotToFile(); - // qSeleniumLib.waitForever(); // todo not commit - in fact, build in linting that makes sure we never do? } @@ -115,7 +112,6 @@ public class QueryScreenTest extends QBaseSeleniumTest /******************************************************************************* ** *******************************************************************************/ - // @RepeatedTest(10) @Test void testMultiCriteriaQueryWithOr() { @@ -123,9 +119,9 @@ public class QueryScreenTest extends QBaseSeleniumTest qSeleniumLib.waitForSelector(QQQMaterialDashboardSelectors.QUERY_GRID_CELL); qSeleniumLib.waitForSelectorContaining("BUTTON", "Filters").click(); - addQueryFilterInput(0, "First Name", "contains", "Dar", "Or"); + addQueryFilterInput(qSeleniumLib, 0, "First Name", "contains", "Dar", "Or"); qSeleniumJavalin.beginCapture(); - addQueryFilterInput(1, "First Name", "contains", "Jam", "Or"); + addQueryFilterInput(qSeleniumLib, 1, "First Name", "contains", "Jam", "Or"); String expectedFilterContents0 = """ {"fieldName":"firstName","operator":"CONTAINS","values":["Dar"]}"""; @@ -138,9 +134,6 @@ public class QueryScreenTest extends QBaseSeleniumTest qSeleniumJavalin.waitForCapturedPathWithBodyContaining("/data/person/query", expectedFilterContents1); qSeleniumJavalin.waitForCapturedPathWithBodyContaining("/data/person/query", expectedFilterContents2); qSeleniumJavalin.endCapture(); - - qSeleniumLib.takeScreenshotToFile(); - // qSeleniumLib.waitForever(); // todo not commit - in fact, build in linting that makes sure we never do? } @@ -148,7 +141,7 @@ public class QueryScreenTest extends QBaseSeleniumTest /******************************************************************************* ** *******************************************************************************/ - private void addQueryFilterInput(int index, String fieldlabel, String operator, String value, String booleanOperator) + static void addQueryFilterInput(QSeleniumLib qSeleniumLib, int index, String fieldLabel, String operator, String value, String booleanOperator) { if(index > 0) { @@ -164,7 +157,7 @@ public class QueryScreenTest extends QBaseSeleniumTest } Select fieldSelect = new Select(subFormForField.findElement(By.cssSelector(".MuiDataGrid-filterFormColumnInput SELECT"))); - fieldSelect.selectByVisibleText(fieldlabel); + fieldSelect.selectByVisibleText(fieldLabel); Select operatorSelect = new Select(subFormForField.findElement(By.cssSelector(".MuiDataGrid-filterFormOperatorInput SELECT"))); operatorSelect.selectByVisibleText(operator); @@ -172,6 +165,7 @@ public class QueryScreenTest extends QBaseSeleniumTest WebElement valueInput = subFormForField.findElement(By.cssSelector(".MuiDataGrid-filterFormValueInput INPUT")); valueInput.click(); valueInput.sendKeys(value); + qSeleniumLib.waitForSeconds(1); } } diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java new file mode 100755 index 0000000..72ce166 --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -0,0 +1,178 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.materialdashboard.tests; + + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; +import com.kingsrook.qqq.materialdashboard.lib.javalin.CapturedContext; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import static com.kingsrook.qqq.materialdashboard.tests.QueryScreenTest.addQueryFilterInput; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Test for Saved Filters functionality on the Query screen. + *******************************************************************************/ +public class SavedFiltersTest extends QBaseSeleniumTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + protected void addJavalinRoutes(QSeleniumJavalin qSeleniumJavalin) + { + addStandardRoutesForThisTest(qSeleniumJavalin); + qSeleniumJavalin.withRouteToFile("/processes/querySavedFilter/init", "processes/querySavedFilter/init.json"); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private void addStandardRoutesForThisTest(QSeleniumJavalin qSeleniumJavalin) + { + super.addJavalinRoutes(qSeleniumJavalin); + qSeleniumJavalin.withRouteToFile("/data/person/count", "data/person/count.json"); + qSeleniumJavalin.withRouteToFile("/data/person/query", "data/person/index.json"); + qSeleniumJavalin.withRouteToFile("/data/person/*", "data/person/1701.json"); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testNavigatingBackAndForth() + { + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person", "Person"); + qSeleniumLib.waitForSelectorContaining("BUTTON", "Saved Filters").click(); + qSeleniumLib.waitForSelectorContaining("LI", "Some People"); + + //////////////////////////////////////// + // need to only return id=2 next time // + //////////////////////////////////////// + qSeleniumJavalin.stop(); + qSeleniumJavalin.clearRoutes(); + addStandardRoutesForThisTest(qSeleniumJavalin); + qSeleniumJavalin.withRouteToFile("/processes/querySavedFilter/init", "processes/querySavedFilter/init-id=2.json"); + qSeleniumJavalin.restart(); + + /////////////////////////////////////////////////////// + // go to a specific filter - assert that it's loaded // + /////////////////////////////////////////////////////// + qSeleniumLib.waitForSelectorContaining("LI", "Some People").click(); + qSeleniumLib.waitForCondition("Current URL should have filter id", () -> driver.getCurrentUrl().endsWith("/person/savedFilter/2")); + qSeleniumLib.waitForSelectorContaining("DIV", "Current Filter: Some People"); + + ////////////////////////////// + // click into a view screen // + ////////////////////////////// + qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); + + ///////////////////////////////////////////////////// + // take breadcrumb back to table query // + // assert the previously selected filter is loaded // + ///////////////////////////////////////////////////// + qSeleniumLib.waitForSelectorContaining("A", "Person").click(); + qSeleniumLib.waitForCondition("Current URL should have filter id", () -> driver.getCurrentUrl().endsWith("/person/savedFilter/2")); + qSeleniumLib.waitForSelectorContaining("DIV", "Current Filter: Some People"); + qSeleniumLib.waitForSelectorContaining(".MuiBadge-badge", "1"); + + ////////////////////// + // modify the query // + ////////////////////// + qSeleniumLib.waitForSelectorContaining(".MuiDataGrid-toolbarContainer BUTTON", "Filters").click(); + addQueryFilterInput(qSeleniumLib, 1, "First Name", "contains", "Jam", "Or"); + qSeleniumLib.waitForSelectorContaining("H5", "Person").click(); + qSeleniumLib.waitForSelectorContaining("DIV", "Current Filter: Some People") + .findElement(By.cssSelector("CIRCLE")); + qSeleniumLib.waitForSelectorContaining(".MuiBadge-badge", "2"); + + ////////////////////////////// + // click into a view screen // + ////////////////////////////// + qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); + + /////////////////////////////////////////////////////////////////////////////// + // take breadcrumb back to table query // + // assert the previously selected filter, with modification, is still loaded // + /////////////////////////////////////////////////////////////////////////////// + qSeleniumJavalin.beginCapture(); + qSeleniumLib.waitForSelectorContaining("A", "Person").click(); + qSeleniumLib.waitForCondition("Current URL should have filter id", () -> driver.getCurrentUrl().endsWith("/person/savedFilter/2")); + qSeleniumLib.waitForSelectorContaining("DIV", "Current Filter: Some People") + .findElement(By.cssSelector("CIRCLE")); + qSeleniumLib.waitForSelectorContaining(".MuiBadge-badge", "2"); + CapturedContext capturedContext = qSeleniumJavalin.waitForCapturedPath("/data/person/query"); + assertTrue(capturedContext.getBody().contains("Jam")); + qSeleniumJavalin.endCapture(); + + //////////////////////////////////////////////////// + // navigate to the table with a filter in the URL // + //////////////////////////////////////////////////// + String filter = """ + { + "criteria": + [ + { + "fieldName": "id", + "operator": "LESS_THAN", + "values": [10] + } + ] + } + """.replace('\n', ' ').replaceAll(" ", ""); + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person?filter=" + URLEncoder.encode(filter, StandardCharsets.UTF_8), "Person"); + qSeleniumLib.waitForSelectorContaining(".MuiBadge-badge", "1"); + qSeleniumLib.waitForSelectorContainingToNotExist("DIV", "Current Filter"); + + ////////////////////////////// + // click into a view screen // + ////////////////////////////// + qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); + + ///////////////////////////////////////////////////////////////////////////////// + // take breadcrumb back to table query // + // assert the filter previously given on the URL is what is loaded & requested // + ///////////////////////////////////////////////////////////////////////////////// + qSeleniumJavalin.beginCapture(); + qSeleniumLib.waitForSelectorContaining("A", "Person").click(); + qSeleniumLib.waitForCondition("Current URL should not have filter id", () -> !driver.getCurrentUrl().endsWith("/person/savedFilter/2")); + qSeleniumLib.waitForSelectorContaining(".MuiBadge-badge", "1"); + capturedContext = qSeleniumJavalin.waitForCapturedPath("/data/person/query"); + assertTrue(capturedContext.getBody().matches("(?s).*id.*LESS_THAN.*10.*")); + qSeleniumJavalin.endCapture(); + + qSeleniumLib.waitForever(); + } + +} diff --git a/src/test/resources/fixtures/metaData/index.json b/src/test/resources/fixtures/metaData/index.json index 1968683..916a6a3 100644 --- a/src/test/resources/fixtures/metaData/index.json +++ b/src/test/resources/fixtures/metaData/index.json @@ -102,10 +102,23 @@ "label": "Sleep Interactive", "isHidden": false }, - "simpleThrow": { - "name": "simpleThrow", - "label": "Simple Throw", - "isHidden": false + "querySavedFilter": { + "name": "querySavedFilter", + "label": "Query Saved Filter", + "isHidden": false, + "hasPermission": true + }, + "storeSavedFilter": { + "name": "storeSavedFilter", + "label": "Store Saved Filter", + "isHidden": false, + "hasPermission": true + }, + "deleteSavedFilter": { + "name": "deleteSavedFilter", + "label": "Delete Saved Filter", + "isHidden": false, + "hasPermission": true }, "carrier.bulkInsert": { "name": "carrier.bulkInsert", diff --git a/src/test/resources/fixtures/processes/querySavedFilter/init-id=2.json b/src/test/resources/fixtures/processes/querySavedFilter/init-id=2.json new file mode 100644 index 0000000..fe19313 --- /dev/null +++ b/src/test/resources/fixtures/processes/querySavedFilter/init-id=2.json @@ -0,0 +1,21 @@ +{ + "values": { + "_qStepTimeoutMillis": "60000", + "savedFilterList": [ + { + "tableName": "savedFilter", + "values": { + "label": "Some People", + "id": 2, + "createDate": "2023-02-20T18:40:58Z", + "modifyDate": "2023-02-20T18:40:58Z", + "tableName": "person", + "filterJson": "{\"criteria\":[{\"fieldName\":\"firstName\",\"operator\":\"STARTS_WITH\",\"values\":[\"D\"]}],\"orderBys\":[{\"fieldName\":\"id\",\"isAscending\":false}],\"booleanOperator\":\"AND\"}", + "userId": "darin.kelkhoff@kingsrook.com" + } + } + ], + "tableName": "person" + }, + "processUUID": "4eaaea82-2d09-4254-90f8-e5b6948ef0b3" +} \ No newline at end of file diff --git a/src/test/resources/fixtures/processes/querySavedFilter/init.json b/src/test/resources/fixtures/processes/querySavedFilter/init.json new file mode 100644 index 0000000..23b8f4a --- /dev/null +++ b/src/test/resources/fixtures/processes/querySavedFilter/init.json @@ -0,0 +1,33 @@ +{ + "values": { + "_qStepTimeoutMillis": "60000", + "savedFilterList": [ + { + "tableName": "savedFilter", + "values": { + "label": "All People", + "id": 1, + "createDate": "2023-02-20T18:39:11Z", + "modifyDate": "2023-02-20T18:39:11Z", + "tableName": "person", + "filterJson": "{\"orderBys\":[{\"fieldName\":\"id\",\"isAscending\":false}],\"booleanOperator\":\"AND\"}", + "userId": "darin.kelkhoff@kingsrook.com" + } + }, + { + "tableName": "savedFilter", + "values": { + "label": "Some People", + "id": 2, + "createDate": "2023-02-20T18:40:58Z", + "modifyDate": "2023-02-20T18:40:58Z", + "tableName": "person", + "filterJson": "{\"criteria\":[{\"fieldName\":\"firstName\",\"operator\":\"STARTS_WITH\",\"values\":[\"D\"]}],\"orderBys\":[{\"fieldName\":\"id\",\"isAscending\":false}],\"booleanOperator\":\"AND\"}", + "userId": "darin.kelkhoff@kingsrook.com" + } + } + ], + "tableName": "person" + }, + "processUUID": "4eaaea82-2d09-4254-90f8-e5b6948ef0b3" +} \ No newline at end of file From 5f20367b3cf55a45ace0e0ca22b06342dd38fa20 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 15:22:04 -0600 Subject: [PATCH 11/23] Add Copy Values to grid column menu --- src/qqq/pages/records/query/RecordQuery.tsx | 93 +++++++++++++++++++-- src/qqq/utils/qqq/ValueUtils.tsx | 2 +- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/qqq/pages/records/query/RecordQuery.tsx b/src/qqq/pages/records/query/RecordQuery.tsx index bb6e2f2..782fe5c 100644 --- a/src/qqq/pages/records/query/RecordQuery.tsx +++ b/src/qqq/pages/records/query/RecordQuery.tsx @@ -27,7 +27,7 @@ import {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJo import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError"; import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord"; import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; -import {Alert, TablePagination} from "@mui/material"; +import {Alert, Collapse, TablePagination} from "@mui/material"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import Card from "@mui/material/Card"; @@ -44,9 +44,9 @@ import Menu from "@mui/material/Menu"; import MenuItem from "@mui/material/MenuItem"; import Modal from "@mui/material/Modal"; import Tooltip from "@mui/material/Tooltip"; -import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnOrderChangeParams, GridColumnVisibilityModel, GridDensity, GridEventListener, GridExportMenuItemProps, GridFilterModel, GridPinnedColumns, gridPreferencePanelStateSelector, GridRowId, GridRowParams, GridRowsProp, GridSelectionModel, GridSortItem, GridSortModel, GridState, GridToolbarColumnsButton, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarExportContainer, GridToolbarFilterButton, MuiEvent, useGridApiContext, useGridApiEventHandler, useGridSelector} from "@mui/x-data-grid-pro"; +import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnMenu, GridColumnMenuContainer, GridColumnMenuProps, GridColumnOrderChangeParams, GridColumnPinningMenuItems, GridColumnsMenuItem, GridColumnVisibilityModel, GridDensity, GridEventListener, GridExportMenuItemProps, GridFilterMenuItem, GridFilterModel, GridPinnedColumns, gridPreferencePanelStateSelector, GridRowId, GridRowParams, GridRowsProp, GridSelectionModel, GridSortItem, GridSortModel, GridState, GridToolbarColumnsButton, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarExportContainer, GridToolbarFilterButton, HideGridColMenuItem, MuiEvent, SortGridMenuItems, useGridApiContext, useGridApiEventHandler, useGridSelector} from "@mui/x-data-grid-pro"; import FormData from "form-data"; -import React, {useContext, useEffect, useReducer, useRef, useState} from "react"; +import React, {forwardRef, useContext, useEffect, useReducer, useRef, useState} from "react"; import {useLocation, useNavigate, useSearchParams} from "react-router-dom"; import QContext from "QContext"; import {QActionsMenuButton, QCreateNewButton} from "qqq/components/buttons/DefaultButtons"; @@ -57,6 +57,7 @@ import DataGridUtils from "qqq/utils/DataGridUtils"; import Client from "qqq/utils/qqq/Client"; import FilterUtils from "qqq/utils/qqq/FilterUtils"; import ProcessUtils from "qqq/utils/qqq/ProcessUtils"; +import ValueUtils from "qqq/utils/qqq/ValueUtils"; const CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedFilterId"; const COLUMN_VISIBILITY_LOCAL_STORAGE_KEY_ROOT = "qqq.columnVisibility"; @@ -83,8 +84,9 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element { const tableName = table.name; const [ searchParams ] = useSearchParams(); - + const [showSuccessfullyDeletedAlert, setShowSuccessfullyDeletedAlert] = useState(searchParams.has("deleteSuccess")); + const [successAlert, setSuccessAlert] = useState(null as string) const location = useLocation(); const navigate = useNavigate(); @@ -175,6 +177,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element const [ countResults, setCountResults ] = useState({} as any); const [ receivedCountTimestamp, setReceivedCountTimestamp ] = useState(new Date()); const [ queryResults, setQueryResults ] = useState({} as any); + const [ latestQueryResults, setLatestQueryResults ] = useState(null as QRecord[]); const [ receivedQueryTimestamp, setReceivedQueryTimestamp ] = useState(new Date()); const [ queryErrors, setQueryErrors ] = useState({} as any); const [ receivedQueryErrorTimestamp, setReceivedQueryErrorTimestamp ] = useState(new Date()); @@ -425,6 +428,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element console.log(`Outputting results for query ${latestQueryId}...`); const results = queryResults[latestQueryId]; delete queryResults[latestQueryId]; + setLatestQueryResults(results); const {rows, columnsToRender} = DataGridUtils.makeRows(results, tableMetaData); @@ -874,7 +878,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element if(selectedSavedFilterId != null) { const qRecord = await fetchSavedFilter(selectedSavedFilterId); - const models = await FilterUtils.determineFilterAndSortModels(qController, tableMetaData, qRecord.values.get("filterJson"), null, null,null); + const models = await FilterUtils.determineFilterAndSortModels(qController, tableMetaData, qRecord.values.get("filterJson"), null, null, null); handleFilterChange(models.filter); handleSortChange(models.sort); localStorage.setItem(currentSavedFilterLocalStorageKey, selectedSavedFilterId.toString()); @@ -917,6 +921,71 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element return(qRecord); } + const copyColumnValues = async (column: GridColDef) => + { + let data = ""; + if(latestQueryResults && latestQueryResults.length) + { + let qFieldMetaData = tableMetaData.fields.get(column.field); + for(let i = 0; i < latestQueryResults.length; i++) + { + let record = latestQueryResults[i] as QRecord; + const value = ValueUtils.getUnadornedValueForDisplay(qFieldMetaData, record.values.get(qFieldMetaData.name), record.displayValues.get(qFieldMetaData.name)); + data += value + "\n"; + } + + await navigator.clipboard.writeText(data) + setSuccessAlert("Copied " + latestQueryResults.length + " " + qFieldMetaData.label + " values."); + setTimeout(() => setSuccessAlert(null), 3000); + } + } + + const CustomColumnMenu = forwardRef( + function GridColumnMenu(props: GridColumnMenuProps, ref) + { + const {hideMenu, currentColumn} = props; + + /* + const [copyMoreMenu, setCopyMoreMenu] = useState(null) + const openCopyMoreMenu = (event: any) => + { + setCopyMoreMenu(event.currentTarget); + event.stopPropagation(); + } + const closeCopyMoreMenu = () => setCopyMoreMenu(null); + */ + + return ( + + + + + + + + + + + + { + hideMenu(e); + copyColumnValues(currentColumn) + }}> + Copy values + + {/* + + + Oh + My + + */} + + + + ); + }); + function CustomToolbar() { const handleMouseDown: GridEventListener<"cellMouseDown"> = ( @@ -1164,6 +1233,18 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element ) : null } + { + (successAlert) ? ( + + + { + setSuccessAlert(null); + }}> + {successAlert} + + + ) : null + } @@ -1182,7 +1263,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element Date: Fri, 24 Feb 2023 15:41:53 -0600 Subject: [PATCH 12/23] fixed query test (filter button selector conflict); removed sleepForever from filter test --- .../qqq/materialdashboard/tests/QueryScreenTest.java | 4 ++-- .../qqq/materialdashboard/tests/SavedFiltersTest.java | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java index 16fd153..f1157e3 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/QueryScreenTest.java @@ -62,7 +62,7 @@ public class QueryScreenTest extends QBaseSeleniumTest { qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person", "Person"); qSeleniumLib.waitForSelector(QQQMaterialDashboardSelectors.QUERY_GRID_CELL); - qSeleniumLib.waitForSelectorContaining("BUTTON", "Filters").click(); + qSeleniumLib.waitForSelectorContaining(".MuiDataGrid-toolbarContainer BUTTON", "Filters").click(); ///////////////////////////////////////////////////////////////////// // open the filter window, enter a value, wait for query to re-run // @@ -117,7 +117,7 @@ public class QueryScreenTest extends QBaseSeleniumTest { qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person", "Person"); qSeleniumLib.waitForSelector(QQQMaterialDashboardSelectors.QUERY_GRID_CELL); - qSeleniumLib.waitForSelectorContaining("BUTTON", "Filters").click(); + qSeleniumLib.waitForSelectorContaining(".MuiDataGrid-toolbarContainer BUTTON", "Filters").click(); addQueryFilterInput(qSeleniumLib, 0, "First Name", "contains", "Dar", "Or"); qSeleniumJavalin.beginCapture(); diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index 72ce166..e654bc4 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -172,7 +172,4 @@ public class SavedFiltersTest extends QBaseSeleniumTest assertTrue(capturedContext.getBody().matches("(?s).*id.*LESS_THAN.*10.*")); qSeleniumJavalin.endCapture(); - qSeleniumLib.waitForever(); - } - } From 1b3b26bdbb1107a3d84c4f5a87e37da984c366a9 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 15:43:20 -0600 Subject: [PATCH 13/23] Missing } --- .../kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index e654bc4..2e725b8 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -171,5 +171,6 @@ public class SavedFiltersTest extends QBaseSeleniumTest capturedContext = qSeleniumJavalin.waitForCapturedPath("/data/person/query"); assertTrue(capturedContext.getBody().matches("(?s).*id.*LESS_THAN.*10.*")); qSeleniumJavalin.endCapture(); + } } From be6d4bb657612bfccd826e405c2a6b42a3ca98ef Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 16:03:33 -0600 Subject: [PATCH 14/23] Improved screenshots --- .../qqq/materialdashboard/lib/QBaseSeleniumTest.java | 7 +++++-- .../kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java | 3 ++- .../qqq/materialdashboard/tests/SavedFiltersTest.java | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java index d21a7c5..0b0fba3 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java @@ -6,6 +6,7 @@ import io.github.bonigarcia.wdm.WebDriverManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; import org.openqa.selenium.Dimension; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; @@ -23,6 +24,8 @@ public class QBaseSeleniumTest protected QSeleniumJavalin qSeleniumJavalin; protected QSeleniumLib qSeleniumLib; + private int screenshotIndex = 1; + /******************************************************************************* @@ -81,9 +84,9 @@ public class QBaseSeleniumTest ** *******************************************************************************/ @AfterEach - void afterEach() + void afterEach(TestInfo testInfo) { - qSeleniumLib.takeScreenshotToFile(); + qSeleniumLib.takeScreenshotToFile(getClass().getSimpleName() + "/" + testInfo.getDisplayName()); if(driver != null) { diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java index 5fd3330..e7f1614 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java @@ -345,6 +345,7 @@ public class QSeleniumLib /******************************************************************************* ** Take a screenshot, and give it a path/name of your choosing (under SCREENSHOTS_PATH) + ** - note - .png will be appended. *******************************************************************************/ public void takeScreenshotToFile(String filePathSuffix) { @@ -353,7 +354,7 @@ public class QSeleniumLib try { File outputFile = driver.findElement(By.cssSelector("html")).getScreenshotAs(OutputType.FILE); - File destFile = new File(SCREENSHOTS_PATH + filePathSuffix); + File destFile = new File(SCREENSHOTS_PATH + filePathSuffix + ".png"); destFile.mkdirs(); if(destFile.exists()) { diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index 2e725b8..cc3df1c 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -93,7 +93,9 @@ public class SavedFiltersTest extends QBaseSeleniumTest ////////////////////////////// // click into a view screen // ////////////////////////////// + qSeleniumLib.takeScreenshotToFile("before-johnny-click"); qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.takeScreenshotToFile("after-johnny-click"); qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); ///////////////////////////////////////////////////// From 82008f081cf587c23f3036e1fc5188e4030e6a22 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 16:15:20 -0600 Subject: [PATCH 15/23] try to capture screenshots in circleci --- .circleci/config.yml | 2 ++ .../com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bcb3c64..ce065e1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -64,6 +64,8 @@ commands: paths: - ~/.m2 key: v1-dependencies-{{ checksum "pom.xml" }} + - store_artifacts: + path: /tmp/QSeleniumScreenshots mvn_deploy: steps: diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java index e7f1614..cbf2eb9 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java @@ -32,7 +32,7 @@ public class QSeleniumLib private long WAIT_SECONDS = 10; private String BASE_URL = "https://localhost:3001"; private boolean SCREENSHOTS_ENABLED = true; - private String SCREENSHOTS_PATH = "/tmp/"; + private String SCREENSHOTS_PATH = "/tmp/QSeleniumScreenshots"; From 369b34c1ccd402dde21b8c3df3fa1c5aa5dab3e5 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 16:20:34 -0600 Subject: [PATCH 16/23] fixing screenshots for ci --- .../kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java | 2 -- .../com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java index 0b0fba3..21c92a5 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java @@ -24,8 +24,6 @@ public class QBaseSeleniumTest protected QSeleniumJavalin qSeleniumJavalin; protected QSeleniumLib qSeleniumLib; - private int screenshotIndex = 1; - /******************************************************************************* diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java index cbf2eb9..82fdb92 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QSeleniumLib.java @@ -32,7 +32,7 @@ public class QSeleniumLib private long WAIT_SECONDS = 10; private String BASE_URL = "https://localhost:3001"; private boolean SCREENSHOTS_ENABLED = true; - private String SCREENSHOTS_PATH = "/tmp/QSeleniumScreenshots"; + private String SCREENSHOTS_PATH = "/tmp/QSeleniumScreenshots/"; From c35605d14defec130ea5c6e3a7f961e14d609692 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 16:37:18 -0600 Subject: [PATCH 17/23] add a wait for menu to go away before tryign to click? --- .../kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index cc3df1c..eb01b8f 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -94,6 +94,7 @@ public class SavedFiltersTest extends QBaseSeleniumTest // click into a view screen // ////////////////////////////// qSeleniumLib.takeScreenshotToFile("before-johnny-click"); + qSeleniumLib.waitForSeconds(1); // wait for the filters menu to fully disappear? if this doesn't work, try a different word to look for... qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); qSeleniumLib.takeScreenshotToFile("after-johnny-click"); qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); From 898ba5b8ac368800d4eb29e88e95189aeae40bc4 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 16:55:19 -0600 Subject: [PATCH 18/23] Try different selector --- .../qqq/materialdashboard/tests/SavedFiltersTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index eb01b8f..089dd19 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -95,7 +95,7 @@ public class SavedFiltersTest extends QBaseSeleniumTest ////////////////////////////// qSeleniumLib.takeScreenshotToFile("before-johnny-click"); qSeleniumLib.waitForSeconds(1); // wait for the filters menu to fully disappear? if this doesn't work, try a different word to look for... - qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.waitForSelectorContaining("DIV", "jdoe@kingsrook.com").click(); qSeleniumLib.takeScreenshotToFile("after-johnny-click"); qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); @@ -121,7 +121,7 @@ public class SavedFiltersTest extends QBaseSeleniumTest ////////////////////////////// // click into a view screen // ////////////////////////////// - qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.waitForSelectorContaining("DIV", "jdoe@kingsrook.com").click(); qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); /////////////////////////////////////////////////////////////////////////////// @@ -160,7 +160,7 @@ public class SavedFiltersTest extends QBaseSeleniumTest ////////////////////////////// // click into a view screen // ////////////////////////////// - qSeleniumLib.waitForSelectorContaining("DIV", "Jonny").click(); + qSeleniumLib.waitForSelectorContaining("DIV", "jdoe@kingsrook.com").click(); qSeleniumLib.waitForSelectorContaining("H5", "Viewing Person: John Doe"); ///////////////////////////////////////////////////////////////////////////////// From 1bc6b75304098d766b46f01e295e0f6337efd3ca Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Tue, 28 Feb 2023 11:58:24 -0600 Subject: [PATCH 19/23] SPRINT-21: fixed import collision on "Map" --- src/qqq/components/scripts/ScriptTestForm.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/qqq/components/scripts/ScriptTestForm.tsx b/src/qqq/components/scripts/ScriptTestForm.tsx index 8d22d96..06d1b63 100644 --- a/src/qqq/components/scripts/ScriptTestForm.tsx +++ b/src/qqq/components/scripts/ScriptTestForm.tsx @@ -20,7 +20,6 @@ */ import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData"; -import {Map} from "@mui/icons-material"; import {Typography} from "@mui/material"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; @@ -75,7 +74,6 @@ function ScriptTestForm({scriptDefinition, tableName, fieldName, recordId, code} const testScript = () => { - // @ts-ignore const inputValues = new Map(); if (scriptDefinition.testInputFields) { From 429a5061d42b9a003b4a99b3b6fbd2e1a0e438ed Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Tue, 28 Feb 2023 12:48:58 -0600 Subject: [PATCH 20/23] SPRINT-21: temporarily disabled test that fails and that could not be reproduced local --- .../kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index 089dd19..5c7a076 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets; import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; import com.kingsrook.qqq.materialdashboard.lib.javalin.CapturedContext; import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import static com.kingsrook.qqq.materialdashboard.tests.QueryScreenTest.addQueryFilterInput; @@ -68,6 +69,7 @@ public class SavedFiltersTest extends QBaseSeleniumTest ** *******************************************************************************/ @Test + @Disabled void testNavigatingBackAndForth() { qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person", "Person"); From f6f586ae48496ab6c0a6e337f91cc96de79dc475 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 1 Mar 2023 10:38:19 -0600 Subject: [PATCH 21/23] Update to convert date-times to UTC before submitting to backend. --- src/qqq/components/misc/SavedFilters.tsx | 4 +- src/qqq/pages/records/query/RecordQuery.tsx | 2 +- src/qqq/utils/qqq/FilterUtils.ts | 54 ++++++++++++++++++--- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/qqq/components/misc/SavedFilters.tsx b/src/qqq/components/misc/SavedFilters.tsx index 810c0a9..39103fa 100644 --- a/src/qqq/components/misc/SavedFilters.tsx +++ b/src/qqq/components/misc/SavedFilters.tsx @@ -98,7 +98,7 @@ function SavedFilters({qController, metaData, tableMetaData, currentSavedFilter, { if (currentSavedFilter != null) { - let qFilter = FilterUtils.buildQFilterFromGridFilter(filterModel, columnSortModel); + let qFilter = FilterUtils.buildQFilterFromGridFilter(tableMetaData, filterModel, columnSortModel); setFilterIsModified(JSON.stringify(qFilter) !== currentSavedFilter.values.get("filterJson")); } @@ -200,7 +200,7 @@ function SavedFilters({qController, metaData, tableMetaData, currentSavedFilter, else { formData.append("tableName", tableMetaData.name); - formData.append("filterJson", JSON.stringify(FilterUtils.buildQFilterFromGridFilter(filterModel, columnSortModel))); + formData.append("filterJson", JSON.stringify(FilterUtils.buildQFilterFromGridFilter(tableMetaData, filterModel, columnSortModel))); if (isSaveFilterAs || isRenameFilter || currentSavedFilter == null) { diff --git a/src/qqq/pages/records/query/RecordQuery.tsx b/src/qqq/pages/records/query/RecordQuery.tsx index 782fe5c..e5191e7 100644 --- a/src/qqq/pages/records/query/RecordQuery.tsx +++ b/src/qqq/pages/records/query/RecordQuery.tsx @@ -283,7 +283,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element const buildQFilter = (filterModel: GridFilterModel) => { - const filter = FilterUtils.buildQFilterFromGridFilter(filterModel, columnSortModel); + const filter = FilterUtils.buildQFilterFromGridFilter(tableMetaData, filterModel, columnSortModel); setHasValidFilters(filter.criteria && filter.criteria.length > 0); return(filter); }; diff --git a/src/qqq/utils/qqq/FilterUtils.ts b/src/qqq/utils/qqq/FilterUtils.ts index c79e10c..257e875 100644 --- a/src/qqq/utils/qqq/FilterUtils.ts +++ b/src/qqq/utils/qqq/FilterUtils.ts @@ -238,7 +238,7 @@ class FilterUtils ** for non-values (e.g., blank), set it to null. ** for list-values, it's already in an array, so don't wrap it. *******************************************************************************/ - public static gridCriteriaValueToQQQ = (operator: QCriteriaOperator, value: any, gridOperatorValue: string): any[] => + public static gridCriteriaValueToQQQ = (operator: QCriteriaOperator, value: any, gridOperatorValue: string, fieldMetaData: QFieldMetaData): any[] => { if (gridOperatorValue === "isTrue") { @@ -263,18 +263,34 @@ class FilterUtils ///////////////////////////////////////////////////////////////////////////////////////////////// return ([null, null]); } - return (FilterUtils.extractIdsFromPossibleValueList(value)); + return (FilterUtils.prepFilterValuesForBackend(value, fieldMetaData)); } - return (FilterUtils.extractIdsFromPossibleValueList([value])); + return (FilterUtils.prepFilterValuesForBackend([value], fieldMetaData)); }; + + /******************************************************************************* + ** + *******************************************************************************/ + private static zeroPad = (n: number): string => + { + if (n < 10) + { + return ("0" + n); + } + return (`${n}`); + }; + + /******************************************************************************* ** Helper method - take a list of values, which may be possible values, and ** either return the original list, or a new list that is just the ids of the - ** possible values (if it was a list of possible values) + ** possible values (if it was a list of possible values). + ** + ** Or, if the values are date-times, convert them to UTC. *******************************************************************************/ - private static extractIdsFromPossibleValueList = (param: any[]): number[] | string[] => + private static prepFilterValuesForBackend = (param: any[], fieldMetaData: QFieldMetaData): number[] | string[] => { if (param === null || param === undefined) { @@ -294,7 +310,27 @@ class FilterUtils } else { - rs.push(param[i]); + if (fieldMetaData?.type == QFieldType.DATE_TIME) + { + try + { + let localDate = new Date(param[i]); + let month = (1 + localDate.getUTCMonth()); + let zp = FilterUtils.zeroPad; + let toPush = localDate.getUTCFullYear() + "-" + zp(month) + "-" + zp(localDate.getUTCDate()) + "T" + zp(localDate.getUTCHours()) + ":" + zp(localDate.getUTCMinutes()) + ":" + zp(localDate.getUTCSeconds()) + "Z"; + console.log(`Input date was ${localDate}. Sending to backend as ${toPush}`); + rs.push(toPush); + } + catch (e) + { + console.log("Error converting date-time to UTC: ", e); + rs.push(param[i]); + } + } + else + { + rs.push(param[i]); + } } } return (rs); @@ -494,7 +530,7 @@ class FilterUtils /******************************************************************************* ** build a qqq filter from a grid and column sort model *******************************************************************************/ - public static buildQFilterFromGridFilter(filterModel: GridFilterModel, columnSortModel: GridSortItem[]): QQueryFilter + public static buildQFilterFromGridFilter(tableMetaData: QTableMetaData, filterModel: GridFilterModel, columnSortModel: GridSortItem[]): QQueryFilter { console.log("Building q filter with model:"); console.log(filterModel); @@ -533,8 +569,10 @@ class FilterUtils return; } + var fieldMetadata = tableMetaData?.fields.get(item.columnField); + const operator = FilterUtils.gridCriteriaOperatorToQQQ(item.operatorValue); - const values = FilterUtils.gridCriteriaValueToQQQ(operator, item.value, item.operatorValue); + const values = FilterUtils.gridCriteriaValueToQQQ(operator, item.value, item.operatorValue, fieldMetadata); qFilter.addCriteria(new QFilterCriteria(item.columnField, operator, values)); foundFilter = true; }); From 5e9734f7127cedad2a1d51c674b60ef3cdb993d5 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 1 Mar 2023 13:43:16 -0600 Subject: [PATCH 22/23] Fix ISO8601 method, to use HH vs hh (24 hour) --- src/qqq/utils/qqq/ValueUtils.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qqq/utils/qqq/ValueUtils.tsx b/src/qqq/utils/qqq/ValueUtils.tsx index 593c838..1ab8086 100644 --- a/src/qqq/utils/qqq/ValueUtils.tsx +++ b/src/qqq/utils/qqq/ValueUtils.tsx @@ -260,7 +260,7 @@ class ValueUtils date = new Date(date) } // @ts-ignore - return (`${date.toString("yyyy-MM-ddThh:mm:ssZ")}`); + return (`${date.toString("yyyy-MM-ddTHH:mm:ssZ")}`); } public static getFullWeekday(date: Date) From 9487f631e7f7d1740d8104d243920fb254c775e8 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Wed, 1 Mar 2023 20:04:54 -0600 Subject: [PATCH 23/23] random attempt to fix weird test failure in circle ci, removed the whole omit reload thing which only half worked --- src/qqq/components/widgets/DashboardWidgets.tsx | 3 +-- .../kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java | 2 +- .../qqq/materialdashboard/tests/SavedFiltersTest.java | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index e92e3cc..2e625fe 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -179,8 +179,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit widgetIndex={i} widgetMetaData={widgetMetaData} data={widgetData[i]} - reloadWidgetCallback={widgetData[i]?.omitReloadWidgetCallback ? () => - {} : reloadWidget} + reloadWidgetCallback={reloadWidget} storeDropdownSelections={widgetMetaData.storeDropdownSelections} /> ) diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java index 21c92a5..374de64 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/lib/QBaseSeleniumTest.java @@ -54,7 +54,7 @@ public class QBaseSeleniumTest void beforeEach() { driver = new ChromeDriver(chromeOptions); - driver.manage().window().setSize(new Dimension(1600, 1200)); + driver.manage().window().setSize(new Dimension(1700, 1300)); qSeleniumLib = new QSeleniumLib(driver); qSeleniumJavalin = new QSeleniumJavalin(); diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java index 5c7a076..089dd19 100755 --- a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/SavedFiltersTest.java @@ -27,7 +27,6 @@ import java.nio.charset.StandardCharsets; import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; import com.kingsrook.qqq.materialdashboard.lib.javalin.CapturedContext; import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import static com.kingsrook.qqq.materialdashboard.tests.QueryScreenTest.addQueryFilterInput; @@ -69,7 +68,6 @@ public class SavedFiltersTest extends QBaseSeleniumTest ** *******************************************************************************/ @Test - @Disabled void testNavigatingBackAndForth() { qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person", "Person");