mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Checkpoint to get cypress working - auth-type from backend, less hard-coded auth0, improvements on query screen (less redundant fetches)
This commit is contained in:
1
cypress/.gitignore
vendored
Normal file
1
cypress/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
videos
|
105
cypress/e2e/entity-list.spec.cy.ts
Normal file
105
cypress/e2e/entity-list.spec.cy.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/// <reference types="cypress-wait-for-stable-dom" />
|
||||||
|
|
||||||
|
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");
|
||||||
|
cy.wait(["@personQuery", "@personCount"]);
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// 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();
|
||||||
|
cy.wait(["@personQuery", "@personCount"]);
|
||||||
|
cy.contains(".MuiDataGrid-toolbarContainer .MuiBadge-root", "1").should("not.exist");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
xit("todo delete", () =>
|
||||||
|
{
|
||||||
|
// 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"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -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"])
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
3
cypress/fixtures/data/city/count.json
Normal file
3
cypress/fixtures/data/city/count.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"count": 101406
|
||||||
|
}
|
2235876
cypress/fixtures/data/city/index.json
Normal file
2235876
cypress/fixtures/data/city/index.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"count": 5
|
"count": 101406
|
||||||
}
|
}
|
||||||
|
4
cypress/fixtures/metaData/authentication.json
Normal file
4
cypress/fixtures/metaData/authentication.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "mock",
|
||||||
|
"type": "MOCK"
|
||||||
|
}
|
@ -1,102 +1,550 @@
|
|||||||
{
|
{
|
||||||
"tables": {
|
"tables": {
|
||||||
"carrier": {
|
"carrier": {
|
||||||
"name": "carrier",
|
"name": "carrier",
|
||||||
"label": "Carrier",
|
"label": "Carrier",
|
||||||
"isHidden": false
|
"isHidden": false,
|
||||||
},
|
"iconName": "local_shipping",
|
||||||
"city": {
|
"capabilities": [
|
||||||
"name": "city",
|
"TABLE_COUNT",
|
||||||
"label": "Cities",
|
"TABLE_GET",
|
||||||
"isHidden": true
|
"TABLE_QUERY",
|
||||||
},
|
"TABLE_UPDATE",
|
||||||
"person": {
|
"TABLE_INSERT",
|
||||||
"name": "person",
|
"TABLE_DELETE"
|
||||||
"label": "Person",
|
]
|
||||||
"isHidden": false
|
},
|
||||||
}
|
"person": {
|
||||||
},
|
"name": "person",
|
||||||
"processes": {
|
"label": "Person",
|
||||||
"person.bulkInsert": {
|
"isHidden": false,
|
||||||
"name": "person.bulkInsert",
|
"iconName": "person",
|
||||||
"label": "Person Bulk Insert",
|
"capabilities": [
|
||||||
"tableName": "person",
|
"TABLE_COUNT",
|
||||||
"isHidden": true
|
"TABLE_GET",
|
||||||
},
|
"TABLE_QUERY",
|
||||||
"carrier.bulkInsert": {
|
"TABLE_UPDATE",
|
||||||
"name": "carrier.bulkInsert",
|
"TABLE_INSERT",
|
||||||
"label": "Carrier Bulk Insert",
|
"TABLE_DELETE"
|
||||||
"tableName": "carrier",
|
]
|
||||||
"isHidden": true
|
},
|
||||||
},
|
"city": {
|
||||||
"simpleSleep": {
|
"name": "city",
|
||||||
"name": "simpleSleep",
|
"label": "Cities",
|
||||||
"label": "Simple Sleep",
|
"isHidden": true,
|
||||||
"isHidden": true
|
"iconName": "location_city",
|
||||||
},
|
"capabilities": [
|
||||||
"carrier.bulkDelete": {
|
"TABLE_COUNT",
|
||||||
"name": "carrier.bulkDelete",
|
"TABLE_GET",
|
||||||
"label": "Carrier Bulk Delete",
|
"TABLE_QUERY",
|
||||||
"tableName": "carrier",
|
"TABLE_UPDATE",
|
||||||
"isHidden": true
|
"TABLE_INSERT",
|
||||||
},
|
"TABLE_DELETE"
|
||||||
"greet": {
|
]
|
||||||
"name": "greet",
|
}
|
||||||
"label": "Greet People",
|
},
|
||||||
"tableName": "person",
|
"processes": {
|
||||||
"isHidden": true
|
"greet": {
|
||||||
},
|
"name": "greet",
|
||||||
"city.bulkDelete": {
|
"label": "Greet People",
|
||||||
"name": "city.bulkDelete",
|
"tableName": "person",
|
||||||
"label": "Cities Bulk Delete",
|
"isHidden": true,
|
||||||
"tableName": "city",
|
"iconName": "emoji_people"
|
||||||
"isHidden": true
|
},
|
||||||
},
|
"greetInteractive": {
|
||||||
"person.bulkDelete": {
|
"name": "greetInteractive",
|
||||||
"name": "person.bulkDelete",
|
"label": "Greet Interactive",
|
||||||
"label": "Person Bulk Delete",
|
"tableName": "person",
|
||||||
"tableName": "person",
|
"isHidden": false,
|
||||||
"isHidden": true
|
"iconName": "waving_hand"
|
||||||
},
|
},
|
||||||
"carrier.bulkEdit": {
|
"clonePeople": {
|
||||||
"name": "carrier.bulkEdit",
|
"name": "clonePeople",
|
||||||
"label": "Carrier Bulk Edit",
|
"label": "Clone People",
|
||||||
"tableName": "carrier",
|
"tableName": "person",
|
||||||
"isHidden": true
|
"isHidden": false,
|
||||||
},
|
"iconName": "content_copy"
|
||||||
"person.bulkEdit": {
|
},
|
||||||
"name": "person.bulkEdit",
|
"simpleSleep": {
|
||||||
"label": "Person Bulk Edit",
|
"name": "simpleSleep",
|
||||||
"tableName": "person",
|
"label": "Simple Sleep",
|
||||||
"isHidden": true
|
"isHidden": true
|
||||||
},
|
},
|
||||||
"greetInteractive": {
|
"sleepInteractive": {
|
||||||
"name": "greetInteractive",
|
"name": "sleepInteractive",
|
||||||
"label": "Greet Interactive",
|
"label": "Sleep Interactive",
|
||||||
"tableName": "person",
|
"isHidden": false
|
||||||
"isHidden": false
|
},
|
||||||
},
|
"simpleThrow": {
|
||||||
"city.bulkEdit": {
|
"name": "simpleThrow",
|
||||||
"name": "city.bulkEdit",
|
"label": "Simple Throw",
|
||||||
"label": "Cities Bulk Edit",
|
"isHidden": false
|
||||||
"tableName": "city",
|
},
|
||||||
"isHidden": true
|
"carrier.bulkInsert": {
|
||||||
},
|
"name": "carrier.bulkInsert",
|
||||||
"simpleThrow": {
|
"label": "Carrier Bulk Insert",
|
||||||
"name": "simpleThrow",
|
"tableName": "carrier",
|
||||||
"label": "Simple Throw",
|
"isHidden": true
|
||||||
"isHidden": false
|
},
|
||||||
},
|
"carrier.bulkEdit": {
|
||||||
"sleepInteractive": {
|
"name": "carrier.bulkEdit",
|
||||||
"name": "sleepInteractive",
|
"label": "Carrier Bulk Edit",
|
||||||
"label": "Sleep Interactive",
|
"tableName": "carrier",
|
||||||
"isHidden": false
|
"isHidden": true
|
||||||
},
|
},
|
||||||
"city.bulkInsert": {
|
"carrier.bulkDelete": {
|
||||||
"name": "city.bulkInsert",
|
"name": "carrier.bulkDelete",
|
||||||
"label": "Cities Bulk Insert",
|
"label": "Carrier Bulk Delete",
|
||||||
"tableName": "city",
|
"tableName": "carrier",
|
||||||
"isHidden": true
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
"backendName": "first_name",
|
"backendName": "first_name",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"isRequired": true,
|
"isRequired": true,
|
||||||
"isEditable": true
|
"isEditable": true,
|
||||||
|
"displayFormat": "%s"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lastName",
|
"name": "lastName",
|
||||||
@ -35,7 +36,8 @@
|
|||||||
"backendName": "last_name",
|
"backendName": "last_name",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"isRequired": true,
|
"isRequired": true,
|
||||||
"isEditable": true
|
"isEditable": true,
|
||||||
|
"displayFormat": "%s"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "birthDate",
|
"name": "birthDate",
|
||||||
@ -43,14 +45,44 @@
|
|||||||
"backendName": "birth_date",
|
"backendName": "birth_date",
|
||||||
"type": "DATE",
|
"type": "DATE",
|
||||||
"isRequired": false,
|
"isRequired": false,
|
||||||
"isEditable": true
|
"isEditable": true,
|
||||||
|
"displayFormat": "%s"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "email",
|
"name": "email",
|
||||||
"label": "Email",
|
"label": "Email",
|
||||||
|
"backendName": "email",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"isRequired": false,
|
"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",
|
"stepType": "frontend",
|
||||||
"components": [
|
"components": [
|
||||||
{
|
{
|
||||||
"type": "HELP_TEXT",
|
"type": "VALIDATION_REVIEW_SCREEN"
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"recordListFields": [
|
"recordListFields": [
|
||||||
@ -82,7 +102,8 @@
|
|||||||
"backendName": "first_name",
|
"backendName": "first_name",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"isRequired": true,
|
"isRequired": true,
|
||||||
"isEditable": true
|
"isEditable": true,
|
||||||
|
"displayFormat": "%s"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lastName",
|
"name": "lastName",
|
||||||
@ -90,7 +111,8 @@
|
|||||||
"backendName": "last_name",
|
"backendName": "last_name",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"isRequired": true,
|
"isRequired": true,
|
||||||
"isEditable": true
|
"isEditable": true,
|
||||||
|
"displayFormat": "%s"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "birthDate",
|
"name": "birthDate",
|
||||||
@ -98,83 +120,54 @@
|
|||||||
"backendName": "birth_date",
|
"backendName": "birth_date",
|
||||||
"type": "DATE",
|
"type": "DATE",
|
||||||
"isRequired": false,
|
"isRequired": false,
|
||||||
"isEditable": true
|
"isEditable": true,
|
||||||
|
"displayFormat": "%s"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "email",
|
"name": "email",
|
||||||
"label": "Email",
|
"label": "Email",
|
||||||
|
"backendName": "email",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"isRequired": false,
|
"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",
|
"name": "result",
|
||||||
"label": "Results",
|
"label": "Result",
|
||||||
"stepType": "frontend",
|
"stepType": "frontend",
|
||||||
"components": [
|
"components": [
|
||||||
{
|
{
|
||||||
"type": "HELP_TEXT",
|
"type": "PROCESS_SUMMARY_RESULTS"
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
155
cypress/fixtures/metaData/table/person.json
Normal file
155
cypress/fixtures/metaData/table/person.json
Normal file
@ -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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
3
cypress/fixtures/processes/person.bulkEdit/records.json
Normal file
3
cypress/fixtures/processes/person.bulkEdit/records.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[
|
||||||
|
{}
|
||||||
|
]
|
1
cypress/fixtures/widget/empty.json
Normal file
1
cypress/fixtures/widget/empty.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
@ -35,3 +35,7 @@
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
import {registerCommand} from "cypress-wait-for-stable-dom";
|
||||||
|
|
||||||
|
registerCommand({pollInterval: 100, timeout: 3000});
|
||||||
|
Binary file not shown.
@ -13,7 +13,7 @@
|
|||||||
"@fullcalendar/interaction": "5.10.0",
|
"@fullcalendar/interaction": "5.10.0",
|
||||||
"@fullcalendar/react": "5.10.0",
|
"@fullcalendar/react": "5.10.0",
|
||||||
"@fullcalendar/timegrid": "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/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.4.1",
|
"@mui/material": "5.4.1",
|
||||||
"@mui/styled-engine": "5.4.1",
|
"@mui/styled-engine": "5.4.1",
|
||||||
@ -105,7 +105,8 @@
|
|||||||
"@types/uuid": "8.3.4",
|
"@types/uuid": "8.3.4",
|
||||||
"@typescript-eslint/eslint-plugin": "5.10.2",
|
"@typescript-eslint/eslint-plugin": "5.10.2",
|
||||||
"@typescript-eslint/parser": "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": "8.8.0",
|
||||||
"eslint-config-airbnb": "19.0.4",
|
"eslint-config-airbnb": "19.0.4",
|
||||||
"eslint-import-resolver-typescript": "2.5.0",
|
"eslint-import-resolver-typescript": "2.5.0",
|
||||||
|
66
src/App.tsx
66
src/App.tsx
@ -23,6 +23,7 @@ import {useAuth0} from "@auth0/auth0-react";
|
|||||||
import {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException";
|
import {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException";
|
||||||
import {QAppNodeType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppNodeType";
|
import {QAppNodeType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppNodeType";
|
||||||
import {QAppTreeNode} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppTreeNode";
|
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 {QBrandingMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QBrandingMetaData";
|
||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||||
import CssBaseline from "@mui/material/CssBaseline";
|
import CssBaseline from "@mui/material/CssBaseline";
|
||||||
@ -86,6 +87,7 @@ function getStaticRoutes()
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const qController = QClient.getInstance();
|
||||||
export const SESSION_ID_COOKIE_NAME = "sessionId";
|
export const SESSION_ID_COOKIE_NAME = "sessionId";
|
||||||
LicenseInfo.setLicenseKey(process.env.REACT_APP_MATERIAL_UI_LICENSE_KEY);
|
LicenseInfo.setLicenseKey(process.env.REACT_APP_MATERIAL_UI_LICENSE_KEY);
|
||||||
|
|
||||||
@ -105,24 +107,51 @@ export default function App()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoadingToken(true);
|
setLoadingToken(true);
|
||||||
|
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
try
|
const authenticationMetaData: QAuthenticationMetaData = await qController.getAuthenticationMetaData();
|
||||||
|
|
||||||
|
if (authenticationMetaData.type === "AUTH_0")
|
||||||
{
|
{
|
||||||
console.log("Loading token...");
|
/////////////////////////////////////////
|
||||||
await getAccessTokenSilently();
|
// use auth0 if auth type is ... auth0 //
|
||||||
const idToken = await getIdTokenClaims();
|
/////////////////////////////////////////
|
||||||
setCookie(SESSION_ID_COOKIE_NAME, idToken.__raw, {path: "/"});
|
try
|
||||||
setIsFullyAuthenticated(true);
|
{
|
||||||
console.log("Token load complete.");
|
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);
|
// use a random token if anonymous or mock //
|
||||||
logout();
|
/////////////////////////////////////////////
|
||||||
|
console.log("Generating random token...");
|
||||||
|
setIsFullyAuthenticated(true);
|
||||||
|
setCookie(SESSION_ID_COOKIE_NAME, Md5.hashStr(`${new Date()}`), {path: "/"});
|
||||||
|
console.log("Token generation complete.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log(`Unrecognized authenticationMetaData.type: ${authenticationMetaData.type}`);
|
||||||
|
qController.clearAuthenticationMetaDataLocalStorage();
|
||||||
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
}, [loadingToken]);
|
}, [loadingToken]);
|
||||||
|
|
||||||
@ -265,7 +294,7 @@ export default function App()
|
|||||||
|
|
||||||
routeList.push({
|
routeList.push({
|
||||||
name: `${app.label}`,
|
name: `${app.label}`,
|
||||||
key: `${app.name}.dev`,
|
key: `${app.name}.record.dev`,
|
||||||
route: `${path}/:id/dev`,
|
route: `${path}/:id/dev`,
|
||||||
component: <EntityDeveloperView table={table} />,
|
component: <EntityDeveloperView table={table} />,
|
||||||
});
|
});
|
||||||
@ -342,13 +371,13 @@ export default function App()
|
|||||||
|
|
||||||
let profileRoutes = {};
|
let profileRoutes = {};
|
||||||
const gravatarBase = "https://www.gravatar.com/avatar/";
|
const gravatarBase = "https://www.gravatar.com/avatar/";
|
||||||
const hash = Md5.hashStr(user.email);
|
const hash = Md5.hashStr(user?.email || "user");
|
||||||
const profilePicture = `${gravatarBase}${hash}`;
|
const profilePicture = `${gravatarBase}${hash}`;
|
||||||
profileRoutes = {
|
profileRoutes = {
|
||||||
type: "collapse",
|
type: "collapse",
|
||||||
name: user.name,
|
name: user?.name,
|
||||||
key: user.name,
|
key: "username",
|
||||||
icon: <MDAvatar src={profilePicture} alt="{user.name}" size="sm" />,
|
icon: <MDAvatar src={profilePicture} alt="{user?.name}" size="sm" />,
|
||||||
collapse: [
|
collapse: [
|
||||||
{
|
{
|
||||||
name: "My Profile",
|
name: "My Profile",
|
||||||
@ -388,11 +417,16 @@ export default function App()
|
|||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
|
console.error(e);
|
||||||
if (e instanceof QException)
|
if (e instanceof QException)
|
||||||
{
|
{
|
||||||
if ((e as QException).message.indexOf("status code 401") !== -1)
|
if ((e as QException).message.indexOf("status code 401") !== -1)
|
||||||
{
|
{
|
||||||
removeCookie(SESSION_ID_COOKIE_NAME);
|
removeCookie(SESSION_ID_COOKIE_NAME);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// todo - this is auth0 logout... make more generic //
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
logout();
|
logout();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Auth0Provider, useAuth0} from "@auth0/auth0-react";
|
import {useAuth0} from "@auth0/auth0-react";
|
||||||
import React, {useEffect} from "react";
|
import React, {useEffect} from "react";
|
||||||
import {useCookies} from "react-cookie";
|
import {useCookies} from "react-cookie";
|
||||||
import {SESSION_ID_COOKIE_NAME} from "App";
|
import {SESSION_ID_COOKIE_NAME} from "App";
|
||||||
import {AUTH0_CLIENT_ID, AUTH0_DOMAIN} from "index";
|
|
||||||
|
|
||||||
interface Props
|
interface Props
|
||||||
{
|
{
|
||||||
@ -44,11 +43,7 @@ function HandleAuthorizationError({errorMessage}: Props)
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Auth0Provider domain={AUTH0_DOMAIN} clientId={AUTH0_CLIENT_ID}>
|
<div>{errorMessage}</div>
|
||||||
<div>
|
|
||||||
<div>{errorMessage}</div>
|
|
||||||
</div>
|
|
||||||
</Auth0Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Auth0Provider} from "@auth0/auth0-react";
|
import {Auth0Provider} from "@auth0/auth0-react";
|
||||||
|
import {QAuthenticationMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAuthenticationMetaData";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {render} from "react-dom";
|
import {render} from "react-dom";
|
||||||
import {BrowserRouter, useNavigate, useSearchParams} from "react-router-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 {MaterialUIControllerProvider} from "context";
|
||||||
import HandleAuthorizationError from "HandleAuthorizationError";
|
import HandleAuthorizationError from "HandleAuthorizationError";
|
||||||
import ProtectedRoute from "qqq/auth0/protected-route";
|
import ProtectedRoute from "qqq/auth0/protected-route";
|
||||||
|
import QClient from "qqq/utils/QClient";
|
||||||
|
|
||||||
export const AUTH0_DOMAIN = process.env.REACT_APP_AUTH0_DOMAIN;
|
const qController = QClient.getInstance();
|
||||||
export const AUTH0_CLIENT_ID = process.env.REACT_APP_AUTH0_CLIENT_ID;
|
const authenticationMetaDataPromise: Promise<QAuthenticationMetaData> = qController.getAuthenticationMetaData()
|
||||||
|
|
||||||
// @ts-ignore
|
authenticationMetaDataPromise.then((authenticationMetaData) =>
|
||||||
function Auth0ProviderWithRedirectCallback({children, ...props})
|
|
||||||
{
|
{
|
||||||
const navigate = useNavigate();
|
|
||||||
const [searchParams] = useSearchParams();
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const onRedirectCallback = (appState) =>
|
function Auth0ProviderWithRedirectCallback({children, ...props})
|
||||||
{
|
{
|
||||||
navigate((appState && appState.returnTo) || window.location.pathname);
|
const navigate = useNavigate();
|
||||||
};
|
const [searchParams] = useSearchParams();
|
||||||
if (searchParams.get("error"))
|
|
||||||
|
// @ts-ignore
|
||||||
|
const onRedirectCallback = (appState) =>
|
||||||
|
{
|
||||||
|
navigate((appState && appState.returnTo) || window.location.pathname);
|
||||||
|
};
|
||||||
|
if (searchParams.get("error"))
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
// @ts-ignore
|
||||||
|
<Auth0Provider {...props}>
|
||||||
|
<HandleAuthorizationError errorMessage={searchParams.get("error_description")} />
|
||||||
|
</Auth0Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
// @ts-ignore
|
||||||
|
<Auth0Provider onRedirectCallback={onRedirectCallback} {...props}>
|
||||||
|
{children}
|
||||||
|
</Auth0Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authenticationMetaData.type === "AUTH_0")
|
||||||
{
|
{
|
||||||
return (
|
const domain = process.env.REACT_APP_AUTH0_DOMAIN;
|
||||||
// @ts-ignore
|
const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID;
|
||||||
<Auth0Provider {...props}>
|
|
||||||
<HandleAuthorizationError errorMessage={searchParams.get("error_description")} />
|
render(
|
||||||
</Auth0Provider>
|
<BrowserRouter>
|
||||||
|
<Auth0ProviderWithRedirectCallback
|
||||||
|
domain={domain}
|
||||||
|
clientId={clientId}
|
||||||
|
redirectUri={`${window.location.origin}/dashboards/overview`}
|
||||||
|
>
|
||||||
|
<MaterialUIControllerProvider>
|
||||||
|
<ProtectedRoute component={App} />
|
||||||
|
</MaterialUIControllerProvider>
|
||||||
|
</Auth0ProviderWithRedirectCallback>
|
||||||
|
</BrowserRouter>,
|
||||||
|
document.getElementById("root"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (
|
render(
|
||||||
// @ts-ignore
|
<BrowserRouter>
|
||||||
<Auth0Provider onRedirectCallback={onRedirectCallback} {...props}>
|
<MaterialUIControllerProvider>
|
||||||
{children}
|
<App />
|
||||||
</Auth0Provider>
|
</MaterialUIControllerProvider>
|
||||||
);
|
</BrowserRouter>
|
||||||
|
, document.getElementById("root"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
render(
|
})
|
||||||
<BrowserRouter>
|
|
||||||
<Auth0ProviderWithRedirectCallback
|
|
||||||
domain={AUTH0_DOMAIN}
|
|
||||||
clientId={AUTH0_CLIENT_ID}
|
|
||||||
redirectUri={`${window.location.origin}/dashboards/overview`}
|
|
||||||
>
|
|
||||||
<MaterialUIControllerProvider>
|
|
||||||
<ProtectedRoute component={App} />
|
|
||||||
</MaterialUIControllerProvider>
|
|
||||||
</Auth0ProviderWithRedirectCallback>
|
|
||||||
</BrowserRouter>,
|
|
||||||
document.getElementById("root"),
|
|
||||||
);
|
|
||||||
|
@ -19,12 +19,9 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/AdornmentType";
|
|
||||||
import {Capability} from "@kingsrook/qqq-frontend-core/lib/model/metaData/Capability";
|
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 {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
||||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
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 {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
|
||||||
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
|
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
|
||||||
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
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 MenuItem from "@mui/material/MenuItem";
|
||||||
import Modal from "@mui/material/Modal";
|
import Modal from "@mui/material/Modal";
|
||||||
import Tooltip from "@mui/material/Tooltip";
|
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 {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 {GridFilterOperator} from "@mui/x-data-grid/models/gridFilterOperator";
|
|
||||||
import React, {useContext, useEffect, useReducer, useRef, useState} from "react";
|
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 QContext from "QContext";
|
||||||
import DashboardLayout from "qqq/components/DashboardLayout";
|
import DashboardLayout from "qqq/components/DashboardLayout";
|
||||||
import Footer from "qqq/components/Footer";
|
import Footer from "qqq/components/Footer";
|
||||||
@ -55,7 +51,6 @@ import Navbar from "qqq/components/Navbar";
|
|||||||
import {QActionsMenuButton, QCreateNewButton} from "qqq/components/QButtons";
|
import {QActionsMenuButton, QCreateNewButton} from "qqq/components/QButtons";
|
||||||
import MDAlert from "qqq/components/Temporary/MDAlert";
|
import MDAlert from "qqq/components/Temporary/MDAlert";
|
||||||
import MDBox from "qqq/components/Temporary/MDBox";
|
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 ProcessRun from "qqq/pages/process-run";
|
||||||
import DataGridUtils from "qqq/utils/DataGridUtils";
|
import DataGridUtils from "qqq/utils/DataGridUtils";
|
||||||
import QClient from "qqq/utils/QClient";
|
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 [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
|
||||||
const [launchingProcess, setLaunchingProcess] = useState(launchProcess);
|
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});
|
const instance = useRef({timer: null});
|
||||||
|
|
||||||
@ -355,13 +350,26 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
|||||||
return qFilter;
|
return qFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTableMetaData = async (): Promise<QTableMetaData> =>
|
||||||
|
{
|
||||||
|
if(tableMetaData !== null)
|
||||||
|
{
|
||||||
|
return(new Promise((resolve) =>
|
||||||
|
{
|
||||||
|
resolve(tableMetaData)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (qController.loadTableMetaData(tableName));
|
||||||
|
}
|
||||||
|
|
||||||
const updateTable = () =>
|
const updateTable = () =>
|
||||||
{
|
{
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setRows([]);
|
setRows([]);
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const tableMetaData = await qController.loadTableMetaData(tableName);
|
const tableMetaData = await getTableMetaData();
|
||||||
setPageHeader(tableMetaData.label);
|
setPageHeader(tableMetaData.label);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -530,7 +538,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
|||||||
|
|
||||||
const handlePinnedColumnsChange = (pinnedColumns: GridPinnedColumns) =>
|
const handlePinnedColumnsChange = (pinnedColumns: GridPinnedColumns) =>
|
||||||
{
|
{
|
||||||
setPinnedColumns(pinnedColumns)
|
setPinnedColumns(pinnedColumns);
|
||||||
localStorage.setItem(pinnedColumnsLocalStorageKey, JSON.stringify(pinnedColumns));
|
localStorage.setItem(pinnedColumnsLocalStorageKey, JSON.stringify(pinnedColumns));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1080,7 +1088,14 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
useEffect(() =>
|
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 ]);
|
}, [ pageNumber, rowsPerPage, columnSortModel ]);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -32,6 +32,7 @@ class QClient
|
|||||||
|
|
||||||
private static handleException(exception: QException)
|
private static handleException(exception: QException)
|
||||||
{
|
{
|
||||||
|
// todo - check for 401 and clear cookie et al & logout?
|
||||||
console.log(`Caught Exception: ${JSON.stringify(exception)}`);
|
console.log(`Caught Exception: ${JSON.stringify(exception)}`);
|
||||||
throw (exception);
|
throw (exception);
|
||||||
}
|
}
|
||||||
|
@ -32,30 +32,36 @@ class QProcessUtils
|
|||||||
public static getProcessesForTable(metaData: QInstance, tableName: string, includeHidden = false): QProcessMetaData[]
|
public static getProcessesForTable(metaData: QInstance, tableName: string, includeHidden = false): QProcessMetaData[]
|
||||||
{
|
{
|
||||||
const matchingProcesses: QProcessMetaData[] = [];
|
const matchingProcesses: QProcessMetaData[] = [];
|
||||||
const processKeys = [...metaData.processes.keys()];
|
if (metaData.processes)
|
||||||
processKeys.forEach((key) =>
|
|
||||||
{
|
{
|
||||||
const process = metaData.processes.get(key);
|
const processKeys = [...metaData.processes.keys()];
|
||||||
if (process.tableName === tableName && (includeHidden || !process.isHidden))
|
processKeys.forEach((key) =>
|
||||||
{
|
{
|
||||||
matchingProcesses.push(process);
|
const process = metaData.processes.get(key);
|
||||||
}
|
if (process.tableName === tableName && (includeHidden || !process.isHidden))
|
||||||
});
|
{
|
||||||
|
matchingProcesses.push(process);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return matchingProcesses;
|
return matchingProcesses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getReportsForTable(metaData: QInstance, tableName: string, includeHidden = false): QReportMetaData[]
|
public static getReportsForTable(metaData: QInstance, tableName: string, includeHidden = false): QReportMetaData[]
|
||||||
{
|
{
|
||||||
const matchingReports: QReportMetaData[] = [];
|
const matchingReports: QReportMetaData[] = [];
|
||||||
const reportKeys = [...metaData.reports.keys()];
|
if (metaData.reports)
|
||||||
reportKeys.forEach((key) =>
|
|
||||||
{
|
{
|
||||||
const process = metaData.reports.get(key);
|
const reportKeys = [...metaData.reports.keys()];
|
||||||
if (process.tableName === tableName)
|
reportKeys.forEach((key) =>
|
||||||
{
|
{
|
||||||
matchingReports.push(process);
|
const process = metaData.reports.get(key);
|
||||||
}
|
if (process.tableName === tableName)
|
||||||
});
|
{
|
||||||
|
matchingReports.push(process);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return matchingReports;
|
return matchingReports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user