Wizard: Add 'Refresh' button to repositories step
Users may visit the Repositories service to add or modify repositories while they are on the repositories step in the wizard. This commit adds a 'Refresh' button that will refetch the repositories and update the table so that the user does not have to restart the wizard to view their modifications.
This commit is contained in:
parent
383f2a6855
commit
05b411c241
2 changed files with 137 additions and 72 deletions
|
|
@ -16,6 +16,8 @@ import {
|
|||
EmptyStateIcon,
|
||||
EmptyStateVariant,
|
||||
Pagination,
|
||||
Panel,
|
||||
PanelMain,
|
||||
SearchInput,
|
||||
Spinner,
|
||||
Title,
|
||||
|
|
@ -47,6 +49,7 @@ const BulkSelect = ({
|
|||
handleSelectAll,
|
||||
handleSelectPage,
|
||||
handleDeselectAll,
|
||||
isDisabled,
|
||||
}) => {
|
||||
const [dropdownIsOpen, setDropdownIsOpen] = useState(false);
|
||||
|
||||
|
|
@ -80,6 +83,7 @@ const BulkSelect = ({
|
|||
toggle={
|
||||
<DropdownToggle
|
||||
id="stacked-example-toggle"
|
||||
isDisabled={isDisabled}
|
||||
splitButtonItems={[
|
||||
<DropdownToggleCheckbox
|
||||
id="example-checkbox-1"
|
||||
|
|
@ -214,10 +218,17 @@ const Repositories = (props) => {
|
|||
const release = getState().values?.release;
|
||||
const version = releaseToVersion(release);
|
||||
|
||||
const { data, isError, isLoading, isSuccess } = useGetRepositoriesQuery({
|
||||
available_for_arch: 'x86_64',
|
||||
available_for_version: version,
|
||||
});
|
||||
const { data, isError, isFetching, isLoading, isSuccess, refetch } =
|
||||
useGetRepositoriesQuery(
|
||||
{
|
||||
available_for_arch: 'x86_64',
|
||||
available_for_version: version,
|
||||
},
|
||||
// The cached repos may be incorrect, for now refetch on mount to ensure that
|
||||
// they are accurate when this step loads. Future PR will implement prefetching
|
||||
// and this can be removed.
|
||||
{ refetchOnMountOrArgChange: true }
|
||||
);
|
||||
|
||||
const repositories = useMemo(() => {
|
||||
return data ? initializeRepositories(data.data) : {};
|
||||
|
|
@ -319,7 +330,7 @@ const Repositories = (props) => {
|
|||
(isSuccess && (
|
||||
<>
|
||||
{Object.values(repositories).length === 0 ? (
|
||||
<Empty />
|
||||
<Empty refetch={refetch} isFetching={isFetching} />
|
||||
) : (
|
||||
<>
|
||||
<Toolbar>
|
||||
|
|
@ -333,6 +344,7 @@ const Repositories = (props) => {
|
|||
handleSelectAll={handleSelectAll}
|
||||
handleSelectPage={handleSelectPage}
|
||||
handleDeselectAll={handleDeselectAll}
|
||||
isDisabled={isFetching}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem variant="search-filter">
|
||||
|
|
@ -343,6 +355,16 @@ const Repositories = (props) => {
|
|||
onClear={handleClearFilter}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="primary"
|
||||
isInline
|
||||
onClick={() => refetch()}
|
||||
isLoading={isFetching}
|
||||
>
|
||||
{isFetching ? 'Refreshing' : 'Refresh'}
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem variant="pagination">
|
||||
<Pagination
|
||||
itemCount={filteredRepositoryURLs.length}
|
||||
|
|
@ -356,68 +378,78 @@ const Repositories = (props) => {
|
|||
</ToolbarItem>
|
||||
</ToolbarContent>
|
||||
</Toolbar>
|
||||
<TableComposable variant="compact" data-testid="repositories-table">
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th />
|
||||
<Th width={50}>Name</Th>
|
||||
<Th>Architecture</Th>
|
||||
<Th>Versions</Th>
|
||||
<Th>Packages</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{filteredRepositoryURLs
|
||||
.slice()
|
||||
.sort((a, b) => {
|
||||
if (repositories[a].name < repositories[b].name) {
|
||||
return -1;
|
||||
} else if (repositories[b].name < repositories[a].name) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.slice(computeStart(), computeEnd())
|
||||
.map((repoURL, rowIndex) => {
|
||||
const repo = repositories[repoURL];
|
||||
return (
|
||||
<Tr key={repo.url}>
|
||||
<Td
|
||||
select={{
|
||||
isSelected: isRepoSelected(repo.url),
|
||||
rowIndex: rowIndex,
|
||||
onSelect: (event, isSelecting) =>
|
||||
handleSelect(repo.url, rowIndex, isSelecting),
|
||||
}}
|
||||
/>
|
||||
<Td dataLabel={'Name'}>
|
||||
{repo.name}
|
||||
<br />
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={repo.url}
|
||||
>
|
||||
{repo.url}
|
||||
</Button>
|
||||
</Td>
|
||||
<Td dataLabel={'Architecture'}>
|
||||
{repo.distribution_arch}
|
||||
</Td>
|
||||
<Td dataLabel={'Version'}>
|
||||
{repo.distribution_versions}
|
||||
</Td>
|
||||
<Td dataLabel={'Packages'}>{repo.package_count}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</Tbody>
|
||||
</TableComposable>
|
||||
<Panel isScrollable>
|
||||
<PanelMain>
|
||||
<TableComposable
|
||||
variant="compact"
|
||||
data-testid="repositories-table"
|
||||
>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th />
|
||||
<Th width={50}>Name</Th>
|
||||
<Th>Architecture</Th>
|
||||
<Th>Versions</Th>
|
||||
<Th>Packages</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{filteredRepositoryURLs
|
||||
.slice()
|
||||
.sort((a, b) => {
|
||||
if (repositories[a].name < repositories[b].name) {
|
||||
return -1;
|
||||
} else if (
|
||||
repositories[b].name < repositories[a].name
|
||||
) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.slice(computeStart(), computeEnd())
|
||||
.map((repoURL, rowIndex) => {
|
||||
const repo = repositories[repoURL];
|
||||
return (
|
||||
<Tr key={repo.url}>
|
||||
<Td
|
||||
select={{
|
||||
isSelected: isRepoSelected(repo.url),
|
||||
rowIndex: rowIndex,
|
||||
onSelect: (event, isSelecting) =>
|
||||
handleSelect(repo.url, rowIndex, isSelecting),
|
||||
disable: isFetching,
|
||||
}}
|
||||
/>
|
||||
<Td dataLabel={'Name'}>
|
||||
{repo.name}
|
||||
<br />
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={repo.url}
|
||||
>
|
||||
{repo.url}
|
||||
</Button>
|
||||
</Td>
|
||||
<Td dataLabel={'Architecture'}>
|
||||
{repo.distribution_arch}
|
||||
</Td>
|
||||
<Td dataLabel={'Version'}>
|
||||
{repo.distribution_versions}
|
||||
</Td>
|
||||
<Td dataLabel={'Packages'}>{repo.package_count}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</Tbody>
|
||||
</TableComposable>
|
||||
</PanelMain>
|
||||
</Panel>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
|
@ -444,7 +476,7 @@ const Loading = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const Empty = () => {
|
||||
const Empty = ({ isFetching, refetch }) => {
|
||||
const { isBeta } = useGetEnvironment();
|
||||
return (
|
||||
<EmptyState variant={EmptyStateVariant.large} data-testid="empty-state">
|
||||
|
|
@ -461,10 +493,19 @@ const Empty = () => {
|
|||
variant="primary"
|
||||
component="a"
|
||||
target="_blank"
|
||||
href={isBeta() ? '/beta/settings/content' : '/settings/content'}
|
||||
href={isBeta() ? '/preview/settings/content' : '/settings/content'}
|
||||
className="pf-u-mr-sm"
|
||||
>
|
||||
Repositories
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
isInline
|
||||
onClick={() => refetch()}
|
||||
isLoading={isFetching}
|
||||
>
|
||||
{isFetching ? 'Refreshing' : 'Refresh'}
|
||||
</Button>
|
||||
</EmptyState>
|
||||
);
|
||||
};
|
||||
|
|
@ -477,6 +518,12 @@ BulkSelect.propTypes = {
|
|||
handleSelectAll: PropTypes.func,
|
||||
handleSelectPage: PropTypes.func,
|
||||
handleDeselectAll: PropTypes.func,
|
||||
isDisabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
Empty.propTypes = {
|
||||
isFetching: PropTypes.bool,
|
||||
refetch: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Repositories;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue