diff --git a/src/components/ArtifactsActionBar/ArtifactsActionBar.js b/src/components/ArtifactsActionBar/ArtifactsActionBar.js index aeae500b1..fb82bf93d 100644 --- a/src/components/ArtifactsActionBar/ArtifactsActionBar.js +++ b/src/components/ArtifactsActionBar/ArtifactsActionBar.js @@ -23,7 +23,7 @@ import arrayMutators from 'final-form-arrays' import { Form } from 'react-final-form' import { useDispatch, useSelector } from 'react-redux' import { isEmpty } from 'lodash' -import { useNavigate, useParams } from 'react-router-dom' +import { useNavigate, useParams, useSearchParams } from 'react-router-dom' import PropTypes from 'prop-types' import { RoundedIcon, Button } from 'igz-controls/components' @@ -39,7 +39,7 @@ import { TAG_FILTER_ALL_ITEMS } from '../../constants' import detailsActions from '../../actions/details' -import { removeFilters, setFilters } from '../../reducers/filtersReducer' +import { removeFilters, setFilters, setModalFiltersValues } from '../../reducers/filtersReducer' import { setFieldState } from 'igz-controls/utils/form.util' import { ReactComponent as RefreshIcon } from 'igz-controls/images/refresh.svg' @@ -62,6 +62,7 @@ function ArtifactsActionBar({ const changes = useSelector(store => store.detailsStore.changes) const dispatch = useDispatch() const params = useParams() + let [searchParams] = useSearchParams() const navigate = useNavigate() const formRef = React.useRef( createForm({ @@ -84,6 +85,29 @@ function ArtifactsActionBar({ } }, [params.pageTab, params.projectName, page, tab, dispatch]) + useEffect(() => { + if (searchParams.get('useUrlParamsAsFilter') === 'true') { + if (params.name) { + dispatch( + setFilters({ + name: params.name, + iter: '' + }) + ) + dispatch( + setModalFiltersValues({ + name: filterMenuName, + value: { iter: '' } + }) + ) + } + } + }, [searchParams, params, dispatch, filterMenuName]) + + useEffect(() => { + formRef.current?.change('name', filtersStore.name) + }, [filtersStore.name]) + const applyChanges = async (name, filterMenuModal) => { const filtersHelperResult = await filtersHelper(changes, dispatch) @@ -153,7 +177,7 @@ function ArtifactsActionBar({ filterMenuName={filterMenuName} initialValues={filtersInitialState} restartFormTrigger={tab ?? page} - values={filtersInitialState} + values={filterMenuModal.values} wizardClassName="artifacts-filters__wrapper" > @@ -211,4 +235,4 @@ ArtifactsActionBar.propTypes = { tab: PropTypes.string } -export default ArtifactsActionBar +export default ArtifactsActionBar \ No newline at end of file diff --git a/src/components/Datasets/Datasets.js b/src/components/Datasets/Datasets.js index f40f0a920..f9f1dc6a4 100644 --- a/src/components/Datasets/Datasets.js +++ b/src/components/Datasets/Datasets.js @@ -33,7 +33,6 @@ import { GROUP_BY_NAME, GROUP_BY_NONE, REQUEST_CANCELED, - SHOW_ITERATIONS, TAG_FILTER_ALL_ITEMS } from '../../constants' import { @@ -63,6 +62,7 @@ import { useGetTagOptions } from '../../hooks/useGetTagOptions.hook' import { useGroupContent } from '../../hooks/groupContent.hook' import { useSortTable } from '../../hooks/useSortTable.hook' import { useYaml } from '../../hooks/yaml.hook' +import { useInitialArtifactsFetch } from '../../hooks/artifacts.hook' const Datasets = () => { const [datasets, setDatasets] = useState([]) @@ -109,7 +109,7 @@ const Datasets = () => { filters => { abortControllerRef.current = new AbortController() - dispatch( + return dispatch( fetchDataSets({ project: params.projectName, filters, @@ -286,21 +286,20 @@ const Datasets = () => { } }) + useInitialArtifactsFetch( + fetchData, + urlTagOption, + datasets.length, + setSelectedRowData, + createDatasetsRowData + ) + useEffect(() => { if (params.name && params.tag && pageData.details.menu.length > 0) { isDetailsTabExists(params.tab, pageData.details.menu, navigate, location) } }, [location, navigate, pageData.details.menu, params.name, params.tab, params.tag]) - useEffect(() => { - if (urlTagOption && datasets.length === 0) { - fetchData({ - tag: urlTagOption, - iter: SHOW_ITERATIONS - }) - } - }, [datasets.length, fetchData, urlTagOption]) - useEffect(() => { dispatch(setFilters({ groupBy: GROUP_BY_NONE })) }, [dispatch, params.projectName]) diff --git a/src/components/Datasets/DatasetsView.js b/src/components/Datasets/DatasetsView.js index a8ae13a23..a926b03e2 100644 --- a/src/components/Datasets/DatasetsView.js +++ b/src/components/Datasets/DatasetsView.js @@ -127,7 +127,7 @@ const DatasetsView = React.forwardRef( diff --git a/src/components/Files/Files.js b/src/components/Files/Files.js index 7e26e5ed3..23f054350 100644 --- a/src/components/Files/Files.js +++ b/src/components/Files/Files.js @@ -34,7 +34,6 @@ import { GROUP_BY_NAME, GROUP_BY_NONE, REQUEST_CANCELED, - SHOW_ITERATIONS, TAG_FILTER_ALL_ITEMS } from '../../constants' import { @@ -64,6 +63,7 @@ import { useGroupContent } from '../../hooks/groupContent.hook' import { useYaml } from '../../hooks/yaml.hook' import { getViewMode } from '../../utils/helper' import { useSortTable } from '../../hooks/useSortTable.hook' +import { useInitialArtifactsFetch } from '../../hooks/artifacts.hook' const Files = () => { const [files, setFiles] = useState([]) @@ -104,7 +104,7 @@ const Files = () => { filters => { abortControllerRef.current = new AbortController() - dispatch( + return dispatch( fetchFiles({ project: params.projectName, filters, @@ -277,18 +277,20 @@ const Files = () => { handleRefresh(filesFilters) } + useInitialArtifactsFetch( + fetchData, + urlTagOption, + files.length, + setSelectedRowData, + createFilesRowData + ) + useEffect(() => { if (params.name && params.tag && pageData.details.menu.length > 0) { isDetailsTabExists(params.tab, pageData.details.menu, navigate, location) } }, [navigate, location, pageData.details.menu, params.name, params.tag, params.tab]) - useEffect(() => { - if (urlTagOption) { - fetchData({ tag: urlTagOption, iter: SHOW_ITERATIONS }) - } - }, [fetchData, urlTagOption]) - useEffect(() => { return () => { setFiles([]) diff --git a/src/components/Files/FilesView.js b/src/components/Files/FilesView.js index e97066835..7e059fb00 100644 --- a/src/components/Files/FilesView.js +++ b/src/components/Files/FilesView.js @@ -127,7 +127,7 @@ const FilesView = React.forwardRef( { + if (!isEqual(initialValues, values)) { + formRef.current?.batch(() => { + for (const filterName in values) { + formRef.current?.change(filterName, values[filterName]) + } + }) + } + }, [initialValues, values]) + const hideFiltersWizard = useCallback(event => { if ( !event.target.closest('.filters-button') && diff --git a/src/components/ModelsPage/Models/Models.js b/src/components/ModelsPage/Models/Models.js index 3640e4777..61417c990 100644 --- a/src/components/ModelsPage/Models/Models.js +++ b/src/components/ModelsPage/Models/Models.js @@ -46,7 +46,6 @@ import { MODELS_FILTERS, REQUEST_CANCELED, MODEL_TYPE, - SHOW_ITERATIONS, FUNCTION_TYPE_SERVING } from '../../../constants' import { @@ -73,6 +72,7 @@ import { useSortTable } from '../../../hooks/useSortTable.hook' import { useGetTagOptions } from '../../../hooks/useGetTagOptions.hook' import { getViewMode } from '../../../utils/helper' import { useMode } from '../../../hooks/mode.hook' +import { useInitialArtifactsFetch } from '../../../hooks/artifacts.hook' const Models = ({ fetchModelFeatureVector }) => { const [models, setModels] = useState([]) @@ -326,21 +326,20 @@ const Models = ({ fetchModelFeatureVector }) => { handleRefresh(modelsFilters) } + useInitialArtifactsFetch( + fetchData, + urlTagOption, + models.length, + setSelectedRowData, + createModelsRowData + ) + useEffect(() => { if (params.name && params.tag && pageData.details.menu.length > 0) { isDetailsTabExists(params.tab, pageData.details.menu, navigate, location) } }, [navigate, location, pageData.details.menu, params.name, params.tag, params.tab]) - useEffect(() => { - if (urlTagOption) { - fetchData({ - tag: urlTagOption, - iter: SHOW_ITERATIONS - }) - } - }, [fetchData, urlTagOption]) - useEffect(() => { return () => { setModels([]) diff --git a/src/components/ModelsPage/Models/ModelsView.js b/src/components/ModelsPage/Models/ModelsView.js index 0383fd476..e1a8cc92d 100644 --- a/src/components/ModelsPage/Models/ModelsView.js +++ b/src/components/ModelsPage/Models/ModelsView.js @@ -133,7 +133,7 @@ const ModelsView = React.forwardRef( actionsMenu={actionsMenu} handleExpandRow={handleExpandRow} rowIndex={index} - key={index} + key={tableItem.data.ui.identifier} rowItem={tableItem} selectedItem={selectedModel} selectedRowData={selectedRowData} diff --git a/src/elements/ArtifactsTableRow/ArtifactsTableRow.js b/src/elements/ArtifactsTableRow/ArtifactsTableRow.js index a5fbd8d95..09f948a0a 100644 --- a/src/elements/ArtifactsTableRow/ArtifactsTableRow.js +++ b/src/elements/ArtifactsTableRow/ArtifactsTableRow.js @@ -53,7 +53,9 @@ const ArtifactsTableRow = ({ getArtifactIdentifier(selectedItem, true) === rowItem.data.ui.identifierUnique && !parent.current?.classList.value.includes('parent-row_expanded') && 'table-row_active', - parent.current?.classList.value.includes('parent-row_expanded') && 'parent-row_expanded' + (parent.current?.classList.value.includes('parent-row_expanded') || + (selectedRowData && rowItem.data.ui.identifier in selectedRowData)) && + 'parent-row_expanded' ) return ( diff --git a/src/hooks/artifacts.hook.js b/src/hooks/artifacts.hook.js new file mode 100644 index 000000000..9aeeff141 --- /dev/null +++ b/src/hooks/artifacts.hook.js @@ -0,0 +1,79 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import { useEffect } from 'react' +import { useParams, useSearchParams } from 'react-router-dom' +import { useDispatch } from 'react-redux' + +import { GROUP_BY_NAME, SHOW_ITERATIONS } from '../constants' +import { setFilters } from '../reducers/filtersReducer' +import { sortListByDate } from '../utils' + +export const useInitialArtifactsFetch = ( + fetchData, + urlTagOption, + artifactsLength, + setExpandedRowsData, + createArtifactsRowData +) => { + const [searchParams] = useSearchParams() + const params = useParams() + const dispatch = useDispatch() + + useEffect(() => { + if (urlTagOption && artifactsLength === 0) { + let filtersLocal = { tag: urlTagOption, iter: SHOW_ITERATIONS } + + if (searchParams.get('useUrlParamsAsFilter') === 'true') { + filtersLocal = { tag: urlTagOption, iter: '', name: params.name } + + dispatch( + setFilters({ + groupBy: GROUP_BY_NAME + }) + ) + } + + fetchData(filtersLocal).then(result => { + if (filtersLocal.name) { + setExpandedRowsData(state => ({ + ...state, + [filtersLocal.name]: { + content: sortListByDate(result, 'updated', false).map(artifact => + createArtifactsRowData(artifact, params.projectName) + ) + }, + error: null, + loading: false + })) + } + }) + } + }, [ + dispatch, + fetchData, + artifactsLength, + params.name, + params.projectName, + searchParams, + urlTagOption, + setExpandedRowsData, + createArtifactsRowData + ]) +}