diff --git a/dashboard/src/actions/repos.test.tsx b/dashboard/src/actions/repos.test.tsx index b5f75918dab..6adc2ec3287 100644 --- a/dashboard/src/actions/repos.test.tsx +++ b/dashboard/src/actions/repos.test.tsx @@ -112,21 +112,6 @@ describe("deleteRepo", () => { }); describe("resyncRepo", () => { - it("dispatches requestRepos and receiveRepos if no error", async () => { - const expectedActions = [ - { - type: getType(repoActions.requestRepos), - }, - { - type: getType(repoActions.receiveRepos), - payload: { foo: "bar" }, - }, - ]; - - await store.dispatch(repoActions.resyncRepo("foo")); - expect(store.getActions()).toEqual(expectedActions); - }); - it("dispatches errorRepos if error on #get", async () => { AppRepository.get = jest.fn().mockImplementationOnce(() => { throw new Error("Boom!"); @@ -158,25 +143,6 @@ describe("resyncRepo", () => { await store.dispatch(repoActions.resyncRepo("foo")); expect(store.getActions()).toEqual(expectedActions); }); - - it("dispatches requestRepos and errorRepos if error on #list", async () => { - AppRepository.list = jest.fn().mockImplementationOnce(() => { - throw new Error("Boom!"); - }); - - const expectedActions = [ - { - type: getType(repoActions.requestRepos), - }, - { - type: getType(repoActions.errorRepos), - payload: { err: new Error("Boom!"), op: "update" }, - }, - ]; - - await store.dispatch(repoActions.resyncRepo("foo")); - expect(store.getActions()).toEqual(expectedActions); - }); }); describe("fetchRepos", () => { diff --git a/dashboard/src/actions/repos.ts b/dashboard/src/actions/repos.ts index d931f3267d8..0ded8eabc71 100644 --- a/dashboard/src/actions/repos.ts +++ b/dashboard/src/actions/repos.ts @@ -92,15 +92,22 @@ export const resyncRepo = ( repo.spec.resyncRequests++; await AppRepository.update(name, namespace, repo); // TODO: Do something to show progress - dispatch(requestRepos()); - const repos = await AppRepository.list(namespace); - dispatch(receiveRepos(repos.items)); } catch (e) { dispatch(errorRepos(e, "update")); } }; }; +export const resyncAllRepos = ( + repoNames: string[], +): ThunkAction, IStoreState, null, AppReposAction> => { + return async (dispatch, getState) => { + repoNames.forEach(name => { + dispatch(resyncRepo(name)); + }); + }; +}; + export const fetchRepos = (): ThunkAction, IStoreState, null, AppReposAction> => { return async (dispatch, getState) => { dispatch(requestRepos()); diff --git a/dashboard/src/components/Config/AppRepoList/AppRepoButton.tsx b/dashboard/src/components/Config/AppRepoList/AppRepoButton.tsx index 2c5143c9821..797bf9fdcec 100644 --- a/dashboard/src/components/Config/AppRepoList/AppRepoButton.tsx +++ b/dashboard/src/components/Config/AppRepoList/AppRepoButton.tsx @@ -43,7 +43,7 @@ export class AppRepoAddButton extends React.Component< public render() { const { redirectTo } = this.props; return ( -
+ @@ -64,7 +64,7 @@ export class AppRepoAddButton extends React.Component< {redirectTo && } -
+ ); } diff --git a/dashboard/src/components/Config/AppRepoList/AppRepoList.tsx b/dashboard/src/components/Config/AppRepoList/AppRepoList.tsx index 9123159b513..2e0909faf91 100644 --- a/dashboard/src/components/Config/AppRepoList/AppRepoList.tsx +++ b/dashboard/src/components/Config/AppRepoList/AppRepoList.tsx @@ -4,6 +4,7 @@ import { IAppRepository, IRBACRole } from "../../../shared/types"; import ErrorSelector from "../../ErrorAlert/ErrorSelector"; import { AppRepoAddButton } from "./AppRepoButton"; import { AppRepoListItem } from "./AppRepoListItem"; +import { AppRepoRefreshAllButton } from "./AppRepoRefreshAllButton"; export interface IAppRepoListProps { errors: { @@ -16,6 +17,7 @@ export interface IAppRepoListProps { fetchRepos: () => void; deleteRepo: (name: string) => Promise; resyncRepo: (name: string) => void; + resyncAllRepos: (names: string[]) => void; install: (name: string, url: string, authHeader: string, customCA: string) => Promise; kubeappsNamespace: string; } @@ -61,7 +63,15 @@ class AppRepoList extends React.Component { } public render() { - const { errors, repos, install, deleteRepo, resyncRepo, kubeappsNamespace } = this.props; + const { + errors, + repos, + install, + deleteRepo, + resyncRepo, + resyncAllRepos, + kubeappsNamespace, + } = this.props; return (

App Repositories

@@ -92,6 +102,11 @@ class AppRepoList extends React.Component { install={install} kubeappsNamespace={kubeappsNamespace} /> +
); } diff --git a/dashboard/src/components/Config/AppRepoList/AppRepoRefreshAllButton.tsx b/dashboard/src/components/Config/AppRepoList/AppRepoRefreshAllButton.tsx new file mode 100644 index 00000000000..38c786eefab --- /dev/null +++ b/dashboard/src/components/Config/AppRepoList/AppRepoRefreshAllButton.tsx @@ -0,0 +1,33 @@ +import * as React from "react"; + +import { IAppRepository } from "shared/types"; +import "./AppRepo.css"; + +interface IAppRepoRefreshAllButtonProps { + resyncAllRepos: (names: string[]) => void; + repos: IAppRepository[]; + kubeappsNamespace: string; +} + +export class AppRepoRefreshAllButton extends React.Component { + public render() { + return ( + + ); + } + + private handleResyncAllClick = async () => { + if (this.props.repos) { + const repoNames = this.props.repos.map(repo => { + return repo.metadata.name; + }); + this.props.resyncAllRepos(repoNames); + } + }; +} diff --git a/dashboard/src/components/Config/AppRepoList/__snapshots__/AppRepoButton.test.tsx.snap b/dashboard/src/components/Config/AppRepoList/__snapshots__/AppRepoButton.test.tsx.snap index 5c4c53a1bfc..e21ba15af6d 100644 --- a/dashboard/src/components/Config/AppRepoList/__snapshots__/AppRepoButton.test.tsx.snap +++ b/dashboard/src/components/Config/AppRepoList/__snapshots__/AppRepoButton.test.tsx.snap @@ -5,301 +5,297 @@ exports[`should open a modal with the repository form 1`] = ` install={[Function]} kubeappsNamespace="kubeapps" > -
- - - + +