Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 4x 31x 4x 28x 28x 28x 28x 28x 31x 31x 6x 6x 4x 6x 25x 28x 4x 222x 222x 5214x 222x 222x 2607x 2607x 2607x 2607x 222x | import { isEmpty, mapKeys } from 'lodash'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { RENAMED_FILTER_KEYS_DEFAULT } from 'ee/issues_analytics/constants'; import { dateFormats } from '~/analytics/shared/constants'; import dateFormat from '~/lib/dateformat'; import { getMonthNames, newDate } from '~/lib/utils/datetime_utility'; /** * Returns an object with renamed filter keys. * * @param {Object} filters - Filters with keys to be renamed * @param {Object} newKeys - Map of old keys to new keys * * @returns {Object} */ const renameFilterKeys = (filters, newKeys) => mapKeys(filters, (value, key) => newKeys[key] ?? key); /** * This util method takes the global page filters and transforms parameters which * are not standardized between the internal issue analytics api and the public * issues api. * * @param {Object} filters - the global filters used to fetch issues data * @param {Object} renamedKeys - map of keys to be renamed * * @returns {Object} - the transformed filters for the public api */ export const transformFilters = (filters = {}, renamedKeys = RENAMED_FILTER_KEYS_DEFAULT) => { let formattedFilters = convertObjectPropsToCamelCase(filters, { deep: true, dropKeys: ['scope', 'include_subepics'], }); Eif (!isEmpty(renamedKeys)) { formattedFilters = renameFilterKeys(formattedFilters, renamedKeys); } const newFilters = {}; Object.entries(formattedFilters).forEach(([key, val]) => { const negatedFilterMatch = key.match(/^not\[(.+)\]/); if (negatedFilterMatch) { const negatedFilterKey = negatedFilterMatch[1]; if (!newFilters.not) { newFilters.not = {}; } Object.assign(newFilters.not, { [negatedFilterKey]: val }); } else { newFilters[key] = val; } }); return newFilters; }; /** * @typedef {Object} monthDataItem * @property {Date} fromDate * @property {Date} toDate * @property {String} month - abbreviated month * @property {Number} year */ /** * Accepts a date range and an Issue Analytics count query type and * generates the data needed to build the GraphQL query for the chart * * @param startDate - start date for the date range * @param endDate - end date for the date range * @param format - format to be used by date range * @return {monthDataItem[]} - date range data */ export const generateChartDateRangeData = (startDate, endDate, format = dateFormats.isoDate) => { const chartDateRangeData = []; const abbrMonthNames = getMonthNames(true); const formatDate = (date) => dateFormat(date, format, true); for ( let fromDate = newDate(startDate); fromDate < endDate; fromDate.setMonth(fromDate.getMonth() + 1, 1) ) { let toDate = newDate(fromDate); toDate.setMonth(toDate.getMonth() + 1, 1); if (toDate > endDate) toDate = endDate; chartDateRangeData.push({ fromDate: formatDate(fromDate), toDate: formatDate(toDate), month: abbrMonthNames[fromDate.getMonth()], year: fromDate.getFullYear(), }); } return chartDateRangeData; }; |