mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
Merge pull request #10798 from keithjgrant/7834-advanced-search-fix
Only allow legal/logical match types in advanced search
This commit is contained in:
@@ -9,6 +9,7 @@ import { CredentialsAPI } from 'api';
|
|||||||
import { getQSConfig, parseQueryString, mergeParams } from 'util/qs';
|
import { getQSConfig, parseQueryString, mergeParams } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import { required } from 'util/validators';
|
import { required } from 'util/validators';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import Popover from '../Popover';
|
import Popover from '../Popover';
|
||||||
|
|
||||||
import ContentError from '../ContentError';
|
import ContentError from '../ContentError';
|
||||||
@@ -59,9 +60,7 @@ function AdHocCredentialStep({ credentialTypeId }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [credentialTypeId, history.location.search]),
|
}, [credentialTypeId, history.location.search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Form, FormGroup } from '@patternfly/react-core';
|
|||||||
import { ExecutionEnvironmentsAPI } from 'api';
|
import { ExecutionEnvironmentsAPI } from 'api';
|
||||||
|
|
||||||
import { parseQueryString, getQSConfig, mergeParams } from 'util/qs';
|
import { parseQueryString, getQSConfig, mergeParams } from 'util/qs';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import Popover from '../Popover';
|
import Popover from '../Popover';
|
||||||
import ContentError from '../ContentError';
|
import ContentError from '../ContentError';
|
||||||
@@ -60,9 +61,7 @@ function AdHocExecutionEnvironmentStep({ organizationId }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [history.location.search, organizationId]),
|
}, [history.location.search, organizationId]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ import { getQSConfig, parseQueryString } from 'util/qs';
|
|||||||
import DataListToolbar from '../DataListToolbar';
|
import DataListToolbar from '../DataListToolbar';
|
||||||
import CheckboxListItem from '../CheckboxListItem';
|
import CheckboxListItem from '../CheckboxListItem';
|
||||||
import { SelectedList } from '../SelectedList';
|
import { SelectedList } from '../SelectedList';
|
||||||
import PaginatedTable, { HeaderCell, HeaderRow } from '../PaginatedTable';
|
import PaginatedTable, {
|
||||||
|
HeaderCell,
|
||||||
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
|
} from '../PaginatedTable';
|
||||||
|
|
||||||
const QS_Config = (sortColumns) =>
|
const QS_Config = (sortColumns) =>
|
||||||
getQSConfig('resource', {
|
getQSConfig('resource', {
|
||||||
@@ -56,9 +60,7 @@ function SelectResourceStep({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location, fetchItems, fetchOptions, sortColumns]),
|
}, [location, fetchItems, fetchOptions, sortColumns]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useHistory } from 'react-router-dom';
|
|||||||
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Button, Modal } from '@patternfly/react-core';
|
import { Button, Modal } from '@patternfly/react-core';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
@@ -53,9 +54,7 @@ function AssociateModal({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [fetchRequest, optionsRequest, history.location.search, displayKey]),
|
}, [fetchRequest, optionsRequest, history.location.search, displayKey]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
AngleRightIcon,
|
AngleRightIcon,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
} from '@patternfly/react-icons';
|
} from '@patternfly/react-icons';
|
||||||
import { SearchColumns, SortColumns, QSConfig } from 'types';
|
import { SearchColumns, SortColumns, QSConfig, SearchableKeys } from 'types';
|
||||||
import { KebabifiedProvider } from 'contexts/Kebabified';
|
import { KebabifiedProvider } from 'contexts/Kebabified';
|
||||||
import ExpandCollapse from '../ExpandCollapse';
|
import ExpandCollapse from '../ExpandCollapse';
|
||||||
import Search from '../Search';
|
import Search from '../Search';
|
||||||
@@ -200,7 +200,7 @@ DataListToolbar.propTypes = {
|
|||||||
clearAllFilters: PropTypes.func,
|
clearAllFilters: PropTypes.func,
|
||||||
qsConfig: QSConfig.isRequired,
|
qsConfig: QSConfig.isRequired,
|
||||||
searchColumns: SearchColumns.isRequired,
|
searchColumns: SearchColumns.isRequired,
|
||||||
searchableKeys: PropTypes.arrayOf(PropTypes.string),
|
searchableKeys: SearchableKeys,
|
||||||
relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
||||||
sortColumns: SortColumns,
|
sortColumns: SortColumns,
|
||||||
isAllSelected: PropTypes.bool,
|
isAllSelected: PropTypes.bool,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from '../PaginatedTable';
|
} from '../PaginatedTable';
|
||||||
import JobListItem from './JobListItem';
|
import JobListItem from './JobListItem';
|
||||||
import JobListCancelButton from './JobListCancelButton';
|
import JobListCancelButton from './JobListCancelButton';
|
||||||
@@ -80,9 +81,7 @@ function JobList({ defaultParams, showTypeColumn = false }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[location] // eslint-disable-line react-hooks/exhaustive-deps
|
[location] // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useField } from 'formik';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Alert, ToolbarItem } from '@patternfly/react-core';
|
import { Alert, ToolbarItem } from '@patternfly/react-core';
|
||||||
import { CredentialsAPI, CredentialTypesAPI } from 'api';
|
import { CredentialsAPI, CredentialTypesAPI } from 'api';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import AnsibleSelect from '../../AnsibleSelect';
|
import AnsibleSelect from '../../AnsibleSelect';
|
||||||
@@ -88,9 +89,7 @@ function CredentialsStep({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [selectedType, history.location.search]),
|
}, [selectedType, history.location.search]),
|
||||||
{ credentials: [], count: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
{ credentials: [], count: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useField } from 'formik';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Alert } from '@patternfly/react-core';
|
import { Alert } from '@patternfly/react-core';
|
||||||
import { InventoriesAPI } from 'api';
|
import { InventoriesAPI } from 'api';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import OptionsList from '../../OptionsList';
|
import OptionsList from '../../OptionsList';
|
||||||
@@ -45,9 +46,7 @@ function InventoryStep({ warningMessage = null }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [history.location]),
|
}, [history.location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
removeParams,
|
removeParams,
|
||||||
updateQueryString,
|
updateQueryString,
|
||||||
} from 'util/qs';
|
} from 'util/qs';
|
||||||
import { QSConfig, SearchColumns, SortColumns } from 'types';
|
import { QSConfig, SearchColumns, SortColumns, SearchableKeys } from 'types';
|
||||||
import DataListToolbar from '../DataListToolbar';
|
import DataListToolbar from '../DataListToolbar';
|
||||||
|
|
||||||
const EmptyStateControlsWrapper = styled.div`
|
const EmptyStateControlsWrapper = styled.div`
|
||||||
@@ -146,7 +146,7 @@ ListHeader.propTypes = {
|
|||||||
itemCount: PropTypes.number.isRequired,
|
itemCount: PropTypes.number.isRequired,
|
||||||
qsConfig: QSConfig.isRequired,
|
qsConfig: QSConfig.isRequired,
|
||||||
searchColumns: SearchColumns.isRequired,
|
searchColumns: SearchColumns.isRequired,
|
||||||
searchableKeys: PropTypes.arrayOf(PropTypes.string),
|
searchableKeys: SearchableKeys,
|
||||||
relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
||||||
sortColumns: SortColumns,
|
sortColumns: SortColumns,
|
||||||
renderToolbar: PropTypes.func,
|
renderToolbar: PropTypes.func,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { t } from '@lingui/macro';
|
|||||||
import { FormGroup } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import { ApplicationsAPI } from 'api';
|
import { ApplicationsAPI } from 'api';
|
||||||
import { Application } from 'types';
|
import { Application } from 'types';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import Lookup from './Lookup';
|
import Lookup from './Lookup';
|
||||||
@@ -42,9 +43,7 @@ function ApplicationLookup({ onChange, value, label, fieldName, validate }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse?.data?.actions?.GET),
|
||||||
actionsResponse?.data?.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { t } from '@lingui/macro';
|
|||||||
import { FormGroup } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import { CredentialsAPI } from 'api';
|
import { CredentialsAPI } from 'api';
|
||||||
import { Credential } from 'types';
|
import { Credential } from 'types';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString, mergeParams } from 'util/qs';
|
import { getQSConfig, parseQueryString, mergeParams } from 'util/qs';
|
||||||
import useAutoPopulateLookup from 'hooks/useAutoPopulateLookup';
|
import useAutoPopulateLookup from 'hooks/useAutoPopulateLookup';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
@@ -82,12 +83,10 @@ function CredentialLookup({
|
|||||||
autoPopulateLookup(data.results);
|
autoPopulateLookup(data.results);
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchKeys = Object.keys(
|
const searchKeys = getSearchableKeys(actionsResponse.data.actions?.GET);
|
||||||
actionsResponse.data.actions?.GET || {}
|
const item = searchKeys.find((k) => k.key === 'type');
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable);
|
|
||||||
const item = searchKeys.indexOf('type');
|
|
||||||
if (item) {
|
if (item) {
|
||||||
searchKeys[item] = 'credential_type__kind';
|
item.key = 'credential_type__kind';
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useLocation } from 'react-router-dom';
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { FormGroup, Tooltip } from '@patternfly/react-core';
|
import { FormGroup, Tooltip } from '@patternfly/react-core';
|
||||||
import { ExecutionEnvironmentsAPI, ProjectsAPI } from 'api';
|
import { ExecutionEnvironmentsAPI, ProjectsAPI } from 'api';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { ExecutionEnvironment } from 'types';
|
import { ExecutionEnvironment } from 'types';
|
||||||
import { getQSConfig, parseQueryString, mergeParams } from 'util/qs';
|
import { getQSConfig, parseQueryString, mergeParams } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
@@ -109,9 +110,7 @@ function ExecutionEnvironmentLookup({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
location,
|
location,
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ import ChipGroup from '../ChipGroup';
|
|||||||
import Popover from '../Popover';
|
import Popover from '../Popover';
|
||||||
import DataListToolbar from '../DataListToolbar';
|
import DataListToolbar from '../DataListToolbar';
|
||||||
import LookupErrorMessage from './shared/LookupErrorMessage';
|
import LookupErrorMessage from './shared/LookupErrorMessage';
|
||||||
import PaginatedTable, { HeaderCell, HeaderRow } from '../PaginatedTable';
|
import PaginatedTable, {
|
||||||
|
HeaderCell,
|
||||||
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
|
} from '../PaginatedTable';
|
||||||
import HostListItem from './HostListItem';
|
import HostListItem from './HostListItem';
|
||||||
import {
|
import {
|
||||||
removeDefaultParams,
|
removeDefaultParams,
|
||||||
@@ -157,9 +161,7 @@ function HostFilterLookup({
|
|||||||
relatedSearchableKeys: (actions?.related_search_fields || []).map(
|
relatedSearchableKeys: (actions?.related_search_fields || []).map(
|
||||||
parseRelatedSearchFields
|
parseRelatedSearchFields
|
||||||
),
|
),
|
||||||
searchableKeys: Object.keys(actions?.actions.GET || {}).filter(
|
searchableKeys: getSearchableKeys(actions?.actions.GET),
|
||||||
(key) => actions.actions?.GET[key].filterable
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[location.search]
|
[location.search]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { t, Trans } from '@lingui/macro';
|
|||||||
import { FormGroup } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import { InstanceGroupsAPI } from 'api';
|
import { InstanceGroupsAPI } from 'api';
|
||||||
import { InstanceGroup } from 'types';
|
import { InstanceGroup } from 'types';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import Popover from '../Popover';
|
import Popover from '../Popover';
|
||||||
@@ -47,9 +48,7 @@ function InstanceGroupsLookup({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [history.location]),
|
}, [history.location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,14 +74,17 @@ function InventoryLookup({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: Object.keys(actionsResponse.data.actions?.GET || {})
|
||||||
actionsResponse.data.actions?.GET || {}
|
.filter((key) => {
|
||||||
).filter((key) => {
|
if (['kind', 'host_filter'].includes(key) && hideSmartInventories) {
|
||||||
if (['kind', 'host_filter'].includes(key) && hideSmartInventories) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
return actionsResponse.data.actions?.GET[key].filterable;
|
||||||
return actionsResponse.data.actions?.GET[key].filterable;
|
})
|
||||||
}),
|
.map((key) => ({
|
||||||
|
key,
|
||||||
|
type: actionsResponse.data.actions?.GET[key].type,
|
||||||
|
})),
|
||||||
canEdit:
|
canEdit:
|
||||||
Boolean(actionsResponse.data.actions.POST) || isOverrideDisabled,
|
Boolean(actionsResponse.data.actions.POST) || isOverrideDisabled,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { ToolbarItem, Alert } from '@patternfly/react-core';
|
import { ToolbarItem, Alert } from '@patternfly/react-core';
|
||||||
import { CredentialsAPI, CredentialTypesAPI } from 'api';
|
import { CredentialsAPI, CredentialTypesAPI } from 'api';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useIsMounted from 'hooks/useIsMounted';
|
import useIsMounted from 'hooks/useIsMounted';
|
||||||
@@ -100,9 +101,7 @@ function MultiCredentialsLookup({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [selectedType, history.location]),
|
}, [selectedType, history.location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { FormGroup } from '@patternfly/react-core';
|
|||||||
import { OrganizationsAPI } from 'api';
|
import { OrganizationsAPI } from 'api';
|
||||||
import { Organization } from 'types';
|
import { Organization } from 'types';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import useAutoPopulateLookup from 'hooks/useAutoPopulateLookup';
|
import useAutoPopulateLookup from 'hooks/useAutoPopulateLookup';
|
||||||
import OptionsList from '../OptionsList';
|
import OptionsList from '../OptionsList';
|
||||||
@@ -57,9 +58,7 @@ function OrganizationLookup({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [autoPopulate, autoPopulateLookup, history.location.search]),
|
}, [autoPopulate, autoPopulateLookup, history.location.search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ProjectsAPI } from 'api';
|
|||||||
import { Project } from 'types';
|
import { Project } from 'types';
|
||||||
import useAutoPopulateLookup from 'hooks/useAutoPopulateLookup';
|
import useAutoPopulateLookup from 'hooks/useAutoPopulateLookup';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import OptionsList from '../OptionsList';
|
import OptionsList from '../OptionsList';
|
||||||
import Popover from '../Popover';
|
import Popover from '../Popover';
|
||||||
@@ -56,9 +57,7 @@ function ProjectLookup({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
canEdit:
|
canEdit:
|
||||||
Boolean(actionsResponse.data.actions.POST) || isOverrideDisabled,
|
Boolean(actionsResponse.data.actions.POST) || isOverrideDisabled,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ import { NotificationTemplatesAPI } from 'api';
|
|||||||
import AlertModal from '../AlertModal';
|
import AlertModal from '../AlertModal';
|
||||||
import ErrorDetail from '../ErrorDetail';
|
import ErrorDetail from '../ErrorDetail';
|
||||||
import NotificationListItem from './NotificationListItem';
|
import NotificationListItem from './NotificationListItem';
|
||||||
import PaginatedTable, { HeaderRow, HeaderCell } from '../PaginatedTable';
|
import PaginatedTable, {
|
||||||
|
HeaderRow,
|
||||||
|
HeaderCell,
|
||||||
|
getSearchableKeys,
|
||||||
|
} from '../PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('notification', {
|
const QS_CONFIG = getQSConfig('notification', {
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -89,9 +93,7 @@ function NotificationList({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (showApprovalsToggle) {
|
if (showApprovalsToggle) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { t } from '@lingui/macro';
|
|||||||
import { useLocation, useHistory } from 'react-router-dom';
|
import { useLocation, useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { parseQueryString, updateQueryString } from 'util/qs';
|
import { parseQueryString, updateQueryString } from 'util/qs';
|
||||||
import { QSConfig, SearchColumns } from 'types';
|
import { QSConfig, SearchColumns, SearchableKeys } from 'types';
|
||||||
import ListHeader from '../ListHeader';
|
import ListHeader from '../ListHeader';
|
||||||
import ContentEmpty from '../ContentEmpty';
|
import ContentEmpty from '../ContentEmpty';
|
||||||
import ContentError from '../ContentError';
|
import ContentError from '../ContentError';
|
||||||
@@ -184,7 +184,7 @@ PaginatedTable.propTypes = {
|
|||||||
qsConfig: QSConfig.isRequired,
|
qsConfig: QSConfig.isRequired,
|
||||||
renderRow: PropTypes.func.isRequired,
|
renderRow: PropTypes.func.isRequired,
|
||||||
toolbarSearchColumns: SearchColumns,
|
toolbarSearchColumns: SearchColumns,
|
||||||
toolbarSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
toolbarSearchableKeys: SearchableKeys,
|
||||||
toolbarRelatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
toolbarRelatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
||||||
showPageSizeOptions: PropTypes.bool,
|
showPageSizeOptions: PropTypes.bool,
|
||||||
renderToolbar: PropTypes.func,
|
renderToolbar: PropTypes.func,
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export default function getSearchableKeys(keys = {}) {
|
||||||
|
return Object.keys(keys)
|
||||||
|
.filter((key) => keys[key].filterable)
|
||||||
|
.map((key) => ({
|
||||||
|
key,
|
||||||
|
type: keys[key].type,
|
||||||
|
}));
|
||||||
|
}
|
||||||
@@ -5,3 +5,4 @@ export { default as ActionItem } from './ActionItem';
|
|||||||
export { default as ToolbarDeleteButton } from './ToolbarDeleteButton';
|
export { default as ToolbarDeleteButton } from './ToolbarDeleteButton';
|
||||||
export { default as ToolbarAddButton } from './ToolbarAddButton';
|
export { default as ToolbarAddButton } from './ToolbarAddButton';
|
||||||
export { default as ToolbarSyncSourceButton } from './ToolbarSyncSourceButton';
|
export { default as ToolbarSyncSourceButton } from './ToolbarSyncSourceButton';
|
||||||
|
export { default as getSearchableKeys } from './getSearchableKeys';
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from '../PaginatedTable';
|
} from '../PaginatedTable';
|
||||||
import DeleteRoleConfirmationModal from './DeleteRoleConfirmationModal';
|
import DeleteRoleConfirmationModal from './DeleteRoleConfirmationModal';
|
||||||
import ResourceAccessListItem from './ResourceAccessListItem';
|
import ResourceAccessListItem from './ResourceAccessListItem';
|
||||||
@@ -89,9 +90,7 @@ function ResourceAccessList({ apiModel, resource }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
organizationRoles: orgRoles,
|
organizationRoles: orgRoles,
|
||||||
};
|
};
|
||||||
}, [apiModel, location, resource]),
|
}, [apiModel, location, resource]),
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from '../../PaginatedTable';
|
} from '../../PaginatedTable';
|
||||||
import DataListToolbar from '../../DataListToolbar';
|
import DataListToolbar from '../../DataListToolbar';
|
||||||
import ScheduleListItem from './ScheduleListItem';
|
import ScheduleListItem from './ScheduleListItem';
|
||||||
@@ -61,9 +62,7 @@ function ScheduleList({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
scheduleActions?.data?.related_search_fields || []
|
scheduleActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(scheduleActions.data.actions?.GET),
|
||||||
scheduleActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => scheduleActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location.search, loadSchedules, loadScheduleOptions]),
|
}, [location.search, loadSchedules, loadScheduleOptions]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'styled-components/macro';
|
import 'styled-components/macro';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import { string, func, bool, arrayOf } from 'prop-types';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -16,6 +16,9 @@ import { SearchIcon, QuestionCircleIcon } from '@patternfly/react-icons';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { useConfig } from 'contexts/Config';
|
import { useConfig } from 'contexts/Config';
|
||||||
import getDocsBaseUrl from 'util/getDocsBaseUrl';
|
import getDocsBaseUrl from 'util/getDocsBaseUrl';
|
||||||
|
import { SearchableKeys } from 'types';
|
||||||
|
import RelatedLookupTypeInput from './RelatedLookupTypeInput';
|
||||||
|
import LookupTypeInput from './LookupTypeInput';
|
||||||
|
|
||||||
const AdvancedGroup = styled.div`
|
const AdvancedGroup = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -42,31 +45,33 @@ function AdvancedSearch({
|
|||||||
// for now, I'm spreading set to get rid of duplicate keys...when they are grouped
|
// for now, I'm spreading set to get rid of duplicate keys...when they are grouped
|
||||||
// we might want to revisit that.
|
// we might want to revisit that.
|
||||||
const allKeys = [
|
const allKeys = [
|
||||||
...new Set([...(searchableKeys || []), ...(relatedSearchableKeys || [])]),
|
...new Set([
|
||||||
|
...(searchableKeys.map((k) => k.key) || []),
|
||||||
|
...(relatedSearchableKeys || []),
|
||||||
|
]),
|
||||||
];
|
];
|
||||||
|
|
||||||
const [isPrefixDropdownOpen, setIsPrefixDropdownOpen] = useState(false);
|
const [isPrefixDropdownOpen, setIsPrefixDropdownOpen] = useState(false);
|
||||||
const [isLookupDropdownOpen, setIsLookupDropdownOpen] = useState(false);
|
|
||||||
const [isKeyDropdownOpen, setIsKeyDropdownOpen] = useState(false);
|
const [isKeyDropdownOpen, setIsKeyDropdownOpen] = useState(false);
|
||||||
const [prefixSelection, setPrefixSelection] = useState(null);
|
const [prefixSelection, setPrefixSelection] = useState(null);
|
||||||
const [lookupSelection, setLookupSelection] = useState(null);
|
const [lookupSelection, setLookupSelection] = useState(null);
|
||||||
const [keySelection, setKeySelection] = useState(null);
|
const [keySelection, setKeySelection] = useState(null);
|
||||||
const [searchValue, setSearchValue] = useState('');
|
const [searchValue, setSearchValue] = useState('');
|
||||||
const [relatedSearchKeySelected, setRelatedSearchKeySelected] =
|
|
||||||
useState(false);
|
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
|
|
||||||
|
const selectedKey = searchableKeys.find((k) => k.key === keySelection);
|
||||||
|
const relatedSearchKeySelected =
|
||||||
|
keySelection &&
|
||||||
|
relatedSearchableKeys.indexOf(keySelection) > -1 &&
|
||||||
|
!selectedKey;
|
||||||
|
const lookupKeyType =
|
||||||
|
keySelection && !relatedSearchKeySelected ? selectedKey?.type : null;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (relatedSearchKeySelected) {
|
||||||
keySelection &&
|
|
||||||
relatedSearchableKeys.indexOf(keySelection) > -1 &&
|
|
||||||
searchableKeys.indexOf(keySelection) === -1
|
|
||||||
) {
|
|
||||||
setLookupSelection('name__icontains');
|
setLookupSelection('name__icontains');
|
||||||
setRelatedSearchKeySelected(true);
|
|
||||||
} else {
|
} else {
|
||||||
setLookupSelection(null);
|
setLookupSelection(null);
|
||||||
setRelatedSearchKeySelected(false);
|
|
||||||
}
|
}
|
||||||
}, [keySelection]); // eslint-disable-line react-hooks/exhaustive-deps
|
}, [keySelection]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
@@ -136,160 +141,6 @@ function AdvancedSearch({
|
|||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderRelatedLookupType = () => (
|
|
||||||
<Select
|
|
||||||
ouiaId="set-lookup-typeahead"
|
|
||||||
aria-label={t`Related search type`}
|
|
||||||
className="lookupSelect"
|
|
||||||
variant={SelectVariant.typeahead}
|
|
||||||
typeAheadAriaLabel={t`Related search type typeahead`}
|
|
||||||
onToggle={setIsLookupDropdownOpen}
|
|
||||||
onSelect={(event, selection) => setLookupSelection(selection)}
|
|
||||||
selections={lookupSelection}
|
|
||||||
isOpen={isLookupDropdownOpen}
|
|
||||||
placeholderText={t`Related search type`}
|
|
||||||
maxHeight={maxSelectHeight}
|
|
||||||
noResultsFoundText={t`No results found`}
|
|
||||||
>
|
|
||||||
<SelectOption
|
|
||||||
id="name-option-select"
|
|
||||||
key="name__icontains"
|
|
||||||
value="name__icontains"
|
|
||||||
description={t`Fuzzy search on name field.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="id-option-select"
|
|
||||||
key="id"
|
|
||||||
value="id"
|
|
||||||
description={t`Exact search on id field.`}
|
|
||||||
/>
|
|
||||||
{enableRelatedFuzzyFiltering && (
|
|
||||||
<SelectOption
|
|
||||||
id="search-option-select"
|
|
||||||
key="search"
|
|
||||||
value="search"
|
|
||||||
description={t`Fuzzy search on id, name or description fields.`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderLookupType = () => (
|
|
||||||
<Select
|
|
||||||
ouiaId="set-lookup-typeahead"
|
|
||||||
aria-label={t`Lookup select`}
|
|
||||||
className="lookupSelect"
|
|
||||||
variant={SelectVariant.typeahead}
|
|
||||||
typeAheadAriaLabel={t`Lookup typeahead`}
|
|
||||||
onToggle={setIsLookupDropdownOpen}
|
|
||||||
onSelect={(event, selection) => setLookupSelection(selection)}
|
|
||||||
onClear={() => setLookupSelection(null)}
|
|
||||||
selections={lookupSelection}
|
|
||||||
isOpen={isLookupDropdownOpen}
|
|
||||||
placeholderText={t`Lookup type`}
|
|
||||||
maxHeight={maxSelectHeight}
|
|
||||||
noResultsFoundText={t`No results found`}
|
|
||||||
>
|
|
||||||
<SelectOption
|
|
||||||
id="exact-option-select"
|
|
||||||
key="exact"
|
|
||||||
value="exact"
|
|
||||||
description={t`Exact match (default lookup if not specified).`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="iexact-option-select"
|
|
||||||
key="iexact"
|
|
||||||
value="iexact"
|
|
||||||
description={t`Case-insensitive version of exact.`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SelectOption
|
|
||||||
id="contains-option-select"
|
|
||||||
key="contains"
|
|
||||||
value="contains"
|
|
||||||
description={t`Field contains value.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="icontains-option-select"
|
|
||||||
key="icontains"
|
|
||||||
value="icontains"
|
|
||||||
description={t`Case-insensitive version of contains`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="startswith-option-select"
|
|
||||||
key="startswith"
|
|
||||||
value="startswith"
|
|
||||||
description={t`Field starts with value.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="istartswith-option-select"
|
|
||||||
key="istartswith"
|
|
||||||
value="istartswith"
|
|
||||||
description={t`Case-insensitive version of startswith.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="endswith-option-select"
|
|
||||||
key="endswith"
|
|
||||||
value="endswith"
|
|
||||||
description={t`Field ends with value.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="iendswith-option-select"
|
|
||||||
key="iendswith"
|
|
||||||
value="iendswith"
|
|
||||||
description={t`Case-insensitive version of endswith.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="regex-option-select"
|
|
||||||
key="regex"
|
|
||||||
value="regex"
|
|
||||||
description={t`Field matches the given regular expression.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="iregex-option-select"
|
|
||||||
key="iregex"
|
|
||||||
value="iregex"
|
|
||||||
description={t`Case-insensitive version of regex.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="gt-option-select"
|
|
||||||
key="gt"
|
|
||||||
value="gt"
|
|
||||||
description={t`Greater than comparison.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="gte-option-select"
|
|
||||||
key="gte"
|
|
||||||
value="gte"
|
|
||||||
description={t`Greater than or equal to comparison.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="lt-option-select"
|
|
||||||
key="lt"
|
|
||||||
value="lt"
|
|
||||||
description={t`Less than comparison.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="lte-option-select"
|
|
||||||
key="lte"
|
|
||||||
value="lte"
|
|
||||||
description={t`Less than or equal to comparison.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="isnull-option-select"
|
|
||||||
key="isnull"
|
|
||||||
value="isnull"
|
|
||||||
description={t`Check whether the given field or related object is null; expects a boolean value.`}
|
|
||||||
/>
|
|
||||||
<SelectOption
|
|
||||||
id="in-option-select"
|
|
||||||
key="in"
|
|
||||||
value="in"
|
|
||||||
description={t`Check whether the given field's value is present in the list provided; expects a comma-separated list of items.`}
|
|
||||||
/>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AdvancedGroup>
|
<AdvancedGroup>
|
||||||
{lookupSelection === 'search' ? (
|
{lookupSelection === 'search' ? (
|
||||||
@@ -328,9 +179,21 @@ function AdvancedSearch({
|
|||||||
</SelectOption>
|
</SelectOption>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
{relatedSearchKeySelected
|
{relatedSearchKeySelected ? (
|
||||||
? renderRelatedLookupType()
|
<RelatedLookupTypeInput
|
||||||
: renderLookupType()}
|
value={lookupSelection}
|
||||||
|
setValue={setLookupSelection}
|
||||||
|
maxSelectHeight={maxSelectHeight}
|
||||||
|
enableFuzzyFiltering={enableRelatedFuzzyFiltering}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<LookupTypeInput
|
||||||
|
value={lookupSelection}
|
||||||
|
type={lookupKeyType}
|
||||||
|
setValue={setLookupSelection}
|
||||||
|
maxSelectHeight={maxSelectHeight}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<TextInput
|
<TextInput
|
||||||
data-cy="advanced-search-text-input"
|
data-cy="advanced-search-text-input"
|
||||||
@@ -369,12 +232,12 @@ function AdvancedSearch({
|
|||||||
}
|
}
|
||||||
|
|
||||||
AdvancedSearch.propTypes = {
|
AdvancedSearch.propTypes = {
|
||||||
onSearch: PropTypes.func.isRequired,
|
onSearch: func.isRequired,
|
||||||
searchableKeys: PropTypes.arrayOf(PropTypes.string),
|
searchableKeys: SearchableKeys,
|
||||||
relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
|
relatedSearchableKeys: arrayOf(string),
|
||||||
maxSelectHeight: PropTypes.string,
|
maxSelectHeight: string,
|
||||||
enableNegativeFiltering: PropTypes.bool,
|
enableNegativeFiltering: bool,
|
||||||
enableRelatedFuzzyFiltering: PropTypes.bool,
|
enableRelatedFuzzyFiltering: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
AdvancedSearch.defaultProps = {
|
AdvancedSearch.defaultProps = {
|
||||||
|
|||||||
@@ -10,22 +10,14 @@ describe('<AdvancedSearch />', () => {
|
|||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initially renders without crashing', () => {
|
|
||||||
wrapper = mountWithContexts(
|
|
||||||
<AdvancedSearch
|
|
||||||
onSearch={jest.fn}
|
|
||||||
searchableKeys={[]}
|
|
||||||
relatedSearchableKeys={[]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect(wrapper.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Remove duplicates from searchableKeys/relatedSearchableKeys list', () => {
|
test('Remove duplicates from searchableKeys/relatedSearchableKeys list', () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={jest.fn}
|
onSearch={jest.fn}
|
||||||
searchableKeys={['foo', 'bar']}
|
searchableKeys={[
|
||||||
|
{ key: 'foo', type: 'string' },
|
||||||
|
{ key: 'bar', type: 'string' },
|
||||||
|
]}
|
||||||
relatedSearchableKeys={['bar', 'baz']}
|
relatedSearchableKeys={['bar', 'baz']}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -42,7 +34,10 @@ describe('<AdvancedSearch />', () => {
|
|||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={advancedSearchMock}
|
onSearch={advancedSearchMock}
|
||||||
searchableKeys={['foo', 'bar']}
|
searchableKeys={[
|
||||||
|
{ key: 'foo', type: 'string' },
|
||||||
|
{ key: 'bar', type: 'string' },
|
||||||
|
]}
|
||||||
relatedSearchableKeys={['bar', 'baz']}
|
relatedSearchableKeys={['bar', 'baz']}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -155,7 +150,10 @@ describe('<AdvancedSearch />', () => {
|
|||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={advancedSearchMock}
|
onSearch={advancedSearchMock}
|
||||||
searchableKeys={['foo', 'bar']}
|
searchableKeys={[
|
||||||
|
{ key: 'foo', type: 'string' },
|
||||||
|
{ key: 'bar', type: 'string' },
|
||||||
|
]}
|
||||||
relatedSearchableKeys={['bar', 'baz']}
|
relatedSearchableKeys={['bar', 'baz']}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -239,7 +237,7 @@ describe('<AdvancedSearch />', () => {
|
|||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={advancedSearchMock}
|
onSearch={advancedSearchMock}
|
||||||
searchableKeys={['foo']}
|
searchableKeys={[{ key: 'foo', type: 'string' }]}
|
||||||
relatedSearchableKeys={[]}
|
relatedSearchableKeys={[]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -278,7 +276,7 @@ describe('<AdvancedSearch />', () => {
|
|||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={advancedSearchMock}
|
onSearch={advancedSearchMock}
|
||||||
searchableKeys={['foo']}
|
searchableKeys={[{ key: 'foo', type: 'string' }]}
|
||||||
relatedSearchableKeys={[]}
|
relatedSearchableKeys={[]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -375,7 +373,10 @@ describe('<AdvancedSearch />', () => {
|
|||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={jest.fn}
|
onSearch={jest.fn}
|
||||||
searchableKeys={['foo', 'bar']}
|
searchableKeys={[
|
||||||
|
{ key: 'foo', type: 'string' },
|
||||||
|
{ key: 'bar', type: 'string' },
|
||||||
|
]}
|
||||||
relatedSearchableKeys={['bar', 'baz']}
|
relatedSearchableKeys={['bar', 'baz']}
|
||||||
enableNegativeFiltering={false}
|
enableNegativeFiltering={false}
|
||||||
/>
|
/>
|
||||||
@@ -399,7 +400,10 @@ describe('<AdvancedSearch />', () => {
|
|||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<AdvancedSearch
|
<AdvancedSearch
|
||||||
onSearch={jest.fn}
|
onSearch={jest.fn}
|
||||||
searchableKeys={['foo', 'bar']}
|
searchableKeys={[
|
||||||
|
{ key: 'foo', type: 'string' },
|
||||||
|
{ key: 'bar', type: 'string' },
|
||||||
|
]}
|
||||||
relatedSearchableKeys={['bar', 'baz']}
|
relatedSearchableKeys={['bar', 'baz']}
|
||||||
enableRelatedFuzzyFiltering={false}
|
enableRelatedFuzzyFiltering={false}
|
||||||
/>
|
/>
|
||||||
|
|||||||
157
awx/ui/src/components/Search/LookupTypeInput.js
Normal file
157
awx/ui/src/components/Search/LookupTypeInput.js
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { string, oneOfType, arrayOf, func } from 'prop-types';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
|
||||||
|
|
||||||
|
function Option({ show, ...props }) {
|
||||||
|
if (!show) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return <SelectOption {...props} />;
|
||||||
|
}
|
||||||
|
Option.defaultProps = {
|
||||||
|
show: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
function LookupTypeInput({ value, type, setValue, maxSelectHeight }) {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
ouiaId="set-lookup-typeahead"
|
||||||
|
aria-label={t`Lookup select`}
|
||||||
|
className="lookupSelect"
|
||||||
|
variant={SelectVariant.typeahead}
|
||||||
|
typeAheadAriaLabel={t`Lookup typeahead`}
|
||||||
|
onToggle={setIsOpen}
|
||||||
|
onSelect={(event, selection) => setValue(selection)}
|
||||||
|
onClear={() => setValue(null)}
|
||||||
|
selections={value}
|
||||||
|
isOpen={isOpen}
|
||||||
|
placeholderText={t`Lookup type`}
|
||||||
|
maxHeight={maxSelectHeight}
|
||||||
|
noResultsFoundText={t`No results found`}
|
||||||
|
>
|
||||||
|
<Option
|
||||||
|
id="exact-option-select"
|
||||||
|
key="exact"
|
||||||
|
value="exact"
|
||||||
|
description={t`Exact match (default lookup if not specified).`}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="iexact-option-select"
|
||||||
|
key="iexact"
|
||||||
|
value="iexact"
|
||||||
|
description={t`Case-insensitive version of exact.`}
|
||||||
|
show={type === 'string'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="contains-option-select"
|
||||||
|
key="contains"
|
||||||
|
value="contains"
|
||||||
|
description={t`Field contains value.`}
|
||||||
|
show={type === 'string'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="icontains-option-select"
|
||||||
|
key="icontains"
|
||||||
|
value="icontains"
|
||||||
|
description={t`Case-insensitive version of contains`}
|
||||||
|
show={type === 'string'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="startswith-option-select"
|
||||||
|
key="startswith"
|
||||||
|
value="startswith"
|
||||||
|
description={t`Field starts with value.`}
|
||||||
|
show={type !== 'datetime'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="istartswith-option-select"
|
||||||
|
key="istartswith"
|
||||||
|
value="istartswith"
|
||||||
|
description={t`Case-insensitive version of startswith.`}
|
||||||
|
show={type !== 'datetime'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="endswith-option-select"
|
||||||
|
key="endswith"
|
||||||
|
value="endswith"
|
||||||
|
description={t`Field ends with value.`}
|
||||||
|
show={type !== 'datetime'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="iendswith-option-select"
|
||||||
|
key="iendswith"
|
||||||
|
value="iendswith"
|
||||||
|
description={t`Case-insensitive version of endswith.`}
|
||||||
|
show={type !== 'datetime'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="regex-option-select"
|
||||||
|
key="regex"
|
||||||
|
value="regex"
|
||||||
|
description={t`Field matches the given regular expression.`}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="iregex-option-select"
|
||||||
|
key="iregex"
|
||||||
|
value="iregex"
|
||||||
|
description={t`Case-insensitive version of regex.`}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="gt-option-select"
|
||||||
|
key="gt"
|
||||||
|
value="gt"
|
||||||
|
description={t`Greater than comparison.`}
|
||||||
|
show={type !== 'json'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="gte-option-select"
|
||||||
|
key="gte"
|
||||||
|
value="gte"
|
||||||
|
description={t`Greater than or equal to comparison.`}
|
||||||
|
show={type !== 'json'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="lt-option-select"
|
||||||
|
key="lt"
|
||||||
|
value="lt"
|
||||||
|
description={t`Less than comparison.`}
|
||||||
|
show={type !== 'json'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="lte-option-select"
|
||||||
|
key="lte"
|
||||||
|
value="lte"
|
||||||
|
description={t`Less than or equal to comparison.`}
|
||||||
|
show={type !== 'json'}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="isnull-option-select"
|
||||||
|
key="isnull"
|
||||||
|
value="isnull"
|
||||||
|
description={t`Check whether the given field or related object is null; expects a boolean value.`}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
id="in-option-select"
|
||||||
|
key="in"
|
||||||
|
value="in"
|
||||||
|
description={t`Check whether the given field's value is present in the list provided; expects a comma-separated list of items.`}
|
||||||
|
/>
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
LookupTypeInput.propTypes = {
|
||||||
|
type: string,
|
||||||
|
value: oneOfType([string, arrayOf(string)]),
|
||||||
|
setValue: func.isRequired,
|
||||||
|
maxSelectHeight: string,
|
||||||
|
};
|
||||||
|
LookupTypeInput.defaultProps = {
|
||||||
|
type: 'string',
|
||||||
|
value: '',
|
||||||
|
maxSelectHeight: '300px',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LookupTypeInput;
|
||||||
52
awx/ui/src/components/Search/RelatedLookupTypeInput.js
Normal file
52
awx/ui/src/components/Search/RelatedLookupTypeInput.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
|
||||||
|
|
||||||
|
function RelatedLookupTypeInput({
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
maxSelectHeight,
|
||||||
|
enableFuzzyFiltering,
|
||||||
|
}) {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
ouiaId="set-lookup-typeahead"
|
||||||
|
aria-label={t`Related search type`}
|
||||||
|
className="lookupSelect"
|
||||||
|
variant={SelectVariant.typeahead}
|
||||||
|
typeAheadAriaLabel={t`Related search type typeahead`}
|
||||||
|
onToggle={setIsOpen}
|
||||||
|
onSelect={(event, selection) => setValue(selection)}
|
||||||
|
selections={value}
|
||||||
|
isOpen={isOpen}
|
||||||
|
placeholderText={t`Related search type`}
|
||||||
|
maxHeight={maxSelectHeight}
|
||||||
|
noResultsFoundText={t`No results found`}
|
||||||
|
>
|
||||||
|
<SelectOption
|
||||||
|
id="name-option-select"
|
||||||
|
key="name__icontains"
|
||||||
|
value="name__icontains"
|
||||||
|
description={t`Fuzzy search on name field.`}
|
||||||
|
/>
|
||||||
|
<SelectOption
|
||||||
|
id="id-option-select"
|
||||||
|
key="id"
|
||||||
|
value="id"
|
||||||
|
description={t`Exact search on id field.`}
|
||||||
|
/>
|
||||||
|
{enableFuzzyFiltering && (
|
||||||
|
<SelectOption
|
||||||
|
id="search-option-select"
|
||||||
|
key="search"
|
||||||
|
value="search"
|
||||||
|
description={t`Fuzzy search on id, name or description fields.`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RelatedLookupTypeInput;
|
||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
import { SearchIcon } from '@patternfly/react-icons';
|
import { SearchIcon } from '@patternfly/react-icons';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { parseQueryString } from 'util/qs';
|
import { parseQueryString } from 'util/qs';
|
||||||
import { QSConfig, SearchColumns } from 'types';
|
import { QSConfig, SearchColumns, SearchableKeys } from 'types';
|
||||||
import AdvancedSearch from './AdvancedSearch';
|
import AdvancedSearch from './AdvancedSearch';
|
||||||
import getChipsByKey from './getChipsByKey';
|
import getChipsByKey from './getChipsByKey';
|
||||||
|
|
||||||
@@ -276,6 +276,7 @@ Search.propTypes = {
|
|||||||
maxSelectHeight: PropTypes.string,
|
maxSelectHeight: PropTypes.string,
|
||||||
enableNegativeFiltering: PropTypes.bool,
|
enableNegativeFiltering: PropTypes.bool,
|
||||||
enableRelatedFuzzyFiltering: PropTypes.bool,
|
enableRelatedFuzzyFiltering: PropTypes.bool,
|
||||||
|
searchableKeys: SearchableKeys,
|
||||||
};
|
};
|
||||||
|
|
||||||
Search.defaultProps = {
|
Search.defaultProps = {
|
||||||
@@ -285,6 +286,7 @@ Search.defaultProps = {
|
|||||||
maxSelectHeight: '300px',
|
maxSelectHeight: '300px',
|
||||||
enableNegativeFiltering: true,
|
enableNegativeFiltering: true,
|
||||||
enableRelatedFuzzyFiltering: true,
|
enableRelatedFuzzyFiltering: true,
|
||||||
|
searchableKeys: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Search;
|
export default Search;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from '../PaginatedTable';
|
} from '../PaginatedTable';
|
||||||
import AddDropDownButton from '../AddDropDownButton';
|
import AddDropDownButton from '../AddDropDownButton';
|
||||||
import TemplateListItem from './TemplateListItem';
|
import TemplateListItem from './TemplateListItem';
|
||||||
@@ -69,9 +70,7 @@ function TemplateList({ defaultParams }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responses[3]?.data?.related_search_fields || []
|
responses[3]?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responses[3].data.actions?.GET),
|
||||||
responses[3].data.actions?.GET || {}
|
|
||||||
).filter((key) => responses[3].data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]), // eslint-disable-line react-hooks/exhaustive-deps
|
}, [location]), // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import DatalistToolbar from 'components/DataListToolbar';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import { getQSConfig, parseQueryString, updateQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString, updateQueryString } from 'util/qs';
|
||||||
@@ -72,9 +73,7 @@ function ActivityStream() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[location] // eslint-disable-line react-hooks/exhaustive-deps
|
[location] // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import { TokensAPI, ApplicationsAPI } from 'api';
|
import { TokensAPI, ApplicationsAPI } from 'api';
|
||||||
@@ -57,9 +58,7 @@ function ApplicationTokenList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [id, location.search]),
|
}, [id, location.search]),
|
||||||
{ tokens: [], itemCount: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
{ tokens: [], itemCount: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
|
|
||||||
@@ -57,9 +58,7 @@ function ApplicationsList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
@@ -44,9 +45,7 @@ function CredentialList() {
|
|||||||
CredentialsAPI.read(params),
|
CredentialsAPI.read(params),
|
||||||
CredentialsAPI.readOptions(),
|
CredentialsAPI.readOptions(),
|
||||||
]);
|
]);
|
||||||
const searchKeys = Object.keys(
|
const searchKeys = getSearchableKeys(credActions.data.actions?.GET);
|
||||||
credActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => credActions.data.actions?.GET[key].filterable);
|
|
||||||
const item = searchKeys.indexOf('type');
|
const item = searchKeys.indexOf('type');
|
||||||
if (item) {
|
if (item) {
|
||||||
searchKeys[item] = 'credential_type__kind';
|
searchKeys[item] = 'credential_type__kind';
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import useRequest from 'hooks/useRequest';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('credential', {
|
const QS_CONFIG = getQSConfig('credential', {
|
||||||
@@ -44,9 +45,7 @@ function CredentialsStep() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [history.location.search]),
|
}, [history.location.search]),
|
||||||
{ credentials: [], count: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
{ credentials: [], count: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
import AlertModal from 'components/AlertModal';
|
import AlertModal from 'components/AlertModal';
|
||||||
@@ -57,9 +58,7 @@ function CredentialTypeList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responseActions?.data?.related_search_fields || []
|
responseActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responseActions.data.actions?.GET),
|
||||||
responseActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => responseActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
import AlertModal from 'components/AlertModal';
|
import AlertModal from 'components/AlertModal';
|
||||||
@@ -56,9 +57,7 @@ function ExecutionEnvironmentList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responseActions?.data?.related_search_fields || []
|
responseActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responseActions.data.actions?.GET),
|
||||||
responseActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => responseActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import DatalistToolbar from 'components/DataListToolbar';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
import ExecutionEnvironmentTemplateListItem from './ExecutionEnvironmentTemplateListItem';
|
import ExecutionEnvironmentTemplateListItem from './ExecutionEnvironmentTemplateListItem';
|
||||||
@@ -56,9 +57,7 @@ function ExecutionEnvironmentTemplateList({ executionEnvironment }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responseActions?.data?.related_search_fields || []
|
responseActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responseActions.data.actions?.GET),
|
||||||
responseActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => responseActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location, id]),
|
}, [location, id]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AssociateModal from 'components/AssociateModal';
|
import AssociateModal from 'components/AssociateModal';
|
||||||
import DisassociateButton from 'components/DisassociateButton';
|
import DisassociateButton from 'components/DisassociateButton';
|
||||||
@@ -66,9 +67,7 @@ function HostGroupsList({ host }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [hostId, search]),
|
}, [hostId, search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
@@ -68,9 +69,7 @@ function HostList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
results[1]?.data?.related_search_fields || []
|
results[1]?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(results[1].data.actions?.GET || {}).filter(
|
searchableKeys: getSearchableKeys(results[1].data.actions?.GET),
|
||||||
(key) => results[1].data.actions?.GET[key].filterable
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
import AlertModal from 'components/AlertModal';
|
import AlertModal from 'components/AlertModal';
|
||||||
@@ -107,9 +108,7 @@ function InstanceGroupList({
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responseActions?.data?.related_search_fields || []
|
responseActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responseActions.data.actions?.GET),
|
||||||
responseActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => responseActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import DisassociateButton from 'components/DisassociateButton';
|
import DisassociateButton from 'components/DisassociateButton';
|
||||||
import AssociateModal from 'components/AssociateModal';
|
import AssociateModal from 'components/AssociateModal';
|
||||||
@@ -61,9 +62,7 @@ function InstanceList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responseActions?.data?.related_search_fields || []
|
responseActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responseActions.data.actions?.GET),
|
||||||
responseActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => responseActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location.search, instanceGroupId]),
|
}, [location.search, instanceGroupId]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import ErrorDetail from 'components/ErrorDetail';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AssociateModal from 'components/AssociateModal';
|
import AssociateModal from 'components/AssociateModal';
|
||||||
import DisassociateButton from 'components/DisassociateButton';
|
import DisassociateButton from 'components/DisassociateButton';
|
||||||
@@ -67,9 +68,7 @@ function InventoryGroupHostList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [groupId, inventoryId, location.search]),
|
}, [groupId, inventoryId, location.search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AdHocCommands from 'components/AdHocCommands/AdHocCommands';
|
import AdHocCommands from 'components/AdHocCommands/AdHocCommands';
|
||||||
import InventoryGroupItem from './InventoryGroupItem';
|
import InventoryGroupItem from './InventoryGroupItem';
|
||||||
@@ -62,9 +63,7 @@ function InventoryGroupsList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
groupOptions?.data?.related_search_fields || []
|
groupOptions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(groupOptions.data.actions?.GET),
|
||||||
groupOptions.data.actions?.GET || {}
|
|
||||||
).filter((key) => groupOptions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [inventoryId, location]),
|
}, [inventoryId, location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AssociateModal from 'components/AssociateModal';
|
import AssociateModal from 'components/AssociateModal';
|
||||||
import DisassociateButton from 'components/DisassociateButton';
|
import DisassociateButton from 'components/DisassociateButton';
|
||||||
@@ -72,9 +73,7 @@ function InventoryHostGroupsList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
hostGroupOptions?.data?.related_search_fields || []
|
hostGroupOptions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(hostGroupOptions.data.actions?.GET),
|
||||||
hostGroupOptions.data.actions?.GET || {}
|
|
||||||
).filter((key) => hostGroupOptions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [hostId, search]), // eslint-disable-line react-hooks/exhaustive-deps
|
}, [hostId, search]), // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
import AdHocCommands from 'components/AdHocCommands/AdHocCommands';
|
import AdHocCommands from 'components/AdHocCommands/AdHocCommands';
|
||||||
@@ -59,9 +60,7 @@ function InventoryHostList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
hostOptions?.data?.related_search_fields || []
|
hostOptions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(hostOptions.data.actions?.GET || {}).filter(
|
searchableKeys: getSearchableKeys(hostOptions.data.actions?.GET),
|
||||||
(key) => hostOptions.data.actions?.GET[key].filterable
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}, [id, search]),
|
}, [id, search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import AddDropDownButton from 'components/AddDropDownButton';
|
import AddDropDownButton from 'components/AddDropDownButton';
|
||||||
@@ -54,9 +55,7 @@ function InventoryList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import DataListToolbar from 'components/DataListToolbar';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AddDropDownButton from 'components/AddDropDownButton';
|
import AddDropDownButton from 'components/AddDropDownButton';
|
||||||
import AdHocCommands from 'components/AdHocCommands/AdHocCommands';
|
import AdHocCommands from 'components/AdHocCommands/AdHocCommands';
|
||||||
@@ -65,9 +66,7 @@ function InventoryRelatedGroupList() {
|
|||||||
relatedSearchableKeys: (actions?.data?.related_search_fields || []).map(
|
relatedSearchableKeys: (actions?.data?.related_search_fields || []).map(
|
||||||
(val) => val.slice(0, -8)
|
(val) => val.slice(0, -8)
|
||||||
),
|
),
|
||||||
searchableKeys: Object.keys(actions.data.actions?.GET || {}).filter(
|
searchableKeys: getSearchableKeys(actions.data.actions?.GET),
|
||||||
(key) => actions.data.actions?.GET[key].filterable
|
|
||||||
),
|
|
||||||
canAdd:
|
canAdd:
|
||||||
actions.data.actions &&
|
actions.data.actions &&
|
||||||
Object.prototype.hasOwnProperty.call(actions.data.actions, 'POST'),
|
Object.prototype.hasOwnProperty.call(actions.data.actions, 'POST'),
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { InventorySourcesAPI } from 'api';
|
|||||||
import ContentError from 'components/ContentError';
|
import ContentError from 'components/ContentError';
|
||||||
import ContentLoading from 'components/ContentLoading';
|
import ContentLoading from 'components/ContentLoading';
|
||||||
import RoutedTabs from 'components/RoutedTabs';
|
import RoutedTabs from 'components/RoutedTabs';
|
||||||
|
import { getSearchableKeys } from 'components/PaginatedTable';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
import { getJobModel } from 'util/jobs';
|
import { getJobModel } from 'util/jobs';
|
||||||
import JobDetail from './JobDetail';
|
import JobDetail from './JobDetail';
|
||||||
@@ -83,9 +84,7 @@ function Job({ setBreadcrumb }) {
|
|||||||
eventRelatedSearchableKeys: (
|
eventRelatedSearchableKeys: (
|
||||||
eventOptions?.related_search_fields || []
|
eventOptions?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
eventSearchableKeys: Object.keys(
|
eventSearchableKeys: getSearchableKeys(eventOptions?.actions?.GET),
|
||||||
eventOptions?.actions?.GET || {}
|
|
||||||
).filter((key) => eventOptions?.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [id, type, setBreadcrumb]),
|
}, [id, type, setBreadcrumb]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import ErrorDetail from 'components/ErrorDetail';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { useConfig } from 'contexts/Config';
|
import { useConfig } from 'contexts/Config';
|
||||||
import { parseQueryString, getQSConfig } from 'util/qs';
|
import { parseQueryString, getQSConfig } from 'util/qs';
|
||||||
@@ -25,9 +26,7 @@ const QS_CONFIG = getQSConfig('system_job_templates', {
|
|||||||
|
|
||||||
const buildSearchKeys = (options) => {
|
const buildSearchKeys = (options) => {
|
||||||
const actions = options?.data?.actions?.GET || {};
|
const actions = options?.data?.actions?.GET || {};
|
||||||
const searchableKeys = Object.keys(actions).filter(
|
const searchableKeys = getSearchableKeys(actions);
|
||||||
(key) => actions[key].filterable
|
|
||||||
);
|
|
||||||
const relatedSearchableKeys = options?.data?.related_search_fields || [];
|
const relatedSearchableKeys = options?.data?.related_search_fields || [];
|
||||||
|
|
||||||
return { searchableKeys, relatedSearchableKeys };
|
return { searchableKeys, relatedSearchableKeys };
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AlertModal from 'components/AlertModal';
|
import AlertModal from 'components/AlertModal';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
@@ -62,9 +63,7 @@ function NotificationTemplatesList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse.data?.related_search_fields || []
|
actionsResponse.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
|||||||
import NotificationTemplateListItem from './NotificationTemplateListItem';
|
import NotificationTemplateListItem from './NotificationTemplateListItem';
|
||||||
|
|
||||||
jest.mock('../../../api/models/NotificationTemplates');
|
jest.mock('../../../api/models/NotificationTemplates');
|
||||||
|
jest.mock('../../../api/models/Notifications');
|
||||||
|
|
||||||
const template = {
|
const template = {
|
||||||
id: 3,
|
id: 3,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import useRequest from 'hooks/useRequest';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import DatalistToolbar from 'components/DataListToolbar';
|
import DatalistToolbar from 'components/DataListToolbar';
|
||||||
|
|
||||||
@@ -51,9 +52,7 @@ function OrganizationExecEnvList({ organization }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
responseActions?.data?.related_search_fields || []
|
responseActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(responseActions.data.actions?.GET),
|
||||||
responseActions.data.actions?.GET || {}
|
|
||||||
).filter((key) => responseActions.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location, id]),
|
}, [location, id]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
@@ -56,9 +57,7 @@ function OrganizationsList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
orgActions?.data?.related_search_fields || []
|
orgActions?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(orgActions.data.actions?.GET || {}).filter(
|
searchableKeys: getSearchableKeys(orgActions.data.actions?.GET),
|
||||||
(key) => orgActions.data.actions?.GET[key].filterable
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { OrganizationsAPI } from 'api';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useRequest from 'hooks/useRequest';
|
import useRequest from 'hooks/useRequest';
|
||||||
@@ -39,9 +40,7 @@ function OrganizationTeamList({ id }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [id, location]),
|
}, [id, location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
@@ -54,9 +55,7 @@ function ProjectJobTemplatesList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location, projectId]),
|
}, [location, projectId]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
import useExpanded from 'hooks/useExpanded';
|
import useExpanded from 'hooks/useExpanded';
|
||||||
@@ -75,9 +76,7 @@ function ProjectList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
@@ -55,9 +56,7 @@ function TeamList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
@@ -69,9 +70,7 @@ function TeamRolesList({ me, team }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [me.id, team.id, team.organization, search]),
|
}, [me.id, team.id, team.organization, search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import CheckboxListItem from 'components/CheckboxListItem';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('inventory-sources', {
|
const QS_CONFIG = getQSConfig('inventory-sources', {
|
||||||
@@ -40,9 +41,7 @@ function InventorySourcesList({ nodeResource, onUpdateNodeResource }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import CheckboxListItem from 'components/CheckboxListItem';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('job-templates', {
|
const QS_CONFIG = getQSConfig('job-templates', {
|
||||||
@@ -42,9 +43,7 @@ function JobTemplatesList({ nodeResource, onUpdateNodeResource }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import CheckboxListItem from 'components/CheckboxListItem';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('projects', {
|
const QS_CONFIG = getQSConfig('projects', {
|
||||||
@@ -40,9 +41,7 @@ function ProjectsList({ nodeResource, onUpdateNodeResource }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import CheckboxListItem from 'components/CheckboxListItem';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('system-job-templates', {
|
const QS_CONFIG = getQSConfig('system-job-templates', {
|
||||||
@@ -46,9 +47,7 @@ function SystemJobTemplatesList({ nodeResource, onUpdateNodeResource }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import CheckboxListItem from 'components/CheckboxListItem';
|
|||||||
import PaginatedTable, {
|
import PaginatedTable, {
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
HeaderRow,
|
HeaderRow,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('workflow-job-templates', {
|
const QS_CONFIG = getQSConfig('workflow-job-templates', {
|
||||||
@@ -47,9 +48,7 @@ function WorkflowJobTemplatesList({ nodeResource, onUpdateNodeResource }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
@@ -53,9 +54,7 @@ function UserList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
import AlertModal from 'components/AlertModal';
|
import AlertModal from 'components/AlertModal';
|
||||||
@@ -67,9 +68,7 @@ function UserRolesList({ user }) {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [user.id, search]),
|
}, [user.id, search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import DataListToolbar from 'components/DataListToolbar';
|
import DataListToolbar from 'components/DataListToolbar';
|
||||||
import DisassociateButton from 'components/DisassociateButton';
|
import DisassociateButton from 'components/DisassociateButton';
|
||||||
@@ -66,9 +67,7 @@ function UserTeamList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [userId, location.search]),
|
}, [userId, location.search]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import PaginatedTable, {
|
|||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import useSelected from 'hooks/useSelected';
|
import useSelected from 'hooks/useSelected';
|
||||||
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
||||||
@@ -58,9 +59,7 @@ function UserTokenList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [id, location.search]),
|
}, [id, location.search]),
|
||||||
{ tokens: [], itemCount: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
{ tokens: [], itemCount: 0, relatedSearchableKeys: [], searchableKeys: [] }
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import PaginatedTable, {
|
|||||||
HeaderRow,
|
HeaderRow,
|
||||||
HeaderCell,
|
HeaderCell,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
|
getSearchableKeys,
|
||||||
} from 'components/PaginatedTable';
|
} from 'components/PaginatedTable';
|
||||||
import AlertModal from 'components/AlertModal';
|
import AlertModal from 'components/AlertModal';
|
||||||
import ErrorDetail from 'components/ErrorDetail';
|
import ErrorDetail from 'components/ErrorDetail';
|
||||||
@@ -50,9 +51,7 @@ function WorkflowApprovalsList() {
|
|||||||
relatedSearchableKeys: (
|
relatedSearchableKeys: (
|
||||||
actionsResponse?.data?.related_search_fields || []
|
actionsResponse?.data?.related_search_fields || []
|
||||||
).map((val) => val.slice(0, -8)),
|
).map((val) => val.slice(0, -8)),
|
||||||
searchableKeys: Object.keys(
|
searchableKeys: getSearchableKeys(actionsResponse.data.actions?.GET),
|
||||||
actionsResponse.data.actions?.GET || {}
|
|
||||||
).filter((key) => actionsResponse.data.actions?.GET[key].filterable),
|
|
||||||
};
|
};
|
||||||
}, [location]),
|
}, [location]),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -421,3 +421,10 @@ export const ExecutionEnvironment = shape({
|
|||||||
description: string,
|
description: string,
|
||||||
pull: string,
|
pull: string,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const SearchableKeys = arrayOf(
|
||||||
|
shape({
|
||||||
|
key: string.isRequired,
|
||||||
|
type: string.isRequired,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user