diff options
Diffstat (limited to 'app/assets/javascripts/analytics/cycle_analytics/utils.js')
-rw-r--r-- | app/assets/javascripts/analytics/cycle_analytics/utils.js | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/app/assets/javascripts/analytics/cycle_analytics/utils.js b/app/assets/javascripts/analytics/cycle_analytics/utils.js new file mode 100644 index 00000000000..428bb11b950 --- /dev/null +++ b/app/assets/javascripts/analytics/cycle_analytics/utils.js @@ -0,0 +1,117 @@ +import { parseSeconds } from '~/lib/utils/datetime_utility'; +import { formatTimeAsSummary } from '~/lib/utils/datetime/date_format_utility'; + +/** + * Takes the stages and median data, combined with the selected stage, to build an + * array which is formatted to proivde the data required for the path navigation. + * + * @param {Array} stages - The stages available to the group / project + * @param {Object} medians - The median values for the stages available to the group / project + * @param {Object} stageCounts - The total item count for the stages available + * @param {Object} selectedStage - The currently selected stage + * @returns {Array} An array of stages formatted with data required for the path navigation + */ +export const transformStagesForPathNavigation = ({ + stages, + medians, + stageCounts = {}, + selectedStage, +}) => { + const formattedStages = stages.map((stage) => { + return { + metric: medians[stage?.id], + selected: stage?.id === selectedStage?.id, // Also could null === null cause an issue here? + stageCount: stageCounts && stageCounts[stage?.id], + icon: null, + ...stage, + }; + }); + + return formattedStages; +}; + +/** + * Takes a raw median value in seconds and converts it to a string representation + * ie. converts 172800 => 2d (2 days) + * + * @param {Number} Median - The number of seconds for the median calculation + * @returns {String} String representation ie 2w + */ +export const medianTimeToParsedSeconds = (value) => + formatTimeAsSummary({ + ...parseSeconds(value, { daysPerWeek: 7, hoursPerDay: 24 }), + seconds: value, + }); + +/** + * Takes the raw median value arrays and converts them into a useful object + * containing the string for display in the path navigation + * ie. converts [{ id: 'test', value: 172800 }] => { 'test': '2d' } + * + * @param {Array} Medians - Array of stage median objects, each contains a `id`, `value` and `error` + * @returns {Object} Returns key value pair with the stage name and its display median value + */ +export const formatMedianValues = (medians = []) => + medians.reduce((acc, { id, value = 0 }) => { + return { + ...acc, + [id]: value ? medianTimeToParsedSeconds(value) : '-', + }; + }, {}); + +export const filterStagesByHiddenStatus = (stages = [], isHidden = true) => + stages.filter(({ hidden = false }) => hidden === isHidden); + +/** + * @typedef {Object} MetricData + * @property {String} title - Title of the metric measured + * @property {String} value - String representing the decimal point value, e.g '1.5' + * @property {String} [unit] - String representing the decimal point value, e.g '1.5' + * + * @typedef {Object} TransformedMetricData + * @property {String} label - Title of the metric measured + * @property {String} value - String representing the decimal point value, e.g '1.5' + * @property {String} identifier - Slugified string based on the 'title' or the provided 'identifier' attribute + * @property {String} description - String to display for a description + * @property {String} unit - String representing the decimal point value, e.g '1.5' + */ + +const extractFeatures = (gon) => ({ + cycleAnalyticsForGroups: Boolean(gon?.licensed_features?.cycleAnalyticsForGroups), +}); + +/** + * Builds the initial data object for Value Stream Analytics with data loaded from the backend + * + * @param {Object} dataset - dataset object paseed to the frontend via data-* properties + * @returns {Object} - The initial data to load the app with + */ +export const buildCycleAnalyticsInitialData = ({ + fullPath, + requestPath, + projectId, + groupId, + groupPath, + labelsPath, + milestonesPath, + stage, + createdAfter, + createdBefore, + gon, +} = {}) => { + return { + projectId: parseInt(projectId, 10), + endpoints: { + requestPath, + fullPath, + labelsPath, + milestonesPath, + groupId: parseInt(groupId, 10), + groupPath, + }, + createdAfter: new Date(createdAfter), + createdBefore: new Date(createdBefore), + selectedStage: stage ? JSON.parse(stage) : null, + features: extractFeatures(gon), + }; +}; |