From 6a1dbd0955289ede433b2968ce748704d67f8f96 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 7 Mar 2024 17:29:31 +0100 Subject: [PATCH] filter --- package-lock.json | 24 +++++ package.json | 1 + public/locales/de/translation.json | 7 +- public/locales/en/translation.json | 6 +- src/Pages/CrmTest/CrmTest.js | 137 ++++++++++++++++++++++++++++- 5 files changed, 170 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e3cfc5..0e97df9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "i18next-http-backend": "^2.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight-words": "^0.20.0", "react-i18next": "^13.0.1", "react-qr-scanner": "^1.0.0-alpha.11", "react-router-dom": "^6.10.0", @@ -11173,6 +11174,11 @@ "he": "bin/he" } }, + "node_modules/highlight-words-core": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words-core/-/highlight-words-core-1.2.2.tgz", + "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -14860,6 +14866,11 @@ "node": ">= 4.0.0" } }, + "node_modules/memoize-one": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-4.0.3.tgz", + "integrity": "sha512-QmpUu4KqDmX0plH4u+tf0riMc1KHE1+lw95cMrLlXQAFOx/xnBtwhZ52XJxd9X2O6kwKBqX32kmhbhlobD0cuw==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -18648,6 +18659,19 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-highlight-words": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/react-highlight-words/-/react-highlight-words-0.20.0.tgz", + "integrity": "sha512-asCxy+jCehDVhusNmCBoxDf2mm1AJ//D+EzDx1m5K7EqsMBIHdZ5G4LdwbSEXqZq1Ros0G0UySWmAtntSph7XA==", + "dependencies": { + "highlight-words-core": "^1.2.0", + "memoize-one": "^4.0.0", + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0" + } + }, "node_modules/react-hook-form": { "version": "7.48.2", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.48.2.tgz", diff --git a/package.json b/package.json index 4f9b262..871bd72 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "i18next-http-backend": "^2.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight-words": "^0.20.0", "react-i18next": "^13.0.1", "react-qr-scanner": "^1.0.0-alpha.11", "react-router-dom": "^6.10.0", diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json index 81a7fb6..85d0086 100644 --- a/public/locales/de/translation.json +++ b/public/locales/de/translation.json @@ -12,7 +12,10 @@ "save": "Speichern", "delete": "Löschen", "confirm": "Bestätigen", - "create": "Erstellen" + "create": "Erstellen", + "search": "Suchen", + "reset": "Zurücksetzen", + "filter": "Filtern" }, "contactAdmin": "Bitte kontaktieren Sie einen Administrator", "text": { @@ -284,7 +287,9 @@ "createdBy": "Erstellt von", "notes": "Notizen" }, + "placeholderSearch": "Suche nach", "buttonNew": "Neu", + "buttonUndo": "Rückgängig machen", "tabs": { "dealInfo": "Deal-Informationen", "activities": "Aktivitäten", diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index f538a80..064fd3e 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -12,7 +12,10 @@ "save": "Save", "delete": "Delete", "confirm": "Confirm", - "create": "Create" + "create": "Create", + "search": "Search", + "reset": "Reset", + "filter": "Filter" }, "contactAdmin": "Please contact an administrator", "text": { @@ -284,6 +287,7 @@ "createdBy": "Created by", "notes": "Notes" }, + "placeholderSearch": "Search for", "buttonNew": "New", "buttonUndo": "Undo", "tabs": { diff --git a/src/Pages/CrmTest/CrmTest.js b/src/Pages/CrmTest/CrmTest.js index 5f917c8..8c42b11 100644 --- a/src/Pages/CrmTest/CrmTest.js +++ b/src/Pages/CrmTest/CrmTest.js @@ -26,7 +26,11 @@ import { wsConnectionCustomEventName, } from "../../utils"; import { useEffect, useRef, useState } from "react"; -import { PlusOutlined, ChromeOutlined } from "@ant-design/icons"; +import { + PlusOutlined, + ChromeOutlined, + SearchOutlined, +} from "@ant-design/icons"; import { t } from "i18next"; import { useCrmContext } from "../../Contexts/CrmContext"; import "@mdxeditor/editor/style.css"; @@ -46,6 +50,7 @@ import { tablePlugin } from "@mdxeditor/editor"; import { frontmatterPlugin } from "@mdxeditor/editor"; import { MyAvatar } from "../../Components/MyAvatar"; import { useAppContext } from "../../Contexts/AppContext"; +import Highlighter from "react-highlight-words"; const CRM_TYPE = { CUSTOMERS: 0, @@ -94,6 +99,10 @@ export default function CrmTest() { const filterAssignedEmployeeRef = useRef([]); + const [searchText, setSearchText] = useState(""); + const [searchedColumn, setSearchedColumn] = useState(""); + const searchInput = useRef(null); + const title = selectedSegmentedTypeValue === CRM_TYPE.CUSTOMERS ? "crm.customers.pageTitle" @@ -129,12 +138,126 @@ export default function CrmTest() { return 0; }; + const handleSearch = (selectedKeys, confirm, dataIndex) => { + confirm(); + setSearchText(selectedKeys[0]); + setSearchedColumn(dataIndex); + }; + const handleReset = (clearFilters) => { + clearFilters(); + setSearchText(""); + }; + + const getColumnSearchProps = (dataIndex) => ({ + filterDropdown: ({ + setSelectedKeys, + selectedKeys, + confirm, + clearFilters, + close, + }) => ( +
e.stopPropagation()} + > + + setSelectedKeys(e.target.value ? [e.target.value] : []) + } + onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)} + style={{ + marginBottom: 8, + display: "block", + }} + /> + + + + + + +
+ ), + filterIcon: (filtered) => ( + + ), + onFilter: (value, record) => + record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()), + onFilterDropdownOpenChange: (visible) => { + if (visible) { + setTimeout(() => searchInput.current?.select(), 100); + } + }, + render: (text) => + searchedColumn === dataIndex ? ( + + ) : ( + text + ), + }); + const getTableContent = () => { return [ { title: t("crm.table.assignedEmployee"), dataIndex: "assignedEmployee", key: "assignedEmployee", + sorter: (a, b) => sorter(a._assignedEmployee, b._assignedEmployee), filters: filterAssignedEmployeeRef.current.map((item) => { return { text: @@ -150,24 +273,28 @@ export default function CrmTest() { }; }), onFilter: (value, record) => record._assignedEmployee === value, + ellipsis: true, }, { title: t("crm.table.firstName"), dataIndex: "firstName", key: "firstName", sorter: (a, b) => sorter(a.firstName, b.firstName), + ...getColumnSearchProps("firstName"), }, { title: t("crm.table.lastName"), dataIndex: "lastName", key: "lastName", sorter: (a, b) => sorter(a.lastName, b.lastName), + ...getColumnSearchProps("lastName"), }, { title: t("crm.table.company"), dataIndex: "company", key: "company", sorter: (a, b) => sorter(a.company, b.company), + ...getColumnSearchProps("company"), }, { title: t("crm.table.createdAt"), @@ -188,12 +315,14 @@ export default function CrmTest() { dataIndex: "telephone", key: "telephone", sorter: (a, b) => sorter(a.telephone, b.telephone), + ...getColumnSearchProps("telephone"), }, { title: t("crm.table.email"), dataIndex: "email", key: "email", sorter: (a, b) => sorter(a.email, b.email), + ...getColumnSearchProps("email"), }, { title: t("crm.table.lastContact"), @@ -410,11 +539,13 @@ export default function CrmTest() { style={{ display: "flex", justifyContent: "space-between", + marginTop: 6, }} > {t(title)}