diff --git a/packages/main/.eslintrc.cjs b/packages/main/.eslintrc.cjs index 9736d57d..aca78c0c 100644 --- a/packages/main/.eslintrc.cjs +++ b/packages/main/.eslintrc.cjs @@ -1,6 +1,6 @@ module.exports = { env: { browser: true, es2020: true }, - extends: ["plugin:@typescript-eslint/recommended"], + extends: ["plugin:@typescript-eslint/recommended","prettier"], parser: "@typescript-eslint/parser", parserOptions: { ecmaVersion: "latest", sourceType: "module" }, plugins: ["react-refresh"], diff --git a/packages/main/package.json b/packages/main/package.json index 17696636..4f466dd5 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -75,6 +75,7 @@ "@vitejs/plugin-basic-ssl": "^1.0.2", "@vitejs/plugin-react": "^4.2.0", "eslint": "^8.54.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.3.5", "happy-dom": "^9.20.3", diff --git a/packages/main/plugins/Cardinality/SeriesRowStyles.tsx b/packages/main/plugins/Cardinality/SeriesRowStyles.tsx index 8ee26807..bf19be82 100644 --- a/packages/main/plugins/Cardinality/SeriesRowStyles.tsx +++ b/packages/main/plugins/Cardinality/SeriesRowStyles.tsx @@ -12,6 +12,15 @@ export const SeriesRowStyle = (theme: Partial) => css` width: auto; border-bottom: 1px solid ${theme.neutral}; } + .cell-column-header { + display: flex; + flex-direction: column; + } + .cell-column-name { + display: flex; + align-items: center; + justify-content: space-between; + } .cell-name { width: 60%; cursor: pointer; diff --git a/packages/main/plugins/Cardinality/TotalsPanel/CardinalityTotals.tsx b/packages/main/plugins/Cardinality/TotalsPanel/CardinalityTotals.tsx index ef58f7d4..8066f71e 100644 --- a/packages/main/plugins/Cardinality/TotalsPanel/CardinalityTotals.tsx +++ b/packages/main/plugins/Cardinality/TotalsPanel/CardinalityTotals.tsx @@ -20,8 +20,9 @@ export default function CardinalityTotals({ isLoading }) { const [sort, setSort] = useState("asc"); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(10); + const [searchValue, setSearchValue] = useState(""); - function paginateTotals(data) { + function paginateTotals(data: Array) { const startIndex = page * rowsPerPage; const endIndex = startIndex + rowsPerPage; return data.slice(startIndex, endIndex); @@ -39,9 +40,27 @@ export default function CardinalityTotals({ isLoading }) { setTotals(paginateTotals(maintenance)); }, [page]); + const searchHandler = useCallback( + (text: string) => { + setSearchValue(text); + + const filteredData = maintenance.filter((item) => { + return item.query.toLowerCase().includes(text.toLowerCase()); + }); + + if (filteredData?.length > 0) { + setTotals(paginateTotals(filteredData)); + } + + if (text === "") { + setTotals(paginateTotals(maintenance)); + } + }, + [totals] + ); + const sortByProperty = useCallback( (column: string) => { - if (column !== "undo") { setTotals(() => { let items = [...maintenance]; @@ -63,11 +82,11 @@ export default function CardinalityTotals({ isLoading }) { return (
-
- {totals?.length > 0 - ? "Fingerprints in Maintainance mode" - : "No Fingerprints in Maintainance mode"} -
+ {totals?.length > 0 && ( ); } + +export const TotalRowsHeader = ({ + totalsLength, + searchHandler, + searchValue, +}) => { + return ( +
+
+ + searchHandler(e.target.value)} + placeholder="" + /> +
+ {totalsLength > 0 + ? "Fingerprints in Maintainance mode" + : "No Fingerprints in Maintainance mode"} +
+ ); +}; diff --git a/packages/main/plugins/Cardinality/TotalsPanel/TableColHeader.tsx b/packages/main/plugins/Cardinality/TotalsPanel/TableColHeader.tsx new file mode 100644 index 00000000..6e9738d8 --- /dev/null +++ b/packages/main/plugins/Cardinality/TotalsPanel/TableColHeader.tsx @@ -0,0 +1,17 @@ +export type TableColHeaderProps = { + value: string; + text: string; + sortByProperty: (value: string) => void; +}; +const TableColHeader = ({ + value, + text, + sortByProperty, +}: TableColHeaderProps) => { + return ( +
sortByProperty(value)} className="cell"> + {text} +
+ ); +}; +export default TableColHeader; diff --git a/packages/main/plugins/Cardinality/TotalsPanel/TotalsTable.tsx b/packages/main/plugins/Cardinality/TotalsPanel/TotalsTable.tsx index 4be23002..8f436ec3 100644 --- a/packages/main/plugins/Cardinality/TotalsPanel/TotalsTable.tsx +++ b/packages/main/plugins/Cardinality/TotalsPanel/TotalsTable.tsx @@ -1,5 +1,6 @@ import { TotalsRow } from "./TotalsRow"; import TotalsPagination from "./Pagination"; +import TableColHeader from "./TableColHeader"; type totalHeader = { value: string; @@ -33,14 +34,13 @@ const TotalsTable = ({ <>
- {headers?.map((header) => ( -
sortByProperty(header.value)} - className="cell" - > - {header.text} -
+ {headers?.map(({ value, text }) => ( + ))}
diff --git a/packages/main/plugins/Cardinality/TotalsPanel/style.tsx b/packages/main/plugins/Cardinality/TotalsPanel/style.tsx index e29e702a..d80c2576 100644 --- a/packages/main/plugins/Cardinality/TotalsPanel/style.tsx +++ b/packages/main/plugins/Cardinality/TotalsPanel/style.tsx @@ -7,11 +7,32 @@ export const TotalRowStyle = (theme: QrynTheme) => css` flex-direction: column; .total-rows-header { text-align: center; - padding: 10px 0px; + padding: 10px 20px; margin: 0px 4px; font-size: 12px; border-radius: 3px; background: ${theme.shadow}; + display: flex; + align-items: center; + justify-content: space-between; + .search-container { + display: flex; + align-items: center; + gap: 6px; + input { + background: ${theme.shadow}; + border: 1px solid ${theme.deep}; + color: ${theme.contrast}; + font-size: 10px; + padding: 5px 10px; + border-radius: 3px; + margin: 0px 4px; + :focus { + outline: none; + background: ${theme.deep}; + } + } + } } .table-container { display: flex; diff --git a/packages/main/plugins/Cardinality/TotalsPanel/useMaintenance.ts b/packages/main/plugins/Cardinality/TotalsPanel/useMaintenance.ts index 243ae9ea..3c8e415b 100644 --- a/packages/main/plugins/Cardinality/TotalsPanel/useMaintenance.ts +++ b/packages/main/plugins/Cardinality/TotalsPanel/useMaintenance.ts @@ -7,7 +7,7 @@ export async function getMaintenance() { return await fetch("http://localhost:8081/api/v1/maintenance"); } -export async function undoAction(id) { +export async function undoAction(id: string) { return await fetch(`http://localhost:8081/api/v1/undo/${id}`) .then((res) => { if (res.status === 200) { @@ -17,7 +17,6 @@ export async function undoAction(id) { message: "Successfully restored fingerprints", }) ); - return res.json(); } else { store.dispatch( @@ -26,7 +25,9 @@ export async function undoAction(id) { message: "Failed to restore fingerprints", }) ); - return { error: "Failed to restore fingerprints" }; + return { + error: "Failed to restore fingerprints", + }; } }) .then((data) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f30539b5..b52ebdd6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' settings: autoInstallPeers: true @@ -45,6 +45,12 @@ importers: '@emotion/styled': specifier: ^11.11.0 version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.39)(react@18.2.0) + '@floating-ui/react': + specifier: ^0.26.7 + version: 0.26.7(react-dom@18.2.0)(react@18.2.0) + '@floating-ui/react-dom': + specifier: ^2.0.7 + version: 2.0.7(react-dom@18.2.0)(react@18.2.0) '@microlink/react-json-view': specifier: latest version: 1.23.0(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) @@ -223,6 +229,9 @@ importers: eslint: specifier: ^8.54.0 version: 8.54.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.54.0) eslint-plugin-react-hooks: specifier: ^4.6.0 version: 4.6.0(eslint@8.54.0) @@ -850,6 +859,12 @@ packages: '@floating-ui/utils': 0.1.6 dev: false + /@floating-ui/core@1.6.0: + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + dependencies: + '@floating-ui/utils': 0.2.1 + dev: false + /@floating-ui/dom@1.5.3: resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==} dependencies: @@ -857,21 +872,45 @@ packages: '@floating-ui/utils': 0.1.6 dev: false - /@floating-ui/react-dom@2.0.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==} + /@floating-ui/dom@1.6.0: + resolution: {integrity: sha512-SZ0BEXzsaaS6THZfZJUcAobbZTD+MvfGM42bxgeg0Tnkp4/an/avqwAXiVLsFtIBZtfsx3Ymvwx0+KnnhdA/9g==} + dependencies: + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/react-dom@2.0.7(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-B5GJxKUyPcGsvE1vua+Abvw0t6zVMyTbtG+Jk7BoI4hfc5Ahv50dstRIAn0nS0274kR9gnKwxIXyGA8EzBZJrA==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@floating-ui/dom': 1.5.3 + '@floating-ui/dom': 1.6.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false + /@floating-ui/react@0.26.7(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0uMI9IBJBPPt8N+8uRg4gazJvQReWTu/fVUHHLfAOuy1WB6f242jtjWm52hLJG8nzuZVuU+2crW4lJbJQoqeIA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/react-dom': 2.0.7(react-dom@18.2.0)(react@18.2.0) + '@floating-ui/utils': 0.2.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tabbable: 6.2.0 + dev: false + /@floating-ui/utils@0.1.6: resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} dev: false + /@floating-ui/utils@0.2.1: + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + dev: false + /@humanwhocodes/config-array@0.11.13: resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} @@ -986,7 +1025,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@floating-ui/react-dom': 2.0.4(react-dom@18.2.0)(react@18.2.0) + '@floating-ui/react-dom': 2.0.7(react-dom@18.2.0)(react@18.2.0) '@mui/types': 7.2.10(@types/react@18.2.39) '@mui/utils': 5.14.19(@types/react@18.2.39)(react@18.2.0) '@popperjs/core': 2.11.8 @@ -2447,6 +2486,15 @@ packages: optionalDependencies: source-map: 0.6.1 + /eslint-config-prettier@9.1.0(eslint@8.54.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.54.0 + dev: true + /eslint-plugin-react-hooks@4.6.0(eslint@8.54.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} @@ -4498,6 +4546,10 @@ packages: /symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: false + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true