@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
348 lines (343 loc) • 11.8 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _enum = require('../components/_filters/filter-input/enum.js');
var utils$2 = require('../components/_inputs/date-range/utils.js');
var utils$1 = require('../components/_inputs/granular-date-range/utils.js');
var utils$3 = require('../components/_inputs/multi-select/utils.js');
var utils = require('../components/_reports/report-heading/report-columns/report-columns-form/utils.js');
var UserReports = require('../types/UserReports.js');
var logger = require('./logger.js');
var queryMappers = require('./queryMappers.js');
/**
* Gets the definition and fields by reportType
*
* @param {ReportType} reportType
* @param {Services} services
* @param {string} token
* @param {string} reportId
* @param {string} id
* @param {string} [definitionsPath]
*/
const getDefinitionByType = async (reportType, services, token, reportId, id, definitionsPath, queryData) => {
let definition;
let fields;
if (reportType === UserReports.ReportType.REPORT) {
definition = await services.reportingService.getDefinition(token, reportId, id, definitionsPath, queryData);
fields = getFields(definition);
}
else {
definition = await services.dashboardService.getDefinition(token, reportId, id, definitionsPath, queryData);
fields = getDashboardFields(definition);
}
if (!definition) {
throw Error(`Unable to retrieve definition for ${reportType} with id:${id} & reportId:${reportId}`);
}
return {
definition,
fields,
};
};
/**
* Given a field id, gets its filter object
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @param {string} fieldId
* @return {*} {(components['schemas']['FilterDefinition'] | undefined)}
*/
const getFilter = (fields, fieldId) => {
return fields.find(f => f.name === fieldId)?.filter;
};
/**
* Gets the current varaint definition
*
* @param {components['schemas']['ReportDefinitionSummary'][]} definitions
* @param {string} reportId
* @param {string} variantId
* @return {*} {(components['schemas']['VariantDefinition'] | undefined)}
*/
const getCurrentVariantDefinition = (definitions, reportId, variantId) => {
if (!definitions) {
logger.default.info('No definitions');
return undefined;
}
let variantDef;
const reportDef = definitions.find((report) => report.id === reportId);
if (reportDef) {
// TODO: this needs fixing, we should never be using `as unknown as`, but the types are very mixed up here
variantDef = reportDef.variants.find(variant => variantId === variant.id);
return variantDef;
}
return undefined;
};
/**
* Gets the display name of a field
*
* @param {(components['schemas']['FieldDefinition'][] | components['schemas']['SummaryField'][])} fields
* @param {string} fieldId
* @return {*}
*/
const getFieldDisplayName = (fields, fieldId) => {
const ids = fieldId.split('.');
const field = fields.find(f => {
return f.name === ids[0];
});
if (field) {
return ids[1] ? `${field.display} ${ids[1]}` : field.display;
}
return fieldId;
};
/**
* Gets a single field by its id/name
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @param {string} fieldId
* @return {*}
*/
const getField = (fields, fieldId) => {
return fields.find(field => {
return field.name === fieldId;
});
};
/**
* Get all fields from a definition
*
* @param {components['schemas']['SingleVariantReportDefinition']} definition
* @return {*} {components['schemas']['FieldDefinition'][]}
*/
const getFields = (definition) => {
return definition.variant.specification?.fields || [];
};
/**
* Get all fields from a definition
*
* @param {components['schemas']['SingleVariantReportDefinition']} definition
* @return {*} {components['schemas']['FieldDefinition'][]}
*/
const getDashboardFields = (definition) => {
return definition.filterFields || [];
};
/**
* Gets only the fields that have filters, from fields
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*} {FieldWithFilter[]}
*/
const getFieldsWithFilters = (fields) => {
return fields.filter((f) => !!f.filter);
};
/**
* Gets the template type
*
* @param {components['schemas']['SingleVariantReportDefinition']} definition
* @return {*} {Template}
*/
const getTemplate = (definition) => {
return definition.variant.specification?.template || 'list';
};
/**
* Gets the filters from a variant
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*} {components['schemas']['FilterDefinition'][]}
*/
const getFilters = (fields) => {
const filters = fields
.filter((field) => field.filter)
.map((field) => field.filter);
return filters.length ? filters : [];
};
/**
* Given an array of string names, will return the relative field types
*
* @param {string[]} names
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*} {components['schemas']['FieldDefinition'][]}
*/
const getFieldsByName = (names, fields) => {
return names.map(s => fields.find(field => field.name === s)).filter(field => field !== undefined);
};
/**
* Validates the definition
*
* @param {components['schemas']['SingleVariantReportDefinition']} definition
* @return {*}
*/
const validateDefinition = (definition) => {
const { variant } = definition;
return validateVariant(variant, definition.id);
};
/**
* Validates that the variant has a `specification`
*
* @param {components['schemas']['VariantDefinition']} variant
* @return {*}
*/
const validateVariant = (variant, defId) => {
const { specification } = variant;
if (!specification) {
logger.default.error(`No specification found for definition ID: ${defId} variant ID: ${variant.id}`);
throw new Error(`No specification found for definition ID: ${defId} variant ID: ${variant.id}`);
}
return { variant, specification };
};
/**
* Determines whether there are any interactive filters
* defined in the definition
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*}
*/
const hasInteractiveFilters = (fields) => {
const filters = getFilters(fields);
return filters.some(filter => filter.interactive);
};
const getReportSummary = (reportId, reportingService, token, definitionPath) => reportingService.getDefinitionSummary(token, reportId, definitionPath);
/**
* Creates a the default filters querystring
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*} {DefaultFilterQueryStrings}
*/
const getDefaultFiltersQueryString = (fields) => {
const defaultParams = new URLSearchParams();
const interactiveParams = new URLSearchParams();
const fieldsWithFilters = getFieldsWithFilters(fields);
fieldsWithFilters.forEach(field => {
const { interactive = false } = field.filter;
appendFilterDefaults(interactive ? interactiveParams : defaultParams, field);
});
return {
defaultFiltersSearch: buildQueryString(defaultParams),
interactiveDefaultFiltersSearch: buildQueryString(interactiveParams),
};
};
/**
* Sets the default sort query string
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*}
*/
const getDefaultSortQueryString = (fields) => {
const defaultSortField = fields.find(field => field.defaultsort);
if (!defaultSortField) {
return '';
}
const defaultSortParams = new URLSearchParams();
const isAsc = (defaultSortField.sortDirection ?? 'asc') === 'asc';
defaultSortParams.set('sortColumn', defaultSortField.name);
defaultSortParams.set('sortedAsc', String(isAsc));
return buildQueryString(defaultSortParams);
};
/**
* Builds the querystring
*
* @param {URLSearchParams} params
* @return {*} {string}
*/
const buildQueryString = (params) => {
const qs = params.toString();
return qs || '';
};
/**
* Appends the filter value to a query string
*
* @param {URLSearchParams} params
* @param {FieldWithFilter} field
*/
const appendFilterDefaults = (params, field) => {
const { name, filter } = field;
const { type, defaultValue, defaultQuickFilterValue } = filter;
if (!defaultValue && !defaultQuickFilterValue)
return;
switch (type.toLowerCase()) {
case _enum.FilterType.radio.toLowerCase():
case _enum.FilterType.select.toLowerCase():
case _enum.FilterType.text.toLowerCase():
case _enum.FilterType.date.toLowerCase():
case _enum.FilterType.autocomplete.toLowerCase(): {
if (!defaultValue)
break;
params.append(`filters.${name}`, defaultValue);
break;
}
case _enum.FilterType.autocompleteMulti.toLowerCase():
case _enum.FilterType.multiselect.toLowerCase(): {
if (!defaultValue)
break;
utils$3.appendMultiSelectValues(params, name, defaultValue);
break;
}
case _enum.FilterType.dateRange.toLowerCase(): {
const resolved = utils$2.resolveDateRangeDefaults(filter);
if (!resolved)
break;
utils$2.appendDateRangeValue(params, name, resolved);
break;
}
case _enum.FilterType.granularDateRange.toLowerCase(): {
const resolved = utils$1.resolveGranularDateRangeDefaults(filter);
if (!resolved)
break;
utils$1.appendGranularDateRangeValue(params, name, resolved);
break;
}
}
};
/**
* Get the default columns from the DPD
* and creates a querystring
*
* @param {components['schemas']['FieldDefinition'][]} fields
* @return {*}
*/
const getDefaultColumnsQueryString = (fields) => {
const visibleCols = utils.visibleColumns(fields);
const mandatoryCols = utils.mandatoryColumns(fields);
const defaultColumns = Array.from(new Set([...mandatoryCols, ...visibleCols]));
const params = new URLSearchParams();
defaultColumns.forEach(column => {
params.append('columns', column);
});
return buildQueryString(params);
};
/**
* Get the definition path from the query
*
* @param {Record<string, unknown>} query
*/
const getDefinitionsPath = (query) => queryMappers.getQueryParamAsString(query, 'dataProductDefinitionsPath');
var DefinitionUtils = {
getCurrentVariantDefinition,
getFieldDisplayName,
getField,
getFields,
getTemplate,
getFilter,
getFilters,
getReportSummary,
hasInteractiveFilters,
getDefaultFiltersQueryString,
getDefaultColumnsQueryString,
getDefinitionByType,
};
exports.default = DefinitionUtils;
exports.getCurrentVariantDefinition = getCurrentVariantDefinition;
exports.getDashboardFields = getDashboardFields;
exports.getDefaultColumnsQueryString = getDefaultColumnsQueryString;
exports.getDefaultFiltersQueryString = getDefaultFiltersQueryString;
exports.getDefaultSortQueryString = getDefaultSortQueryString;
exports.getDefinitionByType = getDefinitionByType;
exports.getDefinitionsPath = getDefinitionsPath;
exports.getField = getField;
exports.getFieldDisplayName = getFieldDisplayName;
exports.getFields = getFields;
exports.getFieldsByName = getFieldsByName;
exports.getFieldsWithFilters = getFieldsWithFilters;
exports.getFilter = getFilter;
exports.getFilters = getFilters;
exports.getReportSummary = getReportSummary;
exports.getTemplate = getTemplate;
exports.hasInteractiveFilters = hasInteractiveFilters;
exports.validateDefinition = validateDefinition;
exports.validateVariant = validateVariant;
//# sourceMappingURL=definitionUtils.js.map