diff --git a/package.json b/package.json
index f75f7ef..d20632d 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.30",
+ "@kingsrook/qqq-frontend-core": "1.0.31",
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
@@ -75,7 +75,7 @@
"geff-ham": "rm -rf node_modules/ && rm -rf package-lock.json && npm install --legacy-peer-deps && npm start",
"install-legacy-peer-deps": "npm install --legacy-peer-deps",
"prepublishOnly": "tsc -p ./ --outDir lib/",
- "start": "react-scripts start",
+ "start": "BROWSER=none react-scripts start",
"test": "react-scripts test",
"cypress:open": "cypress open"
},
diff --git a/src/qqq/components/EntityForm/index.tsx b/src/qqq/components/EntityForm/index.tsx
index 8f6493c..06616e8 100644
--- a/src/qqq/components/EntityForm/index.tsx
+++ b/src/qqq/components/EntityForm/index.tsx
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*/
+import {Capability} from "@kingsrook/qqq-frontend-core/lib/model/metaData/Capability";
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
@@ -73,6 +74,8 @@ function EntityForm({table, id}: Props): JSX.Element
const [tableSections, setTableSections] = useState(null as QTableSection[]);
const [, forceUpdate] = useReducer((x) => x + 1, 0);
+ const [noCapabilityError, setNoCapabilityError] = useState(null as string);
+
const {pageHeader, setPageHeader} = useContext(QContext);
const navigate = useNavigate();
@@ -140,11 +143,21 @@ function EntityForm({table, id}: Props): JSX.Element
});
setFormValues(formValues);
+
+ if(!tableMetaData.capabilities.has(Capability.TABLE_UPDATE))
+ {
+ setNoCapabilityError("You may not edit records in this table");
+ }
}
else
{
setFormTitle(`Creating New ${tableMetaData?.label}`);
setPageHeader(`Creating New ${tableMetaData?.label}`);
+
+ if(!tableMetaData.capabilities.has(Capability.TABLE_INSERT))
+ {
+ setNoCapabilityError("You may not create records in this table");
+ }
}
setInitialValues(initialValues);
@@ -168,6 +181,11 @@ function EntityForm({table, id}: Props): JSX.Element
const section = tableSections[i];
const sectionDynamicFormFields: any[] = [];
+ if(section.isHidden)
+ {
+ continue;
+ }
+
for (let j = 0; j < section.fieldNames.length; j++)
{
const fieldName = section.fieldNames[j];
@@ -277,6 +295,19 @@ function EntityForm({table, id}: Props): JSX.Element
const formId = id != null ? `edit-${tableMetaData?.name}-form` : `create-${tableMetaData?.name}-form`;
+ if(noCapabilityError)
+ {
+ return
+
+
+
+ {noCapabilityError}
+
+
+
+ ;
+ }
+
return (
diff --git a/src/qqq/components/QButtons/index.tsx b/src/qqq/components/QButtons/index.tsx
index 489686b..b813ea9 100644
--- a/src/qqq/components/QButtons/index.tsx
+++ b/src/qqq/components/QButtons/index.tsx
@@ -71,7 +71,7 @@ interface QDeleteButtonProps
export function QDeleteButton({onClickHandler}: QDeleteButtonProps): JSX.Element
{
return (
-
+
delete}>
Delete
@@ -82,7 +82,7 @@ export function QDeleteButton({onClickHandler}: QDeleteButtonProps): JSX.Element
export function QEditButton(): JSX.Element
{
return (
-
+
edit}>
Edit
diff --git a/src/qqq/components/QRecordSidebar/index.tsx b/src/qqq/components/QRecordSidebar/index.tsx
index a15a61f..a404978 100644
--- a/src/qqq/components/QRecordSidebar/index.tsx
+++ b/src/qqq/components/QRecordSidebar/index.tsx
@@ -59,6 +59,11 @@ function QRecordSidebar({tableSections, widgetMetaDataList, light, stickyTop}: P
const sidebarEntries = [] as SidebarEntry[];
tableSections && tableSections.forEach((section, index) =>
{
+ if(section.isHidden)
+ {
+ return;
+ }
+
if (index === 1 && widgetMetaDataList)
{
widgetMetaDataList.forEach((widget) =>
diff --git a/src/qqq/pages/entity-list/index.tsx b/src/qqq/pages/entity-list/index.tsx
index 665ddd6..bdb9e0d 100644
--- a/src/qqq/pages/entity-list/index.tsx
+++ b/src/qqq/pages/entity-list/index.tsx
@@ -20,6 +20,7 @@
*/
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";
@@ -584,9 +585,10 @@ function EntityList({table, launchProcess}: Props): JSX.Element
const row: any = {};
fields.forEach((field) =>
{
- const value = QValueUtils.getDisplayValue(field, record);
+ const value = QValueUtils.getDisplayValue(field, record, "query");
if (typeof value !== "string")
{
+ console.log(`Need to render [${field.name}]`);
columnsToRender[field.name] = true;
}
row[field.name] = value;
@@ -1146,18 +1148,27 @@ function EntityList({table, launchProcess}: Props): JSX.Element
onClose={closeActionsMenu}
keepMounted
>
-
-
-
+ {
+ table.capabilities.has(Capability.TABLE_INSERT) &&
+
+ }
+ {
+ table.capabilities.has(Capability.TABLE_UPDATE) &&
+
+ }
+ {
+ table.capabilities.has(Capability.TABLE_DELETE) &&
+
+ }
{tableProcesses.length > 0 && }
{tableProcesses.map((process) => (
))}
+ {
+ tableProcesses.length == 0 && !table.capabilities.has(Capability.TABLE_INSERT) && !table.capabilities.has(Capability.TABLE_UPDATE) && !table.capabilities.has(Capability.TABLE_DELETE) &&
+
+ }
);
@@ -1226,7 +1244,10 @@ function EntityList({table, launchProcess}: Props): JSX.Element
{renderActionsMenu}
-
+ {
+ table.capabilities.has(Capability.TABLE_INSERT) &&
+
+ }
@@ -1244,6 +1265,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
disableSelectionOnClick
autoHeight
rows={rows}
+ // getRowHeight={() => "auto"} // maybe nice? wraps values in cells...
columns={columnsModel}
rowBuffer={10}
rowCount={totalRecords === null ? 0 : totalRecords}
diff --git a/src/qqq/pages/entity-view/EntityDeveloperView.tsx b/src/qqq/pages/entity-view/EntityDeveloperView.tsx
index 5e9126e..2da31f1 100644
--- a/src/qqq/pages/entity-view/EntityDeveloperView.tsx
+++ b/src/qqq/pages/entity-view/EntityDeveloperView.tsx
@@ -423,7 +423,7 @@ function EntityDeveloperView({table}: Props): JSX.Element
{
- associatedScripts.map((object) =>
+ associatedScripts && associatedScripts.map((object) =>
{
let fieldName = object.associatedScript?.fieldName;
let field = tableMetaData.fields.get(fieldName);
diff --git a/src/qqq/pages/entity-view/EntityView.tsx b/src/qqq/pages/entity-view/EntityView.tsx
index c182d8d..c552cc2 100644
--- a/src/qqq/pages/entity-view/EntityView.tsx
+++ b/src/qqq/pages/entity-view/EntityView.tsx
@@ -20,6 +20,7 @@
*/
import {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException";
+import {Capability} from "@kingsrook/qqq-frontend-core/lib/model/metaData/Capability";
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
@@ -234,6 +235,11 @@ function EntityView({table, launchProcess}: Props): JSX.Element
for (let i = 0; i < tableSections.length; i++)
{
const section = tableSections[i];
+ if(section.isHidden)
+ {
+ continue;
+ }
+
sectionFieldElements.set(
section.name,
@@ -244,7 +250,7 @@ function EntityView({table, launchProcess}: Props): JSX.Element
{tableMetaData.fields.get(fieldName).label}:
- {QValueUtils.getDisplayValue(tableMetaData.fields.get(fieldName), record)}
+ {QValueUtils.getDisplayValue(tableMetaData.fields.get(fieldName), record, "view")}
))
@@ -313,27 +319,33 @@ function EntityView({table, launchProcess}: Props): JSX.Element
onClose={closeActionsMenu}
keepMounted
>
-
-
- {tableProcesses.length > 0 && }
+ table.capabilities.has(Capability.TABLE_UPDATE) &&
+
+ }
+ {
+ table.capabilities.has(Capability.TABLE_DELETE) &&
+
+ }
+ {tableProcesses.length > 0 && (table.capabilities.has(Capability.TABLE_UPDATE) || table.capabilities.has(Capability.TABLE_DELETE)) && }
{tableProcesses.map((process) => (
))}
-
+ {tableProcesses.length > 0 && }
))
}
diff --git a/src/qqq/pages/process-run/index.tsx b/src/qqq/pages/process-run/index.tsx
index 601c9ff..4761d55 100644
--- a/src/qqq/pages/process-run/index.tsx
+++ b/src/qqq/pages/process-run/index.tsx
@@ -362,8 +362,11 @@ function ProcessRun({process, defaultProcessValues, isModal, recordIds, closeMod
{localTableSections.map((section: QTableSection, index: number) =>
{
const name = section.name
- console.log(formData);
- console.log(section.fieldNames);
+
+ if(section.isHidden)
+ {
+ return ;
+ }
const sectionFormFields = {};
for(let i = 0; i
- {QValueUtils.getValueForDisplay(field, processValues[field.name])}
+ {QValueUtils.getValueForDisplay(field, processValues[field.name], "view")}
))}
diff --git a/src/qqq/utils/QValueUtils.tsx b/src/qqq/utils/QValueUtils.tsx
index 065d134..038d5f7 100644
--- a/src/qqq/utils/QValueUtils.tsx
+++ b/src/qqq/utils/QValueUtils.tsx
@@ -25,8 +25,9 @@ import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QField
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
import "datejs";
-import {Chip, Icon} from "@mui/material";
+import {Chip, Icon, Typography} from "@mui/material";
import React, {Fragment} from "react";
+import AceEditor from "react-ace";
import {Link} from "react-router-dom";
import QClient from "qqq/utils/QClient";
@@ -66,19 +67,19 @@ class QValueUtils
** When you have a field, and a record - call this method to get a string or
** element back to display the field's value.
*******************************************************************************/
- public static getDisplayValue(field: QFieldMetaData, record: QRecord): string | JSX.Element
+ public static getDisplayValue(field: QFieldMetaData, record: QRecord, usage: "view" | "query" = "view"): string | JSX.Element
{
const displayValue = record.displayValues ? record.displayValues.get(field.name) : undefined;
const rawValue = record.values ? record.values.get(field.name) : undefined;
- return QValueUtils.getValueForDisplay(field, rawValue, displayValue);
+ return QValueUtils.getValueForDisplay(field, rawValue, displayValue, usage);
}
/*******************************************************************************
** When you have a field and a value (either just a raw value, or a raw and
** display value), call this method to get a string Element to display.
*******************************************************************************/
- public static getValueForDisplay(field: QFieldMetaData, rawValue: any, displayValue: any = rawValue): string | JSX.Element
+ public static getValueForDisplay(field: QFieldMetaData, rawValue: any, displayValue: any = rawValue, usage: "view" | "query" = "view"): string | JSX.Element
{
if (field.hasAdornment(AdornmentType.LINK))
{
@@ -141,6 +142,28 @@ class QValueUtils
return ();
}
+ if (field.hasAdornment(AdornmentType.CODE_EDITOR))
+ {
+ if(usage === "view")
+ {
+ return ();
+ }
+ else
+ {
+ return rawValue;
+ }
+ }
+
return (QValueUtils.getUnadornedValueForDisplay(field, rawValue, displayValue));
}
@@ -227,6 +250,11 @@ class QValueUtils
public static breakTextIntoLines(value: string): JSX.Element
{
+ if(!value)
+ {
+ return ;
+ }
+
return (
{value.split(/\n/).map((value: string, index: number) => (