diff --git a/client/containers/domain-autocomplete/connector.js b/client/containers/domain-autocomplete/connector.js index cbce84533..23b055d5b 100644 --- a/client/containers/domain-autocomplete/connector.js +++ b/client/containers/domain-autocomplete/connector.js @@ -20,6 +20,13 @@ // THE SOFTWARE. import { connect } from 'vuex-connect'; +import { ROUTE_PARAMS_DOMAIN } from '../route/getter-types'; +import { + DOMAIN_AUTOCOMPLETE_COMBINED_DOMAIN_LIST, + DOMAIN_AUTOCOMPLETE_IS_LOADING, + DOMAIN_AUTOCOMPLETE_NAVIGATE_TO_DOMAIN_URL, + DOMAIN_AUTOCOMPLETE_SEARCH, +} from './getter-types'; import { DOMAIN_AUTOCOMPLETE_ON_MOUNTED } from './mutation-types'; const actionsToEvents = { @@ -27,7 +34,11 @@ const actionsToEvents = { }; const gettersToProps = { - // TODO - updated in future PR + isLoading: DOMAIN_AUTOCOMPLETE_IS_LOADING, + domain: ROUTE_PARAMS_DOMAIN, + domainList: DOMAIN_AUTOCOMPLETE_COMBINED_DOMAIN_LIST, + navigateToDomainUrl: DOMAIN_AUTOCOMPLETE_NAVIGATE_TO_DOMAIN_URL, + search: DOMAIN_AUTOCOMPLETE_SEARCH, }; const lifecycle = { diff --git a/client/containers/domain-autocomplete/constants.js b/client/containers/domain-autocomplete/constants.js index 4674c1086..7067d56d0 100644 --- a/client/containers/domain-autocomplete/constants.js +++ b/client/containers/domain-autocomplete/constants.js @@ -21,3 +21,4 @@ export const DOMAIN_AUTOCOMPLETE_STATE_PREFIX = 'domainAutocomplete'; export const DOMAIN_AUTOCOMPLETE_TYPE_PREFIX = 'DOMAIN_AUTOCOMPLETE'; +export const TOP_DOMAIN_LIST_LIMIT = 15; diff --git a/client/containers/domain-autocomplete/getter-types.js b/client/containers/domain-autocomplete/getter-types.js new file mode 100644 index 000000000..53a0606b7 --- /dev/null +++ b/client/containers/domain-autocomplete/getter-types.js @@ -0,0 +1,39 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import { typePrefix } from './helpers'; + +export const DOMAIN_AUTOCOMPLETE_COMBINED_DOMAIN_LIST = typePrefix( + 'COMBINED_DOMAIN_LIST' +); +export const DOMAIN_AUTOCOMPLETE_DOMAIN_LIST = typePrefix('DOMAIN_LIST'); +export const DOMAIN_AUTOCOMPLETE_FILTERED_VISITED_DOMAIN_LIST = typePrefix( + 'FILTERED_VISITED_DOMAIN_LIST' +); +export const DOMAIN_AUTOCOMPLETE_IS_LOADING = typePrefix('IS_LOADING'); +export const DOMAIN_AUTOCOMPLETE_NAVIGATE_TO_DOMAIN_URL = typePrefix( + 'NAVIGATE_TO_DOMAIN_URL' +); +export const DOMAIN_AUTOCOMPLETE_SEARCH = typePrefix('SEARCH'); +export const DOMAIN_AUTOCOMPLETE_SEARCH_URL = typePrefix('SEARCH_URL'); +export const DOMAIN_AUTOCOMPLETE_VISITED_DOMAIN_LIST = typePrefix( + 'VISITED_DOMAIN_LIST' +); diff --git a/client/containers/domain-autocomplete/getters.js b/client/containers/domain-autocomplete/getters.js new file mode 100644 index 000000000..840b89952 --- /dev/null +++ b/client/containers/domain-autocomplete/getters.js @@ -0,0 +1,85 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import { get } from 'lodash-es'; +import { + DOMAIN_AUTOCOMPLETE_COMBINED_DOMAIN_LIST, + DOMAIN_AUTOCOMPLETE_DOMAIN_LIST, + DOMAIN_AUTOCOMPLETE_FILTERED_VISITED_DOMAIN_LIST, + DOMAIN_AUTOCOMPLETE_IS_LOADING, + DOMAIN_AUTOCOMPLETE_NAVIGATE_TO_DOMAIN_URL, + DOMAIN_AUTOCOMPLETE_SEARCH, + DOMAIN_AUTOCOMPLETE_SEARCH_URL, + DOMAIN_AUTOCOMPLETE_VISITED_DOMAIN_LIST, +} from './getter-types'; +import { + combineDomainList, + filterVisitedDomainList, + filterTopDomainList, + formatDomainList, + sortDomainList, + statePrefix, +} from './helpers'; +import { combine } from '~helpers'; + +const getters = { + [DOMAIN_AUTOCOMPLETE_COMBINED_DOMAIN_LIST]: (_, getters) => { + const visitedDomainList = + getters[DOMAIN_AUTOCOMPLETE_FILTERED_VISITED_DOMAIN_LIST]; + const domainList = getters[DOMAIN_AUTOCOMPLETE_DOMAIN_LIST]; + const combinedDomainList = combineDomainList({ + visitedDomainList, + domainList, + }); + + return combine(combinedDomainList)( + sortDomainList, + filterTopDomainList, + formatDomainList + ); + }, + [DOMAIN_AUTOCOMPLETE_DOMAIN_LIST]: state => + sortDomainList(get(state, statePrefix('domainList')) || []), + [DOMAIN_AUTOCOMPLETE_FILTERED_VISITED_DOMAIN_LIST]: (_, getters) => + filterVisitedDomainList({ + visitedDomainList: getters[DOMAIN_AUTOCOMPLETE_VISITED_DOMAIN_LIST], + search: getters[DOMAIN_AUTOCOMPLETE_SEARCH], + }), + [DOMAIN_AUTOCOMPLETE_IS_LOADING]: state => + get(state, statePrefix('isLoading')) || false, + [DOMAIN_AUTOCOMPLETE_NAVIGATE_TO_DOMAIN_URL]: (_, getters) => { + const search = getters[DOMAIN_AUTOCOMPLETE_SEARCH]; + + if (!search) { + return ''; + } + + return `/domains/${search}`; + }, + [DOMAIN_AUTOCOMPLETE_SEARCH]: state => + get(state, statePrefix('search')) || '', + [DOMAIN_AUTOCOMPLETE_SEARCH_URL]: (_, getters) => + `/api/domains?querystring=${getters[DOMAIN_AUTOCOMPLETE_SEARCH]}`, + [DOMAIN_AUTOCOMPLETE_VISITED_DOMAIN_LIST]: state => + sortDomainList(get(state, statePrefix('visitedDomainList')) || []), +}; + +export default getters; diff --git a/client/containers/domain-autocomplete/helpers/combine-domain-list.js b/client/containers/domain-autocomplete/helpers/combine-domain-list.js new file mode 100644 index 000000000..b2b56ee6a --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/combine-domain-list.js @@ -0,0 +1,36 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const combineDomainList = ({ domainList, visitedDomainList }) => { + const domainListUuidList = domainList.map(domain => domain.domainInfo.uuid); + const domainNameList = domainList.map(domain => domain.domainInfo.name); + + return [ + ...domainList, + ...visitedDomainList.filter(domain => + typeof domain === 'string' + ? domainNameList.indexOf(domain) === -1 + : domainListUuidList.indexOf(domain.domainInfo.uuid) === -1 + ), + ]; +}; + +export default combineDomainList; diff --git a/client/containers/domain-autocomplete/helpers/combine-domain-list.spec.js b/client/containers/domain-autocomplete/helpers/combine-domain-list.spec.js new file mode 100644 index 000000000..74e1365b7 --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/combine-domain-list.spec.js @@ -0,0 +1,96 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import combineDomainList from './combine-domain-list'; + +describe('combineDomainList', () => { + describe('when passed domainList & visitedDomainList', () => { + const visitedDomainList = [ + 'domain1', + { + domainInfo: { + name: 'domain2', + uuid: 2, + }, + }, + 'domain3', + { + domainInfo: { + name: 'domain4', + uuid: 4, + }, + }, + ]; + + const domainList = [ + { + domainInfo: { + name: 'domain0', + uuid: 0, + }, + }, + { + domainInfo: { + name: 'domain1', + uuid: 1, + }, + }, + { + domainInfo: { + name: 'domain2', + uuid: 2, + }, + }, + ]; + + it('should combine the two lists into a single list by removing any duplicates from the visitedDomainList.', () => { + const output = combineDomainList({ domainList, visitedDomainList }); + + expect(output).toEqual([ + { + domainInfo: { + name: 'domain0', + uuid: 0, + }, + }, + { + domainInfo: { + name: 'domain1', + uuid: 1, + }, + }, + { + domainInfo: { + name: 'domain2', + uuid: 2, + }, + }, + 'domain3', + { + domainInfo: { + name: 'domain4', + uuid: 4, + }, + }, + ]); + }); + }); +}); diff --git a/client/containers/domain-autocomplete/helpers/filter-top-domain-list.js b/client/containers/domain-autocomplete/helpers/filter-top-domain-list.js new file mode 100644 index 000000000..e24b861ac --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/filter-top-domain-list.js @@ -0,0 +1,27 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import { TOP_DOMAIN_LIST_LIMIT } from '../constants'; + +const filterTopDomainList = domainList => + domainList.slice(0, TOP_DOMAIN_LIST_LIMIT); + +export default filterTopDomainList; diff --git a/client/containers/domain-autocomplete/helpers/filter-top-domain-list.spec.js b/client/containers/domain-autocomplete/helpers/filter-top-domain-list.spec.js new file mode 100644 index 000000000..017dc2907 --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/filter-top-domain-list.spec.js @@ -0,0 +1,53 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import { TOP_DOMAIN_LIST_LIMIT } from '../constants'; +import filterTopDomainList from './filter-top-domain-list'; + +describe('filterTopDomainList', () => { + const createDomainList = size => { + const newDomainList = []; + + for (let i = 1; i < size + 1; i++) { + newDomainList.push(`domain${i}`); + } + + return newDomainList; + }; + + describe('when domainList is greater than TOP_DOMAIN_LIST_LIMIT', () => { + let domainList; + + beforeEach(() => { + domainList = createDomainList(TOP_DOMAIN_LIST_LIMIT * 2); + }); + + it('should return only the first domains of size = TOP_DOMAIN_LIST_LIMIT', () => { + const output = filterTopDomainList(domainList); + + expect(output.length).toEqual(TOP_DOMAIN_LIST_LIMIT); + expect(output[0]).toEqual('domain1'); + expect(output[output.length - 1]).toEqual( + `domain${TOP_DOMAIN_LIST_LIMIT}` + ); + }); + }); +}); diff --git a/client/containers/domain-autocomplete/helpers/filter-visited-domain-list.js b/client/containers/domain-autocomplete/helpers/filter-visited-domain-list.js new file mode 100644 index 000000000..8cf149bef --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/filter-visited-domain-list.js @@ -0,0 +1,32 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const filterVisitedDomainList = ({ search, visitedDomainList }) => + !search + ? visitedDomainList + : visitedDomainList.filter(domain => { + const domainName = + typeof domain === 'string' ? domain : domain.domainInfo.name; + + return domainName.indexOf(search) !== -1; + }); + +export default filterVisitedDomainList; diff --git a/client/containers/domain-autocomplete/helpers/filter-visited-domain-list.spec.js b/client/containers/domain-autocomplete/helpers/filter-visited-domain-list.spec.js new file mode 100644 index 000000000..c5adb9e26 --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/filter-visited-domain-list.spec.js @@ -0,0 +1,67 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import filterVisitedDomainList from './filter-visited-domain-list'; + +describe('filterVisitedDomainList', () => { + let visitedDomainList; + + beforeEach(() => { + visitedDomainList = [ + 'domain1', + { + domainInfo: { + name: 'domain2', + uuid: 2, + }, + }, + 'other', + ]; + }); + + describe('when search = ""', () => { + const search = ''; + + it('should return all of visitedDomainList.', () => { + const output = filterVisitedDomainList({ search, visitedDomainList }); + + expect(output).toEqual(visitedDomainList); + }); + }); + + describe('when search = "domain"', () => { + const search = 'domain'; + + it('should only return domains which match search from visitedDomainList', () => { + const output = filterVisitedDomainList({ search, visitedDomainList }); + + expect(output).toEqual([ + 'domain1', + { + domainInfo: { + name: 'domain2', + uuid: 2, + }, + }, + ]); + }); + }); +}); diff --git a/client/containers/domain-autocomplete/helpers/format-domain-label.js b/client/containers/domain-autocomplete/helpers/format-domain-label.js new file mode 100644 index 000000000..c1dc4d4dc --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/format-domain-label.js @@ -0,0 +1,33 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const formatDomainLabel = domain => + typeof domain === 'string' + ? domain + : [ + domain.domainInfo.name, + domain.isGlobalDomain ? 'Global' : 'Local', + domain.replicationConfiguration.activeClusterName, + ] + .filter(domain => !!domain) + .join(' - '); + +export default formatDomainLabel; diff --git a/client/containers/domain-autocomplete/helpers/format-domain-label.spec.js b/client/containers/domain-autocomplete/helpers/format-domain-label.spec.js new file mode 100644 index 000000000..80c1af59f --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/format-domain-label.spec.js @@ -0,0 +1,70 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import formatDomainLabel from './format-domain-label'; + +describe('formatDomainLabel', () => { + describe('when passed domain string', () => { + const domain = 'domainName'; + + it('should render only the domainName.', () => { + const output = formatDomainLabel(domain); + + expect(output).toEqual('domainName'); + }); + }); + + describe('when passed a local domain object', () => { + it('should return "domainName - Local - activeCluster"', () => { + const domain = { + domainInfo: { + name: 'domainName', + }, + isGlobalDomain: false, + replicationConfiguration: { + activeClusterName: 'activeCluster', + }, + }; + + const output = formatDomainLabel(domain); + + expect(output).toEqual('domainName - Local - activeCluster'); + }); + }); + + describe('when passed a global domain object', () => { + it('should return "domainName - Global - activeCluster"', () => { + const domain = { + domainInfo: { + name: 'domainName', + }, + isGlobalDomain: true, + replicationConfiguration: { + activeClusterName: 'activeCluster', + }, + }; + + const output = formatDomainLabel(domain); + + expect(output).toEqual('domainName - Global - activeCluster'); + }); + }); +}); diff --git a/client/containers/domain-autocomplete/helpers/format-domain-list.js b/client/containers/domain-autocomplete/helpers/format-domain-list.js new file mode 100644 index 000000000..50b4b6d5f --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/format-domain-list.js @@ -0,0 +1,30 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import formatDomainLabel from './format-domain-label'; + +const formatDomainList = domainList => + domainList.map(domain => ({ + label: formatDomainLabel(domain), + value: domain, + })); + +export default formatDomainList; diff --git a/client/containers/domain-autocomplete/helpers/index.js b/client/containers/domain-autocomplete/helpers/index.js index 19b6a175a..bcb19e211 100644 --- a/client/containers/domain-autocomplete/helpers/index.js +++ b/client/containers/domain-autocomplete/helpers/index.js @@ -19,5 +19,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +export { default as combineDomainList } from './combine-domain-list'; +export { default as filterTopDomainList } from './filter-top-domain-list'; +export { default as filterVisitedDomainList } from './filter-visited-domain-list'; +export { default as formatDomainLabel } from './format-domain-label'; +export { default as formatDomainList } from './format-domain-list'; +export { default as sortDomainList } from './sort-domain-list'; export { default as statePrefix } from './state-prefix'; export { default as typePrefix } from './type-prefix'; diff --git a/client/containers/domain-autocomplete/helpers/sort-domain-list.js b/client/containers/domain-autocomplete/helpers/sort-domain-list.js new file mode 100644 index 000000000..c2ca1ec72 --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/sort-domain-list.js @@ -0,0 +1,40 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const sortDomainList = domainList => + domainList.sort((domainA, domainB) => { + const domainNameA = + typeof domainA === 'string' ? domainA : domainA.domainInfo.name; + const domainNameB = + typeof domainB === 'string' ? domainB : domainB.domainInfo.name; + + if (domainNameA < domainNameB) { + return -1; + } + + if (domainNameA > domainNameB) { + return 1; + } + + return 0; + }); + +export default sortDomainList; diff --git a/client/containers/domain-autocomplete/helpers/sort-domain-list.spec.js b/client/containers/domain-autocomplete/helpers/sort-domain-list.spec.js new file mode 100644 index 000000000..496573ae0 --- /dev/null +++ b/client/containers/domain-autocomplete/helpers/sort-domain-list.spec.js @@ -0,0 +1,54 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import sortDomainList from './sort-domain-list'; + +describe('sortDomainList', () => { + const createDomainObject = domainName => ({ + domainInfo: { + name: domainName, + }, + }); + + describe('when passed an unsorted domainList', () => { + it('should return an alphabetically sorted domainList', () => { + const domainA = 'domainA'; + const domainB = 'domainB'; + const domainC = 'domainC'; + const domainD = createDomainObject('domainD'); + const domainE = createDomainObject('domainE'); + const domainF = createDomainObject('domainF'); + + const domainList = [domainF, domainD, domainB, domainE, domainA, domainC]; + + const output = sortDomainList(domainList); + + expect(output).toEqual([ + domainA, + domainB, + domainC, + domainD, + domainE, + domainF, + ]); + }); + }); +}); diff --git a/client/containers/domain-autocomplete/index.js b/client/containers/domain-autocomplete/index.js index 86004e0fb..4d1b2ebce 100644 --- a/client/containers/domain-autocomplete/index.js +++ b/client/containers/domain-autocomplete/index.js @@ -21,9 +21,10 @@ import Component from './component'; import getDefaultState from './get-default-state'; +import getters from './getters'; import connector from './connector'; import mutations from './mutations'; const container = connector(Component); -export { container, getDefaultState, mutations }; +export { container, getDefaultState, getters, mutations }; diff --git a/client/containers/index.js b/client/containers/index.js index 705a45acf..7a0032940 100644 --- a/client/containers/index.js +++ b/client/containers/index.js @@ -28,6 +28,7 @@ export { export { container as DomainAutocomplete, getDefaultState as getDomainAutocompleteDefaultState, + getters as domainAutocompleteGetters, mutations as domainAutocompleteMutations, } from './domain-autocomplete'; export { diff --git a/client/helpers/combine.js b/client/helpers/combine.js new file mode 100644 index 000000000..deb15601e --- /dev/null +++ b/client/helpers/combine.js @@ -0,0 +1,28 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const combine = data => (...callbacks) => + callbacks.reduce( + (accumulator, callback) => (accumulator = callback(accumulator)), + data + ); + +export default combine; diff --git a/client/helpers/index.js b/client/helpers/index.js index 6f8bfd2af..e231954e3 100644 --- a/client/helpers/index.js +++ b/client/helpers/index.js @@ -19,6 +19,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +export { default as combine } from './combine'; export { default as getDatetimeFormattedString } from './get-datetime-formatted-string'; export { default as getEndTimeIsoString } from './get-end-time-iso-string'; export { default as getEnvironment } from './get-environment'; diff --git a/client/store/index.js b/client/store/index.js index d5f79ae7f..b85b600f9 100644 --- a/client/store/index.js +++ b/client/store/index.js @@ -32,6 +32,7 @@ import { // domain autocomplete getDomainAutocompleteDefaultState, + domainAutocompleteGetters, domainAutocompleteMutations, // graph @@ -94,6 +95,7 @@ const getStoreConfig = ({ router, state }) => { }, getters: { ...clusterGetters, + ...domainAutocompleteGetters, ...graphGetters, ...routeGetters, ...settingsWorkflowHistoryGetters,