diff --git a/backend/src/document_data/document_data.service.ts b/backend/src/document_data/document_data.service.ts index 7feeafd7..66de4eff 100644 --- a/backend/src/document_data/document_data.service.ts +++ b/backend/src/document_data/document_data.service.ts @@ -212,13 +212,21 @@ export class DocumentDataService { return null; } - // Used by the search page. + // Used by the search page. *can probably be removed* async findAll(): Promise { return await this.documentDataRepository.find({ relations: ['document_type'], }); } + // Used by the search page. Filters document data for inactive doc types + async findAllWithActiveDT(): Promise { + const documentData = await this.documentDataRepository.find({ + relations: ['document_type'], + }); + return documentData.filter((data) => data.document_type.active === true); + } + async findByDocumentDataId(documentDataId: number): Promise<{ documentData: DocumentData; provisionIds: number[]; diff --git a/backend/src/document_type/document_type.controller.ts b/backend/src/document_type/document_type.controller.ts index 52a14cc2..8bf6cef2 100644 --- a/backend/src/document_type/document_type.controller.ts +++ b/backend/src/document_type/document_type.controller.ts @@ -10,11 +10,6 @@ import { JwtAuthGuard } from 'src/auth/jwtauth.guard'; export class DocumentTypeController { constructor(private documentTypeService: DocumentTypeService) {} - @Get(':id') - findById(@Param('id') id: number) { - return this.documentTypeService.findById(id); - } - @Post('update') update( @Body() data: { id: number; name: string; prefix: string; created_by: string; created_date: string }, @@ -35,6 +30,11 @@ export class DocumentTypeController { return this.documentTypeService.findAll(); } + @Get('active-doc-types') + findActiveDocTypes() { + return this.documentTypeService.findActiveDocTypes(); + } + @Get('get-group-max/:document_type_id') getGroupMaxByDocTypeId(@Param('document_type_id') document_type_id: number) { return this.documentTypeService.getGroupMaxByDocTypeId(document_type_id); @@ -61,4 +61,14 @@ export class DocumentTypeController { removeProvisionGroup(@Body() data: { provision_group_id: number }) { return this.documentTypeService.removeProvisionGroup(data.provision_group_id); } + + @Get('activate/:document_type_id') + activateDocType(@Param('document_type_id') id: number) { + return this.documentTypeService.activateDocType(id); + } + + @Get('deactivate/:document_type_id') + deactivateDocType(@Param('document_type_id') id: number) { + return this.documentTypeService.deactivateDocType(id); + } } diff --git a/backend/src/document_type/document_type.service.ts b/backend/src/document_type/document_type.service.ts index a3620066..41058869 100644 --- a/backend/src/document_type/document_type.service.ts +++ b/backend/src/document_type/document_type.service.ts @@ -156,4 +156,17 @@ export class DocumentTypeService { return accumulator; }, []); } + + findActiveDocTypes() { + return this.documentTypeRepository.find({ where: { active: true } }); + } + + // Active variable determines whether or not doc type is displayed in drop down lists + activateDocType(id: number) { + return this.documentTypeRepository.update(id, { active: true }); + } + + deactivateDocType(id: number) { + return this.documentTypeRepository.update(id, { active: false }); + } } diff --git a/backend/src/document_type/entities/document_type.entity.ts b/backend/src/document_type/entities/document_type.entity.ts index a77ff3ed..8fc1d3a3 100644 --- a/backend/src/document_type/entities/document_type.entity.ts +++ b/backend/src/document_type/entities/document_type.entity.ts @@ -12,9 +12,12 @@ export class DocumentType { @Column() name: string; - @Column() + @Column({ nullable: true }) prefix: string; + @Column({ nullable: true }) + active: boolean; + @Column({ nullable: true }) created_by: string; diff --git a/backend/src/report/report.service.ts b/backend/src/report/report.service.ts index 062ec0c4..22d0ff95 100644 --- a/backend/src/report/report.service.ts +++ b/backend/src/report/report.service.ts @@ -996,7 +996,7 @@ export class ReportService { } async getDocumentData() { - const documentData = await this.documentDataService.findAll(); + const documentData = await this.documentDataService.findAllWithActiveDT(); const templateIds = documentData.map((d) => d.template_id); const allTemplates = await this.documentTemplateService.getTemplatesInfoByIds(templateIds); diff --git a/frontend/src/app/common/manage-doc-types.ts b/frontend/src/app/common/manage-doc-types.ts index 60c9b6b8..7eda746f 100644 --- a/frontend/src/app/common/manage-doc-types.ts +++ b/frontend/src/app/common/manage-doc-types.ts @@ -59,6 +59,26 @@ export const removeDocType = (id: number) => { return api.get(getParameters); }; +export const getActiveDocTypes = () => { + const url = `${config.API_BASE_URL}/document-type/active-doc-types`; + const getParameters = api.generateApiParameters(url); + return api.get(getParameters); +}; + +// used to activate doc type so that it displays in dropdowns +export const activateDocType = (document_type_id: number) => { + const url = `${config.API_BASE_URL}/document-type/activate/${document_type_id}`; + const getParameters = api.generateApiParameters(url); + return api.get(getParameters); +}; + +// used to deactivate doc type so that it does not display in dropdowns +export const deactivateDocType = (document_type_id: number) => { + const url = `${config.API_BASE_URL}/document-type/deactivate/${document_type_id}`; + const getParameters = api.generateApiParameters(url); + return api.get(getParameters); +}; + export const getManageDocumentTypeProvisions = (document_type_id: number) => { const url = `${config.API_BASE_URL}/provision/get-manage-doc-type-provisions/${document_type_id}`; const getParameters = api.generateApiParameters(url); diff --git a/frontend/src/app/components/table/manage-doc-types/ManageDocTypesTable.tsx b/frontend/src/app/components/table/manage-doc-types/ManageDocTypesTable.tsx index 0d6f324b..4b7e3e0c 100644 --- a/frontend/src/app/components/table/manage-doc-types/ManageDocTypesTable.tsx +++ b/frontend/src/app/components/table/manage-doc-types/ManageDocTypesTable.tsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { DataTable } from '../common/DataTable'; import { ColumnDef, createColumnHelper } from '@tanstack/react-table'; import { DocType } from '../../../types/types'; +import { activateDocType, deactivateDocType } from '../../../common/manage-doc-types'; interface ManageDocTypesTableProps { documentTypes: DocType[]; @@ -10,6 +11,13 @@ interface ManageDocTypesTableProps { } const ManageDocTypesTable: React.FC = ({ documentTypes, handleEdit, handleRemove }) => { + // display a local copy of document types to reduce re-renders + const [dtDisplayed, setDtDisplayed] = useState([]); + + useEffect(() => { + setDtDisplayed(documentTypes); + }, [documentTypes]); + const editDocTypeButtonHandler = (id: number) => { handleEdit(id); }; @@ -18,6 +26,24 @@ const ManageDocTypesTable: React.FC = ({ documentTypes handleRemove(id); }; + const activateHandler = async (event: React.ChangeEvent, id: number) => { + if (event.target.checked) { + await activate(id); + } else { + await deactivate(id); + } + }; + + const activate = async (id: number) => { + await activateDocType(id); + setDtDisplayed((prevDtDisplayed) => prevDtDisplayed.map((dt) => (dt.id === id ? { ...dt, active: true } : dt))); + }; + + const deactivate = async (id: number) => { + await deactivateDocType(id); + setDtDisplayed((prevDtDisplayed) => prevDtDisplayed.map((dt) => (dt.id === id ? { ...dt, active: false } : dt))); + }; + const columnHelper = createColumnHelper(); const columns: ColumnDef[] = [ @@ -35,14 +61,28 @@ const ManageDocTypesTable: React.FC = ({ documentTypes ), header: () => 'Create Date', enableSorting: true, - meta: { customCss: { width: '30%' } }, + meta: { customCss: { width: '25%' } }, }), columnHelper.accessor('created_by', { id: 'created_by', cell: (info) => , header: () => 'Created By', enableSorting: true, - meta: { customCss: { width: '30%' } }, + meta: { customCss: { width: '25%' } }, + }), + columnHelper.accessor('active', { + id: 'active', + cell: (info) => ( + activateHandler(e, info.row.original.id)} + style={{ width: '100%' }} + /> + ), + header: () => 'Active', + enableSorting: true, + meta: { customCss: { width: '10%' } }, }), columnHelper.display({ id: 'edit', @@ -91,7 +131,7 @@ const ManageDocTypesTable: React.FC = ({ documentTypes return ( diff --git a/frontend/src/app/content/pages/LandingPage.tsx b/frontend/src/app/content/pages/LandingPage.tsx index 90845f99..6cf0a3b7 100644 --- a/frontend/src/app/content/pages/LandingPage.tsx +++ b/frontend/src/app/content/pages/LandingPage.tsx @@ -24,7 +24,7 @@ import Provisions from '../display/Provisions'; import { ProvisionJson, SaveProvisionData } from '../../components/table/reports/SelectedProvisionsTable'; import VariablesTable, { SaveVariableData, VariableJson } from '../../components/table/reports/VariablesTable'; import { Alert, Button, Row } from 'react-bootstrap'; -import { getDocumentTypes } from '../../common/manage-doc-types'; +import { getActiveDocTypes } from '../../common/manage-doc-types'; import { getVariablesByDocType } from '../../common/manage-provisions'; import { useDispatch, useSelector } from 'react-redux'; import { setProvisionDataObjects, setSelectedProvisionIds } from '../../store/reducers/provisionSlice'; @@ -99,7 +99,7 @@ const LandingPage: FC = () => { useEffect(() => { const fetchBasicData = async () => { try { - const dts: DocType[] = await getDocumentTypes(); + const dts: DocType[] = await getActiveDocTypes(); dts.sort((a, b) => a.name.localeCompare(b.name)); setDocumentTypes(dts); } catch (error) { diff --git a/frontend/src/app/content/pages/ManageTemplatesPage.tsx b/frontend/src/app/content/pages/ManageTemplatesPage.tsx index 4a995b8f..8df28424 100644 --- a/frontend/src/app/content/pages/ManageTemplatesPage.tsx +++ b/frontend/src/app/content/pages/ManageTemplatesPage.tsx @@ -4,7 +4,7 @@ import { Button } from 'react-bootstrap'; import { DocType } from '../../types/types'; import UploadTemplateModal from '../../components/modal/manage-templates/UploadTemplateModal'; import RemoveTemplateModal from '../../components/modal/manage-templates/RemoveTemplateModal'; -import { getDocumentTypes } from '../../common/report'; +import { getActiveDocTypes } from '../../common/manage-doc-types'; const ManageTemplatesPage: FC = () => { const [showUploadModal, setShowUploadModal] = useState(false); @@ -16,7 +16,7 @@ const ManageTemplatesPage: FC = () => { useEffect(() => { const getData = async () => { - const docTypeData = await getDocumentTypes(); + const docTypeData = await getActiveDocTypes(); setAllDocTypes(docTypeData); if (docTypeData.length > 0) { setSelectedDocType(docTypeData[0]); diff --git a/frontend/src/app/content/pages/SearchPage.tsx b/frontend/src/app/content/pages/SearchPage.tsx index daa78eda..680a9741 100644 --- a/frontend/src/app/content/pages/SearchPage.tsx +++ b/frontend/src/app/content/pages/SearchPage.tsx @@ -10,7 +10,7 @@ import SearchDataTable from '../../components/table/search/SearchDataTable'; import { DocType } from '../../types/types'; import { setSearchState } from '../../store/reducers/searchSlice'; import { useDispatch } from 'react-redux'; -import { getDocumentTypes } from '../../common/manage-doc-types'; +import { getActiveDocTypes } from '../../common/manage-doc-types'; import { Row, Col } from 'react-bootstrap'; const SearchPage: FC = () => { @@ -26,7 +26,7 @@ const SearchPage: FC = () => { const fetchData = async () => { try { setLoading(true); - const data = await getDocumentTypes(); + const data = await getActiveDocTypes(); setDocTypes(data); } catch (error) { console.log('Error fetching doc types'); diff --git a/frontend/src/app/store/reducers/docTypeSlice.tsx b/frontend/src/app/store/reducers/docTypeSlice.tsx index a18c04e3..6d989bb7 100644 --- a/frontend/src/app/store/reducers/docTypeSlice.tsx +++ b/frontend/src/app/store/reducers/docTypeSlice.tsx @@ -13,6 +13,7 @@ const initialState: DocumentTypeObjectState = { id: -1, name: '', prefix: '', + active: false, created_by: '', created_date: '', create_userid: '', @@ -24,6 +25,7 @@ const initialState: DocumentTypeObjectState = { id: -1, name: '', prefix: '', + active: false, created_by: '', created_date: '', create_userid: '', diff --git a/frontend/src/app/types/types.ts b/frontend/src/app/types/types.ts index ffdfbe7a..b4762f97 100644 --- a/frontend/src/app/types/types.ts +++ b/frontend/src/app/types/types.ts @@ -262,6 +262,7 @@ export type DocType = { id: number; name: string; prefix: string; + active: boolean; created_by: string; created_date: string; create_userid: string; diff --git a/migrations/sql/V1.0.19__doctype_active.sql b/migrations/sql/V1.0.19__doctype_active.sql new file mode 100644 index 00000000..a28f4355 --- /dev/null +++ b/migrations/sql/V1.0.19__doctype_active.sql @@ -0,0 +1,2 @@ +ALTER TABLE document_type ADD COLUMN active BOOLEAN; +UPDATE document_type SET active=true; \ No newline at end of file