main
alex 2024-03-07 17:29:31 +01:00
parent f9867bc9eb
commit 6a1dbd0955
5 changed files with 170 additions and 5 deletions

24
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": {

View File

@ -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,
}) => (
<div
style={{
padding: 8,
}}
onKeyDown={(e) => e.stopPropagation()}
>
<Input
ref={searchInput}
placeholder={`${t("crm.placeholderSearch")} ${dataIndex}`}
value={selectedKeys[0]}
onChange={(e) =>
setSelectedKeys(e.target.value ? [e.target.value] : [])
}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{
marginBottom: 8,
display: "block",
}}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{
width: 90,
}}
>
{t("common.button.search")}
</Button>
<Button
onClick={() => clearFilters && handleReset(clearFilters)}
size="small"
style={{
width: 100,
}}
>
{t("common.button.reset")}
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({
closeDropdown: false,
});
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
}}
>
{t("common.button.filter")}
</Button>
<Button
type="link"
size="small"
onClick={() => {
close();
}}
>
{t("common.button.close")}
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<SearchOutlined
style={{
color: filtered ? "#1677ff" : undefined,
}}
/>
),
onFilter: (value, record) =>
record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()),
onFilterDropdownOpenChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
},
render: (text) =>
searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{
backgroundColor: "#ffc069",
padding: 0,
}}
searchWords={[searchText]}
autoEscape
textToHighlight={text ? text.toString() : ""}
/>
) : (
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,
}}
>
<Typography.Title level={4}>{t(title)}</Typography.Title>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => {
crmContext.openDrawerCustomerId.current = "new";
@ -710,7 +841,7 @@ function CustomerDrawer({ isOpen, setIsOpen, onClose, notificationApi }) {
<Space>
<Form form={formDealInfo} layout="inline">
<Form.Item name="AssignedEmployee">
<Select>
<Select style={{ minWidth: 100 }}>
{appContext.users.map((user) => (
<Select.Option key={user.Id} value={user.Id}>
<Space>
@ -783,7 +914,7 @@ function TabContentDealInfo({ form }) {
const FormItem = ({ name, label }) => (
<Form.Item name={name} label={typeof label === "string" ? t(label) : label}>
<Input />
<Input maxLength={250} />
</Form.Item>
);