@verdaccio/ui-theme 6.0.0-6-next.9 → 6.0.0-6-next.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +1 -1
- package/.eslintrc +0 -15
- package/CHANGELOG.md +61 -0
- package/jest/api/packages.json +42 -0
- package/jest/jest.config.js +2 -2
- package/jest/server-handlers.ts +9 -0
- package/jest/server.ts +6 -0
- package/jest/setup-env.ts +18 -0
- package/jest/setup.ts +2 -7
- package/jest/unit/components/__mocks__/token.ts +0 -1
- package/jest/unit/components/store/login.ts +1 -0
- package/package.json +43 -33
- package/src/App/App.test.tsx +75 -51
- package/src/App/App.tsx +7 -42
- package/src/App/AppRoute.tsx +3 -16
- package/src/App/Footer/Footer.test.tsx +0 -1
- package/src/App/Footer/Footer.tsx +35 -22
- package/src/App/Footer/__snapshots__/Footer.test.tsx.snap +208 -302
- package/src/App/Footer/styles.ts +2 -3
- package/src/App/Header/Header.test.tsx +53 -61
- package/src/App/Header/Header.tsx +13 -24
- package/src/App/Header/HeaderGreetings.tsx +0 -1
- package/src/App/Header/HeaderLeft.tsx +0 -1
- package/src/App/Header/HeaderMenu.tsx +6 -6
- package/src/App/Header/HeaderRight.tsx +1 -2
- package/src/App/Header/HeaderToolTip.tsx +0 -1
- package/src/App/Header/HeaderToolTipIcon.tsx +10 -10
- package/src/App/Header/LanguageSwitch.tsx +17 -79
- package/src/App/Header/LoginDialog/LoginDialog.test.tsx +25 -35
- package/src/App/Header/LoginDialog/LoginDialog.tsx +28 -46
- package/src/App/Header/LoginDialog/LoginDialogCloseButton.tsx +1 -2
- package/src/App/Header/LoginDialog/LoginDialogForm.tsx +0 -1
- package/src/App/Header/LoginDialog/LoginDialogFormError.tsx +1 -2
- package/src/App/Header/LoginDialog/LoginDialogHeader.tsx +4 -4
- package/src/App/Header/RegistryInfoContent/RegistryInfoContent.test.tsx +1 -3
- package/src/App/Header/RegistryInfoContent/RegistryInfoContent.tsx +9 -10
- package/src/App/Header/RegistryInfoDialog/RegistryInfoDialog.tsx +1 -2
- package/src/App/Header/RegistryInfoDialog/styles.ts +0 -1
- package/src/App/Header/Search/Search.test.tsx +48 -43
- package/src/App/Header/Search/Search.tsx +23 -108
- package/src/App/Header/Search/__snapshots__/Search.test.tsx.snap +392 -28
- package/src/App/Header/styles.ts +2 -3
- package/src/App/index.ts +0 -1
- package/src/App/utils/loadable.tsx +3 -1
- package/src/components/ActionBar/ActionBar.test.tsx +13 -14
- package/src/components/ActionBar/ActionBar.tsx +0 -2
- package/src/components/ActionBar/ActionBarAction.tsx +11 -14
- package/src/components/ActionBar/__snapshots__/ActionBar.test.tsx.snap +198 -53
- package/src/components/AppBar.tsx +1 -1
- package/src/components/Author/Author.test.tsx +1 -4
- package/src/components/Author/Author.tsx +2 -4
- package/src/components/Author/__snapshots__/Author.test.tsx.snap +804 -48
- package/src/components/Author/styles.ts +0 -1
- package/src/components/AutoComplete/AutoComplete.tsx +85 -163
- package/src/components/AutoComplete/AutoCompleteV2.tsx +8 -10
- package/src/components/AutoComplete/styles.tsx +0 -15
- package/src/components/Avatar.tsx +1 -1
- package/src/components/Box.tsx +1 -1
- package/src/components/Button.tsx +1 -1
- package/src/components/Card.tsx +1 -1
- package/src/components/CardActions.tsx +1 -1
- package/src/components/CardContent.tsx +1 -1
- package/src/components/Chip.tsx +1 -1
- package/src/components/CircularProgress.tsx +2 -2
- package/src/components/CopyToClipBoard.tsx +2 -3
- package/src/components/Dialog.tsx +1 -1
- package/src/components/DialogActions.tsx +2 -2
- package/src/components/DialogContent.tsx +2 -2
- package/src/components/DialogTitle.tsx +1 -1
- package/src/components/Divider.tsx +1 -1
- package/src/components/FloatingActionButton.tsx +1 -1
- package/src/components/FormControl.tsx +1 -1
- package/src/components/FormHelperText.tsx +2 -2
- package/src/components/Grid.tsx +1 -1
- package/src/components/Heading.tsx +1 -1
- package/src/components/IconButton.tsx +1 -1
- package/src/components/Icons/index.ts +1 -17
- package/src/components/Input.tsx +1 -1
- package/src/components/InputAdornment/InputAdornment.tsx +2 -2
- package/src/components/InputLabel.tsx +1 -1
- package/src/components/Label/Label.test.tsx +0 -1
- package/src/components/Label/Label.tsx +2 -3
- package/src/components/List.tsx +1 -1
- package/src/components/ListItem.tsx +1 -1
- package/src/components/ListItemText.tsx +1 -4
- package/src/components/Loading/Loading.test.tsx +0 -1
- package/src/components/Loading/Loading.tsx +1 -2
- package/src/components/Loading/Spinner/Spinner.test.tsx +1 -2
- package/src/components/Loading/Spinner/Spinner.tsx +1 -2
- package/src/components/Loading/Spinner/__snapshots__/Spinner.test.tsx.snap +114 -16
- package/src/components/Loading/__snapshots__/Loading.test.tsx.snap +63 -11
- package/src/components/Loading/styles.ts +1 -2
- package/src/components/Logo/Logo.test.tsx +0 -1
- package/src/components/Logo/Logo.tsx +1 -2
- package/src/components/Logo/__snapshots__/Logo.test.tsx.snap +2 -0
- package/src/components/Menu.tsx +1 -1
- package/src/components/MenuItem.tsx +1 -1
- package/src/components/NotFound/NotFound.tsx +1 -3
- package/src/components/NotFound/Notfound.test.tsx +1 -2
- package/src/components/NotFound/__snapshots__/Notfound.test.tsx.snap +138 -11
- package/src/components/NotFound/styles.ts +0 -1
- package/src/components/Paper.tsx +1 -1
- package/src/components/SnackbarContent.tsx +1 -1
- package/src/components/SvgIcon.tsx +1 -1
- package/src/components/Tab.tsx +1 -1
- package/src/components/Tabs.tsx +1 -1
- package/src/components/Text/Text.tsx +1 -1
- package/src/components/Text/TextConfig.ts +1 -1
- package/src/components/TextField/TextField.test.tsx +0 -1
- package/src/components/TextField/TextField.tsx +2 -2
- package/src/components/TextField/__snapshots__/TextField.test.tsx.snap +216 -3
- package/src/components/Toolbar.tsx +1 -1
- package/src/components/Tooltip.tsx +1 -1
- package/src/design-tokens/ResetStyles.tsx +1 -1
- package/src/design-tokens/StyleBaseline.tsx +2 -2
- package/src/design-tokens/ThemeContext.ts +1 -1
- package/src/design-tokens/ThemeProvider.tsx +15 -12
- package/src/design-tokens/theme.ts +28 -26
- package/src/design-tokens/useTheme.ts +1 -1
- package/src/{design-tokens → hooks}/useLocalStorage.ts +0 -0
- package/src/{design-tokens → hooks}/useOnClickOutside.ts +0 -0
- package/src/i18n/ABOUT_TRANSLATIONS.md +13 -0
- package/src/i18n/__mocks__/loadTranslationFile.ts +5 -0
- package/src/i18n/config.ts +38 -0
- package/src/i18n/crowdin/ui.json +170 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/cs-CZ.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/de-DE.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/en-US.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/es-ES.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/fr-FR.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/ja-JP.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/km-KH.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/pt-BR.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/ru-RU.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/tr-TR.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/uk-UA.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/zh-CN.json +0 -0
- package/{i18n/translations → src/i18n/deprecated_translations_dont_use}/zh-TW.json +0 -0
- package/src/i18n/download_translations/ar-SA/ui.json +170 -0
- package/src/i18n/download_translations/cs-CZ/ui.json +170 -0
- package/src/i18n/download_translations/de-DE/ui.json +170 -0
- package/src/i18n/download_translations/es-ES/ui.json +170 -0
- package/src/i18n/download_translations/fi-FI/ui.json +170 -0
- package/src/i18n/download_translations/fil-PH/ui.json +170 -0
- package/src/i18n/download_translations/fr-FR/ui.json +170 -0
- package/src/i18n/download_translations/gl-ES/ui.json +170 -0
- package/src/i18n/download_translations/hi-IN/ui.json +170 -0
- package/src/i18n/download_translations/it-IT/ui.json +170 -0
- package/src/i18n/download_translations/ja-JP/ui.json +170 -0
- package/src/i18n/download_translations/km-KH/ui.json +170 -0
- package/src/i18n/download_translations/ko-KR/ui.json +170 -0
- package/src/i18n/download_translations/pl-PL/ui.json +170 -0
- package/src/i18n/download_translations/pt-BR/ui.json +170 -0
- package/src/i18n/download_translations/pt-PT/ui.json +170 -0
- package/src/i18n/download_translations/ro-RO/ui.json +170 -0
- package/src/i18n/download_translations/ru-RU/ui.json +170 -0
- package/src/i18n/download_translations/si-LK/ui.json +170 -0
- package/src/i18n/download_translations/sr-CS/ui.json +170 -0
- package/src/i18n/download_translations/sr-SP/ui.json +170 -0
- package/src/i18n/download_translations/tg-TJ/ui.json +170 -0
- package/src/i18n/download_translations/tr-TR/ui.json +170 -0
- package/src/i18n/download_translations/uk-UA/ui.json +170 -0
- package/src/i18n/download_translations/vi-VN/ui.json +170 -0
- package/src/i18n/download_translations/yo-NG/ui.json +170 -0
- package/src/i18n/download_translations/zh-CN/ui.json +170 -0
- package/src/i18n/download_translations/zh-TW/ui.json +170 -0
- package/src/i18n/enabledLanguages.ts +35 -0
- package/src/i18n/loadTranslationFile.ts +14 -0
- package/src/index.tsx +13 -11
- package/src/pages/Version/DetailContainer/Dependencies/Dependencies.test.tsx +0 -2
- package/src/pages/Version/DetailContainer/Dependencies/Dependencies.tsx +1 -3
- package/src/pages/Version/DetailContainer/Dependencies/styles.ts +0 -1
- package/src/pages/Version/DetailContainer/Deprecated/Deprecated.test.tsx +1 -3
- package/src/pages/Version/DetailContainer/Deprecated/Deprecated.tsx +2 -3
- package/src/pages/Version/DetailContainer/DetailContainer.test.tsx +0 -1
- package/src/pages/Version/DetailContainer/DetailContainer.tsx +1 -3
- package/src/pages/Version/DetailContainer/DetailContainerContent.tsx +0 -1
- package/src/pages/Version/DetailContainer/DetailContainerContentReadme.tsx +0 -1
- package/src/pages/Version/DetailContainer/DetailContainerTabs.tsx +0 -1
- package/src/pages/Version/DetailContainer/NoItems/NoItems.tsx +0 -1
- package/src/pages/Version/DetailContainer/NoItems/Noitems.test.tsx +0 -1
- package/src/pages/Version/DetailContainer/NoItems/__snapshots__/Noitems.test.tsx.snap +10 -1
- package/src/pages/Version/DetailContainer/Readme/Readme.spec.tsx +1 -2
- package/src/pages/Version/DetailContainer/Readme/Readme.tsx +1 -2
- package/src/pages/Version/DetailContainer/UpLinks/UpLinks.test.tsx +1 -9
- package/src/pages/Version/DetailContainer/UpLinks/UpLinks.tsx +1 -3
- package/src/pages/Version/DetailContainer/UpLinks/__snapshots__/UpLinks.test.tsx.snap +184 -26
- package/src/pages/Version/DetailContainer/UpLinks/styles.ts +2 -3
- package/src/pages/Version/DetailContainer/Versions/Versions.test.tsx +3 -5
- package/src/pages/Version/DetailContainer/Versions/Versions.tsx +1 -2
- package/src/pages/Version/DetailContainer/Versions/VersionsHistoryList.tsx +2 -4
- package/src/pages/Version/DetailContainer/Versions/VersionsTagList.tsx +1 -3
- package/src/pages/Version/DetailContainer/Versions/styles.ts +2 -3
- package/src/pages/Version/DetailContainer/__snapshots__/DetailContainer.test.tsx.snap +168 -34
- package/src/pages/Version/DetailSidebar/DetailSidebar.tsx +0 -2
- package/src/pages/Version/DetailSidebar/DetailSidebarFundButton.test.tsx +0 -2
- package/src/pages/Version/DetailSidebar/DetailSidebarFundButton.tsx +1 -2
- package/src/pages/Version/DetailSidebar/DetailSidebarTitle.tsx +0 -1
- package/src/pages/Version/DetailSidebar/Developers/Developers.test.tsx +3 -5
- package/src/pages/Version/DetailSidebar/Developers/Developers.tsx +3 -5
- package/src/pages/Version/DetailSidebar/Developers/DevelopersTitle.tsx +0 -1
- package/src/pages/Version/DetailSidebar/Developers/__snapshots__/Developers.test.tsx.snap +328 -40
- package/src/pages/Version/DetailSidebar/Developers/styles.ts +0 -1
- package/src/pages/Version/DetailSidebar/Dist/Dist.test.tsx +1 -3
- package/src/pages/Version/DetailSidebar/Dist/Dist.tsx +1 -3
- package/src/pages/Version/DetailSidebar/Dist/__snapshots__/Dist.test.tsx.snap +1436 -74
- package/src/pages/Version/DetailSidebar/Dist/styles.ts +2 -1
- package/src/pages/Version/DetailSidebar/Engines/Engines.test.tsx +1 -3
- package/src/pages/Version/DetailSidebar/Engines/Engines.tsx +1 -3
- package/src/pages/Version/DetailSidebar/Engines/styles.ts +0 -1
- package/src/pages/Version/DetailSidebar/Install/Install.test.tsx +1 -3
- package/src/pages/Version/DetailSidebar/Install/Install.tsx +0 -2
- package/src/pages/Version/DetailSidebar/Install/InstallListItem.tsx +0 -1
- package/src/pages/Version/DetailSidebar/Repository/Repository.test.tsx +1 -3
- package/src/pages/Version/DetailSidebar/Repository/Repository.tsx +1 -3
- package/src/pages/Version/Version.test.tsx +3 -5
- package/src/pages/Version/Version.tsx +21 -6
- package/src/pages/Version/VersionContextProvider.tsx +14 -45
- package/src/pages/Version/VersionLayout.tsx +1 -1
- package/src/pages/Version/context.ts +1 -1
- package/src/pages/home/Home.tsx +9 -28
- package/src/pages/home/PackageList/Help/Help.test.tsx +0 -1
- package/src/pages/home/PackageList/Help/Help.tsx +0 -1
- package/src/pages/home/PackageList/Help/__snapshots__/Help.test.tsx.snap +298 -59
- package/src/pages/home/PackageList/Help/styles.ts +0 -1
- package/src/pages/home/PackageList/Package/Package.test.tsx +5 -4
- package/src/pages/home/PackageList/Package/Package.tsx +20 -28
- package/src/pages/home/PackageList/Package/Tag/Tag.test.tsx +0 -1
- package/src/pages/home/PackageList/Package/styles.ts +5 -6
- package/src/pages/home/PackageList/PackageList.tsx +17 -17
- package/src/pages/home/PackageList/Packagelist.test.tsx +6 -5
- package/src/providers/API/api.test.ts +1 -0
- package/src/providers/API/api.ts +7 -3
- package/src/providers/config/AppConfigurationProvider.tsx +3 -3
- package/src/store/index.ts +1 -0
- package/src/store/models/configuration.ts +41 -0
- package/src/store/models/download.ts +30 -0
- package/src/store/models/index.ts +18 -0
- package/src/store/models/login.ts +92 -0
- package/src/store/models/manifest.ts +91 -0
- package/src/store/models/packages.ts +36 -0
- package/src/store/models/search.ts +81 -0
- package/src/store/store.ts +15 -0
- package/src/utils/login.test.ts +3 -4
- package/src/utils/package.test.ts +2 -3
- package/src/utils/package.ts +2 -1
- package/src/utils/sec-utils.ts +1 -1
- package/src/utils/test-react-testing-library.tsx +22 -5
- package/src/utils/url.test.ts +1 -1
- package/src/utils/url.ts +1 -0
- package/static/Dependencies.15768a14646212b71166.js +2 -0
- package/static/Dependencies.15768a14646212b71166.js.LICENSE.txt +78 -0
- package/static/Dist.15768a14646212b71166.js +2 -0
- package/static/Dist.15768a14646212b71166.js.LICENSE.txt +60 -0
- package/static/Engines.15768a14646212b71166.js +2 -0
- package/static/Engines.15768a14646212b71166.js.LICENSE.txt +66 -0
- package/static/Home.15768a14646212b71166.js +2 -0
- package/static/Home.15768a14646212b71166.js.LICENSE.txt +222 -0
- package/static/Install.15768a14646212b71166.js +2 -0
- package/static/Install.15768a14646212b71166.js.LICENSE.txt +66 -0
- package/static/NotFound.15768a14646212b71166.js +2 -0
- package/static/NotFound.15768a14646212b71166.js.LICENSE.txt +40 -0
- package/static/Provider.15768a14646212b71166.js +2 -0
- package/static/Provider.15768a14646212b71166.js.LICENSE.txt +32 -0
- package/static/Repository.15768a14646212b71166.js +2 -0
- package/static/Repository.15768a14646212b71166.js.LICENSE.txt +50 -0
- package/static/UpLinks.15768a14646212b71166.js +2 -0
- package/static/UpLinks.15768a14646212b71166.js.LICENSE.txt +56 -0
- package/static/Version.15768a14646212b71166.js +2 -0
- package/static/Version.15768a14646212b71166.js.LICENSE.txt +380 -0
- package/static/Versions.15768a14646212b71166.js +2 -0
- package/static/Versions.15768a14646212b71166.js.LICENSE.txt +64 -0
- package/static/index.html +1 -1
- package/static/main.15768a14646212b71166.js +2 -0
- package/static/main.15768a14646212b71166.js.LICENSE.txt +972 -0
- package/static/manifest.json +17 -3
- package/static/runtime.15768a14646212b71166.js +2 -0
- package/static/{runtime.9525ddaaf85378590c63.js.LICENSE.txt → runtime.15768a14646212b71166.js.LICENSE.txt} +2 -2
- package/static/vendors-node_modules_pnpm_mui_icons-material_5_0_5_d1eeebd4022867ee03864a00e16c7901_node_modu-123400.15768a14646212b71166.js +2 -0
- package/static/vendors-node_modules_pnpm_mui_icons-material_5_0_5_d1eeebd4022867ee03864a00e16c7901_node_modu-123400.15768a14646212b71166.js.LICENSE.txt +148 -0
- package/static/vendors-node_modules_pnpm_mui_icons-material_5_0_5_d1eeebd4022867ee03864a00e16c7901_node_modu-d2b578.15768a14646212b71166.js +2 -0
- package/static/vendors-node_modules_pnpm_mui_icons-material_5_0_5_d1eeebd4022867ee03864a00e16c7901_node_modu-d2b578.15768a14646212b71166.js.LICENSE.txt +218 -0
- package/static/vendors-node_modules_pnpm_mui_material_5_0_6_033766d34292bd5d464212fd95cb4b6d_node_modules_mu-1fb115.15768a14646212b71166.js +2 -0
- package/static/vendors-node_modules_pnpm_mui_material_5_0_6_033766d34292bd5d464212fd95cb4b6d_node_modules_mu-1fb115.15768a14646212b71166.js.LICENSE.txt +316 -0
- package/static/vendors.15768a14646212b71166.js +103 -0
- package/static/vendors.15768a14646212b71166.js.LICENSE.txt +3158 -0
- package/tools/dev.server.js +0 -1
- package/tools/webpack.dev.config.babel.js +1 -3
- package/tools/webpack.prod.config.babel.js +1 -1
- package/tsconfig.json +1 -3
- package/types/index.ts +3 -20
- package/i18n/config.ts +0 -94
- package/src/App/AppContext.ts +0 -18
- package/src/App/AppContextProvider.tsx +0 -44
- package/src/App/Header/Search/SearchAdornment.tsx +0 -18
- package/src/components/Icons/Austria.tsx +0 -23
- package/src/components/Icons/Brazil.tsx +0 -44
- package/src/components/Icons/China.tsx +0 -33
- package/src/components/Icons/Czech.tsx +0 -21
- package/src/components/Icons/France.tsx +0 -27
- package/src/components/Icons/Germany.tsx +0 -27
- package/src/components/Icons/India.tsx +0 -44
- package/src/components/Icons/Japan.tsx +0 -23
- package/src/components/Icons/Khmer.tsx +0 -40
- package/src/components/Icons/Nicaragua.tsx +0 -66
- package/src/components/Icons/Russia.tsx +0 -27
- package/src/components/Icons/Spain.tsx +0 -43
- package/src/components/Icons/Taiwan.tsx +0 -25
- package/src/components/Icons/Turkey.tsx +0 -23
- package/src/components/Icons/Ukraine.tsx +0 -30
- package/src/components/Icons/Usa.tsx +0 -34
- package/src/design-tokens/emotion.ts +0 -5
- package/src/lib/constants.ts +0 -9
- package/src/pages/Version/DetailSidebar/ActionBar/ActionBar.test.tsx +0 -84
- package/src/pages/Version/DetailSidebar/ActionBar/__snapshots__/ActionBar.test.tsx.snap +0 -122
- package/src/pages/Version/is-package-version-valid.ts +0 -19
- package/src/providers/API/APIProvider.tsx +0 -109
- package/src/providers/API/index.ts +0 -1
- package/static/main.9525ddaaf85378590c63.js +0 -2
- package/static/main.9525ddaaf85378590c63.js.LICENSE.txt +0 -1588
- package/static/runtime.9525ddaaf85378590c63.js +0 -2
- package/static/vendors.9525ddaaf85378590c63.js +0 -2
- package/static/vendors.9525ddaaf85378590c63.js.LICENSE.txt +0 -4540
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import i18next from 'i18next';
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
|
-
import React, {
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import React, { useCallback, useEffect } from 'react';
|
|
4
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
6
5
|
import Dialog from 'verdaccio-ui/components/Dialog';
|
|
7
6
|
import DialogContent from 'verdaccio-ui/components/DialogContent';
|
|
8
|
-
import { useAPI, LoginBody } from 'verdaccio-ui/providers/API/APIProvider';
|
|
9
|
-
import { LoginError } from 'verdaccio-ui/utils/login';
|
|
10
|
-
import storage from 'verdaccio-ui/utils/storage';
|
|
11
|
-
|
|
12
|
-
import AppContext from '../../../App/AppContext';
|
|
13
7
|
|
|
8
|
+
import { LoginBody } from '../../../store/models/login';
|
|
9
|
+
import { Dispatch, RootState } from '../../../store/store';
|
|
14
10
|
import LoginDialogCloseButton from './LoginDialogCloseButton';
|
|
15
11
|
import LoginDialogForm, { FormValues } from './LoginDialogForm';
|
|
16
12
|
import LoginDialogHeader from './LoginDialogHeader';
|
|
@@ -21,62 +17,48 @@ interface Props {
|
|
|
21
17
|
}
|
|
22
18
|
|
|
23
19
|
const LoginDialog: React.FC<Props> = ({ onClose, open = false }) => {
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const { doLogin } = useAPI();
|
|
27
|
-
|
|
20
|
+
const loginStore = useSelector((state: RootState) => state.login);
|
|
21
|
+
const dispatch = useDispatch<Dispatch>();
|
|
28
22
|
const makeLogin = useCallback(
|
|
29
|
-
async (username?: string, password?: string): Promise<LoginBody> => {
|
|
23
|
+
async (username?: string, password?: string): Promise<LoginBody | void> => {
|
|
30
24
|
// checks isEmpty
|
|
31
25
|
if (isEmpty(username) || isEmpty(password)) {
|
|
32
|
-
|
|
26
|
+
dispatch.login.addError({
|
|
33
27
|
type: 'error',
|
|
34
28
|
description: i18next.t('form-validation.username-or-password-cant-be-empty'),
|
|
35
|
-
};
|
|
36
|
-
return
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
try {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
dispatch.login.getUser({ username, password });
|
|
35
|
+
// const response: LoginBody = await doLogin(username as string, password as string);
|
|
36
|
+
dispatch.login.clearError();
|
|
43
37
|
} catch (e: any) {
|
|
44
|
-
|
|
45
|
-
console.error('login error', e.message);
|
|
46
|
-
const error = {
|
|
38
|
+
dispatch.login.addError({
|
|
47
39
|
type: 'error',
|
|
48
40
|
description: i18next.t('form-validation.unable-to-sign-in'),
|
|
49
|
-
};
|
|
50
|
-
|
|
41
|
+
});
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.error('login error', e.message);
|
|
51
44
|
}
|
|
52
45
|
},
|
|
53
|
-
[
|
|
46
|
+
[dispatch]
|
|
54
47
|
);
|
|
55
48
|
|
|
56
|
-
if (!appContext) {
|
|
57
|
-
throw Error(t('app-context-not-correct-used'));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const [error, setError] = useState<LoginError>();
|
|
61
|
-
|
|
62
49
|
const handleDoLogin = useCallback(
|
|
63
50
|
async (data: FormValues) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (error) {
|
|
67
|
-
setError(error);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (username && token) {
|
|
71
|
-
storage.setItem('username', username);
|
|
72
|
-
storage.setItem('token', token);
|
|
73
|
-
appContext.setUser({ username });
|
|
74
|
-
onClose();
|
|
75
|
-
}
|
|
51
|
+
await makeLogin(data.username, data.password);
|
|
76
52
|
},
|
|
77
|
-
[
|
|
53
|
+
[makeLogin]
|
|
78
54
|
);
|
|
79
55
|
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (loginStore.token && typeof loginStore.error === 'undefined') {
|
|
58
|
+
onClose();
|
|
59
|
+
}
|
|
60
|
+
}, [loginStore, onClose]);
|
|
61
|
+
|
|
80
62
|
return (
|
|
81
63
|
<Dialog
|
|
82
64
|
data-testid="login--dialog"
|
|
@@ -86,9 +68,9 @@ const LoginDialog: React.FC<Props> = ({ onClose, open = false }) => {
|
|
|
86
68
|
onClose={onClose}
|
|
87
69
|
open={open}>
|
|
88
70
|
<LoginDialogCloseButton onClose={onClose} />
|
|
89
|
-
<DialogContent>
|
|
71
|
+
<DialogContent data-testid="dialogContentLogin">
|
|
90
72
|
<LoginDialogHeader />
|
|
91
|
-
<LoginDialogForm error={error} onSubmit={handleDoLogin} />
|
|
73
|
+
<LoginDialogForm error={loginStore.error} onSubmit={handleDoLogin} />
|
|
92
74
|
</DialogContent>
|
|
93
75
|
</Dialog>
|
|
94
76
|
);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import styled from '@emotion/styled';
|
|
2
|
-
import CloseIcon from '@
|
|
2
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
|
|
6
5
|
import DialogTitle from 'verdaccio-ui/components/DialogTitle';
|
|
7
6
|
import IconButton from 'verdaccio-ui/components/IconButton';
|
|
8
7
|
import { Theme } from 'verdaccio-ui/design-tokens/theme';
|
|
@@ -3,7 +3,6 @@ import styled from '@emotion/styled';
|
|
|
3
3
|
import React, { memo } from 'react';
|
|
4
4
|
import { useForm } from 'react-hook-form';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
|
|
7
6
|
import Button from 'verdaccio-ui/components/Button';
|
|
8
7
|
import TextField from 'verdaccio-ui/components/TextField';
|
|
9
8
|
import { Theme } from 'verdaccio-ui/design-tokens/theme';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import styled from '@emotion/styled';
|
|
2
|
-
import Error from '@
|
|
2
|
+
import Error from '@mui/icons-material/Error';
|
|
3
3
|
import React, { memo } from 'react';
|
|
4
|
-
|
|
5
4
|
import Box from 'verdaccio-ui/components/Box';
|
|
6
5
|
import SnackbarContent from 'verdaccio-ui/components/SnackbarContent';
|
|
7
6
|
import { Theme } from 'verdaccio-ui/design-tokens/theme';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import styled from '@emotion/styled';
|
|
2
|
-
import CloseIcon from '@
|
|
3
|
-
import LockOutlined from '@
|
|
2
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
3
|
+
import LockOutlined from '@mui/icons-material/LockOutlined';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
|
|
7
6
|
import Avatar from 'verdaccio-ui/components/Avatar';
|
|
8
7
|
import Box from 'verdaccio-ui/components/Box';
|
|
9
8
|
import Heading from 'verdaccio-ui/components/Heading';
|
|
10
9
|
import IconButton from 'verdaccio-ui/components/IconButton';
|
|
11
10
|
import { Theme } from 'verdaccio-ui/design-tokens/theme';
|
|
11
|
+
|
|
12
12
|
interface Props {
|
|
13
13
|
onClose?: () => void;
|
|
14
14
|
}
|
|
@@ -36,7 +36,7 @@ export default LoginDialogHeader;
|
|
|
36
36
|
const StyledAvatar = styled(Avatar)<{ theme?: Theme }>(({ theme }) => ({
|
|
37
37
|
margin: theme?.spacing(1),
|
|
38
38
|
backgroundColor:
|
|
39
|
-
theme?.palette.
|
|
39
|
+
theme?.palette.mode === 'light' ? theme?.palette.primary.main : theme?.palette.cyanBlue,
|
|
40
40
|
color: theme?.palette.white,
|
|
41
41
|
}));
|
|
42
42
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import { screen, render, cleanup } from 'verdaccio-ui/utils/test-react-testing-library';
|
|
2
|
+
import { cleanup, render, screen } from 'verdaccio-ui/utils/test-react-testing-library';
|
|
4
3
|
|
|
5
4
|
import RegistryInfoContent from './RegistryInfoContent';
|
|
6
5
|
|
|
@@ -18,7 +17,6 @@ describe('<RegistryInfoContent /> component', () => {
|
|
|
18
17
|
const props = { registryUrl: 'http://localhost:4872', scope: '@' };
|
|
19
18
|
render(<RegistryInfoContent registryUrl={props.registryUrl} scope={props.scope} />);
|
|
20
19
|
|
|
21
|
-
screen.debug();
|
|
22
20
|
expect(screen.getByText('pnpm set @:registry http://localhost:4872')).toBeInTheDocument();
|
|
23
21
|
expect(screen.getByText('pnpm adduser --registry http://localhost:4872')).toBeInTheDocument();
|
|
24
22
|
expect(
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import styled from '@emotion/styled';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import Typography from '@material
|
|
9
|
-
import
|
|
2
|
+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
3
|
+
import Accordion from '@mui/material/Accordion';
|
|
4
|
+
import AccordionDetails from '@mui/material/AccordionDetails';
|
|
5
|
+
import AccordionSummary from '@mui/material/AccordionSummary';
|
|
6
|
+
import Box from '@mui/material/Box';
|
|
7
|
+
import Link from '@mui/material/Link';
|
|
8
|
+
import Typography from '@mui/material/Typography';
|
|
9
|
+
import makeStyles from '@mui/styles/makeStyles';
|
|
10
10
|
import React, { FC } from 'react';
|
|
11
11
|
import { useTranslation } from 'react-i18next';
|
|
12
|
-
|
|
13
12
|
import CopyToClipBoard from 'verdaccio-ui/components/CopyToClipBoard';
|
|
14
13
|
import { useConfig } from 'verdaccio-ui/providers/config';
|
|
15
14
|
import {
|
|
16
|
-
getCLISetRegistry,
|
|
17
15
|
getCLIChangePassword,
|
|
18
16
|
getCLISetConfigRegistry,
|
|
17
|
+
getCLISetRegistry,
|
|
19
18
|
} from 'verdaccio-ui/utils/cli-utils';
|
|
20
19
|
import { NODE_MANAGER } from 'verdaccio-ui/utils/constants';
|
|
21
20
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
|
|
4
3
|
import Button from 'verdaccio-ui/components/Button';
|
|
5
4
|
import Dialog from 'verdaccio-ui/components/Dialog';
|
|
6
5
|
import DialogActions from 'verdaccio-ui/components/DialogActions';
|
|
7
6
|
|
|
8
|
-
import {
|
|
7
|
+
import { Content, Title } from './styles';
|
|
9
8
|
import { Props } from './types';
|
|
10
9
|
|
|
11
10
|
const RegistryInfoDialog: React.FC<Props> = ({ open = false, children, onClose }) => {
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BrowserRouter as Router } from 'react-router-dom';
|
|
3
|
-
|
|
4
3
|
import api from 'verdaccio-ui/providers/API/api';
|
|
5
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
fireEvent,
|
|
6
|
+
renderWithStore,
|
|
7
|
+
screen,
|
|
8
|
+
waitFor,
|
|
9
|
+
} from 'verdaccio-ui/utils/test-react-testing-library';
|
|
10
|
+
|
|
11
|
+
import { store } from '../../../store/store';
|
|
12
|
+
import Search from './Search';
|
|
6
13
|
|
|
7
14
|
jest.mock('lodash/debounce', () =>
|
|
8
15
|
jest.fn((fn) => {
|
|
@@ -11,8 +18,6 @@ jest.mock('lodash/debounce', () =>
|
|
|
11
18
|
})
|
|
12
19
|
);
|
|
13
20
|
|
|
14
|
-
import Search from './Search';
|
|
15
|
-
|
|
16
21
|
/* eslint-disable verdaccio/jsx-spread */
|
|
17
22
|
const ComponentToBeRendered: React.FC = () => (
|
|
18
23
|
<Router>
|
|
@@ -41,12 +46,15 @@ describe('<Search /> component', () => {
|
|
|
41
46
|
});
|
|
42
47
|
|
|
43
48
|
test('should load the component in default state', () => {
|
|
44
|
-
const { container } =
|
|
49
|
+
const { container } = renderWithStore(<ComponentToBeRendered />, store);
|
|
45
50
|
expect(container.firstChild).toMatchSnapshot();
|
|
46
51
|
});
|
|
47
52
|
|
|
48
53
|
test('handleSearch: when user type package name in search component, show suggestions', async () => {
|
|
49
|
-
const { getByPlaceholderText, getAllByText } =
|
|
54
|
+
const { getByPlaceholderText, getAllByText } = renderWithStore(
|
|
55
|
+
<ComponentToBeRendered />,
|
|
56
|
+
store
|
|
57
|
+
);
|
|
50
58
|
|
|
51
59
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
52
60
|
|
|
@@ -57,12 +65,15 @@ describe('<Search /> component', () => {
|
|
|
57
65
|
|
|
58
66
|
const suggestionsElements = await waitFor(() => getAllByText('verdaccio', { exact: true }));
|
|
59
67
|
|
|
60
|
-
expect(suggestionsElements).toHaveLength(
|
|
68
|
+
expect(suggestionsElements).toHaveLength(1);
|
|
61
69
|
expect(api.request).toHaveBeenCalledTimes(1);
|
|
62
70
|
});
|
|
63
71
|
|
|
64
72
|
test('onBlur: should cancel all search requests', async () => {
|
|
65
|
-
const { getByPlaceholderText,
|
|
73
|
+
const { getByPlaceholderText, getAllByText } = renderWithStore(
|
|
74
|
+
<ComponentToBeRendered />,
|
|
75
|
+
store
|
|
76
|
+
);
|
|
66
77
|
|
|
67
78
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
68
79
|
|
|
@@ -71,53 +82,44 @@ describe('<Search /> component', () => {
|
|
|
71
82
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
|
72
83
|
|
|
73
84
|
const suggestionsElements = await waitFor(() => getAllByText('verdaccio', { exact: true }));
|
|
74
|
-
expect(suggestionsElements).toHaveLength(
|
|
85
|
+
expect(suggestionsElements).toHaveLength(1);
|
|
75
86
|
expect(api.request).toHaveBeenCalledTimes(1);
|
|
76
87
|
|
|
77
88
|
fireEvent.blur(autoCompleteInput);
|
|
78
|
-
const listBoxElement =
|
|
79
|
-
expect(listBoxElement).
|
|
89
|
+
const listBoxElement = screen.queryAllByRole('listbox');
|
|
90
|
+
expect(listBoxElement).toHaveLength(0);
|
|
80
91
|
});
|
|
81
92
|
|
|
82
93
|
test('handleSearch: cancel all search requests when there is no value in search component with type method', async () => {
|
|
83
|
-
const { getByPlaceholderText
|
|
94
|
+
const { getByPlaceholderText } = renderWithStore(<ComponentToBeRendered />, store);
|
|
84
95
|
|
|
85
96
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
86
97
|
fireEvent.focus(autoCompleteInput);
|
|
87
98
|
fireEvent.change(autoCompleteInput, { target: { value: ' ', method: 'type' } });
|
|
88
|
-
expect(autoCompleteInput).toHaveAttribute('value', '');
|
|
89
|
-
const listBoxElement =
|
|
90
|
-
expect(listBoxElement
|
|
99
|
+
expect(autoCompleteInput).toHaveAttribute('value', ' ');
|
|
100
|
+
const listBoxElement = screen.queryAllByRole('listbox');
|
|
101
|
+
expect(listBoxElement).toHaveLength(0);
|
|
91
102
|
expect(api.request).toHaveBeenCalledTimes(0);
|
|
92
103
|
});
|
|
93
104
|
|
|
94
105
|
test('handleSearch: when method is not type method', async () => {
|
|
95
|
-
const { getByPlaceholderText
|
|
106
|
+
const { getByPlaceholderText } = renderWithStore(<ComponentToBeRendered />, store);
|
|
96
107
|
|
|
97
108
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
98
109
|
|
|
99
110
|
fireEvent.focus(autoCompleteInput);
|
|
100
111
|
fireEvent.change(autoCompleteInput, { target: { value: ' ', method: 'click' } });
|
|
101
|
-
expect(autoCompleteInput).toHaveAttribute('value', '');
|
|
102
|
-
const listBoxElement =
|
|
103
|
-
expect(listBoxElement
|
|
112
|
+
expect(autoCompleteInput).toHaveAttribute('value', ' ');
|
|
113
|
+
const listBoxElement = screen.queryAllByRole('listbox');
|
|
114
|
+
expect(listBoxElement).toHaveLength(0);
|
|
104
115
|
expect(api.request).toHaveBeenCalledTimes(0);
|
|
105
116
|
});
|
|
106
117
|
|
|
107
|
-
test('handleSearch: loading is been displayed', async () => {
|
|
108
|
-
const { getByPlaceholderText, getByText } = render(<ComponentToBeRendered />);
|
|
109
|
-
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
110
|
-
|
|
111
|
-
fireEvent.focus(autoCompleteInput);
|
|
112
|
-
fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } });
|
|
113
|
-
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
|
114
|
-
|
|
115
|
-
const loadingElement = await waitFor(() => getByText('Loading...'));
|
|
116
|
-
expect(loadingElement).toBeTruthy();
|
|
117
|
-
});
|
|
118
|
-
|
|
119
118
|
test('handlePackagesClearRequested: should clear suggestions', async () => {
|
|
120
|
-
const { getByPlaceholderText, getAllByText
|
|
119
|
+
const { getByPlaceholderText, getAllByText } = renderWithStore(
|
|
120
|
+
<ComponentToBeRendered />,
|
|
121
|
+
store
|
|
122
|
+
);
|
|
121
123
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
122
124
|
|
|
123
125
|
fireEvent.focus(autoCompleteInput);
|
|
@@ -125,17 +127,20 @@ describe('<Search /> component', () => {
|
|
|
125
127
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
|
126
128
|
|
|
127
129
|
const suggestionsElements = await waitFor(() => getAllByText('verdaccio', { exact: true }));
|
|
128
|
-
expect(suggestionsElements).toHaveLength(
|
|
130
|
+
expect(suggestionsElements).toHaveLength(1);
|
|
129
131
|
|
|
130
132
|
fireEvent.change(autoCompleteInput, { target: { value: ' ' } });
|
|
131
|
-
const listBoxElement =
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
const listBoxElement = screen.queryAllByRole('listbox');
|
|
134
|
+
// // when the page redirects, the list box should be empty again
|
|
135
|
+
expect(listBoxElement).toHaveLength(0);
|
|
134
136
|
expect(api.request).toHaveBeenCalledTimes(1);
|
|
135
137
|
});
|
|
136
138
|
|
|
137
139
|
test('handleClickSearch: should change the window location on click or return key', async () => {
|
|
138
|
-
const { getByPlaceholderText, getAllByText
|
|
140
|
+
const { getByPlaceholderText, getAllByText } = renderWithStore(
|
|
141
|
+
<ComponentToBeRendered />,
|
|
142
|
+
store
|
|
143
|
+
);
|
|
139
144
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
|
140
145
|
|
|
141
146
|
fireEvent.focus(autoCompleteInput);
|
|
@@ -143,12 +148,12 @@ describe('<Search /> component', () => {
|
|
|
143
148
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
|
144
149
|
|
|
145
150
|
const suggestionsElements = await waitFor(() => getAllByText('verdaccio', { exact: true }));
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
// console.log('suggestionsElements', suggestionsElements);
|
|
152
|
+
expect(suggestionsElements).toHaveLength(1);
|
|
148
153
|
// click on the second suggestion
|
|
149
|
-
fireEvent.click(suggestionsElements[
|
|
150
|
-
const listBoxElement =
|
|
151
|
-
// when the page redirects, the list box should be empty again
|
|
152
|
-
expect(listBoxElement
|
|
154
|
+
fireEvent.click(suggestionsElements[0]);
|
|
155
|
+
const listBoxElement = screen.queryAllByRole('listbox');
|
|
156
|
+
// // when the page redirects, the list box should be empty again
|
|
157
|
+
expect(listBoxElement).toHaveLength(0);
|
|
153
158
|
});
|
|
154
159
|
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import debounce from 'lodash/debounce';
|
|
2
|
-
import React, {
|
|
3
|
-
import { SuggestionSelectedEventData } from 'react-autosuggest';
|
|
2
|
+
import React, { useCallback } from 'react';
|
|
4
3
|
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
5
5
|
import { RouteComponentProps, withRouter } from 'react-router';
|
|
6
|
-
|
|
7
6
|
import AutoComplete from 'verdaccio-ui/components/AutoComplete';
|
|
8
|
-
import { useAPI } from 'verdaccio-ui/providers/API/APIProvider';
|
|
9
7
|
|
|
10
|
-
import
|
|
8
|
+
import { SearchResultWeb } from '@verdaccio/types';
|
|
9
|
+
|
|
10
|
+
import { Dispatch, RootState } from '../../../store/store';
|
|
11
11
|
|
|
12
12
|
const CONSTANTS = {
|
|
13
13
|
API_DELAY: 300,
|
|
@@ -16,87 +16,40 @@ const CONSTANTS = {
|
|
|
16
16
|
|
|
17
17
|
const Search: React.FC<RouteComponentProps> = ({ history }) => {
|
|
18
18
|
const { t } = useTranslation();
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const [error, setError] = useState(false);
|
|
23
|
-
const [loading, setLoading] = useState(false);
|
|
24
|
-
const mountedRef = useRef(true);
|
|
25
|
-
const [requestList, setRequestList] = useState<{ abort: () => void }[]>([]);
|
|
26
|
-
const { callSearch } = useAPI();
|
|
27
|
-
|
|
19
|
+
const { suggestions } = useSelector((state: RootState) => state.search);
|
|
20
|
+
const isLoading = useSelector((state: RootState) => state?.loading?.models.search);
|
|
21
|
+
const dispatch = useDispatch<Dispatch>();
|
|
28
22
|
/**
|
|
29
23
|
* Cancel all the requests which are in pending state.
|
|
30
24
|
*/
|
|
31
25
|
const cancelAllSearchRequests = useCallback(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}, [
|
|
26
|
+
dispatch.search.clearRequestQueue();
|
|
27
|
+
dispatch.search.saveSearch({ suggestions: [] });
|
|
28
|
+
}, [dispatch]);
|
|
35
29
|
|
|
36
30
|
/**
|
|
37
31
|
* As user focuses out from input, we cancel all the request from requestList
|
|
38
32
|
* and set the API state parameters to default boolean values.
|
|
39
33
|
*/
|
|
40
34
|
const handleOnBlur = useCallback(
|
|
41
|
-
(event:
|
|
35
|
+
(event: React.SyntheticEvent) => {
|
|
42
36
|
// stops event bubbling
|
|
43
37
|
event.stopPropagation();
|
|
44
|
-
setLoaded(false);
|
|
45
|
-
setLoading(false);
|
|
46
|
-
setError(false);
|
|
47
38
|
cancelAllSearchRequests();
|
|
48
39
|
},
|
|
49
|
-
[setLoaded, setLoading, cancelAllSearchRequests, setError]
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* onChange method for the input element.
|
|
54
|
-
*/
|
|
55
|
-
const handleSearch = useCallback(
|
|
56
|
-
(event: FormEvent<HTMLInputElement>, { newValue, method }) => {
|
|
57
|
-
// stops event bubbling
|
|
58
|
-
event.stopPropagation();
|
|
59
|
-
if (method === 'type') {
|
|
60
|
-
const value = newValue.trim();
|
|
61
|
-
|
|
62
|
-
setLoading(true);
|
|
63
|
-
setError(false);
|
|
64
|
-
setSearch(value);
|
|
65
|
-
setLoaded(false);
|
|
66
|
-
/**
|
|
67
|
-
* A use case where User keeps adding and removing value in input field,
|
|
68
|
-
* so we cancel all the existing requests when input is empty.
|
|
69
|
-
*/
|
|
70
|
-
if (value?.length === 0) {
|
|
71
|
-
cancelAllSearchRequests();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
40
|
[cancelAllSearchRequests]
|
|
76
41
|
);
|
|
77
42
|
|
|
78
|
-
/**
|
|
79
|
-
* Cancel all the request from list and make request list empty.
|
|
80
|
-
*/
|
|
81
|
-
const handlePackagesClearRequested = useCallback(() => {
|
|
82
|
-
setSuggestions([]);
|
|
83
|
-
}, [setSuggestions]);
|
|
84
|
-
|
|
85
43
|
/**
|
|
86
44
|
* When an user select any package by clicking or pressing return key.
|
|
87
45
|
*/
|
|
88
46
|
const handleClickSearch = useCallback(
|
|
89
|
-
(
|
|
90
|
-
event: FormEvent<HTMLInputElement>,
|
|
91
|
-
{ suggestionValue, method }: SuggestionSelectedEventData<unknown>
|
|
92
|
-
): void | undefined => {
|
|
47
|
+
(event: React.SyntheticEvent, value: SearchResultWeb, reason: string): void => {
|
|
93
48
|
// stops event bubbling
|
|
94
49
|
event.stopPropagation();
|
|
95
|
-
switch (
|
|
96
|
-
case '
|
|
97
|
-
|
|
98
|
-
setSearch('');
|
|
99
|
-
history.push(`/-/web/detail/${suggestionValue}`);
|
|
50
|
+
switch (reason) {
|
|
51
|
+
case 'selectOption':
|
|
52
|
+
history.push(`/-/web/detail/${value.name}`);
|
|
100
53
|
break;
|
|
101
54
|
}
|
|
102
55
|
},
|
|
@@ -108,60 +61,22 @@ const Search: React.FC<RouteComponentProps> = ({ history }) => {
|
|
|
108
61
|
* For AbortController see: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
|
|
109
62
|
*/
|
|
110
63
|
const handleFetchPackages = useCallback(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const signal = controller.signal;
|
|
115
|
-
if (!mountedRef.current) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
// Keep track of search requests.
|
|
119
|
-
setRequestList([...requestList, controller]);
|
|
120
|
-
const suggestions = await callSearch(value, signal);
|
|
121
|
-
// FIXME: Argument of type 'unknown' is not assignable to parameter of type 'SetStateAction<never[]>'
|
|
122
|
-
setSuggestions(suggestions as any);
|
|
123
|
-
setLoaded(true);
|
|
124
|
-
} catch (error: any) {
|
|
125
|
-
/**
|
|
126
|
-
* AbortError is not the API error.
|
|
127
|
-
* It means browser has cancelled the API request.
|
|
128
|
-
*/
|
|
129
|
-
if (error.name === CONSTANTS.ABORT_ERROR) {
|
|
130
|
-
setError(false);
|
|
131
|
-
setLoaded(false);
|
|
132
|
-
} else {
|
|
133
|
-
setError(true);
|
|
134
|
-
setLoaded(false);
|
|
135
|
-
}
|
|
136
|
-
} finally {
|
|
137
|
-
if (mountedRef.current) {
|
|
138
|
-
setLoading(false);
|
|
139
|
-
}
|
|
64
|
+
({ value }: { value: string }) => {
|
|
65
|
+
if (value?.trim() !== '') {
|
|
66
|
+
dispatch.search.getSuggestions({ value });
|
|
140
67
|
}
|
|
141
68
|
},
|
|
142
|
-
[
|
|
69
|
+
[dispatch]
|
|
143
70
|
);
|
|
144
71
|
|
|
145
|
-
useEffect(() => {
|
|
146
|
-
return () => {
|
|
147
|
-
mountedRef.current = false;
|
|
148
|
-
};
|
|
149
|
-
}, []);
|
|
150
|
-
|
|
151
72
|
return (
|
|
152
73
|
<AutoComplete
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
onCleanSuggestions={handlePackagesClearRequested}
|
|
156
|
-
onClick={handleClickSearch}
|
|
74
|
+
onCleanSuggestions={handleOnBlur}
|
|
75
|
+
onSelectItem={handleClickSearch}
|
|
157
76
|
onSuggestionsFetch={debounce(handleFetchPackages, CONSTANTS.API_DELAY)}
|
|
158
77
|
placeholder={t('search.packages')}
|
|
159
|
-
startAdornment={<SearchAdornment />}
|
|
160
78
|
suggestions={suggestions}
|
|
161
|
-
|
|
162
|
-
suggestionsLoaded={loaded}
|
|
163
|
-
suggestionsLoading={loading}
|
|
164
|
-
value={search}
|
|
79
|
+
suggestionsLoading={isLoading}
|
|
165
80
|
/>
|
|
166
81
|
);
|
|
167
82
|
};
|