@awsui/components-react
Version:
On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en
213 lines • 10.2 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { fireNonCancelableEvent } from '../internal/events';
import { operatorToDescription } from './i18n-utils';
import { matchFilteringProperty, matchOperator, matchOperatorPrefix, matchTokenValue, removeOperator, tokenGroupToTokens, trimStart, } from './utils';
export const getQueryActions = ({ query, onChange, filteringOptions, enableTokenGroups, }) => {
const setQuery = (query) => {
function transformToken(token) {
if ('operator' in token) {
return matchTokenValue(token, filteringOptions);
}
return Object.assign(Object.assign({}, token), { tokens: token.tokens.map(transformToken) });
}
const tokens = query.tokens.map(transformToken);
if (enableTokenGroups) {
fireNonCancelableEvent(onChange, { tokens: [], operation: query.operation, tokenGroups: tokens });
}
else {
fireNonCancelableEvent(onChange, { tokens: tokenGroupToTokens(tokens), operation: query.operation });
}
};
const addToken = (token) => {
setQuery(Object.assign(Object.assign({}, query), { tokens: [...query.tokens, token] }));
};
const updateToken = (updateIndex, updatedToken, releasedTokens) => {
const nestedTokens = tokenGroupToTokens([updatedToken]);
const capturedTokenIndices = nestedTokens.map(token => token.standaloneIndex).filter(index => index !== undefined);
const tokens = query.tokens
.map((token, index) => (index === updateIndex ? updatedToken : token))
.filter((_, index) => index === updateIndex || !capturedTokenIndices.includes(index));
tokens.push(...releasedTokens);
setQuery(Object.assign(Object.assign({}, query), { tokens }));
};
const removeToken = (removeIndex) => {
setQuery(Object.assign(Object.assign({}, query), { tokens: query.tokens.filter((_, index) => index !== removeIndex) }));
};
const removeAllTokens = () => {
setQuery(Object.assign(Object.assign({}, query), { tokens: [] }));
};
const updateOperation = (operation) => {
setQuery(Object.assign(Object.assign({}, query), { operation }));
};
return { addToken, updateToken, updateOperation, removeToken, removeAllTokens };
};
export const getAllowedOperators = (property) => {
const { operators = [], defaultOperator } = property;
const operatorOrder = ['=', '!=', ':', '!:', '^', '!^', '>=', '<=', '<', '>'];
const operatorSet = new Set([defaultOperator, ...operators]);
return operatorOrder.filter(op => operatorSet.has(op));
};
/*
* parses the value of the filtering input to figure out the current step of entering the token:
* - "property": means that a filter on a particular column is being added, with operator already finalized
* - "operator": means that a filter on a particular column is being added, with operator not yet finalized
* - "free-text": means that a "free text" token is being added
*/
export const parseText = (filteringText, filteringProperties, freeTextFiltering) => {
const property = matchFilteringProperty(filteringProperties, filteringText);
if (!property) {
if (!freeTextFiltering.disabled) {
// For free text filtering, we allow ! as a shortcut for !:
const freeTextOperators = freeTextFiltering.operators.indexOf('!:') >= 0
? ['!', ...freeTextFiltering.operators]
: freeTextFiltering.operators;
const operator = matchOperator(freeTextOperators, filteringText);
if (operator) {
return {
step: 'free-text',
operator: operator === '!' ? '!:' : operator,
value: removeOperator(filteringText, operator),
};
}
}
return {
step: 'free-text',
value: filteringText,
};
}
const allowedOps = getAllowedOperators(property);
const textWithoutProperty = filteringText.substring(property.propertyLabel.length);
const operator = matchOperator(allowedOps, trimStart(textWithoutProperty));
if (operator) {
return {
step: 'property',
property,
operator,
value: removeOperator(textWithoutProperty, operator),
};
}
const operatorPrefix = matchOperatorPrefix(allowedOps, trimStart(textWithoutProperty));
if (operatorPrefix !== null) {
return { step: 'operator', property, operatorPrefix };
}
return {
step: 'free-text',
value: filteringText,
};
};
const getAllValueSuggestions = (filteringOptions, operator = '=', i18nStrings, customGroupsText) => {
var _a;
const defaultGroup = {
label: (_a = i18nStrings.groupValuesText) !== null && _a !== void 0 ? _a : '',
options: [],
};
const customGroups = {};
filteringOptions.forEach(filteringOption => {
const property = filteringOption.property;
// given option refers to a non-existent filtering property
if (!property) {
return;
}
// this option's filtering property does not support current operator
if (getAllowedOperators(property).indexOf(operator) === -1) {
return;
}
if (property.propertyGroup && !customGroups[property.propertyGroup]) {
const label = customGroupsText.reduce((acc, customGroup) => (customGroup.group === property.propertyGroup ? customGroup.values : acc), '');
customGroups[property.propertyGroup] = {
label,
options: [],
};
}
const propertyGroup = property.propertyGroup ? customGroups[property.propertyGroup] : defaultGroup;
propertyGroup.options.push({
value: property.propertyLabel + ' ' + (operator || '=') + ' ' + filteringOption.value,
label: filteringOption.label,
__labelPrefix: property.propertyLabel + ' ' + (operator || '='),
});
});
return [defaultGroup, ...Object.keys(customGroups).map(group => customGroups[group])];
};
const filteringPropertyToAutosuggestOption = (filteringProperty) => ({
value: filteringProperty.propertyLabel,
label: filteringProperty.propertyLabel,
keepOpenOnSelect: true,
});
export function getPropertySuggestions(filteringProperties, customGroupsText, i18nStrings, filteringPropertyToOption) {
var _a;
const defaultGroup = {
label: (_a = i18nStrings.groupPropertiesText) !== null && _a !== void 0 ? _a : '',
options: [],
};
const customGroups = {};
filteringProperties.forEach(filteringProperty => {
const { propertyGroup } = filteringProperty;
let optionsGroup = defaultGroup;
if (propertyGroup) {
if (!customGroups[propertyGroup]) {
const label = customGroupsText.reduce((acc, customGroup) => (customGroup.group === propertyGroup ? customGroup.properties : acc), '');
customGroups[propertyGroup] = { options: [], label };
}
optionsGroup = customGroups[propertyGroup];
}
optionsGroup.options.push(filteringPropertyToOption(filteringProperty));
});
const defaultGroupArray = defaultGroup.options.length ? [defaultGroup] : [];
const customGroupsArray = Object.keys(customGroups).map(groupKey => customGroups[groupKey]);
return [...defaultGroupArray, ...customGroupsArray];
}
export const getAutosuggestOptions = (parsedText, filteringProperties, filteringOptions, customGroupsText, i18nStrings) => {
switch (parsedText.step) {
case 'property': {
const { propertyLabel, groupValuesLabel } = parsedText.property;
const options = filteringOptions.filter(o => o.property === parsedText.property);
return {
filterText: parsedText.value,
options: [
{
options: options.map(({ label, value }) => ({
value: propertyLabel + ' ' + parsedText.operator + ' ' + value,
label: label,
__labelPrefix: propertyLabel + ' ' + parsedText.operator,
})),
label: groupValuesLabel,
},
],
};
}
case 'operator': {
return {
filterText: parsedText.property.propertyLabel + ' ' + parsedText.operatorPrefix,
options: [
...getPropertySuggestions(filteringProperties, customGroupsText, i18nStrings, filteringPropertyToAutosuggestOption),
{
options: getAllowedOperators(parsedText.property).map(value => ({
value: parsedText.property.propertyLabel + ' ' + value + ' ',
label: parsedText.property.propertyLabel + ' ' + value,
description: operatorToDescription(value, i18nStrings),
keepOpenOnSelect: true,
})),
label: i18nStrings.operatorsText,
},
],
};
}
case 'free-text': {
const needsValueSuggestions = !!parsedText.value;
const needsPropertySuggestions = !(parsedText.step === 'free-text' && parsedText.operator === '!:');
return {
filterText: parsedText.value,
options: [
...(needsPropertySuggestions
? getPropertySuggestions(filteringProperties, customGroupsText, i18nStrings, filteringPropertyToAutosuggestOption)
: []),
...(needsValueSuggestions
? getAllValueSuggestions(filteringOptions, parsedText.operator, i18nStrings, customGroupsText)
: []),
],
};
}
}
};
//# sourceMappingURL=controller.js.map