Skip to content

Commit

Permalink
feat: Added delete record functionality to review phase (#455)
Browse files Browse the repository at this point in the history
  • Loading branch information
chavda-bhavik authored Dec 28, 2023
2 parents e75bb22 + e7f1f59 commit fe2a878
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 5 deletions.
19 changes: 17 additions & 2 deletions apps/api/src/app/review/review.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiOperation, ApiTags, ApiSecurity, ApiQuery, ApiOkResponse } from '@nestjs/swagger';
import { BadRequestException, Body, Controller, Get, Param, Post, Put, Query, UseGuards } from '@nestjs/common';
import { BadRequestException, Body, Controller, Delete, Get, Param, Post, Put, Query, UseGuards } from '@nestjs/common';

import { APIMessages } from '@shared/constants';
import { RecordEntity, UploadEntity } from '@impler/dal';
Expand All @@ -13,6 +13,7 @@ import {
DoReReview,
UpdateRecord,
StartProcess,
DeleteRecord,
GetUploadData,
UpdateImportCount,
UpdateImportCountCommand,
Expand All @@ -31,6 +32,7 @@ export class ReviewController {
private doReview: DoReview,
private getUpload: GetUpload,
private doReReview: DoReReview,
private deleteRecord: DeleteRecord,
private startProcess: StartProcess,
private updateRecord: UpdateRecord,
private updateImportCount: UpdateImportCount,
Expand Down Expand Up @@ -128,9 +130,22 @@ export class ReviewController {
@Put(':uploadId/record')
@UseGuards(JwtAuthGuard)
@ApiOperation({
summary: 'Update review data for ongoing import',
summary: 'Update review record for ongoing import',
})
async updateReviewData(@Param('uploadId', ValidateMongoId) _uploadId: string, @Body() body: RecordEntity) {
await this.updateRecord.execute(_uploadId, body);
}

@Delete(':uploadId/record/:index')
@UseGuards(JwtAuthGuard)
@ApiOperation({
summary: 'Delete review record for ongoing import',
})
async deleteReviewRecord(
@Param('index') index: number,
@Query('isValid') isValid: boolean,
@Param('uploadId', ValidateMongoId) _uploadId: string
) {
await this.deleteRecord.execute(_uploadId, index, isValid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Injectable } from '@nestjs/common';
import { DalService, UploadRepository } from '@impler/dal';

@Injectable()
export class DeleteRecord {
constructor(private dalService: DalService, private uploadRepository: UploadRepository) {}

async execute(_uploadId: string, index: number, isValid?: boolean) {
await this.dalService.deleteRecord(_uploadId, index);
if (typeof isValid !== 'undefined') {
await this.uploadRepository.update(
{
_id: _uploadId,
},
{
$inc: {
totalRecords: -1,
validRecords: isValid ? -1 : 0,
invalidRecords: isValid ? 0 : -1,
},
}
);
}
}
}
14 changes: 13 additions & 1 deletion apps/api/src/app/review/usecases/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UpdateRecord } from './update-cell';
import { DoReview } from './do-review/do-review.usecase';
import { DeleteRecord } from './delete-record/delete-record.usecase';
import { DoReReview } from './do-review/re-review-data.usecase';
import { StartProcess } from './start-process/start-process.usecase';
import { ConfirmReview } from './confirm-review/confirm-review.usecase';
Expand All @@ -13,6 +14,7 @@ export const USE_CASES = [
DoReview,
GetUpload,
DoReReview,
DeleteRecord,
UpdateRecord,
StartProcess,
ConfirmReview,
Expand All @@ -21,5 +23,15 @@ export const USE_CASES = [
//
];

export { DoReview, DoReReview, GetUpload, UpdateRecord, StartProcess, ConfirmReview, GetUploadData, UpdateImportCount };
export {
DoReview,
GetUpload,
DoReReview,
DeleteRecord,
UpdateRecord,
StartProcess,
ConfirmReview,
GetUploadData,
UpdateImportCount,
};
export { UpdateImportCountCommand };

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 30 additions & 1 deletion apps/widget/src/components/Common/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ interface TableProps {
afterRender?: () => void;
data: Record<string, any>[];
columnDefs: HotItemSchema[];
onRecordDelete?: (index: number, isValid: boolean) => void;
onValueChange?: (row: number, prop: string, oldVal: any, newVal: any) => void;
}

Expand Down Expand Up @@ -101,9 +102,30 @@ Handsontable.renderers.registerRenderer(
}
);

// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars
Handsontable.renderers.registerRenderer('del', function renderer(instance, TD, row, col, prop, value, cellProperties) {
TD.classList.add('del-cell');
const soureData = instance.getSourceDataAtRow(row) as IRecord;

TD.dataset.index = String(soureData.index);
TD.dataset.isValid = String(soureData.isValid);
TD.innerHTML = `<button class="del-btn"><svg xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 24 24" width="22" fill="currentColor"><path d="M7.314 5.9l3.535-3.536A1 1 0 1 0 9.435.95L5.899 4.485 2.364.95A1 1 0 1 0 .95 2.364l3.535 3.535L.95 9.435a1 1 0 1 0 1.414 1.414l3.535-3.535 3.536 3.535a1 1 0 1 0 1.414-1.414L7.314 5.899z"></path></svg></button>`;

return TD;
});

export const Table = forwardRef<HotTable, TableProps>(
(
{ afterRender, height = 'auto', width = 'auto', headings, columnDefs, data, onValueChange }: TableProps,
{
afterRender,
height = 'auto',
width = 'auto',
headings,
columnDefs,
data,
onValueChange,
onRecordDelete,
}: TableProps,
gridRef
) => {
return (
Expand All @@ -125,6 +147,13 @@ export const Table = forwardRef<HotTable, TableProps>(
autoInsertRow: false,
direction: 'vertical',
}}
afterOnCellMouseDown={function (e, coords, TD) {
if (TD.classList.contains('del-cell')) {
const dataIndex = TD.dataset.index;
const isValid = TD.dataset.isValid === 'true';
if (onRecordDelete && Number(dataIndex)) onRecordDelete(Number(dataIndex), isValid);
}
}}
stretchH="all"
columns={columnDefs}
colHeaders={headings}
Expand Down
4 changes: 3 additions & 1 deletion apps/widget/src/components/widget/Phases/Phase3/Phase3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function Phase3(props: IPhase3Props) {
columnDefs,
totalPages,
reviewData,
deleteRecord,
onTypeChange,
reReviewData,
updateRecord,
Expand Down Expand Up @@ -76,9 +77,10 @@ export function Phase3(props: IPhase3Props) {
validDataLength={numberFormatter(totalRecords - invalidRecords)}
/>
<Table
ref={tableRef}
onRecordDelete={(index, isValid) => deleteRecord([index, isValid])}
width={tableWrapperDimensions.width}
height={tableWrapperDimensions.height}
ref={tableRef}
onValueChange={(row, prop, oldVal, newVal) => {
const name = String(prop).replace('record.', '');
let formattedNewVal = newVal;
Expand Down
30 changes: 30 additions & 0 deletions apps/widget/src/hooks/Phase3/usePhase3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ export function usePhase3({ onNext }: IUsePhase3Props) {
}
newColumnDefs.push(columnItem);
});
newColumnDefs.push({
type: 'text',
data: 'record._id',
readOnly: true,
editor: false,
renderer: 'del',
className: 'del-cell',
disableVisualSelection: true,
});
newHeadings.push('X');
setHeadings(newHeadings);
setColumnDefs(newColumnDefs);
},
Expand Down Expand Up @@ -173,6 +183,25 @@ export function usePhase3({ onNext }: IUsePhase3Props) {
const { mutate: updateRecord } = useMutation<unknown, IErrorObject, IRecord, [string]>([`update`], (record) =>
api.updateRecord(uploadInfo._id, record)
);
const { mutate: deleteRecord } = useMutation<unknown, IErrorObject, [number, boolean], [string]>(
[`delete`],
([index, isValid]) => api.deleteRecord(uploadInfo._id, index, isValid),
{
onSuccess(data, vars) {
const newReviewData = reviewData.filter((record) => record.index !== vars[0]);
const newUploadInfo = { ...uploadInfo };
newUploadInfo.totalRecords = newUploadInfo.totalRecords - 1;
if (!vars[1]) {
newUploadInfo.invalidRecords = newUploadInfo.invalidRecords - 1;
}
setUploadInfo(newUploadInfo);
setReviewData(newReviewData);
if (newReviewData.length === 0) {
refetchReviewData([defaultPage, type]);
}
},
}
);

const onTypeChange = (newType: ReviewDataTypesEnum) => {
setType(newType);
Expand All @@ -192,6 +221,7 @@ export function usePhase3({ onNext }: IUsePhase3Props) {
updateRecord,
onPageChange,
onTypeChange,
deleteRecord,
setReviewData,
isDoReviewLoading,
isReviewDataLoading,
Expand Down
1 change: 1 addition & 0 deletions apps/widget/src/types/utility.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type HotItemSchema = {
disableVisualSelection?: boolean;
renderer?:
| 'custom'
| 'del'
| ((
instance: Core,
TD: HTMLTableCellElement,
Expand Down
8 changes: 8 additions & 0 deletions libs/dal/src/dal.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ export class DalService {
record
);
}
async deleteRecord(_uploadId: string, index: number) {
const model = this.getRecordCollection(_uploadId);
if (!model) return;

await model.deleteOne({
index,
});
}
getRecordBulkOp(_uploadId: string) {
const model = this.getRecordCollection(_uploadId);
if (!model) return;
Expand Down
6 changes: 6 additions & 0 deletions packages/client/src/api/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,10 @@ export class ApiService {
async updateRecord(uploadId: string, record: IRecord) {
return this.httpClient.put(`/review/${uploadId}/record`, record);
}

async deleteRecord(uploadId: string, index: number, isValid: boolean) {
return this.httpClient.delete(
`/review/${uploadId}/record/${index}?isValid=${isValid}`
);
}
}

0 comments on commit fe2a878

Please sign in to comment.