Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Fixes and improvements #59

Merged
merged 6 commits into from
Jul 2, 2021
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
5 changes: 5 additions & 0 deletions src/assets/images/icon-checkmark-circled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/components/Content/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
padding: 0 10px;

@include desktop {
flex: 1 1 auto;
flex: 1 1 0;
padding: 0 35px;
min-width: 0;
}
}
61 changes: 61 additions & 0 deletions src/components/Icons/CheckmarkCircled/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useEffect, useState } from "react";
import PT from "prop-types";
import cn from "classnames";
import Icon from "../../../assets/images/icon-checkmark-circled.svg";
import styles from "./styles.module.scss";

/**
* Displays an animated checkmark inside circle. After the specified timeout
* the checkmark is faded out and after fade transition ends the onTimeout
* is called.
*
* @param {Object} props component properties
* @param {string} [props.className] class name to be added to root element
* @param {() => void} props.onTimeout
* @param {number} props.timeout timeout milliseconds
* @returns {JSX.Element}
*/
const CheckmarkCircled = ({ className, onTimeout, timeout = 2000 }) => {
const [isAnimated, setIsAnimated] = useState(false);
const [isTimedOut, setIsTimedOut] = useState(false);

useEffect(() => {
setIsAnimated(true);
}, []);

useEffect(() => {
setIsTimedOut(false);
let timeoutId = setTimeout(() => {
timeoutId = 0;
setIsTimedOut(true);
}, Math.max(timeout, /* total CSS animation duration */ 1200));
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, [timeout]);

return (
<span
className={cn(
styles.container,
{ [styles.fadeOut]: isTimedOut },
className
)}
onTransitionEnd={isTimedOut ? onTimeout : null}
>
<Icon
className={cn(styles.checkmark, { [styles.animated]: isAnimated })}
/>
</span>
);
};

CheckmarkCircled.propTypes = {
className: PT.string,
onTimeout: PT.func.isRequired,
timeout: PT.number,
};

export default CheckmarkCircled;
79 changes: 79 additions & 0 deletions src/components/Icons/CheckmarkCircled/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@import "styles/variables";

.container {
display: inline-block;
width: 30px;
height: 30px;
opacity: 1;
transition: opacity 0.2s ease;
}

.checkmark {
display: block;
width: auto;
height: 100%;
border-radius: 999px;
stroke-width: 2;
stroke: $primary-color;
stroke-miterlimit: 10;
box-shadow: inset 0px 0px 0px $primary-color;
animation-play-state: paused;
animation: /*checkmark-circled-fill 0.4s ease-in-out 0.4s forwards,*/ checkmark-circled-scale
0.3s ease-in-out 0.9s both;

:global(.checkmark__circle) {
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
stroke-miterlimit: 10;
stroke: $primary-color;
fill: rgba(255, 255, 255, 0);
animation-play-state: paused;
animation: checkmark-circled-stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1)
forwards;
}

:global(.checkmark__check) {
transform-origin: 50% 50%;
stroke-dasharray: 48;
stroke-dashoffset: 48;
animation-play-state: paused;
animation: checkmark-circled-stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s
forwards;
}
}

.animated {
animation-play-state: running;

:global(.checkmark__circle),
:global(.checkmark__check) {
animation-play-state: running;
}
}

.fadeOut {
opacity: 0;
}

@keyframes checkmark-circled-stroke {
100% {
stroke-dashoffset: 0;
}
}

@keyframes checkmark-circled-scale {
0%,
100% {
transform: none;
}
50% {
transform: scale3d(1.1, 1.1, 1);
}
}

@keyframes checkmark-circled-fill {
100% {
box-shadow: inset 0px 0px 0px 10px $primary-color;
}
}
8 changes: 6 additions & 2 deletions src/components/Popup/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,16 @@ const Popup = ({
return (
<div
ref={setPopperElement}
className={cn(compStyles.container, styles.container, className)}
className={cn(compStyles.container, className)}
style={styles.popper}
{...attributes.popper}
>
{children}
<div className="popup-arrow" ref={setArrowElement} style={styles.arrow} />
<div
className={compStyles.popupArrow}
ref={setArrowElement}
style={styles.arrow}
/>
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/Popup/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
background: #fff;
box-shadow: $popover-box-shadow;

:global(.popup-arrow) {
.popupArrow {
display: none;
}
}
6 changes: 4 additions & 2 deletions src/components/SelectField/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,16 @@

.medium {
:global(.custom__value-container) {
margin-top: 4px;
margin-top: 2px;
margin-bottom: 2px;
padding: 6px 15px;
}
}

.small {
:global(.custom__value-container) {
margin-top: 2px;
margin-top: 1px;
margin-bottom: 1px;
padding: 2px 7px 2px 13px;
}

Expand Down
6 changes: 4 additions & 2 deletions src/decls/svg.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
declare module '*.svg' {
const value: string;
declare module "*.svg" {
const value: import("react").FunctionComponent<
React.SVGAttributes<SVGElement>
>;
export default value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

.container {
display: block;
max-width: 480px;
text-align: left;
}

Expand Down
8 changes: 4 additions & 4 deletions src/routes/WorkPeriods/components/PeriodDetails/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ const PeriodDetails = ({ className, details, isDisabled, isFailed }) => {
</div>
</div>
</div>
<div className={styles.billingAccountSection}>
<div className={styles.billingAccountsSection}>
<div className={styles.sectionLabel}>Billing Account</div>
<SelectField
className={
billingAccountsError ? styles.billingAccountsError : ""
}
className={cn(styles.billingAccountsSelect, {
[styles.billingAccountsError]: billingAccountsError,
})}
id={`rb_bil_acc_${periodId}`}
isDisabled={billingAccountsIsDisabled}
size="small"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@
color: #e90c5a;
}

.billingAccountSection {
.billingAccountsSection {
margin-top: 13px;
}

.billingAccountsSelect {
min-width: 368px;
}

.billingAccountsError {
color: #e90c5a;
}
Expand Down
21 changes: 13 additions & 8 deletions src/routes/WorkPeriods/components/PeriodItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import PT from "prop-types";
import cn from "classnames";
import debounce from "lodash/debounce";
import Checkbox from "components/Checkbox";
import IntegerField from "components/IntegerField";
import ProjectName from "components/ProjectName";
import PaymentError from "../PaymentError";
import PaymentStatus from "../PaymentStatus";
Expand All @@ -13,6 +12,7 @@ import PeriodDetails from "../PeriodDetails";
import { PAYMENT_STATUS } from "constants/workPeriods";
import {
setWorkPeriodWorkingDays,
toggleWorkingDaysUpdated,
toggleWorkPeriod,
} from "store/actions/workPeriods";
import {
Expand All @@ -23,6 +23,7 @@ import { useUpdateEffect } from "utils/hooks";
import { formatUserHandleLink, formatWeeklyRate } from "utils/formatters";
import { stopPropagation } from "utils/misc";
import styles from "./styles.module.scss";
import PeriodWorkingDays from "../PeriodWorkingDays";

/**
* Displays the working period data row to be used in PeriodList component.
Expand Down Expand Up @@ -57,6 +58,10 @@ const PeriodItem = ({
dispatch(toggleWorkPeriodDetails(item));
}, [dispatch, item]);

const onWorkingDaysUpdateHintTimeout = useCallback(() => {
dispatch(toggleWorkingDaysUpdated(item.id, false));
}, [dispatch, item.id]);

const onWorkingDaysChange = useCallback(
(daysWorked) => {
dispatch(setWorkPeriodWorkingDays(item.id, daysWorked));
Expand Down Expand Up @@ -141,19 +146,19 @@ const PeriodItem = ({
<PaymentStatus status={data.paymentStatus} />
</td>
<td className={styles.daysWorked}>
<IntegerField
className={styles.daysWorkedControl}
<PeriodWorkingDays
updateHintTimeout={2000}
controlName={`wp_wrk_days_${item.id}`}
data={data}
isDisabled={isDisabled}
name={`wp_wrk_days_${item.id}`}
onChange={onWorkingDaysChange}
maxValue={5}
minValue={data.daysPaid}
value={data.daysWorked}
onWorkingDaysChange={onWorkingDaysChange}
onWorkingDaysUpdateHintTimeout={onWorkingDaysUpdateHintTimeout}
/>
</td>
</tr>
{details && (
<PeriodDetails
className={styles.periodDetails}
details={details}
isDisabled={isDisabled}
isFailed={isFailed}
Expand Down
28 changes: 20 additions & 8 deletions src/routes/WorkPeriods/components/PeriodItem/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
@import "styles/mixins";
@import "styles/variables";

tr.container {
.container {
> td {
padding-left: 17px;
padding-right: 17px;
padding-left: 15px;
padding-right: 15px;
background: #fff;
}

Expand Down Expand Up @@ -40,8 +40,22 @@ tr.container {
}
}

.periodDetails {
+ .container.hasDetails {
> td {
&.toggle {
padding-top: 12px;
}

&.daysWorked {
padding-top: 5px;
}
}
}
}

td.toggle {
padding: 12px 20px 12px 15px;
padding: 12px 18px 12px 15px;
line-height: 15px;
}

Expand All @@ -67,6 +81,8 @@ td.teamName {

td.startDate,
td.endDate {
padding-left: 10px;
padding-right: 10px;
white-space: nowrap;
}

Expand All @@ -90,7 +106,3 @@ td.paymentTotal {
td.daysWorked {
padding: 5px 10px;
}

.daysWorkedControl {
width: 100px;
}
8 changes: 7 additions & 1 deletion src/routes/WorkPeriods/components/PeriodList/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ const PeriodList = ({ className }) => {

return (
<ProjectNameContextProvider>
<div className={cn(styles.container, className)}>
<div
className={cn(
styles.container,
{ [styles.hasItems]: periods.length },
className
)}
>
<table className={styles.table}>
<thead>
<PeriodListHead />
Expand Down
Loading