diff --git a/.prettierrc.js b/.prettierrc.js index f9345b376..076151234 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -6,10 +6,10 @@ module.exports = { singleQuote: true, trailingComma: 'all', bracketSpacing: true, - jsxBracketSameLine: true, + bracketSameLine: true, arrowParens: 'always', requirePragma: false, insertPragma: false, proseWrap: 'always', - endOfLine:"auto", + endOfLine: 'auto', }; diff --git a/docker-compose.yml b/docker-compose.yml index 6f0cb6099..eb94fc7b9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,7 @@ services: - "5001:5000" volumes: - ./:/ng-app + - node_modules_data:/ng-app/node_modules networks: - forus-network @@ -32,4 +33,8 @@ services: networks: forus-network: name: forus-network - driver: bridge \ No newline at end of file + driver: bridge + +volumes: + node_modules_data: + driver: local diff --git a/package-lock.json b/package-lock.json index 1ad6f15e3..5892601c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@mdi/js": "^7.1.96", "@react-google-maps/api": "^2.20.3", "@uiw/react-color": "^2.4.1", - "aws-rum-web": "^1.19.0", + "aws-rum-web": "^2.0.0", "chart.js": "^4.4.1", "clean-webpack-plugin": "^4.0.0", "date-fns": "^4.1.0", @@ -139,52 +139,30 @@ "ajv": ">=8" } }, - "node_modules/@aws-crypto/crc32": { + "node_modules/@aws-crypto/sha256-js": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^3.0.0", "@aws-sdk/types": "^3.222.0", "tslib": "^1.11.1" } }, - "node_modules/@aws-crypto/crc32/node_modules/@aws-crypto/util": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", - "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/crc32/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.2.tgz", - "integrity": "sha512-iXLdKH19qPmIC73fVCrHWCSYjN/sxaAvZ3jNNyw6FclmHyjLKg0f69WlC9KTnyElxCR5MO9SKaG00VwlJwyAkQ==", - "dependencies": { - "@aws-crypto/util": "^2.0.2", - "@aws-sdk/types": "^3.110.0", - "tslib": "^1.11.1" - } - }, "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" }, "node_modules/@aws-crypto/util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", - "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.110.0", + "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } @@ -192,30 +170,8 @@ "node_modules/@aws-crypto/util/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.374.0.tgz", - "integrity": "sha512-Xt+4F6tGi/q9Z32kLo8SSm9krLlCY2oTLxCfP3/1SKY2wqWKHjAgpLmPD+GW7fdMjAwhDqzW5ZhcSmvHNvoD/w==", - "deprecated": "This package has moved to @smithy/fetch-http-handler", - "dependencies": { - "@smithy/fetch-http-handler": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/protocol-http": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.374.0.tgz", - "integrity": "sha512-9WpRUbINdGroV3HiZZIBoJvL2ndoWk39OfwxWs2otxByppJZNN14bg/lvCx5e8ggHUti7IBk5rb0nqQZ4m05pg==", - "deprecated": "This package has moved to @smithy/protocol-http", - "dependencies": { - "@smithy/protocol-http": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" }, "node_modules/@aws-sdk/querystring-builder": { "version": "3.374.0", @@ -230,48 +186,24 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/signature-v4": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.374.0.tgz", - "integrity": "sha512-2xLJvSdzcZZAg0lsDLUAuSQuihzK0dcxIK7WmfuJeF7DGKJFmp9czQmz5f3qiDz6IDQzvgK1M9vtJSVCslJbyQ==", - "deprecated": "This package has moved to @smithy/signature-v4", - "dependencies": { - "@smithy/signature-v4": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@aws-sdk/types": { - "version": "3.649.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.649.0.tgz", - "integrity": "sha512-PuPw8RysbhJNlaD2d/PzOTf8sbf4Dsn2b7hwyGh7YVG3S75yTpxSAZxrnhKsz9fStgqFmnw/jUfV/G+uQAeTVw==", + "version": "3.973.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.1.tgz", + "integrity": "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^3.4.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.374.0.tgz", - "integrity": "sha512-14X7MDYCFle2Cuq0/Hvz2CHQoYVeoKKBY2Uf+wn0lKnKU+f0K81xRObUM/A7bLmZX4jFRk83gyE8Rj3BOqBdfA==", - "deprecated": "This package has moved to @smithy/util-hex-encoding", - "dependencies": { - "@smithy/util-hex-encoding": "^1.0.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/util-utf8-browser": { "version": "3.259.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.1" } @@ -2798,83 +2730,92 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "node_modules/@smithy/eventstream-codec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-1.1.0.tgz", - "integrity": "sha512-3tEbUb8t8an226jKB6V/Q2XU/J53lCwCzULuBPEaF4JjSh+FlCMp7TmogE/Aij5J9DwlsZ4VAD/IRDuQ/0ZtMw==", + "node_modules/@smithy/fetch-http-handler": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.3.tgz", + "integrity": "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA==", + "license": "Apache-2.0", "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^1.2.0", - "@smithy/util-hex-encoding": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@smithy/eventstream-codec/node_modules/@smithy/types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", - "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", + "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/querystring-builder": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz", + "integrity": "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@smithy/fetch-http-handler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-1.1.0.tgz", - "integrity": "sha512-N22C9R44u5WGlcY+Wuv8EXmCAq62wWwriRAuoczMEwAIjPbvHSthyPSLqI4S7kAST1j6niWg8kwpeJ3ReAv3xg==", + "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^1.2.0", - "@smithy/querystring-builder": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/util-base64": "^1.1.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", - "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", + "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/is-array-buffer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-1.1.0.tgz", - "integrity": "sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/protocol-http": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.2.0.tgz", - "integrity": "sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", + "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/protocol-http/node_modules/@smithy/types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", - "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-builder": { @@ -2902,38 +2843,41 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-1.1.0.tgz", - "integrity": "sha512-fDo3m7YqXBs7neciOePPd/X9LPm5QLlDMdIC4m1H6dgNLnXfLMFNIxEfPyohGA8VW9Wn4X8lygnPSGxDZSmp0Q==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz", + "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^1.1.0", - "@smithy/is-array-buffer": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/util-hex-encoding": "^1.1.0", - "@smithy/util-middleware": "^1.1.0", - "@smithy/util-uri-escape": "^1.1.0", - "@smithy/util-utf8": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", - "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@smithy/types": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.2.tgz", - "integrity": "sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==", + "node_modules/@smithy/signature-v4/node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -2941,50 +2885,80 @@ "node": ">=16.0.0" } }, + "node_modules/@smithy/types": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", + "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/util-base64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-1.1.0.tgz", - "integrity": "sha512-FpYmDmVbOXAxqvoVCwqehUN0zXS+lN8V7VS9O7I8MKeVHdSTsZzlwiMEvGoyTNOXWn8luF4CTDYgNHnZViR30g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-1.1.0.tgz", - "integrity": "sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-hex-encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-1.1.0.tgz", - "integrity": "sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-middleware": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-1.1.0.tgz", - "integrity": "sha512-6hhckcBqVgjWAqLy2vqlPZ3rfxLDhFWEmM7oLh2POGvsi7j0tHkbN7w4DFhuBExVJAbJ/qqxqZdRY6Fu7/OezQ==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", + "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-middleware/node_modules/@smithy/types": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/util-uri-escape": { @@ -2999,15 +2973,16 @@ } }, "node_modules/@smithy/util-utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-1.1.0.tgz", - "integrity": "sha512-p/MYV+JmqmPyjdgyN2UxAeYDj9cBqCjp0C/NsTWnnjoZUVqoeZ6IrW915L9CAKWVECgv9lVQGc4u/yz26/bI1A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { @@ -5085,21 +5060,22 @@ } }, "node_modules/aws-rum-web": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/aws-rum-web/-/aws-rum-web-1.19.0.tgz", - "integrity": "sha512-V3sUSC3U8IYsQS0vK/rmACjzFugG07Zd01SII6JMvEB1/axEQ+SxUTK+nCyJdpCFPB3TuhpFwcfq5PVkn/MJ7w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aws-rum-web/-/aws-rum-web-2.0.0.tgz", + "integrity": "sha512-5LqpIDkgUbg0Iu6jMEeYJ6AIHkAia1UTpF+dS7NLvgzdK3smdjXjp1aV/W6IWjQwRI7rO950BBtcJ+G9VoPKWQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-js": "^2.0.2", - "@aws-sdk/fetch-http-handler": "^3.36.0", - "@aws-sdk/protocol-http": "^3.36.0", + "@aws-crypto/sha256-js": "^3.0.0", "@aws-sdk/querystring-builder": "^3.36.0", - "@aws-sdk/signature-v4": "^3.36.0", - "@aws-sdk/util-hex-encoding": "^3.36.0", "@babel/runtime": "^7.16.0", + "@smithy/fetch-http-handler": "^4.1.0", + "@smithy/protocol-http": "^4.1.6", + "@smithy/signature-v4": "^4.2.2", + "@smithy/util-hex-encoding": "^3.0.0", "shimmer": "^1.2.1", "ua-parser-js": "^1.0.33", "uuid": "^9.0.0", - "web-vitals": "^3.0.2" + "web-vitals": "^4.0.0" } }, "node_modules/axios": { @@ -13712,9 +13688,10 @@ } }, "node_modules/web-vitals": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", - "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" }, "node_modules/webpack": { "version": "5.94.0", diff --git a/package.json b/package.json index 2dd2fc7ae..cbc54d057 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "@mdi/js": "^7.1.96", "@react-google-maps/api": "^2.20.3", "@uiw/react-color": "^2.4.1", - "aws-rum-web": "^1.19.0", + "aws-rum-web": "^2.0.0", "chart.js": "^4.4.1", "clean-webpack-plugin": "^4.0.0", "date-fns": "^4.1.0", diff --git a/react/assets/forus-webshop/scss/includes/blocks/block-action-card.scss b/react/assets/forus-webshop/scss/includes/blocks/block-action-card.scss index 1d34e690f..ce00d7774 100644 --- a/react/assets/forus-webshop/scss/includes/blocks/block-action-card.scss +++ b/react/assets/forus-webshop/scss/includes/blocks/block-action-card.scss @@ -182,7 +182,7 @@ } } - &.bottom { + &.block-card-actions-bottom { width: 100%; padding: 8px 65px 0; diff --git a/react/assets/forus-webshop/scss/includes/blocks/block-reimbursements.scss b/react/assets/forus-webshop/scss/includes/blocks/block-reimbursements.scss index 43f6d32af..0f82f7d70 100644 --- a/react/assets/forus-webshop/scss/includes/blocks/block-reimbursements.scss +++ b/react/assets/forus-webshop/scss/includes/blocks/block-reimbursements.scss @@ -66,13 +66,13 @@ } } - &.reimbursement-image-rejected { + &.reimbursement-image-declined { svg .fill-color-primary { fill: #d38c87; } } - &.reimbursement-image-accepted { + &.reimbursement-image-approved { svg .fill-color-primary { fill: #9bbfa1; } @@ -119,7 +119,7 @@ } .reimbursement-values { - padding: 0px 15px 15px 20px; + padding: 0 15px 15px 20px; display: flex; flex-direction: row; justify-content: flex-end; @@ -161,8 +161,6 @@ flex-direction: column; padding: 15px; position: relative; - display: flex; - flex-direction: column; justify-content: flex-end; white-space: nowrap; @@ -184,7 +182,6 @@ bottom: 25px; left: 25px; text-align: right; - flex-direction: column; justify-content: flex-end; margin: 0 0 5px; diff --git a/react/src/dashboard/components/elements/block-card-emails/BlockCardEmails.tsx b/react/src/dashboard/components/elements/block-card-emails/BlockCardEmails.tsx index b91212e7e..f50982e63 100644 --- a/react/src/dashboard/components/elements/block-card-emails/BlockCardEmails.tsx +++ b/react/src/dashboard/components/elements/block-card-emails/BlockCardEmails.tsx @@ -13,15 +13,12 @@ import TableRowActions from '../tables/TableRowActions'; import ModalLogEmailShow from '../../modals/ModalLogEmailShow'; import { ApiResponse, PaginationData } from '../../../props/ApiResponses'; import usePushApiError from '../../../hooks/usePushApiError'; -import Paginator from '../../../modules/paginator/components/Paginator'; import { trimStart } from 'lodash'; import { extractText } from '../../../helpers/utils'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import useEmailLogService from '../../../services/EmailLogService'; import { useFileService } from '../../../services/FileService'; import Organization from '../../../props/models/Organization'; -import useConfigurableTable from '../../pages/vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../tables/TableTopScroller'; import { FilterModel } from '../../../modules/filter_next/types/FilterParams'; import FormGroup from '../forms/elements/FormGroup'; @@ -56,8 +53,6 @@ export default function BlockCardEmails({ per_page: paginatorService.getPerPage(paginatorKey), }); - const { headElement, configsElement } = useConfigurableTable(emailLogService.getColumns()); - const exportEmailLog = useCallback( (emailLog: EmailLog) => { emailLogService @@ -135,92 +130,66 @@ export default function BlockCardEmails({ - -
-
- {configsElement} - - - - {headElement} - - - {emailLogs?.data.map((emailLog) => ( - - - - - - - - ))} - -
- - -
{emailLog.subject}
-
- {strLimit( - trimStart( - extractText(emailLog.content).trim(), - emailLog.subject, - ).trim(), - 64, - )} -
-
-
- {emailLog.to_address || } -
-
{emailLog.to_name || }
-
-
- {emailLog.from_address || } -
-
{emailLog.from_name || }
-
- ( - - )} - /> -
-
-
-
- {emailLogs?.meta && ( -
- -
- )} + + {emailLogs?.data?.map((emailLog) => ( + + + + + +
{emailLog.subject}
+
+ {strLimit(trimStart(extractText(emailLog.content).trim(), emailLog.subject).trim(), 64)} +
+ + +
+ {emailLog.to_address || } +
+
{emailLog.to_name || }
+ + +
+ {emailLog.from_address || } +
+
{emailLog.from_name || }
+ + + ( +
+ { + openEmail(emailLog); + close(); + }}> + + Bekijken + + { + exportEmailLog(emailLog); + close(); + }}> + + Download + +
+ )} + /> + + + ))}
); diff --git a/react/src/dashboard/components/elements/block-card-notes/BlockCardNotes.tsx b/react/src/dashboard/components/elements/block-card-notes/BlockCardNotes.tsx index f503045c2..192adef87 100644 --- a/react/src/dashboard/components/elements/block-card-notes/BlockCardNotes.tsx +++ b/react/src/dashboard/components/elements/block-card-notes/BlockCardNotes.tsx @@ -1,7 +1,6 @@ import FormValuesModel from '../../../types/FormValuesModel'; import { useCallback, useEffect, useState } from 'react'; import { ApiResponse, ApiResponseSingle, PaginationData } from '../../../props/ApiResponses'; -import Paginator from '../../../modules/paginator/components/Paginator'; import React from 'react'; import useOpenModal from '../../../hooks/useOpenModal'; import ModalDangerZone from '../../modals/ModalDangerZone'; @@ -16,9 +15,7 @@ import useTranslate from '../../../hooks/useTranslate'; import LoaderTableCard from '../loader-table-card/LoaderTableCard'; import TableRowActions from '../tables/TableRowActions'; import usePushApiError from '../../../hooks/usePushApiError'; -import useConfigurableTable from '../../pages/vouchers/hooks/useConfigurableTable'; import { useOrganizationService } from '../../../services/OrganizationService'; -import TableTopScroller from '../tables/TableTopScroller'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { FilterModel } from '../../../modules/filter_next/types/FilterParams'; @@ -53,8 +50,6 @@ export default function BlockCardNotes({ per_page: paginatorService.getPerPage(paginatorKey), }); - const { headElement, configsElement } = useConfigurableTable(organizationService.getNoteColumns()); - const updateNotes = useCallback(() => { setProgress(0); @@ -127,7 +122,7 @@ export default function BlockCardNotes({
- {translate('notes.header.title')}({notes.meta.total}) + {translate('notes.header.title')}({notes?.meta?.total})
{showCreate && ( @@ -139,68 +134,47 @@ export default function BlockCardNotes({
- -
-
- {configsElement} - - - - {headElement} - - - {notes.data?.map((note) => ( - - - - - - - - - ))} - -
{note.id}{note.created_at_locale}{note.employee.email} - {note.description?.split('\n').map((line: string, index) => ( -
- {line} -
- ))} -
- {note.employee.identity_address === identity.address && ( - ( -
-
{ - e?.close(); - onDeleteNote(note); - }} - data-dusk="deleteNoteBtn"> - - Verwijderen -
-
- )} - /> - )} -
-
-
-
- - {notes?.meta && ( -
- -
- )} + + {notes?.data?.map((note) => ( + + {note.id} + {note.created_at_locale} + {note.employee.email} + + {note.description?.split('\n').map((line: string, index) => ( +
+ {line} +
+ ))} + + + + {note.employee.identity_address === identity.address && ( + ( +
+
{ + e?.close(); + onDeleteNote(note); + }} + data-dusk="deleteNoteBtn"> + + Verwijderen +
+
+ )} + /> + )} + + + ))}
); diff --git a/react/src/dashboard/components/elements/block-reimbursement-categories/BlockReimbursementCategories.tsx b/react/src/dashboard/components/elements/block-reimbursement-categories/BlockReimbursementCategories.tsx index 96ede7a8d..426dc0f16 100644 --- a/react/src/dashboard/components/elements/block-reimbursement-categories/BlockReimbursementCategories.tsx +++ b/react/src/dashboard/components/elements/block-reimbursement-categories/BlockReimbursementCategories.tsx @@ -1,7 +1,6 @@ import React, { useCallback, useEffect, useState } from 'react'; import { PaginationData } from '../../../props/ApiResponses'; import ReimbursementCategory from '../../../props/models/ReimbursementCategory'; -import Paginator from '../../../modules/paginator/components/Paginator'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; import useOpenModal from '../../../hooks/useOpenModal'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; @@ -14,8 +13,6 @@ import useTranslate from '../../../hooks/useTranslate'; import LoadingCard from '../loading-card/LoadingCard'; import LoaderTableCard from '../loader-table-card/LoaderTableCard'; import usePushApiError from '../../../hooks/usePushApiError'; -import useConfigurableTable from '../../pages/vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../tables/TableTopScroller'; import TableRowActions from '../tables/TableRowActions'; import classNames from 'classnames'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; @@ -48,8 +45,6 @@ export default function BlockReimbursementCategories({ per_page: paginatorService.getPerPage(paginatorKey), }); - const { headElement, configsElement } = useConfigurableTable(reimbursementCategoryService.getColumns()); - const fetchReimbursementCategories = useCallback(() => { setLoading(true); setProgress(0); @@ -129,7 +124,7 @@ export default function BlockReimbursementCategories({
{categories?.meta - ? `Declaratie categorieën (${categories?.meta.total})` + ? `Declaratie categorieën (${categories?.meta?.total})` : `Declaratie categorieën`}
@@ -149,71 +144,47 @@ export default function BlockReimbursementCategories({ -
-
- {configsElement} - - - - {headElement} - - - {categories?.data.map((reimbursementCategory) => ( - - - - - - - - ))} - -
{reimbursementCategory.name}{reimbursementCategory.organization.name}{reimbursementCategory.reimbursements_count} - ( - - )} - /> -
-
-
-
- - {categories?.meta.total > 0 && ( -
- -
- )} + empty={categories?.data?.length === 0} + emptyTitle={'Er zijn momenteel geen declaratie categorieën.'} + columns={reimbursementCategoryService.getColumns()} + paginator={{ key: paginatorKey, data: categories, filterValues, filterUpdate }}> + {categories?.data?.map((reimbursementCategory) => ( + + {reimbursementCategory.name} + {reimbursementCategory.organization.name} + {reimbursementCategory.reimbursements_count} + + + ( + + )} + /> + + + ))}
); diff --git a/react/src/dashboard/components/elements/card-table/CardTable.tsx b/react/src/dashboard/components/elements/card-table/CardTable.tsx deleted file mode 100644 index b4a8c7426..000000000 --- a/react/src/dashboard/components/elements/card-table/CardTable.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { ReactNode } from 'react'; -import TableTopScroller from '../tables/TableTopScroller'; -import useConfigurableTable, { ConfigurableTableColumn } from '../../pages/vouchers/hooks/useConfigurableTable'; -import { FilterModel, FilterScope } from '../../../modules/filter_next/types/FilterParams'; - -export default function CardTable({ - columns, - options, - children, -}: { - columns: Array; - options?: { - sortable?: boolean; - sortableExclude?: Array; - filter?: FilterScope; - trPrepend?: ReactNode; - hasTooltips?: boolean; - }; - children: ReactNode | ReactNode[]; -}) { - const { headElement, configsElement } = useConfigurableTable(columns, options); - - return ( -
- {configsElement} - - - - {headElement} - {children} -
-
-
- ); -} diff --git a/react/src/dashboard/components/elements/empty-card/EmptyCard.tsx b/react/src/dashboard/components/elements/empty-card/EmptyCard.tsx index 56cce15d1..b05a2540c 100644 --- a/react/src/dashboard/components/elements/empty-card/EmptyCard.tsx +++ b/react/src/dashboard/components/elements/empty-card/EmptyCard.tsx @@ -1,10 +1,12 @@ import React, { Fragment, ReactNode, useMemo } from 'react'; import classNames from 'classnames'; -import { NavLink } from 'react-router'; +import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import StateNavLink from '../../../modules/state_router/StateNavLink'; -interface EmptyButtonType { - to?: string; +export interface EmptyButtonType { type?: 'default' | 'primary' | 'danger'; + state?: DashboardRoutes; + stateParams?: object; icon?: string; text?: string; dusk?: string; @@ -20,8 +22,8 @@ export default function EmptyCard({ imageIconSvg, textAlign = 'center', button = null, - buttons = [], type = 'card', + actions, }: { title?: string; description?: string; @@ -30,8 +32,8 @@ export default function EmptyCard({ imageIconSvg?: ReactNode; textAlign?: 'left' | 'center' | 'right'; button?: EmptyButtonType; - buttons?: Array; type?: 'card' | 'card-section' | 'card-section-content'; + actions?: ReactNode; }) { const descriptionLines = useMemo(() => { return description?.split('\n') || []; @@ -95,31 +97,31 @@ export default function EmptyCard({ )} - {button && ( -
-
- {[button, ...buttons].map((button, index) => ( - - {button.icon && (!button.iconPosition || button.iconPosition == 'start') && ( - - )} - {button.text} - {button.icon && button.iconPosition == 'end' && ( - - )} - - ))} -
+ {(button || actions) && ( +
+ {button && ( + + {button.icon && (!button.iconPosition || button.iconPosition == 'start') && ( + + )} + {button.text} + {button.icon && button.iconPosition == 'end' && ( + + )} + + )} + + {actions}
)}
diff --git a/react/src/dashboard/components/elements/forms/elements/FormGroup.tsx b/react/src/dashboard/components/elements/forms/elements/FormGroup.tsx index 3a02bd77b..65cd77461 100644 --- a/react/src/dashboard/components/elements/forms/elements/FormGroup.tsx +++ b/react/src/dashboard/components/elements/forms/elements/FormGroup.tsx @@ -36,7 +36,7 @@ export default function FormGroup({ className, )}> {label && ( -
-
{funds.meta.total} resultaten
+
{funds?.meta?.total} resultaten
diff --git a/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotificationSend.tsx b/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotificationSend.tsx index 11cae502c..7bb80bf14 100644 --- a/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotificationSend.tsx +++ b/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotificationSend.tsx @@ -12,7 +12,6 @@ import { useNavigateState } from '../../../modules/state_router/Router'; import { hasPermission } from '../../../helpers/utils'; import SelectControl from '../../elements/select-control/SelectControl'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; -import Paginator from '../../../modules/paginator/components/Paginator'; import SponsorIdentity, { SponsorIdentityCounts } from '../../../props/models/Sponsor/SponsorIdentity'; import Fund from '../../../props/models/Fund'; import { useFundService } from '../../../services/FundService'; @@ -24,10 +23,9 @@ import SystemNotification from '../../../props/models/SystemNotification'; import useFundIdentitiesExporter from '../../../services/exporters/useFundIdentitiesExporter'; import useTranslate from '../../../hooks/useTranslate'; import EmptyCard from '../../elements/empty-card/EmptyCard'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; import usePushApiError from '../../../hooks/usePushApiError'; import { Permission } from '../../../props/models/Organization'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableEmptyValue from '../../elements/table-empty-value/TableEmptyValue'; import ImplementationsRootBreadcrumbs from '../implementations/elements/ImplementationsRootBreadcrumbs'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; @@ -157,14 +155,6 @@ export default function ImplementationNotificationSend() { order_dir: 'desc', }); - const { headElement, configsElement } = useConfigurableTable( - implementationNotificationsService.getIdentitiesColumns(), - { - sortable: true, - filter: identitiesFilter, - }, - ); - const exportIdentities = useCallback(() => { fundIdentitiesExporter.exportData(activeOrganization.id, fund.id, { ...identitiesFilterValuesActive, @@ -605,55 +595,35 @@ export default function ImplementationNotificationSend() { )} - {showIdentities && identities.meta.total > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {identities.data.map((identity) => ( - - - - - - - - - ))} - -
{identity.id}{identity.email}{identity.count_vouchers}{identity.count_vouchers_active}{identity.count_vouchers_active_with_balance} - -
-
-
-
- )} - - {showIdentities && identities.meta.total == 0 && ( - - )} - - {showIdentities && identities && identities?.meta && ( -
- -
+ columns={implementationNotificationsService.getIdentitiesColumns()} + tableOptions={{ sortable: true, filter: identitiesFilter }} + paginator={{ + key: perPageKey, + data: identities, + filterValues: identitiesFilterValues, + filterUpdate: identitiesFilterUpdate, + }}> + {identities?.data?.map((identity) => ( + + {identity.id} + {identity.email} + {identity.count_vouchers} + {identity.count_vouchers_active} + {identity.count_vouchers_active_with_balance} + + + + + ))} + )}
diff --git a/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotifications.tsx b/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotifications.tsx index a227321ad..3ec407202 100644 --- a/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotifications.tsx +++ b/react/src/dashboard/components/pages/implementation-notifications/ImplementationNotifications.tsx @@ -11,13 +11,12 @@ import SystemNotification from '../../../props/models/SystemNotification'; import useTranslate from '../../../hooks/useTranslate'; import usePushApiError from '../../../hooks/usePushApiError'; import Label from '../../elements/image_cropper/Label'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableRowActions from '../../elements/tables/TableRowActions'; import InfoBox from '../../elements/info-box/InfoBox'; import { useParams } from 'react-router'; import ImplementationsRootBreadcrumbs from '../implementations/elements/ImplementationsRootBreadcrumbs'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; export default function ImplementationNotifications() { const { id } = useParams(); @@ -51,7 +50,7 @@ export default function ImplementationNotifications() { const groupOrder = Object.keys(groupLabels); - const list = notifications.data.map((notification) => ({ + const list = notifications?.data?.map((notification) => ({ ...notification, state: implementationNotificationsService.notificationToStateLabel(notification), title: translate(`system_notifications.notifications.${notification.key}.title`), @@ -66,8 +65,6 @@ export default function ImplementationNotifications() { .sort((a, b) => groupOrder.indexOf(a.group) - groupOrder.indexOf(b.group)); }, [translate, groupLabels, notifications, implementationNotificationsService]); - const { headElement, configsElement } = useConfigurableTable(implementationNotificationsService.getColumns()); - const notificationIconColor = useCallback( (notification: SystemNotification, type: 'database' | 'mail' | 'push') => { const templateChanged = notification.templates.filter((item) => item.type == type).length > 0; @@ -204,110 +201,82 @@ export default function ImplementationNotifications() {
{notificationGroup.groupLabel}
-
-
- {configsElement} - - - - {headElement} - - - {notificationGroup.notifications.map((notification) => ( - - + + - - - - - - + + ))} - -
-
- {notification.editable ? ( - - {' '} - - ) : ( - - )} - {notification.title} + + {notificationGroup.notifications.map((notification) => ( +
+
+ {notification.editable ? ( + + ) : ( + + )} + {notification.title} +
+ {notification.description} +
+
+ {channels.map((channel, index) => ( + +
+
+ {notificationIconTooltip(notification, channel).heading}
- {notification.description} -
-
- {channels.map((channel, index) => ( - -
-
- { - notificationIconTooltip( - notification, - channel, - ).heading - } -
-
- { - notificationIconTooltip( - notification, - channel, - ).text - } -
-
-
- ))} +
+ {notificationIconTooltip(notification, channel).text}
-
- {notification.state?.state === 'active' && ( - - )} - - {notification.state?.state === 'inactive' && ( - - )} - - {notification.state?.state === 'active_partly' && ( - - )} - - {!['active', 'inactive', 'active_partly'].includes( - notification.state?.state, - ) && ( - - )} - - ( -
- - - Bekijken - -
- )} - /> -
-
-
-
+
+ + + + {notification.state?.state === 'active' && ( + + )} + + {notification.state?.state === 'inactive' && ( + + )} + + {notification.state?.state === 'active_partly' && ( + + )} + + {!['active', 'inactive', 'active_partly'].includes(notification.state?.state) && ( + + )} + + + + ( +
+ + + Bekijken + +
+ )} + /> + + + ))} + ))} diff --git a/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationEditor.tsx b/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationEditor.tsx index 8035a5ab2..2e481715d 100644 --- a/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationEditor.tsx +++ b/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationEditor.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useMemo, useState } from 'react'; +import classNames from 'classnames'; import ToggleControl from '../../../elements/forms/controls/ToggleControl'; import useImplementationNotificationService from '../../../../services/ImplementationNotificationService'; import { keyBy } from 'lodash'; @@ -131,8 +132,14 @@ export default function SystemNotificationEditor({ return (
-
-
+
+
{notification.title} {translate(`system_notifications.notifications.${notification.key}.title`)} @@ -154,7 +161,7 @@ export default function SystemNotificationEditor({
{funds && funds.length > 0 && ( -
+
@@ -177,7 +184,7 @@ export default function SystemNotificationEditor({
)} -
+
diff --git a/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationTemplateEditor.tsx b/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationTemplateEditor.tsx index 26c02e7e4..b86ea175a 100644 --- a/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationTemplateEditor.tsx +++ b/react/src/dashboard/components/pages/implementation-notifications/elements/SystemNotificationTemplateEditor.tsx @@ -1,4 +1,5 @@ import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import classNames from 'classnames'; import FormError from '../../../elements/forms/errors/FormError'; import MarkdownEditor from '../../../elements/forms/markdown-editor/MarkdownEditor'; import ToggleControl from '../../../elements/forms/controls/ToggleControl'; @@ -373,7 +374,8 @@ export default function SystemNotificationTemplateEditor({
) : ( -
+
{header.title} @@ -386,7 +388,10 @@ export default function SystemNotificationTemplateEditor({
+ className={classNames( + 'card-section', + !((enable && notification.enable_all) || compose) && 'card-section-danger', + )}>
{!compose && notification.editable && !edit && (
@@ -499,7 +505,7 @@ export default function SystemNotificationTemplateEditor({ {type != 'mail' ? (
-
+
{!edit && type === 'push' && (
{template.content || 'Geen bericht'}
)} diff --git a/react/src/dashboard/components/pages/implementation-pages/ImplementationPages.tsx b/react/src/dashboard/components/pages/implementation-pages/ImplementationPages.tsx index 92bd3e8cf..b325c290e 100644 --- a/react/src/dashboard/components/pages/implementation-pages/ImplementationPages.tsx +++ b/react/src/dashboard/components/pages/implementation-pages/ImplementationPages.tsx @@ -10,8 +10,6 @@ import ImplementationPage from '../../../props/models/ImplementationPage'; import useTranslate from '../../../hooks/useTranslate'; import { keyBy } from 'lodash'; import usePushApiError from '../../../hooks/usePushApiError'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableRowActions from '../../elements/tables/TableRowActions'; import classNames from 'classnames'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; @@ -19,6 +17,7 @@ import useImplementationService from '../../../services/ImplementationService'; import { useParams } from 'react-router'; import ImplementationsRootBreadcrumbs from '../implementations/elements/ImplementationsRootBreadcrumbs'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; export default function ImplementationPages() { const { id } = useParams(); @@ -40,8 +39,6 @@ export default function ImplementationPages() { const [pagesByKey, setPagesByKey] = useState<{ [key: string]: ImplementationPage }>(null); - const { headElement, configsElement } = useConfigurableTable(implementationPageService.getColumns()); - const fetchPages = useCallback(() => { if (!implementation) return; @@ -112,119 +109,97 @@ export default function ImplementationPages() {
{translate('implementation_edit.implementations_table.title')}
-
-
- {configsElement} - - - - {headElement} - - - {pageTypes.map((pageType) => ( - - - {pageType.type === 'static' && ( - - )} - {pageType.type === 'extra' && ( - - )} - {pageType.type === 'element' && ( - - )} - - {pageType.blocks ? ( - + + {pageTypes.map((pageType) => ( + + + {pageType.type === 'static' && } + {pageType.type === 'extra' && } + {pageType.type === 'element' && } + + {pageType.blocks ? ( + + ) : ( + + )} + + + + + + + {translate('implementation_edit.implementations_table.labels.edit')} + )} - - - - ))} - -
{translate(`implementation_edit.labels.${pageType.key}`)}Standaard paginaOptionele paginaPagina element{pagesByKey?.[pageType.key]?.blocks?.length || 'None'}{translate(`implementation_edit.labels.${pageType.key}`)}Standaard paginaOptionele paginaPagina element{pagesByKey?.[pageType.key]?.blocks?.length || 'None'}Niet beschikbaar{pagesByKey?.[pageType.key]?.state == 'public' ? 'Ja' : 'Nee'} + {(pagesByKey?.[pageType.key]?.id && pagesByKey?.[pageType.key]?.state === 'public') || + pageType.type == 'static' ? ( + + Bekijk + + + ) : ( +
-
+ )} +
+ ( +
+ {pagesByKey?.[pageType.key]?.id ? ( + + + {translate('implementation_edit.implementations_table.labels.edit')} + ) : ( -
Niet beschikbaar{pagesByKey?.[pageType.key]?.state == 'public' ? 'Ja' : 'Nee'} - {(pagesByKey?.[pageType.key]?.id && - pagesByKey?.[pageType.key]?.state === 'public') || - pageType.type == 'static' ? ( - - Bekijk - - - ) : ( -
-
+ -
- ( -
- {pagesByKey?.[pageType.key]?.id ? ( - - - {translate( - 'implementation_edit.implementations_table.labels.edit', - )} - - ) : ( - - - {translate( - 'implementation_edit.implementations_table.labels.edit', - )} - - )} - - { - deletePage(pagesByKey?.[pageType.key]); - close(); - }}> - - Verwijderen - -
- )} - /> -
-
-
-
+ onClick={() => { + deletePage(pagesByKey?.[pageType.key]); + close(); + }}> + + Verwijderen + +
+ )} + /> + + + ))} +
); diff --git a/react/src/dashboard/components/pages/implementation-pre-check/ImplementationPreCheck.tsx b/react/src/dashboard/components/pages/implementation-pre-check/ImplementationPreCheck.tsx index ff5c0992e..2bd38a0bc 100644 --- a/react/src/dashboard/components/pages/implementation-pre-check/ImplementationPreCheck.tsx +++ b/react/src/dashboard/components/pages/implementation-pre-check/ImplementationPreCheck.tsx @@ -9,7 +9,7 @@ import { PaginationData, ResponseError } from '../../../props/ApiResponses'; import type PreCheck from '../../../props/models/PreCheck'; import PreCheckStepEditor from './elements/PreCheckStepEditor'; import EmptyCard from '../../elements/empty-card/EmptyCard'; -import { getStateRouteUrl, useNavigateState } from '../../../modules/state_router/Router'; +import { useNavigateState } from '../../../modules/state_router/Router'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import PhotoSelector from '../../elements/photo-selector/PhotoSelector'; import useImplementationService from '../../../services/ImplementationService'; @@ -383,9 +383,8 @@ export default function ImplementationPreCheck() { text: 'Ga naar de fondsenpagina', type: 'primary', icon: 'plus', - to: getStateRouteUrl(DashboardRoutes.FUND_CREATE, { - organizationId: activeOrganization.id, - }), + state: DashboardRoutes.FUND_CREATE, + stateParams: { organizationId: activeOrganization.id }, }} /> )} diff --git a/react/src/dashboard/components/pages/implementation-pre-check/cards/PreCheckExclusionsCard.tsx b/react/src/dashboard/components/pages/implementation-pre-check/cards/PreCheckExclusionsCard.tsx index 087584d25..36445507e 100644 --- a/react/src/dashboard/components/pages/implementation-pre-check/cards/PreCheckExclusionsCard.tsx +++ b/react/src/dashboard/components/pages/implementation-pre-check/cards/PreCheckExclusionsCard.tsx @@ -1,6 +1,5 @@ import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import TableRowActions from '../../../elements/tables/TableRowActions'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; import React, { useCallback, useMemo, useState } from 'react'; import Fund from '../../../../props/models/Fund'; import ModalPreCheckEditFundExclusions from '../../../modals/ModalPreCheckEditFundExclusions'; @@ -12,9 +11,7 @@ import usePushApiError from '../../../../hooks/usePushApiError'; import Implementation from '../../../../props/models/Implementation'; import usePreCheckService from '../../../../services/PreCheckService'; import { strLimit } from '../../../../helpers/string'; -import PreCheckFundsLogo from '../../../../../../assets/forus-platform/resources/_platform-common/assets/img/pre-check-funds-logo.svg'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function PreCheckExclusionsCard({ funds, @@ -35,8 +32,6 @@ export default function PreCheckExclusionsCard({ const preCheckService = usePreCheckService(); - const { headElement, configsElement } = useConfigurableTable(preCheckService.getExclusionColumns()); - const excludedFunds = useMemo(() => { return funds?.filter((fund) => fund.pre_check_excluded || fund.pre_check_note) || []; }, [funds]); @@ -123,63 +118,50 @@ export default function PreCheckExclusionsCard({
- {excludedFunds?.length > 0 ? ( -
-
- {configsElement} - - - - {headElement} - - - {excludedFunds.map((fund) => ( - - - - - - - ))} - -
{fund.name}{fund.pre_check_excluded ? 'Ja' : 'Nee'} - {!fund.pre_check_excluded && fund.pre_check_note ? ( - strLimit(fund.pre_check_note, 500) - ) : ( - - )} - - ( - - )} - /> -
-
-
-
- ) : ( - } type={'card-section'} /> - )} + + {excludedFunds.map((fund) => ( + + {fund.name} + {fund.pre_check_excluded ? 'Ja' : 'Nee'} + + {!fund.pre_check_excluded && fund.pre_check_note ? ( + strLimit(fund.pre_check_note, 500) + ) : ( + + )} + + + ( + + )} + /> + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/implementations-edit/ImplementationSocialMediaLinks.tsx b/react/src/dashboard/components/pages/implementations-edit/ImplementationSocialMediaLinks.tsx index c92ea83e0..97166361e 100644 --- a/react/src/dashboard/components/pages/implementations-edit/ImplementationSocialMediaLinks.tsx +++ b/react/src/dashboard/components/pages/implementations-edit/ImplementationSocialMediaLinks.tsx @@ -6,7 +6,6 @@ import useSetProgress from '../../../hooks/useSetProgress'; import { PaginationData, ResponseError } from '../../../props/ApiResponses'; import useImplementationService from '../../../services/ImplementationService'; import Implementation from '../../../props/models/Implementation'; -import Paginator from '../../../modules/paginator/components/Paginator'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; import useOpenModal from '../../../hooks/useOpenModal'; import ModalDangerZone from '../../modals/ModalDangerZone'; @@ -18,13 +17,11 @@ import useTranslate from '../../../hooks/useTranslate'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { NumberParam } from 'use-query-params'; import { useParams } from 'react-router'; -import EmptyCard from '../../elements/empty-card/EmptyCard'; import usePushApiError from '../../../hooks/usePushApiError'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableRowActions from '../../elements/tables/TableRowActions'; import ImplementationsRootBreadcrumbs from '../implementations/elements/ImplementationsRootBreadcrumbs'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; export default function ImplementationSocialMediaLinks() { const { id } = useParams(); @@ -59,8 +56,6 @@ export default function ImplementationSocialMediaLinks() { }, ); - const { headElement, configsElement } = useConfigurableTable(implementationService.getSocialMediaColumns()); - const fetchImplementation = useCallback(() => { implementationService .read(activeOrganization.id, parseInt(id)) @@ -101,7 +96,7 @@ export default function ImplementationSocialMediaLinks() { organization={activeOrganization} implementation={implementation} socialMedia={socialMedia} - usedTypes={socialMedias.data.map((socialMedia) => socialMedia.type)} + usedTypes={socialMedias?.data?.map((socialMedia) => socialMedia.type)} onSubmit={() => fetchSocialMedias()} /> )); @@ -171,7 +166,7 @@ export default function ImplementationSocialMediaLinks() {
-
{`${translate('implementation_edit.labels.cms_media_links')} (${socialMedias.meta.total})`}
+
{`${translate('implementation_edit.labels.cms_media_links')} (${socialMedias?.meta?.total})`}
@@ -186,72 +181,45 @@ export default function ImplementationSocialMediaLinks() {
- {socialMedias.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {socialMedias.data.map((socialMedia) => ( - - - - - - - - - ))} - -
-
-
{socialMedia.type_locale}{socialMedia.url}{socialMedia.title || '-'} - ( - - )} - /> -
-
-
-
- )} - - {socialMedias.meta.total == 0 && ( - - )} - - {socialMedias?.meta && ( -
- -
- )} + + {socialMedias?.data?.map((socialMedia) => ( + + +
+ + {socialMedia.type_locale} + {socialMedia.url} + {socialMedia.title || '-'} + + + ( + + )} + /> + + + ))} +
); diff --git a/react/src/dashboard/components/pages/implementations/Implementations.tsx b/react/src/dashboard/components/pages/implementations/Implementations.tsx index bee942582..c7a6fbbda 100644 --- a/react/src/dashboard/components/pages/implementations/Implementations.tsx +++ b/react/src/dashboard/components/pages/implementations/Implementations.tsx @@ -10,7 +10,6 @@ import LoadingCard from '../../elements/loading-card/LoadingCard'; import usePushApiError from '../../../hooks/usePushApiError'; import { Permission } from '../../../props/models/Organization'; import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableRowActions from '../../elements/tables/TableRowActions'; import TableEntityMain from '../../elements/tables/elements/TableEntityMain'; import TableEmptyValue from '../../elements/table-empty-value/TableEmptyValue'; @@ -19,6 +18,7 @@ import ImplementationsRootBreadcrumbs from './elements/ImplementationsRootBreadc import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { NumberParam, StringParam } from 'use-query-params'; import useSetProgress from '../../../hooks/useSetProgress'; +import { ConfigurableTableColumn } from '../vouchers/hooks/useConfigurableTable'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; export default function Implementations() { @@ -31,6 +31,11 @@ export default function Implementations() { const [paginatorKey] = useState('implementations'); const [implementations, setImplementations] = useState>(null); + const columns: Array = [ + { key: 'name', label: 'Webshop' }, + { key: 'url', label: 'Website url' }, + { key: 'actions', label: 'Acties' }, + ]; const [filterValues, filterValuesActive, filterUpdate] = useFilterNext<{ q: string; @@ -96,174 +101,143 @@ export default function Implementations() { loading={!implementations} empty={implementations?.meta?.total === 0} emptyTitle={'Geen webshops'} - emptyDescription={'Geen webshops gevonden.'}> -
-
- - - - - - - - - - - {implementations.data.map((implementation: Implementation) => { - const organizationId = - implementation.organization_id || activeOrganization.id; - const implementationLogo: Media = { - identity_address: '', - original_name: '', - type: '', - ext: '', - uid: `implementation-logo-${implementation.id}`, - sizes: { - thumbnail: implementation.logo || '', - }, - }; - - return ( + emptyDescription={'Geen webshops gevonden.'} + columns={columns} + tableOptions={{ hasTooltips: false }} + paginator={{ key: paginatorKey, data: implementations, filterValues, filterUpdate }}> + {implementations?.data?.map((implementation: Implementation) => { + const organizationId = implementation.organization_id || activeOrganization.id; + + const implementationLogo: Media = { + identity_address: '', + original_name: '', + type: '', + ext: '', + uid: `implementation-logo-${implementation.id}`, + sizes: { + thumbnail: implementation.logo || '', + }, + }; + + return ( + + + + - - + params={{ + id: implementation.id, + organizationId, + }} + className="dropdown-item" + onClick={e.close}> + Bekijken - ); - })} - -
WebshopWebsite urlActies
+ + + {implementation.url_webshop ? ( + e.stopPropagation()}> + {implementation.url_webshop} + + ) : ( + + )} + + ( +
-
- - - {implementation.url_webshop ? ( - e.stopPropagation()}> - {implementation.url_webshop} - - ) : ( - - )} - - ( -
- - {' '} - Bekijken - - - {activeOrganization.allow_translations && - hasPermission( - activeOrganization, - Permission.MANAGE_IMPLEMENTATION, - ) && ( - - - Vertalingen beheren - - )} - - {hasPermission( - activeOrganization, - Permission.MANAGE_IMPLEMENTATION, - ) && ( - - - Cookiemelding beheren - - )} - - {hasPermission( - activeOrganization, - Permission.MANAGE_IMPLEMENTATION, - ) && ( - - - E-mailinstellingen - - )} - - {hasPermission( - activeOrganization, - Permission.MANAGE_IMPLEMENTATION, - ) && ( - - - DigiD-instellingen - - )} -
- )} - /> -
-
-
-
- {implementations?.meta?.total > 0 && ( -
-
-
- {implementations?.meta?.total || 0} resultaten -
-
-
- )} + {activeOrganization.allow_translations && + hasPermission( + activeOrganization, + Permission.MANAGE_IMPLEMENTATION, + ) && ( + + + Vertalingen beheren + + )} + + {hasPermission( + activeOrganization, + Permission.MANAGE_IMPLEMENTATION, + ) && ( + + + Cookiemelding beheren + + )} + + {hasPermission( + activeOrganization, + Permission.MANAGE_IMPLEMENTATION, + ) && ( + + + E-mailinstellingen + + )} + + {hasPermission( + activeOrganization, + Permission.MANAGE_IMPLEMENTATION, + ) && ( + + + DigiD-instellingen + + )} +
+ )} + /> + + + ); + })}
diff --git a/react/src/dashboard/components/pages/offices-edit/elements/OfficesForm.tsx b/react/src/dashboard/components/pages/offices-edit/elements/OfficesForm.tsx index bd14ca451..d7be9ed14 100644 --- a/react/src/dashboard/components/pages/offices-edit/elements/OfficesForm.tsx +++ b/react/src/dashboard/components/pages/offices-edit/elements/OfficesForm.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import PhotoSelector from '../../../elements/photo-selector/PhotoSelector'; import useFormBuilder from '../../../../hooks/useFormBuilder'; import FormError from '../../../elements/forms/errors/FormError'; @@ -197,9 +198,13 @@ export default function OfficesForm({ organization, id }: { organization: Organi
setShowBranchNumberTooltip(!showBranchNumberTooltip)}>
@@ -234,9 +239,13 @@ export default function OfficesForm({ organization, id }: { organization: Organi
setShowBranchNameTooltip(!showBranchNameTooltip)}>
@@ -271,9 +280,13 @@ export default function OfficesForm({ organization, id }: { organization: Organi
setShowBranchIdTooltip(!showBranchIdTooltip)}>
diff --git a/react/src/dashboard/components/pages/offices-edit/elements/ScheduleControl.tsx b/react/src/dashboard/components/pages/offices-edit/elements/ScheduleControl.tsx index 5cd64cea8..cf0b7a4d2 100644 --- a/react/src/dashboard/components/pages/offices-edit/elements/ScheduleControl.tsx +++ b/react/src/dashboard/components/pages/offices-edit/elements/ScheduleControl.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import classNames from 'classnames'; import useOfficeService from '../../../../services/OfficeService'; import FormError from '../../../elements/forms/errors/FormError'; import UIControlCheckbox from '../../../elements/forms/ui-controls/UIControlCheckbox'; @@ -285,7 +286,7 @@ export default function ScheduleControl({ {weekDaysKeys.map((weekDayNumber) => ( - = 5 ? 'weekend' : ''}`}> + = 5 && 'weekend')}> {weekDays[weekDayNumber]} @@ -415,7 +416,7 @@ export default function ScheduleControl({
-
= 5 ? 'text-danger' : ''}`}> +
= 5 && 'text-danger')}> {weekDays[weekDayNumber]}
{scheduleData[weekDayNumber].is_closed && ( diff --git a/react/src/dashboard/components/pages/offices/Offices.tsx b/react/src/dashboard/components/pages/offices/Offices.tsx index eeb2826ed..4f7ec844c 100644 --- a/react/src/dashboard/components/pages/offices/Offices.tsx +++ b/react/src/dashboard/components/pages/offices/Offices.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import LoadingCard from '../../elements/loading-card/LoadingCard'; import { NavLink, useNavigate } from 'react-router'; @@ -175,16 +176,21 @@ export default function Offices() {
{translate('offices.labels.business_type')}
-
+
{organization.business_type?.name || 'Geen data'}
{translate('offices.labels.mail')}
+ className={classNames( + 'keyvalue-value', + !organization.email ? 'text-muted' : 'text-primary-light', + )}> {organization.email || 'Geen data'}
@@ -194,19 +200,19 @@ export default function Offices() {
KVK
-
+
{organization.kvk || 'Geen data'}
BTW
-
+
{organization.btw || 'Geen data'}
IBAN
-
+
{organization.iban || 'Geen data'}
@@ -381,7 +387,8 @@ export default function Offices() { description={'Je hebt momenteel geen vestigingen.'} button={{ text: 'Vestiging toevoegen', - to: getStateRouteUrl(DashboardRoutes.OFFICE_CREATE, { organizationId: organization.id }), + state: DashboardRoutes.OFFICE_CREATE, + stateParams: { organizationId: organization.id }, }} /> )} diff --git a/react/src/dashboard/components/pages/organizations-funds-edit/OrganizationsFundsEdit.tsx b/react/src/dashboard/components/pages/organizations-funds-edit/OrganizationsFundsEdit.tsx index b2886e44e..44e640aa2 100644 --- a/react/src/dashboard/components/pages/organizations-funds-edit/OrganizationsFundsEdit.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-edit/OrganizationsFundsEdit.tsx @@ -1,4 +1,5 @@ import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import classNames from 'classnames'; import { useFundService } from '../../../services/FundService'; import useSetProgress from '../../../hooks/useSetProgress'; import Fund from '../../../props/models/Fund'; @@ -656,9 +657,13 @@ export default function OrganizationsFundsEdit() {
setShowInfoBlock(!showInfoBlock)}>
diff --git a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowFormulasCard.tsx b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowFormulasCard.tsx index 672341c40..75569cfff 100644 --- a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowFormulasCard.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowFormulasCard.tsx @@ -1,52 +1,35 @@ import React from 'react'; import Fund from '../../../../../props/models/Fund'; -import EmptyCard from '../../../../elements/empty-card/EmptyCard'; import TableDateTime from '../../../../elements/tables/elements/TableDateTime'; -import TableTopScroller from '../../../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../../../vouchers/hooks/useConfigurableTable'; import { useFundService } from '../../../../../services/FundService'; import TableEmptyValue from '../../../../elements/table-empty-value/TableEmptyValue'; +import LoaderTableCard from '../../../../elements/loader-table-card/LoaderTableCard'; export default function OrganizationsFundsShowFormulasCard({ fund }: { fund: Fund }) { const fundService = useFundService(); - const { headElement, configsElement } = useConfigurableTable(fundService.getFormulasColumns()); - return ( -
-
- {configsElement} - - - {fund.formulas?.length > 0 ? ( - - {headElement} - - - {fund.formulas.map((formula) => ( - - - - - - - - - - ))} - -
{formula.id}{formula.type}{formula.amount_locale}{formula.record_type_name || '-'} - - - - - -
- ) : ( - - )} -
-
-
+ + {fund.formulas?.map((formula) => ( + + {formula.id} + {formula.type} + {formula.amount_locale} + {formula.record_type_name || '-'} + + + + + + + + + + + ))} + ); } diff --git a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowStatisticsCard.tsx b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowStatisticsCard.tsx index 046af6665..ca8a14fb0 100644 --- a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowStatisticsCard.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/OrganizationsFundsShowStatisticsCard.tsx @@ -1,4 +1,5 @@ import React, { Fragment, useCallback, useMemo } from 'react'; +import classNames from 'classnames'; import Fund from '../../../../../props/models/Fund'; import EmptyCard from '../../../../elements/empty-card/EmptyCard'; import { useNavigateState } from '../../../../../modules/state_router/Router'; @@ -79,9 +80,12 @@ export default function OrganizationsFundsShowStatisticsCard({
inviteProvider(fund)}>
{translate('fund_card_sponsor.labels.providers')}
@@ -91,7 +95,12 @@ export default function OrganizationsFundsShowStatisticsCard({
{ navigateState(DashboardRoutes.CSV_VALIDATION, { organizationId: fund.organization_id }); }}> diff --git a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/tables/FundPhysicalCardTypesTable.tsx b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/tables/FundPhysicalCardTypesTable.tsx index 63d3a57d5..96b8a9271 100644 --- a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/tables/FundPhysicalCardTypesTable.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-details-card/tables/FundPhysicalCardTypesTable.tsx @@ -1,11 +1,8 @@ import { PaginationData } from '../../../../../../props/ApiResponses'; -import TableTopScroller from '../../../../../elements/tables/TableTopScroller'; import StateNavLink from '../../../../../../modules/state_router/StateNavLink'; import TableRowActions from '../../../../../elements/tables/TableRowActions'; -import Paginator from '../../../../../../modules/paginator/components/Paginator'; import LoaderTableCard from '../../../../../elements/loader-table-card/LoaderTableCard'; import React, { useCallback, useEffect, useState } from 'react'; -import useConfigurableTable from '../../../../vouchers/hooks/useConfigurableTable'; import usePaginatorService from '../../../../../../modules/paginator/services/usePaginatorService'; import Organization from '../../../../../../props/models/Organization'; import useTranslate from '../../../../../../hooks/useTranslate'; @@ -33,17 +30,12 @@ export default function FundPhysicalCardTypesTable({ fund, organization }: { fun const paginatorService = usePaginatorService(); const fundPhysicalCardTypeService = useFundPhysicalCardTypeService(); - const [, filterActiveValues, filterUpdate, filter] = useFilterNext<{ + const [filterValues, filterActiveValues, filterUpdate, filter] = useFilterNext<{ q: string; fund_id?: number; per_page?: number; }>({ q: '', fund_id: fund?.id, per_page: paginatorService.getPerPage(paginatorKey) }); - const { headElement, configsElement } = useConfigurableTable(fundPhysicalCardTypeService.getColumns(), { - sortable: true, - filter: filter, - }); - const fetchPhysicalCardTypes = useCallback(() => { setProgress(0); @@ -73,7 +65,7 @@ export default function FundPhysicalCardTypesTable({ fund, organization }: { fun organization, fund, null, - fundPhysicalCardTypes.data.map((type) => type.physical_card_type_id), + fundPhysicalCardTypes?.data?.map((type) => type.physical_card_type_id), fetchPhysicalCardTypes, ) } @@ -101,117 +93,83 @@ export default function FundPhysicalCardTypesTable({ fund, organization }: { fun loading={!fundPhysicalCardTypes?.meta} empty={fundPhysicalCardTypes?.meta?.total === 0} emptyTitle={'Geen fysieke passen'} - emptyDescription={'Er zijn momenteel geen fysieke passen.'}> -
-
- {configsElement} - - - - {headElement} - - - {fundPhysicalCardTypes?.data.map((cardType) => ( - - - - - - - - ))} - -
- - {cardType?.allow_physical_card_linking ? 'Ja' : 'Nee'}{cardType?.allow_physical_card_deactivation ? 'Ja' : 'Nee'}{cardType?.allow_physical_card_requests ? 'Ja' : 'Nee'} - {filter.values.source != 'archive' ? ( - ( -
- -
- Bekijk - - -
{ - e?.close(); - storeFundPhysicalCardType( - organization, - fund, - cardType, - null, - fetchPhysicalCardTypes, - ); - }} - className="dropdown-item"> -
- Bewerking -
- -
{ - e?.close(); - deleteFundPhysicalCardType( - fund, - cardType, - fetchPhysicalCardTypes, - ); - }}> - - Verwijderen -
-
- )} - /> - ) : ( - - {translate('organization_employees.labels.owner')} - - )} -
-
-
-
- - {fundPhysicalCardTypes?.meta.total > 0 && ( -
- -
- )} + emptyDescription={'Er zijn momenteel geen fysieke passen.'} + columns={fundPhysicalCardTypeService.getColumns()} + tableOptions={{ sortable: true, filter }} + paginator={{ key: paginatorKey, data: fundPhysicalCardTypes, filterValues, filterUpdate }}> + {fundPhysicalCardTypes?.data?.map((cardType) => ( + + + + + {cardType?.allow_physical_card_linking ? 'Ja' : 'Nee'} + {cardType?.allow_physical_card_deactivation ? 'Ja' : 'Nee'} + {cardType?.allow_physical_card_requests ? 'Ja' : 'Nee'} + + {filter.values.source != 'archive' ? ( + ( +
+ +
+ Bekijk + + +
{ + e?.close(); + storeFundPhysicalCardType( + organization, + fund, + cardType, + null, + fetchPhysicalCardTypes, + ); + }} + className="dropdown-item"> +
+ Bewerking +
+ +
{ + e?.close(); + deleteFundPhysicalCardType(fund, cardType, fetchPhysicalCardTypes); + }}> + + Verwijderen +
+
+ )} + /> + ) : ( + {translate('organization_employees.labels.owner')} + )} + + + ))}
); diff --git a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowIdentitiesCard.tsx b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowIdentitiesCard.tsx index 43ea94f8f..16a40a6f4 100644 --- a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowIdentitiesCard.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowIdentitiesCard.tsx @@ -1,8 +1,6 @@ -import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import Fund from '../../../../../props/models/Fund'; import FilterItemToggle from '../../../../elements/tables/elements/FilterItemToggle'; -import EmptyCard from '../../../../elements/empty-card/EmptyCard'; -import Paginator from '../../../../../modules/paginator/components/Paginator'; import useTranslate from '../../../../../hooks/useTranslate'; import useActiveOrganization from '../../../../../hooks/useActiveOrganization'; import usePaginatorService from '../../../../../modules/paginator/services/usePaginatorService'; @@ -15,13 +13,12 @@ import { useFundService } from '../../../../../services/FundService'; import useFundIdentitiesExporter from '../../../../../services/exporters/useFundIdentitiesExporter'; import { hasPermission } from '../../../../../helpers/utils'; import { Permission } from '../../../../../props/models/Organization'; -import useConfigurableTable from '../../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../../elements/tables/TableTopScroller'; import TableRowActions from '../../../../elements/tables/TableRowActions'; import { DashboardRoutes } from '../../../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../../../modules/filter_next/useFilterNext'; import CardHeaderFilter from '../../../../elements/tables/elements/CardHeaderFilter'; import BlockLabelTabs from '../../../../elements/block-label-tabs/BlockLabelTabs'; +import LoaderTableCard from '../../../../elements/loader-table-card/LoaderTableCard'; export default function OrganizationsFundsShowIdentitiesCard({ fund, @@ -55,11 +52,6 @@ export default function OrganizationsFundsShowIdentitiesCard({ per_page: paginatorService.getPerPage(paginationPerPageKey), }); - const { headElement, configsElement } = useConfigurableTable(fundService.getIdentitiesColumns(), { - filter, - sortable: true, - }); - const fetchIdentities = useCallback(() => { setProgress(0); @@ -158,7 +150,7 @@ export default function OrganizationsFundsShowIdentitiesCard({ {translate('components.dropdown.export', { - total: identities.meta.total, + total: identities?.meta?.total, })} @@ -169,81 +161,49 @@ export default function OrganizationsFundsShowIdentitiesCard({
- {identities ? ( - - {identities?.meta?.total > 0 ? ( -
- {configsElement} - - - - {headElement} - - - {identities.data.map((identity: SponsorIdentity, index: number) => ( - - - - - - - - - - ))} - -
{identity.id}{identity.email}{identity.count_vouchers}{identity.count_vouchers_active}{identity.count_vouchers_active_with_balance} - ( -
- - - Bekijken - -
- )} - /> -
-
-
- ) : ( - - )} - - -
- ) : ( - - )} + + {identities?.data?.map((identity: SponsorIdentity, index: number) => ( + + {identity.id} + {identity.email} + {identity.count_vouchers} + {identity.count_vouchers_active} + {identity.count_vouchers_active_with_balance} + + + ( +
+ + + Bekijken + +
+ )} + /> + + + ))} +
{identities?.meta?.total > 0 && (
diff --git a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowImplementationsCard.tsx b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowImplementationsCard.tsx index 0a9a1ec7f..5c0e5d192 100644 --- a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowImplementationsCard.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowImplementationsCard.tsx @@ -1,13 +1,11 @@ -import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import Fund from '../../../../../props/models/Fund'; import FilterItemToggle from '../../../../elements/tables/elements/FilterItemToggle'; -import EmptyCard from '../../../../elements/empty-card/EmptyCard'; -import Paginator from '../../../../../modules/paginator/components/Paginator'; +import LoaderTableCard from '../../../../elements/loader-table-card/LoaderTableCard'; import useTranslate from '../../../../../hooks/useTranslate'; import useActiveOrganization from '../../../../../hooks/useActiveOrganization'; import usePaginatorService from '../../../../../modules/paginator/services/usePaginatorService'; import { PaginationData } from '../../../../../props/ApiResponses'; -import LoadingCard from '../../../../elements/loading-card/LoadingCard'; import TableRowActions from '../../../../elements/tables/TableRowActions'; import { hasPermission } from '../../../../../helpers/utils'; import StateNavLink from '../../../../../modules/state_router/StateNavLink'; @@ -15,8 +13,6 @@ import useAssetUrl from '../../../../../hooks/useAssetUrl'; import Implementation from '../../../../../props/models/Implementation'; import Label from '../../../../elements/image_cropper/Label'; import { Permission } from '../../../../../props/models/Organization'; -import useConfigurableTable from '../../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../../elements/tables/TableTopScroller'; import { useFundService } from '../../../../../services/FundService'; import { DashboardRoutes } from '../../../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../../../modules/filter_next/useFilterNext'; @@ -52,8 +48,6 @@ export default function OrganizationsFundsShowImplementationsCard({ const { resetFilters: resetFilters } = filter; - const { headElement, configsElement } = useConfigurableTable(fundService.getImplementationsColumns()); - const transformImplementations = useCallback(() => { const { q = '', per_page } = filterValuesActive; const links = { active: false, label: '', url: '' }; @@ -148,103 +142,68 @@ export default function OrganizationsFundsShowImplementationsCard({
- {implementations ? ( - - {implementations?.meta?.total > 0 ? ( -
- {configsElement} - - - - {headElement} - - - {implementations?.data?.map((implementation) => ( - - - - {fund.state == 'active' && ( - - )} - {fund.state != 'active' && ( - - )} - - - - ))} - -
- {''} - {implementation?.name} - - - - - ( -
- - {' '} - Bekijk op webshop - - - {hasPermission( - activeOrganization, - Permission.MANAGE_IMPLEMENTATION_CMS, - ) && ( - - - Ga naar CMS - - )} -
- )} - /> -
-
-
- ) : ( - - )} - - -
- ) : ( - - )} + + {implementations?.data?.map((implementation) => ( + + + {''} + + {implementation?.name} + {fund.state == 'active' && ( + + + + )} + {fund.state != 'active' && ( + + + + )} + + + ( + + )} + /> + + + ))} +
+ + Bekijk op webshop + + + {hasPermission(activeOrganization, Permission.MANAGE_IMPLEMENTATION_CMS) && ( + + + Ga naar CMS + + )} +
); } diff --git a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowTopUpsCard.tsx b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowTopUpsCard.tsx index 3a4395e1c..90082f4d0 100644 --- a/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowTopUpsCard.tsx +++ b/react/src/dashboard/components/pages/organizations-funds-show/elements/tabs-relations-card/OrganizationsFundsShowTopUpsCard.tsx @@ -1,20 +1,17 @@ -import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import Fund from '../../../../../props/models/Fund'; import FilterItemToggle from '../../../../elements/tables/elements/FilterItemToggle'; import DatePickerControl from '../../../../elements/forms/controls/DatePickerControl'; import { dateFormat, dateParse } from '../../../../../helpers/dates'; import FundTopUpTransaction from '../../../../../props/models/FundTopUpTransaction'; -import EmptyCard from '../../../../elements/empty-card/EmptyCard'; -import Paginator from '../../../../../modules/paginator/components/Paginator'; +import LoaderTableCard from '../../../../elements/loader-table-card/LoaderTableCard'; import useTranslate from '../../../../../hooks/useTranslate'; import useSetProgress from '../../../../../hooks/useSetProgress'; import useActiveOrganization from '../../../../../hooks/useActiveOrganization'; import { useFundService } from '../../../../../services/FundService'; import usePaginatorService from '../../../../../modules/paginator/services/usePaginatorService'; import { PaginationData } from '../../../../../props/ApiResponses'; -import LoadingCard from '../../../../elements/loading-card/LoadingCard'; -import useConfigurableTable from '../../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../../elements/tables/TableTopScroller'; import TableEmptyValue from '../../../../elements/table-empty-value/TableEmptyValue'; import useFilterNext from '../../../../../modules/filter_next/useFilterNext'; import CardHeaderFilter from '../../../../elements/tables/elements/CardHeaderFilter'; @@ -66,11 +63,6 @@ export default function OrganizationsFundsShowTopUpsCard({ const { resetFilters: resetFilters } = filter; - const { headElement, configsElement } = useConfigurableTable(fundService.getTopUpColumns(), { - filter, - sortable: true, - }); - const fetchTopUps = useCallback(() => { if (!fund?.is_configured) { setLastQueryTopUpTransactions(filterValuesActive.q); @@ -219,58 +211,32 @@ export default function OrganizationsFundsShowTopUpsCard({
- {topUpTransactions ? ( - - {topUpTransactions?.meta?.total > 0 ? ( -
- {configsElement} - - - - {headElement} - - - {topUpTransactions.data.map((top_up_transaction: FundTopUpTransaction) => ( - - - - - - - - ))} - -
{top_up_transaction.code} - {top_up_transaction.iban || 'Geen IBAN'} - {top_up_transaction.amount_locale}{top_up_transaction.created_at_locale} - -
-
-
- ) : ( - - )} - - -
- ) : ( - - )} + + {topUpTransactions?.data?.map((top_up_transaction: FundTopUpTransaction) => ( + + {top_up_transaction.code} + + {top_up_transaction.iban || 'Geen IBAN'} + + {top_up_transaction.amount_locale} + {top_up_transaction.created_at_locale} + + + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/organizations-funds/OrganizationFunds.tsx b/react/src/dashboard/components/pages/organizations-funds/OrganizationFunds.tsx index 916ccf8bf..cfa9220f7 100644 --- a/react/src/dashboard/components/pages/organizations-funds/OrganizationFunds.tsx +++ b/react/src/dashboard/components/pages/organizations-funds/OrganizationFunds.tsx @@ -18,13 +18,10 @@ import usePushSuccess from '../../../hooks/usePushSuccess'; import ModalDangerZone from '../../modals/ModalDangerZone'; import useOpenModal from '../../../hooks/useOpenModal'; import { createEnumParam, NumberParam, StringParam } from 'use-query-params'; -import Paginator from '../../../modules/paginator/components/Paginator'; import ModalFundTopUp from '../../modals/ModalFundTopUp'; import useTranslate from '../../../hooks/useTranslate'; import TableEmptyValue from '../../elements/table-empty-value/TableEmptyValue'; import FundStateLabels from '../../elements/resource-states/FundStateLabels'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; import TableEntityMain from '../../elements/tables/elements/TableEntityMain'; import usePushApiError from '../../../hooks/usePushApiError'; import classNames from 'classnames'; @@ -93,10 +90,6 @@ export default function OrganizationFunds() { const { resetFilters: resetFilters } = filter; - const { headElement, configsElement } = useConfigurableTable( - fundService.getColumns(activeOrganization, filterValues.funds_type), - ); - const fetchFunds = useCallback(() => { setProgress(0); @@ -217,7 +210,7 @@ export default function OrganizationFunds() {
- {translate('components.organization_funds.title')} ({funds.meta.total}) + {translate('components.organization_funds.title')} ({funds?.meta?.total})
@@ -330,177 +323,135 @@ export default function OrganizationFunds() { -
-
- {configsElement} - - - - {headElement} - - - {funds.data.map((fund) => ( - - - - - - {filterValues.funds_type == 'active' && ( - - {hasPermission(activeOrganization, Permission.VIEW_FINANCES) && ( - - )} + {funds?.data?.map((fund) => ( + + + + + + {filterValues.funds_type == 'active' && ( + + {hasPermission(activeOrganization, Permission.VIEW_FINANCES) && ( + + )} + + + + )} - - + + + - - - - ))} - -
- - - {fund?.implementation?.name || } - {fund.budget?.left_locale} + + + {fund?.implementation?.name || } + {fund.budget?.left_locale}{fund.requester_count} - {fund.requester_count} - + + + {!fund.archived ? ( + ( +
+ + Bekijken + + + {hasPermission( + activeOrganization, + [Permission.MANAGE_FUNDS, Permission.MANAGE_FUND_TEXTS], + false, + ) && ( + + + Bewerken + )} -
- - - {!fund.archived ? ( - ( -
- - Bekijken - - - {hasPermission( - activeOrganization, - [ - Permission.MANAGE_FUNDS, - Permission.MANAGE_FUND_TEXTS, - ], - false, - ) && ( - - - Bewerken - - )} - - {activeOrganization.allow_2fa_restrictions && - hasPermission( - activeOrganization, - Permission.MANAGE_FUNDS, - ) && ( - - - Beveiliging - - )} - - {hasPermission( - activeOrganization, - Permission.VIEW_FINANCES, - ) && - fund.key && - fund.state != 'closed' && ( - { - topUpModal(fund); - close(); - }}> - - Budget toevoegen - - )} - - {hasPermission( - activeOrganization, - Permission.MANAGE_FUNDS, - ) && ( - { - archiveFund(fund); - close(); - }}> - - {translate( - 'components.organization_funds.buttons.archive', - )} - - )} -
+ {activeOrganization.allow_2fa_restrictions && + hasPermission(activeOrganization, Permission.MANAGE_FUNDS) && ( + + + Beveiliging + + )} + + {hasPermission(activeOrganization, Permission.VIEW_FINANCES) && + fund.key && + fund.state != 'closed' && ( + - ) : ( - hasPermission(activeOrganization, Permission.MANAGE_FUNDS) && ( - - ) + onClick={() => { + topUpModal(fund); + close(); + }}> + + Budget toevoegen + )} -
-
-
-
- {funds?.meta.total > 0 && ( -
- -
- )} + {hasPermission(activeOrganization, Permission.MANAGE_FUNDS) && ( + { + archiveFund(fund); + close(); + }}> + + {translate('components.organization_funds.buttons.archive')} + + )} +
+ )} + /> + ) : ( + hasPermission(activeOrganization, Permission.MANAGE_FUNDS) && ( + + ) + )} + + + ))}
); diff --git a/react/src/dashboard/components/pages/organizations-notifications/OrganizationsNotifications.tsx b/react/src/dashboard/components/pages/organizations-notifications/OrganizationsNotifications.tsx index d8979ef3e..183c140b7 100644 --- a/react/src/dashboard/components/pages/organizations-notifications/OrganizationsNotifications.tsx +++ b/react/src/dashboard/components/pages/organizations-notifications/OrganizationsNotifications.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import { PaginationData } from '../../../props/ApiResponses'; import Notification from '../../../props/models/Notification'; import { useNotificationService } from '../../../services/NotificationService'; @@ -82,7 +83,7 @@ export default function OrganizationsNotifications() { {notifications.data.map((notification) => (
+ className={classNames('notification-item', !notification.seen && 'notification-item-new')}>
{notification.title}
diff --git a/react/src/dashboard/components/pages/organizations-translations/elements/TranslationStatsTable.tsx b/react/src/dashboard/components/pages/organizations-translations/elements/TranslationStatsTable.tsx index 0e10e83b1..14934b2cc 100644 --- a/react/src/dashboard/components/pages/organizations-translations/elements/TranslationStatsTable.tsx +++ b/react/src/dashboard/components/pages/organizations-translations/elements/TranslationStatsTable.tsx @@ -2,8 +2,7 @@ import React, { Fragment, useState } from 'react'; import classNames from 'classnames'; import { numberFormat } from '../../../../helpers/string'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import { useOrganizationService } from '../../../../services/OrganizationService'; import { TranslationStats } from '../../../../props/models/Organization'; @@ -15,94 +14,71 @@ export default function TranslationStatsTable({ const organizationService = useOrganizationService(); const [shownKeys, setShownKeys] = useState([]); - const { headElement, configsElement } = useConfigurableTable(organizationService.getTranslationStatsColumns()); - return ( -
-
- {configsElement} - - - - {headElement} - - - {stats.data.groups.map((group, index) => ( - - { - e?.preventDefault(); - e?.stopPropagation(); + + {stats.data.groups.map((group, index) => ( + + { + e?.preventDefault(); + e?.stopPropagation(); - setShownKeys((keys) => { - return keys.includes(index) - ? keys.filter((item) => item !== index) - : [...keys, index]; - }); - }}> - - - - - - {shownKeys.includes(index) && - group?.locales?.map((locale) => ( - - - - - - - ))} +
{group.name}
+ + + + + + + {shownKeys.includes(index) && + group?.locales?.map((locale) => ( + + + + + + + ))} - {index === stats.data.groups?.length - 1 && ( - - - - - - - )} - - ))} - -
-
-
-
-
+ setShownKeys((keys) => { + return keys.includes(index) ? keys.filter((item) => item !== index) : [...keys, index]; + }); + }}> +
+
+
+
+
-
{group.name}
-
-
- {group.symbols ? numberFormat(group.symbols) : } - {group.costs} - -
-
{locale.name}
-
- {locale.symbols ? ( - numberFormat(locale.symbols) - ) : ( - - )} - {locale.symbols ? locale.costs : } - -
+ {group.symbols ? numberFormat(group.symbols) : } + {group.costs} + +
+
{locale.name}
+
{locale.symbols ? numberFormat(locale.symbols) : }{locale.symbols ? locale.costs : } + +
Totaal - {numberFormat(stats?.data?.total?.symbols || 0)} - {stats?.data?.total?.cost} - -
-
-
-
+ {index === stats.data.groups?.length - 1 && ( + + Totaal + {numberFormat(stats?.data?.total?.symbols || 0)} + {stats?.data?.total?.cost} + + + + + )} + + ))} + ); } diff --git a/react/src/dashboard/components/pages/payment-methods/PaymentMethods.tsx b/react/src/dashboard/components/pages/payment-methods/PaymentMethods.tsx index 0d73d05e2..78250bc17 100644 --- a/react/src/dashboard/components/pages/payment-methods/PaymentMethods.tsx +++ b/react/src/dashboard/components/pages/payment-methods/PaymentMethods.tsx @@ -1,4 +1,5 @@ import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import LoadingCard from '../../elements/loading-card/LoadingCard'; import useSetProgress from '../../../hooks/useSetProgress'; @@ -184,7 +185,9 @@ export default function PaymentMethods() { Een nieuw Mollie account aanmaken -
or
+
+ or +
+ )} + /> + + + ))} ); } diff --git a/react/src/dashboard/components/pages/person-prevalidations/PrevalidationRequests.tsx b/react/src/dashboard/components/pages/person-prevalidations/PrevalidationRequests.tsx index 6fe03ac49..3c3e7b775 100644 --- a/react/src/dashboard/components/pages/person-prevalidations/PrevalidationRequests.tsx +++ b/react/src/dashboard/components/pages/person-prevalidations/PrevalidationRequests.tsx @@ -12,17 +12,14 @@ import useOpenModal from '../../../hooks/useOpenModal'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; import { PaginationData } from '../../../props/ApiResponses'; import PrevalidationRequest from '../../../props/models/PrevalidationRequest'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import ClickOutside from '../../elements/click-outside/ClickOutside'; import FilterItemToggle from '../../elements/tables/elements/FilterItemToggle'; import DatePickerControl from '../../elements/forms/controls/DatePickerControl'; import { dateFormat, dateParse } from '../../../helpers/dates'; import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import { strLimit } from '../../../helpers/string'; import TableEmptyValue from '../../elements/table-empty-value/TableEmptyValue'; -import Paginator from '../../../modules/paginator/components/Paginator'; import { createEnumParam, NumberParam, StringParam } from 'use-query-params'; import EmptyCard from '../../elements/empty-card/EmptyCard'; import { Permission } from '../../../props/models/Organization'; @@ -98,8 +95,6 @@ export default function PrevalidationRequests() { }, ); - const { headElement, configsElement } = useConfigurableTable(prevalidationRequestService.getColumns()); - const fetchPrevalidationRequests = useCallback(() => { if (activeOrganization?.allow_prevalidation_requests) { setProgress(0); @@ -372,102 +367,67 @@ export default function PrevalidationRequests() { -
-
- {configsElement} - - - - {headElement} - - - {prevalidationRequests.data.map((row) => ( - - - - - - - - - - - ))} - -
{row.bsn} -
- {row.fund ? strLimit(row.fund?.name, 32) : } -
- -
- {row.fund ? ( - strLimit(row.fund?.implementation?.name, 32) - ) : ( - - )} -
-
- {row.employee?.email || 'Onbekend'} - - - - {row.state === 'fail' && row.failed_reason ? ( - row.failed_reason_locale - ) : ( - - )} - - {row.state === 'fail' ? ( - ( -
-
{ - resubmitRequest(row); - close(); - }}> - {' '} - {translate( - 'prevalidation_requests.buttons.resubmit', - )} -
-
{ - deleteRequest(row); - close(); - }}> - {' '} - {translate('prevalidation_requests.buttons.delete')} -
-
- )} - /> - ) : ( - - )} -
-
-
-
+ emptyDescription={translate('prevalidation_requests.empty.description')} + columns={prevalidationRequestService.getColumns()} + paginator={{ key: paginatorKey, data: prevalidationRequests, filterValues, filterUpdate }}> + {prevalidationRequests?.data?.map((row) => ( + + {row.bsn} + + +
+ {row.fund ? strLimit(row.fund?.name, 32) : } +
- {prevalidationRequests?.meta.total > 0 && ( -
- -
- )} +
+ {row.fund ? strLimit(row.fund?.implementation?.name, 32) : } +
+ + {row.employee?.email || 'Onbekend'} + + + + + {row.state === 'fail' && row.failed_reason ? row.failed_reason_locale : } + + + + {row.state === 'fail' ? ( + ( +
+
{ + resubmitRequest(row); + close(); + }}> + {' '} + {translate('prevalidation_requests.buttons.resubmit')} +
+
{ + deleteRequest(row); + close(); + }}> + {' '} + {translate('prevalidation_requests.buttons.delete')} +
+
+ )} + /> + ) : ( + + )} + + + ))}
); diff --git a/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypeFundsTable.tsx b/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypeFundsTable.tsx index f249f0d44..824602c7a 100644 --- a/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypeFundsTable.tsx +++ b/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypeFundsTable.tsx @@ -1,11 +1,8 @@ import { PaginationData } from '../../../../props/ApiResponses'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import React, { Fragment, useCallback, useEffect, useState } from 'react'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import usePaginatorService from '../../../../modules/paginator/services/usePaginatorService'; import useTranslate from '../../../../hooks/useTranslate'; import useSetProgress from '../../../../hooks/useSetProgress'; @@ -65,10 +62,6 @@ export default function PhysicalCardTypeFundsTable({ physicalCardType }: { physi physical_card_type_id: physicalCardType?.id, }); - const { headElement, configsElement } = useConfigurableTable( - fundService.getColumns(activeOrganization, filterActiveValues?.funds_type), - ); - const fetchFunds = useCallback(() => { setProgress(0); @@ -99,7 +92,7 @@ export default function PhysicalCardTypeFundsTable({ physicalCardType }: { physi
- {translate('components.organization_funds.title')} ({funds.meta.total}) + {translate('components.organization_funds.title')} ({funds?.meta?.total})
@@ -187,87 +180,62 @@ export default function PhysicalCardTypeFundsTable({ physicalCardType }: { physi loading={!funds?.meta} empty={funds?.meta?.total === 0} emptyTitle={'Geen fondsen'} - emptyDescription={'Geen fondsen gevonden.'}> -
-
- {configsElement} - - - - {headElement} - - - {funds.data.map((fund) => ( + emptyDescription={'Geen fondsen gevonden.'} + columns={fundService.getColumns(activeOrganization, filterActiveValues?.funds_type)} + paginator={{ key: paginatorKey, data: funds, filterValues, filterUpdate }}> + {funds?.data?.map((fund) => ( + + + + + + {filterActiveValues?.funds_type == 'active' && ( + + {hasPermission(activeOrganization, Permission.VIEW_FINANCES) && ( + + )} + + + + )} + + + + - - - - {filterActiveValues?.funds_type == 'active' && ( - - {hasPermission(activeOrganization, Permission.VIEW_FINANCES) && ( - - )} - - - - )} - - - - + params={{ + organizationId: activeOrganization.id, + fundId: fund.id, + }} + className="dropdown-item"> + Bekijken - ))} - -
+ + + {fund?.implementation?.name || } + {fund.budget?.left_locale}{fund.requester_count} + + + ( +
-
- - - {fund?.implementation?.name || } - {fund.budget?.left_locale} - {fund.requester_count} - - - - ( -
- - Bekijken - -
- )} - /> -
-
-
-
- - {funds?.meta.total > 0 && ( -
- -
- )} +
+ )} + /> + + + ))}
); diff --git a/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypesTable.tsx b/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypesTable.tsx index 63c634fbb..c599d470b 100644 --- a/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypesTable.tsx +++ b/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardTypesTable.tsx @@ -1,12 +1,9 @@ import { PaginationData } from '../../../../props/ApiResponses'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import TableRowActions from '../../../elements/tables/TableRowActions'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import React, { useCallback, useEffect, useState } from 'react'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import usePaginatorService from '../../../../modules/paginator/services/usePaginatorService'; import Organization from '../../../../props/models/Organization'; import useTranslate from '../../../../hooks/useTranslate'; @@ -66,11 +63,6 @@ export default function PhysicalCardTypesTable({ { queryParams: filterUseQueryParams ? { q: StringParam, fund_id: StringParam, per_page: StringParam } : null }, ); - const { headElement, configsElement } = useConfigurableTable(physicalCardTypeService.getColumns(), { - sortable: true, - filter: filter, - }); - const fetchPhysicalCardTypes = useCallback(() => { setProgress(0); @@ -134,112 +126,82 @@ export default function PhysicalCardTypesTable({ loading={!physicalCardTypes?.meta} empty={physicalCardTypes?.meta?.total === 0} emptyTitle={'Geen fysieke passen'} - emptyDescription={'Er zijn momenteel geen fysieke passen.'}> -
-
- {configsElement} - - - - {headElement} - - - {physicalCardTypes?.data.map((cardType) => ( - - - - - - - - - ))} - -
- - {cardType?.physical_cards_count}{cardType?.funds_count}{cardType?.code_blocks || }{cardType?.code_block_size || } - {filter.values.source != 'archive' ? ( - ( -
- -
- Bekijk - - -
{ - e?.close(); - editPhysicalCardType( - organization, - cardType, - fetchPhysicalCardTypes, - ); - }} - className="dropdown-item"> -
- Bewerking -
- -
{ - e?.close(); - deletePhysicalCardType( - cardType, - fetchPhysicalCardTypes, - ); - }}> - - Verwijderen -
-
- )} - /> - ) : ( - - {translate('organization_employees.labels.owner')} - - )} -
-
-
-
- - {physicalCardTypes?.meta.total > 0 && ( -
- -
- )} + emptyDescription={'Er zijn momenteel geen fysieke passen.'} + columns={physicalCardTypeService.getColumns()} + tableOptions={{ sortable: true, filter }} + paginator={{ key: paginatorKey, data: physicalCardTypes, filterValues, filterUpdate }}> + {physicalCardTypes?.data?.map((cardType) => ( + + + + + {cardType?.physical_cards_count} + {cardType?.funds_count} + {cardType?.code_blocks || } + {cardType?.code_block_size || } + + {filter.values.source != 'archive' ? ( + ( +
+ +
+ Bekijk + + +
{ + e?.close(); + editPhysicalCardType( + organization, + cardType, + fetchPhysicalCardTypes, + ); + }} + className="dropdown-item"> +
+ Bewerking +
+ +
{ + e?.close(); + deletePhysicalCardType(cardType, fetchPhysicalCardTypes); + }}> + + Verwijderen +
+
+ )} + /> + ) : ( + {translate('organization_employees.labels.owner')} + )} + + + ))}
); diff --git a/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardsTable.tsx b/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardsTable.tsx index d5f146bda..b7e55e172 100644 --- a/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardsTable.tsx +++ b/react/src/dashboard/components/pages/physical-cards/elements/PhysicalCardsTable.tsx @@ -1,12 +1,9 @@ import { PaginationData } from '../../../../props/ApiResponses'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import TableRowActions from '../../../elements/tables/TableRowActions'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import React, { useCallback, useEffect, useState } from 'react'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import { usePhysicalCardService } from '../../../../services/PhysicalCardService'; import usePaginatorService from '../../../../modules/paginator/services/usePaginatorService'; import Organization from '../../../../props/models/Organization'; @@ -72,11 +69,6 @@ export default function PhysicalCardsTable({ }, ); - const { headElement, configsElement } = useConfigurableTable(physicalCardService.getColumns(), { - sortable: true, - filter: filter, - }); - const fetchPhysicalCards = useCallback(() => { setProgress(0); @@ -131,122 +123,98 @@ export default function PhysicalCardsTable({ loading={!physicalCards?.meta} empty={physicalCards?.meta?.total === 0} emptyTitle={'Geen fysieke passen'} - emptyDescription={'Er zijn momenteel geen fysieke passen.'}> -
-
- {configsElement} - - - - {headElement} - - - {physicalCards?.data.map((card) => ( - - - - - - - - - ))} - -
{card.id} - {card.code_locale} - - {card?.voucher ? ( - {`#${card?.voucher?.number}`} - ) : ( - - )} - - {card?.voucher?.fund ? ( - - {strLimit(card?.voucher?.fund.name, 64)} - - ) : ( - - )} - - {card?.physical_card_type ? ( - - {strLimit(card?.physical_card_type?.name, 53)} - - ) : ( - - )} - - {filterValues.source != 'archive' ? ( - ( -
- {card?.voucher && ( - -
- Bekijk tegoeden - - )} - - {card.physical_card_type && ( - -
- Bekijk passen type - - )} -
- )} - /> - ) : ( - - {translate('organization_employees.labels.owner')} - - )} -
-
-
-
- - {physicalCards?.meta.total > 0 && ( -
- -
- )} + emptyDescription={'Er zijn momenteel geen fysieke passen.'} + columns={physicalCardService.getColumns()} + tableOptions={{ sortable: true, filter }} + paginator={{ key: paginatorKey, data: physicalCards, filterValues, filterUpdate }}> + {physicalCards?.data?.map((card) => ( + + {card.id} + + {card.code_locale} + + + {card?.voucher ? ( + {`#${card?.voucher?.number}`} + ) : ( + + )} + + + {card?.voucher?.fund ? ( + + {strLimit(card?.voucher?.fund.name, 64)} + + ) : ( + + )} + + + {card?.physical_card_type ? ( + + {strLimit(card?.physical_card_type?.name, 53)} + + ) : ( + + )} + + + {filterValues.source != 'archive' ? ( + ( +
+ {card?.voucher && ( + +
+ Bekijk tegoeden + + )} + + {card.physical_card_type && ( + +
+ Bekijk passen type + + )} +
+ )} + /> + ) : ( + {translate('organization_employees.labels.owner')} + )} + + + ))}
); diff --git a/react/src/dashboard/components/pages/prevalidations/Prevalidations.tsx b/react/src/dashboard/components/pages/prevalidations/Prevalidations.tsx index 8f279e0d9..6500160a4 100644 --- a/react/src/dashboard/components/pages/prevalidations/Prevalidations.tsx +++ b/react/src/dashboard/components/pages/prevalidations/Prevalidations.tsx @@ -18,7 +18,6 @@ import { usePrevalidationService } from '../../../services/PrevalidationService' import Employee from '../../../props/models/Employee'; import { PaginationData } from '../../../props/ApiResponses'; import Prevalidation from '../../../props/models/Prevalidation'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import ModalNotification from '../../modals/ModalNotification'; import ModalCreatePrevalidation from '../../modals/ModalCreatePrevalidation'; @@ -28,11 +27,9 @@ import FilterItemToggle from '../../elements/tables/elements/FilterItemToggle'; import DatePickerControl from '../../elements/forms/controls/DatePickerControl'; import { dateFormat, dateParse } from '../../../helpers/dates'; import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import { strLimit } from '../../../helpers/string'; import TableRowActions from '../../elements/tables/TableRowActions'; import TableEmptyValue from '../../elements/table-empty-value/TableEmptyValue'; -import Paginator from '../../../modules/paginator/components/Paginator'; import { NumberParam, StringParam } from 'use-query-params'; import EmptyCard from '../../elements/empty-card/EmptyCard'; import usePrevalidationExporter from '../../../services/exporters/usePrevalidationExporter'; @@ -150,10 +147,6 @@ export default function Prevalidations() { })); }, [headers, prevalidations?.data]); - const { headElement, configsElement } = useConfigurableTable( - prevalidationService.getColumns(headers || [], typesByKey), - ); - const exportData = useCallback(() => { prevalidationExporter.exportData(activeOrganization.id, { ...filterValuesActive, ...filter.activeValues }); }, [activeOrganization.id, filterValuesActive, filter.activeValues, prevalidationExporter]); @@ -410,10 +403,10 @@ export default function Prevalidations() { className="button button-primary button-wide" onClick={() => exportData()} data-dusk="export" - disabled={prevalidations?.meta.total == 0}> + disabled={prevalidations?.meta?.total == 0}> {translate('components.dropdown.export', { - total: prevalidations.meta.total, + total: prevalidations?.meta?.total, })}
@@ -435,98 +428,69 @@ export default function Prevalidations() { -
-
- {configsElement} - - - - {headElement} - - - {rows?.map((row) => ( - - - - - - - {row.records?.map((record, index) => ( - - ))} - - - - - - - - ))} - -
{row.uid} -
- {row.fund ? strLimit(row.fund?.name, 32) : } -
- -
- {row.fund ? ( - strLimit(row.fund?.implementation?.name, 32) - ) : ( - - )} -
-
- {employeesByAddress?.[row?.identity_address] || 'Unknown'} - - {record ? record.value : } - - - - - - {row.state === 'pending' ? ( - ( - - )} - /> - ) : ( - - )} -
-
-
-
+ } + columns={prevalidationService.getColumns(headers || [], typesByKey)} + paginator={{ key: paginatorKey, data: prevalidations, filterValues, filterUpdate }}> + {rows?.map((row) => ( + + {row.uid} + + +
+ {row.fund ? strLimit(row.fund?.name, 32) : } +
- {prevalidations?.meta.total > 0 && ( -
- -
- )} +
+ {row.fund ? strLimit(row.fund?.implementation?.name, 32) : } +
+ + + {employeesByAddress?.[row?.identity_address] || 'Unknown'} + + + {row.records?.map((record, index) => ( + + {record ? record.value : } + + ))} + + + + + + + + + + + {row.state === 'pending' ? ( + ( + + )} + /> + ) : ( + + )} + + + ))}
); diff --git a/react/src/dashboard/components/pages/products-edit/elements/ProductsForm.tsx b/react/src/dashboard/components/pages/products-edit/elements/ProductsForm.tsx index 18465da32..ed312340c 100644 --- a/react/src/dashboard/components/pages/products-edit/elements/ProductsForm.tsx +++ b/react/src/dashboard/components/pages/products-edit/elements/ProductsForm.tsx @@ -637,6 +637,40 @@ export default function ProductsForm({ /> + + form.update({ info_duration })} + /> + form.update({ info_when })} + /> + form.update({ info_where })} + /> + form.update({ info_more_info })} + /> + + form.update({ info_attention })} + /> + +
@@ -795,153 +829,157 @@ export default function ProductsForm({ )}
-
- - {!isInformational && ( - - {(!product || (product && !product.unlimited_stock)) && ( -
-
- - Kies of het product een voorraadlimiet heeft of altijd - beschikbaar is. - - } - input={(id) => ( - { - form.update({ unlimited_stock }); - }} - /> - )} - /> -
-
- - Kies of het product een voorraadlimiet heeft of altijd - beschikbaar is. - - } - error={form.errors.total_amount} - input={(id) => - !form.values.unlimited_stock ? ( - + {(!product || (product && !product.unlimited_stock)) && ( +
+
+ + Kies of het product een voorraadlimiet heeft of altijd + beschikbaar is. + + } + input={(id) => ( + { - form.update({ - total_amount: e.target.value - ? parseFloat(e.target.value) - : '', - }); + value={form.values.unlimited_stock} + options={[ + { value: false, label: 'Aantal op voorraad' }, + { value: true, label: 'Onbeperkt aanbod' }, + ]} + onChange={(unlimited_stock: boolean) => { + form.update({ unlimited_stock }); }} - type="number" - placeholder="Aantal in voorraad" /> - ) : ( - - ) - } - /> + )} + /> +
+ +
+ + Kies of het product een voorraadlimiet heeft of altijd + beschikbaar is. + + } + error={form.errors.total_amount} + input={(id) => + !form.values.unlimited_stock ? ( + { + form.update({ + total_amount: e.target.value + ? parseFloat(e.target.value) + : '', + }); + }} + type="number" + placeholder="Aantal in voorraad" + /> + ) : ( + + ) + } + /> +
-
- )} + )} - {product && ( -
-
- - Hoe vaak dit aanbod is gekocht. Dit wordt automatisch - bijgewerkt. - - } - input={(id) => ( - - form.update({ - sold_amount: e.target.value - ? parseFloat(e.target.value) - : '', - }) - } - type="number" - placeholder="Verkocht" - /> - )} - /> -
-
- - product.unlimited_stock ? ( + {product && ( +
+
+ + Hoe vaak dit aanbod is gekocht. Dit wordt automatisch + bijgewerkt. + + } + input={(id) => ( - ) : ( - form.update({ - stock_amount: e.target.value + sold_amount: e.target.value ? parseFloat(e.target.value) : '', }) } type="number" - placeholder="Current stock" - disabled={!isEditable} + placeholder="Verkocht" /> - ) - } - /> + )} + /> +
+
+ + product.unlimited_stock ? ( + + ) : ( + + form.update({ + stock_amount: e.target.value + ? parseFloat(e.target.value) + : '', + }) + } + type="number" + placeholder="Current stock" + disabled={!isEditable} + /> + ) + } + /> +
-
- )} - - )} + )} + + )} + {!isInformational && ( @@ -1321,42 +1359,6 @@ export default function ProductsForm({ onChange={(product_category_id) => form.update({ product_category_id })} errors={form.errors.product_category_id} /> - - - form.update({ info_duration })} - /> - form.update({ info_when })} - /> - form.update({ info_where })} - /> - form.update({ info_more_info })} - /> - - - form.update({ info_attention })} - /> - -
diff --git a/react/src/dashboard/components/pages/products-view/ProductView.tsx b/react/src/dashboard/components/pages/products-view/ProductView.tsx index 3eb805cbb..6654d87a4 100644 --- a/react/src/dashboard/components/pages/products-view/ProductView.tsx +++ b/react/src/dashboard/components/pages/products-view/ProductView.tsx @@ -17,18 +17,16 @@ import LoadingCard from '../../elements/loading-card/LoadingCard'; import StateNavLink from '../../../modules/state_router/StateNavLink'; import ProductDetailsBlock from './elements/ProductDetailsBlock'; import ToggleControl from '../../elements/forms/controls/ToggleControl'; -import Paginator from '../../../modules/paginator/components/Paginator'; import ProductFund from '../../../props/models/ProductFund'; import usePushApiError from '../../../hooks/usePushApiError'; import Label from '../../elements/image_cropper/Label'; import TableEntityMain from '../../elements/tables/elements/TableEntityMain'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableRowActions from '../../elements/tables/TableRowActions'; import classNames from 'classnames'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { NumberParam, StringParam } from 'use-query-params'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; type ProductFundLocal = ProductFund & { chat?: FundProviderChat; @@ -74,8 +72,6 @@ export default function ProductView() { }, ); - const { headElement, configsElement } = useConfigurableTable(productService.getFundsColumns(product)); - const deleteProduct = useCallback( (product: Product) => { openModal((modal) => ( @@ -121,7 +117,7 @@ export default function ProductView() { ): PaginationData => { return { ...funds, - data: funds.data.map((fund) => ({ + data: funds?.data?.map((fund) => ({ ...fund, chat: chats.data.find((chat) => fund.id == chat.fund_id), })), @@ -250,139 +246,101 @@ export default function ProductView() {
- {funds?.meta.total > 0 ? ( -
-
- {configsElement} - - - - {headElement} - - - {funds?.data?.map((fund) => ( - - - - {!product.sponsor_organization && fundToggles && ( - + + {funds?.data?.map((fund) => ( + + + + {!product.sponsor_organization && fundToggles && ( + + )} + + - - - ))} - -
- - - {fund.approved ? ( - - ) : ( - - )} - - { - setFundToggles((fundToggles) => ({ - ...fundToggles, - [fund.id]: !fundToggles[fund.id], - })); - changeFundExclusion(fund, fundToggles[fund.id]); - }} - /> -
+ + + {fund.approved ? ( + + ) : ( + + )} + + { + setFundToggles((fundToggles) => ({ + ...fundToggles, + [fund.id]: !fundToggles[fund.id], + })); + changeFundExclusion(fund, fundToggles[fund.id]); + }} + /> + + + + {!fund.chat &&    Geen berichten} + {fund.chat?.provider_unseen_messages > 0 && ( +    {`${fund.chat.provider_unseen_messages} nieuwe`} + )} + + ( + - ( - - )} - /> -
-
-
-
- ) : ( -
-
-
- Uw aanbod kan nog niet op een website worden geplaatst omdat u zich eerst voor een fonds - moet aanmelden. Meld u aan voor één of meerdere fondsen. -
-
-
- - - Bekijk beschikbare fondsen - -
-
-
-
- )} - - {funds?.meta && ( -
- -
- )} + href={`${fund.implementation.url_webshop}products/${product.id}`} + target="_blank" + rel="noreferrer"> + + {fund.provider_excluded ? 'Verborgen op webshop' : 'Bekijk op webshop'} + +
+ )} + /> + + + ))} +
); diff --git a/react/src/dashboard/components/pages/products/Products.tsx b/react/src/dashboard/components/pages/products/Products.tsx index 34c32d10d..7f36bafd4 100644 --- a/react/src/dashboard/components/pages/products/Products.tsx +++ b/react/src/dashboard/components/pages/products/Products.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import LoadingCard from '../../elements/loading-card/LoadingCard'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; import useSetProgress from '../../../hooks/useSetProgress'; import useProductService from '../../../services/ProductService'; import Product from '../../../props/models/Product'; @@ -8,12 +9,9 @@ import { PaginationData } from '../../../props/ApiResponses'; import useAppConfigs from '../../../hooks/useAppConfigs'; import useOpenModal from '../../../hooks/useOpenModal'; import StateNavLink from '../../../modules/state_router/StateNavLink'; -import Paginator from '../../../modules/paginator/components/Paginator'; import ModalNotification from '../../modals/ModalNotification'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; import useTranslate from '../../../hooks/useTranslate'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; import TableRowActions from '../../elements/tables/TableRowActions'; import classNames from 'classnames'; import BlockLabelTabs from '../../elements/block-label-tabs/BlockLabelTabs'; @@ -83,11 +81,6 @@ export default function Products() { }, ); - const { headElement, configsElement } = useConfigurableTable(productService.getColumns(), { - sortable: true, - filter: filter, - }); - const deleteProduct = useCallback( function (product: Product) { openModal((modal) => ( @@ -138,7 +131,7 @@ export default function Products() {
- {translate('products.offers')} ({products.meta.total}) + {translate('products.offers')} ({products?.meta?.total})
@@ -146,13 +139,18 @@ export default function Products() { {translate('products.add')} {productSoftLimitReached - ? ` (${products.meta.total_provider} / ${maxProductHardLimit})` + ? ` (${products?.meta?.total_provider} / ${maxProductHardLimit})` : ``} @@ -181,178 +179,133 @@ export default function Products() {
- {loading && ( -
-
-
-
-
- )} - - {!loading && products?.meta.total > 0 && ( -
- {configsElement} - - - - {headElement} - - - {products?.data.map((product) => ( - - - - - {product?.price_type === 'informational' ? ( - - ) : ( - - )} - - - - - - - - + + + {product?.price_type === 'informational' ? ( + + ) : ( + + )} + + + + + + + + - - ))} - -
{product.id} - - - - - {product.unlimited_stock - ? translate('product_edit.labels.unlimited') - : product.stock_amount} - {product.price_locale} - {product.expire_at_locale ? product.expire_at_locale : 'Geen'} - - {product.expired ? 'Ja' : 'Nee'} - - {filterValues.source != 'archive' ? ( - ( -
- -
- Bekijk - - - -
- Bewerking - - - {product.sponsor_organization ? ( -
{ - deleteProduct(product); - e.close(); - }}> - - Verwijderen -
- ) : ( - 0) && 'disabled', - )}> - - Bericht - - )} -
- )} - /> + + {products?.data?.map((product) => ( + +
{product.id} + + + + + {product.unlimited_stock + ? translate('product_edit.labels.unlimited') + : product.stock_amount} + {product.price_locale} + {product.expire_at_locale ? product.expire_at_locale : 'Geen'} + + {product.expired ? 'Ja' : 'Nee'} + + {filterValues.source != 'archive' ? ( + ( +
+ +
+ Bekijk + + + +
+ Bewerking + + + {product.sponsor_organization ? ( +
{ + deleteProduct(product); + e.close(); + }}> + + Verwijderen +
) : ( - - {translate('organization_employees.labels.owner')} - + 0) && 'disabled', + )}> + + Bericht + )} -
-
-
- )} - - {!loading && filterValues.source == 'provider' && products.meta.total == 0 && !filterValuesActive.q && ( -
-
Er zijn momenteel geen aanbiedingen.
-
- - - Aanbieding toevoegen +
+ )} + /> + ) : ( + {translate('organization_employees.labels.owner')} + )} + -
- )} - - {!loading && filterValues.source == 'provider' && products.meta.total == 0 && filterValuesActive.q && ( -
-
Er zijn geen aanbiedingen gevonden voor de zoekopdracht.
-
- )} - - {!loading && filterValues.source == 'sponsor' && products.meta.total == 0 && ( -
-
Er zijn momenteel geen aanbiedingen.
-
- )} - - {!loading && filterValues.source == 'archive' && products.meta.total == 0 && ( -
-
Er zijn momenteel geen aanbiedingen.
-
- )} - - {!loading && products?.meta && ( -
- -
- )} + ))} +
); } diff --git a/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundInvitationsTable.tsx b/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundInvitationsTable.tsx index 0c9c71659..50271f030 100644 --- a/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundInvitationsTable.tsx +++ b/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundInvitationsTable.tsx @@ -1,9 +1,9 @@ import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react'; +import classNames from 'classnames'; import { PaginationData } from '../../../../props/ApiResponses'; import Organization from '../../../../props/models/Organization'; import useSetProgress from '../../../../hooks/useSetProgress'; import usePushSuccess from '../../../../hooks/usePushSuccess'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import useAssetUrl from '../../../../hooks/useAssetUrl'; import TableCheckboxControl from '../../../elements/tables/elements/TableCheckboxControl'; import FundProviderInvitation from '../../../../props/models/FundProviderInvitation'; @@ -11,10 +11,8 @@ import useFundProviderInvitationsService from '../../../../services/useFundProvi import { strLimit } from '../../../../helpers/string'; import useTableToggles from '../../../../hooks/useTableToggles'; import usePaginatorService from '../../../../modules/paginator/services/usePaginatorService'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import useTranslate from '../../../../hooks/useTranslate'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import usePushApiError from '../../../../hooks/usePushApiError'; import Label, { LabelType } from '../../../elements/image_cropper/Label'; @@ -86,21 +84,6 @@ export default function ProviderFundInvitationsTable({ }; }, [invitations?.data, selected]); - const { headElement, configsElement } = useConfigurableTable(fundProviderInvitationsService.getColumns(), { - trPrepend: ( - - {[null, 'pending'].includes(filterValues.state) && ( - - toggleAll(e, invitations?.data)} - /> - - )} - - ), - }); - const mapProviderFunds = useCallback( ( items: Array, @@ -191,7 +174,7 @@ export default function ProviderFundInvitationsTable({ {translate(`provider_funds.title.${type}`)} {!loading && selected.length > 0 && ` (${selected.length}/${invitations.data.length})`} - {!loading && selected.length == 0 && ` (${invitations.meta.total})`} + {!loading && selected.length == 0 && ` (${invitations?.meta?.total})`}
@@ -220,121 +203,99 @@ export default function ProviderFundInvitationsTable({
- {!loading && invitations.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {invitations.data?.map((invitation) => ( - - {[null, 'pending'].includes(filterValues.state) && ( - - )} - - - - - - - - {type === 'invitations' && invitation.can_be_accepted ? ( - - ) : ( - - )} - - ))} - -
- toggle(e, invitation)} - /> - -
-
- -
-
-
- {strLimit(invitation.fund.name, 32)} -
- - {strLimit(invitation.fund.implementation?.name, 32)} - -
-
-
- {strLimit(invitation.fund?.organization?.name, 25)} - - - {invitation.fund?.start_date_locale} - - - - {invitation.fund?.end_date_locale} - - - - -
-
acceptInvitations([invitation])}> - - {translate('provider_funds.labels.accept_invitation')} -
-
-
- -
-
-
-
- )} - - {loading && ( -
-
-
-
-
- )} + + {[null, 'pending'].includes(filterValues.state) && ( + + toggleAll(e, invitations?.data)} + /> + + )} + + ), + }} + paginator={{ key: paginatorKey, data: invitations, filterValues, filterUpdate }}> + {invitations?.data?.map((invitation) => ( + + {[null, 'pending'].includes(filterValues.state) && ( + + toggle(e, invitation)} + /> + + )} + +
+
+ +
+
+
+ {strLimit(invitation.fund.name, 32)} +
+ + {strLimit(invitation.fund.implementation?.name, 32)} + +
+
+ - {!loading && invitations?.meta?.total == 0 && ( - - )} + + {strLimit(invitation.fund?.organization?.name, 25)} + - {invitations?.meta && ( -
- -
- )} + + + {invitation.fund?.start_date_locale} + + + + + {invitation.fund?.end_date_locale} + + + + + + {type === 'invitations' && invitation.can_be_accepted ? ( + +
+
acceptInvitations([invitation])}> + + {translate('provider_funds.labels.accept_invitation')} +
+
+ + ) : ( + + + + )} + + ))} +
); } diff --git a/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsAvailableTable.tsx b/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsAvailableTable.tsx index cf3d249f2..481ad813b 100644 --- a/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsAvailableTable.tsx +++ b/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsAvailableTable.tsx @@ -1,9 +1,9 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import classNames from 'classnames'; import { PaginationData } from '../../../../props/ApiResponses'; import Organization from '../../../../props/models/Organization'; import useProviderFundService from '../../../../services/ProviderFundService'; import useSetProgress from '../../../../hooks/useSetProgress'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import useAssetUrl from '../../../../hooks/useAssetUrl'; import { strLimit } from '../../../../helpers/string'; import TableCheckboxControl from '../../../elements/tables/elements/TableCheckboxControl'; @@ -15,10 +15,8 @@ import SelectControl from '../../../elements/select-control/SelectControl'; import useTableToggles from '../../../../hooks/useTableToggles'; import Implementation from '../../../../props/models/Implementation'; import usePaginatorService from '../../../../modules/paginator/services/usePaginatorService'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import useTranslate from '../../../../hooks/useTranslate'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import usePushApiError from '../../../../hooks/usePushApiError'; import useFilterNext from '../../../../modules/filter_next/useFilterNext'; import { NumberParam, StringParam } from 'use-query-params'; @@ -94,19 +92,6 @@ export default function ProviderFundsAvailableTable({ const { resetFilters: resetFilters } = filter; - const { headElement, configsElement } = useConfigurableTable(providerFundService.getColumnsAvailable(), { - filter: filter, - sortable: true, - trPrepend: ( - - toggleAll(e, funds?.data)} - /> - - ), - }); - const fetchFunds = useCallback(() => { setSelected([]); setLoading(true); @@ -210,7 +195,7 @@ export default function ProviderFundsAvailableTable({ {translate(`provider_funds.title.available`)} {!loading && selected.length > 0 && ` (${selected.length}/${funds.data.length})`} - {!loading && selected.length == 0 && ` (${funds.meta.total})`} + {!loading && selected.length == 0 && ` (${funds?.meta?.total})`}
@@ -298,114 +283,88 @@ export default function ProviderFundsAvailableTable({
- {!loading && funds.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {funds.data?.map((fund) => ( - - - - - - - - - - - - - - ))} - -
- toggle(e, fund)} - /> - -
-
- -
-
-
- {strLimit(fund.name, 32)} -
- - {strLimit(fund.implementation?.name, 32)} - -
-
-
- {strLimit(fund.organization?.name, 25)} - - - {fund.start_date_locale} - - - - {fund.end_date_locale} - - -
- {fund.state != 'closed' && ( - - )} -
-
-
-
-
- )} - - {loading && ( -
-
-
-
-
- )} - - {!loading && funds?.meta?.total == 0 && ( - - )} - - {!loading && funds?.meta && ( -
- -
- )} + + toggleAll(e, funds?.data)} + /> + + ), + }} + paginator={{ key: paginatorKey, data: funds, filterValues, filterUpdate }}> + {funds?.data?.map((fund) => ( + + + toggle(e, fund)} + /> + + + +
+
+ +
+
+
+ {strLimit(fund.name, 32)} +
+ + {strLimit(fund.implementation?.name, 32)} + +
+
+ + + {strLimit(fund.organization?.name, 25)} + + + {fund.start_date_locale} + + + + {fund.end_date_locale} + + + +
+ {fund.state != 'closed' && ( + + )} +
+ + + ))} +
); } diff --git a/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsTable.tsx b/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsTable.tsx index 1d41504de..ffb8b0b12 100644 --- a/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsTable.tsx +++ b/react/src/dashboard/components/pages/provider-funds/elements/ProviderFundsTable.tsx @@ -1,11 +1,11 @@ import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react'; +import classNames from 'classnames'; import { PaginationData } from '../../../../props/ApiResponses'; import FundProvider from '../../../../props/models/FundProvider'; import Organization from '../../../../props/models/Organization'; import useProviderFundService from '../../../../services/ProviderFundService'; import useSetProgress from '../../../../hooks/useSetProgress'; import usePushSuccess from '../../../../hooks/usePushSuccess'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import useAssetUrl from '../../../../hooks/useAssetUrl'; import { strLimit } from '../../../../helpers/string'; import TableCheckboxControl from '../../../elements/tables/elements/TableCheckboxControl'; @@ -15,10 +15,8 @@ import ModalFundOffers from '../../../modals/ModalFundOffers'; import ModalFundUnsubscribe from '../../../modals/ModalFundUnsubscribe'; import useTableToggles from '../../../../hooks/useTableToggles'; import usePaginatorService from '../../../../modules/paginator/services/usePaginatorService'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import useTranslate from '../../../../hooks/useTranslate'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import TableRowActions from '../../../elements/tables/TableRowActions'; import usePushApiError from '../../../../hooks/usePushApiError'; @@ -73,21 +71,6 @@ export default function ProviderFundsTable({ }; }, [providerFunds?.data, selected]); - const { headElement, configsElement } = useConfigurableTable(providerFundService.getColumns(type), { - trPrepend: ( - - {type !== 'archived' && ( - - toggleAll(e, providerFunds?.data)} - /> - - )} - - ), - }); - const viewOffers = useCallback( (providerFund: FundProvider) => { openModal((modal) => ( @@ -241,7 +224,7 @@ export default function ProviderFundsTable({ {translate(`provider_funds.title.${type}`)} {!loading && selected.length > 0 && ` (${selected.length}/${providerFunds.data.length})`} - {!loading && selected.length == 0 && ` (${providerFunds.meta.total})`} + {!loading && selected.length == 0 && ` (${providerFunds?.meta?.total})`}
@@ -271,211 +254,181 @@ export default function ProviderFundsTable({
- {!loading && providerFunds.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {providerFunds.data?.map((providerFund) => ( - - {type !== 'archived' && ( - - )} - + )} + + ), + }} + paginator={{ key: paginatorKey, data: providerFunds, filterValues, filterUpdate }}> + {providerFunds?.data?.map((providerFund) => ( + + {type !== 'archived' && ( + + )} + + + + + {type === 'active' && ( + + )} + + + {!providerFund.fund.archived && !providerFund.fund.expired && ( + + )} + + {(providerFund.fund.archived || providerFund.fund.expired) && ( + + )} + + {type !== 'archived' ? ( + - - - - {type === 'active' && ( - - )} - - - {!providerFund.fund.archived && !providerFund.fund.expired && ( - )} - {(providerFund.fund.archived || providerFund.fund.expired) && ( - + {type == 'active' && ( +
{ + unsubscribe(providerFund); + e.close(); + }}> + + Uitschrijven +
)} - {type !== 'archived' ? ( - - ) : ( - + {providerFund.can_cancel && ( +
{ + cancelApplications([providerFund]); + e.close(); + }}> + + Annuleren +
)} -
- ))} - -
- toggle(e, providerFund)} - /> - -
-
- -
-
-
- {strLimit(providerFund.fund.name, 32)} -
- - {strLimit(providerFund.fund.implementation?.name, 32)} - + + {type !== 'archived' && ( +
+ toggleAll(e, providerFunds?.data)} + /> +
+ toggle(e, providerFund)} + /> + +
+
+ +
+
+
+ {strLimit(providerFund.fund.name, 32)} +
+ + {strLimit(providerFund.fund.implementation?.name, 32)} + +
+
+
+ {strLimit(providerFund.fund?.organization?.name, 25)} + + + {providerFund.fund?.start_date_locale} + + + + {providerFund.fund?.end_date_locale} + + {providerFund.fund?.fund_amount_locale || '-'}{providerFund.allow_budget ? 'Ja' : 'Nee'}{providerFund.allow_some_products || providerFund.allow_products ? 'Ja' : 'Nee'} + {providerFund.state == 'accepted' && ( + + )} + + {providerFund.state == 'pending' && ( + + )} + + {providerFund.state == 'rejected' && ( + + )} + + {providerFund.state == 'unsubscribed' && ( + + )} + + + + ( +
+ {providerFund.fund.state != 'closed' && + providerFund.state === 'unsubscribed' && ( +
{ + applyFund(providerFund); + e.close(); + }}> + + {translate('provider_funds.buttons.join_unsubscribed')}
+ )} + + {providerFund.fund.state != 'closed' && ( +
{ + viewOffers(providerFund); + e.close(); + }}> + + Bekijk
-
- {strLimit(providerFund.fund?.organization?.name, 25)} - - - {providerFund.fund?.start_date_locale} - - - - {providerFund.fund?.end_date_locale} - - - {providerFund.fund?.fund_amount_locale || '-'} - {providerFund.allow_budget ? 'Ja' : 'Nee'} - {providerFund.allow_some_products || providerFund.allow_products - ? 'Ja' - : 'Nee'} - - {providerFund.state == 'accepted' && ( - - )} - - {providerFund.state == 'pending' && ( - - )} - - {providerFund.state == 'rejected' && ( - - )} - - {providerFund.state == 'unsubscribed' && ( - - )} - - - - ( -
- {providerFund.fund.state != 'closed' && - providerFund.state === 'unsubscribed' && ( -
{ - applyFund(providerFund); - e.close(); - }}> - - {translate( - 'provider_funds.buttons.join_unsubscribed', - )} -
- )} - - {providerFund.fund.state != 'closed' && ( -
{ - viewOffers(providerFund); - e.close(); - }}> - - Bekijk -
- )} - - {type == 'active' && ( -
{ - unsubscribe(providerFund); - e.close(); - }}> - - Uitschrijven -
- )} - - {providerFund.can_cancel && ( -
{ - cancelApplications([providerFund]); - e.close(); - }}> - - Annuleren -
- )} -
- )} - /> -
- -
-
-
-
- )} - - {loading && ( -
-
-
-
-
- )} - - {!loading && providerFunds?.meta?.total == 0 && ( - - )} - - {providerFunds?.meta && ( -
- -
- )} +
+ )} + /> + + ) : ( + + + + )} + + ))} +
); } diff --git a/react/src/dashboard/components/pages/provider-overview/ProviderOverview.tsx b/react/src/dashboard/components/pages/provider-overview/ProviderOverview.tsx index 484af10ae..43b39c915 100644 --- a/react/src/dashboard/components/pages/provider-overview/ProviderOverview.tsx +++ b/react/src/dashboard/components/pages/provider-overview/ProviderOverview.tsx @@ -14,6 +14,7 @@ import { hasPermission } from '../../../helpers/utils'; import ProductsRequiredNotification from './elements/ProductsRequiredNotification'; import { Permission } from '../../../props/models/Organization'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import classNames from 'classnames'; export default function ProviderOverview() { const envData = useEnvData(); @@ -101,9 +102,11 @@ export default function ProviderOverview() { diff --git a/react/src/dashboard/components/pages/reimbursements-view/ReimbursementsView.tsx b/react/src/dashboard/components/pages/reimbursements-view/ReimbursementsView.tsx index ab54d7e44..db04a656e 100644 --- a/react/src/dashboard/components/pages/reimbursements-view/ReimbursementsView.tsx +++ b/react/src/dashboard/components/pages/reimbursements-view/ReimbursementsView.tsx @@ -25,6 +25,7 @@ import usePushApiError from '../../../hooks/usePushApiError'; import ReimbursementStateLabel from '../../elements/resource-states/ReimbursementStateLabel'; import { Permission } from '../../../props/models/Organization'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import classNames from 'classnames'; export default function ReimbursementsView() { const { id } = useParams(); @@ -328,11 +329,10 @@ export default function ReimbursementsView() {
{activeOrganization.bsn_enabled ? (
+ className={classNames( + 'text-semibold', + reimbursement.identity_bsn ? 'text-black' : 'text-muted', + )}> {reimbursement.identity_bsn || 'Geen BSN'}
) : ( @@ -356,9 +356,10 @@ export default function ReimbursementsView() { {translate('reimbursements.labels.employee')}
+ className={classNames( + 'text-semibold', + reimbursement.employee_id ? 'text-black' : 'text-muted', + )}> {reimbursement.employee?.email || 'Niet toegewezen'}
diff --git a/react/src/dashboard/components/pages/reimbursements/Reimbursements.tsx b/react/src/dashboard/components/pages/reimbursements/Reimbursements.tsx index 199252c28..588944cc2 100644 --- a/react/src/dashboard/components/pages/reimbursements/Reimbursements.tsx +++ b/react/src/dashboard/components/pages/reimbursements/Reimbursements.tsx @@ -9,9 +9,6 @@ import usePaginatorService from '../../../modules/paginator/services/usePaginato import { useFundService } from '../../../services/FundService'; import FilterItemToggle from '../../elements/tables/elements/FilterItemToggle'; import SelectControl from '../../elements/select-control/SelectControl'; -import { hasPermission } from '../../../helpers/utils'; -import EmptyCard from '../../elements/empty-card/EmptyCard'; -import { getStateRouteUrl } from '../../../modules/state_router/Router'; import useReimbursementsExporter from '../../../services/exporters/useReimbursementsExporter'; import useImplementationService from '../../../services/ImplementationService'; import DatePickerControl from '../../elements/forms/controls/DatePickerControl'; @@ -25,7 +22,6 @@ import CardHeaderFilter from '../../elements/tables/elements/CardHeaderFilter'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { createEnumParam, NumberParam, StringParam } from 'use-query-params'; import ReimbursementsTable from './elements/ReimbursementsTable'; -import { Permission } from '../../../props/models/Organization'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; import BlockLabelTabs from '../../elements/block-label-tabs/BlockLabelTabs'; @@ -365,24 +361,6 @@ export default function Reimbursements() { filterUpdate={filterUpdate} />
- - {funds?.length == 0 && ( - - {hasPermission(activeOrganization, Permission.MANAGE_FUNDS) ? ( - - ) : ( - - )} - - )} ); } diff --git a/react/src/dashboard/components/pages/reimbursements/elements/ReimbursementsTable.tsx b/react/src/dashboard/components/pages/reimbursements/elements/ReimbursementsTable.tsx index aae5814b7..4f273499d 100644 --- a/react/src/dashboard/components/pages/reimbursements/elements/ReimbursementsTable.tsx +++ b/react/src/dashboard/components/pages/reimbursements/elements/ReimbursementsTable.tsx @@ -1,7 +1,5 @@ import React from 'react'; import Organization from '../../../../props/models/Organization'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import { PaginationData } from '../../../../props/ApiResponses'; import { FilterModel, FilterSetter } from '../../../../modules/filter_next/types/FilterParams'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; @@ -12,7 +10,6 @@ import TableRowActions from '../../../elements/tables/TableRowActions'; import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; import { useReimbursementsService } from '../../../../services/ReimbursementService'; import Reimbursement from '../../../../props/models/Reimbursement'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import ReimbursementStateLabel from '../../../elements/resource-states/ReimbursementStateLabel'; import Label from '../../../elements/image_cropper/Label'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; @@ -34,144 +31,107 @@ export default function ReimbursementsTable({ }) { const reimbursementService = useReimbursementsService(); - const { headElement, configsElement } = useConfigurableTable(reimbursementService.getColumns()); - return ( -
-
- {configsElement} - - - - {headElement} - - - {reimbursements.data.map((reimbursement) => ( + empty={reimbursements?.meta?.total == 0} + emptyTitle={'Geen declaraties gevonden'} + columns={reimbursementService.getColumns()} + paginator={{ key: paginatorKey, data: reimbursements, filterValues, filterUpdate }}> + {reimbursements?.data?.map((reimbursement) => ( + + + + + + + + + + + + + + + + + + + - - - {/* Amount */} - - - - - - - - - - - - - - - + className="dropdown-item" + params={{ + id: reimbursement.id, + organizationId: organization.id, + }}> + Bekijken - ))} - -
+
+ {strLimit(reimbursement.identity_email, 25) || 'Geen E-mail'} +
+ + {organization.bsn_enabled && ( +
+ {reimbursement.identity_bsn ? 'BSN: ' + reimbursement.identity_bsn : 'Geen BSN'} +
+ )} +
+
{strLimit(reimbursement.fund.name, 25)}
+
+ {strLimit(reimbursement.implementation_name, 25)} +
+
+ {reimbursement.amount_locale} + +
+ {reimbursement.created_at_locale.split(' - ')[0]} +
+
+ {reimbursement.created_at_locale.split(' - ')[1]} +
+
{reimbursement.lead_time_locale} + {strLimit(reimbursement.employee?.email || 'Niet toegewezen', 25)} + + {reimbursement.expired ? 'Ja' : 'Nee'} + + + + {reimbursement.voucher_transaction?.state == 'pending' && ( + + )} + + {reimbursement.voucher_transaction?.state == 'success' && ( + + )} + + {reimbursement.voucher_transaction?.state == 'canceled' && ( + + )} + + {!reimbursement.voucher_transaction && } + + ( +
-
- {/* Email */} -
- {strLimit(reimbursement.identity_email, 25) || 'Geen E-mail'} -
- - {/* BSN */} - {organization.bsn_enabled && ( -
- {reimbursement.identity_bsn - ? 'BSN: ' + reimbursement.identity_bsn - : 'Geen BSN'} -
- )} -
-
- {strLimit(reimbursement.fund.name, 25)} -
-
- {strLimit(reimbursement.implementation_name, 25)} -
-
- {reimbursement.amount_locale} - -
- {reimbursement.created_at_locale.split(' - ')[0]} -
-
- {reimbursement.created_at_locale.split(' - ')[1]} -
-
{reimbursement.lead_time_locale} - {strLimit(reimbursement.employee?.email || 'Niet toegewezen', 25)} - - {reimbursement.expired ? 'Ja' : 'Nee'} - - - - {reimbursement.voucher_transaction?.state == 'pending' && ( - - )} - - {reimbursement.voucher_transaction?.state == 'success' && ( - - )} - - {reimbursement.voucher_transaction?.state == 'canceled' && ( - - )} - - {!reimbursement.voucher_transaction && } - - ( -
- - Bekijken - -
- )} - /> -
-
-
-
- - {reimbursements.meta && ( -
- -
- )} +
+ )} + /> + + + ))} ); } diff --git a/react/src/dashboard/components/pages/reservations-view/elements/ReservationExtraPaymentRefundsCard.tsx b/react/src/dashboard/components/pages/reservations-view/elements/ReservationExtraPaymentRefundsCard.tsx index 79eb8344b..2339a62b1 100644 --- a/react/src/dashboard/components/pages/reservations-view/elements/ReservationExtraPaymentRefundsCard.tsx +++ b/react/src/dashboard/components/pages/reservations-view/elements/ReservationExtraPaymentRefundsCard.tsx @@ -2,20 +2,15 @@ import React from 'react'; import ExtraPaymentRefund from '../../../../props/models/ExtraPaymentRefund'; import useTranslate from '../../../../hooks/useTranslate'; import Label from '../../../elements/image_cropper/Label'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import useProductReservationService from '../../../../services/ProductReservationService'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function ReservationExtraPaymentRefundsCard({ refunds }: { refunds: Array }) { const translate = useTranslate(); const productReservationService = useProductReservationService(); - const { headElement, configsElement } = useConfigurableTable( - productReservationService.getExtraPaymentRefundsColumns(), - ); - return (
@@ -26,46 +21,33 @@ export default function ReservationExtraPaymentRefundsCard({ refunds }: { refund
-
-
- {configsElement} - - - - {headElement} - - - {refunds?.map((refund) => ( - - - - - - - ))} - -
- - {refund.created_at_locale} - - {refund.amount_locale} - {refund.state == 'refunded' && ( - - )} - - {['canceled', 'failed'].includes(refund.state) && ( - - )} - - {!['refunded', 'canceled', 'failed'].includes(refund.state) && ( - - )} - - -
-
-
-
+ + {refunds?.map((refund) => ( + + + {refund.created_at_locale} + + {refund.amount_locale} + + {refund.state == 'refunded' && } + + {['canceled', 'failed'].includes(refund.state) && ( + + )} + + {!['refunded', 'canceled', 'failed'].includes(refund.state) && ( + + )} + + + + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/reservations-view/elements/panes/ReservationExtraInformationPane.tsx b/react/src/dashboard/components/pages/reservations-view/elements/panes/ReservationExtraInformationPane.tsx index 37f70e1d1..6d9d84c4e 100644 --- a/react/src/dashboard/components/pages/reservations-view/elements/panes/ReservationExtraInformationPane.tsx +++ b/react/src/dashboard/components/pages/reservations-view/elements/panes/ReservationExtraInformationPane.tsx @@ -1,4 +1,5 @@ import React, { Dispatch, SetStateAction, useCallback, useMemo } from 'react'; +import classNames from 'classnames'; import Organization from '../../../../../props/models/Organization'; import Reservation, { ReservationCustomFieldValue } from '../../../../../props/models/Reservation'; import KeyValueItem from '../../../../elements/key-value/KeyValueItem'; @@ -107,7 +108,7 @@ export default function ReservationExtraInformationPane({ editCustomFieldValue(field)} - className={field.file ? 'flex flex-grow' : null} + className={classNames(field.file && 'flex flex-grow')} editDusk={`editCustomFieldBtn${field.id}`}> {field.file ? ( diff --git a/react/src/dashboard/components/pages/reservations/elements/ReservationsTable.tsx b/react/src/dashboard/components/pages/reservations/elements/ReservationsTable.tsx index 491208bf9..e72755d7c 100644 --- a/react/src/dashboard/components/pages/reservations/elements/ReservationsTable.tsx +++ b/react/src/dashboard/components/pages/reservations/elements/ReservationsTable.tsx @@ -1,16 +1,14 @@ import React, { ReactNode, useMemo } from 'react'; import { PaginationData } from '../../../../props/ApiResponses'; import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import TableCheckboxControl from '../../../elements/tables/elements/TableCheckboxControl'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import Organization from '../../../../props/models/Organization'; import { FilterModel, FilterScope, FilterSetter } from '../../../../modules/filter_next/types/FilterParams'; import Reservation from '../../../../props/models/Reservation'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import useProductReservationService from '../../../../services/ProductReservationService'; import ReservationsTableRowProvider from './ReservationsTableRowProvider'; import ReservationsTableRowSponsor from './ReservationsTableRowSponsor'; +import Paginator from '../../../../modules/paginator/components/Paginator'; export default function ReservationsTable({ fetchReservations, @@ -52,60 +50,48 @@ export default function ReservationsTable({ return organization.can_view_provider_extra_payments || hasExtraPaymentsOnPage; }, [organization, reservations]); - const { headElement, configsElement } = useConfigurableTable( - productReservationService.getColumns(showExtraPayments, type === 'sponsor'), - { - filter: filter, - sortable: true, - trPrepend: toggleAll ? ( - - toggleAll(e, reservations?.data)} - /> - - ) : null, - }, - ); - return ( - - {reservations.meta.total > 0 && ( -
- {configsElement} - - - - {headElement} - - - {reservations.data?.map((reservation) => - type === 'sponsor' ? ( - - ) : ( - - ), - )} - -
-
-
- )} + <> + + toggleAll(e, reservations?.data)} + /> + + ) : null, + }}> + {reservations?.data?.map((reservation) => + type === 'sponsor' ? ( + + ) : ( + + ), + )} + {children} @@ -119,6 +105,6 @@ export default function ReservationsTable({ />
)} - + ); } diff --git a/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCard.tsx b/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCard.tsx index 4d7c0e017..9883bca16 100644 --- a/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCard.tsx +++ b/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCard.tsx @@ -3,16 +3,14 @@ import React, { useState } from 'react'; import useTranslate from '../../../../hooks/useTranslate'; import BlockLabelTabs from '../../../elements/block-label-tabs/BlockLabelTabs'; import ProductMonitoredHistoryCardItem from './ProductMonitoredHistoryCardItem'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import { useFundService } from '../../../../services/FundService'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function ProductMonitoredHistoryCard({ product }: { product: SponsorProduct }) { const translate = useTranslate(); const [historyView, setHistoryView] = useState<'compare' | 'diff'>('compare'); const fundService = useFundService(); - const { headElement, configsElement } = useConfigurableTable(fundService.getProductHistoryColumns()); return (
@@ -30,35 +28,14 @@ export default function ProductMonitoredHistoryCard({ product }: { product: Spon />
- {product?.monitored_history?.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {product?.monitored_history?.map((item, id) => ( - - ))} - -
-
-
-
- )} - - {product?.monitored_history.length == 0 && ( -
-
Er zijn geen wijzigingen geregistreerd.
-
- )} + + {product?.monitored_history?.map((item, id) => ( + + ))} +
); } diff --git a/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCardFunds.tsx b/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCardFunds.tsx index f14f33f6e..67358d299 100644 --- a/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCardFunds.tsx +++ b/react/src/dashboard/components/pages/sponsor-product/elements/ProductMonitoredHistoryCardFunds.tsx @@ -1,16 +1,15 @@ import React, { Fragment } from 'react'; import SponsorProduct from '../../../../props/models/Sponsor/SponsorProduct'; import TableEntityMain from '../../../elements/tables/elements/TableEntityMain'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import TableRowActions from '../../../elements/tables/TableRowActions'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import { useFundService } from '../../../../services/FundService'; import Organization from '../../../../props/models/Organization'; import classNames from 'classnames'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import Label from '../../../elements/image_cropper/Label'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function ProductMonitoredHistoryCardFunds({ type = 'card', @@ -22,120 +21,113 @@ export default function ProductMonitoredHistoryCardFunds({ activeOrganization: Organization; }) { const fundService = useFundService(); - const { headElement, configsElement } = useConfigurableTable(fundService.getColumnsProductFunds(), { - hasTooltips: type !== 'table', - }); const tableElement = ( - - - {headElement} - - - {product.funds?.map((fund) => ( - - - + - - + + - - ))} - -
- - - {fund.implementation ? ( - - {fund.state === 'approved' ? ( - e.stopPropagation()} - className="text-primary text-semibold flex flex-gap-sm text-underline" - href={fund.url_product} - target={'_blank'} - rel="noreferrer"> - {fund.implementation?.name} - - - ) : ( - fund.implementation?.name - )} - + + {product.funds?.map((fund) => ( + + + + + {fund.implementation ? ( + + {fund.state === 'approved' ? ( + e.stopPropagation()} + className="text-primary text-semibold flex flex-gap-sm text-underline" + href={fund.url_product} + target={'_blank'} + rel="noreferrer"> + {fund.implementation?.name} + + ) : ( - + fund.implementation?.name )} - - {fund.state === 'approved' && } - {fund.state === 'pending' && } - {fund.state === 'not_applied' && } - - ( -
- {fund.fund_provider_id && ( - - Bekijk aanbod - - )} + + ) : ( + + )} +
+ {fund.state === 'approved' && } + {fund.state === 'pending' && } + {fund.state === 'not_applied' && } + + ( +
+ {fund.fund_provider_id && ( + + Bekijk aanbod + + )} - {fund.fund_provider_id && ( - - Bekijk aanbieder - - )} + {fund.fund_provider_id && ( + + Bekijk aanbieder + + )} - {fund.state === 'approved' && fund.url_product && ( - - Bekijk aanbod op webshop - - )} -
+ {fund.state === 'approved' && fund.url_product && ( + + Bekijk aanbod op webshop + )} - /> -
-
+
+ )} + /> + + + ))} + ); if (type === 'table') { @@ -158,12 +150,7 @@ export default function ProductMonitoredHistoryCardFunds({
-
-
- {configsElement} - {tableElement} -
-
+ {tableElement}
); } diff --git a/react/src/dashboard/components/pages/sponsor-products/SponsorProducts.tsx b/react/src/dashboard/components/pages/sponsor-products/SponsorProducts.tsx index 4c30529e6..10ec93db7 100644 --- a/react/src/dashboard/components/pages/sponsor-products/SponsorProducts.tsx +++ b/react/src/dashboard/components/pages/sponsor-products/SponsorProducts.tsx @@ -1,10 +1,10 @@ import React, { Fragment, useCallback, useEffect, useState } from 'react'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import LoadingCard from '../../elements/loading-card/LoadingCard'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; import useSetProgress from '../../../hooks/useSetProgress'; import useProductService from '../../../services/ProductService'; import { PaginationData } from '../../../props/ApiResponses'; -import Paginator from '../../../modules/paginator/components/Paginator'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; import useTranslate from '../../../hooks/useTranslate'; import ClickOutside from '../../elements/click-outside/ClickOutside'; @@ -19,9 +19,7 @@ import DatePickerControl from '../../elements/forms/controls/DatePickerControl'; import { dateFormat, dateParse } from '../../../helpers/dates'; import { useFundService } from '../../../services/FundService'; import Fund from '../../../props/models/Fund'; -import EmptyCard from '../../elements/empty-card/EmptyCard'; import SelectControlOptionsFund from '../../elements/select-control/templates/SelectControlOptionsFund'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; import BlockLabelTabs from '../../elements/block-label-tabs/BlockLabelTabs'; export default function SponsorProducts() { @@ -101,10 +99,8 @@ export default function SponsorProducts() { }, ); - const columns = productService.getColumnsSponsor(view); - const { headElement, configsElement } = useConfigurableTable(columns); - const { resetFilters: resetFilters } = filter; + const columns = productService.getColumnsSponsor(view); const fetchProducts = useCallback(() => { setProgress(0); @@ -154,7 +150,7 @@ export default function SponsorProducts() {
- {translate('products.offers')} ({products.meta.total}) + {translate('products.offers')} ({products?.meta?.total})
@@ -329,50 +325,31 @@ export default function SponsorProducts() {
- {loading ? ( - - ) : ( - - {products?.meta?.total > 0 && ( -
-
- {configsElement} - - {view == 'products' ? ( - - ) : ( - - )} -
-
- )} - - {products?.meta?.total === 0 && ( - - )} - - {products?.meta && ( -
- -
- )} -
- )} + + {view == 'products' ? ( + + ) : ( + + )} +
); } diff --git a/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsChangesTable.tsx b/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsChangesTable.tsx index 737ba0041..e0370f89f 100644 --- a/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsChangesTable.tsx +++ b/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsChangesTable.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, ReactNode, useCallback, useRef, useState } from 'react'; +import React, { Fragment, useCallback, useState } from 'react'; import { strLimit } from '../../../../helpers/string'; import TableRowActions from '../../../elements/tables/TableRowActions'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; @@ -8,22 +8,18 @@ import { ConfigurableTableColumn } from '../../vouchers/hooks/useConfigurableTab import ProductMonitoredHistoryCardFunds from '../../sponsor-product/elements/ProductMonitoredHistoryCardFunds'; import TableEntityMain from '../../../elements/tables/elements/TableEntityMain'; import Organization from '../../../../props/models/Organization'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; export default function SponsorProductsChangesTable({ columns, products = null, - headElement = null, activeOrganization, }: { columns: Array; products: Array; - headElement: ReactNode; activeOrganization: Organization; }) { const [shownIds, setShownIds] = useState>([]); - const tableRef = useRef(null); const toggleCollapsed = useCallback((e: { stopPropagation: () => void }, id: number) => { e.stopPropagation(); @@ -33,84 +29,70 @@ export default function SponsorProductsChangesTable({ }); }, []); - return ( - tableRef.current?.click()}> - - {headElement} + return products?.map((product, index) => ( + + + - - {products?.map((product, index) => ( - - - + - + - + - + + - - - - {shownIds?.includes(product.id) && ( - - - - )} - - ))} - -
+ toggleCollapsed(e, product.id)} + collapsed={!shownIds.includes(product.id)} + /> +
- toggleCollapsed(e, product.id)} - collapsed={!shownIds.includes(product.id)} - /> - + + - - {product.monitored_changes_count}{product.monitored_changes_count} item.state === 'approved') + .map((fund) => fund.name) + ?.join(', ')}> +
+ {product.funds.filter((item) => item.state === 'approved').length}/{product.funds.length} +
+
item.state === 'approved') - .map((fund) => fund.name) - ?.join(', ')}> -
- {product.funds.filter((item) => item.state === 'approved').length}/ - {product.funds.length} -
-
+ ( +
+ + + Bekijk aanbod + +
+ )} + /> +
- ( -
- - - Bekijk aanbod - -
- )} - /> -
- -
-
- ); + {shownIds?.includes(product.id) && ( + + + + + + )} + + )); } diff --git a/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsTable.tsx b/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsTable.tsx index ce85d4df6..a029225fc 100644 --- a/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsTable.tsx +++ b/react/src/dashboard/components/pages/sponsor-products/elements/SponsorProductsTable.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, ReactNode, useCallback, useRef, useState } from 'react'; +import React, { Fragment, useCallback, useState } from 'react'; import { strLimit } from '../../../../helpers/string'; import TableRowActions from '../../../elements/tables/TableRowActions'; import useTranslate from '../../../../hooks/useTranslate'; @@ -10,24 +10,20 @@ import TableEntityMain from '../../../elements/tables/elements/TableEntityMain'; import { ConfigurableTableColumn } from '../../vouchers/hooks/useConfigurableTable'; import ProductMonitoredHistoryCardFunds from '../../sponsor-product/elements/ProductMonitoredHistoryCardFunds'; import Organization from '../../../../props/models/Organization'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; export default function SponsorProductsTable({ - columns = null, + columns, products = null, - headElement = null, activeOrganization, }: { columns: Array; products: Array; - headElement: ReactNode; activeOrganization: Organization; }) { const translate = useTranslate(); const [shownIds, setShownIds] = useState>([]); - const tableRef = useRef(null); const toggleCollapsed = useCallback((e: { stopPropagation: () => void }, id: number) => { e.stopPropagation(); @@ -37,112 +33,99 @@ export default function SponsorProductsTable({ }); }, []); - return ( - tableRef.current?.click()}> - - {headElement} + return products?.map((product) => ( + + + - - {products?.map((product) => ( - - - + - + - + - + {product?.price_type === 'informational' ? ( + + ) : ( + + )} - {product?.price_type === 'informational' ? ( - - ) : ( - - )} + - + - + + - - - - {shownIds?.includes(product.id) && ( - - - - )} - - ))} - -
+ toggleCollapsed(e, product.id)} + collapsed={!shownIds.includes(product.id)} + /> +
- toggleCollapsed(e, product.id)} - collapsed={!shownIds.includes(product.id)} - /> - + + - - item.state === 'approved') + .map((fund) => fund.name) + ?.join(', ')}> +
+ {product.funds.filter((item) => item.state === 'approved').length}/{product.funds.length} +
+
item.state === 'approved') - .map((fund) => fund.name) - ?.join(', ')}> -
- {product.funds.filter((item) => item.state === 'approved').length}/ - {product.funds.length} -
-
{product.price_locale}{product.price_locale} + + + {product.unlimited_stock ? translate('product_edit.labels.unlimited') : product.stock_amount} + - - - {product.unlimited_stock - ? translate('product_edit.labels.unlimited') - : product.stock_amount} - {product.product_category?.name || }{product.product_category?.name || } + + - - + ( +
+ + + Bekijk aanbieder + + + + Bekijk aanbod + +
+ )} + /> +
- ( -
- - - Bekijk aanbieder - - - - Bekijk aanbod - -
- )} - /> -
- -
-
- ); + {shownIds?.includes(product.id) && ( + + + + + + )} + + )); } diff --git a/react/src/dashboard/components/pages/sponsor-provider-organization/SponsorProviderOrganization.tsx b/react/src/dashboard/components/pages/sponsor-provider-organization/SponsorProviderOrganization.tsx index 90711ede3..bf6b39df3 100644 --- a/react/src/dashboard/components/pages/sponsor-provider-organization/SponsorProviderOrganization.tsx +++ b/react/src/dashboard/components/pages/sponsor-provider-organization/SponsorProviderOrganization.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'; +import React, { Fragment, useCallback, useEffect, useState } from 'react'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import { PaginationData } from '../../../props/ApiResponses'; import { useParams } from 'react-router'; @@ -6,22 +6,19 @@ import useSetProgress from '../../../hooks/useSetProgress'; import { useOrganizationService } from '../../../services/OrganizationService'; import FundProvider from '../../../props/models/FundProvider'; import StateNavLink from '../../../modules/state_router/StateNavLink'; -import Paginator from '../../../modules/paginator/components/Paginator'; import FundProviderTableItem from './elements/FundProviderTableItem'; import LoadingCard from '../../elements/loading-card/LoadingCard'; import ProviderOrganizationOverview from './elements/ProviderOrganizationOverview'; import type { SponsorProviderOrganization } from '../../../props/models/Organization'; import useTranslate from '../../../hooks/useTranslate'; -import EmptyCard from '../../elements/empty-card/EmptyCard'; import usePushApiError from '../../../hooks/usePushApiError'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; import { useFundService } from '../../../services/FundService'; import SponsorProviderOffices from './elements/SponsorProviderOffices'; import SponsorProviderEmployees from './elements/SponsorProviderEmployees'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { NumberParam, StringParam } from 'use-query-params'; +import LoaderTableCard from '../../elements/loader-table-card/LoaderTableCard'; export default function SponsorProviderOrganization() { const { id } = useParams(); @@ -36,6 +33,7 @@ export default function SponsorProviderOrganization() { const [fundProviders, setFundProviders] = useState>(null); const [providerOrganization, setProviderOrganization] = useState(null); + const [paginatorKey] = useState('fund_providers'); const [filterValues, filterValuesActive, filterUpdate] = useFilterNext<{ q: string; @@ -55,10 +53,6 @@ export default function SponsorProviderOrganization() { }, ); - const tableRef = useRef(null); - - const { headElement, configsElement } = useConfigurableTable(fundService.getProviderFundColumns()); - const updateFundProviderInList = useCallback( (data: FundProvider, index: number) => { const list = { ...fundProviders }; @@ -133,34 +127,20 @@ export default function SponsorProviderOrganization() {
-
- {configsElement} - - tableRef.current?.click()}> - - {headElement} - - - {fundProviders.data.map((fundProvider, index) => ( - updateFundProviderInList(data, index)} - /> - ))} - -
-
-
- - {fundProviders.meta.total == 0 && } - - {fundProviders.meta && ( -
- -
- )} + + {fundProviders?.data?.map((fundProvider, index) => ( + updateFundProviderInList(data, index)} + /> + ))} +
diff --git a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/FundProviderTableItem.tsx b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/FundProviderTableItem.tsx index aa363669f..c62d706c2 100644 --- a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/FundProviderTableItem.tsx +++ b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/FundProviderTableItem.tsx @@ -12,6 +12,7 @@ import TableRowActions from '../../../elements/tables/TableRowActions'; import ToggleControl from '../../../elements/forms/controls/ToggleControl'; import useSetProgress from '../../../../hooks/useSetProgress'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; +import classNames from 'classnames'; export default function FundProviderTableItem({ fundProvider, @@ -94,11 +95,13 @@ export default function FundProviderTableItem({
+ className={classNames( + 'label', + fundProvider.state === 'accepted' && 'label-success', + fundProvider.state === 'pending' && 'label-default', + fundProvider.state === 'rejected' && 'label-danger', + fundProvider.state === 'unsubscribed' && 'label-danger-light', + )}> {fundProvider.state_locale}
diff --git a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/ProviderOrganizationOverview.tsx b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/ProviderOrganizationOverview.tsx index 52a6b4c2e..faa0338c6 100644 --- a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/ProviderOrganizationOverview.tsx +++ b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/ProviderOrganizationOverview.tsx @@ -8,6 +8,7 @@ import usePushSuccess from '../../../../hooks/usePushSuccess'; import useSetProgress from '../../../../hooks/useSetProgress'; import ToggleControl from '../../../elements/forms/controls/ToggleControl'; import usePushApiError from '../../../../hooks/usePushApiError'; +import classNames from 'classnames'; export default function ProviderOrganizationOverview({ organization, @@ -170,9 +171,10 @@ export default function ProviderOrganizationOverview({
{property.label}
+ className={classNames( + 'card-block-listing-value', + property.primary && 'text-primary-light', + )}> {property.value}
diff --git a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderEmployees.tsx b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderEmployees.tsx index e4d2695e6..041e3ac2d 100644 --- a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderEmployees.tsx +++ b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderEmployees.tsx @@ -1,51 +1,36 @@ import React from 'react'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; import { useFundService } from '../../../../services/FundService'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import Employee from '../../../../props/models/Employee'; import { strLimit } from '../../../../helpers/string'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function SponsorProviderEmployees({ employees }: { employees: Array }) { const fundService = useFundService(); - const { headElement, configsElement } = useConfigurableTable(fundService.getProviderEmployeeColumns()); - return (
Medewerkers
- {employees.length > 0 ? ( -
- {configsElement} - - - - {headElement} - - - {employees.map((employee) => ( - - {employee.email ? ( - - ) : ( - - )} - - - ))} - -
{employee.email}{strLimit(employee.identity_address, 32)} - -
-
-
- ) : ( - - )} + + {employees.map((employee) => ( + + {employee.email ? ( + {employee.email} + ) : ( + {strLimit(employee.identity_address, 32)} + )} + + + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderOffices.tsx b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderOffices.tsx index 5f0a59c06..f36891a69 100644 --- a/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderOffices.tsx +++ b/react/src/dashboard/components/pages/sponsor-provider-organization/elements/SponsorProviderOffices.tsx @@ -1,51 +1,33 @@ import React from 'react'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; +import classNames from 'classnames'; import { useFundService } from '../../../../services/FundService'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; import Office from '../../../../props/models/Office'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function SponsorProviderOffices({ offices }: { offices: Array }) { const fundService = useFundService(); - const { headElement, configsElement } = useConfigurableTable(fundService.getProviderOfficeColumns()); - return (
Vestigingen
- {offices.length > 0 ? ( -
- {configsElement} - - - - {headElement} - - - {offices.map((office) => ( - - - - - - ))} - -
- {office.address || 'n.v.t.'} - - {office.phone || 'n.v.t.'} - - -
-
-
- ) : ( - - )} + + {offices.map((office) => ( + + {office.address || 'n.v.t.'} + {office.phone || 'n.v.t.'} + + + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/sponsor-provider-organizations/SponsorProviderOrganizations.tsx b/react/src/dashboard/components/pages/sponsor-provider-organizations/SponsorProviderOrganizations.tsx index 9cc53ec81..c7a425305 100644 --- a/react/src/dashboard/components/pages/sponsor-provider-organizations/SponsorProviderOrganizations.tsx +++ b/react/src/dashboard/components/pages/sponsor-provider-organizations/SponsorProviderOrganizations.tsx @@ -173,7 +173,7 @@ export default function SponsorProviderOrganizations() {
- {translate('provider_organizations.header.title')} ({providerOrganizations.meta.total}) + {translate('provider_organizations.header.title')} ({providerOrganizations?.meta?.total})
@@ -434,12 +434,12 @@ export default function SponsorProviderOrganizations() { {providerOrganizations && ( )} @@ -451,7 +451,7 @@ export default function SponsorProviderOrganizations() { {headElement} - {providerOrganizations.data.map((providerOrganization) => ( + {providerOrganizations?.data?.map((providerOrganization) => (
- {providerOrganizations.meta.total > 0 && ( + {providerOrganizations?.meta?.total > 0 && (
+ className={classNames( + 'label', + fundProvider.state === 'accepted' && 'label-success', + fundProvider.state === 'pending' && 'label-default', + fundProvider.state === 'rejected' && 'label-danger', + fundProvider.state === 'unsubscribed' && 'label-danger-light', + )}> {fundProvider.state_locale}
diff --git a/react/src/dashboard/components/pages/transaction-bulks-view/elements/TransactionBulkTransactionsTable.tsx b/react/src/dashboard/components/pages/transaction-bulks-view/elements/TransactionBulkTransactionsTable.tsx index c6ff0157b..964e1b9a1 100644 --- a/react/src/dashboard/components/pages/transaction-bulks-view/elements/TransactionBulkTransactionsTable.tsx +++ b/react/src/dashboard/components/pages/transaction-bulks-view/elements/TransactionBulkTransactionsTable.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import { strLimit } from '../../../../helpers/string'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import Transaction from '../../../../props/models/Transaction'; import { PaginationData } from '../../../../props/ApiResponses'; import useTransactionExporter from '../../../../services/exporters/useTransactionExporter'; @@ -15,11 +15,10 @@ import LoadingCard from '../../../elements/loading-card/LoadingCard'; import useTranslate from '../../../../hooks/useTranslate'; import usePushApiError from '../../../../hooks/usePushApiError'; import Label from '../../../elements/image_cropper/Label'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../../modules/filter_next/useFilterNext'; import { NumberParam, StringParam } from 'use-query-params'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function TransactionBulkTransactionsTable({ organization, @@ -61,11 +60,6 @@ export default function TransactionBulkTransactionsTable({ }, ); - const { headElement, configsElement } = useConfigurableTable(transactionService.getBulkTransactionsColumns(), { - filter, - sortable: true, - }); - const exportTransactions = useCallback(() => { transactionExporter.exportData(organization.id, { ...filterValuesActive, @@ -104,7 +98,7 @@ export default function TransactionBulkTransactionsTable({
- {`${translate('transactions.header.title')} (${transactions.meta.total})`} + {`${translate('transactions.header.title')} (${transactions?.meta?.total})`}
@@ -115,84 +109,66 @@ export default function TransactionBulkTransactionsTable({
-
-
- {configsElement} - - - - {headElement} - - - {transactions?.data.map((transaction) => ( - - - - - - - - - - - - - - - - - - - ))} - -
{transaction.id}{strLimit(transaction.uid || '-', 25)} - - {transaction.amount_locale} - - -
- {transaction.created_at_locale.split(' - ')[0]} -
-
- {transaction.created_at_locale.split(' - ')[1]} -
-
{strLimit(transaction.fund.name, 25)} - {strLimit(transaction.organization?.name || '-', 25) || '-'} - {strLimit(transaction.product?.name || '-', 25) || '-'} - - - - - -
-
-
-
- - {transactions?.meta.last_page > 1 && ( -
- -
- )} + + {transactions?.data?.map((transaction) => ( + + {transaction.id} + + {strLimit(transaction.uid || '-', 25)} + + + + {transaction.amount_locale} + + + + +
+ {transaction.created_at_locale.split(' - ')[0]} +
+
+ {transaction.created_at_locale.split(' - ')[1]} +
+ + + {strLimit(transaction.fund.name, 25)} + + + {strLimit(transaction.organization?.name || '-', 25) || '-'} + + + {strLimit(transaction.product?.name || '-', 25) || '-'} + + + + + + + + + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/transaction-settings/TransactionSettings.tsx b/react/src/dashboard/components/pages/transaction-settings/TransactionSettings.tsx index bba5460a4..0b84f8a97 100644 --- a/react/src/dashboard/components/pages/transaction-settings/TransactionSettings.tsx +++ b/react/src/dashboard/components/pages/transaction-settings/TransactionSettings.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useMemo, useState } from 'react'; +import React, { Fragment, useContext, useMemo, useState } from 'react'; import useActiveOrganization from '../../../hooks/useActiveOrganization'; import usePushSuccess from '../../../hooks/usePushSuccess'; import StateNavLink from '../../../modules/state_router/StateNavLink'; @@ -9,8 +9,10 @@ import SelectControl from '../../elements/select-control/SelectControl'; import Tooltip from '../../elements/tooltip/Tooltip'; import usePushApiError from '../../../hooks/usePushApiError'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; +import { mainContext } from '../../../contexts/MainContext'; export default function TransactionSettings() { + const { setOrganizationData } = useContext(mainContext); const activeOrganization = useActiveOrganization(); const pushSuccess = usePushSuccess(); @@ -49,7 +51,13 @@ export default function TransactionSettings() { const form = useFormBuilder(activeOrganization.bank_statement_details, (values) => { organizationService .updateBankFields(activeOrganization.id, values) - .then(() => pushSuccess('Opgeslagen!')) + .then((res) => { + pushSuccess('Opgeslagen!'); + + setOrganizationData(activeOrganization.id, { + bank_statement_details: res.data.data.bank_statement_details, + }); + }) .catch(pushApiError) .finally(() => form.setIsLocked(false)); }); diff --git a/react/src/dashboard/components/pages/transactions-view/elements/PayoutTransactionDetails.tsx b/react/src/dashboard/components/pages/transactions-view/elements/PayoutTransactionDetails.tsx index b7944cc41..ffab0f7bb 100644 --- a/react/src/dashboard/components/pages/transactions-view/elements/PayoutTransactionDetails.tsx +++ b/react/src/dashboard/components/pages/transactions-view/elements/PayoutTransactionDetails.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import classNames from 'classnames'; import Tooltip from '../../../elements/tooltip/Tooltip'; import LoadingCard from '../../../elements/loading-card/LoadingCard'; import useTranslate from '../../../../hooks/useTranslate'; @@ -73,7 +74,7 @@ export default function PayoutTransactionDetails({ transaction }: { transaction:
IBAN (van)
- + {transaction.iban_from} {!transaction.iban_final && ( @@ -88,11 +89,11 @@ export default function PayoutTransactionDetails({ transaction }: { transaction:
IBAN (naar)
+ className={classNames( + !transaction.iban_final && + transaction.target != 'iban' && + 'text-muted-dark', + )}> {transaction.iban_to} @@ -108,11 +109,11 @@ export default function PayoutTransactionDetails({ transaction }: { transaction:
IBAN naam (naar)
+ className={classNames( + !transaction.iban_final && + transaction.target != 'iban' && + 'text-muted-dark', + )}> {transaction.iban_to_name} {!transaction.iban_final && transaction.target != 'iban' && ( diff --git a/react/src/dashboard/components/pages/transactions-view/elements/panes/TransactionDetailsPane.tsx b/react/src/dashboard/components/pages/transactions-view/elements/panes/TransactionDetailsPane.tsx index 13d19e38c..4078cef24 100644 --- a/react/src/dashboard/components/pages/transactions-view/elements/panes/TransactionDetailsPane.tsx +++ b/react/src/dashboard/components/pages/transactions-view/elements/panes/TransactionDetailsPane.tsx @@ -3,6 +3,7 @@ import useTransactionService from '../../../../../services/TransactionService'; import useProductReservationService from '../../../../../services/ProductReservationService'; import Reservation from '../../../../../props/models/Reservation'; import React, { Fragment, useCallback, useEffect, useMemo } from 'react'; +import classNames from 'classnames'; import useEnvData from '../../../../../hooks/useEnvData'; import useActiveOrganization from '../../../../../hooks/useActiveOrganization'; import StateNavLink from '../../../../../modules/state_router/StateNavLink'; @@ -222,7 +223,7 @@ export default function TransactionDetailsPane({ {transaction.iban_from && ( - + {transaction.iban_from} {!transaction.iban_final && ( @@ -238,9 +239,9 @@ export default function TransactionDetailsPane({ + className={classNames( + !transaction.iban_final && transaction.target != 'iban' && 'text-muted-dark', + )}> {transaction.iban_to} @@ -257,9 +258,9 @@ export default function TransactionDetailsPane({ + className={classNames( + !transaction.iban_final && transaction.target != 'iban' && 'text-muted-dark', + )}> {transaction.iban_to_name} {!transaction.iban_final && transaction.target != 'iban' && ( diff --git a/react/src/dashboard/components/pages/transactions/Transactions.tsx b/react/src/dashboard/components/pages/transactions/Transactions.tsx index 6dd1a6fc9..378ccd029 100644 --- a/react/src/dashboard/components/pages/transactions/Transactions.tsx +++ b/react/src/dashboard/components/pages/transactions/Transactions.tsx @@ -8,12 +8,9 @@ import useSetProgress from '../../../hooks/useSetProgress'; import useEnvData from '../../../hooks/useEnvData'; import useTransactionBulkService from '../../../services/TransactionBulkService'; import { PaginationData } from '../../../props/ApiResponses'; -import { strLimit } from '../../../helpers/string'; import usePushSuccess from '../../../hooks/usePushSuccess'; import TransactionBulk from '../../../props/models/TransactionBulk'; import useTransactionExporter from '../../../services/exporters/useTransactionExporter'; -import EmptyCard from '../../elements/empty-card/EmptyCard'; -import Paginator from '../../../modules/paginator/components/Paginator'; import LoadingCard from '../../elements/loading-card/LoadingCard'; import { useFundService } from '../../../services/FundService'; import useProviderFundService from '../../../services/ProviderFundService'; @@ -22,28 +19,22 @@ import FilterItemToggle from '../../elements/tables/elements/FilterItemToggle'; import SelectControl from '../../elements/select-control/SelectControl'; import DatePickerControl from '../../elements/forms/controls/DatePickerControl'; import CardHeaderFilter from '../../elements/tables/elements/CardHeaderFilter'; -import StateNavLink from '../../../modules/state_router/StateNavLink'; -import TranslateHtml from '../../elements/translate-html/TranslateHtml'; import { hasPermission } from '../../../helpers/utils'; import useTransactionBulkExporter from '../../../services/exporters/useTransactionBulkExporter'; import { dateFormat, dateParse } from '../../../helpers/dates'; import ModalVoucherTransactionsUpload from '../../modals/ModalVoucherTransactionsUpload'; import usePaginatorService from '../../../modules/paginator/services/usePaginatorService'; import useTranslate from '../../../hooks/useTranslate'; -import TableEmptyValue from '../../elements/table-empty-value/TableEmptyValue'; -import TableTopScroller from '../../elements/tables/TableTopScroller'; -import TableRowActions from '../../elements/tables/TableRowActions'; -import TransactionStateLabel from '../../elements/resource-states/TransactionStateLabel'; -import useConfigurableTable from '../vouchers/hooks/useConfigurableTable'; import usePushApiError from '../../../hooks/usePushApiError'; -import Label from '../../elements/image_cropper/Label'; import useConfirmDangerAction from '../../../hooks/useConfirmDangerAction'; import { Permission } from '../../../props/models/Organization'; -import TransactionBulksCard from './elements/TransactionBulksCard'; import { DashboardRoutes } from '../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../modules/filter_next/useFilterNext'; import { createEnumParam, NumberParam, StringParam } from 'use-query-params'; import BlockLabelTabs from '../../elements/block-label-tabs/BlockLabelTabs'; +import TransactionsTableSection from './elements/TransactionsTableSection'; +import TransactionBulksTableSection from './elements/TransactionBulksTableSection'; +import StateNavLink from '../../../modules/state_router/StateNavLink'; export default function Transactions() { const envData = useEnvData(); @@ -85,7 +76,7 @@ export default function Transactions() { return funds?.filter((fund: Fund) => fund.allow_direct_payments).length > 0; }, [funds]); - const [viewTypes] = useState>([ + const [viewTypes] = useState>([ { key: 'transactions', label: 'Individueel' }, { key: 'bulks', label: 'Bulk' }, ]); @@ -184,12 +175,6 @@ export default function Transactions() { }, ); - const { headElement, configsElement } = useConfigurableTable(transactionService.getColumns(isSponsor, isProvider), { - filter: filter, - sortable: true, - sortableExclude: ['method', 'branch_name', 'branch_number', 'amount_extra'], - }); - const [bulkFilterValues, bulkFilterValuesActive, bulkFilterUpdate, bulkFilter] = useFilterNext<{ from?: string; to?: string; @@ -445,7 +430,7 @@ export default function Transactions() {
- {hasDirectPayments && ( + {hasDirectPayments && viewType.key == 'transactions' && (
- {viewType.key == 'transactions' && transactions.meta.total > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {transactions.data.map((transaction) => ( - - - - {isSponsor && ( - - )} - - {isProvider && ( - - )} - {isProvider && ( - - )} - {isProvider && ( - - )} - {isProvider && ( - - )} - - - {isProvider && ( - - )} - {isSponsor && ( - - )} - {isSponsor && ( - - {transaction.organization ? ( - - ) : ( - - )} - - )} - - {isSponsor && ( - - )} - - {isSponsor && ( - - )} - - {isSponsor && transaction.voucher_transaction_bulk_id && ( - - )} - {isSponsor && !transaction.voucher_transaction_bulk_id && ( - - )} - {isSponsor && ( - - )} - - - - - ))} - -
{transaction.id} - {strLimit(transaction.uid || '-', 32)} - - - {transaction.amount_locale} - - - {transaction?.reservation?.amount_extra > 0 - ? 'iDeal + Tegoed' - : 'Tegoed'} - - {transaction?.branch_name && ( -
{transaction?.branch_name}
- )} - - {transaction?.branch_id && ( -
- ID {transaction?.branch_id} -
- )} - - {!transaction.branch_id && !transaction.branch_name && ( -
Geen...
- )} -
-
- {strLimit(transaction.branch_number?.toString(), 32) || - 'Geen...'} -
-
- {transaction?.reservation?.amount_extra > 0 - ? transaction?.reservation?.amount_extra_locale - : '-'} - -
- {transaction.created_at_locale.split(' - ')[0]} -
-
- {transaction.created_at_locale.split(' - ')[1]} -
-
- {strLimit(transaction.fund.name, 25)} - - {transaction.product?.name ? ( - strLimit(transaction.product?.name || '', 25) - ) : ( - - )} - -
- {transaction.payment_type_locale.title} -
-
- {strLimit(transaction.payment_type_locale.subtitle)} -
-
- {strLimit(transaction.organization.name, 25)} - - - - {transaction.non_cancelable_at_locale ? ( -
- {transaction.non_cancelable_at_locale} -
- ) : ( - - )} -
- {transaction.execution_date_locale ? ( -
- {transaction.execution_date_locale} -
- ) : ( - - )} -
- - {`#${transaction.voucher_transaction_bulk_id}`} - - - {transaction.transfer_in > 0 && - transaction.state == 'pending' && - transaction.attempts < 3 ? ( -
In afwachting
- ) : ( - - )} -
- {(transaction.bulk_state == 'rejected' || - transaction.bulk_state == 'error') && ( - - )} - - {(transaction.bulk_state == 'draft' || - transaction.bulk_state == 'pending') && ( - - )} - - {transaction.bulk_state == 'accepted' && ( - - )} - - {!transaction.bulk_state && } - - - - {transaction.transfer_in > 0 && transaction.state == 'pending' ? ( -
- - {transaction.transfer_in} dagen resterend -
- ) : ( - - )} -
- ( -
- - - Bekijken - -
- )} - /> -
-
-
-
- )} - - {!isSponsor && transactions.meta?.total > 0 && viewType.key == 'transactions' && ( -
-
-
-
- -
-
-
-
- )} - - {isSponsor && - pendingBulkingMeta?.total > 0 && - hasPermission(activeOrganization, Permission.MANAGE_TRANSACTION_BULKS) && ( - - )} - - {viewType.key == 'transactions' && transactions.meta.total == 0 && ( - - )} - - {viewType.key == 'transactions' && transactions?.meta && ( - - )} - - {viewType.key == 'bulks' && transactionBulks.meta.total > 0 && ( - )} - {viewType.key === 'bulks' && transactionBulks.meta.total == 0 && ( - )} - - {transactionBulks && viewType.key == 'bulks' && transactionBulks?.meta && ( - - )}
); } diff --git a/react/src/dashboard/components/pages/transactions/elements/TransactionBulksCard.tsx b/react/src/dashboard/components/pages/transactions/elements/TransactionBulksCard.tsx deleted file mode 100644 index d067a1823..000000000 --- a/react/src/dashboard/components/pages/transactions/elements/TransactionBulksCard.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React from 'react'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import StateNavLink from '../../../../modules/state_router/StateNavLink'; -import TransactionBulk from '../../../../props/models/TransactionBulk'; -import Label from '../../../elements/image_cropper/Label'; -import TableRowActions from '../../../elements/tables/TableRowActions'; -import Organization from '../../../../props/models/Organization'; -import { FilterModel, FilterScope } from '../../../../modules/filter_next/types/FilterParams'; -import useTransactionBulkService from '../../../../services/TransactionBulkService'; -import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; - -export default function TransactionBulksCard({ - bulks, - filter, - organization, -}: { - bulks: Array; - filter: FilterScope; - organization: Organization; -}) { - const transactionBulkService = useTransactionBulkService(); - - const { headElement, configsElement } = useConfigurableTable(transactionBulkService.getColumns(), { - filter, - sortable: true, - }); - - return ( -
-
- {configsElement} - - - - {headElement} - - - {bulks?.map((transactionBulk) => ( - - - - - - - - - - ))} - -
{transactionBulk.id} - {transactionBulk.voucher_transactions_amount_locale} - -
- {transactionBulk.created_at_locale.split(' - ')[0]} -
-
- {transactionBulk.created_at_locale.split(' - ')[1]} -
-
{transactionBulk.voucher_transactions_count} - {transactionBulk.state === 'rejected' && ( - - )} - - {transactionBulk.state === 'error' && ( - - )} - - {transactionBulk.state === 'draft' && ( - - )} - - {transactionBulk.state === 'accepted' && ( - - )} - - {transactionBulk.state === 'pending' && ( - - )} - - ( -
- - - Bekijken - -
- )} - /> -
-
-
-
- ); -} diff --git a/react/src/dashboard/components/pages/transactions/elements/TransactionBulksTableSection.tsx b/react/src/dashboard/components/pages/transactions/elements/TransactionBulksTableSection.tsx new file mode 100644 index 000000000..bf728e5d9 --- /dev/null +++ b/react/src/dashboard/components/pages/transactions/elements/TransactionBulksTableSection.tsx @@ -0,0 +1,121 @@ +import React from 'react'; +import { PaginationData } from '../../../../props/ApiResponses'; +import TransactionBulk from '../../../../props/models/TransactionBulk'; +import Organization from '../../../../props/models/Organization'; +import { FilterModel, FilterScope, FilterSetter } from '../../../../modules/filter_next/types/FilterParams'; +import { ConfigurableTableColumn } from '../../vouchers/hooks/useConfigurableTable'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; +import StateNavLink from '../../../../modules/state_router/StateNavLink'; +import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; +import Label from '../../../elements/image_cropper/Label'; +import TableRowActions from '../../../elements/tables/TableRowActions'; +import Paginator from '../../../../modules/paginator/components/Paginator'; + +export default function TransactionBulksTableSection({ + bulks, + organization, + columns, + bulkFilter, + bulkFilterValues, + bulkFilterUpdate, + paginatorKey, +}: { + bulks: PaginationData; + organization: Organization; + columns: Array; + bulkFilter: FilterScope; + bulkFilterValues: FilterModel; + bulkFilterUpdate: FilterSetter; + paginatorKey: string; +}) { + return ( +
+ + {bulks?.data?.map((transactionBulk) => ( + + {transactionBulk.id} + {transactionBulk.voucher_transactions_amount_locale} + +
+ {transactionBulk.created_at_locale.split(' - ')[0]} +
+
+ {transactionBulk.created_at_locale.split(' - ')[1]} +
+ + {transactionBulk.voucher_transactions_count} + + {transactionBulk.state === 'rejected' && ( + + )} + + {transactionBulk.state === 'error' && ( + + )} + + {transactionBulk.state === 'draft' && ( + + )} + + {transactionBulk.state === 'accepted' && ( + + )} + + {transactionBulk.state === 'pending' && ( + + )} + + + + ( +
+ + + Bekijken + +
+ )} + /> + +
+ ))} +
+ + {bulks?.meta && ( + + )} +
+ ); +} diff --git a/react/src/dashboard/components/pages/transactions/elements/TransactionsTableSection.tsx b/react/src/dashboard/components/pages/transactions/elements/TransactionsTableSection.tsx new file mode 100644 index 000000000..cf910a522 --- /dev/null +++ b/react/src/dashboard/components/pages/transactions/elements/TransactionsTableSection.tsx @@ -0,0 +1,321 @@ +import React, { Fragment } from 'react'; +import classNames from 'classnames'; +import { PaginationData } from '../../../../props/ApiResponses'; +import Transaction from '../../../../props/models/Transaction'; +import Organization from '../../../../props/models/Organization'; +import { FilterModel, FilterScope, FilterSetter } from '../../../../modules/filter_next/types/FilterParams'; +import { ConfigurableTableColumn } from '../../vouchers/hooks/useConfigurableTable'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; +import StateNavLink from '../../../../modules/state_router/StateNavLink'; +import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; +import { strLimit } from '../../../../helpers/string'; +import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; +import TableRowActions from '../../../elements/tables/TableRowActions'; +import TransactionStateLabel from '../../../elements/resource-states/TransactionStateLabel'; +import Label from '../../../elements/image_cropper/Label'; +import TranslateHtml from '../../../elements/translate-html/TranslateHtml'; +import Paginator from '../../../../modules/paginator/components/Paginator'; + +export default function TransactionsTableSection({ + transactions, + organization, + isSponsor, + isProvider, + columns, + filter, + filterValues, + filterUpdate, + paginatorKey, + pendingBulkingMeta, + canManageBulks, + buildingBulks, + onBulkPendingNow, +}: { + transactions: PaginationData; + organization: Organization; + isSponsor: boolean; + isProvider: boolean; + columns: Array; + filter: FilterScope; + filterValues: FilterModel; + filterUpdate: FilterSetter; + paginatorKey: string; + pendingBulkingMeta?: { + total_amount_locale?: string; + total_amount?: string; + total: number; + }; + canManageBulks: boolean; + buildingBulks: boolean; + onBulkPendingNow: () => void; +}) { + return ( + + + {transactions?.data?.map((transaction) => ( + + {transaction.id} + + {isSponsor && {strLimit(transaction.uid || '-', 32)}} + + + {transaction.amount_locale} + + + {isProvider && ( + {transaction?.reservation?.amount_extra > 0 ? 'iDeal + Tegoed' : 'Tegoed'} + )} + {isProvider && ( + + {transaction?.branch_name && ( +
{transaction?.branch_name}
+ )} + + {transaction?.branch_id && ( +
+ ID {transaction?.branch_id} +
+ )} + + {!transaction.branch_id && !transaction.branch_name && ( +
Geen...
+ )} + + )} + {isProvider && ( + +
+ {strLimit(transaction.branch_number?.toString(), 32) || 'Geen...'} +
+ + )} + {isProvider && ( + + {transaction?.reservation?.amount_extra > 0 + ? transaction?.reservation?.amount_extra_locale + : '-'} + + )} + +
+ {transaction.created_at_locale.split(' - ')[0]} +
+
+ {transaction.created_at_locale.split(' - ')[1]} +
+ + {strLimit(transaction.fund.name, 25)} + {isProvider && ( + + {transaction.product?.name ? ( + strLimit(transaction.product?.name || '', 25) + ) : ( + + )} + + )} + {isSponsor && ( + +
+ {transaction.payment_type_locale.title} +
+
+ {strLimit(transaction.payment_type_locale.subtitle)} +
+ + )} + {isSponsor && ( + + {transaction.organization ? ( + + {strLimit(transaction.organization.name, 25)} + + ) : ( + + + + )} + + )} + + {isSponsor && ( + + {transaction.non_cancelable_at_locale ? ( +
+ {transaction.non_cancelable_at_locale} +
+ ) : ( + + )} + + )} + + {isSponsor && ( + + {transaction.execution_date_locale ? ( +
+ {transaction.execution_date_locale} +
+ ) : ( + + )} + + )} + + {isSponsor && transaction.voucher_transaction_bulk_id && ( + + + {`#${transaction.voucher_transaction_bulk_id}`} + + + )} + {isSponsor && !transaction.voucher_transaction_bulk_id && ( + + {transaction.transfer_in > 0 && + transaction.state == 'pending' && + transaction.attempts < 3 ? ( +
In afwachting
+ ) : ( + + )} + + )} + {isSponsor && ( + + {(transaction.bulk_state == 'rejected' || transaction.bulk_state == 'error') && ( + + )} + + {(transaction.bulk_state == 'draft' || transaction.bulk_state == 'pending') && ( + + )} + + {transaction.bulk_state == 'accepted' && ( + + )} + + {!transaction.bulk_state && } + + )} + + + + + {transaction.transfer_in > 0 && transaction.state == 'pending' ? ( +
+ + {transaction.transfer_in} dagen resterend +
+ ) : ( + + )} + + + ( +
+ + + Bekijken + +
+ )} + /> + +
+ ))} +
+ + {!isSponsor && transactions.meta?.total > 0 && ( +
+
+
+
+ +
+
+
+
+ )} + + {pendingBulkingMeta?.total > 0 && canManageBulks && ( +
+
+
+ +
+ +
+
+ )} + + {transactions?.meta && ( + + )} +
+ ); +} diff --git a/react/src/dashboard/components/pages/vouchers-view/elements/VoucherRecordsCard.tsx b/react/src/dashboard/components/pages/vouchers-view/elements/VoucherRecordsCard.tsx index 74355a102..b44a534b6 100644 --- a/react/src/dashboard/components/pages/vouchers-view/elements/VoucherRecordsCard.tsx +++ b/react/src/dashboard/components/pages/vouchers-view/elements/VoucherRecordsCard.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import SponsorVoucher from '../../../../props/models/Sponsor/SponsorVoucher'; import Organization, { Permission } from '../../../../props/models/Organization'; import useOpenModal from '../../../../hooks/useOpenModal'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import ModalVoucherRecordEdit from '../../../modals/ModalVoucherRecordEdit'; import useVoucherRecordService from '../../../../services/VoucherRecordService'; import { PaginationData } from '../../../../props/ApiResponses'; @@ -14,13 +14,11 @@ import usePushSuccess from '../../../../hooks/usePushSuccess'; import { hasPermission } from '../../../../helpers/utils'; import useTranslate from '../../../../hooks/useTranslate'; import useSetProgress from '../../../../hooks/useSetProgress'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; import usePushApiError from '../../../../hooks/usePushApiError'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import TableRowActions from '../../../elements/tables/TableRowActions'; import TableEmptyValue from '../../../elements/table-empty-value/TableEmptyValue'; import useFilterNext from '../../../../modules/filter_next/useFilterNext'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function VoucherRecordsCard({ voucher, @@ -54,11 +52,6 @@ export default function VoucherRecordsCard({ order_dir: 'asc', }); - const { headElement, configsElement } = useConfigurableTable(voucherRecordService.getColumns(), { - filter, - sortable: true, - }); - const fetchRecords = useCallback(() => { setProgress(0); @@ -124,7 +117,7 @@ export default function VoucherRecordsCard({
{translate('voucher_records.header.title')} - {records.meta ? ` (${records.meta.total})` : ''} + {records?.meta ? ` (${records?.meta?.total})` : ''}
@@ -147,71 +140,43 @@ export default function VoucherRecordsCard({
- {records.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {records.data.map((record, index: number) => ( - - - - - - - - - - ))} - -
{record.id}{record.record_type.name}{record.value_locale}{record.created_at_locale} - {record.note || 'Geen notitie'} - - {hasPermission(organization, Permission.MANAGE_VOUCHERS) ? ( - ( -
-
-
-
- )} - - {records.meta.total == 0 ? ( - - ) : ( -
- -
- )} + + {records?.data?.map((record, index: number) => ( + + {record.id} + {record.record_type.name} + {record.value_locale} + {record.created_at_locale} + {record.note || 'Geen notitie'} + + + {hasPermission(organization, Permission.MANAGE_VOUCHERS) ? ( + ( +
+ editRecord(record)}> +
+ Bewerking + + deleteRecord(record)}> + + )} + /> + ) : ( + + )} + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/vouchers-view/elements/VoucherTransactionsCard.tsx b/react/src/dashboard/components/pages/vouchers-view/elements/VoucherTransactionsCard.tsx index 8398a2392..a7bf490f8 100644 --- a/react/src/dashboard/components/pages/vouchers-view/elements/VoucherTransactionsCard.tsx +++ b/react/src/dashboard/components/pages/vouchers-view/elements/VoucherTransactionsCard.tsx @@ -1,7 +1,7 @@ import Transaction from '../../../../props/models/Transaction'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import classNames from 'classnames'; import useEnvData from '../../../../hooks/useEnvData'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import { currencyFormat, strLimit } from '../../../../helpers/string'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; import useTransactionService from '../../../../services/TransactionService'; @@ -9,14 +9,12 @@ import Organization from '../../../../props/models/Organization'; import { PaginationData } from '../../../../props/ApiResponses'; import LoadingCard from '../../../elements/loading-card/LoadingCard'; import useSetProgress from '../../../../hooks/useSetProgress'; -import EmptyCard from '../../../elements/empty-card/EmptyCard'; import Label from '../../../elements/image_cropper/Label'; -import useConfigurableTable from '../../vouchers/hooks/useConfigurableTable'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import TableRowActions from '../../../elements/tables/TableRowActions'; import { DashboardRoutes } from '../../../../modules/state_router/RouterBuilder'; import useFilterNext from '../../../../modules/filter_next/useFilterNext'; import { FilterModel } from '../../../../modules/filter_next/types/FilterParams'; +import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; export default function VoucherTransactionsCard({ blockTitle, @@ -34,6 +32,7 @@ export default function VoucherTransactionsCard({ const transactionService = useTransactionService(); const [transactions, setTransactions] = useState>(null); + const [paginatorKey] = useState('voucher_transactions'); const isSponsor = useMemo(() => { return envData.client_type == 'sponsor'; @@ -41,11 +40,6 @@ export default function VoucherTransactionsCard({ const [filterValues, filterValuesActive, filterUpdate, filter] = useFilterNext(filters); - const { headElement, configsElement } = useConfigurableTable(transactionService.getColumnsForVoucher(isSponsor), { - filter, - sortable: true, - }); - const fetchTransactions = useCallback(() => { setProgress(100); @@ -73,102 +67,79 @@ export default function VoucherTransactionsCard({
- {blockTitle || 'Transactions'} ({transactions.meta.total}) + {blockTitle || 'Transactions'} ({transactions?.meta?.total})
- {transactions.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {transactions.data.map((transaction) => ( - - - - - - - - {isSponsor && ( - - )} - - - - - - ))} - -
{transaction.id} - {strLimit(transaction.uid || '-', 25)} - - - {currencyFormat(parseFloat(transaction.amount))} - - - - {transaction.created_at_locale.split(' - ')[0]} - -
- - {transaction.created_at_locale.split(' - ')[1]} - -
- {strLimit(transaction.fund.name, 25)} - {transaction.target_locale} - {strLimit(transaction.organization?.name || '-', 25)} - - {strLimit(transaction.product?.name || '-', 25)} - - {transaction.state == 'success' ? ( - - ) : ( - - )} - - ( -
- - - Bekijken - -
- )} - /> -
-
-
-
- )} - - {transactions.meta.total === 0 ? ( - - ) : ( -
- -
- )} + + {transactions?.data?.map((transaction) => ( + + {transaction.id} + {strLimit(transaction.uid || '-', 25)} + + + {currencyFormat(parseFloat(transaction.amount))} + + + + {transaction.created_at_locale.split(' - ')[0]} +
+ + {transaction.created_at_locale.split(' - ')[1]} + + + {strLimit(transaction.fund.name, 25)} + {transaction.target_locale} + {isSponsor && ( + + {strLimit(transaction.organization?.name || '-', 25)} + + )} + + {strLimit(transaction.product?.name || '-', 25)} + + + {transaction.state == 'success' ? ( + + ) : ( + + )} + + + + ( +
+ + + Bekijken + +
+ )} + /> + + + ))} +
); } diff --git a/react/src/dashboard/components/pages/vouchers/Vouchers.tsx b/react/src/dashboard/components/pages/vouchers/Vouchers.tsx index 1ff0b9a74..a0dae68b6 100644 --- a/react/src/dashboard/components/pages/vouchers/Vouchers.tsx +++ b/react/src/dashboard/components/pages/vouchers/Vouchers.tsx @@ -174,7 +174,7 @@ export default function Vouchers() { return (
-
+
{translate('vouchers.header.title')} ({vouchers?.meta?.total})
diff --git a/react/src/dashboard/components/pages/vouchers/elements/VouchersTable.tsx b/react/src/dashboard/components/pages/vouchers/elements/VouchersTable.tsx index 80a51f29c..94be6200a 100644 --- a/react/src/dashboard/components/pages/vouchers/elements/VouchersTable.tsx +++ b/react/src/dashboard/components/pages/vouchers/elements/VouchersTable.tsx @@ -2,11 +2,8 @@ import React from 'react'; import SponsorVoucher from '../../../../props/models/Sponsor/SponsorVoucher'; import Organization from '../../../../props/models/Organization'; import Fund from '../../../../props/models/Fund'; -import TableTopScroller from '../../../elements/tables/TableTopScroller'; import VouchersTableRow from './VouchersTableRow'; -import Paginator from '../../../../modules/paginator/components/Paginator'; import { PaginationData } from '../../../../props/ApiResponses'; -import useConfigurableTable from '../hooks/useConfigurableTable'; import useVoucherService from '../../../../services/VoucherService'; import { FilterModel, FilterSetter } from '../../../../modules/filter_next/types/FilterParams'; import LoaderTableCard from '../../../elements/loader-table-card/LoaderTableCard'; @@ -32,46 +29,22 @@ export default function VouchersTable({ }) { const voucherService = useVoucherService(); - const { headElement, configsElement } = useConfigurableTable(voucherService.getColumns()); - return ( - - {!loading && vouchers.data.length > 0 && ( -
-
- {configsElement} - - - - {headElement} - - - {vouchers.data.map((voucher) => ( - - ))} - -
-
-
-
- )} - - {vouchers.meta && ( -
- -
- )} + + {vouchers?.data?.map((voucher) => ( + + ))} ); } diff --git a/react/src/dashboard/components/pages/vouchers/elements/VouchersTableNoFundsBlock.tsx b/react/src/dashboard/components/pages/vouchers/elements/VouchersTableNoFundsBlock.tsx index e372f83c8..10ca6a439 100644 --- a/react/src/dashboard/components/pages/vouchers/elements/VouchersTableNoFundsBlock.tsx +++ b/react/src/dashboard/components/pages/vouchers/elements/VouchersTableNoFundsBlock.tsx @@ -1,5 +1,4 @@ import EmptyCard from '../../../elements/empty-card/EmptyCard'; -import { getStateRouteUrl } from '../../../../modules/state_router/Router'; import React from 'react'; import { hasPermission } from '../../../../helpers/utils'; import Organization, { Permission } from '../../../../props/models/Organization'; @@ -11,7 +10,8 @@ export default function VouchersTableNoFundsBlock({ organization }: { organizati description={'Je hebt momenteel geen fondsen.'} button={{ text: 'Fonds toevoegen', - to: getStateRouteUrl(DashboardRoutes.ORGANIZATION_FUNDS, { organizationId: organization.id }), + state: DashboardRoutes.ORGANIZATION_FUNDS, + stateParams: { organizationId: organization.id }, }} /> ) : ( diff --git a/react/src/dashboard/components/pages/vouchers/elements/VouchersTableRow.tsx b/react/src/dashboard/components/pages/vouchers/elements/VouchersTableRow.tsx index 1a5ffea53..291b3a311 100644 --- a/react/src/dashboard/components/pages/vouchers/elements/VouchersTableRow.tsx +++ b/react/src/dashboard/components/pages/vouchers/elements/VouchersTableRow.tsx @@ -1,4 +1,5 @@ import React, { Fragment, useCallback } from 'react'; +import classNames from 'classnames'; import SponsorVoucher from '../../../../props/models/Sponsor/SponsorVoucher'; import StateNavLink from '../../../../modules/state_router/StateNavLink'; import Organization, { Permission } from '../../../../props/models/Organization'; @@ -190,14 +191,20 @@ export default function VouchersTableRow({ voucher.state != 'deactivated' && ( Activeren QR-code diff --git a/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js b/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js index 956a3befa..81d590896 100644 --- a/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js +++ b/react/src/dashboard/i18n/nl/i18n-modals-danger_zone.js @@ -17,6 +17,7 @@ import remove_reservation_field from './modals/danger-zone/remove-reservation-fi import remove_mollie_connection from './modals/danger-zone/remove-mollie-connection'; import exclude_pre_check_fund from './modals/danger-zone/exclude_pre_check_fund'; import remove_prevalidation_request from './modals/danger-zone/remove-prevalidation-request'; +import confirm_extra_payment_refund from './modals/danger-zone/confirm-extra-payment-refund'; export default { remove_provider_application, @@ -38,4 +39,5 @@ export default { remove_mollie_connection, exclude_pre_check_fund, remove_prevalidation_request, + confirm_extra_payment_refund, }; diff --git a/react/src/dashboard/i18n/nl/modals/danger-zone/confirm-extra-payment-refund.js b/react/src/dashboard/i18n/nl/modals/danger-zone/confirm-extra-payment-refund.js new file mode 100644 index 000000000..9e45c69b8 --- /dev/null +++ b/react/src/dashboard/i18n/nl/modals/danger-zone/confirm-extra-payment-refund.js @@ -0,0 +1,9 @@ +export default { + title: 'Bankrekening verwijderen?', + description: + 'Je staat op het punt een bankrekening te verwijderen. Deze actie kan niet ongedaan worden gemaakt, weet je zeker dat je door wilt gaan?', + buttons: { + cancel: 'Annuleren', + confirm: 'Bevestigen', + }, +}; diff --git a/react/src/dashboard/layout/Layout.tsx b/react/src/dashboard/layout/Layout.tsx index 8eb366e33..8bf8bd7c6 100644 --- a/react/src/dashboard/layout/Layout.tsx +++ b/react/src/dashboard/layout/Layout.tsx @@ -14,6 +14,7 @@ import { Libraries, LoadScript } from '@react-google-maps/api'; import useEnvData from '../hooks/useEnvData'; import Printable from '../modules/printable/components/Printable'; import ErrorBoundaryHandler from '../components/elements/error-boundary-handler/ErrorBoundaryHandler'; +import classNames from 'classnames'; export const Layout = ({ children }: { children: React.ReactElement }) => { const { modals } = useContext(modalsContext); @@ -43,9 +44,11 @@ export const Layout = ({ children }: { children: React.ReactElement }) => {
{ {layout == LayoutType.dashboard && activeOrganization && } {isReady && ( -
+
{ if (url) { return ( - `auth-user-menu-item ${active ? 'active' : ''}`}> + classNames('auth-user-menu-item', active && 'active')}>
{icon}
{name}
@@ -54,7 +55,11 @@ const IdentityMenuItem = ({ url, href, name, icon, dusk, active, onClick }: Iden } return ( -
+
{icon}
{name}
@@ -172,7 +177,12 @@ export const LayoutHeader = () => { />
- +
{showIdentityMenu && ( diff --git a/react/src/dashboard/layout/elements/aside/elements/LayoutAsideNavGroup.tsx b/react/src/dashboard/layout/elements/aside/elements/LayoutAsideNavGroup.tsx index 2d781d77c..b40e2e1ef 100644 --- a/react/src/dashboard/layout/elements/aside/elements/LayoutAsideNavGroup.tsx +++ b/react/src/dashboard/layout/elements/aside/elements/LayoutAsideNavGroup.tsx @@ -124,9 +124,7 @@ export default function LayoutAsideNavGroup({ }); } }}> - {hasItems && ( - - )} + {hasItems && }
diff --git a/react/src/dashboard/modules/paginator/components/Paginator.tsx b/react/src/dashboard/modules/paginator/components/Paginator.tsx index 777ae8645..051b12765 100644 --- a/react/src/dashboard/modules/paginator/components/Paginator.tsx +++ b/react/src/dashboard/modules/paginator/components/Paginator.tsx @@ -98,7 +98,7 @@ export default function Paginator({ }, [meta?.current_page, loadingPage]); return ( -
+
{meta.from && meta.to && (
@@ -131,7 +131,7 @@ export default function Paginator({ onKeyDown={clickOnKeyEnter} tabIndex={meta.current_page === 1 ? undefined : 0} disabled={loading || meta.current_page === 1} - className={`table-pagination-button`}> + className="table-pagination-button"> {translate('paginator.buttons.first')} {pages.map((page) => ( @@ -157,7 +157,7 @@ export default function Paginator({ onKeyDown={clickOnKeyEnter} disabled={loading || meta.current_page === meta.last_page} tabIndex={meta.current_page === meta.last_page ? undefined : 0} - className={`table-pagination-button`}> + className="table-pagination-button"> {translate('paginator.buttons.last')}
diff --git a/react/src/dashboard/modules/push_notifications/components/PushNotificationsGroup.tsx b/react/src/dashboard/modules/push_notifications/components/PushNotificationsGroup.tsx index 4aeed4238..35d664b93 100644 --- a/react/src/dashboard/modules/push_notifications/components/PushNotificationsGroup.tsx +++ b/react/src/dashboard/modules/push_notifications/components/PushNotificationsGroup.tsx @@ -70,7 +70,12 @@ export default function PushNotificationsGroup({ {shownNotifications?.map((notification) => (
{notification.icon && } diff --git a/react/src/props/elements/ButtonType.ts b/react/src/props/elements/ButtonType.ts index 1258ce004..f7c67c2b6 100644 --- a/react/src/props/elements/ButtonType.ts +++ b/react/src/props/elements/ButtonType.ts @@ -1,8 +1,22 @@ import React from 'react'; +export type ButtonVariant = + | 'default' + | 'default-dashed' + | 'dashed' + | 'primary' + | 'primary-light' + | 'primary-outline' + | 'primary-variant' + | 'secondary' + | 'danger' + | 'text' + | 'text-primary' + | 'text-padless'; + type ButtonType = { text?: string; - type?: string; + type?: ButtonVariant; icon?: string; iconEnd?: boolean; onClick: ( diff --git a/react/src/webshop/components/elements/announcements/Announcements.tsx b/react/src/webshop/components/elements/announcements/Announcements.tsx index 5e297aafd..660d8fb7c 100644 --- a/react/src/webshop/components/elements/announcements/Announcements.tsx +++ b/react/src/webshop/components/elements/announcements/Announcements.tsx @@ -1,4 +1,5 @@ import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import classNames from 'classnames'; import Announcement from '../../../../dashboard/props/models/Announcement'; import Markdown from '../markdown/Markdown'; @@ -44,9 +45,12 @@ export default function Announcements({ announcements }: { announcements?: Array {listActive?.map((announcement) => (
+ className={classNames( + 'block', + 'block-announcement', + `announcement-${announcement.type}`, + announcement.dismissed && 'dismissed', + )}> {announcement.title && (
{(announcement.type == 'default' || announcement.type == 'primary') && ( diff --git a/react/src/webshop/components/elements/app-links/AppLinks.tsx b/react/src/webshop/components/elements/app-links/AppLinks.tsx index 0e1ef441d..dd6cb574e 100644 --- a/react/src/webshop/components/elements/app-links/AppLinks.tsx +++ b/react/src/webshop/components/elements/app-links/AppLinks.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import classNames from 'classnames'; import useEnvData from '../../../hooks/useEnvData'; import useAssetUrl from '../../../hooks/useAssetUrl'; import useTranslate from '../../../../dashboard/hooks/useTranslate'; @@ -25,7 +26,7 @@ export default function AppLinks({ const translate = useTranslate(); return ( -
+
{showAndroidButton && ( +
{showMore2FADetails ? (
setShowMore2FADetails(false)}> {translate('global.card_2fa_warning.2fa_policy.show_less')} diff --git a/react/src/webshop/components/elements/block-loader/BlockLoader.tsx b/react/src/webshop/components/elements/block-loader/BlockLoader.tsx index ac7f91eb0..15567207f 100644 --- a/react/src/webshop/components/elements/block-loader/BlockLoader.tsx +++ b/react/src/webshop/components/elements/block-loader/BlockLoader.tsx @@ -1,8 +1,9 @@ import React from 'react'; +import classNames from 'classnames'; export default function BlockLoader({ type }: { type?: 'full' }) { return ( -
+
diff --git a/react/src/webshop/components/elements/block-organization-offices/BlockOrganizationOffices.tsx b/react/src/webshop/components/elements/block-organization-offices/BlockOrganizationOffices.tsx index 80031b0c2..bdadce1d2 100644 --- a/react/src/webshop/components/elements/block-organization-offices/BlockOrganizationOffices.tsx +++ b/react/src/webshop/components/elements/block-organization-offices/BlockOrganizationOffices.tsx @@ -13,7 +13,7 @@ export default function BlockOrganizationOffices({ provider }: { provider: Provi return (
-
+
setShowOffices(!showOffices)}>
- +
{translate('list_blocks.provider_item_list.show_locations')}
-
+
{provider.offices.length}
diff --git a/react/src/webshop/components/elements/block-panel-group/PaneGroupPanel.tsx b/react/src/webshop/components/elements/block-panel-group/PaneGroupPanel.tsx index f5d252726..1cf974f65 100644 --- a/react/src/webshop/components/elements/block-panel-group/PaneGroupPanel.tsx +++ b/react/src/webshop/components/elements/block-panel-group/PaneGroupPanel.tsx @@ -1,4 +1,5 @@ import React, { ReactNode, Ref, useId, useState } from 'react'; +import classNames from 'classnames'; import useTranslate from '../../../../dashboard/hooks/useTranslate'; type PaneGroupIcon = @@ -50,7 +51,10 @@ export default function PaneGroupPanel({

{title}

-