mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Merge pull request #28 from Kingsrook/feature/CE-607-mvp-of-transportation-plan-record
CE-607 Support fields from an exposed-join on a view screen.
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
"@auth0/auth0-react": "1.10.2",
|
"@auth0/auth0-react": "1.10.2",
|
||||||
"@emotion/react": "11.7.1",
|
"@emotion/react": "11.7.1",
|
||||||
"@emotion/styled": "11.6.0",
|
"@emotion/styled": "11.6.0",
|
||||||
"@kingsrook/qqq-frontend-core": "1.0.79",
|
"@kingsrook/qqq-frontend-core": "1.0.80",
|
||||||
"@mui/icons-material": "5.4.1",
|
"@mui/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.11.1",
|
"@mui/material": "5.11.1",
|
||||||
"@mui/styles": "5.11.1",
|
"@mui/styles": "5.11.1",
|
||||||
|
@ -346,6 +346,12 @@ function EntityForm(props: Props): JSX.Element
|
|||||||
const fieldName = section.fieldNames[j];
|
const fieldName = section.fieldNames[j];
|
||||||
const field = tableMetaData.fields.get(fieldName);
|
const field = tableMetaData.fields.get(fieldName);
|
||||||
|
|
||||||
|
if(!field)
|
||||||
|
{
|
||||||
|
console.log(`Omitting un-found field ${fieldName} from form`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// if id !== null (and we're not copying) - means we're on the edit screen -- show all fields on the edit screen. //
|
// if id !== null (and we're not copying) - means we're on the edit screen -- show all fields on the edit screen. //
|
||||||
// || (or) we're on the insert screen in which case, only show editable fields. //
|
// || (or) we're on the insert screen in which case, only show editable fields. //
|
||||||
|
@ -985,6 +985,10 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
}
|
}
|
||||||
setQJobRunning(null);
|
setQJobRunning(null);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.warn(`Process response was not of an expected type (need an npm clean?) ${JSON.stringify(lastProcessResponse)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [lastProcessResponse]);
|
}, [lastProcessResponse]);
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ import DataGridUtils from "qqq/utils/DataGridUtils";
|
|||||||
import Client from "qqq/utils/qqq/Client";
|
import Client from "qqq/utils/qqq/Client";
|
||||||
import FilterUtils from "qqq/utils/qqq/FilterUtils";
|
import FilterUtils from "qqq/utils/qqq/FilterUtils";
|
||||||
import ProcessUtils from "qqq/utils/qqq/ProcessUtils";
|
import ProcessUtils from "qqq/utils/qqq/ProcessUtils";
|
||||||
|
import TableUtils from "qqq/utils/qqq/TableUtils";
|
||||||
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
||||||
|
|
||||||
const CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedFilterId";
|
const CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedFilterId";
|
||||||
@ -628,6 +629,8 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
let models = await FilterUtils.determineFilterAndSortModels(qController, tableMetaData, null, searchParams, filterLocalStorageKey, sortLocalStorageKey);
|
let models = await FilterUtils.determineFilterAndSortModels(qController, tableMetaData, null, searchParams, filterLocalStorageKey, sortLocalStorageKey);
|
||||||
setFilterModel(models.filter);
|
setFilterModel(models.filter);
|
||||||
setColumnSortModel(models.sort);
|
setColumnSortModel(models.sort);
|
||||||
|
setWarningAlert(models.warning);
|
||||||
|
|
||||||
setQueryFilter(FilterUtils.buildQFilterFromGridFilter(tableMetaData, models.filter, models.sort, rowsPerPage));
|
setQueryFilter(FilterUtils.buildQFilterFromGridFilter(tableMetaData, models.filter, models.sort, rowsPerPage));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -708,16 +711,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
if (tableMetaData?.exposedJoins)
|
if (tableMetaData?.exposedJoins)
|
||||||
{
|
{
|
||||||
const visibleJoinTables = getVisibleJoinTables();
|
const visibleJoinTables = getVisibleJoinTables();
|
||||||
|
queryJoins = TableUtils.getQueryJoins(tableMetaData, visibleJoinTables);
|
||||||
queryJoins = [];
|
|
||||||
for (let i = 0; i < tableMetaData.exposedJoins.length; i++)
|
|
||||||
{
|
|
||||||
const join = tableMetaData.exposedJoins[i];
|
|
||||||
if (visibleJoinTables.has(join.joinTable.name))
|
|
||||||
{
|
|
||||||
queryJoins.push(new QueryJoin(join.joinTable.name, true, "LEFT"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1400,6 +1394,8 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
const models = await FilterUtils.determineFilterAndSortModels(qController, tableMetaData, qRecord.values.get("filterJson"), null, null, null);
|
const models = await FilterUtils.determineFilterAndSortModels(qController, tableMetaData, qRecord.values.get("filterJson"), null, null, null);
|
||||||
handleFilterChange(models.filter);
|
handleFilterChange(models.filter);
|
||||||
handleSortChange(models.sort, models.filter);
|
handleSortChange(models.sort, models.filter);
|
||||||
|
setWarningAlert(models.warning);
|
||||||
|
|
||||||
localStorage.setItem(currentSavedFilterLocalStorageKey, selectedSavedFilterId.toString());
|
localStorage.setItem(currentSavedFilterLocalStorageKey, selectedSavedFilterId.toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1431,35 +1427,13 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
return (qRecord);
|
return (qRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFieldAndTable = (fieldName: string): [QFieldMetaData, QTableMetaData] =>
|
|
||||||
{
|
|
||||||
if(fieldName.indexOf(".") > -1)
|
|
||||||
{
|
|
||||||
const nameParts = fieldName.split(".", 2);
|
|
||||||
for (let i = 0; i < tableMetaData?.exposedJoins?.length; i++)
|
|
||||||
{
|
|
||||||
const join = tableMetaData?.exposedJoins[i];
|
|
||||||
if(join?.joinTable.name == nameParts[0])
|
|
||||||
{
|
|
||||||
return ([join.joinTable.fields.get(nameParts[1]), join.joinTable]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ([tableMetaData.fields.get(fieldName), tableMetaData]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (null);
|
|
||||||
}
|
|
||||||
|
|
||||||
const copyColumnValues = async (column: GridColDef) =>
|
const copyColumnValues = async (column: GridColDef) =>
|
||||||
{
|
{
|
||||||
let data = "";
|
let data = "";
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
if (latestQueryResults && latestQueryResults.length)
|
if (latestQueryResults && latestQueryResults.length)
|
||||||
{
|
{
|
||||||
let [qFieldMetaData, fieldTable] = getFieldAndTable(column.field);
|
let [qFieldMetaData, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, column.field);
|
||||||
for (let i = 0; i < latestQueryResults.length; i++)
|
for (let i = 0; i < latestQueryResults.length; i++)
|
||||||
{
|
{
|
||||||
let record = latestQueryResults[i] as QRecord;
|
let record = latestQueryResults[i] as QRecord;
|
||||||
@ -1489,7 +1463,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
setFilterForColumnStats(buildQFilter(tableMetaData, filterModel));
|
setFilterForColumnStats(buildQFilter(tableMetaData, filterModel));
|
||||||
setColumnStatsFieldName(column.field);
|
setColumnStatsFieldName(column.field);
|
||||||
|
|
||||||
const [field, fieldTable] = getFieldAndTable(column.field);
|
const [field, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, column.field);
|
||||||
setColumnStatsField(field);
|
setColumnStatsField(field);
|
||||||
setColumnStatsFieldTableName(fieldTable.name);
|
setColumnStatsFieldTableName(fieldTable.name);
|
||||||
};
|
};
|
||||||
@ -1962,7 +1936,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
(warningAlert) ? (
|
(warningAlert) ? (
|
||||||
<Collapse in={Boolean(warningAlert)}>
|
<Collapse in={Boolean(warningAlert)}>
|
||||||
<Alert color="warning" sx={{mb: 3}} onClose={() => setWarningAlert(null)}>{warningAlert}</Alert>
|
<Alert color="warning" icon={<Icon>warning</Icon>} sx={{mb: 3}} onClose={() => setWarningAlert(null)}>{warningAlert}</Alert>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QT
|
|||||||
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
||||||
import {QTableVariant} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableVariant";
|
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 {QueryJoin} from "@kingsrook/qqq-frontend-core/lib/model/query/QueryJoin";
|
||||||
import {Alert, Typography} from "@mui/material";
|
import {Alert, Typography} from "@mui/material";
|
||||||
import Avatar from "@mui/material/Avatar";
|
import Avatar from "@mui/material/Avatar";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
@ -103,7 +104,7 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
const [allTableProcesses, setAllTableProcesses] = useState([] as QProcessMetaData[]);
|
const [allTableProcesses, setAllTableProcesses] = useState([] as QProcessMetaData[]);
|
||||||
const [actionsMenu, setActionsMenu] = useState(null);
|
const [actionsMenu, setActionsMenu] = useState(null);
|
||||||
const [notFoundMessage, setNotFoundMessage] = useState(null as string);
|
const [notFoundMessage, setNotFoundMessage] = useState(null as string);
|
||||||
const [errorMessage, setErrorMessage] = useState(null as string)
|
const [errorMessage, setErrorMessage] = useState(null as string);
|
||||||
const [successMessage, setSuccessMessage] = useState(null as string);
|
const [successMessage, setSuccessMessage] = useState(null as string);
|
||||||
const [warningMessage, setWarningMessage] = useState(null as string);
|
const [warningMessage, setWarningMessage] = useState(null as string);
|
||||||
const [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
|
const [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
|
||||||
@ -325,6 +326,31 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
reload();
|
reload();
|
||||||
}, [location.pathname, location.hash]);
|
}, [location.pathname, location.hash]);
|
||||||
|
|
||||||
|
const getVisibleJoinTables = (tableMetaData: QTableMetaData): Set<string> =>
|
||||||
|
{
|
||||||
|
const visibleJoinTables = new Set<string>();
|
||||||
|
|
||||||
|
for (let i = 0; i < tableMetaData?.sections.length; i++)
|
||||||
|
{
|
||||||
|
const section = tableMetaData?.sections[i];
|
||||||
|
if (section.isHidden || !section.fieldNames || !section.fieldNames.length)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.fieldNames.forEach((fieldName) =>
|
||||||
|
{
|
||||||
|
const [field, tableForField] = TableUtils.getFieldAndTable(tableMetaData, fieldName);
|
||||||
|
if(tableForField && tableForField.name != tableMetaData.name)
|
||||||
|
{
|
||||||
|
visibleJoinTables.add(tableForField.name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (visibleJoinTables);
|
||||||
|
};
|
||||||
|
|
||||||
if (!asyncLoadInited)
|
if (!asyncLoadInited)
|
||||||
{
|
{
|
||||||
setAsyncLoadInited(true);
|
setAsyncLoadInited(true);
|
||||||
@ -368,13 +394,20 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
setActiveModalProcess(launchingProcess);
|
setActiveModalProcess(launchingProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queryJoins: QueryJoin[] = null;
|
||||||
|
const visibleJoinTables = getVisibleJoinTables(tableMetaData);
|
||||||
|
if(visibleJoinTables.size > 0)
|
||||||
|
{
|
||||||
|
queryJoins = TableUtils.getQueryJoins(tableMetaData, visibleJoinTables);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// load the record //
|
// load the record //
|
||||||
/////////////////////
|
/////////////////////
|
||||||
let record: QRecord;
|
let record: QRecord;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
record = await qController.get(tableName, id, tableVariant);
|
record = await qController.get(tableName, id, tableVariant, null, queryJoins);
|
||||||
setRecord(record);
|
setRecord(record);
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
@ -465,17 +498,22 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
const fields = (
|
const fields = (
|
||||||
<Box key={section.name} display="flex" flexDirection="column" py={1} pr={2}>
|
<Box key={section.name} display="flex" flexDirection="column" py={1} pr={2}>
|
||||||
{
|
{
|
||||||
section.fieldNames.map((fieldName: string) => (
|
section.fieldNames.map((fieldName: string) =>
|
||||||
<Box key={fieldName} flexDirection="row" pr={2}>
|
{
|
||||||
<Typography variant="button" textTransform="none" fontWeight="bold" pr={1} color="rgb(52, 71, 103)">
|
let [field, tableForField] = TableUtils.getFieldAndTable(tableMetaData, fieldName);
|
||||||
{tableMetaData.fields.get(fieldName).label}:
|
let label = field.label;
|
||||||
<div style={{display: "inline-block", width: 0}}> </div>
|
return (
|
||||||
</Typography>
|
<Box key={fieldName} flexDirection="row" pr={2}>
|
||||||
<Typography variant="button" textTransform="none" fontWeight="regular" color="rgb(123, 128, 154)">
|
<Typography variant="button" textTransform="none" fontWeight="bold" pr={1} color="rgb(52, 71, 103)">
|
||||||
{ValueUtils.getDisplayValue(tableMetaData.fields.get(fieldName), record, "view")}
|
{label}:
|
||||||
</Typography>
|
<div style={{display: "inline-block", width: 0}}> </div>
|
||||||
</Box>
|
</Typography>
|
||||||
))
|
<Typography variant="button" textTransform="none" fontWeight="regular" color="rgb(123, 128, 154)">
|
||||||
|
{ValueUtils.getDisplayValue(field, record, "view", fieldName)}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -31,6 +31,7 @@ import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilt
|
|||||||
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
||||||
import {ThisOrLastPeriodExpression} from "@kingsrook/qqq-frontend-core/lib/model/query/ThisOrLastPeriodExpression";
|
import {ThisOrLastPeriodExpression} from "@kingsrook/qqq-frontend-core/lib/model/query/ThisOrLastPeriodExpression";
|
||||||
import {GridFilterItem, GridFilterModel, GridLinkOperator, GridSortItem} from "@mui/x-data-grid-pro";
|
import {GridFilterItem, GridFilterModel, GridLinkOperator, GridSortItem} from "@mui/x-data-grid-pro";
|
||||||
|
import TableUtils from "qqq/utils/qqq/TableUtils";
|
||||||
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
||||||
|
|
||||||
const CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedFilterId";
|
const CURRENT_SAVED_FILTER_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedFilterId";
|
||||||
@ -375,10 +376,11 @@ class FilterUtils
|
|||||||
** Get the default filter to use on the page - either from given filter string, query string param, or
|
** Get the default filter to use on the page - either from given filter string, query string param, or
|
||||||
** local storage, or a default (empty).
|
** local storage, or a default (empty).
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static async determineFilterAndSortModels(qController: QController, tableMetaData: QTableMetaData, filterString: string, searchParams: URLSearchParams, filterLocalStorageKey: string, sortLocalStorageKey: string): Promise<{ filter: GridFilterModel, sort: GridSortItem[] }>
|
public static async determineFilterAndSortModels(qController: QController, tableMetaData: QTableMetaData, filterString: string, searchParams: URLSearchParams, filterLocalStorageKey: string, sortLocalStorageKey: string): Promise<{ filter: GridFilterModel, sort: GridSortItem[], warning: string }>
|
||||||
{
|
{
|
||||||
let defaultFilter = {items: []} as GridFilterModel;
|
let defaultFilter = {items: []} as GridFilterModel;
|
||||||
let defaultSort = [] as GridSortItem[];
|
let defaultSort = [] as GridSortItem[];
|
||||||
|
let warningParts = [] as string[];
|
||||||
|
|
||||||
if (tableMetaData && tableMetaData.fields !== undefined)
|
if (tableMetaData && tableMetaData.fields !== undefined)
|
||||||
{
|
{
|
||||||
@ -396,30 +398,11 @@ class FilterUtils
|
|||||||
for (let i = 0; i < qQueryFilter?.criteria?.length; i++)
|
for (let i = 0; i < qQueryFilter?.criteria?.length; i++)
|
||||||
{
|
{
|
||||||
const criteria = qQueryFilter.criteria[i];
|
const criteria = qQueryFilter.criteria[i];
|
||||||
let fieldTable = tableMetaData;
|
let [field, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, criteria.fieldName);
|
||||||
let field = null;
|
|
||||||
if (criteria.fieldName.indexOf(".") > -1)
|
|
||||||
{
|
|
||||||
const nameParts = criteria.fieldName.split(".", 2);
|
|
||||||
for (let i = 0; i < tableMetaData?.exposedJoins?.length; i++)
|
|
||||||
{
|
|
||||||
const joinTable = tableMetaData.exposedJoins[i].joinTable;
|
|
||||||
if (joinTable.name == nameParts[0])
|
|
||||||
{
|
|
||||||
fieldTable = joinTable;
|
|
||||||
field = joinTable.fields.get(nameParts[1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
field = tableMetaData.fields.get(criteria.fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field == null)
|
if (field == null)
|
||||||
{
|
{
|
||||||
console.log("Couldn't find field for filter: " + criteria.fieldName);
|
console.log("Couldn't find field for filter: " + criteria.fieldName);
|
||||||
|
warningParts.push("Your filter contained an unrecognized field name: " + criteria.fieldName)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +483,7 @@ class FilterUtils
|
|||||||
localStorage.setItem(sortLocalStorageKey, JSON.stringify(defaultSort));
|
localStorage.setItem(sortLocalStorageKey, JSON.stringify(defaultSort));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ({filter: defaultFilter, sort: defaultSort});
|
return ({filter: defaultFilter, sort: defaultSort, warning: warningParts.length > 0 ? "Warning: " + warningParts.join("; ") : ""});
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
@ -551,7 +534,7 @@ class FilterUtils
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ({filter: defaultFilter, sort: defaultSort});
|
return ({filter: defaultFilter, sort: defaultSort, warning: warningParts.length > 0 ? "Warning: " + warningParts.join("; ") : ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,8 +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 {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
||||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||||
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
||||||
|
import {QueryJoin} from "@kingsrook/qqq-frontend-core/lib/model/query/QueryJoin";
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Utility class for working with QQQ Tables
|
** Utility class for working with QQQ Tables
|
||||||
@ -28,7 +30,6 @@ import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTa
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
class TableUtils
|
class TableUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -85,6 +86,61 @@ class TableUtils
|
|||||||
})]);
|
})]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static getFieldAndTable(tableMetaData: QTableMetaData, fieldName: string): [QFieldMetaData, QTableMetaData]
|
||||||
|
{
|
||||||
|
if (fieldName.indexOf(".") > -1)
|
||||||
|
{
|
||||||
|
const nameParts = fieldName.split(".", 2);
|
||||||
|
for (let i = 0; i < tableMetaData?.exposedJoins?.length; i++)
|
||||||
|
{
|
||||||
|
const join = tableMetaData?.exposedJoins[i];
|
||||||
|
if (join?.joinTable.name == nameParts[0])
|
||||||
|
{
|
||||||
|
return ([join.joinTable.fields.get(nameParts[1]), join.joinTable]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ([tableMetaData.fields.get(fieldName), tableMetaData]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static getQueryJoins(tableMetaData: QTableMetaData, visibleJoinTables: Set<string>): QueryJoin[]
|
||||||
|
{
|
||||||
|
const queryJoins = [];
|
||||||
|
for (let i = 0; i < tableMetaData.exposedJoins.length; i++)
|
||||||
|
{
|
||||||
|
const join = tableMetaData.exposedJoins[i];
|
||||||
|
if (visibleJoinTables.has(join.joinTable.name))
|
||||||
|
{
|
||||||
|
let joinName = null;
|
||||||
|
if (join.joinPath && join.joinPath.length == 1 && join.joinPath[0].name)
|
||||||
|
{
|
||||||
|
joinName = join.joinPath[0].name;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// todo - what about a join with a longer path? it would be nice to pass such joinNames through there too, //
|
||||||
|
// but what, that would actually be multiple queryJoins? needs a fair amount of thought. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
queryJoins.push(new QueryJoin(join.joinTable.name, true, "LEFT", null, null, joinName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryJoins;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TableUtils;
|
export default TableUtils;
|
||||||
|
Reference in New Issue
Block a user