mirror of
https://github.com/ansible/awx.git
synced 2026-01-15 11:50:42 -03:30
* use qs utils to namespace query params * refactor Lookup and SelectResource Steps to use PaginatedDataList * preserve query params when adding new ones * require namespace for QS Configs
114 lines
2.9 KiB
JavaScript
114 lines
2.9 KiB
JavaScript
/**
|
|
* Convert query param object to url query string
|
|
*
|
|
* @param {object} query param object
|
|
* @return {string} url query string
|
|
*/
|
|
export const encodeQueryString = (params) => {
|
|
if (!params) {
|
|
return '';
|
|
}
|
|
|
|
return Object.keys(params)
|
|
.sort()
|
|
.filter(key => params[key] !== null)
|
|
.map(key => ([key, params[key]]))
|
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
|
.join('&');
|
|
};
|
|
|
|
/**
|
|
* Convert url query string to query param object
|
|
*
|
|
* @param {string} url query string
|
|
* @param {object} default params
|
|
* @param {array} array of keys to parse as integers
|
|
* @return {object} query param object
|
|
*/
|
|
export const parseQueryString = (queryString, integerFields = ['page', 'page_size']) => {
|
|
if (!queryString) return {};
|
|
|
|
const keyValuePairs = queryString.replace(/^\?/, '').split('&')
|
|
.map(s => s.split('='))
|
|
.map(([key, value]) => {
|
|
if (integerFields.includes(key)) {
|
|
return [key, parseInt(value, 10)];
|
|
}
|
|
|
|
return [key, value];
|
|
});
|
|
|
|
return Object.assign(...keyValuePairs.map(([k, v]) => ({ [k]: v })));
|
|
};
|
|
|
|
export function getQSConfig (
|
|
namespace,
|
|
defaultParams = { page: 1, page_size: 5, order_by: 'name' },
|
|
integerFields = ['page', 'page_size']
|
|
) {
|
|
if (!namespace) {
|
|
throw new Error('a QS namespace is required');
|
|
}
|
|
return {
|
|
defaultParams,
|
|
namespace,
|
|
integerFields,
|
|
};
|
|
}
|
|
|
|
export function encodeNamespacedQueryString (config, params) {
|
|
return encodeQueryString(namespaceParams(config.namespace, params));
|
|
}
|
|
|
|
export function parseNamespacedQueryString (config, queryString, includeDefaults = true) {
|
|
const integerFields = prependNamespaceToArray(config.namespace, config.integerFields);
|
|
const parsed = parseQueryString(queryString, integerFields);
|
|
|
|
const namespace = {};
|
|
Object.keys(parsed).forEach(field => {
|
|
if (namespaceMatches(config.namespace, field)) {
|
|
let fieldname = field;
|
|
if (config.namespace) {
|
|
fieldname = field.substr(config.namespace.length + 1);
|
|
}
|
|
namespace[fieldname] = parsed[field];
|
|
}
|
|
});
|
|
return {
|
|
...includeDefaults ? config.defaultParams : {},
|
|
...namespace,
|
|
};
|
|
}
|
|
|
|
export function updateNamespacedQueryString (config, queryString, newParams) {
|
|
const params = parseQueryString(queryString);
|
|
return encodeQueryString({
|
|
...params,
|
|
...namespaceParams(config.namespace, newParams),
|
|
});
|
|
}
|
|
|
|
function namespaceParams (ns, params) {
|
|
if (!ns) return params;
|
|
|
|
const namespaced = {};
|
|
Object.keys(params).forEach(key => {
|
|
namespaced[`${ns}.${key}`] = params[key];
|
|
});
|
|
return namespaced;
|
|
}
|
|
|
|
function namespaceMatches (namespace, fieldname) {
|
|
if (!namespace) {
|
|
return !fieldname.includes('.');
|
|
}
|
|
return fieldname.startsWith(`${namespace}.`);
|
|
}
|
|
|
|
function prependNamespaceToArray (namespace, arr) {
|
|
if (!namespace) {
|
|
return arr;
|
|
}
|
|
return arr.map(f => `${namespace}.${f}`);
|
|
}
|