add a document upload indicator

This commit is contained in:
2019-08-30 18:40:21 +02:00
parent a1a5084b96
commit 1ee044806d
5 changed files with 83 additions and 2 deletions

View File

@@ -10,6 +10,9 @@ module.exports = {
...pathsToModuleNameMapper(compilerOptions.paths, {
prefix: "<rootDir>/",
}),
"react-spring/renderprops":
"<rootDir>/node_modules/react-spring/renderprops.cjs",
"react-spring": "<rootDir>/node_modules/react-spring/web.cjs",
},
setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
};

View File

@@ -24,6 +24,10 @@
.bp3-navbar {
transition: 0.3s;
}
#uploadingStatusButton {
width: 40px;
}
}
#mainContainer.bp3-dark {

View File

@@ -6,9 +6,11 @@ import {
Button,
Classes,
IBreadcrumbProps,
Icon,
Menu,
Navbar,
Popover,
Spinner,
} from "@blueprintjs/core";
import * as React from "react";
import { connect } from "react-redux";
@@ -24,10 +26,13 @@ import { toggleDarkMode } from "~redux/localSettings/actions";
import { IAppState } from "~redux/reducers";
import { logoutUser } from "~redux/user/actions";
interface IHomeProps extends RouteComponentProps {
export interface IHomeProps extends RouteComponentProps {
allDocs: { [key: number]: IDocumentJSON };
user: IUserJSON | null;
fetching: boolean;
uploading: boolean;
darkMode: boolean;
logout: () => void;
@@ -72,6 +77,13 @@ export class HomeComponent extends React.PureComponent<IHomeProps> {
<Breadcrumbs items={breadcrumbs} />
</Navbar.Group>
<Navbar.Group align={Alignment.RIGHT}>
<Button id="uploadingStatusButton">
{this.props.uploading ? (
<Spinner size={20} />
) : (
<Icon icon="saved" />
)}
</Button>
<Popover
target={
<Button id="userButton">
@@ -161,6 +173,8 @@ function mapStateToProps(state: IAppState) {
allDocs: state.docs.all,
user: state.user.user,
darkMode: state.localSettings.darkMode,
fetching: state.docs.fetching,
uploading: state.docs.uploading,
};
}

View File

@@ -0,0 +1,52 @@
import { shallow } from "enzyme";
import * as React from "react";
import { Icon, Spinner } from "@blueprintjs/core";
import { HomeComponent, IHomeProps } from "../Home";
const defaultHomeProps: IHomeProps = {
allDocs: {},
user: { id: 1, username: "test" },
fetching: false,
uploading: false,
darkMode: false,
logout: jest.fn(),
dispatchToggleDarkMode: jest.fn(),
history: { location: { pathname: "/" } } as any,
location: { pathname: "/" } as any,
match: {
params: {
id: null,
},
} as any,
};
describe("<Home />", () => {
it("should show a spinner when uploading", () => {
const wrapper = shallow(
<HomeComponent {...defaultHomeProps} uploading={true} />,
);
expect(
wrapper.find("#uploadingStatusButton").find(Spinner),
).toHaveLength(1);
expect(wrapper.find("#uploadingStatusButton").find(Icon)).toHaveLength(
0,
);
});
it("should show a saved icon when not uploading", () => {
const wrapper = shallow(
<HomeComponent {...defaultHomeProps} uploading={false} />,
);
expect(
wrapper.find("#uploadingStatusButton").find(Spinner),
).toHaveLength(0);
expect(wrapper.find("#uploadingStatusButton").find(Icon)).toHaveLength(
1,
);
});
});

View File

@@ -7,6 +7,7 @@ import { DocsAction, DocsTypes } from "./actions";
export interface IDocsState {
all: { [key: number]: IDocumentJSON };
fetching: boolean;
uploading: boolean;
error: string | null;
spinner: boolean;
@@ -18,6 +19,7 @@ export interface IDocsState {
const defaultDocsState: IDocsState = {
all: null,
fetching: false,
uploading: false,
error: null,
spinner: false,
newDocumentID: null,
@@ -64,11 +66,17 @@ export const docsReducer: Reducer<IDocsState, DocsAction> = (
all[deletedDocument.id] = deletedDocument;
return { ...state, deletedDocument: null, all };
}
case DocsTypes.DOC_UPDATE_START: {
return { ...state, uploading: true };
}
case DocsTypes.DOC_UPDATE_FAIL: {
return { ...state, uploading: false };
}
case DocsTypes.DOC_UPDATE_SUCCESS: {
const all = { ...state.all };
const doc = action.payload.doc;
all[doc.id] = doc;
return { ...state, all };
return { ...state, all, uploading: false };
}
case DocsTypes.DOCS_FETCH_FAIL:
return { ...defaultDocsState, ...action.payload };