Skip to content

Commit

Permalink
Ij 337 Fix release bugs reported by users (#234)
Browse files Browse the repository at this point in the history
* IJ-337 swat to vite

* IJ-337 disable TEMPORARY few lint rules

* IJ-337 Swap to vitest

* IJ-337 Swap to vitest

* IJ-337 Upgrate tests

* IJ-337 Cleanup

* IJ-337 Change tests file extensions to *.jsx

* IJ-337 Bump required Node.js version to v16.*

* IJ-337 Remove `.only`

* Fix vulnerabilities

* Update the build destination directory to meet CRA scheme

* Change dist directory to build

* Update java security whitelist to allow access to /assets and /icons

* Update sidebard component styling to open/close properly with width adjustment, center calendars, change time registration component styling

* UI Bugfixes: missing remaining vacations & pending days, time picker location, select boxes height for multiselection

* Remvoe console logs

* Cleanup: remove unused pieces of code, update tests due to a provider level change

---------

Co-authored-by: Maciej Roszkiewicz <[email protected]>
Co-authored-by: Kamil Matuszewski <[email protected]>
  • Loading branch information
3 people authored Jan 11, 2024
1 parent 84c6d80 commit 2485fe2
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ export const DashboardCalendar = () => {
valueContainer: (provided, state) => ({
...provided,
padding: '0',
height: "20px"
}),
input: (provided, state) => ({
...provided,
Expand All @@ -162,7 +161,6 @@ export const DashboardCalendar = () => {
}),
indicatorsContainer: (provided, state) => ({
...provided,
height: '20px',
}),
dropdownIndicator: base => ({
...base,
Expand Down
30 changes: 6 additions & 24 deletions view.react/src/components/main/Main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,9 @@ import {Sidebar} from "../sidebar/Sidebar";
import {TopBar} from "../topbar/TopBar";
import styles from './Main.module.scss';
export const Main = () => {


const [, setUser] = useState({isLeader: false, isAdmin: false})
const {isLeader: isUserALeader} = getCurrentUser();

const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const [acceptancesPresent, setAcceptancesPresent] = useState(false);

const [, appInfoDispatch] = useAppInfo()

useEffect(() => {
Expand All @@ -41,32 +36,19 @@ export const Main = () => {
})
}, []);


useEffect(() => {
fetchAppInfo(appInfoDispatch)
}, [appInfoDispatch])

const handleHamburgerClick = () => {
setIsSidebarOpen(!isSidebarOpen);
}

const handleClickOutsideSidebar = () => {
setIsSidebarOpen(false);
}
const sidebarColClass = classNames('m-0', 'p-0', {'d-none d-lg-block': !isSidebarOpen});

return (
<UserPreferencesProvider>
<TopBar onHamburgerClick={handleHamburgerClick}/>
<Container fluid>
<VacationDaysProvider>
<VacationDaysProvider>
<TopBar />
<Container fluid>
<UsersVacationsProvider>
<Row>
<Col xs={12} lg={12} xl={12} className='d-flex'>
<Sidebar
onClickLinkOrOutside={handleClickOutsideSidebar}
acceptancesPresent={acceptancesPresent}
/>
<Sidebar acceptancesPresent={acceptancesPresent} />
<RequestProvider>
{isUserALeader &&
<AcceptanceLoader setAcceptancesPresent={setAcceptancesPresent}/>}
Expand All @@ -77,8 +59,8 @@ export const Main = () => {
</Col>
</Row>
</UsersVacationsProvider>
</VacationDaysProvider>
</Container>
</Container>
</VacationDaysProvider>
</UserPreferencesProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
}

.dateTimePickerInput {
margin-top: -10px;
width: 8rem;
height: 44px;
background-color: #F2EFEA;
Expand Down
23 changes: 8 additions & 15 deletions view.react/src/components/sidebar/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import WorkHistoryOutlinedIcon from '@mui/icons-material/WorkHistoryOutlined';
import classNames from "classnames";
import PropTypes from 'prop-types';
import {useState} from "react";
import {Container, Nav} from 'react-bootstrap';
import {Nav} from 'react-bootstrap';

import {getCurrentUser} from "../../api/services/session.service";
import {useAppInfo} from "../../contexts/app-info-context/appInfoContext";
import {AttentionIcon, TextWithIcon} from "../../helpers/icons/Icons";
import {Link} from "./link/Link";
import styles from './Sidebar.module.scss';

export const Sidebar = ({onClickLinkOrOutside, acceptancesPresent}) => {
export const Sidebar = ({acceptancesPresent}) => {
const {isAdmin: isUserAnAdmin, isLeader: isUserALeader} = getCurrentUser();
const {ec: isUserEC} = getCurrentUser();
const overlayClass = classNames(styles.overlay, 'd-lg-none');
Expand All @@ -42,7 +42,6 @@ export const Sidebar = ({onClickLinkOrOutside, acceptancesPresent}) => {
</button>
<Link
testId="CalendarLink"
onClick={onClickLinkOrOutside}
exact
activeClassName="active"
to="/calendar"
Expand All @@ -52,7 +51,6 @@ export const Sidebar = ({onClickLinkOrOutside, acceptancesPresent}) => {
</Link>
<Link
testId="RequestsLink"
onClick={onClickLinkOrOutside}
exact
activeClassName="active"
to="/requests"
Expand All @@ -66,7 +64,6 @@ export const Sidebar = ({onClickLinkOrOutside, acceptancesPresent}) => {
</Link>
<Link
testId="UsersHistoryLink"
onClick={onClickLinkOrOutside}
exact
activeClassName="active"
to="/history"
Expand All @@ -75,30 +72,30 @@ export const Sidebar = ({onClickLinkOrOutside, acceptancesPresent}) => {
<span>Historia użytkownika</span>
</Link>
{isUserALeader &&
<Link to="/acceptances/history" onClick={onClickLinkOrOutside}>
<Link to="/acceptances/history">
<WorkHistoryOutlinedIcon />
<span>Historia akceptacji</span>
</Link>
}
{isUserAnAdmin && (
<>
<Link to="/associates" onClick={onClickLinkOrOutside} testId="ContractorsLink">
<Link to="/associates" testId="ContractorsLink">
<PeopleOutlineRoundedIcon />
<span>Współpracownicy</span>
</Link>
<Link to="/workers" onClick={onClickLinkOrOutside} testId="EmployeesLink">
<Link to="/workers" testId="EmployeesLink">
<GroupAddOutlinedIcon />
<span>Pracownicy</span>
</Link>
<Link to="/holidays" onClick={onClickLinkOrOutside} testId="HolidaysLink">
<Link to="/holidays" testId="HolidaysLink">
<EventAvailableOutlinedIcon />
<span>Dni świąteczne</span>
</Link>
<Link to="/reports" onClick={onClickLinkOrOutside} testId="ReportsLink">
<Link to="/reports" testId="ReportsLink">
<BarChartOutlinedIcon />
<span>Raporty</span>
</Link>
<Link to="/automaticVacationDays" onClick={onClickLinkOrOutside}>
<Link to="/automaticVacationDays">
<EventRepeatOutlinedIcon />
<span>Dni na nowy rok</span>
</Link>
Expand All @@ -109,18 +106,14 @@ export const Sidebar = ({onClickLinkOrOutside, acceptancesPresent}) => {
<div className={styles.versionContainer}>
{`${version} ${commitId}`}
</div>
<div className={overlayClass}
onClick={onClickLinkOrOutside}/>
</>
);
}

Sidebar.propTypes = {
onClickLinkOrOutside: PropTypes.func,
newAcceptancesPresent: PropTypes.bool
}

Sidebar.defaultProps = {
onClickLinkOrOutside: () => null,
newAcceptancesPresent: false
}
27 changes: 3 additions & 24 deletions view.react/src/components/topbar/TopBar.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import classNames from "classnames";
import PropTypes from 'prop-types';
import {useEffect, useState} from "react";
import {Container, Navbar} from 'react-bootstrap';
import {GearFill as GearIcon, List as ListIcon, Power as PowerIcon} from "react-bootstrap-icons";
Expand All @@ -15,7 +13,7 @@ import { NoAuthUsersDropdown } from "./noauth-users-dropdown/NoAuthUsersDropdown
import {TeamDropdown} from "./team-dropdown/TeamDropdown";
import styles from './TopBar.module.scss';

export const TopBar = ({onHamburgerClick}) => {
export const TopBar = () => {
const userName = getFullUserName();
const teams = getUserTeams();

Expand All @@ -27,14 +25,9 @@ export const TopBar = ({onHamburgerClick}) => {
fetchWorkingHoursPreferences(userPreferencesDispatch)
}, [userPreferencesDispatch])

const handleLogout = () => {
logout()
}

const handleLogout = () => logout();
const isNoAuth = isNoAuthMode();

const listBtnClass = classNames('d-lg-none', styles.button);
const listIconClass = classNames(styles.hamburger, styles.icon);
return (
<>
<PreferencesModal
Expand All @@ -45,23 +38,13 @@ export const TopBar = ({onHamburgerClick}) => {
/>
<Navbar className={styles.topBar} variant="dark" expand="lg" collapseOnSelect sticky='top'>
<Container fluid className='px-0'>
<button
type="button"
className={listBtnClass}
onClick={onHamburgerClick}
>
<ListIcon className={listIconClass}/>
</button>

<Navbar.Brand href='/#/calendar' className="d-none d-lg-block">
<img src={logoImg} alt="FINGO logo" className={styles.brandLogo}/>
</Navbar.Brand>

<img src={UrlopiaLogo} alt={"Urlopia"} className={styles.appLogo}/>
<div className={styles.mobileRightSide}>
{
isNoAuth && <NoAuthUsersDropdown />
}
{isNoAuth && <NoAuthUsersDropdown />}
<button type="button" className={styles.settingsButton} onClick={() => setShowModal(true)}>
<GearIcon className={styles.settingsIcon} size={20}/>
</button>
Expand All @@ -75,7 +58,3 @@ export const TopBar = ({onHamburgerClick}) => {
</>
);
}

TopBar.propTypes = {
onHamburgerClick: PropTypes.func.isRequired,
}
3 changes: 2 additions & 1 deletion view.react/src/components/topbar/TopBar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
}

.appLogo {
margin-left: 20px;
filter: brightness(0) invert(1);
height: 40px;
}
}
15 changes: 8 additions & 7 deletions view.react/src/components/topbar/TopBar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {UserPreferencesProvider} from "../../contexts/user-preferences-context/u
import {mockLocalStorage} from "../../helpers/TestHelper";
import {TopBar} from "./TopBar";
import {vi} from "vitest";
import {VacationDaysProvider} from "../../contexts/vacation-days-context/vacationDaysContext";


vi.mock("../../contexts/user-preferences-context/actions/fetchWorkingHoursPreferences", async () => {
const originalModule = await vi.importActual("../../contexts/user-preferences-context/actions/fetchWorkingHoursPreferences");
Expand Down Expand Up @@ -35,28 +37,27 @@ describe("TopBar", () => {
})

it('should show logo',() => {
render(<Router><UserPreferencesProvider><TopBar onHamburgerClick={() => null}/></UserPreferencesProvider></Router>);
render(<Router><UserPreferencesProvider><VacationDaysProvider><TopBar /></VacationDaysProvider></UserPreferencesProvider></Router>);
const displayedImage = document.querySelector("img");
expect((displayedImage.src)).toContain('logo.svg');
});

it('should show correct user name', () => {
render(<UserPreferencesProvider><TopBar onHamburgerClick={() => null}/></UserPreferencesProvider>);
const userName = screen.getByText(sampleFullName);
render(<UserPreferencesProvider><VacationDaysProvider><TopBar /></VacationDaysProvider></UserPreferencesProvider>);
const userName = screen.getByText(sampleFullName, { exact: false });
expect(userName).toBeInTheDocument();
});

it('should show teams dropdown after clicking on user name', async () => {
render(<UserPreferencesProvider><TopBar onHamburgerClick={() => null}/></UserPreferencesProvider>);

const userNameLabel = screen.getByText(sampleFullName);
render(<UserPreferencesProvider><VacationDaysProvider><TopBar /></VacationDaysProvider></UserPreferencesProvider>);
const userNameLabel = screen.getByText(sampleFullName, { exact: false });
expect(userNameLabel).toBeInTheDocument();

await act(async () => {
fireEvent.click(userNameLabel);
});
const teamName = screen.getByText(sampleTeams[0].name, { exact: false });

const teamName = screen.getByText(sampleTeams[0].name);
const teamLeader = screen.getByText(`Lider: ${sampleTeams[0].leader}`);

expect(teamName).toBeInTheDocument();
Expand Down
49 changes: 46 additions & 3 deletions view.react/src/components/topbar/team-dropdown/TeamDropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,63 @@
import PropTypes from 'prop-types';
import {Dropdown} from 'react-bootstrap';
import {PersonCircle} from "react-bootstrap-icons";
import {useState, useEffect} from "react";

import styles from './TeamDropdown.module.scss';
import {useVacationDays} from "../../../contexts/vacation-days-context/vacationDaysContext";
import {fetchPendingDays} from "../../../contexts/vacation-days-context/actions/fetchPendingDays";
import {fetchVacationDays} from "../../../contexts/vacation-days-context/actions/fetchVacationDays";
import {formatHoursToDays} from "../../../helpers/RemainingDaysFormatterHelper";

export const TeamDropdown = ({
userName,
teams,
}) => {
return (

const [vacationDays, setVacationDays] = useState(0);
const [vacationHours, setVacationHours] = useState(0);
const [pendingDays, setPendingDays] = useState(0);
const [pendingHours, setPendingHours] = useState(0);
const [workTime, setWorkTime] = useState(8);

const [vacationDaysState, vacationDaysDispatch] = useVacationDays();

useEffect(() => {
fetchPendingDays(vacationDaysDispatch);
}, [vacationDaysDispatch]);

useEffect(() => {
fetchVacationDays(vacationDaysDispatch);
}, [vacationDaysDispatch]);

useEffect(() => {
const {pendingDays, pendingHours} = vacationDaysState.pendingDays;
setPendingDays(pendingDays);
setPendingHours(pendingHours);
}, [vacationDaysState.pendingDays]);

useEffect(() => {
const {remainingDays, remainingHours, workTime} = vacationDaysState.vacationDays;
setVacationDays(remainingDays);
setVacationHours(remainingHours);
setWorkTime(workTime);
}, [vacationDaysState.vacationDays]);

const remainingDays = vacationDays - pendingDays
const remainingHours = vacationHours - pendingHours
const remainingHoursAsDays = formatHoursToDays(remainingHours/workTime)

return (
<Dropdown align="end">
<Dropdown.Toggle className={styles.dropdown} bsPrefix="p-0" variant="link">
<span>
<PersonCircle className={styles.icon}/>
</span>
<p className="d-none d-lg-flex">{userName}</p>
<p className="d-none d-lg-flex">
{userName}
({workTime === 8 ? <span><strong>{remainingDays}d</strong> {remainingHours}h</span> :
<strong>{remainingHours}h ({remainingHoursAsDays}d)</strong>})
</p>
</Dropdown.Toggle>

<Dropdown.Menu>
Expand Down Expand Up @@ -48,4 +91,4 @@ TeamDropdown.propTypes = {
name: PropTypes.string,
leader: PropTypes.string,
})).isRequired,
}
}
Loading

0 comments on commit 2485fe2

Please sign in to comment.