mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 12:50:43 +00:00
the missing selenium test for the report setup screen from last sprint
This commit is contained in:
@ -261,9 +261,7 @@ public class QueryScreenLib
|
||||
if(StringUtils.hasContent(value))
|
||||
{
|
||||
qSeleniumLib.waitForSelector(".filterValuesColumn INPUT").click();
|
||||
// todo - no, not in a listbox/LI here...
|
||||
qSeleniumLib.waitForSelectorContaining(".MuiAutocomplete-listbox LI", value).click();
|
||||
System.out.println(value);
|
||||
qSeleniumLib.waitForSelector(".filterValuesColumn INPUT").sendKeys(value);
|
||||
}
|
||||
|
||||
qSeleniumLib.clickBackdrop();
|
||||
@ -271,6 +269,21 @@ public class QueryScreenLib
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setBasicBooleanFilter(String fieldLabel, String operatorLabel)
|
||||
{
|
||||
qSeleniumLib.waitForSelectorContaining("BUTTON", fieldLabel).click();
|
||||
qSeleniumLib.waitForMillis(250);
|
||||
qSeleniumLib.waitForSelector("#criteriaOperator").click();
|
||||
qSeleniumLib.waitForSelectorContaining("LI", operatorLabel).click();
|
||||
|
||||
qSeleniumLib.clickBackdrop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.frontend.materialdashboard.selenium.tests;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.frontend.materialdashboard.selenium.lib.QBaseSeleniumTest;
|
||||
import com.kingsrook.qqq.frontend.materialdashboard.selenium.lib.QSeleniumLib;
|
||||
import com.kingsrook.qqq.frontend.materialdashboard.selenium.lib.QueryScreenLib;
|
||||
import com.kingsrook.qqq.frontend.materialdashboard.selenium.lib.javalin.QSeleniumJavalin;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.Keys;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Test for Saved Report screen (table has some special behaviors)
|
||||
*******************************************************************************/
|
||||
public class SavedReportTest extends QBaseSeleniumTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
protected void addJavalinRoutes(QSeleniumJavalin qSeleniumJavalin)
|
||||
{
|
||||
super.addJavalinRoutes(qSeleniumJavalin);
|
||||
qSeleniumJavalin
|
||||
.withRouteToFile("/metaData/table/savedReport", "metaData/table/savedReport.json")
|
||||
.withRouteToFile("/widget/reportSetupWidget", "widget/reportSetupWidget.json")
|
||||
.withRouteToFile("/widget/pivotTableSetupWidget", "widget/pivotTableSetupWidget.json")
|
||||
.withRouteToFile("/data/savedReport/possibleValues/tableName", "data/savedReport/possibleValues/tableName.json")
|
||||
|
||||
.withRouteToFile("/data/person/count", "data/person/count.json")
|
||||
.withRouteToFile("/data/person/query", "data/person/index.json")
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testCreate()
|
||||
{
|
||||
qSeleniumLib.gotoAndWaitForBreadcrumbHeaderToContain("/userCustomizations/savedReport/create", "Creating New Saved Report");
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// make sure things are disabled before a table is selected //
|
||||
//////////////////////////////////////////////////////////////
|
||||
WebElement webElement = qSeleniumLib.waitForSelectorContaining("button", "Edit Filters and Columns");
|
||||
assertEquals("true", webElement.getAttribute("disabled"));
|
||||
|
||||
qSeleniumLib.waitForSelector("#label").click();
|
||||
qSeleniumLib.waitForSelector("#label").sendKeys("My Report");
|
||||
|
||||
qSeleniumLib.waitForSelector("#tableName").click();
|
||||
qSeleniumLib.waitForSelector("#tableName").sendKeys("Person" + Keys.DOWN + Keys.ENTER);
|
||||
|
||||
//////////////////////////////////
|
||||
// make sure things enabled now //
|
||||
//////////////////////////////////
|
||||
webElement = qSeleniumLib.waitForSelectorContaining("button", "Edit Filters and Columns");
|
||||
assertNull(webElement.getAttribute("disabled"));
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// open query-screen popup, wait for query to run //
|
||||
////////////////////////////////////////////////////
|
||||
qSeleniumJavalin.beginCapture();
|
||||
qSeleniumLib.waitForSelectorContaining("button", "Edit Filters and Columns").click();
|
||||
qSeleniumJavalin.waitForCapturedPath("/data/person/count");
|
||||
qSeleniumJavalin.waitForCapturedPath("/data/person/query");
|
||||
qSeleniumJavalin.endCapture();
|
||||
|
||||
QueryScreenLib queryScreenLib = new QueryScreenLib(qSeleniumLib);
|
||||
queryScreenLib.setBasicFilter("First Name", "contains", "Darin");
|
||||
|
||||
////////////////////////
|
||||
// close query screen //
|
||||
////////////////////////
|
||||
qSeleniumLib.waitForSelectorContaining("button", "OK").click();
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// make sure query things appear on edit screen now //
|
||||
//////////////////////////////////////////////////////
|
||||
qSeleniumLib.waitForSelectorContaining(".advancedQueryString", "First Name");
|
||||
qSeleniumLib.waitForSelectorContaining(".advancedQueryString", "contains");
|
||||
qSeleniumLib.waitForSelectorContaining(".advancedQueryString", "Darin");
|
||||
List<WebElement> columns = qSeleniumLib.waitForSelectorContaining("h5", "Columns")
|
||||
.findElement(QSeleniumLib.PARENT)
|
||||
.findElements(By.cssSelector("DIV"));
|
||||
|
||||
assertThat(columns)
|
||||
.hasSizeGreaterThanOrEqualTo(5) // at least this many
|
||||
.anyMatch(we -> we.getText().equals("Home City")); // a few fields are found
|
||||
|
||||
///////////////////
|
||||
// turn on pivot //
|
||||
///////////////////
|
||||
qSeleniumLib.waitForSelectorContaining("label", "Use Pivot Table").click();
|
||||
qSeleniumLib.waitForSelectorContaining("button", "Edit Pivot Table").click();
|
||||
qSeleniumLib.waitForSelectorContaining("h3", "Edit Pivot Table");
|
||||
|
||||
///////////////
|
||||
// add a row //
|
||||
///////////////
|
||||
qSeleniumLib.waitForSelectorContaining(".MuiModal-root button", "Add new row").click();
|
||||
WebElement row0Input = qSeleniumLib.waitForSelector("#rows-0");
|
||||
row0Input.click();
|
||||
row0Input.sendKeys("Last Name" + Keys.ENTER);
|
||||
|
||||
//////////////////
|
||||
// add a column //
|
||||
//////////////////
|
||||
qSeleniumLib.waitForSelectorContaining(".MuiModal-root button", "Add new column").click();
|
||||
WebElement column0Input = qSeleniumLib.waitForSelector("#columns-0");
|
||||
column0Input.click();
|
||||
column0Input.sendKeys("Home City" + Keys.ENTER);
|
||||
|
||||
/////////////////
|
||||
// add a value //
|
||||
/////////////////
|
||||
qSeleniumLib.waitForSelectorContaining(".MuiModal-root button", "Add new value").click();
|
||||
WebElement value0Input = qSeleniumLib.waitForSelector("#values-field-0");
|
||||
value0Input.click();
|
||||
value0Input.sendKeys("Id" + Keys.ENTER);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// try to submit - but expect an error //
|
||||
/////////////////////////////////////////
|
||||
qSeleniumLib.waitForSelectorContaining("button", "OK").click();
|
||||
qSeleniumLib.waitForSelectorContaining(".MuiAlert-standard", "Missing value in 1 field.").click();
|
||||
|
||||
///////////////////////////
|
||||
// now select a function //
|
||||
///////////////////////////
|
||||
WebElement function0Input = qSeleniumLib.waitForSelector("#values-function-0");
|
||||
function0Input.click();
|
||||
function0Input.sendKeys("Count" + Keys.ENTER);
|
||||
|
||||
qSeleniumLib.waitForSelectorContaining("button", "OK").click();
|
||||
qSeleniumLib.waitForSelectorContainingToNotExist("h3", "Edit Pivot Table");
|
||||
|
||||
// qSeleniumLib.waitForever();
|
||||
}
|
||||
|
||||
}
|
@ -153,16 +153,16 @@ public class QueryScreenTest extends QBaseSeleniumTest
|
||||
|
||||
queryScreenLib.addBasicFilter("Is Employed");
|
||||
|
||||
testBasicCriteria(queryScreenLib, "Is Employed", "equals yes", null, "(?s).*Is Employed:.*yes.*", """
|
||||
testBasicBooleanCriteria(queryScreenLib, "Is Employed", "equals yes", "(?s).*Is Employed:.*yes.*", """
|
||||
{"fieldName":"isEmployed","operator":"EQUALS","values":[true]}""");
|
||||
|
||||
testBasicCriteria(queryScreenLib, "Is Employed", "equals no", null, "(?s).*Is Employed:.*no.*", """
|
||||
testBasicBooleanCriteria(queryScreenLib, "Is Employed", "equals no", "(?s).*Is Employed:.*no.*", """
|
||||
{"fieldName":"isEmployed","operator":"EQUALS","values":[false]}""");
|
||||
|
||||
testBasicCriteria(queryScreenLib, "Is Employed", "is empty", null, "(?s).*Is Employed:.*is empty.*", """
|
||||
testBasicBooleanCriteria(queryScreenLib, "Is Employed", "is empty", "(?s).*Is Employed:.*is empty.*", """
|
||||
{"fieldName":"isEmployed","operator":"IS_BLANK","values":[]}""");
|
||||
|
||||
testBasicCriteria(queryScreenLib, "Is Employed", "is not empty", null, "(?s).*Is Employed:.*is not empty.*", """
|
||||
testBasicBooleanCriteria(queryScreenLib, "Is Employed", "is not empty", "(?s).*Is Employed:.*is not empty.*", """
|
||||
{"fieldName":"isEmployed","operator":"IS_NOT_BLANK","values":[]}""");
|
||||
}
|
||||
|
||||
@ -203,10 +203,10 @@ public class QueryScreenTest extends QBaseSeleniumTest
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void testBasicCriteria(QueryScreenLib queryScreenLib, String fieldLabel, String operatorLabel, String value, String expectButtonStringRegex, String expectFilterJsonContains)
|
||||
private void testBasicBooleanCriteria(QueryScreenLib queryScreenLib, String fieldLabel, String operatorLabel, String expectButtonStringRegex, String expectFilterJsonContains)
|
||||
{
|
||||
qSeleniumJavalin.beginCapture();
|
||||
queryScreenLib.setBasicFilter(fieldLabel, operatorLabel, value);
|
||||
queryScreenLib.setBasicBooleanFilter(fieldLabel, operatorLabel);
|
||||
queryScreenLib.waitForBasicFilterButtonMatchingRegex(expectButtonStringRegex);
|
||||
qSeleniumJavalin.waitForCapturedPathWithBodyContaining("/data/person/query", expectFilterJsonContains);
|
||||
qSeleniumJavalin.endCapture();
|
||||
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"options": [
|
||||
{
|
||||
"id": "person",
|
||||
"label": "Person"
|
||||
},
|
||||
{
|
||||
"id": "city",
|
||||
"label": "City"
|
||||
},
|
||||
{
|
||||
"id": "savedReport",
|
||||
"label": "Saved Report"
|
||||
}
|
||||
]
|
||||
}
|
@ -189,6 +189,26 @@
|
||||
"insertPermission": true,
|
||||
"editPermission": true,
|
||||
"deletePermission": true
|
||||
},
|
||||
"savedReport": {
|
||||
"name": "savedReport",
|
||||
"label": "Saved Report",
|
||||
"isHidden": false,
|
||||
"iconName": "article",
|
||||
"capabilities": [
|
||||
"TABLE_COUNT",
|
||||
"TABLE_GET",
|
||||
"TABLE_QUERY",
|
||||
"QUERY_STATS",
|
||||
"TABLE_UPDATE",
|
||||
"TABLE_INSERT",
|
||||
"TABLE_DELETE"
|
||||
],
|
||||
"readPermission": true,
|
||||
"insertPermission": true,
|
||||
"editPermission": true,
|
||||
"deletePermission": true,
|
||||
"usesVariants": false
|
||||
}
|
||||
},
|
||||
"processes": {
|
||||
@ -420,6 +440,40 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"userCustomizations": {
|
||||
"name": "userCustomizations",
|
||||
"label": "User Customizations",
|
||||
"iconName": "article",
|
||||
"widgets": [],
|
||||
"children": [
|
||||
{
|
||||
"type": "TABLE",
|
||||
"name": "savedReport",
|
||||
"label": "Saved Report",
|
||||
"iconName": "article"
|
||||
}
|
||||
],
|
||||
"childMap": {
|
||||
"savedReport": {
|
||||
"type": "TABLE",
|
||||
"name": "savedReport",
|
||||
"label": "Saved Report",
|
||||
"iconName": "article"
|
||||
}
|
||||
},
|
||||
"sections": [
|
||||
{
|
||||
"name": "userCustomizations",
|
||||
"label": "User Customizations",
|
||||
"icon": {
|
||||
"name": "badge"
|
||||
},
|
||||
"tables": [
|
||||
"savedReport"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"miscellaneous": {
|
||||
"name": "miscellaneous",
|
||||
"label": "Miscellaneous",
|
||||
@ -730,6 +784,20 @@
|
||||
}
|
||||
],
|
||||
"iconName": "data_object"
|
||||
},
|
||||
{
|
||||
"type": "APP",
|
||||
"name": "userCustomizations",
|
||||
"label": "User Customizations",
|
||||
"children": [
|
||||
{
|
||||
"type": "TABLE",
|
||||
"name": "savedReport",
|
||||
"label": "Saved Report",
|
||||
"iconName": "article"
|
||||
}
|
||||
],
|
||||
"iconName": "data_object"
|
||||
}
|
||||
],
|
||||
"branding": {
|
||||
@ -750,6 +818,28 @@
|
||||
"isCard": true,
|
||||
"storeDropdownSelections": false,
|
||||
"hasPermission": true
|
||||
},
|
||||
"reportSetupWidget": {
|
||||
"name": "reportSetupWidget",
|
||||
"label": "Filters and Columns",
|
||||
"type": "reportSetup",
|
||||
"isCard": true,
|
||||
"storeDropdownSelections": false,
|
||||
"showReloadButton": true,
|
||||
"showExportButton": false,
|
||||
"defaultValues": {},
|
||||
"hasPermission": true
|
||||
},
|
||||
"pivotTableSetupWidget": {
|
||||
"name": "pivotTableSetupWidget",
|
||||
"label": "Pivot Table",
|
||||
"type": "pivotTableSetup",
|
||||
"isCard": true,
|
||||
"storeDropdownSelections": false,
|
||||
"showReloadButton": true,
|
||||
"showExportButton": false,
|
||||
"defaultValues": {},
|
||||
"hasPermission": true
|
||||
}
|
||||
},
|
||||
"environmentValues": {
|
||||
|
218
src/test/resources/fixtures/metaData/table/savedReport.json
Normal file
218
src/test/resources/fixtures/metaData/table/savedReport.json
Normal file
@ -0,0 +1,218 @@
|
||||
{
|
||||
"table": {
|
||||
"name": "savedReport",
|
||||
"label": "Saved Report",
|
||||
"isHidden": false,
|
||||
"primaryKeyField": "id",
|
||||
"iconName": "article",
|
||||
"fields": {
|
||||
"queryFilterJson": {
|
||||
"name": "queryFilterJson",
|
||||
"label": "Query Filter",
|
||||
"type": "STRING",
|
||||
"isRequired": false,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"columnsJson": {
|
||||
"name": "columnsJson",
|
||||
"label": "Columns",
|
||||
"type": "STRING",
|
||||
"isRequired": false,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"inputFieldsJson": {
|
||||
"name": "inputFieldsJson",
|
||||
"label": "Input Fields",
|
||||
"type": "STRING",
|
||||
"isRequired": false,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"pivotTableJson": {
|
||||
"name": "pivotTableJson",
|
||||
"label": "Pivot Table",
|
||||
"type": "STRING",
|
||||
"isRequired": false,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"modifyDate": {
|
||||
"name": "modifyDate",
|
||||
"label": "Modify Date",
|
||||
"type": "DATE_TIME",
|
||||
"isRequired": false,
|
||||
"isEditable": false,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"label": {
|
||||
"name": "label",
|
||||
"label": "Report Name",
|
||||
"type": "STRING",
|
||||
"isRequired": true,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"id": {
|
||||
"name": "id",
|
||||
"label": "Id",
|
||||
"type": "INTEGER",
|
||||
"isRequired": false,
|
||||
"isEditable": false,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"userId": {
|
||||
"name": "userId",
|
||||
"label": "User Id",
|
||||
"type": "STRING",
|
||||
"isRequired": false,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"tableName": {
|
||||
"name": "tableName",
|
||||
"label": "Table",
|
||||
"type": "STRING",
|
||||
"isRequired": true,
|
||||
"isEditable": true,
|
||||
"isHeavy": false,
|
||||
"possibleValueSourceName": "tables",
|
||||
"displayFormat": "%s"
|
||||
},
|
||||
"createDate": {
|
||||
"name": "createDate",
|
||||
"label": "Create Date",
|
||||
"type": "DATE_TIME",
|
||||
"isRequired": false,
|
||||
"isEditable": false,
|
||||
"isHeavy": false,
|
||||
"displayFormat": "%s"
|
||||
}
|
||||
},
|
||||
"sections": [
|
||||
{
|
||||
"name": "identity",
|
||||
"label": "Identity",
|
||||
"tier": "T1",
|
||||
"fieldNames": [
|
||||
"id",
|
||||
"label",
|
||||
"tableName"
|
||||
],
|
||||
"icon": {
|
||||
"name": "badge"
|
||||
},
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "filtersAndColumns",
|
||||
"label": "Filters and Columns",
|
||||
"tier": "T2",
|
||||
"widgetName": "reportSetupWidget",
|
||||
"icon": {
|
||||
"name": "table_chart"
|
||||
},
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "pivotTable",
|
||||
"label": "Pivot Table",
|
||||
"tier": "T2",
|
||||
"widgetName": "pivotTableSetupWidget",
|
||||
"icon": {
|
||||
"name": "pivot_table_chart"
|
||||
},
|
||||
"isHidden": false
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"label": "Data",
|
||||
"tier": "T2",
|
||||
"fieldNames": [
|
||||
"queryFilterJson",
|
||||
"columnsJson",
|
||||
"pivotTableJson"
|
||||
],
|
||||
"icon": {
|
||||
"name": "text_snippet"
|
||||
},
|
||||
"isHidden": true
|
||||
},
|
||||
{
|
||||
"name": "hidden",
|
||||
"label": "Hidden",
|
||||
"tier": "T2",
|
||||
"fieldNames": [
|
||||
"inputFieldsJson",
|
||||
"userId"
|
||||
],
|
||||
"icon": {
|
||||
"name": "text_snippet"
|
||||
},
|
||||
"isHidden": true
|
||||
},
|
||||
{
|
||||
"name": "dates",
|
||||
"label": "Dates",
|
||||
"tier": "T3",
|
||||
"fieldNames": [
|
||||
"createDate",
|
||||
"modifyDate"
|
||||
],
|
||||
"icon": {
|
||||
"name": "calendar_month"
|
||||
},
|
||||
"isHidden": false
|
||||
}
|
||||
],
|
||||
"exposedJoins": [],
|
||||
"supplementalTableMetaData": {
|
||||
"materialDashboard": {
|
||||
"fieldRules": [
|
||||
{
|
||||
"trigger": "ON_CHANGE",
|
||||
"sourceField": "tableName",
|
||||
"action": "CLEAR_TARGET_FIELD",
|
||||
"targetField": "queryFilterJson"
|
||||
},
|
||||
{
|
||||
"trigger": "ON_CHANGE",
|
||||
"sourceField": "tableName",
|
||||
"action": "CLEAR_TARGET_FIELD",
|
||||
"targetField": "columnsJson"
|
||||
},
|
||||
{
|
||||
"trigger": "ON_CHANGE",
|
||||
"sourceField": "tableName",
|
||||
"action": "CLEAR_TARGET_FIELD",
|
||||
"targetField": "pivotTableJson"
|
||||
}
|
||||
],
|
||||
"type": "materialDashboard"
|
||||
}
|
||||
},
|
||||
"capabilities": [
|
||||
"TABLE_COUNT",
|
||||
"TABLE_GET",
|
||||
"TABLE_QUERY",
|
||||
"QUERY_STATS",
|
||||
"TABLE_UPDATE",
|
||||
"TABLE_INSERT",
|
||||
"TABLE_DELETE"
|
||||
],
|
||||
"readPermission": true,
|
||||
"insertPermission": true,
|
||||
"editPermission": true,
|
||||
"deletePermission": true,
|
||||
"usesVariants": false
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
{"type":"pivotTableSetup"}
|
@ -0,0 +1 @@
|
||||
{"type":"reportSetup"}
|
Reference in New Issue
Block a user