debian-mirror-gitlab/app/assets/javascripts/runner/runner_search_utils.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

254 lines
6.6 KiB
JavaScript
Raw Normal View History

2022-08-27 11:52:29 +05:30
import { isEmpty } from 'lodash';
2021-09-04 01:27:46 +05:30
import { queryToObject, setUrlParams } from '~/lib/utils/url_utility';
import {
filterToQueryObject,
processFilters,
urlQueryToFilter,
prepareTokens,
} from '~/vue_shared/components/filtered_search_bar/filtered_search_utils';
2022-06-21 17:19:12 +05:30
import { parseBoolean } from '~/lib/utils/common_utils';
2021-09-04 01:27:46 +05:30
import {
2022-06-21 17:19:12 +05:30
PARAM_KEY_PAUSED,
2021-09-04 01:27:46 +05:30
PARAM_KEY_STATUS,
PARAM_KEY_RUNNER_TYPE,
2021-09-30 23:02:18 +05:30
PARAM_KEY_TAG,
PARAM_KEY_SEARCH,
2021-09-04 01:27:46 +05:30
PARAM_KEY_SORT,
PARAM_KEY_AFTER,
PARAM_KEY_BEFORE,
DEFAULT_SORT,
RUNNER_PAGE_SIZE,
2021-10-27 15:23:28 +05:30
} from './constants';
2022-04-04 11:22:00 +05:30
import { getPaginationVariables } from './utils';
2021-09-04 01:27:46 +05:30
2021-12-11 22:18:48 +05:30
/**
* The filters and sorting of the runners are built around
* an object called "search" that contains the current state
* of search in the UI. For example:
*
* ```
* const search = {
* // The current tab
* runnerType: 'INSTANCE_TYPE',
*
* // Filters in the search bar
* filters: [
* { type: 'status', value: { data: 'ACTIVE', operator: '=' } },
* { type: 'filtered-search-term', value: { data: '' } },
* ],
*
* // Current sorting value
* sort: 'CREATED_DESC',
*
* // Pagination information
2022-08-27 11:52:29 +05:30
* pagination: { "after": "..." },
2021-12-11 22:18:48 +05:30
* };
* ```
*
* An object in this format can be used to generate URLs
* with the search parameters or by runner components
* a input using a v-model.
*
* @module runner_search_utils
*/
/**
* Validates a search value
* @param {Object} search
* @returns {boolean} True if the value follows the search format.
*/
export const searchValidator = ({ runnerType, filters, sort }) => {
return (
(runnerType === null || typeof runnerType === 'string') &&
Array.isArray(filters) &&
typeof sort === 'string'
);
};
2021-09-04 01:27:46 +05:30
const getPaginationFromParams = (params) => {
return {
2022-08-27 11:52:29 +05:30
after: params[PARAM_KEY_AFTER],
before: params[PARAM_KEY_BEFORE],
2021-09-04 01:27:46 +05:30
};
};
2022-03-02 08:16:31 +05:30
// Outdated URL parameters
2022-06-21 17:19:12 +05:30
const STATUS_ACTIVE = 'ACTIVE';
const STATUS_PAUSED = 'PAUSED';
2022-08-27 11:52:29 +05:30
const PARAM_KEY_PAGE = 'page';
2022-06-21 17:19:12 +05:30
/**
* Replaces params into a URL
*
* @param {String} url - Original URL
* @param {Object} params - Query parameters to update
* @returns Updated URL
*/
const updateUrlParams = (url, params = {}) => {
return setUrlParams(params, url, false, true, true);
};
2022-03-02 08:16:31 +05:30
2022-08-27 11:52:29 +05:30
const outdatedStatusParams = (status) => {
if (status === STATUS_ACTIVE) {
return {
[PARAM_KEY_PAUSED]: ['false'],
[PARAM_KEY_STATUS]: [], // Important! clear PARAM_KEY_STATUS to avoid a redirection loop!
};
} else if (status === STATUS_PAUSED) {
return {
[PARAM_KEY_PAUSED]: ['true'],
[PARAM_KEY_STATUS]: [], // Important! clear PARAM_KEY_STATUS to avoid a redirection loop!
};
}
return {};
};
2022-03-02 08:16:31 +05:30
/**
* Returns an updated URL for old (or deprecated) admin runner URLs.
*
* Use for redirecting users to currently used URLs.
*
* @param {String?} URL
* @returns Updated URL if outdated, `null` otherwise
*/
export const updateOutdatedUrl = (url = window.location.href) => {
const urlObj = new URL(url);
const query = urlObj.search;
const params = queryToObject(query, { gatherArrays: true });
2022-08-27 11:52:29 +05:30
// Remove `page` completely, not needed for keyset pagination
const pageParams = PARAM_KEY_PAGE in params ? { [PARAM_KEY_PAGE]: null } : {};
const status = params[PARAM_KEY_STATUS]?.[0];
const redirectParams = {
// Replace paused status (active, paused) with a paused flag
...outdatedStatusParams(status),
...pageParams,
};
if (!isEmpty(redirectParams)) {
return updateUrlParams(url, redirectParams);
2022-03-02 08:16:31 +05:30
}
2022-08-27 11:52:29 +05:30
return null;
2022-03-02 08:16:31 +05:30
};
2021-12-11 22:18:48 +05:30
/**
* Takes a URL query and transforms it into a "search" object
* @param {String?} query
* @returns {Object} A search object
*/
2021-09-04 01:27:46 +05:30
export const fromUrlQueryToSearch = (query = window.location.search) => {
const params = queryToObject(query, { gatherArrays: true });
2021-12-11 22:18:48 +05:30
const runnerType = params[PARAM_KEY_RUNNER_TYPE]?.[0] || null;
2021-09-04 01:27:46 +05:30
return {
2021-12-11 22:18:48 +05:30
runnerType,
2021-09-04 01:27:46 +05:30
filters: prepareTokens(
urlQueryToFilter(query, {
2022-06-21 17:19:12 +05:30
filterNamesAllowList: [PARAM_KEY_PAUSED, PARAM_KEY_STATUS, PARAM_KEY_TAG],
2021-09-04 01:27:46 +05:30
filteredSearchTermKey: PARAM_KEY_SEARCH,
}),
),
sort: params[PARAM_KEY_SORT] || DEFAULT_SORT,
pagination: getPaginationFromParams(params),
};
};
2021-12-11 22:18:48 +05:30
/**
* Takes a "search" object and transforms it into a URL.
*
* @param {Object} search
* @param {String} url
* @returns {String} New URL for the page
*/
2021-09-04 01:27:46 +05:30
export const fromSearchToUrl = (
2021-12-11 22:18:48 +05:30
{ runnerType = null, filters = [], sort = null, pagination = {} },
2021-09-04 01:27:46 +05:30
url = window.location.href,
) => {
const filterParams = {
// Defaults
[PARAM_KEY_STATUS]: [],
[PARAM_KEY_RUNNER_TYPE]: [],
2021-09-30 23:02:18 +05:30
[PARAM_KEY_TAG]: [],
2021-09-04 01:27:46 +05:30
// Current filters
...filterToQueryObject(processFilters(filters), {
filteredSearchTermKey: PARAM_KEY_SEARCH,
}),
};
2021-12-11 22:18:48 +05:30
if (runnerType) {
filterParams[PARAM_KEY_RUNNER_TYPE] = [runnerType];
}
2021-09-30 23:02:18 +05:30
if (!filterParams[PARAM_KEY_SEARCH]) {
filterParams[PARAM_KEY_SEARCH] = null;
}
2021-09-04 01:27:46 +05:30
const isDefaultSort = sort !== DEFAULT_SORT;
const otherParams = {
// Sorting & Pagination
[PARAM_KEY_SORT]: isDefaultSort ? sort : null,
2022-08-27 11:52:29 +05:30
[PARAM_KEY_BEFORE]: pagination?.before || null,
[PARAM_KEY_AFTER]: pagination?.after || null,
2021-09-04 01:27:46 +05:30
};
return setUrlParams({ ...filterParams, ...otherParams }, url, false, true, true);
};
2021-12-11 22:18:48 +05:30
/**
* Takes a "search" object and transforms it into variables for runner a GraphQL query.
*
* @param {Object} search
* @returns {Object} Hash of filter values
*/
export const fromSearchToVariables = ({
runnerType = null,
filters = [],
sort = null,
pagination = {},
} = {}) => {
2022-04-04 11:22:00 +05:30
const filterVariables = {};
2021-09-04 01:27:46 +05:30
const queryObj = filterToQueryObject(processFilters(filters), {
filteredSearchTermKey: PARAM_KEY_SEARCH,
});
2022-04-04 11:22:00 +05:30
[filterVariables.status] = queryObj[PARAM_KEY_STATUS] || [];
filterVariables.search = queryObj[PARAM_KEY_SEARCH];
filterVariables.tagList = queryObj[PARAM_KEY_TAG];
2021-09-30 23:02:18 +05:30
2022-06-21 17:19:12 +05:30
if (queryObj[PARAM_KEY_PAUSED]) {
filterVariables.paused = parseBoolean(queryObj[PARAM_KEY_PAUSED]);
} else {
filterVariables.paused = undefined;
}
2021-12-11 22:18:48 +05:30
if (runnerType) {
2022-04-04 11:22:00 +05:30
filterVariables.type = runnerType;
2021-12-11 22:18:48 +05:30
}
2021-09-04 01:27:46 +05:30
if (sort) {
2022-04-04 11:22:00 +05:30
filterVariables.sort = sort;
2021-09-04 01:27:46 +05:30
}
2022-04-04 11:22:00 +05:30
const paginationVariables = getPaginationVariables(pagination, RUNNER_PAGE_SIZE);
2021-09-04 01:27:46 +05:30
2022-04-04 11:22:00 +05:30
return {
...filterVariables,
...paginationVariables,
};
2021-09-04 01:27:46 +05:30
};
2022-07-23 23:45:48 +05:30
/**
* Decides whether or not a search object is the "default" or empty.
*
* A search is filtered if the user has entered filtering criteria.
*
* @param {Object} search
* @returns true if this search is filtered, false otherwise
*/
export const isSearchFiltered = ({ runnerType = null, filters = [], pagination = {} } = {}) => {
return Boolean(
2022-08-27 11:52:29 +05:30
runnerType !== null || filters?.length !== 0 || pagination?.before || pagination?.after,
2022-07-23 23:45:48 +05:30
);
};