Compare commits

37 Commits

Author SHA1 Message Date
Borislav Pantaleev
c596d38d7a Add notifications badge and page (#240)
* WIP on server notifications

* WIP: Add server notifications page and removal of notifications

* improve design

* fix missing notifications case; add tooltop

* Fix api response

* fix tests

* add docs; update readme
2024-12-19 11:24:42 +02:00
Aine
c643bdcfce correctly handle MXIDs with not just-domain server names; update testdata config to include that case by default; fixes #239 2024-12-16 12:53:42 +02:00
Aine
630286a781 use the same protocol for .well-known lookup as in homeserver url from the login form, fixes #238 2024-12-16 12:44:00 +02:00
Aine
71e90c12a7 enable media bulk delete button, fixes #216 2024-12-16 11:51:12 +02:00
Aine
db6594f11f Merge pull request #237 from etkecc/purge-remote-media
Add "Purge Remote Media" button
2024-12-16 09:31:01 +00:00
Aine
7844987fe0 update readme 2024-12-16 11:30:48 +02:00
Aine
9f2293f9c4 Add "Purge Remote Media" button 2024-12-16 11:25:49 +02:00
Aine
fd4bf7ce5c Merge pull request #221 from etkecc/dependabot/npm_and_yarn/typescript-eslint-8.18.0
Bump typescript-eslint from 8.17.0 to 8.18.0
2024-12-16 08:50:35 +00:00
Aine
0dc969ce2c Merge pull request #236 from etkecc/dependabot/npm_and_yarn/mui/icons-material-6.2.0
Bump @mui/icons-material from 6.1.9 to 6.2.0
2024-12-16 08:50:25 +00:00
dependabot[bot]
f5455ef667 Bump @mui/icons-material from 6.1.9 to 6.2.0
Bumps [@mui/icons-material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-icons-material) from 6.1.9 to 6.2.0.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/v6.2.0/packages/mui-icons-material)

---
updated-dependencies:
- dependency-name: "@mui/icons-material"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:36:21 +00:00
dependabot[bot]
edb8028162 Bump typescript-eslint from 8.17.0 to 8.18.0
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.17.0 to 8.18.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.18.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:35:55 +00:00
Aine
f415d637e9 Merge pull request #220 from etkecc/dependabot/npm_and_yarn/eslint-9.17.0
Bump eslint from 9.16.0 to 9.17.0
2024-12-16 08:34:50 +00:00
Aine
2c9103c769 Merge pull request #223 from etkecc/dependabot/npm_and_yarn/types/node-22.10.2
Bump @types/node from 22.10.1 to 22.10.2
2024-12-16 08:34:30 +00:00
Aine
1c6f91d3a9 Merge pull request #224 from etkecc/dependabot/npm_and_yarn/mui/material-6.2.0
Bump @mui/material from 6.1.10 to 6.2.0
2024-12-16 08:34:16 +00:00
Aine
05826e2ae1 Merge pull request #225 from etkecc/dependabot/npm_and_yarn/emotion/react-11.14.0
Bump @emotion/react from 11.13.5 to 11.14.0
2024-12-16 08:34:03 +00:00
Aine
f6ebd71ac2 Merge pull request #227 from etkecc/dependabot/npm_and_yarn/typescript-eslint/parser-8.18.0
Bump @typescript-eslint/parser from 8.17.0 to 8.18.0
2024-12-16 08:33:50 +00:00
dependabot[bot]
49d0157c81 Bump @emotion/react from 11.13.5 to 11.14.0
Bumps [@emotion/react](https://github.com/emotion-js/emotion) from 11.13.5 to 11.14.0.
- [Release notes](https://github.com/emotion-js/emotion/releases)
- [Changelog](https://github.com/emotion-js/emotion/blob/main/CHANGELOG.md)
- [Commits](https://github.com/emotion-js/emotion/compare/@emotion/react@11.13.5...@emotion/react@11.14.0)

---
updated-dependencies:
- dependency-name: "@emotion/react"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:32:54 +00:00
dependabot[bot]
ccfc5e4478 Bump @mui/material from 6.1.10 to 6.2.0
Bumps [@mui/material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material) from 6.1.10 to 6.2.0.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/v6.2.0/packages/mui-material)

---
updated-dependencies:
- dependency-name: "@mui/material"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:32:46 +00:00
dependabot[bot]
66953dba3d Bump @types/node from 22.10.1 to 22.10.2
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.1 to 22.10.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:31:49 +00:00
dependabot[bot]
f4df8c070c Bump eslint from 9.16.0 to 9.17.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.16.0 to 9.17.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.16.0...v9.17.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:31:33 +00:00
dependabot[bot]
c3fa4daddb Bump @typescript-eslint/parser from 8.17.0 to 8.18.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.17.0 to 8.18.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.18.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:31:33 +00:00
Aine
b6782c64f7 Merge pull request #235 from etkecc/dependabot/npm_and_yarn/npm_and_yarn-af93afb32e
Bump nanoid from 3.3.7 to 3.3.8 in the npm_and_yarn group
2024-12-16 08:30:20 +00:00
Aine
8a65621b35 Merge pull request #228 from etkecc/dependabot/npm_and_yarn/ra-language-french-5.4.2
Bump ra-language-french from 5.4.1 to 5.4.2
2024-12-16 08:30:05 +00:00
Aine
b8b0d46070 Merge pull request #229 from etkecc/dependabot/npm_and_yarn/tanstack/react-query-5.62.7
Bump @tanstack/react-query from 5.62.3 to 5.62.7
2024-12-16 08:29:53 +00:00
dependabot[bot]
2f73970e47 Bump nanoid from 3.3.7 to 3.3.8 in the npm_and_yarn group
Bumps the npm_and_yarn group with 1 update: [nanoid](https://github.com/ai/nanoid).


Updates `nanoid` from 3.3.7 to 3.3.8
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:29:50 +00:00
Aine
ceacddf9c6 Merge pull request #231 from etkecc/dependabot/npm_and_yarn/emotion/styled-11.14.0
Bump @emotion/styled from 11.13.5 to 11.14.0
2024-12-16 08:29:39 +00:00
Aine
4e89ad5f56 Merge pull request #234 from etkecc/dependabot/npm_and_yarn/eslint/js-9.17.0
Bump @eslint/js from 9.16.0 to 9.17.0
2024-12-16 08:29:27 +00:00
Aine
1d4b4f97da Merge pull request #232 from etkecc/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-8.18.0
Bump @typescript-eslint/eslint-plugin from 8.17.0 to 8.18.0
2024-12-16 08:29:16 +00:00
Aine
ac36a93203 Merge pull request #230 from etkecc/dependabot/npm_and_yarn/react-hook-form-7.54.1
Bump react-hook-form from 7.54.0 to 7.54.1
2024-12-16 08:29:03 +00:00
Aine
1dd0b242e2 Merge pull request #233 from etkecc/dependabot/npm_and_yarn/react-admin-5.4.2
Bump react-admin from 5.4.1 to 5.4.2
2024-12-16 08:28:46 +00:00
dependabot[bot]
608d9fa9d8 Bump @eslint/js from 9.16.0 to 9.17.0
Bumps [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) from 9.16.0 to 9.17.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v9.17.0/packages/js)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:09:20 +00:00
dependabot[bot]
f5841c6a30 Bump react-admin from 5.4.1 to 5.4.2
Bumps [react-admin](https://github.com/marmelab/react-admin) from 5.4.1 to 5.4.2.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.4.1...v5.4.2)

---
updated-dependencies:
- dependency-name: react-admin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:09:11 +00:00
dependabot[bot]
266b13ce0b Bump @typescript-eslint/eslint-plugin from 8.17.0 to 8.18.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.17.0 to 8.18.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.18.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:09:02 +00:00
dependabot[bot]
1be9171b93 Bump @emotion/styled from 11.13.5 to 11.14.0
Bumps [@emotion/styled](https://github.com/emotion-js/emotion) from 11.13.5 to 11.14.0.
- [Release notes](https://github.com/emotion-js/emotion/releases)
- [Changelog](https://github.com/emotion-js/emotion/blob/main/CHANGELOG.md)
- [Commits](https://github.com/emotion-js/emotion/compare/@emotion/styled@11.13.5...@emotion/styled@11.14.0)

---
updated-dependencies:
- dependency-name: "@emotion/styled"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:08:48 +00:00
dependabot[bot]
037c2acee2 Bump react-hook-form from 7.54.0 to 7.54.1
Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.54.0 to 7.54.1.
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.54.0...v7.54.1)

---
updated-dependencies:
- dependency-name: react-hook-form
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:08:29 +00:00
dependabot[bot]
38a0c9a9fc Bump @tanstack/react-query from 5.62.3 to 5.62.7
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.62.3 to 5.62.7.
- [Release notes](https://github.com/TanStack/query/releases)
- [Commits](https://github.com/TanStack/query/commits/v5.62.7/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:08:20 +00:00
dependabot[bot]
8703cff7bf Bump ra-language-french from 5.4.1 to 5.4.2
Bumps [ra-language-french](https://github.com/marmelab/react-admin) from 5.4.1 to 5.4.2.
- [Release notes](https://github.com/marmelab/react-admin/releases)
- [Changelog](https://github.com/marmelab/react-admin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/marmelab/react-admin/compare/v5.4.1...v5.4.2)

---
updated-dependencies:
- dependency-name: ra-language-french
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 08:08:11 +00:00
26 changed files with 766 additions and 212 deletions

View File

@@ -107,6 +107,7 @@ The following changes are already implemented:
* 🎞️ [Add "Media" tab for rooms](https://github.com/etkecc/synapse-admin/pull/196)
* 📞 [Support E.164-based Matrix IDs (MSC4009)](https://github.com/etkecc/synapse-admin/pull/214)
* 🛑 [Add support for Account Suspension (MSC3823)](https://github.com/etkecc/synapse-admin/pull/195)
* 🗑️ [Add "Purge Remote Media" button](https://github.com/etkecc/synapse-admin/pull/237)
#### exclusive for [etke.cc](https://etke.cc) customers
@@ -114,6 +115,7 @@ We at [etke.cc](https://etke.cc) attempting to develop everything open-source, b
The following list contains such features - they are only available for [etke.cc](https://etke.cc) customers.
* 📊 [Server Status indicator and page](https://github.com/etkecc/synapse-admin/pull/182)
* 📬 [Server Notifications indicator and page](https://github.com/etkecc/synapse-admin/pull/240)
### Development

View File

@@ -11,20 +11,20 @@
"url": "https://github.com/etkecc/synapse-admin"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"@eslint/js": "^9.17.0",
"@testing-library/dom": "^10.0.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.14",
"@types/lodash": "^4.17.13",
"@types/node": "^22.10.1",
"@types/node": "^22.10.2",
"@types/papaparse": "^5.3.15",
"@types/react": "^18.3.12",
"@typescript-eslint/eslint-plugin": "^8.14.0",
"@typescript-eslint/parser": "^8.15.0",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.16.0",
"eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
@@ -39,19 +39,19 @@
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.7.2",
"typescript-eslint": "^8.17.0",
"typescript-eslint": "^8.18.0",
"vite": "^6.0.3",
"vite-plugin-version-mark": "^0.1.4"
},
"dependencies": {
"@emotion/react": "^11.13.5",
"@emotion/styled": "^11.13.5",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@haleos/ra-language-german": "^1.0.0",
"@haxqer/ra-language-chinese": "^4.16.2",
"@mui/icons-material": "^6.1.9",
"@mui/material": "^6.1.10",
"@mui/icons-material": "^6.2.0",
"@mui/material": "^6.2.0",
"@mui/utils": "^5.16.8",
"@tanstack/react-query": "^5.62.3",
"@tanstack/react-query": "^5.62.7",
"history": "^5.3.0",
"lodash": "^4.17.21",
"papaparse": "^5.4.1",
@@ -59,13 +59,13 @@
"ra-i18n-polyglot": "^5.3.4",
"ra-language-english": "^5.3.4",
"ra-language-farsi": "^5.1.0",
"ra-language-french": "^5.4.1",
"ra-language-french": "^5.4.2",
"ra-language-italian": "^3.13.1",
"ra-language-russian": "^4.14.2",
"react": "^18.3.1",
"react-admin": "^5.4.1",
"react-admin": "^5.4.2",
"react-dom": "^18.3.1",
"react-hook-form": "^7.54.0",
"react-hook-form": "^7.54.1",
"react-is": "^18.3.1",
"react-router": "^6.26.2",
"react-router-dom": "^6.28.0"

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -25,6 +25,7 @@ import authProvider from "./synapse/authProvider";
import dataProvider from "./synapse/dataProvider";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import ServerStatusPage from "./components/etke.cc/ServerStatusPage";
import ServerNotificationsPage from "./components/etke.cc/ServerNotificationsPage";
// TODO: Can we use lazy loading together with browser locale?
const messages = {
@@ -65,6 +66,7 @@ export const App = () => (
<CustomRoutes>
<Route path="/import_users" element={<UserImport />} />
<Route path="/server_status" element={<ServerStatusPage />} />
<Route path="/server_notifications" element={<ServerNotificationsPage />} />
</CustomRoutes>
<Resource {...users} />
<Resource {...rooms} />

View File

@@ -5,6 +5,7 @@ import { Icons, DefaultIcon } from "../utils/icons";
import { MenuItem, GetConfig, ClearConfig } from "../utils/config";
import Footer from "./Footer";
import ServerStatusBadge from "./etke.cc/ServerStatusBadge";
import { ServerNotificationsBadge } from "./etke.cc/ServerNotificationsBadge";
const AdminUserMenu = () => {
const [open, setOpen] = useState(false);
@@ -50,6 +51,7 @@ const AdminAppBar = () => {
return (<AppBar userMenu={<AdminUserMenu />}>
<TitlePortal />
<ServerStatusBadge />
<ServerNotificationsBadge />
<InspectorButton />
</AppBar>);
};

View File

@@ -28,3 +28,15 @@ Server Status page. This page contains the following information:
* Overall server status (up/updating/has issues)
* Details about the currently running command (if any)
* Details about the server's components statuses (up/down with error details and suggested actions) by categories
### Server Notifications icon
![Server Notifications icon](../../../screenshots/etke.cc/server-notifications/badge.webp)
In the application bar the new notifications icon is displayed that shows the number of unread (not removed) notifications
### Server Notifications page
![Server Notifications Page](../../../screenshots/etke.cc/server-notifications/page.webp)
When you click on a notification from the [Server Notifications icon](#server-notifications-icon)'s list in the application bar, you will be redirected to the Server Notifications page. This page contains the full text of all the notifications you have about your server.

View File

@@ -0,0 +1,184 @@
import { Badge, useTheme, Button, Paper, Popper, ClickAwayListener, Box, List, ListItem, ListItemText, Typography, ListSubheader, IconButton, Divider, Tooltip } from "@mui/material";
import NotificationsIcon from '@mui/icons-material/Notifications';
import DeleteIcon from "@mui/icons-material/Delete";
import { useDataProvider, useStore } from "react-admin";
import { useNavigate } from "react-router";
import { Fragment, useEffect, useState } from "react";
import { useAppContext } from "../../Context";
import { ServerNotificationsResponse } from "../../synapse/dataProvider";
const SERVER_NOTIFICATIONS_INTERVAL_TIME = 300000;
const useServerNotifications = () => {
const [serverNotifications, setServerNotifications] = useStore<ServerNotificationsResponse>("serverNotifications", { notifications: [], success: false });
const { etkeccAdmin } = useAppContext();
const dataProvider = useDataProvider();
const { notifications, success } = serverNotifications;
const fetchNotifications = async () => {
const notificationsResponse: ServerNotificationsResponse = await dataProvider.getServerNotifications(etkeccAdmin);
setServerNotifications({
...notificationsResponse,
notifications: notificationsResponse.notifications,
success: notificationsResponse.success
});
};
const deleteServerNotifications = async () => {
const deleteResponse = await dataProvider.deleteServerNotifications(etkeccAdmin);
if (deleteResponse.success) {
await fetchNotifications();
}
};
useEffect(() => {
let serverNotificationsInterval: NodeJS.Timeout;
if (etkeccAdmin) {
fetchNotifications();
setTimeout(() => {
// start the interval after the SERVER_NOTIFICATIONS_INTERVAL_TIME to avoid too many requests
serverNotificationsInterval = setInterval(fetchNotifications, SERVER_NOTIFICATIONS_INTERVAL_TIME);
}, SERVER_NOTIFICATIONS_INTERVAL_TIME);
}
return () => {
if (serverNotificationsInterval) {
clearInterval(serverNotificationsInterval);
}
}
}, [etkeccAdmin]);
return { success, notifications, deleteServerNotifications };
};
export const ServerNotificationsBadge = () => {
const navigate = useNavigate();
const { success, notifications, deleteServerNotifications } = useServerNotifications();
const theme = useTheme();
// Modify menu state to work with Popper
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleOpen = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const handleSeeAllNotifications = () => {
handleClose();
navigate("/server_notifications");
};
const handleClearAllNotifications = async () => {
deleteServerNotifications()
handleClose();
};
if (!success) {
return null;
}
return (
<Box>
<IconButton onClick={handleOpen} sx={{ color: theme.palette.common.white }}>
<Tooltip title={notifications && notifications.length > 0 ? `${notifications.length} new notifications` : `No notifications yet`}>
{notifications && notifications.length > 0 && (
<Badge badgeContent={notifications.length} color="error">
<NotificationsIcon />
</Badge>
) || <NotificationsIcon />}
</Tooltip>
</IconButton>
<Popper
open={open}
anchorEl={anchorEl}
placement="bottom-end"
style={{ zIndex: 1300 }}
>
<ClickAwayListener onClickAway={handleClose}>
<Paper
elevation={3}
sx={{
p: 1,
maxHeight: "350px",
overflowY: "auto",
minWidth: "300px",
maxWidth: {
xs: "100vw", // Full width on mobile
sm: "400px" // Fixed width on desktop
}
}}
>
{(!notifications || notifications.length === 0) ? (
<Typography sx={{ p: 1 }} variant="body2">No new notifications</Typography>
) : (
<List sx={{ p: 0 }} dense={true}>
<ListSubheader
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
fontWeight: "bold",
backgroundColor: "inherit",
}}
>
<Typography variant="h6">Notifications</Typography>
<Box sx={{ cursor: "pointer", color: theme.palette.primary.main }} onClick={() => handleSeeAllNotifications()}>See all notifications</Box>
</ListSubheader>
<Divider />
{notifications.map((notification, index) => {
return (<Fragment key={notification.event_id ? notification.event_id : index }>
<ListItem
onClick={() => handleSeeAllNotifications()}
sx={{
"&:hover": {
backgroundColor: "action.hover",
cursor: "pointer"
}
}}
>
<ListItemText
primary={
<Typography
variant="body2"
sx={{
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap"
}}
dangerouslySetInnerHTML={{ __html: notification.output.split("\n")[0] }}
/>
}
/>
</ListItem>
<Divider />
</Fragment>
)})}
<ListItem>
<Button
key="clear-all-notifications"
onClick={() => handleClearAllNotifications()}
size="small"
color="error"
sx={{
pl: 0,
pt: 1,
verticalAlign: "middle"
}}
>
<DeleteIcon fontSize="small" sx={{ mr: 1 }} />
Clear all
</Button>
</ListItem>
</List>
)}
</Paper>
</ClickAwayListener>
</Popper>
</Box>
);
};

View File

@@ -0,0 +1,58 @@
import { Box, Typography, Paper, Button } from "@mui/material"
import { Stack } from "@mui/material"
import { useStore } from "react-admin"
import dataProvider, { ServerNotificationsResponse } from "../../synapse/dataProvider"
import { useAppContext } from "../../Context";
import DeleteIcon from "@mui/icons-material/Delete";
const DisplayTime = ({ date }: { date: string }) => {
const dateFromDateString = new Date(date);
return <>{dateFromDateString.toLocaleString()}</>;
};
const ServerNotificationsPage = () => {
const { etkeccAdmin } = useAppContext();
const [serverNotifications, setServerNotifications] = useStore<ServerNotificationsResponse>("serverNotifications", {
notifications: [],
success: false,
});
const notifications = serverNotifications.notifications;
return (
<Stack spacing={3} mt={3}>
<Stack spacing={1} direction="row" alignItems="center">
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", gap: 1 }}>
<Typography variant="h4">Server Notifications</Typography>
<Button variant="text" color="error" onClick={async () => {
await dataProvider.deleteServerNotifications(etkeccAdmin);
setServerNotifications({
notifications: [],
success: true,
});
}}>
<DeleteIcon fontSize="small" sx={{ mr: 1 }} /> Clear
</Button>
</Box>
</Stack>
{notifications.length === 0 ? (
<Paper sx={{ p: 2 }}>
<Typography>No new notifications.</Typography>
</Paper>
) : (
notifications.map((notification, index) => (
<Paper key={notification.event_id ? notification.event_id : index} sx={{ p: 2 }}>
<Stack spacing={1}>
<Typography variant="subtitle1" fontWeight="bold" color="text.secondary">
<DisplayTime date={notification.sent_at} />
</Typography>
<Typography dangerouslySetInnerHTML={{ __html: notification.output }} />
</Stack>
</Paper>
))
)}
</Stack>
);
};
export default ServerNotificationsPage;

View File

@@ -124,6 +124,80 @@ export const DeleteMediaButton = (props: ButtonProps) => {
);
};
const PurgeRemoteMediaDialog = ({ open, onClose, onSubmit }) => {
const translate = useTranslate();
const PurgeRemoteMediaToolbar = (props: ToolbarProps) => (
<Toolbar {...props}>
<SaveButton label="purge_remote_media.action.send" icon={<DeleteSweepIcon />} />
<Button label="ra.action.cancel" onClick={onClose}>
<IconCancel />
</Button>
</Toolbar>
);
return (
<Dialog open={open} onClose={onClose}>
<DialogTitle>{translate("purge_remote_media.action.send")}</DialogTitle>
<DialogContent>
<DialogContentText>{translate("purge_remote_media.helper.send")}</DialogContentText>
<SimpleForm toolbar={<PurgeRemoteMediaToolbar />} onSubmit={onSubmit}>
<DateTimeInput
source="before_ts"
label="purge_remote_media.fields.before_ts"
defaultValue={0}
parse={dateParser}
/>
</SimpleForm>
</DialogContent>
</Dialog>
);
};
export const PurgeRemoteMediaButton = (props: ButtonProps) => {
const theme = useTheme();
const [open, setOpen] = useState(false);
const notify = useNotify();
const dataProvider = useDataProvider<SynapseDataProvider>();
const { mutate: purgeRemoteMedia, isPending } = useMutation({
mutationFn: (values: DeleteMediaParams) => dataProvider.purgeRemoteMedia(values),
onSuccess: () => {
notify("purge_remote_media.action.send_success");
closeDialog();
},
onError: () => {
notify("purge_remote_media.action.send_failure", {
type: "error",
});
},
});
const openDialog = () => setOpen(true);
const closeDialog = () => setOpen(false);
return (
<>
<Button
{...props}
label="purge_remote_media.action.send"
onClick={openDialog}
disabled={isPending}
sx={{
"&:hover": {
// Reset on mouse devices
"@media (hover: none)": {
backgroundColor: "transparent",
},
},
}}
>
<DeleteSweepIcon />
</Button>
<PurgeRemoteMediaDialog open={open} onClose={closeDialog} onSubmit={purgeRemoteMedia} />
</>
);
};
export const ProtectMediaButton = (props: ButtonProps) => {
const record = useRecordContext();
const translate = useTranslate();

View File

@@ -147,6 +147,20 @@ const de: SynapseTranslationMessages = {
send: "Diese API löscht die lokalen Medien von der Festplatte des eigenen Servers. Dies umfasst alle lokalen Miniaturbilder und Kopien von Medien. Diese API wirkt sich nicht auf Medien aus, die sich in externen Medien-Repositories befinden.",
},
},
purge_remote_media: {
name: "Externe Medien",
fields: {
before_ts: "letzter Zugriff vor",
},
action: {
send: "Externe Medien löschen",
send_success: "Die Anfrage zum Löschen externer Medien wurde gesendet.",
send_failure: "Bei der Anfrage zum Löschen externer Medien ist ein Fehler aufgetreten.",
},
helper: {
send: "Diese API löscht den externen Medien-Cache von der Festplatte Ihres eigenen Servers. Dazu gehören alle lokalen Thumbnails und Kopien heruntergeladener Medien. Diese API beeinflusst nicht die Medien, die in das eigene Medienarchiv des Servers hochgeladen wurden.",
},
},
resources: {
users: {
name: "Benutzer",

View File

@@ -120,6 +120,20 @@ const en: SynapseTranslationMessages = {
send: "This API deletes the local media from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to external media repositories.",
},
},
purge_remote_media: {
name: "Remote Media",
fields: {
before_ts: "last access before",
},
action: {
send: "Purge remote media",
send_success: "Purge remote media request has been sent.",
send_failure: "An error has occurred with the purge remote media request.",
},
helper: {
send: "This API purges the remote media cache from the disk of your own server. This includes any local thumbnails and copies of media downloaded. This API will not affect media that has been uploaded to the server's own media repository.",
},
},
resources: {
users: {
name: "User |||| Users",

View File

@@ -114,6 +114,20 @@ const fa: SynapseTranslationMessages = {
send: "این API رسانه های محلی را از دیسک سرور خود حذف می کند. این شامل هر تصویر کوچک محلی و کپی از رسانه دانلود شده است. این API بر رسانه‌هایی که در مخازن رسانه خارجی آپلود شده‌اند تأثیری نخواهد گذاشت.",
},
},
purge_remote_media: {
name: "رسانه‌های از راه دور",
fields: {
before_ts: "آخرین دسترسی قبل از",
},
action: {
send: "پاک کردن رسانه‌های از راه دور",
send_success: "درخواست پاک کردن رسانه‌های از راه دور ارسال شد.",
send_failure: "درخواست برای پاک کردن رسانه‌های از راه دور با خطا مواجه شد.",
},
helper: {
send: "این API کش رسانه‌های از راه دور را از دیسک سرور شما پاک می‌کند. این شامل هر گونه بندانگشتی محلی و نسخه‌های رسانه‌های دانلود شده می‌شود. این API بر رسانه‌های آپلود شده به مخزن رسانه سرور تأثیری نخواهد داشت.",
},
},
resources: {
users: {
name: "کاربر |||| کاربران",

View File

@@ -117,6 +117,20 @@ const fr: SynapseTranslationMessages = {
send: "Cette API supprime les médias locaux du disque de votre propre serveur. Cela inclut toutes les vignettes locales et les copies des médias téléchargés. Cette API n'affectera pas les médias qui ont été téléversés dans des dépôts de médias externes.",
},
},
purge_remote_media: {
name: "Médias distants",
fields: {
before_ts: "dernier accès avant",
},
action: {
send: "Purger les médias distants",
send_success: "La demande de purge des médias distants a été envoyée.",
send_failure: "Une erreur est survenue lors de la demande de purge des médias distants.",
},
helper: {
send: "Cette API purge le cache des médias distants du disque de votre propre serveur. Cela inclut toutes les vignettes locales et les copies des médias téléchargés. Cette API n'affectera pas les médias qui ont été téléchargés dans le dépôt de médias du serveur.",
},
},
resources: {
users: {
name: "Utilisateur |||| Utilisateurs",

14
src/i18n/index.d.ts vendored
View File

@@ -112,6 +112,20 @@ interface SynapseTranslationMessages extends TranslationMessages {
send: string;
};
};
purge_remote_media: {
name: string;
fields: {
before_ts: string;
};
action: {
send: string;
send_success: string;
send_failure: string;
};
helper: {
send: string;
};
};
resources: {
users: {
name: string;

View File

@@ -114,6 +114,20 @@ const it: SynapseTranslationMessages = {
send: "Questa API cancella i media locali dal disco del tuo server. Questo include anche ogni miniatura e copia del media scaricato. Questa API non inciderà sui media che sono stati caricati nei repository esterni.",
},
},
purge_remote_media: {
name: "Media Remoti",
fields: {
before_ts: "ultimo accesso prima di",
},
action: {
send: "Elimina media remoti",
send_success: "La richiesta per eliminare i media remoti è stata inviata.",
send_failure: "Si è verificato un errore con la richiesta di eliminazione dei media remoti.",
},
helper: {
send: "Questa API elimina la cache dei media remoti dal disco del tuo server. Questo include qualsiasi miniatura locale e copie di media scaricati. Questa API non influirà sui media che sono stati caricati nel repository multimediale del server.",
},
},
resources: {
users: {
name: "Utente |||| Utenti",

View File

@@ -150,6 +150,20 @@ const ru: SynapseTranslationMessages = {
Данный API не затрагивает файлы, загруженные во внешние хранилища.",
},
},
purge_remote_media: {
name: "Внешние медиа",
fields: {
before_ts: "последний доступ до",
},
action: {
send: "Очистить внешние медиа",
send_success: "Запрос на очистку внешних медиа был отправлен.",
send_failure: "Произошла ошибка при запросе очистки внешних медиа.",
},
helper: {
send: "Этот API очищает кэш внешних медиа с диска вашего сервера. Это включает любые локальные миниатюры и копии загруженных медиа. Этот API не повлияет на медиа, которые были загружены в собственное медиа-хранилище сервера.",
},
},
resources: {
users: {
name: "Пользователь |||| Пользователи",

View File

@@ -142,6 +142,20 @@ const zh: SynapseTranslationMessages = {
send: "这个API会删除您硬盘上的本地媒体。包含了任何的本地缓存和下载的媒体备份。这个API不会影响上传到外部媒体存储库上的媒体文件。",
},
},
purge_remote_media: {
name: "远程媒体",
fields: {
before_ts: "最后访问于之前",
},
action: {
send: "清除远程媒体",
send_success: "远程媒体清除请求已发送。",
send_failure: "发生错误,远程媒体清除请求未成功。",
},
helper: {
send: "此API清除您服务器磁盘上的远程媒体缓存。这包括任何本地缩略图和下载的媒体副本。此API不会影响已经上传到服务器媒体存储库的媒体。",
},
},
resources: {
users: {
name: "用户",

View File

@@ -14,13 +14,14 @@ import {
useListContext,
} from "react-admin";
import { DeleteMediaButton } from "../components/media";
import { DeleteMediaButton, PurgeRemoteMediaButton } from "../components/media";
const ListActions = () => {
const { isLoading, total } = useListContext();
return (
<TopToolbar>
<DeleteMediaButton />
<PurgeRemoteMediaButton />
<ExportButton disabled={isLoading || total === 0} />
</TopToolbar>
);

View File

@@ -50,6 +50,7 @@ import {
SaveButton,
CreateButton,
ExportButton,
BulkDeleteButton,
TopToolbar,
Toolbar,
NumberField,
@@ -496,7 +497,7 @@ export const UserEdit = (props: EditProps) => {
perPage={50}
sort={{ field: "created_ts", order: "DESC" }}
>
<Datagrid sx={{ width: "100%" }}>
<Datagrid sx={{ width: "100%" }} bulkActionButtons={<BulkDeleteButton/>}>
<MediaIDField source="media_id" />
<DateField source="created_ts" showTime options={DATE_FORMAT} />
<DateField source="last_access_ts" showTime options={DATE_FORMAT} />

View File

@@ -80,11 +80,7 @@ const authProvider: AuthProvider = {
localStorage.setItem("access_token", accessToken ? accessToken : json.access_token);
localStorage.setItem("device_id", json.device_id);
localStorage.setItem("login_type", accessToken ? "accessToken" : "credentials");
// when doing access token auth, config is not fetched, so we need to do it here
if (accessToken) {
await FetchConfig();
}
await FetchConfig();
return Promise.resolve({redirectTo: "/"});
} catch(err) {

View File

@@ -291,8 +291,20 @@ export interface ServerProcessResponse {
command?: string;
}
export interface ServerNotification {
event_id: string;
output: string;
sent_at: string;
}
export interface ServerNotificationsResponse {
success: boolean;
notifications: ServerNotification[];
}
export interface SynapseDataProvider extends DataProvider {
deleteMedia: (params: DeleteMediaParams) => Promise<DeleteMediaResult>;
purgeRemoteMedia: (params: DeleteMediaParams) => Promise<DeleteMediaResult>;
uploadMedia: (params: UploadMediaParams) => Promise<UploadMediaResult>;
updateFeatures: (id: Identifier, features: ExperimentalFeaturesModel) => Promise<void>;
getRateLimits: (id: Identifier) => Promise<RateLimitsModel>;
@@ -301,6 +313,8 @@ export interface SynapseDataProvider extends DataProvider {
makeRoomAdmin: (room_id: string, user_id: string) => Promise<{ success: boolean; error?: string; errcode?: string }>;
getServerRunningProcess: (etkeAdminUrl: string) => Promise<ServerProcessResponse>;
getServerStatus: (etkeAdminUrl: string) => Promise<ServerStatusResponse>;
getServerNotifications: (etkeAdminUrl: string) => Promise<ServerNotificationsResponse>;
deleteServerNotifications: (etkeAdminUrl: string) => Promise<{ success: boolean }>;
}
const resourceMap = {
@@ -849,6 +863,23 @@ const baseDataProvider: SynapseDataProvider = {
return json as DeleteMediaResult;
},
/**
* Purge remote media by date
*
* @link https://element-hq.github.io/synapse/latest/admin_api/media_admin_api.html#purge-remote-media-api
*
* @param before_ts Unix timestamp in milliseconds. Files that were last used before this timestamp will be deleted. It is the timestamp of last access, not the timestamp when the file was created.
* @returns
*/
purgeRemoteMedia: async ({ before_ts }) => {
const endpoint = `/_synapse/admin/v1/purge_media_cache?before_ts=${before_ts}`;
const base_url = localStorage.getItem("base_url");
const endpoint_url = base_url + endpoint;
const { json } = await jsonClient(endpoint_url, { method: "POST" });
return json as DeleteMediaResult;
},
uploadMedia: async ({ file, filename, content_type }: UploadMediaParams) => {
const base_url = localStorage.getItem("base_url");
const uploadMediaURL = `${base_url}/_matrix/media/v3/upload`;
@@ -977,6 +1008,60 @@ const baseDataProvider: SynapseDataProvider = {
}
return { success: false, ok: false, host: "", results: [] };
},
getServerNotifications: async (serverNotificationsUrl: string): Promise<ServerNotificationsResponse> => {
try {
const response = await fetch(`${serverNotificationsUrl}/notifications`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
});
if (!response.ok) {
console.error(`Error getting server notifications: ${response.status} ${response.statusText}`);
return { success: false, notifications: [] };
}
const status = response.status;
if (status === 204) {
return { success: true, notifications: [] };
}
if (status === 200) {
const json = await response.json();
const result = { success: true, notifications: json } as ServerNotificationsResponse;
return result;
}
return { success: true, notifications: [] };
} catch (error) {
console.error("Error getting server notifications", error);
}
return { success: false, notifications: [] };
},
deleteServerNotifications: async (serverNotificationsUrl: string) => {
try {
const response = await fetch(`${serverNotificationsUrl}/notifications`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
},
method: "DELETE"
});
if (!response.ok) {
console.error(`Error deleting server notifications: ${response.status} ${response.statusText}`);
return { success: false };
}
const status = response.status;
if (status === 204) {
const result = { success: true }
return result;
}
} catch (error) {
console.error("Error deleting server notifications", error);
}
return { success: false };
}
};

View File

@@ -31,23 +31,28 @@ export const FetchConfig = async () => {
console.error(e);
}
let protocol = "https";
const baseURL = localStorage.getItem("base_url");
if (baseURL && baseURL.startsWith("http://")) {
protocol = "http";
}
// if home_server is set, try to load https://home_server/.well-known/matrix/client
const homeserver = localStorage.getItem("home_server");
if (homeserver) {
try {
const resp = await fetch(`https://${homeserver}/.well-known/matrix/client`);
const configWK = await resp.json();
const resp = await fetch(`${protocol}://${homeserver}/.well-known/matrix/client`);
const configWK = await resp.json();
if (!configWK[WellKnownKey]) {
console.log(`Loaded https://${homeserver}.well-known/matrix/client, but it doesn't contain ${WellKnownKey} key, skipping`, configWK);
console.log(`Loaded ${protocol}://${homeserver}.well-known/matrix/client, but it doesn't contain ${WellKnownKey} key, skipping`, configWK);
} else {
console.log(`Loaded https://${homeserver}.well-known/matrix/client`, configWK);
console.log(`Loaded ${protocol}://${homeserver}.well-known/matrix/client`, configWK);
LoadConfig(configWK[WellKnownKey]);
}
} catch (e) {
console.log(`https://${homeserver}/.well-known/matrix/client not found, skipping`, e);
console.log(`${protocol}://${homeserver}/.well-known/matrix/client not found, skipping`, e);
}
}
}
// load config from context

View File

@@ -16,7 +16,11 @@ export const isMXID = (id: string | Identifier): boolean => mxidPattern.test(id
* @returns Whether the user is managed by an application service
*/
export const isASManaged = (id: string | Identifier): boolean => {
return GetConfig().asManagedUsers.some(regex => regex.test(id as string));
const managedUsers = GetConfig().asManagedUsers;
if (!managedUsers) {
return false;
}
return managedUsers.some(regex => regex.test(id as string));
};
/**
@@ -38,14 +42,20 @@ export function generateRandomMXID(): string {
* @returns full MXID as string
*/
export function returnMXID(input: string | Identifier): string {
const homeserver = localStorage.getItem("home_server");
const inputStr = input as string;
const homeserver = localStorage.getItem("home_server") || "";
// when homeserver is not (just) a domain name, but a domain:port or even an IPv6 address
if (homeserver != "" && inputStr.endsWith(homeserver) && inputStr.startsWith("@")) {
return inputStr; // Already a valid MXID
}
// Check if the input already looks like a valid MXID (i.e., starts with "@" and contains ":")
if (isMXID(input)) {
return input as string; // Already a valid MXID
return inputStr; // Already a valid MXID
}
// If input is not a valid MXID, assume it's a localpart and construct the MXID
const localpart = typeof input === 'string' && input.startsWith('@') ? input.slice(1) : input;
const localpart = typeof input === 'string' && inputStr.startsWith('@') ? inputStr.slice(1) : inputStr;
return `@${localpart}:${homeserver}`;
}

View File

@@ -149,7 +149,7 @@ saml2_config:
sp_config: null
user_mapping_provider:
config: null
server_name: synapse
server_name: synapse:8008
signing_key_path: /config/synapse.signing.key
spam_checker: []
sso: null

370
yarn.lock
View File

@@ -412,10 +412,10 @@
source-map "^0.5.7"
stylis "4.2.0"
"@emotion/cache@^11.11.0", "@emotion/cache@^11.13.5":
version "11.13.5"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.5.tgz#e78dad0489e1ed7572507ba8ed9d2130529e4266"
integrity sha512-Z3xbtJ+UcK76eWkagZ1onvn/wAVb1GOMuR15s30Fm2wrMgC7jzpnO2JZXr4eujTTqoQFUrZIw/rT0c6Zzjca1g==
"@emotion/cache@^11.11.0", "@emotion/cache@^11.13.5", "@emotion/cache@^11.14.0":
version "11.14.0"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76"
integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==
dependencies:
"@emotion/memoize" "^0.9.0"
"@emotion/sheet" "^1.4.0"
@@ -440,16 +440,16 @@
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz"
integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==
"@emotion/react@^11.13.5", "@emotion/react@^11.4.1":
version "11.13.5"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.13.5.tgz#fc818ff5b13424f86501ba4d0740f343ae20b8d9"
integrity sha512-6zeCUxUH+EPF1s+YF/2hPVODeV/7V07YU5x+2tfuRL8MdW6rv5vb2+CBEGTGwBdux0OIERcOS+RzxeK80k2DsQ==
"@emotion/react@^11.14.0", "@emotion/react@^11.4.1":
version "11.14.0"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.14.0.tgz#cfaae35ebc67dd9ef4ea2e9acc6cd29e157dd05d"
integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.13.5"
"@emotion/cache" "^11.13.5"
"@emotion/cache" "^11.14.0"
"@emotion/serialize" "^1.3.3"
"@emotion/use-insertion-effect-with-fallbacks" "^1.1.0"
"@emotion/use-insertion-effect-with-fallbacks" "^1.2.0"
"@emotion/utils" "^1.4.2"
"@emotion/weak-memoize" "^0.4.0"
hoist-non-react-statics "^3.3.1"
@@ -470,16 +470,16 @@
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz"
integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==
"@emotion/styled@^11.13.5", "@emotion/styled@^11.3.0":
version "11.13.5"
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.13.5.tgz#0fa6602227414c5e42cf267506e3c35bae655df9"
integrity sha512-gnOQ+nGLPvDXgIx119JqGalys64lhMdnNQA9TMxhDA4K0Hq5+++OE20Zs5GxiCV9r814xQ2K5WmtofSpHVW6BQ==
"@emotion/styled@^11.14.0", "@emotion/styled@^11.3.0":
version "11.14.0"
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.14.0.tgz#f47ca7219b1a295186d7661583376fcea95f0ff3"
integrity sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.13.5"
"@emotion/is-prop-valid" "^1.3.0"
"@emotion/serialize" "^1.3.3"
"@emotion/use-insertion-effect-with-fallbacks" "^1.1.0"
"@emotion/use-insertion-effect-with-fallbacks" "^1.2.0"
"@emotion/utils" "^1.4.2"
"@emotion/unitless@^0.10.0":
@@ -487,10 +487,10 @@
resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz"
integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==
"@emotion/use-insertion-effect-with-fallbacks@^1.1.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz"
integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==
"@emotion/use-insertion-effect-with-fallbacks@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz#8a8cb77b590e09affb960f4ff1e9a89e532738bf"
integrity sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==
"@emotion/utils@^1.4.2":
version "1.4.2"
@@ -663,10 +663,10 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@9.16.0", "@eslint/js@^9.13.0":
version "9.16.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4"
integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==
"@eslint/js@9.17.0", "@eslint/js@^9.17.0":
version "9.17.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.17.0.tgz#1523e586791f80376a6f8398a3964455ecc651ec"
integrity sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==
"@eslint/object-schema@^2.1.4":
version "2.1.4"
@@ -977,10 +977,10 @@
resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz"
integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==
"@mui/core-downloads-tracker@^6.1.10":
version "6.1.10"
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.10.tgz#871b5a4876cfd0beac6672fe50d57e0c0a53db36"
integrity sha512-LY5wdiLCBDY7u+Od8UmFINZFGN/5ZU90fhAslf/ZtfP+5RhuY45f679pqYIxe0y54l6Gkv9PFOc8Cs10LDTBYg==
"@mui/core-downloads-tracker@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.2.0.tgz#52953b858eaf3204ac505bf0329528fd3130c775"
integrity sha512-Nn5PSkUqbDrvezpiiiYZiAbX4SFEiy3CbikUL6pWOXEUsq+L1j50OOyyUIHpaX2Hr+5V5UxTh+fPeC4nsGNhdw==
"@mui/icons-material@^5.15.20":
version "5.16.7"
@@ -989,10 +989,10 @@
dependencies:
"@babel/runtime" "^7.23.9"
"@mui/icons-material@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-6.1.9.tgz#68b1003d3e29db4f5d5e5f46a4333f34762aeeeb"
integrity sha512-AzlhIT51rdjkZ/EcUV2dbhNkNSUHIqCnNoUxodpiTw8buyAUBd+qnxg5OBSuPpun/ZEdSSB8Q7Uyh6zqjiMsEQ==
"@mui/icons-material@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-6.2.0.tgz#8815b7b064234f525a174dd8bc59eb2f8986e79b"
integrity sha512-WR1EEhGOSvxAsoTSzWZBlrWFjul8wziDrII4rC3PvMBHhBYBqEc2n/0aamfFbwkH5EiYb96aqc6kYY6tB310Sw==
dependencies:
"@babel/runtime" "^7.26.0"
@@ -1014,22 +1014,22 @@
react-is "^18.3.1"
react-transition-group "^4.4.5"
"@mui/material@^6.1.10":
version "6.1.10"
resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.1.10.tgz#eab2a9df24c68548d0df2b5b25c0410311313ff9"
integrity sha512-txnwYObY4N9ugv5T2n5h1KcbISegZ6l65w1/7tpSU5OB6MQCU94YkP8n/3slDw2KcEfRk4+4D8EUGfhSPMODEQ==
"@mui/material@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.2.0.tgz#e649438c3de3d26c8e79845711572a4ae34125bb"
integrity sha512-7FXXUPIyYzP02a7GvqwJ7ocmdP+FkvLvmy/uxG1TDmTlsr8nEClQp75uxiVznJqAY/jJy4d+Rj/fNWNxwidrYQ==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/core-downloads-tracker" "^6.1.10"
"@mui/system" "^6.1.10"
"@mui/core-downloads-tracker" "^6.2.0"
"@mui/system" "^6.2.0"
"@mui/types" "^7.2.19"
"@mui/utils" "^6.1.10"
"@mui/utils" "^6.2.0"
"@popperjs/core" "^2.11.8"
"@types/react-transition-group" "^4.4.11"
clsx "^2.1.1"
csstype "^3.1.3"
prop-types "^15.8.1"
react-is "^18.3.1"
react-is "^19.0.0"
react-transition-group "^4.4.5"
"@mui/private-theming@^5.16.6":
@@ -1041,13 +1041,13 @@
"@mui/utils" "^5.16.6"
prop-types "^15.8.1"
"@mui/private-theming@^6.1.10":
version "6.1.10"
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.1.10.tgz#cfe8f70c30351208e8ca5c2b16c6992ce0288559"
integrity sha512-DqgsH0XFEweeG3rQfVkqTkeXcj/E76PGYWag8flbPdV8IYdMo+DfVdFlZK8JEjsaIVD2Eu1kJg972XnH5pfnBQ==
"@mui/private-theming@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.2.0.tgz#b94a7c5726b7337cfad1800bfd5927cf2af4b131"
integrity sha512-lYd2MrVddhentF1d/cMXKnwlDjr/shbO3A2eGq22PCYUoZaqtAGZMc0U86KnJ/Sh5YzNYePqTOaaowAN8Qea8A==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/utils" "^6.1.10"
"@mui/utils" "^6.2.0"
prop-types "^15.8.1"
"@mui/styled-engine@^5.16.6":
@@ -1060,10 +1060,10 @@
csstype "^3.1.3"
prop-types "^15.8.1"
"@mui/styled-engine@^6.1.10":
version "6.1.10"
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.1.10.tgz#0f093defd35934b6accff156011c9deac22356be"
integrity sha512-+NV9adKZYhslJ270iPjf2yzdVJwav7CIaXcMlPSi1Xy1S/zRe5xFgZ6BEoMdmGRpr34lIahE8H1acXP2myrvRw==
"@mui/styled-engine@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.2.0.tgz#f0d4450b86ee4f39906b51d1439710b754269d3f"
integrity sha512-rV4YCu6kcCjMnHFXU/tQcL6XfYVfFVR8n3ZVNGnk2rpXnt/ctOPJsF+eUQuhkHciueLVKpI06+umr1FxWWhVmQ==
dependencies:
"@babel/runtime" "^7.26.0"
"@emotion/cache" "^11.13.5"
@@ -1086,16 +1086,16 @@
csstype "^3.1.3"
prop-types "^15.8.1"
"@mui/system@^6.1.10":
version "6.1.10"
resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.1.10.tgz#d8a6f9099883880182cfafc08fc8ab8099647c01"
integrity sha512-5YNIqxETR23SIkyP7MY2fFnXmplX/M4wNi2R+10AVRd3Ub+NLctWY/Vs5vq1oAMF0eSDLhRTGUjaUe+IGSfWqg==
"@mui/system@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.2.0.tgz#1841438bc50716c7c739345756bc4cd60aa34a71"
integrity sha512-DCeqev9Cd4f4pm3O1lqSGW/DIHHBG6ZpqMX9iIAvN4asYv+pPWv2/lKov9kWk5XThhxFnGSv93SRNE1kNRRg5Q==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/private-theming" "^6.1.10"
"@mui/styled-engine" "^6.1.10"
"@mui/private-theming" "^6.2.0"
"@mui/styled-engine" "^6.2.0"
"@mui/types" "^7.2.19"
"@mui/utils" "^6.1.10"
"@mui/utils" "^6.2.0"
clsx "^2.1.1"
csstype "^3.1.3"
prop-types "^15.8.1"
@@ -1117,17 +1117,17 @@
prop-types "^15.8.1"
react-is "^18.3.1"
"@mui/utils@^6.1.10":
version "6.1.10"
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.1.10.tgz#edf8c5c9cf930a8290b5347550ece15f5800b1c3"
integrity sha512-1ETuwswGjUiAf2dP9TkBy8p49qrw2wXa+RuAjNTRE5+91vtXJ1HKrs7H9s8CZd1zDlQVzUcUAPm9lpQwF5ogTw==
"@mui/utils@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.2.0.tgz#a39f0a2837048a42114169d298ce970913097203"
integrity sha512-77CaFJi+OIi2SjbPwCis8z5DXvE0dfx9hBz5FguZHt1VYFlWEPCWTHcMsQCahSErnfik5ebLsYK8+D+nsjGVfw==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/types" "^7.2.19"
"@types/prop-types" "^15.7.13"
"@types/prop-types" "^15.7.14"
clsx "^2.1.1"
prop-types "^15.8.1"
react-is "^18.3.1"
react-is "^19.0.0"
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
@@ -1284,17 +1284,17 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
"@tanstack/query-core@5.62.3":
version "5.62.3"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.62.3.tgz#7cfde68f7d78807faebee2a2bb1e31b81067f46b"
integrity sha512-Jp/nYoz8cnO7kqhOlSv8ke/0MJRJVGuZ0P/JO9KQ+f45mpN90hrerzavyTKeSoT/pOzeoOUkv1Xd0wPsxAWXfg==
"@tanstack/query-core@5.62.7":
version "5.62.7"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.62.7.tgz#c7f6d0131c08cd2f60e73ec6e7b70e2e9e335def"
integrity sha512-fgpfmwatsrUal6V+8EC2cxZIQVl9xvL7qYa03gsdsCy985UTUlS4N+/3hCzwR0PclYDqisca2AqR1BVgJGpUDA==
"@tanstack/react-query@^5.21.7", "@tanstack/react-query@^5.62.3":
version "5.62.3"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.62.3.tgz#c6766b1764dcf924f6ed5fd88daf8d246e2f5c14"
integrity sha512-y2zDNKuhgiuMgsKkqd4AcsLIBiCfEO8U11AdrtAUihmLbRNztPrlcZqx2lH1GacZsx+y1qRRbCcJLYTtF1vKsw==
"@tanstack/react-query@^5.21.7", "@tanstack/react-query@^5.62.7":
version "5.62.7"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.62.7.tgz#8f253439a38ad6ce820bc6d42d89ca2556574d1a"
integrity sha512-+xCtP4UAFDTlRTYyEjLx0sRtWyr5GIk7TZjZwBu4YaNahi3Rt2oMyRqfpfVrtwsqY2sayP4iXVCwmC+ZqqFmuw==
dependencies:
"@tanstack/query-core" "5.62.3"
"@tanstack/query-core" "5.62.7"
"@testing-library/dom@^10.0.0":
version "10.4.0"
@@ -1461,10 +1461,10 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb"
integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==
"@types/node@*", "@types/node@^22.10.1":
version "22.10.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.1.tgz#41ffeee127b8975a05f8c4f83fb89bcb2987d766"
integrity sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==
"@types/node@*", "@types/node@^22.10.2":
version "22.10.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.2.tgz#a485426e6d1fdafc7b0d4c7b24e2c78182ddabb9"
integrity sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==
dependencies:
undici-types "~6.20.0"
@@ -1480,11 +1480,16 @@
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz"
integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==
"@types/prop-types@*", "@types/prop-types@^15.7.12", "@types/prop-types@^15.7.13":
"@types/prop-types@*", "@types/prop-types@^15.7.12":
version "15.7.13"
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz"
integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==
"@types/prop-types@^15.7.14":
version "15.7.14"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2"
integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==
"@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.11":
version "4.4.11"
resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz"
@@ -1522,62 +1527,62 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@8.17.0", "@typescript-eslint/eslint-plugin@^8.14.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz#2ee073c421f4e81e02d10e731241664b6253b23c"
integrity sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==
"@typescript-eslint/eslint-plugin@8.18.0", "@typescript-eslint/eslint-plugin@^8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.0.tgz#0901933326aea4443b81df3f740ca7dfc45c7bea"
integrity sha512-NR2yS7qUqCL7AIxdJUQf2MKKNDVNaig/dEB0GBLU7D+ZdHgK1NoH/3wsgO3OnPVipn51tG3MAwaODEGil70WEw==
dependencies:
"@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "8.17.0"
"@typescript-eslint/type-utils" "8.17.0"
"@typescript-eslint/utils" "8.17.0"
"@typescript-eslint/visitor-keys" "8.17.0"
"@typescript-eslint/scope-manager" "8.18.0"
"@typescript-eslint/type-utils" "8.18.0"
"@typescript-eslint/utils" "8.18.0"
"@typescript-eslint/visitor-keys" "8.18.0"
graphemer "^1.4.0"
ignore "^5.3.1"
natural-compare "^1.4.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/parser@8.17.0", "@typescript-eslint/parser@^8.15.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.17.0.tgz#2ee972bb12fa69ac625b85813dc8d9a5a053ff52"
integrity sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg==
"@typescript-eslint/parser@8.18.0", "@typescript-eslint/parser@^8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.18.0.tgz#a1c9456cbb6a089730bf1d3fc47946c5fb5fe67b"
integrity sha512-hgUZ3kTEpVzKaK3uNibExUYm6SKKOmTU2BOxBSvOYwtJEPdVQ70kZJpPjstlnhCHcuc2WGfSbpKlb/69ttyN5Q==
dependencies:
"@typescript-eslint/scope-manager" "8.17.0"
"@typescript-eslint/types" "8.17.0"
"@typescript-eslint/typescript-estree" "8.17.0"
"@typescript-eslint/visitor-keys" "8.17.0"
"@typescript-eslint/scope-manager" "8.18.0"
"@typescript-eslint/types" "8.18.0"
"@typescript-eslint/typescript-estree" "8.18.0"
"@typescript-eslint/visitor-keys" "8.18.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@8.17.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz#a3f49bf3d4d27ff8d6b2ea099ba465ef4dbcaa3a"
integrity sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==
"@typescript-eslint/scope-manager@8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.18.0.tgz#30b040cb4557804a7e2bcc65cf8fdb630c96546f"
integrity sha512-PNGcHop0jkK2WVYGotk/hxj+UFLhXtGPiGtiaWgVBVP1jhMoMCHlTyJA+hEj4rszoSdLTK3fN4oOatrL0Cp+Xw==
dependencies:
"@typescript-eslint/types" "8.17.0"
"@typescript-eslint/visitor-keys" "8.17.0"
"@typescript-eslint/types" "8.18.0"
"@typescript-eslint/visitor-keys" "8.18.0"
"@typescript-eslint/type-utils@8.17.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz#d326569f498cdd0edf58d5bb6030b4ad914e63d3"
integrity sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw==
"@typescript-eslint/type-utils@8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.18.0.tgz#6f0d12cf923b6fd95ae4d877708c0adaad93c471"
integrity sha512-er224jRepVAVLnMF2Q7MZJCq5CsdH2oqjP4dT7K6ij09Kyd+R21r7UVJrF0buMVdZS5QRhDzpvzAxHxabQadow==
dependencies:
"@typescript-eslint/typescript-estree" "8.17.0"
"@typescript-eslint/utils" "8.17.0"
"@typescript-eslint/typescript-estree" "8.18.0"
"@typescript-eslint/utils" "8.18.0"
debug "^4.3.4"
ts-api-utils "^1.3.0"
"@typescript-eslint/types@8.17.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.17.0.tgz#ef84c709ef8324e766878834970bea9a7e3b72cf"
integrity sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==
"@typescript-eslint/types@8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.18.0.tgz#3afcd30def8756bc78541268ea819a043221d5f3"
integrity sha512-FNYxgyTCAnFwTrzpBGq+zrnoTO4x0c1CKYY5MuUTzpScqmY5fmsh2o3+57lqdI3NZucBDCzDgdEbIaNfAjAHQA==
"@typescript-eslint/typescript-estree@8.17.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz#40b5903bc929b1e8dd9c77db3cb52cfb199a2a34"
integrity sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==
"@typescript-eslint/typescript-estree@8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.0.tgz#d8ca785799fbb9c700cdff1a79c046c3e633c7f9"
integrity sha512-rqQgFRu6yPkauz+ms3nQpohwejS8bvgbPyIDq13cgEDbkXt4LH4OkDMT0/fN1RUtzG8e8AKJyDBoocuQh8qNeg==
dependencies:
"@typescript-eslint/types" "8.17.0"
"@typescript-eslint/visitor-keys" "8.17.0"
"@typescript-eslint/types" "8.18.0"
"@typescript-eslint/visitor-keys" "8.18.0"
debug "^4.3.4"
fast-glob "^3.3.2"
is-glob "^4.0.3"
@@ -1585,22 +1590,22 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/utils@8.17.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.17.0.tgz#41c05105a2b6ab7592f513d2eeb2c2c0236d8908"
integrity sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==
"@typescript-eslint/utils@8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.18.0.tgz#48f67205d42b65d895797bb7349d1be5c39a62f7"
integrity sha512-p6GLdY383i7h5b0Qrfbix3Vc3+J2k6QWw6UMUeY5JGfm3C5LbZ4QIZzJNoNOfgyRe0uuYKjvVOsO/jD4SJO+xg==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
"@typescript-eslint/scope-manager" "8.17.0"
"@typescript-eslint/types" "8.17.0"
"@typescript-eslint/typescript-estree" "8.17.0"
"@typescript-eslint/scope-manager" "8.18.0"
"@typescript-eslint/types" "8.18.0"
"@typescript-eslint/typescript-estree" "8.18.0"
"@typescript-eslint/visitor-keys@8.17.0":
version "8.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz#4dbcd0e28b9bf951f4293805bf34f98df45e1aa8"
integrity sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==
"@typescript-eslint/visitor-keys@8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.0.tgz#7b6d33534fa808e33a19951907231ad2ea5c36dd"
integrity sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==
dependencies:
"@typescript-eslint/types" "8.17.0"
"@typescript-eslint/types" "8.18.0"
eslint-visitor-keys "^4.2.0"
"@vitejs/plugin-react@^4.3.4":
@@ -2193,10 +2198,10 @@ cross-fetch@^3.0.4:
dependencies:
node-fetch "^2.6.12"
cross-spawn@^7.0.3, cross-spawn@^7.0.5:
version "7.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82"
integrity sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==
cross-spawn@^7.0.3, cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
@@ -2761,17 +2766,17 @@ eslint-visitor-keys@^4.2.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint@^9.16.0:
version "9.16.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6"
integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==
eslint@^9.17.0:
version "9.17.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.17.0.tgz#faa1facb5dd042172fdc520106984b5c2421bb0c"
integrity sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.12.1"
"@eslint/config-array" "^0.19.0"
"@eslint/core" "^0.9.0"
"@eslint/eslintrc" "^3.2.0"
"@eslint/js" "9.16.0"
"@eslint/js" "9.17.0"
"@eslint/plugin-kit" "^0.2.3"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
@@ -2780,7 +2785,7 @@ eslint@^9.16.0:
"@types/json-schema" "^7.0.15"
ajv "^6.12.4"
chalk "^4.0.0"
cross-spawn "^7.0.5"
cross-spawn "^7.0.6"
debug "^4.3.2"
escape-string-regexp "^4.0.0"
eslint-scope "^8.2.0"
@@ -4253,9 +4258,9 @@ nano-time@1.0.0:
big-integer "^1.6.16"
nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
version "3.3.8"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
natural-compare@^1.4.0:
version "1.4.0"
@@ -4634,10 +4639,10 @@ ra-core@^4.11.2, ra-core@^4.16.2:
react-is "^17.0.2"
react-query "^3.32.1"
ra-core@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ra-core/-/ra-core-5.4.1.tgz#f387826789f74ab656068c571523a46b4c07f286"
integrity sha512-jn1kU3Yn6OMLZFi0Ym3hsNnOo6+qJRp9En61t7MccfY+ultVx2FBWi+EZRoV1+hlVZmO7OcpKJ2dM7Sb5csx1w==
ra-core@^5.4.1, ra-core@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/ra-core/-/ra-core-5.4.2.tgz#8b65bf3c6abddc6b8025d754b8ce00c2392b6979"
integrity sha512-HxfxhUVl0U6rjobb50wiv3IblnRDQPqHXXv3WNZaUK2/bAZ5qX8qfSHe96quhrzSXbv5FHS4G3aPRxANXWVauQ==
dependencies:
"@tanstack/react-query" "^5.21.7"
clsx "^2.1.1"
@@ -4650,32 +4655,32 @@ ra-core@^5.4.1:
react-error-boundary "^4.0.13"
react-is "^18.2.0"
ra-i18n-polyglot@^5.3.4, ra-i18n-polyglot@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ra-i18n-polyglot/-/ra-i18n-polyglot-5.4.1.tgz#b1562b3aa6bec2f84c663ab09cfa5af5c3ee9f81"
integrity sha512-2UIFk7yUbicCU1dpo8bdWSeAMKffjg82JaDRuoUU/eo0LkXGz0VrmFqhC4OQQ1CSMrFx+NuhD/7vFbRFOPzcww==
ra-i18n-polyglot@^5.3.4, ra-i18n-polyglot@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/ra-i18n-polyglot/-/ra-i18n-polyglot-5.4.2.tgz#918dc09cce71e51fa002dc290e291fbb83a81e73"
integrity sha512-twBYo++iTCejdJBpROgl6uQKOwv5hyv/df3w/vWrYudpdjbudGTpj/B8Q5Rfax4op6K8dGCtOkBdNbK0XM/T9A==
dependencies:
node-polyglot "^2.2.2"
ra-core "^5.4.1"
ra-core "^5.4.2"
ra-language-english@^5.3.4, ra-language-english@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ra-language-english/-/ra-language-english-5.4.1.tgz#352d90be7987db0a3bd8ce79c52eae4da4783b74"
integrity sha512-coeh3CgGNYfAVngXBaa+euIAqIr1xSGC5ZnaOjehMfeA763BdoNUE7PJ25ExrBmuXhIBOuXuUW5y+q0/DNp/yw==
ra-language-english@^5.3.4, ra-language-english@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/ra-language-english/-/ra-language-english-5.4.2.tgz#f44b617a54040b8dc8e42f79d7a5f84c7b59dcb6"
integrity sha512-gQ6lRFRDzvuhPwq9+CXiJD6bF1Fjyuuk+PS/hUeQ7bxx4N0vJXK7Pe+GNLKEq+XD9rw9mFyU/0tOX/Pa9xy9iQ==
dependencies:
ra-core "^5.4.1"
ra-core "^5.4.2"
ra-language-farsi@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/ra-language-farsi/-/ra-language-farsi-5.1.0.tgz#27d2cc50e4074a0e2565e05da153da0d213729f8"
integrity sha512-U4swqsijT6foRP9v/fqLGEXV1TjuyjpQcmoDJfsN2kPyR9QiKlLGNrbv/sfpt7LT0om3egIXIRp/iQG1u44GXQ==
ra-language-french@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ra-language-french/-/ra-language-french-5.4.1.tgz#34368e87f2d6418b6f32e62cc65d2a8c6777f936"
integrity sha512-HEalm5lO8p0hrxU38LDK63IPtF8rKnKISjep3RG1kpWsjjbrVJLoSt78RBjdpwuQ/Xd8sBDB9BVJjQ/pTekuhw==
ra-language-french@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/ra-language-french/-/ra-language-french-5.4.2.tgz#d156118bd70663671c9da2479313ad5bccd2b80d"
integrity sha512-STivmtbd4vY55axKzzJ6/bDOh6dM7W6lEx3B1YX4W6dN1+m2oLnqU8Iye66l9A0q96Ax2OYis0c2a+xbojfCOA==
dependencies:
ra-core "^5.4.1"
ra-core "^5.4.2"
ra-language-italian@^3.13.1:
version "3.13.1"
@@ -4689,10 +4694,10 @@ ra-language-russian@^4.14.2:
dependencies:
ra-core "^4.16.2"
ra-ui-materialui@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ra-ui-materialui/-/ra-ui-materialui-5.4.1.tgz#25d52cd4feaab76103489dbbda832550509f9463"
integrity sha512-d1v9k/6+1HAQiKe0BN3kusD4SbpY9GLMwDbilmidcHCiqzpzvJiVdWgBtxTwd7oz2rBIQFHW34Pehzw7NlEoCQ==
ra-ui-materialui@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/ra-ui-materialui/-/ra-ui-materialui-5.4.2.tgz#d4efa73ce9dd27bb72a4d2ab60ca006e33eb62a7"
integrity sha512-bVR86VpjwMEVUcJptungxFeBra+27K6ERflabTxSzcRi3T2BOTwFF8dt4KGJ2/o7ejAHRKyjAWJLMOvT3gXQRA==
dependencies:
"@tanstack/react-query" "^5.21.7"
autosuggest-highlight "^3.1.1"
@@ -4707,19 +4712,19 @@ ra-ui-materialui@^5.4.1:
react-error-boundary "^4.0.13"
react-transition-group "^4.4.5"
react-admin@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/react-admin/-/react-admin-5.4.1.tgz#03b9c45066aad0ea4f324b4c550687e2a450eeb9"
integrity sha512-ksQrCJHpIeTgE5NaABTVQh6hDqcZ1rPBRN+9gjG3oJqJGLisoYnUhKQc7stREnai2rxuT+vWufZg291kOOFUmQ==
react-admin@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/react-admin/-/react-admin-5.4.2.tgz#e721d1537d33c36661c281f82245eb9d50126d1f"
integrity sha512-zww+s8B8g44feQfib4zV8qU4KfH968KloKuJ75knLifGlHVxlryzwJLdnIA1v5AQN/DCK1kQUSpo8LBiYau4mg==
dependencies:
"@emotion/react" "^11.4.1"
"@emotion/styled" "^11.3.0"
"@mui/icons-material" "^5.15.20"
"@mui/material" "^5.15.20"
ra-core "^5.4.1"
ra-i18n-polyglot "^5.4.1"
ra-language-english "^5.4.1"
ra-ui-materialui "^5.4.1"
ra-core "^5.4.2"
ra-i18n-polyglot "^5.4.2"
ra-language-english "^5.4.2"
ra-ui-materialui "^5.4.2"
react-hook-form "^7.53.0"
react-router "^6.22.0"
react-router-dom "^6.22.0"
@@ -4748,10 +4753,10 @@ react-error-boundary@^4.0.13:
dependencies:
"@babel/runtime" "^7.12.5"
react-hook-form@^7.53.0, react-hook-form@^7.54.0:
version "7.54.0"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.54.0.tgz#46bd9142d65fd16ac064a2bbf4dc0333e2d6840d"
integrity sha512-PS05+UQy/IdSbJNojBypxAo9wllhHgGmyr8/dyGQcPoiMf3e7Dfb9PWYVRco55bLbxH9S+1yDDJeTdlYCSxO3A==
react-hook-form@^7.53.0, react-hook-form@^7.54.1:
version "7.54.1"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.54.1.tgz#e99c2a55a5e4859fb47a8f55adf66b34d6ac331d"
integrity sha512-PUNzFwQeQ5oHiiTUO7GO/EJXGEtuun2Y1A59rLnZBBj+vNEOWt/3ERTiG1/zt7dVeJEM+4vDX/7XQ/qanuvPMg==
"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0, react-is@^18.3.1:
version "18.3.1"
@@ -4768,6 +4773,11 @@ react-is@^17.0.1, react-is@^17.0.2:
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-is@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.0.0.tgz#d6669fd389ff022a9684f708cf6fa4962d1fea7a"
integrity sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==
react-query@^3.32.1:
version "3.39.3"
resolved "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz"
@@ -5424,14 +5434,14 @@ typed-array-length@^1.0.6:
is-typed-array "^1.1.13"
possible-typed-array-names "^1.0.0"
typescript-eslint@^8.17.0:
version "8.17.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.17.0.tgz#fa4033c26b3b40f778287bc12918d985481b220b"
integrity sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA==
typescript-eslint@^8.18.0:
version "8.18.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.18.0.tgz#41026f27a3481185f3239d817ae5b960572145a0"
integrity sha512-Xq2rRjn6tzVpAyHr3+nmSg1/9k9aIHnJ2iZeOH7cfGOWqTkXTm3kwpQglEuLGdNrYvPF+2gtAs+/KF5rjVo+WQ==
dependencies:
"@typescript-eslint/eslint-plugin" "8.17.0"
"@typescript-eslint/parser" "8.17.0"
"@typescript-eslint/utils" "8.17.0"
"@typescript-eslint/eslint-plugin" "8.18.0"
"@typescript-eslint/parser" "8.18.0"
"@typescript-eslint/utils" "8.18.0"
typescript@^5.7.2:
version "5.7.2"