From 58237a1d23111faf0ba95fc24e8eb0ae722b64d3 Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Mon, 23 Mar 2026 11:28:10 +0000 Subject: [PATCH] fix(ui): drop lodash --- ui/package-lock.json | 191 ++++++------------ ui/package.json | 9 +- ui/src/Common/Fetch.test.ts | 35 ++-- ui/src/Common/Fetch.ts | 24 +-- ui/src/Components/Fetcher/index.test.tsx | 2 +- ui/src/Components/Grid/AlertGrid/Grid.tsx | 2 +- .../AlertGroupWidthConfiguration.test.tsx | 7 + .../AlertGroupWidthConfiguration.tsx | 2 +- ui/src/Hooks/useFetchAny.ts | 11 +- ui/src/Hooks/useFetchDelete.ts | 11 +- ui/src/Hooks/useFetchGet.ts | 20 +- ui/src/Stores/AlertStore.ts | 2 +- ui/src/Stores/SilenceFormStore.ts | 5 +- 13 files changed, 117 insertions(+), 204 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 817c36000..275a16198 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -22,12 +22,9 @@ "csshake": "1.7.0", "date-fns": "4.1.0", "downshift": "9.3.2", + "es-toolkit": "1.45.1", "favico.js": "0.3.10", "fontfaceobserver": "2.3.0", - "lodash.debounce": "4.0.8", - "lodash.merge": "4.6.2", - "lodash.throttle": "4.1.1", - "lodash.uniqueid": "4.0.1", "mobx": "6.15.0", "mobx-react-lite": "4.1.1", "promise-retry": "2.0.1", @@ -58,10 +55,6 @@ "@types/bricks.js": "1.8.5", "@types/fontfaceobserver": "2.1.3", "@types/jest": "30.0.0", - "@types/lodash.debounce": "4.0.9", - "@types/lodash.merge": "4.6.9", - "@types/lodash.throttle": "4.1.9", - "@types/lodash.uniqueid": "4.0.9", "@types/node": "25.5.0", "@types/promise-retry": "1.1.6", "@types/react": "19.2.14", @@ -2180,9 +2173,9 @@ "license": "MIT" }, "node_modules/@emnapi/core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", - "integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", "dev": true, "license": "MIT", "optional": true, @@ -2192,9 +2185,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", - "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", "dev": true, "license": "MIT", "optional": true, @@ -4942,53 +4935,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/lodash": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", - "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/lodash.debounce": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz", - "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/lodash.merge": { - "version": "4.6.9", - "resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.9.tgz", - "integrity": "sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/lodash.throttle": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.9.tgz", - "integrity": "sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/lodash.uniqueid": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/lodash.uniqueid/-/lodash.uniqueid-4.0.9.tgz", - "integrity": "sha512-SEzkJBS8t+tqAUnSmyqbuWqxKU+Z/Xu2cgPtD+Ik0l+M7L2q7So9VoN2rQ8H0mmL87lJ00ykxal8oB54QRet6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/lodash": "*" - } - }, "node_modules/@types/node": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", @@ -5996,9 +5942,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.8", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz", - "integrity": "sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==", + "version": "2.10.10", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.10.tgz", + "integrity": "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6208,9 +6154,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001780", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001780.tgz", - "integrity": "sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==", + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", "dev": true, "funding": [ { @@ -6493,9 +6439,9 @@ } }, "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", "license": "ISC", "engines": { "node": ">= 6" @@ -6744,9 +6690,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.313", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", - "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", + "version": "1.5.321", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.321.tgz", + "integrity": "sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==", "dev": true, "license": "ISC" }, @@ -6808,6 +6754,16 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-toolkit": { + "version": "1.45.1", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.45.1.tgz", + "integrity": "sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6953,6 +6909,29 @@ "eslint": ">=7" } }, + "node_modules/eslint-plugin-react-compiler/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/eslint-plugin-react-compiler/node_modules/zod-validation-error": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.5.4.tgz", + "integrity": "sha512-+hEiRIiPobgyuFlEojnqjJnhFvg4r/i3cqgcm67eehZf/WBaK3g6cD02YU9mtdVxZjv8CzCA9n/Rhrs3yAAvAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.24.4" + } + }, "node_modules/eslint-plugin-react-dom": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-dom/-/eslint-plugin-react-dom-2.13.0.tgz", @@ -7517,9 +7496,9 @@ } }, "node_modules/flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -9442,16 +9421,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/knip/node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/knot.js": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/knot.js/-/knot.js-1.1.5.tgz", @@ -9785,6 +9754,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, "license": "MIT" }, "node_modules/lodash.memoize": { @@ -9794,18 +9764,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", - "license": "MIT" - }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -9813,12 +9771,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.uniqueid": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.uniqueid/-/lodash.uniqueid-4.0.1.tgz", - "integrity": "sha512-GQQWaIeGlL6DIIr06kj1j6sSmBxyNMwI8kaX9aKpHR/XsMTiaXDVPNPAkiboOTK9OJpTJF/dXT3xYoFQnj386Q==", - "license": "MIT" - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -12495,9 +12447,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -13203,9 +13155,9 @@ } }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, "license": "MIT", "engines": { @@ -13352,27 +13304,14 @@ } }, "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } - }, - "node_modules/zod-validation-error": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.5.4.tgz", - "integrity": "sha512-+hEiRIiPobgyuFlEojnqjJnhFvg4r/i3cqgcm67eehZf/WBaK3g6cD02YU9mtdVxZjv8CzCA9n/Rhrs3yAAvAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "zod": "^3.24.4" - } } } } diff --git a/ui/package.json b/ui/package.json index dcac0e73e..e2d61248a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -18,12 +18,9 @@ "csshake": "1.7.0", "date-fns": "4.1.0", "downshift": "9.3.2", + "es-toolkit": "1.45.1", "favico.js": "0.3.10", "fontfaceobserver": "2.3.0", - "lodash.debounce": "4.0.8", - "lodash.merge": "4.6.2", - "lodash.throttle": "4.1.1", - "lodash.uniqueid": "4.0.1", "mobx": "6.15.0", "mobx-react-lite": "4.1.1", "promise-retry": "2.0.1", @@ -54,10 +51,6 @@ "@types/bricks.js": "1.8.5", "@types/fontfaceobserver": "2.1.3", "@types/jest": "30.0.0", - "@types/lodash.debounce": "4.0.9", - "@types/lodash.merge": "4.6.9", - "@types/lodash.throttle": "4.1.9", - "@types/lodash.uniqueid": "4.0.9", "@types/node": "25.5.0", "@types/promise-retry": "1.1.6", "@types/react": "19.2.14", diff --git a/ui/src/Common/Fetch.test.ts b/ui/src/Common/Fetch.test.ts index 3fa06eae2..7f5e88201 100644 --- a/ui/src/Common/Fetch.test.ts +++ b/ui/src/Common/Fetch.test.ts @@ -1,7 +1,5 @@ import { CommonOptions, FetchGet, FetchRetryConfig } from "./Fetch"; -import merge from "lodash.merge"; - import fetchMock from "@fetch-mock/jest"; beforeEach(() => { @@ -31,9 +29,10 @@ describe("Fetch", () => { const request = func("http://example.com/", {}, jest.fn()); await expect(request).resolves.toMatchObject({ status: 200 }); expect(fetchMock.callHistory.lastCall()?.url).toBe("http://example.com/"); - expect(fetchMock.callHistory.lastCall()?.options).toEqual( - merge({}, CommonOptions, methodOptions[name]), - ); + expect(fetchMock.callHistory.lastCall()?.options).toEqual({ + ...CommonOptions, + ...methodOptions[name], + }); }); it(`${name}: custom keys are merged with defaults`, async () => { @@ -46,15 +45,11 @@ describe("Fetch", () => { ); await expect(request).resolves.toMatchObject({ status: 200 }); expect(fetchMock.callHistory.lastCall()?.url).toBe("http://example.com/"); - expect(fetchMock.callHistory.lastCall()?.options).toEqual( - merge( - {}, - CommonOptions, - methodOptions[name], - { keepalive: false }, - () => {}, - ), - ); + expect(fetchMock.callHistory.lastCall()?.options).toEqual({ + ...CommonOptions, + ...methodOptions[name], + keepalive: false, + }); }); it(`${name}: custom credentials are used when passed`, async () => { @@ -68,12 +63,12 @@ describe("Fetch", () => { ); await expect(request).resolves.toMatchObject({ status: 200 }); expect(fetchMock.callHistory.lastCall()?.url).toBe("http://example.com/"); - expect(fetchMock.callHistory.lastCall()?.options).toEqual( - merge({}, CommonOptions, methodOptions[name], { - credentials: "omit", - redirect: "follow", - }), - ); + expect(fetchMock.callHistory.lastCall()?.options).toEqual({ + ...CommonOptions, + ...methodOptions[name], + credentials: "omit", + redirect: "follow", + }); }); } diff --git a/ui/src/Common/Fetch.ts b/ui/src/Common/Fetch.ts index 5e98050da..9f664b739 100644 --- a/ui/src/Common/Fetch.ts +++ b/ui/src/Common/Fetch.ts @@ -1,12 +1,10 @@ -import merge from "lodash.merge"; - import promiseRetry from "promise-retry"; const CommonOptions = { mode: "cors", credentials: "include", redirect: "follow", -}; +} as const; const FetchRetryConfig = { retries: 9, @@ -23,20 +21,12 @@ const FetchGet = async ( ): Promise => await promiseRetry( (retry, number) => - fetch( - uri, - merge( - {}, - { - method: "GET", - }, - CommonOptions, - { - mode: number <= FetchRetryConfig.retries ? "cors" : "no-cors", - }, - options, - ), - ).catch((err) => { + fetch(uri, { + ...{ method: "GET" }, + ...CommonOptions, + mode: number <= FetchRetryConfig.retries ? "cors" : "no-cors", + ...options, + }).catch((err) => { beforeRetry && beforeRetry(number); return retry(err); }), diff --git a/ui/src/Components/Fetcher/index.test.tsx b/ui/src/Components/Fetcher/index.test.tsx index 618fa6715..c1eda688e 100644 --- a/ui/src/Components/Fetcher/index.test.tsx +++ b/ui/src/Components/Fetcher/index.test.tsx @@ -25,7 +25,7 @@ beforeEach(() => { .spyOn(alertStore, "fetchWithThrottle") .mockImplementation(() => { alertStore.status.setIdle(); - return new Promise((success) => { + return new Promise((success) => { success(); }); }); diff --git a/ui/src/Components/Grid/AlertGrid/Grid.tsx b/ui/src/Components/Grid/AlertGrid/Grid.tsx index 1fea4b04d..04b03b524 100644 --- a/ui/src/Components/Grid/AlertGrid/Grid.tsx +++ b/ui/src/Components/Grid/AlertGrid/Grid.tsx @@ -12,7 +12,7 @@ import React, { import { observer } from "mobx-react-lite"; -import debounce from "lodash.debounce"; +import { debounce } from "es-toolkit"; import type { SizeDetail } from "bricks.js"; diff --git a/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.test.tsx b/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.test.tsx index 70f9a1ff9..536150dfa 100644 --- a/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.test.tsx +++ b/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.test.tsx @@ -5,9 +5,14 @@ import { AlertGroupWidthConfiguration } from "./AlertGroupWidthConfiguration"; let settingsStore: Settings; beforeEach(() => { + jest.useFakeTimers(); settingsStore = new Settings(null); }); +afterEach(() => { + jest.useRealTimers(); +}); + const renderConfiguration = () => { return render(); }; @@ -27,6 +32,7 @@ describe("", () => { fireEvent.keyDown(slider!, { key: "ArrowLeft", keyCode: 37 }); fireEvent.keyUp(slider!, { key: "ArrowLeft", keyCode: 37 }); + jest.advanceTimersByTime(250); expect(settingsStore.gridConfig.config.groupWidth).toBe(410); @@ -34,6 +40,7 @@ describe("", () => { fireEvent.keyUp(slider!, { key: "ArrowRight", keyCode: 39 }); fireEvent.keyDown(slider!, { key: "ArrowRight", keyCode: 39 }); fireEvent.keyUp(slider!, { key: "ArrowRight", keyCode: 39 }); + jest.advanceTimersByTime(250); expect(settingsStore.gridConfig.config.groupWidth).toBe(430); }); diff --git a/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.tsx b/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.tsx index 40ed1603b..b7890c83e 100644 --- a/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.tsx +++ b/ui/src/Components/MainModal/Configuration/AlertGroupWidthConfiguration.tsx @@ -1,6 +1,6 @@ import { FC, useState } from "react"; -import debounce from "lodash.debounce"; +import { debounce } from "es-toolkit"; import { Range } from "react-range"; diff --git a/ui/src/Hooks/useFetchAny.ts b/ui/src/Hooks/useFetchAny.ts index a7afa69ef..6de0bad79 100644 --- a/ui/src/Hooks/useFetchAny.ts +++ b/ui/src/Hooks/useFetchAny.ts @@ -1,7 +1,5 @@ import { useState, useEffect, useCallback } from "react"; -import merge from "lodash.merge"; - import { CommonOptions } from "Common/Fetch"; export interface UpstreamT { @@ -67,10 +65,11 @@ const useFetchAny = ( inProgress: true, }); try { - const res = await (fetcher || fetch)( - uri, - merge({}, { method: "GET" }, CommonOptions, options) as RequestInit, - ); + const res = await (fetcher || fetch)(uri, { + ...{ method: "GET" }, + ...CommonOptions, + ...options, + } as RequestInit); if (!isCancelled) { let body; diff --git a/ui/src/Hooks/useFetchDelete.ts b/ui/src/Hooks/useFetchDelete.ts index b6a9ba6e0..87c2d36f6 100644 --- a/ui/src/Hooks/useFetchDelete.ts +++ b/ui/src/Hooks/useFetchDelete.ts @@ -1,7 +1,5 @@ import { useState, useEffect } from "react"; -import merge from "lodash.merge"; - import { CommonOptions } from "Common/Fetch"; type useFetchDeleteDepsT = string[] | number[]; @@ -28,10 +26,11 @@ const useFetchDelete = ( const fetchData = async () => { try { setIsDeleting(true); - const res = await fetch( - uri, - merge({}, { method: "DELETE" }, CommonOptions, options), - ); + const res = await fetch(uri, { + ...{ method: "DELETE" }, + ...CommonOptions, + ...options, + }); const text = await res.text(); if (!isCancelled) { diff --git a/ui/src/Hooks/useFetchGet.ts b/ui/src/Hooks/useFetchGet.ts index 4b384e604..a7c39d9c0 100644 --- a/ui/src/Hooks/useFetchGet.ts +++ b/ui/src/Hooks/useFetchGet.ts @@ -1,7 +1,5 @@ import { useState, useEffect, useCallback, useRef } from "react"; -import merge from "lodash.merge"; - import promiseRetry from "promise-retry"; import { CommonOptions, FetchRetryConfig } from "Common/Fetch"; @@ -65,19 +63,11 @@ const useFetchGet = ( const res = await promiseRetry( (retry: (err: Error) => Promise, n: number) => - (fetcher || fetch)( - uri, - merge( - {}, - { - method: "GET", - }, - CommonOptions, - { - mode: n <= FetchRetryConfig.retries ? "cors" : "no-cors", - }, - ) as RequestInit, - ).catch((err: Error) => { + (fetcher || fetch)(uri, { + ...{ method: "GET" }, + ...CommonOptions, + mode: n <= FetchRetryConfig.retries ? "cors" : "no-cors", + } as RequestInit).catch((err: Error) => { if (!isCanceledRef.current) { setResponse((r) => ({ ...r, diff --git a/ui/src/Stores/AlertStore.ts b/ui/src/Stores/AlertStore.ts index 560eab64b..3ae5e8ffe 100644 --- a/ui/src/Stores/AlertStore.ts +++ b/ui/src/Stores/AlertStore.ts @@ -1,6 +1,6 @@ import { observable, action, computed, toJS } from "mobx"; -import throttle from "lodash.throttle"; +import { throttle } from "es-toolkit"; import { FetchGet } from "Common/Fetch"; import type { diff --git a/ui/src/Stores/SilenceFormStore.ts b/ui/src/Stores/SilenceFormStore.ts index 5058a1be7..a70102d5a 100644 --- a/ui/src/Stores/SilenceFormStore.ts +++ b/ui/src/Stores/SilenceFormStore.ts @@ -1,7 +1,5 @@ import { observable, action, computed } from "mobx"; -import uniqueId from "lodash.uniqueid"; - import { parseISO } from "date-fns/parseISO"; import { addHours } from "date-fns/addHours"; import { addMinutes } from "date-fns/addMinutes"; @@ -20,6 +18,9 @@ import type { import { StringToOption, OptionT, MultiValueOptionT } from "Common/Select"; import { QueryOperators } from "Common/Query"; +let idCounter = 0; +const uniqueId = (): string => String(++idCounter); + export interface MatcherT { name: string; values: OptionT[];