Add accessibility settings where you can disable keyboard shortcuts (#2157)

An accessibility requirement dictates that our custom shortcut system must be allowed to be disabled. A new accessibility settings page has been added to the user profile, similar to the theme settings. It is persisted in local storage.

Co-authored-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
Konstantin Schaper
2022-11-16 16:50:17 +01:00
committed by GitHub
parent 4a556dda8b
commit 19938b3af8
34 changed files with 293 additions and 197 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -47,3 +47,9 @@ Diese können global oder repository-spezifisch sein oder in einem komplett ande
Sie werden automatisch in der Übersicht im SCM-Manager mit aufgelistet. Sie werden automatisch in der Übersicht im SCM-Manager mit aufgelistet.
Um die Tastenkürzel eines Plugins innerhalb der Benutzerdokumentation zu finden, verweisen wir hier auf die Um die Tastenkürzel eines Plugins innerhalb der Benutzerdokumentation zu finden, verweisen wir hier auf die
Dokumentation des jeweiligen Plugins. Dokumentation des jeweiligen Plugins.
### Barrierefreiheit
Das oben beschriebene System kann in den Profileinstellungen unter "Barrierefreiheit" deaktiviert werden.
![Einstellungen der Barrierefreiheit](assets/accessibility_settings.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -45,3 +45,9 @@ Plugins can introduce new shortcuts.
They may be global, repository-specific or connected to an entirely different context. They may be global, repository-specific or connected to an entirely different context.
They will automatically be included in the summary generated within the SCM-Manager. They will automatically be included in the summary generated within the SCM-Manager.
To find the shortcuts outside the SCM-Manager, please refer to the documentation of the plugin. To find the shortcuts outside the SCM-Manager, please refer to the documentation of the plugin.
### Accessibility
The system described above can be disabled in the profile settings under "Accessibility".
![Accessibility Settings](assets/accessibility_settings.png)

View File

@@ -0,0 +1,2 @@
- type: added
description: Accessibility settings where you can disable keyboard shortcuts ([#2157](https://github.com/scm-manager/scm-manager/pull/2157))

View File

@@ -15,7 +15,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/plugin-scripts": "^1.2.2", "@scm-manager/plugin-scripts": "^1.2.2",
"@scm-manager/prettier-config": "^2.11.1", "@scm-manager/prettier-config": "^2.11.1",

View File

@@ -14,7 +14,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/plugin-scripts": "^1.2.2", "@scm-manager/plugin-scripts": "^1.2.2",
"@scm-manager/prettier-config": "^2.11.1", "@scm-manager/prettier-config": "^2.11.1",

View File

@@ -14,7 +14,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/plugin-scripts": "^1.2.2", "@scm-manager/plugin-scripts": "^1.2.2",
"@scm-manager/prettier-config": "^2.11.1", "@scm-manager/prettier-config": "^2.11.1",

View File

@@ -14,7 +14,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/plugin-scripts": "^1.2.2", "@scm-manager/plugin-scripts": "^1.2.2",
"@scm-manager/prettier-config": "^2.11.1", "@scm-manager/prettier-config": "^2.11.1",

View File

@@ -17,7 +17,7 @@
"fluent-ffmpeg": "^2.1.2" "fluent-ffmpeg": "^2.1.2"
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/eslint-config": "^2.16.0" "@scm-manager/eslint-config": "^2.17.0"
}, },
"prettier": "@scm-manager/prettier-config", "prettier": "@scm-manager/prettier-config",
"eslintConfig": { "eslintConfig": {

View File

@@ -19,7 +19,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/tsconfig": "^2.13.0", "@scm-manager/tsconfig": "^2.13.0",

View File

@@ -28,7 +28,7 @@
"devDependencies": { "devDependencies": {
"@scm-manager/prettier-config": "^2.11.1", "@scm-manager/prettier-config": "^2.11.1",
"@scm-manager/ui-api": "2.39.2-SNAPSHOT", "@scm-manager/ui-api": "2.39.2-SNAPSHOT",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@babel/core": "^7.17.8", "@babel/core": "^7.17.8",
"@scm-manager/tsconfig": "^2.12.0", "@scm-manager/tsconfig": "^2.12.0",
"@storybook/addon-essentials": "^6.4.20", "@storybook/addon-essentials": "^6.4.20",

View File

@@ -24,7 +24,7 @@
"@scm-manager/ui-shortcuts": "2.39.2-SNAPSHOT", "@scm-manager/ui-shortcuts": "2.39.2-SNAPSHOT",
"@scm-manager/ui-text": "2.39.2-SNAPSHOT", "@scm-manager/ui-text": "2.39.2-SNAPSHOT",
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/tsconfig": "^2.13.0", "@scm-manager/tsconfig": "^2.13.0",

View File

@@ -1619,6 +1619,16 @@ exports[`Storyshots Footer Default 1`] = `
footer.user.theme footer.user.theme
</a> </a>
</li> </li>
<li>
<a
className=""
data-testid="footer-user-accessibility"
href="/me/settings/accessibility"
onClick={[Function]}
>
footer.user.accessibility
</a>
</li>
</ul> </ul>
</section> </section>
<section <section
@@ -1776,6 +1786,16 @@ exports[`Storyshots Footer Full 1`] = `
footer.user.theme footer.user.theme
</a> </a>
</li> </li>
<li>
<a
className=""
data-testid="footer-user-accessibility"
href="/me/settings/accessibility"
onClick={[Function]}
>
footer.user.accessibility
</a>
</li>
<li> <li>
<a <a
className="" className=""
@@ -1972,6 +1992,16 @@ exports[`Storyshots Footer With Avatar 1`] = `
footer.user.theme footer.user.theme
</a> </a>
</li> </li>
<li>
<a
className=""
data-testid="footer-user-accessibility"
href="/me/settings/accessibility"
onClick={[Function]}
>
footer.user.accessibility
</a>
</li>
</ul> </ul>
</section> </section>
<section <section
@@ -2121,6 +2151,16 @@ exports[`Storyshots Footer With Plugin Links 1`] = `
footer.user.theme footer.user.theme
</a> </a>
</li> </li>
<li>
<a
className=""
data-testid="footer-user-accessibility"
href="/me/settings/accessibility"
onClick={[Function]}
>
footer.user.accessibility
</a>
</li>
<li> <li>
<a <a
className="" className=""

View File

@@ -101,6 +101,11 @@ const Footer: FC<Props> = ({ me, version, links }) => {
<FooterSection title={meSectionTile}> <FooterSection title={meSectionTile}>
<NavLink to="/me" label={t("footer.user.profile")} testId="footer-user-profile" /> <NavLink to="/me" label={t("footer.user.profile")} testId="footer-user-profile" />
<NavLink to="/me/settings/theme" label={t("footer.user.theme")} testId="footer-user-theme" /> <NavLink to="/me/settings/theme" label={t("footer.user.theme")} testId="footer-user-theme" />
<NavLink
to="/me/settings/accessibility"
label={t("footer.user.accessibility")}
testId="footer-user-accessibility"
/>
{me?._links?.password && ( {me?._links?.password && (
<NavLink to="/me/settings/password" label={t("profile.changePasswordNavLink")} /> <NavLink to="/me/settings/password" label={t("profile.changePasswordNavLink")} />
)} )}

View File

@@ -22,7 +22,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/tsconfig": "^2.13.0", "@scm-manager/tsconfig": "^2.13.0",

View File

@@ -21,7 +21,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@types/react": "^17.0.1", "@types/react": "^17.0.1",

View File

@@ -18,7 +18,7 @@
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"tsup": "^5.12.6" "tsup": "^5.12.6"
}, },
"babel": { "babel": {

View File

@@ -21,7 +21,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/plugin-scripts": "^1.2.2", "@scm-manager/plugin-scripts": "^1.2.2",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",

View File

@@ -31,7 +31,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"webpack-bundle-analyzer": "^4.5.0" "webpack-bundle-analyzer": "^4.5.0"
}, },

View File

@@ -27,7 +27,7 @@
"@types/mousetrap": "1.6.5", "@types/mousetrap": "1.6.5",
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/tsconfig": "^2.13.0", "@scm-manager/tsconfig": "^2.13.0",
"@testing-library/react-hooks": "8.0.1", "@testing-library/react-hooks": "8.0.1",
"@testing-library/react": "12.1.5", "@testing-library/react": "12.1.5",

View File

@@ -15,7 +15,7 @@
"react-diff-view": "^2.4.10" "react-diff-view": "^2.4.10"
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/prettier-config": "^2.11.1", "@scm-manager/prettier-config": "^2.11.1",
"css-loader": "^6.5.0", "css-loader": "^6.5.0",
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",

View File

@@ -24,7 +24,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/tsconfig": "^2.13.0", "@scm-manager/tsconfig": "^2.13.0",

View File

@@ -23,7 +23,7 @@
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/babel-preset": "^2.13.1", "@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1", "@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/tsconfig": "^2.13.0", "@scm-manager/tsconfig": "^2.13.0",

View File

@@ -15,7 +15,7 @@
"lint": "eslint src" "lint": "eslint src"
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/tsconfig": "^2.13.0" "@scm-manager/tsconfig": "^2.13.0"
}, },
"babel": { "babel": {

View File

@@ -37,7 +37,7 @@
"build": "webpack-cli --mode=production --config=../ui-scripts/src/webpack.config.js" "build": "webpack-cli --mode=production --config=../ui-scripts/src/webpack.config.js"
}, },
"devDependencies": { "devDependencies": {
"@scm-manager/eslint-config": "^2.16.0", "@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/jest-preset": "^2.13.0", "@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/ui-tests": "2.39.2-SNAPSHOT", "@scm-manager/ui-tests": "2.39.2-SNAPSHOT",
"@testing-library/react": "^12.1.5", "@testing-library/react": "^12.1.5",

View File

@@ -116,6 +116,15 @@
"displayName": "Systemstandard", "displayName": "Systemstandard",
"description": "Verwendet die Standardeinstellung des Systems" "description": "Verwendet die Standardeinstellung des Systems"
} }
},
"accessibility": {
"navLink": "Barrierefreiheit",
"subtitle": "Barrierefreiheit",
"deactivateShortcuts": {
"label": "Tastaturkürzel deaktivieren",
"helpText": "Deaktiviert alle speziellen Tastaturkombinationen, welche die Barrierefreiheit beeinträchtigen könnten."
},
"submit": "Speichern"
} }
}, },
"password": { "password": {
@@ -133,7 +142,8 @@
"footer": { "footer": {
"user": { "user": {
"profile": "Profil", "profile": "Profil",
"theme": "Design" "theme": "Design",
"accessibility": "Barrierefreiheit"
}, },
"information": { "information": {
"title": "Information" "title": "Information"

View File

@@ -117,6 +117,15 @@
"displayName": "System default", "displayName": "System default",
"description": "Use the default setting of the system" "description": "Use the default setting of the system"
} }
},
"accessibility": {
"navLink": "Accessibility",
"subtitle": "Accessibility",
"deactivateShortcuts": {
"label": "Deactivate Shortcuts",
"helpText": "Disable all custom shortcuts which could negatively impact accessibility."
},
"submit": "Submit"
} }
}, },
"password": { "password": {
@@ -134,7 +143,8 @@
"footer": { "footer": {
"user": { "user": {
"profile": "Profile", "profile": "Profile",
"theme": "Theme" "theme": "Theme",
"accessibility": "Accessibility"
}, },
"information": { "information": {
"title": "Information" "title": "Information"

View File

@@ -0,0 +1,46 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import useLocalStorage from "./useLocalStorage";
import { useCallback, useState } from "react";
const LOCAL_STORAGE_KEY = "scm.accessibility";
export type AccessibilityConfig = {
deactivateShortcuts: boolean;
};
export const useAccessibilityConfig = () => {
const [value, updateConfig] = useLocalStorage<AccessibilityConfig>(LOCAL_STORAGE_KEY, { deactivateShortcuts: false });
const [isLoading, setLoading] = useState(false);
const setValue = useCallback(
(newConfig: AccessibilityConfig) => {
setLoading(true);
updateConfig(newConfig);
window.location.reload();
},
[updateConfig]
);
return { value, setValue, isLoading } as const;
};

View File

@@ -0,0 +1,60 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { FC } from "react";
import { ButtonGroup, Checkbox, SubmitButton, Subtitle } from "@scm-manager/ui-components";
import { useTranslation } from "react-i18next";
import { useForm } from "react-hook-form";
import { AccessibilityConfig, useAccessibilityConfig } from "../accessibilityConfig";
const Accessibility: FC = () => {
const [t] = useTranslation("commons");
const { value: accessibilityConfig, setValue: setAccessibilityConfig, isLoading } = useAccessibilityConfig();
const {
register,
handleSubmit,
formState: { isDirty },
} = useForm<AccessibilityConfig>({
mode: "onChange",
defaultValues: accessibilityConfig,
});
return (
<>
<Subtitle>{t("profile.accessibility.subtitle")}</Subtitle>
<form onSubmit={handleSubmit(setAccessibilityConfig)}>
<Checkbox
label={t("profile.accessibility.deactivateShortcuts.label")}
helpText={t("profile.accessibility.deactivateShortcuts.helpText")}
{...register("deactivateShortcuts")}
/>
<ButtonGroup className="is-justify-content-flex-end">
<SubmitButton label={t("profile.accessibility.submit")} disabled={!isDirty} loading={isLoading} />
</ButtonGroup>
</form>
</>
);
};
export default Accessibility;

View File

@@ -34,7 +34,7 @@ import {
SecondaryNavigationColumn, SecondaryNavigationColumn,
StateMenuContextProvider, StateMenuContextProvider,
SubNavigation, SubNavigation,
urls urls,
} from "@scm-manager/ui-components"; } from "@scm-manager/ui-components";
import ChangeUserPassword from "./ChangeUserPassword"; import ChangeUserPassword from "./ChangeUserPassword";
import ProfileInfo from "./ProfileInfo"; import ProfileInfo from "./ProfileInfo";
@@ -45,6 +45,7 @@ import SetApiKeys from "../users/components/apiKeys/SetApiKeys";
import SetApiKeysNavLink from "../users/components/navLinks/SetApiKeysNavLink"; import SetApiKeysNavLink from "../users/components/navLinks/SetApiKeysNavLink";
import { useRequiredMe } from "@scm-manager/ui-api"; import { useRequiredMe } from "@scm-manager/ui-api";
import Theme from "./Theme"; import Theme from "./Theme";
import Accessibility from "./Accessibility";
const Profile: FC = () => { const Profile: FC = () => {
const match = useRouteMatch(); const match = useRouteMatch();
@@ -63,7 +64,7 @@ const Profile: FC = () => {
subtitle={t("profile.error-subtitle")} subtitle={t("profile.error-subtitle")}
error={{ error={{
name: t("profile.error"), name: t("profile.error"),
message: t("profile.error-message") message: t("profile.error-message"),
}} }}
/> />
); );
@@ -71,7 +72,7 @@ const Profile: FC = () => {
const extensionProps = { const extensionProps = {
me, me,
url url,
}; };
return ( return (
@@ -85,6 +86,9 @@ const Profile: FC = () => {
<Route path={`${url}/settings/theme`} exact> <Route path={`${url}/settings/theme`} exact>
<Theme /> <Theme />
</Route> </Route>
<Route path={`${url}/settings/accessibility`} exact>
<Accessibility />
</Route>
{mayChangePassword && ( {mayChangePassword && (
<Route path={`${url}/settings/password`}> <Route path={`${url}/settings/password`}>
<ChangeUserPassword me={me} /> <ChangeUserPassword me={me} />
@@ -120,6 +124,7 @@ const Profile: FC = () => {
title={t("profile.settingsNavLink")} title={t("profile.settingsNavLink")}
> >
<NavLink to={`${url}/settings/theme`} label={t("profile.theme.navLink")} /> <NavLink to={`${url}/settings/theme`} label={t("profile.theme.navLink")} />
<NavLink to={`${url}/settings/accessibility`} label={t("profile.accessibility.navLink")} />
{mayChangePassword && ( {mayChangePassword && (
<NavLink to={`${url}/settings/password`} label={t("profile.changePasswordNavLink")} /> <NavLink to={`${url}/settings/password`} label={t("profile.changePasswordNavLink")} />
)} )}

View File

@@ -24,6 +24,7 @@
import { useActiveModals } from "@scm-manager/ui-components"; import { useActiveModals } from "@scm-manager/ui-components";
import { usePauseShortcuts } from "@scm-manager/ui-shortcuts"; import { usePauseShortcuts } from "@scm-manager/ui-shortcuts";
import { useAccessibilityConfig } from "../accessibilityConfig";
/** /**
* Keyboard shortcuts are not active in modals using {@link useActiveModals} to determine whether any modals are open. * Keyboard shortcuts are not active in modals using {@link useActiveModals} to determine whether any modals are open.
@@ -32,5 +33,8 @@ import { usePauseShortcuts } from "@scm-manager/ui-shortcuts";
*/ */
export default function usePauseShortcutsWhenModalsActive() { export default function usePauseShortcutsWhenModalsActive() {
const areModalsActive = useActiveModals(); const areModalsActive = useActiveModals();
usePauseShortcuts(areModalsActive); const {
value: { deactivateShortcuts },
} = useAccessibilityConfig();
usePauseShortcuts(deactivateShortcuts || areModalsActive);
} }

View File

@@ -0,0 +1,45 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import { useEffect, useState } from "react";
export default function useLocalStorage<T>(
key: string,
initialValue: T
): [value: T, setValue: (value: T | ((previousConfig: T) => T)) => void] {
const [value, setValue] = useState<T>(() => {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
return initialValue;
}
});
useEffect(() => localStorage.setItem(key, JSON.stringify(value)), [key, value]);
return [value, setValue];
}

169
yarn.lock
View File

@@ -2242,7 +2242,7 @@
"@babel/preset-typescript" "^7.16.7" "@babel/preset-typescript" "^7.16.7"
babel-plugin-styled-components "^1.13.3" babel-plugin-styled-components "^1.13.3"
"@scm-manager/eslint-config@2.17.0": "@scm-manager/eslint-config@2.17.0", "@scm-manager/eslint-config@^2.17.0":
version "2.17.0" version "2.17.0"
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-2.17.0.tgz#b29b65f131a520cb47b5355d16fac99beb1ca881" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-2.17.0.tgz#b29b65f131a520cb47b5355d16fac99beb1ca881"
integrity sha512-wbYI6g09NNhpyHSjRwStB7P0xRE6WxC30HZzmNpTN+2aqI0UZidkybCzTKMjAwW587uitg0z1g/cbntyXwYQFw== integrity sha512-wbYI6g09NNhpyHSjRwStB7P0xRE6WxC30HZzmNpTN+2aqI0UZidkybCzTKMjAwW587uitg0z1g/cbntyXwYQFw==
@@ -2262,27 +2262,6 @@
eslint-plugin-react-hooks "^2.1.2" eslint-plugin-react-hooks "^2.1.2"
jest "^26.6.3" jest "^26.6.3"
"@scm-manager/eslint-config@^2.16.0":
version "2.16.0"
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-2.16.0.tgz#fe682a1e1d53355c13fff8bffd9b44505e734a63"
integrity sha512-x1o+2RKnTOkuEfNz6zAir6lAaapBWtwy7PLMrs+d7i5kEfE9gJwNOYZqORxBdGZ3u3r6w/PJCc+LNEmOHdwxUA==
dependencies:
"@typescript-eslint/eslint-plugin" "^5.19.0"
"@typescript-eslint/parser" "^5.19.0"
babel-eslint "^10.0.3"
eslint "^7.32.0"
eslint-config-airbnb-base "^14.2.0"
eslint-config-prettier "^6.4.0"
eslint-config-react-app "^5.0.2"
eslint-plugin-flowtype "^4.3.0"
eslint-plugin-import "^2.18.2"
eslint-plugin-jsx-a11y "^6.2.3"
eslint-plugin-prettier "^3.1.1"
eslint-plugin-react "^7.16.0"
eslint-plugin-react-hooks "^2.1.2"
eslint-plugin-tailwindcss "^3.6.0"
jest "^26.6.3"
"@scm-manager/integration-test-runner@^3.3.0": "@scm-manager/integration-test-runner@^3.3.0":
version "3.4.1" version "3.4.1"
resolved "https://registry.yarnpkg.com/@scm-manager/integration-test-runner/-/integration-test-runner-3.4.1.tgz#6b7745cda03b44456e1e7e6e15762748406e1503" resolved "https://registry.yarnpkg.com/@scm-manager/integration-test-runner/-/integration-test-runner-3.4.1.tgz#6b7745cda03b44456e1e7e6e15762748406e1503"
@@ -4764,21 +4743,12 @@ acorn-jsx@^5.3.1:
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn-node@^1.8.2:
version "1.8.2"
resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8"
integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==
dependencies:
acorn "^7.0.0"
acorn-walk "^7.0.0"
xtend "^4.0.2"
acorn-walk@^6.0.1: acorn-walk@^6.0.1:
version "6.2.0" version "6.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
acorn-walk@^7.0.0, acorn-walk@^7.1.1, acorn-walk@^7.2.0: acorn-walk@^7.1.1, acorn-walk@^7.2.0:
version "7.2.0" version "7.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
@@ -4798,7 +4768,7 @@ acorn@^6.0.1, acorn@^6.4.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1:
version "7.4.1" version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
@@ -5034,11 +5004,6 @@ are-we-there-yet@^2.0.0:
delegates "^1.0.0" delegates "^1.0.0"
readable-stream "^3.6.0" readable-stream "^3.6.0"
arg@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
argparse@^1.0.7: argparse@^1.0.7:
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@@ -6190,7 +6155,7 @@ camel-case@^4.1.1, camel-case@^4.1.2:
pascal-case "^3.1.2" pascal-case "^3.1.2"
tslib "^2.0.3" tslib "^2.0.3"
camelcase-css@2.0.1, camelcase-css@^2.0.1: camelcase-css@2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
@@ -6682,7 +6647,7 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@^1.1.4, color-name@~1.1.4: color-name@~1.1.4:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
@@ -7579,11 +7544,6 @@ define-property@^2.0.2:
is-descriptor "^1.0.2" is-descriptor "^1.0.2"
isobject "^3.0.1" isobject "^3.0.1"
defined@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
integrity sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==
delayed-stream@~1.0.0: delayed-stream@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -7703,25 +7663,11 @@ detect-port@^1.3.0:
address "^1.0.1" address "^1.0.1"
debug "^2.6.0" debug "^2.6.0"
detective@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034"
integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==
dependencies:
acorn-node "^1.8.2"
defined "^1.0.0"
minimist "^1.2.6"
devtools-protocol@0.0.1019158: devtools-protocol@0.0.1019158:
version "0.0.1019158" version "0.0.1019158"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1019158.tgz#4b08d06108a784a2134313149626ba55f030a86f" resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1019158.tgz#4b08d06108a784a2134313149626ba55f030a86f"
integrity sha512-wvq+KscQ7/6spEV7czhnZc9RM/woz1AY+/Vpd8/h2HFMwJSdTliu7f/yr1A6vDdJfKICZsShqsYpEQbdhg8AFQ== integrity sha512-wvq+KscQ7/6spEV7czhnZc9RM/woz1AY+/Vpd8/h2HFMwJSdTliu7f/yr1A6vDdJfKICZsShqsYpEQbdhg8AFQ==
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
diff-match-patch@^1.0.5: diff-match-patch@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37" resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
@@ -7780,11 +7726,6 @@ discontinuous-range@1.0.0:
resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
integrity sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ== integrity sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==
dlv@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
dns-equal@^1.0.0: dns-equal@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
@@ -8547,15 +8488,6 @@ eslint-plugin-react@^7.16.0:
semver "^6.3.0" semver "^6.3.0"
string.prototype.matchall "^4.0.7" string.prototype.matchall "^4.0.7"
eslint-plugin-tailwindcss@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.6.0.tgz#b29605a53b5c27b7e74986ca7fcc0c6bdc435ad3"
integrity sha512-gWLGNWHuhh5ngwkJ2sgSByanpRw2s5GdrM2ff2/w8Ho2mWh2MyGvpnFZpL4b0XT/C0WF9zlq57+vFHJOeFhMkg==
dependencies:
fast-glob "^3.2.5"
postcss "^8.4.4"
tailwindcss "^3.1.3"
eslint-scope@5.1.1, eslint-scope@^5.1.1: eslint-scope@5.1.1, eslint-scope@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
@@ -8958,7 +8890,7 @@ fast-glob@^2.2.6:
merge2 "^1.2.3" merge2 "^1.2.3"
micromatch "^3.1.10" micromatch "^3.1.10"
fast-glob@^3.2.11, fast-glob@^3.2.5, fast-glob@^3.2.9: fast-glob@^3.2.9:
version "3.2.11" version "3.2.11"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
@@ -9630,13 +9562,6 @@ glob-parent@^5.1.2, glob-parent@~5.1.2:
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"
glob-parent@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies:
is-glob "^4.0.3"
glob-promise@^3.4.0: glob-promise@^3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20"
@@ -13943,11 +13868,6 @@ object-copy@^0.1.0:
define-property "^0.2.5" define-property "^0.2.5"
kind-of "^3.0.3" kind-of "^3.0.3"
object-hash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
object-inspect@^1.12.0, object-inspect@^1.7.0, object-inspect@^1.9.0: object-inspect@^1.12.0, object-inspect@^1.7.0, object-inspect@^1.9.0:
version "1.12.2" version "1.12.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
@@ -14591,7 +14511,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.0, picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: pify@^2.0.0, pify@^2.2.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
@@ -14805,22 +14725,6 @@ postcss-flexbugs-fixes@^4.2.1:
dependencies: dependencies:
postcss "^7.0.26" postcss "^7.0.26"
postcss-import@^14.1.0:
version "14.1.0"
resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0"
integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==
dependencies:
postcss-value-parser "^4.0.0"
read-cache "^1.0.0"
resolve "^1.1.7"
postcss-js@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00"
integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==
dependencies:
camelcase-css "^2.0.1"
postcss-load-config@2.0.0: postcss-load-config@2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484" resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484"
@@ -14829,7 +14733,7 @@ postcss-load-config@2.0.0:
cosmiconfig "^4.0.0" cosmiconfig "^4.0.0"
import-cwd "^2.0.0" import-cwd "^2.0.0"
postcss-load-config@^3.0.1, postcss-load-config@^3.1.4: postcss-load-config@^3.0.1:
version "3.1.4" version "3.1.4"
resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855"
integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==
@@ -14982,13 +14886,6 @@ postcss-modules@4.3.1:
postcss-modules-values "^4.0.0" postcss-modules-values "^4.0.0"
string-hash "^1.1.1" string-hash "^1.1.1"
postcss-nested@5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc"
integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==
dependencies:
postcss-selector-parser "^6.0.6"
postcss-normalize-charset@^5.1.0: postcss-normalize-charset@^5.1.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed"
@@ -15075,7 +14972,7 @@ postcss-reduce-transforms@^5.1.0:
dependencies: dependencies:
postcss-value-parser "^4.2.0" postcss-value-parser "^4.2.0"
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9:
version "6.0.10" version "6.0.10"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
@@ -15098,7 +14995,7 @@ postcss-unique-selectors@^5.1.1:
dependencies: dependencies:
postcss-selector-parser "^6.0.5" postcss-selector-parser "^6.0.5"
postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
@@ -15111,7 +15008,7 @@ postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0
picocolors "^0.2.1" picocolors "^0.2.1"
source-map "^0.6.1" source-map "^0.6.1"
postcss@^8.1.10, postcss@^8.2.1, postcss@^8.2.15, postcss@^8.4.12, postcss@^8.4.14, postcss@^8.4.4, postcss@^8.4.7: postcss@^8.1.10, postcss@^8.2.1, postcss@^8.2.15, postcss@^8.4.12, postcss@^8.4.7:
version "8.4.14" version "8.4.14"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
@@ -15507,11 +15404,6 @@ quick-lru@^4.0.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
quick-lru@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
raf@^3.4.0, raf@^3.4.1: raf@^3.4.0, raf@^3.4.1:
version "3.4.1" version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
@@ -15923,13 +15815,6 @@ react@^17.0.1:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
read-cache@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==
dependencies:
pify "^2.3.0"
read-pkg-up@^1.0.1: read-pkg-up@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
@@ -16707,7 +16592,7 @@ resolve@1.1.7:
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==
resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1, resolve@^1.3.2, resolve@^1.9.0: resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.3.2, resolve@^1.9.0:
version "1.22.1" version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -18060,34 +17945,6 @@ table@^6.0.9:
string-width "^4.2.3" string-width "^4.2.3"
strip-ansi "^6.0.1" strip-ansi "^6.0.1"
tailwindcss@^3.1.3:
version "3.1.6"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.6.tgz#bcb719357776c39e6376a8d84e9834b2b19a49f1"
integrity sha512-7skAOY56erZAFQssT1xkpk+kWt2NrO45kORlxFPXUt3CiGsVPhH1smuH5XoDH6sGPXLyBv+zgCKA2HWBsgCytg==
dependencies:
arg "^5.0.2"
chokidar "^3.5.3"
color-name "^1.1.4"
detective "^5.2.1"
didyoumean "^1.2.2"
dlv "^1.1.3"
fast-glob "^3.2.11"
glob-parent "^6.0.2"
is-glob "^4.0.3"
lilconfig "^2.0.5"
normalize-path "^3.0.0"
object-hash "^3.0.0"
picocolors "^1.0.0"
postcss "^8.4.14"
postcss-import "^14.1.0"
postcss-js "^4.0.0"
postcss-load-config "^3.1.4"
postcss-nested "5.0.6"
postcss-selector-parser "^6.0.10"
postcss-value-parser "^4.2.0"
quick-lru "^5.1.1"
resolve "^1.22.1"
tapable@^1.0.0, tapable@^1.1.3: tapable@^1.0.0, tapable@^1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
@@ -19937,7 +19794,7 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==