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 5 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;
}
}
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="period-details"
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 {
}
}

:global(.period-details) {
+ .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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
.container {
position: relative;
padding: 0 20px 0 15px;
width: 100%;
overflow-x: auto;
overflow-y: visible;

&.hasItems {
min-height: 348px;
}
}

.table {
Expand Down
4 changes: 2 additions & 2 deletions src/routes/WorkPeriods/components/PeriodListHead/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ const PeriodListHead = () => {
const HEAD_CELLS = [
{ label: "Topcoder Handle", id: SORT_BY.USER_HANDLE },
{ label: "Team Name", id: SORT_BY.TEAM_NAME, disableSort: true },
{ label: "Start Date", id: SORT_BY.START_DATE },
{ label: "End Date", id: SORT_BY.END_DATE },
{ label: "Start Date", id: SORT_BY.START_DATE, className: "startDate" },
{ label: "End Date", id: SORT_BY.END_DATE, className: "endDate" },
{ label: "Weekly Rate", id: SORT_BY.WEEKLY_RATE, className: "weeklyRate" },
{ label: "Total Paid", id: SORT_BY.PAYMENT_TOTAL, className: "totalPaid" },
{ label: "Status", id: SORT_BY.PAYMENT_STATUS },
Expand Down
Loading