From 0cd80b6ef65ed4d60b33cb653204019a57472b43 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 Jan 2021 22:09:16 -0800 Subject: [PATCH] WIP: bulk submit cont [gh-1132] --- api/controller/contributions.ts | 1 + api/routes/index.ts | 47 ++++++++++++++ .../ContributionsTable/ContributionsTable.js | 63 +++++++++++++++---- .../Utils/ContributionsFields.js | 3 - app/src/api/api.js | 6 ++ .../ContributorMatchPicker/index.js | 1 + .../Forms/ContributionReady/index.js | 1 + app/src/components/Table/index.js | 1 + app/src/state/ducks/contributions.js | 2 + 9 files changed, 111 insertions(+), 14 deletions(-) diff --git a/api/controller/contributions.ts b/api/controller/contributions.ts index 1d4aeb75f..bb200e4e5 100644 --- a/api/controller/contributions.ts +++ b/api/controller/contributions.ts @@ -175,6 +175,7 @@ export class UpdateContributionDto implements IUpdateContributionAttrs { export async function updateContribution(request: IRequest, response: Response, next: Function) { try { + console.log(response); checkCurrentUser(request); const updateContributionDto = Object.assign(new UpdateContributionDto(), { ...request.body, diff --git a/api/routes/index.ts b/api/routes/index.ts index 2567fb93c..07f627c16 100644 --- a/api/routes/index.ts +++ b/api/routes/index.ts @@ -519,6 +519,53 @@ export const AppRoutes = [ action: contributions.updateContribution }, + /** + * @swagger + * /bulk-update-contributions: + * put: + * summary: Bulk update contributions + * tags: + * - Contributions + * security: + * - cookieAuth: [] + * produces: + * - application/json + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: array + * items: + * type: object + * properties: + * currentUserId: + * type: integer + * id: + * type: integer + * status: + * type: string + * responses: + * 200: + * description: Success response (X of X updated, X invalid) + * content: + * application/json: + * schema: + * type: object + * properties: + * message: + * type: string + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + * + */ + // TODO: verify swagger is correct + { + path: '/contributions/:id', + method: 'put', + action: contributions.updateContribution + }, + /** * @swagger * /contributions/{id}: diff --git a/app/src/Pages/Portal/Contributions/ContributionsTable/ContributionsTable.js b/app/src/Pages/Portal/Contributions/ContributionsTable/ContributionsTable.js index 7de7912da..3aab5c043 100644 --- a/app/src/Pages/Portal/Contributions/ContributionsTable/ContributionsTable.js +++ b/app/src/Pages/Portal/Contributions/ContributionsTable/ContributionsTable.js @@ -41,7 +41,7 @@ const buttonWrapper = css` const actionInfo = (name, buttonType, onClick, isFreeAction = undefined) => isFreeAction ? { icon: 'none', name, buttonType, onClick, isFreeAction } - : { icon: 'none', name, buttonType, onClick }; + : { icon: 'none', name, buttonType, onClick, position: 'row' }; const columns = isGovAdmin => { const cols = [ @@ -118,11 +118,27 @@ const columns = isGovAdmin => { class ContributionsTable extends React.Component { constructor(props) { super(props); + this.state = { + itemsToSubmit: null, + }; props.getContributions({ governmentId: props.govId, currentUserId: props.userId, campaignId: props.campaignId, }); + this.updateItemsToSubmit = this.updateItemsToSubmit.bind(this); + } + + updateItemsToSubmit(items) { + if (items.length > 0) { + this.setState({ + itemsToSubmit: items, + }); + } else { + this.setState({ + itemsToSubmit: null, + }); + } } render() { @@ -144,9 +160,14 @@ class ContributionsTable extends React.Component { const isLoading = isListLoading && !Array.isArray(contributionList); const actions = [ - actionInfo('View', 'submit', (event, rowData) => { - history.push(`/contributions/${rowData.id}`); - }), + actionInfo( + 'View', + 'submit', + (event, rowData) => { + history.push(`/contributions/${rowData.id}`); + }, + false + ), ]; const components = { @@ -253,6 +274,14 @@ class ContributionsTable extends React.Component { options={{ pageSize: filterOptions.perPage || 50, showTitle: false, + actionsColumnIndex: -1, + selection: true, + selectionProps: rowData => { + return { + disabled: rowData.status === 'Submitted', + color: 'primary', + }; + }, }} actions={actions} components={components} @@ -275,18 +304,30 @@ class ContributionsTable extends React.Component { pageNumber={filterOptions.page || 0} totalRows={total} onChangePage={handleOnChangePage} - // eslint-disable-next-line no-use-before-define onChangeRowsPerPage={handleOnRowsPerPageChange} toolbarAction={ !isGovAdmin ? ( - + <> + + {this.state.itemsToSubmit && ( + + )} + ) : null } + onSelectionChange={items => this.updateItemsToSubmit(items)} /> ); diff --git a/app/src/Pages/Portal/Contributions/Utils/ContributionsFields.js b/app/src/Pages/Portal/Contributions/Utils/ContributionsFields.js index 99bf31db2..09e76db6d 100644 --- a/app/src/Pages/Portal/Contributions/Utils/ContributionsFields.js +++ b/app/src/Pages/Portal/Contributions/Utils/ContributionsFields.js @@ -530,9 +530,6 @@ export const validate = values => { checkNumber, occupation, occupationLetterDate, - employerName, - employerCity, - employerState, subTypeOfContribution, inKindType, lastName, diff --git a/app/src/api/api.js b/app/src/api/api.js index 5415c5ad4..dd5c32e18 100644 --- a/app/src/api/api.js +++ b/app/src/api/api.js @@ -603,6 +603,12 @@ export function updateContribution(contributionAttrs) { ); } +// path: '/bulk-update-contributions' +// method: 'put', +export function bulkUpdateContribution(contributionAttrs) { + return put(`${baseUrl()}/bulk-update-contributions`, contributionAttrs); +} + // path: '/contributions/new', // method: 'post', export function createContribution(contributionAttrs) { diff --git a/app/src/components/ContributorMatchPicker/index.js b/app/src/components/ContributorMatchPicker/index.js index 993f715e0..03099d91d 100644 --- a/app/src/components/ContributorMatchPicker/index.js +++ b/app/src/components/ContributorMatchPicker/index.js @@ -139,6 +139,7 @@ class contributorMatchPicker extends React.Component { } handleSubmit() { + // TODO: does this need to update this? this.props.updateMatchForContribution({ contributionId: this.props.contributionId, matchId: this.state.pages[this.state.currentPage].id, diff --git a/app/src/components/Forms/ContributionReady/index.js b/app/src/components/Forms/ContributionReady/index.js index 5ddf0c60f..1fd9234a3 100644 --- a/app/src/components/Forms/ContributionReady/index.js +++ b/app/src/components/Forms/ContributionReady/index.js @@ -148,6 +148,7 @@ class ContributionReadyForm extends React.Component { ) : ( <> +

nice

diff --git a/app/src/state/ducks/contributions.js b/app/src/state/ducks/contributions.js index 872bed9ba..6a48a8f9f 100644 --- a/app/src/state/ducks/contributions.js +++ b/app/src/state/ducks/contributions.js @@ -268,10 +268,12 @@ export function createContribution(contributionAttrs) { } export function updateContribution(contributionAttrs) { + // TODO: duplicate for bulk submission return async (dispatch, getState, { api, schema }) => { dispatch(actionCreators.updateContribution.request()); try { const response = await api.updateContribution(contributionAttrs); + console.log({ contributionAttrs, response }); if (response.status === 204) { let status = ''; if (contributionAttrs.status) {