Skip to content

Commit

Permalink
Merge pull request #319 from labzero/jeffrey/confirm-modal
Browse files Browse the repository at this point in the history
Convert ConfirmModal to TypeScript
  • Loading branch information
JeffreyATW authored May 23, 2023
2 parents 79f55fb + 8ef68e2 commit 21a8b30
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 52 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,4 @@
"prepare": "husky install"
},
"packageManager": "[email protected]"
}
}
9 changes: 2 additions & 7 deletions src/actions/tests/decisions.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-env mocha */
/* eslint-disable no-unused-expressions, no-underscore-dangle, import/no-duplicates, arrow-body-style */

import { ThunkDispatch } from "@reduxjs/toolkit";
import { expect } from "chai";
import {
configureMockStore,
Expand All @@ -10,17 +9,13 @@ import {
import fetchMock from "fetch-mock";
import thunk from "redux-thunk";
import * as decisions from "../decisions";
import { Action, State } from "../../interfaces";
import { Action, Dispatch, State } from "../../interfaces";

const middlewares = [thunk];
const mockStore = configureMockStore<State, Action>(middlewares);

describe("actions/decisions", () => {
let store: MockStoreEnhanced<
State,
Action,
ThunkDispatch<State, unknown, Action>
>;
let store: MockStoreEnhanced<State, Action, Dispatch>;

beforeEach(() => {
store = mockStore({});
Expand Down
4 changes: 2 additions & 2 deletions src/actions/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export function removeUser(
};
}

export function postUser(obj: User): Action {
export function postUser(obj: Partial<User>): Action {
return {
type: "POST_USER",
user: obj,
Expand All @@ -129,7 +129,7 @@ export function userPosted(json: User): Action {
}

export function addUser(
payload: User
payload: Partial<User>
): ThunkAction<void, State, unknown, Action> {
return (dispatch) => {
dispatch(postUser(payload));
Expand Down
28 changes: 14 additions & 14 deletions src/actions/websockets.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ThunkAction } from "@reduxjs/toolkit";
import { sortRestaurants } from "./restaurants";
import { notify } from "./notifications";
import { Action, State } from "../interfaces";
import { ThunkAction, ThunkDispatch } from "@reduxjs/toolkit";
import { Action, Dispatch, State } from "../interfaces";

let sortTimeout: NodeJS.Timer;

const sort = (dispatch: ThunkDispatch<State, unknown, Action>) => {
const sort = (dispatch: Dispatch) => {
clearTimeout(sortTimeout);
sortTimeout = setTimeout(() => {
dispatch(sortRestaurants());
Expand Down Expand Up @@ -47,17 +47,17 @@ const actionMap: Partial<{
data: Action
) => ThunkAction<void, State, unknown, Action>;
}> = {
["RESTAURANT_POSTED"]: dispatchSortNotify,
["RESTAURANT_DELETED"]: notifyDispatch,
["RESTAURANT_RENAMED"]: notifyDispatchSort,
["VOTE_POSTED"]: notifyDispatchSort,
["VOTE_DELETED"]: notifyDispatchSort,
["POSTED_TAG_TO_RESTAURANT"]: dispatchNotify,
["POSTED_NEW_TAG_TO_RESTAURANT"]: dispatchNotify,
["DELETED_TAG_FROM_RESTAURANT"]: dispatchNotify,
["TAG_DELETED"]: notifyDispatch,
["DECISION_POSTED"]: dispatchSortNotify,
["DECISIONS_DELETED"]: dispatchSortNotify,
RESTAURANT_POSTED: dispatchSortNotify,
RESTAURANT_DELETED: notifyDispatch,
RESTAURANT_RENAMED: notifyDispatchSort,
VOTE_POSTED: notifyDispatchSort,
VOTE_DELETED: notifyDispatchSort,
POSTED_TAG_TO_RESTAURANT: dispatchNotify,
POSTED_NEW_TAG_TO_RESTAURANT: dispatchNotify,
DELETED_TAG_FROM_RESTAURANT: dispatchNotify,
TAG_DELETED: notifyDispatch,
DECISION_POSTED: dispatchSortNotify,
DECISIONS_DELETED: dispatchSortNotify,
};

export function messageReceived(
Expand Down
5 changes: 3 additions & 2 deletions src/components/AddUserForm/AddUserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import Form from "react-bootstrap/Form";
import Row from "react-bootstrap/Row";
import { IntlShape } from "react-intl";
import { globalMessageDescriptor as gm } from "../../helpers/generateMessageDescriptor";
import { RoleType } from "../../interfaces";

interface AddUserFormState {
email?: string;
name?: string;
type?: string;
type?: RoleType;
}

export interface AddUserFormProps {
Expand All @@ -21,7 +22,7 @@ export interface AddUserFormProps {
}

class AddUserForm extends Component<AddUserFormProps, AddUserFormState> {
static defaultState = {
static defaultState: AddUserFormState = {
email: "",
name: "",
type: "member",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import { injectIntl } from "react-intl";
import { addUser } from "../../actions/users";
import { currentUserHasRole, isUserListReady } from "../../selectors";
import AddUserForm from "./AddUserForm";
import { Dispatch, State, User } from "../../interfaces";

const mapStateToProps = (state) => ({
const mapStateToProps = (state: State) => ({
hasGuestRole: currentUserHasRole(state, "guest"),
hasMemberRole: currentUserHasRole(state, "member"),
hasOwnerRole: currentUserHasRole(state, "owner"),
userListReady: isUserListReady(state),
});

const mapDispatchToProps = (dispatch) => ({
addUserToTeam: (payload) => dispatch(addUser(payload)),
const mapDispatchToProps = (dispatch: Dispatch) => ({
addUserToTeam: (payload: Partial<User>) => dispatch(addUser(payload)),
});

export default connect(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { connect } from "react-redux";
import { ThunkDispatch } from "@reduxjs/toolkit";
import { updateTeam } from "../../actions/team";
import { hideModal } from "../../actions/modals";
import { Action, State, Team } from "../../interfaces";
import { Dispatch, State, Team } from "../../interfaces";
import { getTeam } from "../../selectors/team";
import ChangeTeamURLModal from "./ChangeTeamURLModal";

Expand All @@ -14,9 +13,7 @@ const mapStateToProps = (state: State) => ({
shown: !!state.modals[modalName].shown,
});

const mapDispatchToProps = (
dispatch: ThunkDispatch<State, unknown, Action>
) => ({
const mapDispatchToProps = (dispatch: Dispatch) => ({
hideModal: () => {
dispatch(hideModal(modalName));
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { expect } from "chai";
import React from "react";
import sinon from "sinon";
import { render, screen } from "../../../test/test-utils";
import ConfirmModal from "./ConfirmModal";
import ConfirmModal, { ConfirmModalProps } from "./ConfirmModal";

describe("ConfirmModal", () => {
let props;
let props: ConfirmModalProps;

beforeEach(() => {
props = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import PropTypes from "prop-types";
import React from "react";
import React, { ReactNode } from "react";
import Modal from "react-bootstrap/Modal";
import ModalBody from "react-bootstrap/ModalBody";
import ModalFooter from "react-bootstrap/ModalFooter";
import Button from "react-bootstrap/Button";

export interface ConfirmModalProps {
actionLabel: string;
shown: boolean;
hideModal: () => void;
body: ReactNode;
handleSubmit: () => void;
}

const ConfirmModal = ({
actionLabel,
shown,
hideModal,
body,
handleSubmit,
}) => (
}: ConfirmModalProps) => (
<Modal show={shown} onHide={hideModal}>
<ModalBody>{body}</ModalBody>
<ModalFooter>
Expand All @@ -31,12 +38,4 @@ const ConfirmModal = ({
</Modal>
);

ConfirmModal.propTypes = {
actionLabel: PropTypes.node.isRequired,
body: PropTypes.node.isRequired,
shown: PropTypes.bool.isRequired,
hideModal: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
};

export default ConfirmModal;
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import { connect } from "react-redux";
import { hideModal } from "../../actions/modals";
import ConfirmModal from "./ConfirmModal";
import { Dispatch, State } from "../../interfaces";

const modalName = "confirm";

const mapStateToProps = (state) => ({
const mapStateToProps = (state: State) => ({
actionLabel: state.modals[modalName].actionLabel,
body: state.modals[modalName].body,
action: state.modals[modalName].action,
shown: !!state.modals[modalName].shown,
});

const mapDispatchToProps = (dispatch) => ({
const mapDispatchToProps = (dispatch: Dispatch) => ({
dispatch,
hideModal: () => dispatch(hideModal("confirm")),
});

const mergeProps = (stateProps, dispatchProps) => ({
const mergeProps = (
stateProps: ReturnType<typeof mapStateToProps>,
dispatchProps: ReturnType<typeof mapDispatchToProps>
) => ({
...stateProps,
...dispatchProps,
handleSubmit: () => {
Expand Down
15 changes: 13 additions & 2 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
User as UserModel,
Vote as VoteModel,
} from "./db";
import { ThunkDispatch } from "@reduxjs/toolkit";
import { ReactNode } from "react";

export interface ExtWebSocket extends WebSocket {
teamId?: number;
Expand Down Expand Up @@ -239,7 +241,7 @@ export type Action =
}
| {
type: "POST_USER";
user: User;
user: Partial<User>;
}
| {
type: "USER_POSTED";
Expand Down Expand Up @@ -453,7 +455,14 @@ interface BaseState {
flashes: Flash[];
host: string;
notifications: Notification[];
modals: { [index: string]: { shown: boolean } };
modals: {
[index: string]: {
action: () => void;
actionLabel: string;
body: ReactNode;
shown: boolean;
};
};
listUi: {
editNameFormValue?: string;
flipMove: boolean;
Expand Down Expand Up @@ -555,3 +564,5 @@ export type Reducer<T extends keyof State> = (
state: State[T],
action: Action
) => State[T];

export type Dispatch = ThunkDispatch<State, unknown, Action>;

0 comments on commit 21a8b30

Please sign in to comment.