Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ij 337 Fix release bugs reported by users #234

Merged
merged 18 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading