From 88b30d8168a077fda4adaa6ccf397de562308d1e Mon Sep 17 00:00:00 2001 From: casperiv0 <53900565+casperiv0@users.noreply.github.com> Date: Mon, 23 Oct 2023 19:06:42 +0200 Subject: [PATCH] feat: call 911 disposition code --- .../migration.sql | 8 +++++ apps/api/prisma/schema.prisma | 17 +++++++---- .../admin/values/import-values-controller.ts | 1 + apps/client/locales/en/calls.json | 3 +- apps/client/locales/en/values.json | 4 ++- .../admin/values/ManageValueModal.tsx | 12 ++++++++ .../modals/manage-911-call-form.tsx | 29 ++++++++++++++++++- .../form/inputs/value-select-field.tsx | 2 ++ apps/client/src/lib/admin/values/values.tsx | 6 +++- packages/schemas/src/admin/values/import.ts | 1 + 10 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 apps/api/prisma/migrations/20231023170026_disposition_code_call/migration.sql diff --git a/apps/api/prisma/migrations/20231023170026_disposition_code_call/migration.sql b/apps/api/prisma/migrations/20231023170026_disposition_code_call/migration.sql new file mode 100644 index 000000000..6a2de6ae7 --- /dev/null +++ b/apps/api/prisma/migrations/20231023170026_disposition_code_call/migration.sql @@ -0,0 +1,8 @@ +-- AlterTable +ALTER TABLE "Call911" ADD COLUMN "dispositionCodeId" TEXT; + +-- AlterTable +ALTER TABLE "CallTypeValue" ADD COLUMN "isDisposition" BOOLEAN NOT NULL DEFAULT false; + +-- AddForeignKey +ALTER TABLE "Call911" ADD CONSTRAINT "Call911_dispositionCodeId_fkey" FOREIGN KEY ("dispositionCodeId") REFERENCES "CallTypeValue"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/apps/api/prisma/schema.prisma b/apps/api/prisma/schema.prisma index 1bf6cee7c..881bc3936 100644 --- a/apps/api/prisma/schema.prisma +++ b/apps/api/prisma/schema.prisma @@ -824,11 +824,14 @@ model WeaponValue { } model CallTypeValue { - id String @id @default(cuid()) - priority String? - valueId String - value Value @relation("callTypeValueToValue", fields: [valueId], references: [id], onDelete: Cascade) - Call911 Call911[] + id String @id @default(cuid()) + priority String? + valueId String + isDisposition Boolean @default(false) + value Value @relation("callTypeValueToValue", fields: [valueId], references: [id], onDelete: Cascade) + + dispositionCodeToCall Call911[] @relation("dispositionCodeToCall") + callTypeToCall Call911[] @relation("callTypeToCall") } // notifications @@ -1310,12 +1313,14 @@ model Call911 { ended Boolean? @default(false) situationCode StatusValue? @relation(fields: [situationCodeId], references: [id]) situationCodeId String? + dispositionCode CallTypeValue? @relation("dispositionCodeToCall", fields: [dispositionCodeId], references: [id]) + dispositionCodeId String? viaDispatch Boolean? @default(false) divisions DivisionValue[] departments DepartmentValue[] events Call911Event[] incidents LeoIncident[] - type CallTypeValue? @relation(fields: [typeId], references: [id]) + type CallTypeValue? @relation("callTypeToCall", fields: [typeId], references: [id]) typeId String? Officer Officer[] @relation("activeCall") EmsFdDeputy EmsFdDeputy[] @relation("emsFdActiveCall") diff --git a/apps/api/src/controllers/admin/values/import-values-controller.ts b/apps/api/src/controllers/admin/values/import-values-controller.ts index 35606388a..566ab5a37 100644 --- a/apps/api/src/controllers/admin/values/import-values-controller.ts +++ b/apps/api/src/controllers/admin/values/import-values-controller.ts @@ -483,6 +483,7 @@ export const typeHandlers = { where: { id: String(id) }, ...makePrismaData(ValueType.CALL_TYPE, { priority: item.priority, + isDisposition: item.isDisposition ?? false, value: item.value, isDisabled: item.isDisabled, }), diff --git a/apps/client/locales/en/calls.json b/apps/client/locales/en/calls.json index ec8524d4b..087505c3d 100644 --- a/apps/client/locales/en/calls.json +++ b/apps/client/locales/en/calls.json @@ -69,7 +69,8 @@ "id": "id", "towLogsDescription": "Here you can view all archived tow logs. This allows you to view all tow logs that have been ended/archived.", "addAllUnits": "Add all active units", - "openCallModalAfterCreation": "Open Manage 911 call modal after call creation?" + "openCallModalAfterCreation": "Open Manage 911 call modal after call creation?", + "dispositionCode": "Disposition Code" }, "Events": { "unitAssignedToCall": "{unit} has been assigned to this call.", diff --git a/apps/client/locales/en/values.json b/apps/client/locales/en/values.json index 3fb97e347..eddca38d0 100644 --- a/apps/client/locales/en/values.json +++ b/apps/client/locales/en/values.json @@ -74,7 +74,9 @@ "FELONY": "Felony", "warningApplicable": "Warning Applicable", "warningNotApplicable": "Warning Not Applicable", - "isPrimary": "Is Primary" + "isPrimary": "Is Primary", + "isDispositionDescription": "A disposition code can be used when a call is closed. This will be used to determine the outcome of the call.", + "isDisposition": "Is Disposition" }, "PENAL_CODE_GROUP": { "MANAGE": "Manage Penal Code Groups", diff --git a/apps/client/src/components/admin/values/ManageValueModal.tsx b/apps/client/src/components/admin/values/ManageValueModal.tsx index 7d1964924..706cdc7cc 100644 --- a/apps/client/src/components/admin/values/ManageValueModal.tsx +++ b/apps/client/src/components/admin/values/ManageValueModal.tsx @@ -133,6 +133,7 @@ function createInitialValues(options: CreateInitialValuesOptions) { licenseType: value && isBaseValue(value) ? value.licenseType : null, isDefault: value && isBaseValue(value) ? value.isDefault : undefined, priority: value && isCallTypeValue(value) ? value.priority ?? undefined : undefined, + isDisposition: value && isCallTypeValue(value) ? value.isDisposition ?? undefined : undefined, officerRankImageId: "", officerRankDepartments: @@ -376,6 +377,17 @@ export function ManageValueModal({ onCreate, onUpdate, type, value }: Props) { /> ) : null} + {type === ValueType.CALL_TYPE ? ( + setFieldValue("isDisposition", value)} + isSelected={values.isDisposition} + description={tValues("isDispositionDescription")} + > + {tValues("isDisposition")} + + ) : null} + {type === ValueType.OFFICER_RANK ? ( <> diff --git a/apps/client/src/components/dispatch/active-calls/modals/manage-911-call-form.tsx b/apps/client/src/components/dispatch/active-calls/modals/manage-911-call-form.tsx index c572188fe..4e3e8c259 100644 --- a/apps/client/src/components/dispatch/active-calls/modals/manage-911-call-form.tsx +++ b/apps/client/src/components/dispatch/active-calls/modals/manage-911-call-form.tsx @@ -111,6 +111,7 @@ export function Manage911CallForm({ call, isDisabled, setShowAlert, handleClose departments: call?.departments?.map((dep) => ({ value: dep.id, label: dep.value.value })) ?? [], divisions: call?.divisions?.map((dep) => ({ value: dep.id, label: dep.value.value })) ?? [], situationCode: call?.situationCodeId ?? null, + dispositionCodeId: call?.dispositionCodeId ?? null, type: call?.typeId ?? null, notifyAssignedUnits: true, openCallModalAfterCreation: true, @@ -208,7 +209,7 @@ export function Manage911CallForm({ call, isDisabled, setShowAlert, handleClose ) : null} - + value.type === StatusValueType.SITUATION_CODE} + className="w-full" + /> + + value.isDisposition} + className="w-full" /> !value.isDisposition} + className="w-full" /> + value.type === StatusValueType.SITUATION_CODE} + /> + (props: Props) { }, [getDefaultSearchValue]); function handleSuggestionPress(node?: Node | null) { + if (node) setSearch(node?.textValue); + const fieldData = { [props.fieldName]: node?.key ?? null }; setValues({ ...values, ...fieldData }); props.onSelectionChange?.((node?.value as T | null) ?? null); diff --git a/apps/client/src/lib/admin/values/values.tsx b/apps/client/src/lib/admin/values/values.tsx index 16a74ddf5..da8637f9f 100644 --- a/apps/client/src/lib/admin/values/values.tsx +++ b/apps/client/src/lib/admin/values/values.tsx @@ -189,6 +189,7 @@ export function useTableDataOfType(type: ValueType) { return { priority: v.priority ?? common("none"), + isDisposition: common(yesOrNoText(v.isDisposition)), }; } case ValueType.DRIVERSLICENSE_CATEGORY: { @@ -275,7 +276,10 @@ export function useTableHeadersOfType(type: ValueType): ColumnDef<{ id: string } ]; } case ValueType.CALL_TYPE: { - return [{ header: t("priority"), accessorKey: "priority" }]; + return [ + { header: t("priority"), accessorKey: "priority" }, + { header: t("isDisposition"), accessorKey: "isDisposition" }, + ]; } case ValueType.DRIVERSLICENSE_CATEGORY: { return [ diff --git a/packages/schemas/src/admin/values/import.ts b/packages/schemas/src/admin/values/import.ts index 7eed18f13..b45c13de6 100644 --- a/packages/schemas/src/admin/values/import.ts +++ b/packages/schemas/src/admin/values/import.ts @@ -144,6 +144,7 @@ export const QUALIFICATION_ARR = z.array(QUALIFICATION_SCHEMA).min(1); */ export const CALL_TYPE_SCHEMA = BASE_VALUE_SCHEMA.extend({ priority: z.string().nullish(), + isDisposition: z.boolean().nullish(), }); export const CALL_TYPE_ARR = z.array(CALL_TYPE_SCHEMA).min(1);