diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..e6062e0
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,50 @@
+version: 2.1
+
+orbs:
+ cypress: cypress-io/cypress@2
+
+commands:
+ setup:
+ steps:
+ - checkout
+ - run:
+ name: write npmrc
+ command: |
+ echo "@kingsrook:registry=https://npm.pkg.github.com/" >> .npmrc
+ echo "NPM_TOKEN=${NPM_TOKEN}" >> .npmrc
+ echo "@OWNER:registry=https://npm.pkg.github.com/" >> .npmrc
+ echo "//npm.pkg.github.com/:_authToken=${NPM_TOKEN}" >> .npmrc
+ - run:
+ name: copy .env
+ command: |
+ cp .circleci/env ./.env
+ cat ./.env
+
+jobs:
+ setup-job:
+ executor: cypress/base-10
+ steps:
+ - setup
+
+workflows:
+ build:
+ jobs:
+ - setup-job:
+ context: [ qqq-maven-registry-credentials ]
+ - cypress/install:
+ context: [ qqq-maven-registry-credentials ]
+ requires:
+ - setup-job
+ build: 'cp .circleci/env ./.env && npm run build' # run a custom app build step
+ - cypress/run:
+ context: [ qqq-maven-registry-credentials ]
+ requires:
+ - cypress/install
+ start: 'cp .circleci/env ./.env && npm run start' # start server before running tests
+ wait-on: 'https://localhost:3000'
+ ## record: true # record results on Cypress Dashboard
+ ## parallel: true # split all specs across machines
+ ## parallelism: 4 # use 4 CircleCI machines to finish quickly
+ ## group: 'all tests' # name this group "all tests" on the dashboard
+
+
diff --git a/.circleci/env b/.circleci/env
new file mode 100644
index 0000000..3581308
--- /dev/null
+++ b/.circleci/env
@@ -0,0 +1,7 @@
+GENERATE_SOURCEMAP=false
+HTTPS=true
+
+REACT_APP_MATERIAL_UI_LICENSE_KEY=${MATERIAL_UI_LICENSE_KEY}
+
+REACT_APP_GOOGLE_APP_API_KEY=${GOOGLE_APP_API_KEY}
+REACT_APP_GOOGLE_APP_CLIENT_ID=${GOOGLE_APP_CLIENT_ID
diff --git a/cypress/.gitignore b/cypress/.gitignore
new file mode 100644
index 0000000..4094344
--- /dev/null
+++ b/cypress/.gitignore
@@ -0,0 +1 @@
+videos
diff --git a/cypress/e2e/entity-list.spec.cy.ts b/cypress/e2e/entity-list.spec.cy.ts
new file mode 100644
index 0000000..886f20c
--- /dev/null
+++ b/cypress/e2e/entity-list.spec.cy.ts
@@ -0,0 +1,83 @@
+///
+
+describe("table query screen", () =>
+{
+
+ before(() =>
+ {
+ cy.intercept("GET", "/metaData/authentication", {fixture: "metaData/authentication.json"}).as("authenticationMetaData");
+ cy.intercept("GET", "/metaData", {fixture: "metaData/index.json"}).as("metaData");
+ cy.intercept("GET", "/metaData/table/person", {fixture: "metaData/table/person.json"}).as("personMetaData");
+ cy.intercept("POST", "/data/person/query?*", {fixture: "data/person/index.json"}).as("personQuery");
+ cy.intercept("POST", "/data/person/count", {fixture: "data/person/count.json"}).as("personCount");
+ cy.intercept("POST", "/data/city/count", {fixture: "data/city/count.json"}).as("cityCount");
+
+ cy.intercept("GET", "/metaData/process/person.bulkEdit", {fixture: "metaData/process/person.bulkEdit.json"}).as("personBulkEditMetaData");
+ cy.intercept("POST", "/processes/person.bulkEdit/init?recordsParam=recordIds&recordIds=1,2,3,4,5", {fixture: "processes/person.bulkEdit/init.json"}).as("personBulkEditInit");
+ cy.intercept("POST", "/processes/person.bulkEdit/74a03a7d-2f53-4784-9911-3a21f7646c43/step/edit", {fixture: "processes/person.bulkEdit/step/edit.json"}).as("personBulkEditStepEdit");
+ cy.intercept("GET", "/processes/person.bulkEdit/74a03a7d-2f53-4784-9911-3a21f7646c43/records?skip=0&limit=10", {fixture: "processes/person.bulkEdit/records.json"}).as("personBulkEditRecords");
+ cy.intercept("GET", "/widget/* ", {fixture: "widget/empty.json"}).as("emptyWidget");
+ });
+
+ it("can be loaded from app screen", () =>
+ {
+ cy.visit("https://localhost:3000/peopleApp/greetingsApp/");
+ cy.contains("Person").click();
+ cy.location().should((loc) =>
+ {
+ expect(loc.pathname).to.eq("/peopleApp/greetingsApp/person");
+ });
+ });
+
+ it.only("can add query filters", () =>
+ {
+ /////////////////////////////////////////////////////////////
+ // go to table, wait for filter to run, and rows to appear //
+ /////////////////////////////////////////////////////////////
+ cy.visit("https://localhost:3000/peopleApp/greetingsApp/person");
+ cy.wait(["@personQuery", "@personCount"]);
+ cy.get(".MuiDataGrid-virtualScrollerRenderZone").children().should("have.length.greaterThan", 3);
+
+ /////////////////////////////////////////////////////////////////////
+ // open the filter window, enter a value, wait for query to re-run //
+ /////////////////////////////////////////////////////////////////////
+ cy.contains("Filters").click();
+ cy.get(".MuiDataGrid-filterForm input.MuiInput-input").should("be.focused").type("1");
+
+ ///////////////////////////////////////////////////////////////////
+ // assert that query & count both have the expected filter value //
+ ///////////////////////////////////////////////////////////////////
+ let expectedFilterContents = JSON.stringify({fieldName: "id", operator: "EQUALS", values: ["1"]});
+ cy.wait("@personQuery").its("request.body").should((body) => expect(body).to.contain(expectedFilterContents));
+ cy.wait("@personCount").its("request.body").should((body) => expect(body).to.contain(expectedFilterContents));
+
+ ///////////////////////////////////////
+ // click away from the filter window //
+ ///////////////////////////////////////
+ cy.get("#root").click("topLeft", {force: true});
+ cy.contains(".MuiBadge-root", "1").should("be.visible");
+
+ ///////////////////////////////////////////////////////////////////
+ // click the 'x' clear icon, then yes, then expect another query //
+ ///////////////////////////////////////////////////////////////////
+ cy.waitForStableDOM();
+ cy.get("#clearFiltersButton").should("be.visible").click();
+ cy.contains("button", "Yes").click();
+
+ ////////////////////////////////////////////////////////////////////
+ // assert that query & count both no longer have the filter value //
+ ////////////////////////////////////////////////////////////////////
+ cy.wait("@personQuery").its("request.body").should((body) => expect(body).not.to.contain(expectedFilterContents));
+ cy.wait("@personCount").its("request.body").should((body) => expect(body).not.to.contain(expectedFilterContents));
+ cy.contains(".MuiDataGrid-toolbarContainer .MuiBadge-root", "1").should("not.exist");
+ });
+
+ // tests to add:
+ // - filter boolean OR
+ // - sort column
+ // - all field types and operators
+ // - pagination, page size
+ // - check marks, select all
+ // - column chooser
+
+});
diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts
deleted file mode 100644
index ac0fd02..0000000
--- a/cypress/e2e/spec.cy.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-// noinspection ES6UnusedImports
-import * as cypress from "cypress";
-
-describe("empty spec", () =>
-{
- it("passes", () =>
- {
- cy.intercept("GET", "/metaData", {fixture: "metaData/index.json"}).as("metaData");
- cy.intercept("GET", "/data/person?*", {fixture: "data/person/index.json"}).as("personQuery");
- cy.intercept("GET", "/data/person/count?*", {fixture: "data/person/count.json"}).as("personCount")
- cy.intercept("GET", "/metaData/process/person.bulkEdit", {fixture: "metaData/process/person.bulkEdit.json"}).as("personBulkEditMetaData")
- cy.intercept("POST", "/processes/person.bulkEdit/init?recordsParam=recordIds&recordIds=1,2,3,4,5", {fixture: "processes/person.bulkEdit/init.json"}).as("personBulkEditInit")
- cy.intercept("POST", "/processes/person.bulkEdit/74a03a7d-2f53-4784-9911-3a21f7646c43/step/edit", {fixture: "processes/person.bulkEdit/step/edit.json"}).as("personBulkEditStepEdit")
- cy.intercept("GET", "/processes/person.bulkEdit/74a03a7d-2f53-4784-9911-3a21f7646c43/records?skip=0&limit=10", {fixture: "processes/person.bulkEdit/records.json"}).as("personBulkEditRecords")
-
- /////////////////
- // home screen //
- /////////////////
- cy.visit("http://localhost:3000/");
- cy.wait(["@metaData"])
-
- cy.contains(".MuiListItem-root", "Tables").click();
- cy.contains(".MuiListItem-root", "Person").click();
-
- /////////////////////////
- // person query screen //
- /////////////////////////
- cy.location().should((loc) =>
- {
- expect(loc.pathname).to.eq("/person")
- });
- cy.wait(["@personQuery", "@personCount"])
-
- cy.get(".MuiDataGrid-columnHeaders input[type='checkbox']").click();
- cy.contains("button", "Bulk Actions").click();
- cy.contains("li", "Bulk Edit").click();
-
- ////////////////////////////
- // bulk edit process init //
- ////////////////////////////
- cy.location().should((loc) =>
- {
- expect(loc.pathname).to.eq("/processes/person.bulkEdit");
- expect(loc.search).to.eq("?recordsParam=recordIds&recordIds=1,2,3,4,5");
- });
- cy.wait(["@personBulkEditMetaData"])
- cy.wait(["@personBulkEditInit"])
-
- cy.contains("p[variation='h5']", "Edit Values");
- cy.get("#bulkEditSwitch-firstName").click();
- cy.get("input[name='firstName']").click()
- .type("Kahhhhn");
- cy.contains("button", "next").click();
-
- ///////////////////////////
- // bulk edit review step //
- ///////////////////////////
- cy.contains("p[variation='h5']", "Review");
- cy.contains(".MuiDataGrid-cellContent", "Kahhhhn");
-
- cy.contains("button", "submit").click();
- cy.wait(["@personBulkEditStepEdit"])
- cy.wait(["@personBulkEditRecords"])
-
- ////////////////////////////
- // bulk edit result step //
- ////////////////////////////
- cy.contains("p[variation='h5']", "Results");
- cy.wait(["@personBulkEditRecords"])
- });
-
-});
diff --git a/cypress/fixtures/data/city/count.json b/cypress/fixtures/data/city/count.json
new file mode 100644
index 0000000..92fba2e
--- /dev/null
+++ b/cypress/fixtures/data/city/count.json
@@ -0,0 +1,3 @@
+{
+ "count": 101406
+}
diff --git a/cypress/fixtures/data/person/count.json b/cypress/fixtures/data/person/count.json
index 8d1d5b4..92fba2e 100644
--- a/cypress/fixtures/data/person/count.json
+++ b/cypress/fixtures/data/person/count.json
@@ -1,3 +1,3 @@
{
- "count": 5
+ "count": 101406
}
diff --git a/cypress/fixtures/metaData/authentication.json b/cypress/fixtures/metaData/authentication.json
new file mode 100644
index 0000000..71c87b5
--- /dev/null
+++ b/cypress/fixtures/metaData/authentication.json
@@ -0,0 +1,4 @@
+{
+ "name": "mock",
+ "type": "MOCK"
+}
diff --git a/cypress/fixtures/metaData/index.json b/cypress/fixtures/metaData/index.json
index 6858e0b..0f8133d 100644
--- a/cypress/fixtures/metaData/index.json
+++ b/cypress/fixtures/metaData/index.json
@@ -1,102 +1,550 @@
{
- "tables": {
- "carrier": {
- "name": "carrier",
- "label": "Carrier",
- "isHidden": false
- },
- "city": {
- "name": "city",
- "label": "Cities",
- "isHidden": true
- },
- "person": {
- "name": "person",
- "label": "Person",
- "isHidden": false
- }
- },
- "processes": {
- "person.bulkInsert": {
- "name": "person.bulkInsert",
- "label": "Person Bulk Insert",
- "tableName": "person",
- "isHidden": true
- },
- "carrier.bulkInsert": {
- "name": "carrier.bulkInsert",
- "label": "Carrier Bulk Insert",
- "tableName": "carrier",
- "isHidden": true
- },
- "simpleSleep": {
- "name": "simpleSleep",
- "label": "Simple Sleep",
- "isHidden": true
- },
- "carrier.bulkDelete": {
- "name": "carrier.bulkDelete",
- "label": "Carrier Bulk Delete",
- "tableName": "carrier",
- "isHidden": true
- },
- "greet": {
- "name": "greet",
- "label": "Greet People",
- "tableName": "person",
- "isHidden": true
- },
- "city.bulkDelete": {
- "name": "city.bulkDelete",
- "label": "Cities Bulk Delete",
- "tableName": "city",
- "isHidden": true
- },
- "person.bulkDelete": {
- "name": "person.bulkDelete",
- "label": "Person Bulk Delete",
- "tableName": "person",
- "isHidden": true
- },
- "carrier.bulkEdit": {
- "name": "carrier.bulkEdit",
- "label": "Carrier Bulk Edit",
- "tableName": "carrier",
- "isHidden": true
- },
- "person.bulkEdit": {
- "name": "person.bulkEdit",
- "label": "Person Bulk Edit",
- "tableName": "person",
- "isHidden": true
- },
- "greetInteractive": {
- "name": "greetInteractive",
- "label": "Greet Interactive",
- "tableName": "person",
- "isHidden": false
- },
- "city.bulkEdit": {
- "name": "city.bulkEdit",
- "label": "Cities Bulk Edit",
- "tableName": "city",
- "isHidden": true
- },
- "simpleThrow": {
- "name": "simpleThrow",
- "label": "Simple Throw",
- "isHidden": false
- },
- "sleepInteractive": {
- "name": "sleepInteractive",
- "label": "Sleep Interactive",
- "isHidden": false
- },
- "city.bulkInsert": {
- "name": "city.bulkInsert",
- "label": "Cities Bulk Insert",
- "tableName": "city",
- "isHidden": true
- }
- }
+ "tables": {
+ "carrier": {
+ "name": "carrier",
+ "label": "Carrier",
+ "isHidden": false,
+ "iconName": "local_shipping",
+ "capabilities": [
+ "TABLE_COUNT",
+ "TABLE_GET",
+ "TABLE_QUERY",
+ "TABLE_UPDATE",
+ "TABLE_INSERT",
+ "TABLE_DELETE"
+ ]
+ },
+ "person": {
+ "name": "person",
+ "label": "Person",
+ "isHidden": false,
+ "iconName": "person",
+ "capabilities": [
+ "TABLE_COUNT",
+ "TABLE_GET",
+ "TABLE_QUERY",
+ "TABLE_UPDATE",
+ "TABLE_INSERT",
+ "TABLE_DELETE"
+ ]
+ },
+ "city": {
+ "name": "city",
+ "label": "Cities",
+ "isHidden": true,
+ "iconName": "location_city",
+ "capabilities": [
+ "TABLE_COUNT",
+ "TABLE_GET",
+ "TABLE_QUERY",
+ "TABLE_UPDATE",
+ "TABLE_INSERT",
+ "TABLE_DELETE"
+ ]
+ }
+ },
+ "processes": {
+ "greet": {
+ "name": "greet",
+ "label": "Greet People",
+ "tableName": "person",
+ "isHidden": true,
+ "iconName": "emoji_people"
+ },
+ "greetInteractive": {
+ "name": "greetInteractive",
+ "label": "Greet Interactive",
+ "tableName": "person",
+ "isHidden": false,
+ "iconName": "waving_hand"
+ },
+ "clonePeople": {
+ "name": "clonePeople",
+ "label": "Clone People",
+ "tableName": "person",
+ "isHidden": false,
+ "iconName": "content_copy"
+ },
+ "simpleSleep": {
+ "name": "simpleSleep",
+ "label": "Simple Sleep",
+ "isHidden": true
+ },
+ "sleepInteractive": {
+ "name": "sleepInteractive",
+ "label": "Sleep Interactive",
+ "isHidden": false
+ },
+ "simpleThrow": {
+ "name": "simpleThrow",
+ "label": "Simple Throw",
+ "isHidden": false
+ },
+ "carrier.bulkInsert": {
+ "name": "carrier.bulkInsert",
+ "label": "Carrier Bulk Insert",
+ "tableName": "carrier",
+ "isHidden": true
+ },
+ "carrier.bulkEdit": {
+ "name": "carrier.bulkEdit",
+ "label": "Carrier Bulk Edit",
+ "tableName": "carrier",
+ "isHidden": true
+ },
+ "carrier.bulkDelete": {
+ "name": "carrier.bulkDelete",
+ "label": "Carrier Bulk Delete",
+ "tableName": "carrier",
+ "isHidden": true
+ },
+ "person.bulkInsert": {
+ "name": "person.bulkInsert",
+ "label": "Person Bulk Insert",
+ "tableName": "person",
+ "isHidden": true
+ },
+ "person.bulkEdit": {
+ "name": "person.bulkEdit",
+ "label": "Person Bulk Edit",
+ "tableName": "person",
+ "isHidden": true
+ },
+ "person.bulkDelete": {
+ "name": "person.bulkDelete",
+ "label": "Person Bulk Delete",
+ "tableName": "person",
+ "isHidden": true
+ },
+ "city.bulkInsert": {
+ "name": "city.bulkInsert",
+ "label": "Cities Bulk Insert",
+ "tableName": "city",
+ "isHidden": true
+ },
+ "city.bulkEdit": {
+ "name": "city.bulkEdit",
+ "label": "Cities Bulk Edit",
+ "tableName": "city",
+ "isHidden": true
+ },
+ "city.bulkDelete": {
+ "name": "city.bulkDelete",
+ "label": "Cities Bulk Delete",
+ "tableName": "city",
+ "isHidden": true
+ }
+ },
+ "apps": {
+ "greetingsApp": {
+ "name": "greetingsApp",
+ "label": "Greetings App",
+ "iconName": "emoji_people",
+ "widgets": [
+ "PersonsByCreateDateBarChart",
+ "QuickSightChartRenderer"
+ ],
+ "children": [
+ {
+ "type": "PROCESS",
+ "name": "greet",
+ "label": "Greet People",
+ "iconName": "emoji_people"
+ },
+ {
+ "type": "TABLE",
+ "name": "person",
+ "label": "Person",
+ "iconName": "person"
+ },
+ {
+ "type": "TABLE",
+ "name": "city",
+ "label": "Cities",
+ "iconName": "location_city"
+ },
+ {
+ "type": "PROCESS",
+ "name": "greetInteractive",
+ "label": "Greet Interactive",
+ "iconName": "waving_hand"
+ }
+ ],
+ "childMap": {
+ "greetInteractive": {
+ "type": "PROCESS",
+ "name": "greetInteractive",
+ "label": "Greet Interactive",
+ "iconName": "waving_hand"
+ },
+ "city": {
+ "type": "TABLE",
+ "name": "city",
+ "label": "Cities",
+ "iconName": "location_city"
+ },
+ "person": {
+ "type": "TABLE",
+ "name": "person",
+ "label": "Person",
+ "iconName": "person"
+ },
+ "greet": {
+ "type": "PROCESS",
+ "name": "greet",
+ "label": "Greet People",
+ "iconName": "emoji_people"
+ }
+ },
+ "sections": [
+ {
+ "name": "greetingsApp",
+ "label": "Greetings App",
+ "icon": {
+ "name": "badge"
+ },
+ "tables": [
+ "person",
+ "city"
+ ],
+ "processes": [
+ "greet",
+ "greetInteractive"
+ ]
+ }
+ ]
+ },
+ "peopleApp": {
+ "name": "peopleApp",
+ "label": "People App",
+ "iconName": "person",
+ "widgets": [],
+ "children": [
+ {
+ "type": "APP",
+ "name": "greetingsApp",
+ "label": "Greetings App",
+ "iconName": "emoji_people"
+ },
+ {
+ "type": "PROCESS",
+ "name": "clonePeople",
+ "label": "Clone People",
+ "iconName": "content_copy"
+ }
+ ],
+ "childMap": {
+ "greetingsApp": {
+ "type": "APP",
+ "name": "greetingsApp",
+ "label": "Greetings App",
+ "iconName": "emoji_people"
+ },
+ "clonePeople": {
+ "type": "PROCESS",
+ "name": "clonePeople",
+ "label": "Clone People",
+ "iconName": "content_copy"
+ }
+ },
+ "sections": [
+ {
+ "name": "peopleApp",
+ "label": "People App",
+ "icon": {
+ "name": "badge"
+ },
+ "processes": [
+ "clonePeople"
+ ]
+ }
+ ]
+ },
+ "miscellaneous": {
+ "name": "miscellaneous",
+ "label": "Miscellaneous",
+ "iconName": "stars",
+ "widgets": [],
+ "children": [
+ {
+ "type": "TABLE",
+ "name": "carrier",
+ "label": "Carrier",
+ "iconName": "local_shipping"
+ },
+ {
+ "type": "PROCESS",
+ "name": "simpleSleep",
+ "label": "Simple Sleep"
+ },
+ {
+ "type": "PROCESS",
+ "name": "sleepInteractive",
+ "label": "Sleep Interactive"
+ },
+ {
+ "type": "PROCESS",
+ "name": "simpleThrow",
+ "label": "Simple Throw"
+ }
+ ],
+ "childMap": {
+ "carrier": {
+ "type": "TABLE",
+ "name": "carrier",
+ "label": "Carrier",
+ "iconName": "local_shipping"
+ },
+ "simpleSleep": {
+ "type": "PROCESS",
+ "name": "simpleSleep",
+ "label": "Simple Sleep"
+ },
+ "simpleThrow": {
+ "type": "PROCESS",
+ "name": "simpleThrow",
+ "label": "Simple Throw"
+ },
+ "sleepInteractive": {
+ "type": "PROCESS",
+ "name": "sleepInteractive",
+ "label": "Sleep Interactive"
+ }
+ },
+ "sections": [
+ {
+ "name": "miscellaneous",
+ "label": "Miscellaneous",
+ "icon": {
+ "name": "badge"
+ },
+ "tables": [
+ "carrier"
+ ],
+ "processes": [
+ "simpleSleep",
+ "sleepInteractive",
+ "simpleThrow"
+ ]
+ }
+ ]
+ }
+ },
+ "appTree": [
+ {
+ "type": "APP",
+ "name": "peopleApp",
+ "label": "People App",
+ "children": [
+ {
+ "type": "APP",
+ "name": "greetingsApp",
+ "label": "Greetings App",
+ "children": [
+ {
+ "type": "PROCESS",
+ "name": "greet",
+ "label": "Greet People",
+ "iconName": "emoji_people"
+ },
+ {
+ "type": "TABLE",
+ "name": "person",
+ "label": "Person",
+ "iconName": "person"
+ },
+ {
+ "type": "TABLE",
+ "name": "city",
+ "label": "Cities",
+ "iconName": "location_city"
+ },
+ {
+ "type": "PROCESS",
+ "name": "greetInteractive",
+ "label": "Greet Interactive",
+ "iconName": "waving_hand"
+ }
+ ],
+ "iconName": "emoji_people"
+ },
+ {
+ "type": "PROCESS",
+ "name": "clonePeople",
+ "label": "Clone People",
+ "iconName": "content_copy"
+ }
+ ],
+ "iconName": "person"
+ },
+ {
+ "type": "APP",
+ "name": "miscellaneous",
+ "label": "Miscellaneous",
+ "children": [
+ {
+ "type": "TABLE",
+ "name": "carrier",
+ "label": "Carrier",
+ "iconName": "local_shipping"
+ },
+ {
+ "type": "PROCESS",
+ "name": "simpleSleep",
+ "label": "Simple Sleep"
+ },
+ {
+ "type": "PROCESS",
+ "name": "sleepInteractive",
+ "label": "Sleep Interactive"
+ },
+ {
+ "type": "PROCESS",
+ "name": "simpleThrow",
+ "label": "Simple Throw"
+ }
+ ],
+ "iconName": "stars"
+ }
+ ],
+ "branding": {
+ "logo": "/kr-logo.png",
+ "icon": "/kr-icon.png"
+ },
+ "widgets": {
+ "parcelTrackingDetails": {
+ "name": "parcelTrackingDetails",
+ "label": "Tracking Details",
+ "type": "childRecordList"
+ },
+ "deposcoSalesOrderLineItems": {
+ "name": "deposcoSalesOrderLineItems",
+ "label": "Line Items",
+ "type": "childRecordList"
+ },
+ "TotalShipmentsByDayBarChart": {
+ "name": "TotalShipmentsByDayBarChart",
+ "label": "Total Shipments By Day",
+ "type": "chart"
+ },
+ "TotalShipmentsByMonthLineChart": {
+ "name": "TotalShipmentsByMonthLineChart",
+ "label": "Total Shipments By Month",
+ "type": "chart"
+ },
+ "YTDShipmentsByCarrierPieChart": {
+ "name": "YTDShipmentsByCarrierPieChart",
+ "label": "Shipments By Carrier Year To Date",
+ "type": "chart"
+ },
+ "TodaysShipmentsStatisticsCard": {
+ "name": "TodaysShipmentsStatisticsCard",
+ "label": "Today's Shipments",
+ "type": "statistics"
+ },
+ "ShipmentsInTransitStatisticsCard": {
+ "name": "ShipmentsInTransitStatisticsCard",
+ "label": "Shipments In Transit",
+ "type": "statistics"
+ },
+ "OpenOrdersStatisticsCard": {
+ "name": "OpenOrdersStatisticsCard",
+ "label": "Open Orders",
+ "type": "statistics"
+ },
+ "ShippingExceptionsStatisticsCard": {
+ "name": "ShippingExceptionsStatisticsCard",
+ "label": "Shipping Exceptions",
+ "type": "statistics"
+ },
+ "WarehouseLocationCards": {
+ "name": "WarehouseLocationCards",
+ "type": "location"
+ },
+ "TotalShipmentsStatisticsCard": {
+ "name": "TotalShipmentsStatisticsCard",
+ "label": "Total Shipments",
+ "type": "statistics"
+ },
+ "SuccessfulDeliveriesStatisticsCard": {
+ "name": "SuccessfulDeliveriesStatisticsCard",
+ "label": "Successful Deliveries",
+ "type": "statistics"
+ },
+ "ServiceFailuresStatisticsCard": {
+ "name": "ServiceFailuresStatisticsCard",
+ "label": "Service Failures",
+ "type": "statistics"
+ },
+ "CarrierVolumeLineChart": {
+ "name": "CarrierVolumeLineChart",
+ "label": "Carrier Volume By Month",
+ "type": "lineChart"
+ },
+ "YTDSpendByCarrierTable": {
+ "name": "YTDSpendByCarrierTable",
+ "label": "Spend By Carrier Year To Date",
+ "type": "table"
+ },
+ "TimeInTransitBarChart": {
+ "name": "TimeInTransitBarChart",
+ "label": "Time In Transit Last 30 Days",
+ "type": "chart"
+ },
+ "OpenBillingWorksheetsTable": {
+ "name": "OpenBillingWorksheetsTable",
+ "label": "Open Billing Worksheets",
+ "type": "table"
+ },
+ "AssociatedParcelInvoicesTable": {
+ "name": "AssociatedParcelInvoicesTable",
+ "label": "Associated Parcel Invoices",
+ "type": "table",
+ "icon": "receipt"
+ },
+ "BillingWorksheetLinesTable": {
+ "name": "BillingWorksheetLinesTable",
+ "label": "Billing Worksheet Lines",
+ "type": "table"
+ },
+ "RatingIssuesWidget": {
+ "name": "RatingIssuesWidget",
+ "label": "Rating Issues",
+ "type": "html",
+ "icon": "warning",
+ "gridColumns": 6
+ },
+ "UnassignedParcelInvoicesTable": {
+ "name": "UnassignedParcelInvoicesTable",
+ "label": "Unassigned Parcel Invoices",
+ "type": "table"
+ },
+ "ParcelInvoiceSummaryWidget": {
+ "name": "ParcelInvoiceSummaryWidget",
+ "label": "Parcel Invoice Summary",
+ "type": "multiStatistics"
+ },
+ "ParcelInvoiceLineExceptionsSummaryWidget": {
+ "name": "ParcelInvoiceLineExceptionsSummaryWidget",
+ "label": "Parcel Invoice Line Exceptions",
+ "type": "multiStatistics"
+ },
+ "BillingWorksheetStatusStepper": {
+ "name": "BillingWorksheetStatusStepper",
+ "label": "Billing Worksheet Progress",
+ "type": "stepper",
+ "icon": "refresh",
+ "gridColumns": 6
+ },
+ "PersonsByCreateDateBarChart": {
+ "name": "PersonsByCreateDateBarChart",
+ "label": "Persons By Create Date",
+ "type": "barChart"
+ },
+ "QuickSightChartRenderer": {
+ "name": "QuickSightChartRenderer",
+ "label": "Quick Sight",
+ "type": "quickSightChart"
+ }
+ }
}
diff --git a/cypress/fixtures/metaData/process/person.bulkEdit.json b/cypress/fixtures/metaData/process/person.bulkEdit.json
index 62b2260..f7b0546 100644
--- a/cypress/fixtures/metaData/process/person.bulkEdit.json
+++ b/cypress/fixtures/metaData/process/person.bulkEdit.json
@@ -27,7 +27,8 @@
"backendName": "first_name",
"type": "STRING",
"isRequired": true,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
},
{
"name": "lastName",
@@ -35,7 +36,8 @@
"backendName": "last_name",
"type": "STRING",
"isRequired": true,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
},
{
"name": "birthDate",
@@ -43,14 +45,44 @@
"backendName": "birth_date",
"type": "DATE",
"isRequired": false,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
},
{
"name": "email",
"label": "Email",
+ "backendName": "email",
"type": "STRING",
"isRequired": false,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ {
+ "name": "isEmployed",
+ "label": "Is Employed",
+ "backendName": "is_employed",
+ "type": "BOOLEAN",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ {
+ "name": "annualSalary",
+ "label": "Annual Salary",
+ "backendName": "annual_salary",
+ "type": "DECIMAL",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "$%,.2f"
+ },
+ {
+ "name": "daysWorked",
+ "label": "Days Worked",
+ "backendName": "days_worked",
+ "type": "INTEGER",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%,d"
}
]
},
@@ -60,19 +92,7 @@
"stepType": "frontend",
"components": [
{
- "type": "HELP_TEXT",
- "values": {
- "text": "The records below will be updated if you click Submit."
- }
- }
- ],
- "viewFields": [
- {
- "name": "valuesBeingUpdated",
- "label": "Values Being Updated",
- "type": "STRING",
- "isRequired": false,
- "isEditable": true
+ "type": "VALIDATION_REVIEW_SCREEN"
}
],
"recordListFields": [
@@ -82,7 +102,8 @@
"backendName": "first_name",
"type": "STRING",
"isRequired": true,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
},
{
"name": "lastName",
@@ -90,7 +111,8 @@
"backendName": "last_name",
"type": "STRING",
"isRequired": true,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
},
{
"name": "birthDate",
@@ -98,83 +120,54 @@
"backendName": "birth_date",
"type": "DATE",
"isRequired": false,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
},
{
"name": "email",
"label": "Email",
+ "backendName": "email",
"type": "STRING",
"isRequired": false,
- "isEditable": true
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ {
+ "name": "isEmployed",
+ "label": "Is Employed",
+ "backendName": "is_employed",
+ "type": "BOOLEAN",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ {
+ "name": "annualSalary",
+ "label": "Annual Salary",
+ "backendName": "annual_salary",
+ "type": "DECIMAL",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "$%,.2f"
+ },
+ {
+ "name": "daysWorked",
+ "label": "Days Worked",
+ "backendName": "days_worked",
+ "type": "INTEGER",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%,d"
}
]
},
{
- "name": "results",
- "label": "Results",
+ "name": "result",
+ "label": "Result",
"stepType": "frontend",
"components": [
{
- "type": "HELP_TEXT",
- "values": {
- "text": "The records below have been updated."
- }
- }
- ],
- "recordListFields": [
- {
- "name": "id",
- "label": "Id",
- "type": "INTEGER",
- "isRequired": false,
- "isEditable": false
- },
- {
- "name": "createDate",
- "label": "Create Date",
- "backendName": "create_date",
- "type": "DATE_TIME",
- "isRequired": false,
- "isEditable": false
- },
- {
- "name": "modifyDate",
- "label": "Modify Date",
- "backendName": "modify_date",
- "type": "DATE_TIME",
- "isRequired": false,
- "isEditable": false
- },
- {
- "name": "firstName",
- "label": "First Name",
- "backendName": "first_name",
- "type": "STRING",
- "isRequired": true,
- "isEditable": true
- },
- {
- "name": "lastName",
- "label": "Last Name",
- "backendName": "last_name",
- "type": "STRING",
- "isRequired": true,
- "isEditable": true
- },
- {
- "name": "birthDate",
- "label": "Birth Date",
- "backendName": "birth_date",
- "type": "DATE",
- "isRequired": false,
- "isEditable": true
- },
- {
- "name": "email",
- "label": "Email",
- "type": "STRING",
- "isRequired": false,
- "isEditable": true
+ "type": "PROCESS_SUMMARY_RESULTS"
}
]
}
diff --git a/cypress/fixtures/metaData/table/person.json b/cypress/fixtures/metaData/table/person.json
new file mode 100644
index 0000000..5f69a3b
--- /dev/null
+++ b/cypress/fixtures/metaData/table/person.json
@@ -0,0 +1,155 @@
+{
+ "table": {
+ "name": "person",
+ "label": "Person",
+ "isHidden": false,
+ "primaryKeyField": "id",
+ "iconName": "person",
+ "fields": {
+ "firstName": {
+ "name": "firstName",
+ "label": "First Name",
+ "type": "STRING",
+ "isRequired": true,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ "lastName": {
+ "name": "lastName",
+ "label": "Last Name",
+ "type": "STRING",
+ "isRequired": true,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ "annualSalary": {
+ "name": "annualSalary",
+ "label": "Annual Salary",
+ "type": "DECIMAL",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "$%,.2f"
+ },
+ "modifyDate": {
+ "name": "modifyDate",
+ "label": "Modify Date",
+ "type": "DATE_TIME",
+ "isRequired": false,
+ "isEditable": false,
+ "displayFormat": "%s"
+ },
+ "daysWorked": {
+ "name": "daysWorked",
+ "label": "Days Worked",
+ "type": "INTEGER",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%,d"
+ },
+ "id": {
+ "name": "id",
+ "label": "Id",
+ "type": "INTEGER",
+ "isRequired": false,
+ "isEditable": false,
+ "displayFormat": "%s"
+ },
+ "birthDate": {
+ "name": "birthDate",
+ "label": "Birth Date",
+ "type": "DATE",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ "isEmployed": {
+ "name": "isEmployed",
+ "label": "Is Employed",
+ "type": "BOOLEAN",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ "email": {
+ "name": "email",
+ "label": "Email",
+ "type": "STRING",
+ "isRequired": false,
+ "isEditable": true,
+ "displayFormat": "%s"
+ },
+ "createDate": {
+ "name": "createDate",
+ "label": "Create Date",
+ "type": "DATE_TIME",
+ "isRequired": false,
+ "isEditable": false,
+ "displayFormat": "%s"
+ }
+ },
+ "sections": [
+ {
+ "name": "identity",
+ "label": "Identity",
+ "tier": "T1",
+ "fieldNames": [
+ "id",
+ "firstName",
+ "lastName"
+ ],
+ "icon": {
+ "name": "badge"
+ },
+ "isHidden": false
+ },
+ {
+ "name": "basicInfo",
+ "label": "Basic Info",
+ "tier": "T2",
+ "fieldNames": [
+ "email",
+ "birthDate"
+ ],
+ "icon": {
+ "name": "dataset"
+ },
+ "isHidden": false
+ },
+ {
+ "name": "employmentInfo",
+ "label": "Employment Info",
+ "tier": "T2",
+ "fieldNames": [
+ "isEmployed",
+ "annualSalary",
+ "daysWorked"
+ ],
+ "icon": {
+ "name": "work"
+ },
+ "isHidden": false
+ },
+ {
+ "name": "dates",
+ "label": "Dates",
+ "tier": "T3",
+ "fieldNames": [
+ "createDate",
+ "modifyDate"
+ ],
+ "icon": {
+ "name": "calendar_month"
+ },
+ "isHidden": false
+ }
+ ],
+ "capabilities": [
+ "TABLE_COUNT",
+ "TABLE_GET",
+ "TABLE_QUERY",
+ "TABLE_DELETE",
+ "TABLE_INSERT",
+ "TABLE_UPDATE"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/cypress/fixtures/processes/person.bulkEdit/records.json b/cypress/fixtures/processes/person.bulkEdit/records.json
new file mode 100644
index 0000000..1765643
--- /dev/null
+++ b/cypress/fixtures/processes/person.bulkEdit/records.json
@@ -0,0 +1,3 @@
+[
+ {}
+]
\ No newline at end of file
diff --git a/cypress/fixtures/widget/empty.json b/cypress/fixtures/widget/empty.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/cypress/fixtures/widget/empty.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
index 698b01a..41cc226 100644
--- a/cypress/support/commands.ts
+++ b/cypress/support/commands.ts
@@ -34,4 +34,8 @@
// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
// }
// }
-// }
\ No newline at end of file
+// }
+
+import {registerCommand} from "cypress-wait-for-stable-dom";
+
+registerCommand({pollInterval: 100, timeout: 3000});
diff --git a/cypress/videos/spec.cy.ts.mp4 b/cypress/videos/spec.cy.ts.mp4
deleted file mode 100644
index 0acb14d..0000000
Binary files a/cypress/videos/spec.cy.ts.mp4 and /dev/null differ
diff --git a/package-lock.json b/package-lock.json
index 09889cb..e407ac7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,7 +17,7 @@
"@fullcalendar/interaction": "5.10.0",
"@fullcalendar/react": "5.10.0",
"@fullcalendar/timegrid": "5.10.0",
- "@kingsrook/qqq-frontend-core": "1.0.25",
+ "@kingsrook/qqq-frontend-core": "1.0.36",
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
@@ -38,6 +38,7 @@
"@types/react": "17.0.38",
"@types/react-dom": "17.0.11",
"@types/react-router-hash-link": "2.4.5",
+ "ace-builds": "1.12.3",
"chart.js": "3.4.1",
"chroma-js": "2.4.2",
"datejs": "1.0.0-rc3",
@@ -49,6 +50,7 @@
"html-react-parser": "1.4.8",
"http-proxy-middleware": "2.0.6",
"react": "17.0.2",
+ "react-ace": "10.1.0",
"react-chartjs-2": "3.0.4",
"react-cookie": "4.1.1",
"react-dom": "17.0.2",
@@ -78,7 +80,8 @@
"@types/uuid": "8.3.4",
"@typescript-eslint/eslint-plugin": "5.10.2",
"@typescript-eslint/parser": "5.10.2",
- "cypress": "10.3.1",
+ "cypress": "11.0.1",
+ "cypress-wait-for-stable-dom": "0.1.0",
"eslint": "8.8.0",
"eslint-config-airbnb": "19.0.4",
"eslint-import-resolver-typescript": "2.5.0",
@@ -86,6 +89,7 @@
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-react": "7.28.0",
"eslint-plugin-react-hooks": "4.3.0",
+ "start-server-and-test": "^1.14.0",
"typescript": "^4.7.3"
}
},
@@ -2649,6 +2653,21 @@
"tslib": "^2.1.0"
}
},
+ "node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+ "dev": true
+ },
+ "node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "dev": true,
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.9.5",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
@@ -3178,9 +3197,9 @@
}
},
"node_modules/@kingsrook/qqq-frontend-core": {
- "version": "1.0.25",
- "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.25/03014325ceda54cd984e44e0f650f0eff81ab536",
- "integrity": "sha512-oO0ykxZnafzyomy8ZqZxiv5QVf0E5NIqvkXp2rUlNq44zt4Sx+93uMWl4IczcRCpbFpfaWxzpLxhdN/mjmMcUw==",
+ "version": "1.0.36",
+ "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.36/ddc9de26e08e365e999642619dacaaa290920370",
+ "integrity": "sha512-KC9Uj/1W87qxpBWLPe+hyJlPQiV43YAotguDUYkTytriNUhmSnTqVhyrC9crBxW4rj4+MX4IJXVFOqoh86A3Uw==",
"license": "ISC",
"dependencies": {
"axios": "0.27.2",
@@ -3847,6 +3866,27 @@
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
"integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg=="
},
+ "node_modules/@sideway/address": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
+ "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
+ "dev": true,
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
+ "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
+ "dev": true
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+ "dev": true
+ },
"node_modules/@sinclair/typebox": {
"version": "0.24.44",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz",
@@ -5131,6 +5171,11 @@
"node": ">= 0.6"
}
},
+ "node_modules/ace-builds": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.12.3.tgz",
+ "integrity": "sha512-LHAsa5oOaRqmIlb8gBe81nj2kOqlfbV0XkWkFZL4mIfPXL4zoeTUcandHvBgHQCyjif3tGfoLTXelWSlnCT/dA=="
+ },
"node_modules/acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@@ -7265,9 +7310,9 @@
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"node_modules/cypress": {
- "version": "10.3.1",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.3.1.tgz",
- "integrity": "sha512-As9HrExjAgpgjCnbiQCuPdw5sWKx5HUJcK2EOKziu642akwufr/GUeqL5UnCPYXTyyibvEdWT/pSC2qnGW/e5w==",
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-11.0.1.tgz",
+ "integrity": "sha512-NuEfd0Vim492RJ3m/+bbTZ3OZrqXgfAfuLaZfIQ9D5lKocS3EDr2tyAarZdAhKwLyoh7OJ33jwMeMFIDbzYqog==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -7290,7 +7335,7 @@
"dayjs": "^1.10.4",
"debug": "^4.3.2",
"enquirer": "^2.3.6",
- "eventemitter2": "^6.4.3",
+ "eventemitter2": "6.4.7",
"execa": "4.1.0",
"executable": "^4.1.1",
"extract-zip": "2.0.1",
@@ -7321,6 +7366,12 @@
"node": ">=12.0.0"
}
},
+ "node_modules/cypress-wait-for-stable-dom": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/cypress-wait-for-stable-dom/-/cypress-wait-for-stable-dom-0.1.0.tgz",
+ "integrity": "sha512-iVJc6CDzlu1xUnTcZph+zbkOlImaDelpvRv4G+3naugvjkF6b9EFpDmRCC/16xL1pqpkFq4rFyfhuNw4C3PQjw==",
+ "dev": true
+ },
"node_modules/cypress/node_modules/@types/node": {
"version": "14.18.32",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.32.tgz",
@@ -7645,6 +7696,11 @@
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
},
+ "node_modules/diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
"node_modules/diff-sequences": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
@@ -8913,10 +8969,25 @@
"node": ">= 0.6"
}
},
+ "node_modules/event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
+ "dev": true,
+ "dependencies": {
+ "duplexer": "~0.1.1",
+ "from": "~0",
+ "map-stream": "~0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3",
+ "stream-combiner": "~0.0.4",
+ "through": "~2.3.1"
+ }
+ },
"node_modules/eventemitter2": {
- "version": "6.4.9",
- "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
- "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==",
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
+ "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==",
"dev": true
},
"node_modules/eventemitter3": {
@@ -9610,6 +9681,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true
+ },
"node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
@@ -12183,6 +12260,19 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/joi": {
+ "version": "17.7.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz",
+ "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==",
+ "dev": true,
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0",
+ "@hapi/topo": "^5.0.0",
+ "@sideway/address": "^4.1.3",
+ "@sideway/formula": "^3.0.0",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
"node_modules/jquery": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
@@ -12622,6 +12712,16 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -12805,6 +12905,12 @@
"tmpl": "1.0.5"
}
},
+ "node_modules/map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
+ "dev": true
+ },
"node_modules/mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@@ -13523,6 +13629,15 @@
"node": ">=8"
}
},
+ "node_modules/pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "dependencies": {
+ "through": "~2.3"
+ }
+ },
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -14984,6 +15099,21 @@
"integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
"dev": true
},
+ "node_modules/ps-tree": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
+ "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
+ "dev": true,
+ "dependencies": {
+ "event-stream": "=3.3.4"
+ },
+ "bin": {
+ "ps-tree": "bin/ps-tree.js"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/psl": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -15165,6 +15295,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "dependencies": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-app-polyfill": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz",
@@ -16678,6 +16824,18 @@
"wbuf": "^1.7.3"
}
},
+ "node_modules/split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
+ "dev": true,
+ "dependencies": {
+ "through": "2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -16738,6 +16896,90 @@
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="
},
+ "node_modules/start-server-and-test": {
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz",
+ "integrity": "sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==",
+ "dev": true,
+ "dependencies": {
+ "bluebird": "3.7.2",
+ "check-more-types": "2.24.0",
+ "debug": "4.3.2",
+ "execa": "5.1.1",
+ "lazy-ass": "1.6.0",
+ "ps-tree": "1.2.0",
+ "wait-on": "6.0.0"
+ },
+ "bin": {
+ "server-test": "src/bin/start.js",
+ "start-server-and-test": "src/bin/start.js",
+ "start-test": "src/bin/start.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/start-server-and-test/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/start-server-and-test/node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/start-server-and-test/node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/start-server-and-test/node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -16746,6 +16988,15 @@
"node": ">= 0.8"
}
},
+ "node_modules/stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
+ "dev": true,
+ "dependencies": {
+ "duplexer": "~0.1.1"
+ }
+ },
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -17877,6 +18128,34 @@
"node": ">=10"
}
},
+ "node_modules/wait-on": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz",
+ "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==",
+ "dev": true,
+ "dependencies": {
+ "axios": "^0.21.1",
+ "joi": "^17.4.0",
+ "lodash": "^4.17.21",
+ "minimist": "^1.2.5",
+ "rxjs": "^7.1.0"
+ },
+ "bin": {
+ "wait-on": "bin/wait-on"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/wait-on/node_modules/axios": {
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+ "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "dev": true,
+ "dependencies": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@@ -20410,6 +20689,21 @@
"tslib": "^2.1.0"
}
},
+ "@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+ "dev": true
+ },
+ "@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
"@humanwhocodes/config-array": {
"version": "0.9.5",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
@@ -20819,9 +21113,9 @@
}
},
"@kingsrook/qqq-frontend-core": {
- "version": "1.0.25",
- "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.25/03014325ceda54cd984e44e0f650f0eff81ab536",
- "integrity": "sha512-oO0ykxZnafzyomy8ZqZxiv5QVf0E5NIqvkXp2rUlNq44zt4Sx+93uMWl4IczcRCpbFpfaWxzpLxhdN/mjmMcUw==",
+ "version": "1.0.36",
+ "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.36/ddc9de26e08e365e999642619dacaaa290920370",
+ "integrity": "sha512-KC9Uj/1W87qxpBWLPe+hyJlPQiV43YAotguDUYkTytriNUhmSnTqVhyrC9crBxW4rj4+MX4IJXVFOqoh86A3Uw==",
"requires": {
"axios": "0.27.2",
"form-data": "4.0.0"
@@ -21201,6 +21495,27 @@
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
"integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg=="
},
+ "@sideway/address": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
+ "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/formula": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
+ "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
+ "dev": true
+ },
+ "@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+ "dev": true
+ },
"@sinclair/typebox": {
"version": "0.24.44",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz",
@@ -22211,6 +22526,11 @@
"negotiator": "0.6.3"
}
},
+ "ace-builds": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.12.3.tgz",
+ "integrity": "sha512-LHAsa5oOaRqmIlb8gBe81nj2kOqlfbV0XkWkFZL4mIfPXL4zoeTUcandHvBgHQCyjif3tGfoLTXelWSlnCT/dA=="
+ },
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@@ -23751,9 +24071,9 @@
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"cypress": {
- "version": "10.3.1",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.3.1.tgz",
- "integrity": "sha512-As9HrExjAgpgjCnbiQCuPdw5sWKx5HUJcK2EOKziu642akwufr/GUeqL5UnCPYXTyyibvEdWT/pSC2qnGW/e5w==",
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-11.0.1.tgz",
+ "integrity": "sha512-NuEfd0Vim492RJ3m/+bbTZ3OZrqXgfAfuLaZfIQ9D5lKocS3EDr2tyAarZdAhKwLyoh7OJ33jwMeMFIDbzYqog==",
"dev": true,
"requires": {
"@cypress/request": "^2.88.10",
@@ -23775,7 +24095,7 @@
"dayjs": "^1.10.4",
"debug": "^4.3.2",
"enquirer": "^2.3.6",
- "eventemitter2": "^6.4.3",
+ "eventemitter2": "6.4.7",
"execa": "4.1.0",
"executable": "^4.1.1",
"extract-zip": "2.0.1",
@@ -23838,6 +24158,12 @@
}
}
},
+ "cypress-wait-for-stable-dom": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/cypress-wait-for-stable-dom/-/cypress-wait-for-stable-dom-0.1.0.tgz",
+ "integrity": "sha512-iVJc6CDzlu1xUnTcZph+zbkOlImaDelpvRv4G+3naugvjkF6b9EFpDmRCC/16xL1pqpkFq4rFyfhuNw4C3PQjw==",
+ "dev": true
+ },
"damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -24038,6 +24364,11 @@
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
},
+ "diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
"diff-sequences": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
@@ -24957,10 +25288,25 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
},
+ "event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1",
+ "from": "~0",
+ "map-stream": "~0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3",
+ "stream-combiner": "~0.0.4",
+ "through": "~2.3.1"
+ }
+ },
"eventemitter2": {
- "version": "6.4.9",
- "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
- "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==",
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
+ "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==",
"dev": true
},
"eventemitter3": {
@@ -25481,6 +25827,12 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
},
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true
+ },
"fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
@@ -27359,6 +27711,19 @@
}
}
},
+ "joi": {
+ "version": "17.7.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz",
+ "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0",
+ "@hapi/topo": "^5.0.0",
+ "@sideway/address": "^4.1.3",
+ "@sideway/formula": "^3.0.0",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
"jquery": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
@@ -27706,6 +28071,16 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -27850,6 +28225,12 @@
"tmpl": "1.0.5"
}
},
+ "map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
+ "dev": true
+ },
"mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@@ -28358,6 +28739,15 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
},
+ "pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "requires": {
+ "through": "~2.3"
+ }
+ },
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -29240,6 +29630,15 @@
"integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
"dev": true
},
+ "ps-tree": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
+ "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
+ "dev": true,
+ "requires": {
+ "event-stream": "=3.3.4"
+ }
+ },
"psl": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -29377,6 +29776,18 @@
"object-assign": "^4.1.1"
}
},
+ "react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "requires": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ }
+ },
"react-app-polyfill": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz",
@@ -30536,6 +30947,15 @@
"wbuf": "^1.7.3"
}
},
+ "split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -30583,11 +31003,75 @@
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="
},
+ "start-server-and-test": {
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz",
+ "integrity": "sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.7.2",
+ "check-more-types": "2.24.0",
+ "debug": "4.3.2",
+ "execa": "5.1.1",
+ "lazy-ass": "1.6.0",
+ "ps-tree": "1.2.0",
+ "wait-on": "6.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true
+ }
+ }
+ },
"statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
},
+ "stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1"
+ }
+ },
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -31440,6 +31924,30 @@
"xml-name-validator": "^3.0.0"
}
},
+ "wait-on": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz",
+ "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==",
+ "dev": true,
+ "requires": {
+ "axios": "^0.21.1",
+ "joi": "^17.4.0",
+ "lodash": "^4.17.21",
+ "minimist": "^1.2.5",
+ "rxjs": "^7.1.0"
+ },
+ "dependencies": {
+ "axios": {
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+ "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "dev": true,
+ "requires": {
+ "follow-redirects": "^1.14.0"
+ }
+ }
+ }
+ },
"walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
diff --git a/package.json b/package.json
index 1b761c6..4aecab8 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"@fullcalendar/interaction": "5.10.0",
"@fullcalendar/react": "5.10.0",
"@fullcalendar/timegrid": "5.10.0",
- "@kingsrook/qqq-frontend-core": "1.0.35",
+ "@kingsrook/qqq-frontend-core": "1.0.36",
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
@@ -77,7 +77,8 @@
"prepublishOnly": "tsc -p ./ --outDir lib/",
"start": "BROWSER=none react-scripts start",
"test": "react-scripts test",
- "cypress:open": "cypress open"
+ "cypress:open": "cypress open",
+ "cypress:run": "cypress run"
},
"eslintConfig": {
"extends": [
@@ -105,7 +106,8 @@
"@types/uuid": "8.3.4",
"@typescript-eslint/eslint-plugin": "5.10.2",
"@typescript-eslint/parser": "5.10.2",
- "cypress": "10.3.1",
+ "cypress": "11.0.1",
+ "cypress-wait-for-stable-dom": "0.1.0",
"eslint": "8.8.0",
"eslint-config-airbnb": "19.0.4",
"eslint-import-resolver-typescript": "2.5.0",
diff --git a/src/App.tsx b/src/App.tsx
index 4e50dae..4510c97 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -23,6 +23,7 @@ import {useAuth0} from "@auth0/auth0-react";
import {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException";
import {QAppNodeType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppNodeType";
import {QAppTreeNode} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppTreeNode";
+import {QAuthenticationMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAuthenticationMetaData";
import {QBrandingMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QBrandingMetaData";
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
import CssBaseline from "@mui/material/CssBaseline";
@@ -86,6 +87,7 @@ function getStaticRoutes()
];
}
+const qController = QClient.getInstance();
export const SESSION_ID_COOKIE_NAME = "sessionId";
LicenseInfo.setLicenseKey(process.env.REACT_APP_MATERIAL_UI_LICENSE_KEY);
@@ -105,24 +107,51 @@ export default function App()
return;
}
setLoadingToken(true);
+
(async () =>
{
- try
+ const authenticationMetaData: QAuthenticationMetaData = await qController.getAuthenticationMetaData();
+
+ if (authenticationMetaData.type === "AUTH_0")
{
- console.log("Loading token...");
- await getAccessTokenSilently();
- const idToken = await getIdTokenClaims();
- setCookie(SESSION_ID_COOKIE_NAME, idToken.__raw, {path: "/"});
- setIsFullyAuthenticated(true);
- console.log("Token load complete.");
+ /////////////////////////////////////////
+ // use auth0 if auth type is ... auth0 //
+ /////////////////////////////////////////
+ try
+ {
+ console.log("Loading token...");
+ await getAccessTokenSilently();
+ const idToken = await getIdTokenClaims();
+ setCookie(SESSION_ID_COOKIE_NAME, idToken.__raw, {path: "/"});
+ setIsFullyAuthenticated(true);
+ console.log("Token load complete.");
+ }
+ catch (e)
+ {
+ console.log(`Error loading token: ${JSON.stringify(e)}`);
+ removeCookie(SESSION_ID_COOKIE_NAME);
+ qController.clearAuthenticationMetaDataLocalStorage();
+ logout();
+ return;
+ }
}
- catch (e)
+ else if (authenticationMetaData.type === "FULLY_ANONYMOUS" || authenticationMetaData.type === "MOCK")
{
- console.log(`Error loading token: ${JSON.stringify(e)}`);
- removeCookie(SESSION_ID_COOKIE_NAME);
- logout();
+ /////////////////////////////////////////////
+ // use a random token if anonymous or mock //
+ /////////////////////////////////////////////
+ console.log("Generating random token...");
+ setIsFullyAuthenticated(true);
+ setCookie(SESSION_ID_COOKIE_NAME, Md5.hashStr(`${new Date()}`), {path: "/"});
+ console.log("Token generation complete.");
return;
}
+ else
+ {
+ console.log(`Unrecognized authenticationMetaData.type: ${authenticationMetaData.type}`);
+ qController.clearAuthenticationMetaDataLocalStorage();
+ }
+
})();
}, [loadingToken]);
@@ -265,7 +294,7 @@ export default function App()
routeList.push({
name: `${app.label}`,
- key: `${app.name}.dev`,
+ key: `${app.name}.record.dev`,
route: `${path}/:id/dev`,
component: ,
});
@@ -342,13 +371,13 @@ export default function App()
let profileRoutes = {};
const gravatarBase = "https://www.gravatar.com/avatar/";
- const hash = Md5.hashStr(user.email);
+ const hash = Md5.hashStr(user?.email || "user");
const profilePicture = `${gravatarBase}${hash}`;
profileRoutes = {
type: "collapse",
- name: user.name,
- key: user.name,
- icon: ,
+ name: user?.name,
+ key: "username",
+ icon: ,
collapse: [
{
name: "My Profile",
@@ -388,11 +417,16 @@ export default function App()
}
catch (e)
{
+ console.error(e);
if (e instanceof QException)
{
if ((e as QException).message.indexOf("status code 401") !== -1)
{
removeCookie(SESSION_ID_COOKIE_NAME);
+
+ //////////////////////////////////////////////////////
+ // todo - this is auth0 logout... make more generic //
+ //////////////////////////////////////////////////////
logout();
return;
}
diff --git a/src/HandleAuthorizationError.tsx b/src/HandleAuthorizationError.tsx
index 0bedfa9..6f3556c 100644
--- a/src/HandleAuthorizationError.tsx
+++ b/src/HandleAuthorizationError.tsx
@@ -19,11 +19,10 @@
* along with this program. If not, see .
*/
-import {Auth0Provider, useAuth0} from "@auth0/auth0-react";
+import {useAuth0} from "@auth0/auth0-react";
import React, {useEffect} from "react";
import {useCookies} from "react-cookie";
import {SESSION_ID_COOKIE_NAME} from "App";
-import {AUTH0_CLIENT_ID, AUTH0_DOMAIN} from "index";
interface Props
{
@@ -44,11 +43,7 @@ function HandleAuthorizationError({errorMessage}: Props)
});
return (
-
-
-
+ {errorMessage}
);
}
diff --git a/src/index.tsx b/src/index.tsx
index 95ebc2a..8b07d3b 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -20,6 +20,7 @@
*/
import {Auth0Provider} from "@auth0/auth0-react";
+import {QAuthenticationMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAuthenticationMetaData";
import React from "react";
import {render} from "react-dom";
import {BrowserRouter, useNavigate, useSearchParams} from "react-router-dom";
@@ -28,52 +29,73 @@ import "qqq/styles/qqq-override-styles.css";
import {MaterialUIControllerProvider} from "context";
import HandleAuthorizationError from "HandleAuthorizationError";
import ProtectedRoute from "qqq/auth0/protected-route";
+import QClient from "qqq/utils/QClient";
-export const AUTH0_DOMAIN = process.env.REACT_APP_AUTH0_DOMAIN;
-export const AUTH0_CLIENT_ID = process.env.REACT_APP_AUTH0_CLIENT_ID;
+const qController = QClient.getInstance();
+const authenticationMetaDataPromise: Promise = qController.getAuthenticationMetaData()
-// @ts-ignore
-function Auth0ProviderWithRedirectCallback({children, ...props})
+authenticationMetaDataPromise.then((authenticationMetaData) =>
{
- const navigate = useNavigate();
- const [searchParams] = useSearchParams();
-
// @ts-ignore
- const onRedirectCallback = (appState) =>
+ function Auth0ProviderWithRedirectCallback({children, ...props})
{
- navigate((appState && appState.returnTo) || window.location.pathname);
- };
- if (searchParams.get("error"))
+ const navigate = useNavigate();
+ const [searchParams] = useSearchParams();
+
+ // @ts-ignore
+ const onRedirectCallback = (appState) =>
+ {
+ navigate((appState && appState.returnTo) || window.location.pathname);
+ };
+ if (searchParams.get("error"))
+ {
+ return (
+ // @ts-ignore
+
+
+
+ );
+ }
+ else
+ {
+ return (
+ // @ts-ignore
+
+ {children}
+
+ );
+ }
+ }
+
+ if (authenticationMetaData.type === "AUTH_0")
{
- return (
- // @ts-ignore
-
-
-
+ const domain = process.env.REACT_APP_AUTH0_DOMAIN;
+ const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID;
+
+ render(
+
+
+
+
+
+
+ ,
+ document.getElementById("root"),
);
}
else
{
- return (
- // @ts-ignore
-
- {children}
-
- );
+ render(
+
+
+
+
+
+ , document.getElementById("root"));
}
-}
-render(
-
-
-
-
-
-
- ,
- document.getElementById("root"),
-);
+})
diff --git a/src/qqq/pages/entity-list/EntityList.tsx b/src/qqq/pages/entity-list/EntityList.tsx
index 55ed266..bfcd30b 100644
--- a/src/qqq/pages/entity-list/EntityList.tsx
+++ b/src/qqq/pages/entity-list/EntityList.tsx
@@ -19,12 +19,9 @@
* along with this program. If not, see .
*/
-import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/AdornmentType";
import {Capability} from "@kingsrook/qqq-frontend-core/lib/model/metaData/Capability";
-import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
-import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
@@ -44,10 +41,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, getGridDateOperators, GridCallbackDetails, GridColDef, GridColumnOrderChangeParams, GridColumnVisibilityModel, GridDensity, GridEventListener, GridExportMenuItemProps, GridFilterModel, GridLinkOperator, 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 {GridFilterOperator} from "@mui/x-data-grid/models/gridFilterOperator";
+import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnOrderChangeParams, GridColumnVisibilityModel, GridDensity, GridEventListener, GridExportMenuItemProps, GridFilterModel, GridLinkOperator, 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 React, {useContext, useEffect, useReducer, useRef, useState} from "react";
-import {Link, useLocation, useNavigate, useSearchParams} from "react-router-dom";
+import {useLocation, useNavigate, useSearchParams} from "react-router-dom";
import QContext from "QContext";
import DashboardLayout from "qqq/components/DashboardLayout";
import Footer from "qqq/components/Footer";
@@ -55,7 +51,6 @@ import Navbar from "qqq/components/Navbar";
import {QActionsMenuButton, QCreateNewButton} from "qqq/components/QButtons";
import MDAlert from "qqq/components/Temporary/MDAlert";
import MDBox from "qqq/components/Temporary/MDBox";
-import {buildQGridPvsOperators, QGridBooleanOperators, QGridNumericOperators, QGridStringOperators} from "qqq/pages/entity-list/QGridFilterOperators";
import ProcessRun from "qqq/pages/process-run";
import DataGridUtils from "qqq/utils/DataGridUtils";
import QClient from "qqq/utils/QClient";
@@ -237,7 +232,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
const [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
const [launchingProcess, setLaunchingProcess] = useState(launchProcess);
- const [recordIdsForProcess, setRecordIdsForProcess] = useState(null as string | QQueryFilter)
+ const [recordIdsForProcess, setRecordIdsForProcess] = useState(null as string | QQueryFilter);
const instance = useRef({timer: null});
@@ -355,13 +350,26 @@ function EntityList({table, launchProcess}: Props): JSX.Element
return qFilter;
};
+ const getTableMetaData = async (): Promise =>
+ {
+ if(tableMetaData !== null)
+ {
+ return(new Promise((resolve) =>
+ {
+ resolve(tableMetaData)
+ }));
+ }
+
+ return (qController.loadTableMetaData(tableName));
+ }
+
const updateTable = () =>
{
setLoading(true);
setRows([]);
(async () =>
{
- const tableMetaData = await qController.loadTableMetaData(tableName);
+ const tableMetaData = await getTableMetaData();
setPageHeader(tableMetaData.label);
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -530,7 +538,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
const handlePinnedColumnsChange = (pinnedColumns: GridPinnedColumns) =>
{
- setPinnedColumns(pinnedColumns)
+ setPinnedColumns(pinnedColumns);
localStorage.setItem(pinnedColumnsLocalStorageKey, JSON.stringify(pinnedColumns));
};
@@ -1080,7 +1088,14 @@ function EntityList({table, launchProcess}: Props): JSX.Element
///////////////////////////////////////////////////////////////////////////////////////////
useEffect(() =>
{
- updateTable();
+ if(latestQueryId > 0)
+ {
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // to avoid both this useEffect and the one below from both doing an "initial query", //
+ // only run this one if at least 1 query has already been ran //
+ ////////////////////////////////////////////////////////////////////////////////////////
+ updateTable();
+ }
}, [ pageNumber, rowsPerPage, columnSortModel ]);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/qqq/utils/QClient.ts b/src/qqq/utils/QClient.ts
index aff6d58..96272f5 100644
--- a/src/qqq/utils/QClient.ts
+++ b/src/qqq/utils/QClient.ts
@@ -32,6 +32,7 @@ class QClient
private static handleException(exception: QException)
{
+ // todo - check for 401 and clear cookie et al & logout?
console.log(`Caught Exception: ${JSON.stringify(exception)}`);
throw (exception);
}
diff --git a/src/qqq/utils/QProcessUtils.ts b/src/qqq/utils/QProcessUtils.ts
index f7b2e6d..06e82a0 100644
--- a/src/qqq/utils/QProcessUtils.ts
+++ b/src/qqq/utils/QProcessUtils.ts
@@ -32,30 +32,36 @@ class QProcessUtils
public static getProcessesForTable(metaData: QInstance, tableName: string, includeHidden = false): QProcessMetaData[]
{
const matchingProcesses: QProcessMetaData[] = [];
- const processKeys = [...metaData.processes.keys()];
- processKeys.forEach((key) =>
+ if (metaData.processes)
{
- const process = metaData.processes.get(key);
- if (process.tableName === tableName && (includeHidden || !process.isHidden))
+ const processKeys = [...metaData.processes.keys()];
+ processKeys.forEach((key) =>
{
- matchingProcesses.push(process);
- }
- });
+ const process = metaData.processes.get(key);
+ if (process.tableName === tableName && (includeHidden || !process.isHidden))
+ {
+ matchingProcesses.push(process);
+ }
+ });
+ }
return matchingProcesses;
}
public static getReportsForTable(metaData: QInstance, tableName: string, includeHidden = false): QReportMetaData[]
{
const matchingReports: QReportMetaData[] = [];
- const reportKeys = [...metaData.reports.keys()];
- reportKeys.forEach((key) =>
+ if (metaData.reports)
{
- const process = metaData.reports.get(key);
- if (process.tableName === tableName)
+ const reportKeys = [...metaData.reports.keys()];
+ reportKeys.forEach((key) =>
{
- matchingReports.push(process);
- }
- });
+ const process = metaData.reports.get(key);
+ if (process.tableName === tableName)
+ {
+ matchingReports.push(process);
+ }
+ });
+ }
return matchingReports;
}