mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 12:50:43 +00:00
Merged feature/sftp-and-headless-bulk-load into dev
This commit is contained in:
@ -270,7 +270,7 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
pageHeader &&
|
pageHeader &&
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
<MDTypography pb="0.5rem" textTransform="capitalize" variant="h3" color={light ? "white" : "dark"} noWrap>
|
<MDTypography pb="0.5rem" variant="h3" color={light ? "white" : "dark"} noWrap>
|
||||||
{pageHeader}
|
{pageHeader}
|
||||||
</MDTypography>
|
</MDTypography>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -109,6 +109,7 @@ export const getOperatorOptions = (tableMetaData: QTableMetaData, fieldName: str
|
|||||||
{
|
{
|
||||||
case QFieldType.DECIMAL:
|
case QFieldType.DECIMAL:
|
||||||
case QFieldType.INTEGER:
|
case QFieldType.INTEGER:
|
||||||
|
case QFieldType.LONG:
|
||||||
operatorOptions.push({label: "equals", value: QCriteriaOperator.EQUALS, valueMode: ValueMode.SINGLE});
|
operatorOptions.push({label: "equals", value: QCriteriaOperator.EQUALS, valueMode: ValueMode.SINGLE});
|
||||||
operatorOptions.push({label: "does not equal", value: QCriteriaOperator.NOT_EQUALS_OR_IS_NULL, valueMode: ValueMode.SINGLE});
|
operatorOptions.push({label: "does not equal", value: QCriteriaOperator.NOT_EQUALS_OR_IS_NULL, valueMode: ValueMode.SINGLE});
|
||||||
operatorOptions.push({label: "greater than", value: QCriteriaOperator.GREATER_THAN, valueMode: ValueMode.SINGLE});
|
operatorOptions.push({label: "greater than", value: QCriteriaOperator.GREATER_THAN, valueMode: ValueMode.SINGLE});
|
||||||
|
@ -111,7 +111,7 @@ function RecordGridWidget({widgetMetaData, data, addNewRecordCallback, disableRo
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tableMetaData = data.childTableMetaData instanceof QTableMetaData ? data.childTableMetaData as QTableMetaData : new QTableMetaData(data.childTableMetaData);
|
const tableMetaData = data.childTableMetaData instanceof QTableMetaData ? data.childTableMetaData as QTableMetaData : new QTableMetaData(data.childTableMetaData);
|
||||||
const rows = DataGridUtils.makeRows(records, tableMetaData, true);
|
const rows = DataGridUtils.makeRows(records, tableMetaData, undefined, true);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
// note - tablePath may be null, if the user doesn't have access to the table. //
|
// note - tablePath may be null, if the user doesn't have access to the table. //
|
||||||
@ -255,14 +255,14 @@ function RecordGridWidget({widgetMetaData, data, addNewRecordCallback, disableRo
|
|||||||
disabledFields = data.defaultValuesForNewChildRecords;
|
disabledFields = data.defaultValuesForNewChildRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultValuesForNewChildRecords = data.defaultValuesForNewChildRecords || {}
|
const defaultValuesForNewChildRecords = data.defaultValuesForNewChildRecords || {};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
// copy values from specified fields in the parent record down into the child record //
|
// copy values from specified fields in the parent record down into the child record //
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
if(data.defaultValuesForNewChildRecordsFromParentFields)
|
if (data.defaultValuesForNewChildRecordsFromParentFields)
|
||||||
{
|
{
|
||||||
for(let childField in data.defaultValuesForNewChildRecordsFromParentFields)
|
for (let childField in data.defaultValuesForNewChildRecordsFromParentFields)
|
||||||
{
|
{
|
||||||
const parentField = data.defaultValuesForNewChildRecordsFromParentFields[childField];
|
const parentField = data.defaultValuesForNewChildRecordsFromParentFields[childField];
|
||||||
defaultValuesForNewChildRecords[childField] = parentRecord?.values?.get(parentField);
|
defaultValuesForNewChildRecords[childField] = parentRecord?.values?.get(parentField);
|
||||||
|
@ -1103,7 +1103,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, isPreview, allowVariable
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// make the rows for the grid //
|
// make the rows for the grid //
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
const rows = DataGridUtils.makeRows(results, tableMetaData);
|
const rows = DataGridUtils.makeRows(results, tableMetaData, tableVariant);
|
||||||
setRows(rows);
|
setRows(rows);
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
@ -92,7 +92,7 @@ const TABLE_VARIANT_LOCAL_STORAGE_KEY_ROOT = "qqq.tableVariant";
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
export function renderSectionOfFields(key: string, fieldNames: string[], tableMetaData: QTableMetaData, helpHelpActive: boolean, record: QRecord, fieldMap?: { [name: string]: QFieldMetaData }, styleOverrides?: { label?: SxProps, value?: SxProps })
|
export function renderSectionOfFields(key: string, fieldNames: string[], tableMetaData: QTableMetaData, helpHelpActive: boolean, record: QRecord, fieldMap?: { [name: string]: QFieldMetaData }, styleOverrides?: {label?: SxProps, value?: SxProps}, tableVariant?: QTableVariant)
|
||||||
{
|
{
|
||||||
return <Grid container lg={12} key={key} display="flex" py={1} pr={2}>
|
return <Grid container lg={12} key={key} display="flex" py={1} pr={2}>
|
||||||
{
|
{
|
||||||
@ -119,7 +119,7 @@ export function renderSectionOfFields(key: string, fieldNames: string[], tableMe
|
|||||||
}
|
}
|
||||||
<div style={{display: "inline-block", width: 0}}> </div>
|
<div style={{display: "inline-block", width: 0}}> </div>
|
||||||
<Typography variant="button" textTransform="none" fontWeight="regular" color="rgb(123, 128, 154)" sx={{...(styleOverrides?.value ?? {})}}>
|
<Typography variant="button" textTransform="none" fontWeight="regular" color="rgb(123, 128, 154)" sx={{...(styleOverrides?.value ?? {})}}>
|
||||||
{ValueUtils.getDisplayValue(field, record, "view", fieldName)}
|
{ValueUtils.getDisplayValue(field, record, "view", fieldName, tableVariant)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</>
|
</>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -598,7 +598,7 @@ function RecordView({table, record: overrideRecord, launchProcess}: Props): JSX.
|
|||||||
// for a section with field names, render the field values. //
|
// for a section with field names, render the field values. //
|
||||||
// for the T1 section, the "wrapper" will come out below - but for other sections, produce a wrapper too. //
|
// for the T1 section, the "wrapper" will come out below - but for other sections, produce a wrapper too. //
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
const fields = renderSectionOfFields(section.name, section.fieldNames, tableMetaData, helpHelpActive, record);
|
const fields = renderSectionOfFields(section.name, section.fieldNames, tableMetaData, helpHelpActive, record, undefined, undefined, tableVariant);
|
||||||
|
|
||||||
if (section.tier === "T1")
|
if (section.tier === "T1")
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@ import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QF
|
|||||||
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||||
|
import {QTableVariant} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableVariant";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import Tooltip from "@mui/material/Tooltip/Tooltip";
|
import Tooltip from "@mui/material/Tooltip/Tooltip";
|
||||||
import {GridColDef, GridRowsProp, MuiEvent} from "@mui/x-data-grid-pro";
|
import {GridColDef, GridRowsProp, MuiEvent} from "@mui/x-data-grid-pro";
|
||||||
@ -70,7 +71,7 @@ export default class DataGridUtils
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static makeRows = (results: QRecord[], tableMetaData: QTableMetaData, allowEmptyId = false): GridRowsProp[] =>
|
public static makeRows = (results: QRecord[], tableMetaData: QTableMetaData, tableVariant?: QTableVariant, allowEmptyId = false): GridRowsProp[] =>
|
||||||
{
|
{
|
||||||
const fields = [...tableMetaData.fields.values()];
|
const fields = [...tableMetaData.fields.values()];
|
||||||
const rows = [] as any[];
|
const rows = [] as any[];
|
||||||
@ -82,7 +83,7 @@ export default class DataGridUtils
|
|||||||
|
|
||||||
fields.forEach((field) =>
|
fields.forEach((field) =>
|
||||||
{
|
{
|
||||||
row[field.name] = ValueUtils.getDisplayValue(field, record, "query");
|
row[field.name] = ValueUtils.getDisplayValue(field, record, "query", undefined, tableVariant);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tableMetaData.exposedJoins)
|
if (tableMetaData.exposedJoins)
|
||||||
@ -97,7 +98,7 @@ export default class DataGridUtils
|
|||||||
fields.forEach((field) =>
|
fields.forEach((field) =>
|
||||||
{
|
{
|
||||||
let fieldName = join.joinTable.name + "." + field.name;
|
let fieldName = join.joinTable.name + "." + field.name;
|
||||||
row[fieldName] = ValueUtils.getDisplayValue(field, record, "query", fieldName);
|
row[fieldName] = ValueUtils.getDisplayValue(field, record, "query", fieldName, tableVariant);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/Ado
|
|||||||
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
||||||
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||||
|
import {QTableVariant} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableVariant";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import "datejs"; // https://github.com/datejs/Datejs
|
import "datejs"; // https://github.com/datejs/Datejs
|
||||||
import {Chip, ClickAwayListener, Icon} from "@mui/material";
|
import {Chip, ClickAwayListener, Icon} from "@mui/material";
|
||||||
@ -76,14 +77,14 @@ class ValueUtils
|
|||||||
** When you have a field, and a record - call this method to get a string or
|
** When you have a field, and a record - call this method to get a string or
|
||||||
** element back to display the field's value.
|
** element back to display the field's value.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static getDisplayValue(field: QFieldMetaData, record: QRecord, usage: "view" | "query" = "view", overrideFieldName?: string): string | JSX.Element | JSX.Element[]
|
public static getDisplayValue(field: QFieldMetaData, record: QRecord, usage: "view" | "query" = "view", overrideFieldName?: string, tableVariant?: QTableVariant): string | JSX.Element | JSX.Element[]
|
||||||
{
|
{
|
||||||
const fieldName = overrideFieldName ?? field.name;
|
const fieldName = overrideFieldName ?? field.name;
|
||||||
|
|
||||||
const displayValue = record.displayValues ? record.displayValues.get(fieldName) : undefined;
|
const displayValue = record.displayValues ? record.displayValues.get(fieldName) : undefined;
|
||||||
const rawValue = record.values ? record.values.get(fieldName) : undefined;
|
const rawValue = record.values ? record.values.get(fieldName) : undefined;
|
||||||
|
|
||||||
return ValueUtils.getValueForDisplay(field, rawValue, displayValue, usage);
|
return ValueUtils.getValueForDisplay(field, rawValue, displayValue, usage, tableVariant, record, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -91,14 +92,35 @@ class ValueUtils
|
|||||||
** When you have a field and a value (either just a raw value, or a raw and
|
** 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.
|
** display value), call this method to get a string Element to display.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static getValueForDisplay(field: QFieldMetaData, rawValue: any, displayValue: any = rawValue, usage: "view" | "query" = "view"): string | JSX.Element | JSX.Element[]
|
public static getValueForDisplay(field: QFieldMetaData, rawValue: any, displayValue: any = rawValue, usage: "view" | "query" = "view", tableVariant?: QTableVariant, record?: QRecord, fieldName?: string): string | JSX.Element | JSX.Element[]
|
||||||
{
|
{
|
||||||
if (field.hasAdornment(AdornmentType.LINK))
|
if (field.hasAdornment(AdornmentType.LINK))
|
||||||
{
|
{
|
||||||
const adornment = field.getAdornment(AdornmentType.LINK);
|
const adornment = field.getAdornment(AdornmentType.LINK);
|
||||||
let href = rawValue;
|
let href = String(rawValue);
|
||||||
|
|
||||||
|
let toRecordFromTable = adornment.getValue("toRecordFromTable");
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the link adornment has a 'toRecordFromTableDynamic', then look for a display //
|
||||||
|
// value named `fieldName`:toRecordFromTableDynamic for the table name. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(adornment.getValue("toRecordFromTableDynamic"))
|
||||||
|
{
|
||||||
|
const toRecordFromTableDynamic = record?.displayValues?.get(fieldName + ":toRecordFromTableDynamic");
|
||||||
|
if(toRecordFromTableDynamic)
|
||||||
|
{
|
||||||
|
toRecordFromTable = toRecordFromTableDynamic;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// if the table name isn't known, then return w/o the adornment. //
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
return (ValueUtils.getUnadornedValueForDisplay(field, rawValue, displayValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const toRecordFromTable = adornment.getValue("toRecordFromTable");
|
|
||||||
if (toRecordFromTable)
|
if (toRecordFromTable)
|
||||||
{
|
{
|
||||||
if (ValueUtils.getQInstance())
|
if (ValueUtils.getQInstance())
|
||||||
@ -107,7 +129,7 @@ class ValueUtils
|
|||||||
if (!tablePath)
|
if (!tablePath)
|
||||||
{
|
{
|
||||||
console.log("Couldn't find path for table: " + toRecordFromTable);
|
console.log("Couldn't find path for table: " + toRecordFromTable);
|
||||||
return (displayValue ?? rawValue);
|
return (ValueUtils.getUnadornedValueForDisplay(field, rawValue, displayValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tablePath.endsWith("/"))
|
if (!tablePath.endsWith("/"))
|
||||||
@ -199,12 +221,44 @@ class ValueUtils
|
|||||||
|
|
||||||
if (field.type == QFieldType.BLOB || field.hasAdornment(AdornmentType.FILE_DOWNLOAD))
|
if (field.type == QFieldType.BLOB || field.hasAdornment(AdornmentType.FILE_DOWNLOAD))
|
||||||
{
|
{
|
||||||
return (<BlobComponent field={field} url={rawValue} filename={displayValue} usage={usage} />);
|
let url = rawValue;
|
||||||
|
if(tableVariant)
|
||||||
|
{
|
||||||
|
url += "?tableVariant=" + encodeURIComponent(JSON.stringify(tableVariant));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the field has the download adornment with a downloadUrlDynamic value, //
|
||||||
|
// then get the url from a displayValue of `fieldName`:downloadUrlDynamic. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(field.hasAdornment(AdornmentType.FILE_DOWNLOAD))
|
||||||
|
{
|
||||||
|
const adornment = field.getAdornment(AdornmentType.FILE_DOWNLOAD);
|
||||||
|
let downloadUrlDynamicAdornmentValue = adornment.getValue("downloadUrlDynamic");
|
||||||
|
if(downloadUrlDynamicAdornmentValue)
|
||||||
|
{
|
||||||
|
const downloadUrlDynamicValue = record?.displayValues?.get(fieldName + ":downloadUrlDynamic");
|
||||||
|
if (downloadUrlDynamicValue)
|
||||||
|
{
|
||||||
|
url = downloadUrlDynamicValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// if the url isn't available, then return w/o the adornment. //
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
return (ValueUtils.getUnadornedValueForDisplay(field, rawValue, displayValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<BlobComponent field={field} url={url} filename={displayValue} usage={usage} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ValueUtils.getUnadornedValueForDisplay(field, rawValue, displayValue));
|
return (ValueUtils.getUnadornedValueForDisplay(field, rawValue, displayValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** After we know there's no element to be returned (e.g., because no adornment),
|
** After we know there's no element to be returned (e.g., because no adornment),
|
||||||
** this method does the string formatting.
|
** this method does the string formatting.
|
||||||
|
Reference in New Issue
Block a user