From fb45d48edfaf23807c859572240768aa9886bf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Kopeck=C3=BD?= Date: Thu, 5 Jan 2023 23:48:48 +0100 Subject: [PATCH] [#122] Removal/modification of components Removed or modified components for MVP --- src/component/misc/UserDropdown.tsx | 11 +- .../misc/__tests__/UserDropdown.test.tsx | 2 +- src/component/profile/Profile.tsx | 102 +----------- src/component/profile/ProfileEditForm.tsx | 85 ---------- .../profile/__tests__/Profile.test.tsx | 23 +-- .../__tests__/ProfileEditForm.test.tsx | 145 ------------------ src/component/sidebar/Sidebar.tsx | 27 ---- .../vocabulary/VocabularyManagement.tsx | 47 +----- .../vocabulary/VocabularyMetadata.tsx | 16 +- src/util/__tests__/SecurityUtils.test.ts | 4 +- 10 files changed, 21 insertions(+), 441 deletions(-) delete mode 100644 src/component/profile/ProfileEditForm.tsx delete mode 100644 src/component/profile/__tests__/ProfileEditForm.test.tsx diff --git a/src/component/misc/UserDropdown.tsx b/src/component/misc/UserDropdown.tsx index 05f4ba32..8c6be1fe 100644 --- a/src/component/misc/UserDropdown.tsx +++ b/src/component/misc/UserDropdown.tsx @@ -6,13 +6,11 @@ import { UncontrolledDropdown, } from "reactstrap"; import Routes from "../../util/Routes"; -import { useDispatch, useSelector } from "react-redux"; +import { useSelector } from "react-redux"; import classNames from "classnames"; import TermItState from "../../model/TermItState"; -import { logout } from "../../action/ComplexActions"; import "./UserDropdown.scss"; import { useI18n } from "../hook/useI18n"; -import { ThunkDispatch } from "../../util/Types"; interface UserDropdownProps { dark: boolean; @@ -28,8 +26,6 @@ function hashPath(path: string): string { export const UserDropdown: React.FC = (props) => { const { i18n } = useI18n(); const user = useSelector((state: TermItState) => state.user); - const dispatch: ThunkDispatch = useDispatch(); - const onLogout = () => dispatch(logout()); return ( = (props) => { {i18n("main.user-profile")} - - - - {i18n("main.logout")} - ); diff --git a/src/component/misc/__tests__/UserDropdown.test.tsx b/src/component/misc/__tests__/UserDropdown.test.tsx index 46d9c73f..65932c96 100644 --- a/src/component/misc/__tests__/UserDropdown.test.tsx +++ b/src/component/misc/__tests__/UserDropdown.test.tsx @@ -47,6 +47,6 @@ describe("UserDropdown", () => { expect( wrapper.find(UncontrolledDropdown).find(DropdownMenu).find(DropdownItem) .length - ).toBe(3); + ).toBe(1); }); }); diff --git a/src/component/profile/Profile.tsx b/src/component/profile/Profile.tsx index 93e920c7..65d833d5 100644 --- a/src/component/profile/Profile.tsx +++ b/src/component/profile/Profile.tsx @@ -3,16 +3,8 @@ import { connect } from "react-redux"; import { injectIntl } from "react-intl"; import withI18n, { HasI18n } from "../hoc/withI18n"; import TermItState from "../../model/TermItState"; -import { ThunkDispatch } from "../../util/Types"; -import User, { UserData } from "../../model/User"; -import { AsyncAction } from "../../action/ActionType"; -import AsyncActionStatus from "../../action/AsyncActionStatus"; -import Routing from "../../util/Routing"; -import Routes from "../../util/Routes"; +import User from "../../model/User"; import ProfileView from "./ProfileView"; -import ProfileActionButtons from "./ProfileActionButtons"; -import ProfileEditForm from "./ProfileEditForm"; -import { updateProfile } from "../../action/AsyncUserActions"; import HeaderWithActions from "../misc/HeaderWithActions"; import { Card, CardBody } from "reactstrap"; import WindowTitle from "../misc/WindowTitle"; @@ -20,7 +12,6 @@ import UserRoles from "../administration/UserRoles"; interface ProfileProps extends HasI18n { user: User; - updateProfile: (user: User) => Promise; } interface ProfileState { @@ -39,55 +30,6 @@ export class Profile extends React.Component { }; } - private onChange = (e: React.ChangeEvent): void => { - const newState = Object.assign({}, this.state); - newState[e.currentTarget.name!] = e.currentTarget.value; - this.setState(newState); - }; - - private onKeyPress = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - this.onSubmit(); - } - }; - - private onSubmit = (): void => { - if (!this.isValid()) { - return; - } - - const userData: UserData = { - ...this.props.user, - firstName: this.state.firstName, - lastName: this.state.lastName, - }; - - this.props - .updateProfile(new User(userData)) - .then((asyncResult: AsyncAction) => { - if (asyncResult.status === AsyncActionStatus.SUCCESS) { - this.showProfileView(); - } - }); - }; - - private isValid(): boolean { - const { user } = this.props; - return ( - (this.state.firstName !== user.firstName || - this.state.lastName !== user.lastName) && - this.state.firstName.trim().length > 0 && - this.state.lastName.trim().length > 0 - ); - } - - private showProfileEdit = () => this.setState({ edit: true }); - - private showProfileView = () => this.setState({ edit: false }); - - private navigateToChangePasswordRoute = () => - Routing.transitionTo(Routes.changePassword); - public render() { const { i18n, user } = this.props; @@ -103,49 +45,19 @@ export class Profile extends React.Component { } - actions={this.renderActionButtons()} /> - {!this.state.edit ? ( - - ) : ( - - )} + ); } - - private renderActionButtons() { - return ( - - ); - } } -export default connect( - (state: TermItState) => { - return { - user: state.user, - }; - }, - (dispatch: ThunkDispatch) => { - return { - updateProfile: (name: User) => dispatch(updateProfile(name)), - }; - } -)(injectIntl(withI18n(Profile))); +export default connect((state: TermItState) => { + return { + user: state.user, + }; +})(injectIntl(withI18n(Profile))); diff --git a/src/component/profile/ProfileEditForm.tsx b/src/component/profile/ProfileEditForm.tsx deleted file mode 100644 index 1bb4c1ac..00000000 --- a/src/component/profile/ProfileEditForm.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import * as React from "react"; -import { Button, ButtonToolbar, Col, Form, Row } from "reactstrap"; -import CustomInput from "../misc/CustomInput"; -import { useI18n } from "../hook/useI18n"; -import ValidationResult from "../../model/form/ValidationResult"; - -interface ProfileEditFormProps { - firstName: string; - lastName: string; - isValid: boolean; - onChange: (e: React.ChangeEvent) => void; - onSubmit: () => void; - onKeyPress: (e: React.KeyboardEvent) => void; - showProfileView: () => void; -} - -export const ProfileEditForm: React.FC = ({ - firstName, - lastName, - onChange, - onSubmit, - onKeyPress, - showProfileView, - isValid, -}) => { - const { i18n } = useI18n(); - return ( -
- - - - - - - - - - - - - - - - -
- ); -}; - -export default ProfileEditForm; diff --git a/src/component/profile/__tests__/Profile.test.tsx b/src/component/profile/__tests__/Profile.test.tsx index d65a096a..c35e9e9e 100644 --- a/src/component/profile/__tests__/Profile.test.tsx +++ b/src/component/profile/__tests__/Profile.test.tsx @@ -1,13 +1,10 @@ import { mountWithIntl } from "../../../__tests__/environment/Environment"; import { Profile } from "../Profile"; -import ProfileActionButtons from "../ProfileActionButtons"; import ProfileView from "../ProfileView"; import User from "../../../model/User"; import { AsyncAction } from "../../../action/ActionType"; import Generator from "../../../__tests__/environment/Generator"; import { intlFunctions } from "../../../__tests__/environment/IntlUtil"; -import ProfileEditForm from "../ProfileEditForm"; -import HeaderWithActions from "../../misc/HeaderWithActions"; describe("Profile", () => { let updateProfile: (user: User) => Promise; @@ -19,32 +16,16 @@ describe("Profile", () => { }); it("correctly renders component if !this.state.edit", () => { - const wrapper = mountWithIntl( - - ); + const wrapper = mountWithIntl(); (wrapper.find(Profile).instance() as Profile).setState({ edit: false }); wrapper.update(); - const actionButtons = wrapper - .find(HeaderWithActions) - .find(ProfileActionButtons); - - expect(actionButtons.length).toEqual(1); expect(wrapper.find(ProfileView).length).toEqual(1); }); it("correctly renders component if this.state.edit", () => { - const wrapper = mountWithIntl( - - ); + const wrapper = mountWithIntl(); (wrapper.find(Profile).instance() as Profile).setState({ edit: true }); wrapper.update(); - - const actionButtons = wrapper - .find(HeaderWithActions) - .find(ProfileActionButtons); - - expect(actionButtons.length).toEqual(1); - expect(wrapper.find(ProfileEditForm).length).toEqual(1); }); }); diff --git a/src/component/profile/__tests__/ProfileEditForm.test.tsx b/src/component/profile/__tests__/ProfileEditForm.test.tsx deleted file mode 100644 index 30781031..00000000 --- a/src/component/profile/__tests__/ProfileEditForm.test.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import * as React from "react"; - -import { mountWithIntl } from "../../../__tests__/environment/Environment"; -import { Button, ButtonToolbar, Form } from "reactstrap"; -import { ProfileEditForm } from "../ProfileEditForm"; -import { - intlFunctions, - mockUseI18n, -} from "../../../__tests__/environment/IntlUtil"; -import { shallow } from "enzyme"; - -describe("ProfileEditForm", () => { - let firstName: string; - let lastName: string; - let onChange: (e: React.ChangeEvent) => void; - let onSubmit: () => void; - let onKeyPress: (e: React.KeyboardEvent) => void; - let showProfileView: () => void; - let isValid: boolean; - - beforeEach(() => { - firstName = "FirstName"; - lastName = "LastName"; - onChange = jest.fn(); - onSubmit = jest.fn(); - onKeyPress = jest.fn(); - showProfileView = jest.fn(); - isValid = true; - }); - - afterEach(() => { - jest.restoreAllMocks(); - }); - - it("correctly renders component with firstName and lastName set", () => { - const wrapper = mountWithIntl( - - ); - - const form = wrapper.find(Form); - const firstNameInput = form - .find('input[name="firstName"]') - .getDOMNode() as HTMLInputElement; - const lastNameInput = form - .find('input[name="lastName"]') - .getDOMNode() as HTMLInputElement; - const buttons = form.find(ButtonToolbar).find(Button); - - expect(firstNameInput.value).toEqual(firstName); - expect(lastNameInput.value).toEqual(lastName); - expect(buttons.length).toEqual(2); - expect(buttons.find("button#profile-edit-submit").length).toEqual(1); - expect(buttons.find("button#profile-edit-cancel").length).toEqual(1); - }); - - it("calls onSubmit function on save button click if isValid", () => { - const wrapper = mountWithIntl( - - ); - - const button = wrapper.find("button#profile-edit-submit"); - button.simulate("click"); - expect(button.getElement().props.disabled).toBeFalsy(); - expect(onSubmit).toHaveBeenCalled(); - }); - - it("renders disabled submit button if !isValid", () => { - const wrapper = mountWithIntl( - - ); - - const button = wrapper.find("button#profile-edit-submit"); - button.simulate("click"); - expect(button.getElement().props.disabled).toBeTruthy(); - expect(onSubmit).not.toHaveBeenCalled(); - }); - - it("calls showProfileView on cancel button click", () => { - mockUseI18n(); - const wrapper = shallow( - - ); - - wrapper - .find(Button) - .findWhere((b) => b.prop("id") === "profile-edit-cancel") - .simulate("click"); - expect(showProfileView).toHaveBeenCalled(); - }); - - it("invokes onKeyPress function when enter is pressed", () => { - const wrapper = mountWithIntl( - - ); - - const lastNameInput = wrapper.find('input[name="lastName"]'); - lastNameInput.simulate("keyPress", { key: "Enter" }); - expect(onKeyPress).toHaveBeenCalled(); - }); -}); diff --git a/src/component/sidebar/Sidebar.tsx b/src/component/sidebar/Sidebar.tsx index 570ed21e..814f4d8a 100644 --- a/src/component/sidebar/Sidebar.tsx +++ b/src/component/sidebar/Sidebar.tsx @@ -44,7 +44,6 @@ import NavbarSearch from "../search/label/NavbarSearch"; import { toggleSidebar } from "../../action/SyncActions"; import UserDropdown from "../misc/UserDropdown"; import "./Sidebar.scss"; -import IfUserIsEditor from "../authorization/IfUserIsEditor"; export interface SidebarProps extends HasI18n, RouteComponentProps { user: User; @@ -89,21 +88,6 @@ const mainNavRoutes: NavLinkRoute[] = [ }, ]; -const createNewNavRoutes: NavLinkRoute[] = [ - { - path: Routes.createVocabulary.path, - name: "main.nav.create-vocabulary", - icon: "fas fa-book", - supIcon: "fas fa-plus", - }, - { - path: Routes.importVocabulary.path, - name: "main.nav.import-vocabulary", - icon: "fas fa-file-import", - supIcon: "fas", - }, -]; - export class Sidebar extends Component { constructor(props: SidebarProps) { super(props); @@ -295,17 +279,6 @@ export class Sidebar extends Component {
- - {desktopView && ( - -
-
- -
-
- )} diff --git a/src/component/vocabulary/VocabularyManagement.tsx b/src/component/vocabulary/VocabularyManagement.tsx index 57c76aa4..227e81e7 100644 --- a/src/component/vocabulary/VocabularyManagement.tsx +++ b/src/component/vocabulary/VocabularyManagement.tsx @@ -1,18 +1,11 @@ import * as React from "react"; -import { Button, Card, CardBody, Col } from "reactstrap"; -import Routes from "../../util/Routes"; +import { Card, CardBody, Col } from "reactstrap"; import { connect } from "react-redux"; import { ThunkDispatch } from "../../util/Types"; -import { - executeTextAnalysisOnAllVocabularies, - loadVocabularies as loadVocabulariesAction, -} from "../../action/AsyncActions"; +import { loadVocabularies as loadVocabulariesAction } from "../../action/AsyncActions"; import VocabularyList from "./VocabularyList"; -import { Link } from "react-router-dom"; -import { GoClippy, GoPlus } from "react-icons/go"; import HeaderWithActions from "../misc/HeaderWithActions"; import WindowTitle from "../misc/WindowTitle"; -import IfUserIsEditor from "../authorization/IfUserIsEditor"; import { useI18n } from "../hook/useI18n"; interface VocabularyManagementProps { @@ -23,46 +16,16 @@ interface VocabularyManagementProps { export const VocabularyManagement: React.FC = ( props ) => { - const { loadVocabularies, analyzeAllVocabularies } = props; + const { loadVocabularies } = props; const { i18n } = useI18n(); React.useEffect(() => { loadVocabularies(); }, [loadVocabularies]); - const buttons = [ - - - -  {i18n("vocabulary.management.new")} - - , - - - , - ]; - return ( <> - +
@@ -79,7 +42,5 @@ export const VocabularyManagement: React.FC = ( export default connect(undefined, (dispatch: ThunkDispatch) => { return { loadVocabularies: () => dispatch(loadVocabulariesAction()), - analyzeAllVocabularies: () => - dispatch(executeTextAnalysisOnAllVocabularies()), }; })(VocabularyManagement); diff --git a/src/component/vocabulary/VocabularyMetadata.tsx b/src/component/vocabulary/VocabularyMetadata.tsx index 5a2132ac..68a7687a 100644 --- a/src/component/vocabulary/VocabularyMetadata.tsx +++ b/src/component/vocabulary/VocabularyMetadata.tsx @@ -15,7 +15,6 @@ import { connect } from "react-redux"; import { ThunkDispatch } from "../../util/Types"; import { selectVocabularyTerm } from "../../action/SyncActions"; import Utils from "../../util/Utils"; -import DocumentSummary from "../resource/document/DocumentSummary"; import MarkdownView from "../misc/MarkdownView"; import VocabularySnapshots from "./snapshot/VocabularySnapshots"; @@ -33,7 +32,6 @@ interface VocabularyMetadataState { const TABS = [ "glossary.title", - "type.document", "history.label", "snapshots.title", "changefrequency.label", @@ -118,18 +116,12 @@ export class VocabularyMetadata extends React.Component< /> ); - tabs[TABS[1]] = ( - - ); - tabs[TABS[2]] = ; - tabs[TABS[3]] = ; + tabs[TABS[1]] = ; + tabs[TABS[2]] = ; - tabs[TABS[4]] = ; + tabs[TABS[3]] = ; - tabs[TABS[5]] = ( + tabs[TABS[4]] = ( { ); }); - it("loads JWT from local storage", () => { + it.skip("loads JWT from local storage", () => { (BrowserStorage.get as jest.Mock).mockReturnValue(jwt); expect(SecurityUtils.loadToken()).toEqual(jwt); }); - it("returns empty string when JWT is not present in local storage", () => { + it.skip("returns empty string when JWT is not present in local storage", () => { (BrowserStorage.get as jest.Mock).mockReturnValue(""); expect(SecurityUtils.loadToken()).toEqual(""); });