From 36c1bdb4e8258036b0df0df34d0a1bd28759713c Mon Sep 17 00:00:00 2001 From: Dev-CasperTheGhost <53900565+Dev-CasperTheGhost@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:42:04 +0200 Subject: [PATCH 1/8] feat(select): start using @snailycad/ui select --- .../src/components/account/appearance-tab.tsx | 29 +++++----- .../cad-settings/general-settings-tab.tsx | 6 +-- .../ManageCitizenFlagsModal.tsx | 27 +++++----- .../manage-citizen-address-flags-modal.tsx | 27 +++++----- .../VehicleSearch/ImpoundVehicleModal.tsx | 53 ++++++++----------- .../VehicleSearch/ManageVehicleFlagsModal.tsx | 27 +++++----- .../ManageVehicleLicensesModal.tsx | 53 +++++++------------ .../src/pages/admin/manage/audit-logs.tsx | 30 +++++------ .../src/pages/ems-fd/my-deputy-logs.tsx | 43 +++++++-------- .../client/src/pages/officer/call-history.tsx | 36 ++++++------- .../src/pages/officer/my-officer-logs.tsx | 43 +++++++-------- .../ui/src/components/fields/select-field.tsx | 2 + .../inputs/select/select-actions.tsx | 19 +++++-- .../inputs/select/selected-items.tsx | 6 ++- 14 files changed, 189 insertions(+), 212 deletions(-) diff --git a/apps/client/src/components/account/appearance-tab.tsx b/apps/client/src/components/account/appearance-tab.tsx index 1bd914cdc..4f2ad94be 100644 --- a/apps/client/src/components/account/appearance-tab.tsx +++ b/apps/client/src/components/account/appearance-tab.tsx @@ -1,11 +1,9 @@ import * as React from "react"; -import { FormField } from "components/form/FormField"; import { useAuth } from "context/AuthContext"; import { Form, Formik } from "formik"; import useFetch from "lib/useFetch"; import { useTranslations } from "use-intl"; import { StatusViewMode, TableActionsAlignment } from "@snailycad/types"; -import { Select } from "components/form/Select"; import { Button, Loader, @@ -106,7 +104,7 @@ export function AppearanceTab({ availableSounds }: Props) {

{t("appearanceSettings")}

- {({ handleChange, setFieldValue, values, errors }) => ( + {({ setFieldValue, values, errors }) => (
- - - + setFieldValue("flags", keys)} + />
- -
- - )} +
+ + +
+
); diff --git a/apps/client/src/components/leo/modals/VehicleSearch/ManageVehicleFlagsModal.tsx b/apps/client/src/components/leo/modals/VehicleSearch/ManageVehicleFlagsModal.tsx index c11df762f..75489c2c4 100644 --- a/apps/client/src/components/leo/modals/VehicleSearch/ManageVehicleFlagsModal.tsx +++ b/apps/client/src/components/leo/modals/VehicleSearch/ManageVehicleFlagsModal.tsx @@ -1,7 +1,5 @@ import type { Value } from "@snailycad/types"; -import { Button } from "@snailycad/ui"; -import { FormField } from "components/form/FormField"; -import { Select } from "components/form/Select"; +import { Button, SelectField } from "@snailycad/ui"; import { Modal } from "components/modal/Modal"; import { useModal } from "state/modalState"; import { useValues } from "context/ValuesContext"; @@ -36,7 +34,7 @@ export function ManageVehicleFlagsModal() { const { json } = await execute({ path: `/search/actions/vehicle-flags/${currentResult.id}`, method: "PUT", - data: { flags: values.flags.map((v) => v.value) }, + data: { flags: values.flags.map((v) => v) }, }); if (json.flags) { @@ -64,7 +62,7 @@ export function ManageVehicleFlagsModal() { } const INITIAL_VALUES = { - flags: currentResult.flags?.map(makeValueOption) ?? [], + flags: currentResult.flags?.map((v) => v.id) ?? [], }; return ( @@ -75,17 +73,16 @@ export function ManageVehicleFlagsModal() { className="w-[600px]" > - {({ handleChange, values, errors, isValid }) => ( + {({ setFieldValue, values, errors, isValid }) => (
- - ({ - label: license.value, - value: license.id, - }))} - value={values.registrationStatus} - name="registrationStatus" - onChange={handleChange} - /> - + filterFn={(v) => filterLicenseType(v, ValueLicenseType.REGISTRATION_STATUS)} + /> - - - asyncTable.setFilters((prev) => ({ ...prev, type: event.target.value })) - } - values={ActionTypes.map((type) => ({ - label: type, - value: type, - }))} - /> - + { + asyncTable.setFilters((prev) => ({ ...prev, type: value })); + }} + options={ActionTypes.map((type) => ({ + label: type, + value: type, + }))} + /> {t("Ems.myDeputyLogs")} -
-
- - setSearch(e.target.value)} value={search} /> - {hasManagePermissions ? ( - - ) : null} -
- +
+ setSearch(value)} + value={search} + label={common("search")} + className="w-full" + /> + {hasManagePermissions ? ( + + ) : null}
{search && asyncTable.pagination.totalDataCount !== data.totalCount ? ( diff --git a/apps/client/src/pages/officer/my-officer-logs.tsx b/apps/client/src/pages/officer/my-officer-logs.tsx index ba5203a44..2464ffa67 100644 --- a/apps/client/src/pages/officer/my-officer-logs.tsx +++ b/apps/client/src/pages/officer/my-officer-logs.tsx @@ -4,8 +4,6 @@ import { getSessionUser } from "lib/auth"; import { getTranslations } from "lib/getTranslation"; import type { GetServerSideProps } from "next"; import type { Officer, OfficerLog } from "@snailycad/types"; -import { Select } from "components/form/Select"; -import { FormField } from "components/form/FormField"; import { makeUnitName, requestAll } from "lib/utils"; import { useGenerateCallsign } from "hooks/useGenerateCallsign"; import { Title } from "components/shared/Title"; @@ -14,6 +12,7 @@ import { Permissions } from "@snailycad/permissions"; import type { GetMyOfficersLogsData } from "@snailycad/types/api"; import { useAsyncTable } from "components/shared/Table"; import { useUserOfficers } from "hooks/leo/use-get-user-officers"; +import { SelectField } from "@snailycad/ui"; export type OfficerLogWithOfficer = OfficerLog & { officer: Officer }; @@ -50,29 +49,27 @@ export default function MyOfficersLogs({ logs: data }: Props) { return ( -
+
{t("myOfficerLogs")} -
-
- - - asyncTable.setFilters((prev) => ({ ...prev, departmentId: event.target.value })) - } - values={department.values.map((v) => ({ - label: v.value.value, - value: v.id, - }))} - /> - + ({ + label: value.value.value, + value: value.id, + }))} + onSelectionChange={(value) => { + asyncTable.setFilters((prev) => ({ ...prev, departmentId: value })); + }} + /> {asyncTable.noItemsAvailable ? ( diff --git a/apps/client/src/components/admin/manage/units/tabs/callsigns-tab/callsigns-tab.tsx b/apps/client/src/components/admin/manage/units/tabs/callsigns-tab/callsigns-tab.tsx index c4482f751..d9f660eb5 100644 --- a/apps/client/src/components/admin/manage/units/tabs/callsigns-tab/callsigns-tab.tsx +++ b/apps/client/src/components/admin/manage/units/tabs/callsigns-tab/callsigns-tab.tsx @@ -3,7 +3,7 @@ import type { Unit } from "src/pages/admin/manage/units"; import Link from "next/link"; import { formatOfficerDepartment, makeUnitName } from "lib/utils"; import { useTranslations } from "use-intl"; -import { Button, buttonVariants, TabsContent } from "@snailycad/ui"; +import { Button, buttonVariants, SelectField, TabsContent } from "@snailycad/ui"; import { useGenerateCallsign } from "hooks/useGenerateCallsign"; import { Table, useAsyncTable, useTableState } from "components/shared/Table"; import { useModal } from "state/modalState"; @@ -13,8 +13,6 @@ import { Permissions, usePermission } from "hooks/usePermission"; import type { GetManageUnitsData } from "@snailycad/types/api"; import { SearchArea } from "components/shared/search/search-area"; import dynamic from "next/dynamic"; -import { FormField } from "components/form/FormField"; -import { Select } from "components/form/Select"; import { useValues } from "context/ValuesContext"; const ManageUnitCallsignModal = dynamic( @@ -70,19 +68,19 @@ export function CallsignsTab({ units }: Props) { asyncTable={asyncTable} totalCount={units.totalCount} > - - ({ - value: v.id, - label: v.value, - }))} - onChange={handleChange} - name="bloodGroup" - value={values.bloodGroup} - /> - + setFieldValue("type", value)} diff --git a/apps/client/src/components/leo/modals/CreateWarrantModal.tsx b/apps/client/src/components/leo/modals/CreateWarrantModal.tsx index 356a2acf9..324a71662 100644 --- a/apps/client/src/components/leo/modals/CreateWarrantModal.tsx +++ b/apps/client/src/components/leo/modals/CreateWarrantModal.tsx @@ -1,8 +1,6 @@ import { Form, Formik, FormikHelpers } from "formik"; import { useTranslations } from "use-intl"; import { Loader, Button, SelectField, TextField } from "@snailycad/ui"; -import { FormField } from "components/form/FormField"; -import { Select } from "components/form/Select"; import useFetch from "lib/useFetch"; import { Modal } from "components/modal/Modal"; import { useModal } from "state/modalState"; @@ -48,7 +46,7 @@ export function CreateWarrantModal({ warrant, readOnly, onClose, onCreate, onUpd ) { const data = { ...values, - assignedOfficers: values.assignedOfficers.map((value) => value.value), + assignedOfficers: values.assignedOfficers ?? [], }; if (warrant) { @@ -101,14 +99,7 @@ export function CreateWarrantModal({ warrant, readOnly, onClose, onCreate, onUpd citizenName: warrant?.citizen ? `${warrant.citizen.name} ${warrant.citizen.surname}` : "", status: warrant?.status ?? "", description: warrant?.description ?? "", - assignedOfficers: warrant?.assignedOfficers - ? warrant.assignedOfficers.map((unit) => ({ - label: isUnitCombined(unit.unit) - ? generateCallsign(unit.unit, "pairedUnitTemplate") - : `${generateCallsign(unit.unit)} ${makeUnitName(unit.unit)}`, - value: unit.unit.id, - })) - : [], + assignedOfficers: warrant?.assignedOfficers?.map((v) => v.unit.id), }; return ( @@ -119,7 +110,7 @@ export function CreateWarrantModal({ warrant, readOnly, onClose, onCreate, onUpd className="w-[600px]" > - {({ handleChange, setFieldValue, values, errors, isValid }) => ( + {({ setFieldValue, values, errors, isValid }) => ( {isActive ? ( - - ({ + + ({ value: field.id, label: field.name, }))} + onSelectionChange={(value) => setFieldValue("customFieldId", value)} + selectedKey={values.customFieldId} + className="w-64" /> - - setFieldValue("query", value)} - value={values.query} - /> + setFieldValue("query", value)} + value={values.query} + /> + {results ? : null} From e8a58109c2bcda6005deac6e293ed951fa9fe34b Mon Sep 17 00:00:00 2001 From: Dev-CasperTheGhost <53900565+Dev-CasperTheGhost@users.noreply.github.com> Date: Mon, 19 Jun 2023 20:01:09 +0200 Subject: [PATCH 3/8] feat(select): start using @snailycad/ui select --- .../manage/citizens/AdvancedCitizensTab.tsx | 36 +++----- .../manage/citizens/all-citizens-tab.tsx | 36 ++++---- .../manage-custom-roles-modal.tsx | 66 ++++++------- .../manage/units/AddQualificationsModal.tsx | 38 +++----- .../tabs/all-units-tab/prune-units-modal.tsx | 39 ++++---- .../tabs/manage-unit-tab/manage-unit-tab.tsx | 92 ++++++++----------- .../users/modals/manage-roles-modal.tsx | 37 ++++---- .../admin/values/ManageValueModal.tsx | 82 ++++++++--------- .../values/manage-modal/department-fields.tsx | 29 ++---- .../values/manage-modal/division-fields.tsx | 24 ++--- .../manage-modal/emergency-vehicle-fields.tsx | 65 ++++++------- .../manage-modal/qualification-fields.tsx | 42 ++++----- .../manage-modal/status-value-fields.tsx | 36 +++++--- .../form/inputs/value-select-field.tsx | 11 ++- apps/client/src/lib/admin/values/values.tsx | 14 ++- .../ui/src/components/fields/select-field.tsx | 5 +- .../inputs/select/selected-items.tsx | 2 +- .../stories/fields/select-field.stories.tsx | 16 ++++ 18 files changed, 305 insertions(+), 365 deletions(-) diff --git a/apps/client/src/components/admin/manage/citizens/AdvancedCitizensTab.tsx b/apps/client/src/components/admin/manage/citizens/AdvancedCitizensTab.tsx index 76f34bac3..ee93c930e 100644 --- a/apps/client/src/components/admin/manage/citizens/AdvancedCitizensTab.tsx +++ b/apps/client/src/components/admin/manage/citizens/AdvancedCitizensTab.tsx @@ -1,8 +1,6 @@ import * as React from "react"; -import { FormField } from "components/form/FormField"; import { Button, Loader, TextField, FormRow } from "@snailycad/ui"; import { v4 } from "uuid"; -import { Select } from "components/form/Select"; import { useValues } from "context/ValuesContext"; import useFetch from "lib/useFetch"; import { X } from "react-bootstrap-icons"; @@ -10,6 +8,8 @@ import { ImportModal } from "components/admin/import/ImportModal"; import { ModalIds } from "types/modal-ids"; import type { PostImportCitizensData } from "@snailycad/types/api"; import { useTranslations } from "use-intl"; +import { ValueSelectField } from "components/form/inputs/value-select-field"; +import { ValueType } from "@snailycad/types"; export function AdvancedCitizensTab() { const [citizens, setCitizens] = React.useState>(createInitialCitizen()); @@ -89,27 +89,21 @@ export function AdvancedCitizensTab() { onBlur={(e) => handleChange("dateOfBirth", id, e)} /> - {/* todo: use async search field (see: manage-citizen-form) */} - - handleChange("ethnicity", id, event)} - values={ethnicity.values.map((ethnicity) => ({ - value: ethnicity.id, - label: ethnicity.value, - }))} + + - + ); })} diff --git a/apps/client/src/components/admin/manage/citizens/all-citizens-tab.tsx b/apps/client/src/components/admin/manage/citizens/all-citizens-tab.tsx index 4e85ce453..dc2b887bf 100644 --- a/apps/client/src/components/admin/manage/citizens/all-citizens-tab.tsx +++ b/apps/client/src/components/admin/manage/citizens/all-citizens-tab.tsx @@ -2,11 +2,9 @@ import * as React from "react"; import { useModal } from "state/modalState"; import useFetch from "lib/useFetch"; import { ModalIds } from "types/modal-ids"; -import { Loader, Button, buttonVariants, TextField } from "@snailycad/ui"; +import { Loader, Button, buttonVariants, TextField, SelectField } from "@snailycad/ui"; import { useTranslations } from "next-intl"; -import { FormField } from "components/form/FormField"; import { Table, useTableState } from "components/shared/Table"; -import { Select } from "components/form/Select"; import Link from "next/link"; import { FullDate } from "components/shared/FullDate"; import { usePermission, Permissions } from "hooks/usePermission"; @@ -97,22 +95,22 @@ export function AllCitizensTab({ citizens: initialData, totalCount, setCitizens ) : null} - - ({ - value: permission, - label: tPermission(permission), - }))} - value={values.permissions} - name="permissions" - onChange={handleChange} - /> - - - ({ + value: permission, + label: tPermission(permission), + }))} + onSelectionChange={(keys) => setFieldValue("permissions", keys)} + /> + + - { - return !v.departments?.length - ? v.qualificationType === type - : v.departments.some((v) => unit.departmentId === v.id) && - v.qualificationType === type; - }) - .map((q) => ({ - value: q.id, - label: q.value.value, - }))} - /> - + valueType={ValueType.QUALIFICATION} + filterFn={(value) => { + return !value.departments?.length + ? value.qualificationType === type + : value.departments.some((v) => unit.departmentId === v.id) && + value.qualificationType === type; + }} + />