Skip to content

Commit 3e50929

Browse files
committed
improved time table user interaction, and fixed inline messages too often popping up
1 parent e906095 commit 3e50929

File tree

11 files changed

+410
-304
lines changed

11 files changed

+410
-304
lines changed

library/src/components/inlinemessage/InlineMessage.tsx

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,102 +2,107 @@ import React, { useEffect, useRef, useState } from "react"
22
import Button, { Appearance } from "@atlaskit/button"
33
import { token } from "@atlaskit/tokens"
44

5-
export type MessageUrgency = "success" | "error" | "warning" | "information" | "danger" | undefined
5+
export type MessageUrgency =
6+
| "success"
7+
| "error"
8+
| "warning"
9+
| "information"
10+
| "danger"
11+
| undefined
612

713
export type Message = {
8-
text: string | JSX.Element,
9-
urgency?: MessageUrgency,
10-
timeOut?: number, // in seconds
14+
text: string | JSX.Element
15+
urgency?: MessageUrgency
16+
timeOut?: number // in seconds
1117
}
1218

13-
export default function InlineMessage ( {
19+
export default function InlineMessage({
1420
message,
1521
display = "block",
1622
}: {
17-
message: Message,
18-
display?: "inline-block" | "block",
19-
} ) {
20-
21-
const [ open, setOpen ] = useState( true )
22-
const [ msg, setMessage ] = useState( message )
23+
message: Message
24+
display?: "inline-block" | "block"
25+
}) {
26+
const [open, setOpen] = useState(true)
27+
const [msg, setMessage] = useState(message)
2328
const currentTimeOut = useRef<number>()
2429

25-
useEffect( () => {
26-
setMessage( message )
27-
setOpen( !!message?.text )
28-
if ( currentTimeOut.current ) {
29-
clearTimeout( currentTimeOut.current )
30+
useEffect(() => {
31+
setMessage(message)
32+
setOpen(!!message?.text)
33+
if (currentTimeOut.current) {
34+
clearTimeout(currentTimeOut.current)
3035
currentTimeOut.current = undefined
3136
}
32-
if ( message.timeOut && message.text ) {
33-
currentTimeOut.current = setTimeout( () => {
34-
setOpen( false )
37+
if (message.timeOut && message.text) {
38+
currentTimeOut.current = setTimeout(() => {
39+
setOpen(false)
3540
currentTimeOut.current = undefined
36-
}, message.timeOut * 1000 )
41+
}, message.timeOut * 1000)
3742
}
38-
}, [ message ] )
43+
}, [message])
3944

4045
let bgColor = undefined
4146
let textColor = undefined
4247
let borderColor = undefined
4348
let closeBtnAppearance: Appearance = "default"
44-
switch ( message.urgency ) {
49+
switch (message.urgency) {
4550
case "success":
46-
bgColor = token( "color.background.success" )
47-
textColor = token( "color.text.success" )
48-
borderColor = token( "color.border.success" )
51+
bgColor = token("color.background.success")
52+
textColor = token("color.text.success")
53+
borderColor = token("color.border.success")
4954
break
5055
case "error":
51-
bgColor = token( "color.background.danger" )
52-
textColor = token( "color.text.danger" )
53-
borderColor = token( "color.border.danger" )
56+
bgColor = token("color.background.danger")
57+
textColor = token("color.text.danger")
58+
borderColor = token("color.border.danger")
5459
closeBtnAppearance = "danger"
5560
break
5661
case "warning":
57-
bgColor = token( "color.background.warning" )
58-
textColor = token( "color.text.warning" )
59-
borderColor = token( "color.border.warning" )
62+
bgColor = token("color.background.warning")
63+
textColor = token("color.text.warning")
64+
borderColor = token("color.border.warning")
6065
closeBtnAppearance = "warning"
6166
break
6267
case "information":
63-
bgColor = token( "color.background.information" )
64-
textColor = token( "color.text.information" )
65-
borderColor = token( "color.border.information" )
68+
bgColor = token("color.background.information")
69+
textColor = token("color.text.information")
70+
borderColor = token("color.border.information")
6671
closeBtnAppearance = "primary"
6772
break
6873
case "danger":
69-
bgColor = token( "color.background.danger" )
70-
textColor = token( "color.text.danger" )
71-
borderColor = token( "color.border.danger" )
74+
bgColor = token("color.background.danger")
75+
textColor = token("color.text.danger")
76+
borderColor = token("color.border.danger")
7277
closeBtnAppearance = "danger"
7378
break
7479
default:
75-
borderColor = token( "color.border" )
80+
borderColor = token("color.border")
7681
break
7782
}
7883

7984
return (
8085
<div
81-
onMouseEnter={ () => {
82-
if ( !message.text ) return
83-
setOpen( true )
84-
} }
85-
onMouseLeave={ () => {
86-
if ( !message.text ) return
87-
if ( message.timeOut ) {
88-
clearTimeout( currentTimeOut.current )
89-
currentTimeOut.current = setTimeout( () => {
90-
setOpen( false )
86+
onMouseEnter={() => {
87+
if (!message.text) return
88+
setOpen(true)
89+
}}
90+
onMouseLeave={() => {
91+
if (!message.text) return
92+
if (message.timeOut) {
93+
clearTimeout(currentTimeOut.current)
94+
currentTimeOut.current = setTimeout(() => {
95+
setOpen(false)
9196
currentTimeOut.current = undefined
92-
}, message.timeOut * 1000 )
97+
}, message.timeOut * 1000)
9398
}
94-
} }
99+
}}
95100
>
96101
<div
97-
style={ {
102+
style={{
98103
display,
99104
backgroundColor: bgColor,
100-
border: `2px solid ${ borderColor }`,
105+
border: `2px solid ${borderColor}`,
101106
borderRadius: "2px",
102107
color: textColor,
103108
padding: "2px",
@@ -106,29 +111,29 @@ export default function InlineMessage ( {
106111
overflow: "hidden",
107112
scale: open ? "1 1" : "1 0",
108113
transformOrigin: "top",
109-
} }
114+
}}
110115
>
111116
<div
112-
style={ {
117+
style={{
113118
display: "flex",
114119
flexDirection: "row",
115120
justifyContent: "space-between",
116121
alignItems: "center",
117-
} }
122+
}}
118123
>
119-
{ msg?.text ?? "" }
124+
{msg?.text ?? ""}
120125
<Button
121-
appearance={ closeBtnAppearance }
122-
style={ {
126+
appearance={closeBtnAppearance}
127+
style={{
123128
borderRadius: "100%",
124129
userSelect: "none",
125-
} }
126-
onClick={ () => setOpen( false ) }
130+
}}
131+
onClick={() => setOpen(false)}
127132
>
128133
X
129134
</Button>
130135
</div>
131136
</div>
132137
</div>
133138
)
134-
}
139+
}

library/src/components/timetable/Messages.tsx

Lines changed: 99 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,108 @@
11
import React from "react"
22
import { FormattedMessage } from "react-intl-next"
33

4-
54
/// LPTimeTable
6-
//#region
7-
export const ItemsOutsideDayTimeFrame = ( { outsideItemCount }: { outsideItemCount: number } ) => <FormattedMessage
8-
defaultMessage={ "Found {outsideItemCount} outside of the valid time frame of each day." }
9-
values={ { outsideItemCount } }
10-
id="timetable.itemsOutsideTimeFrame"
11-
/>
12-
13-
export const UnfittingTimeSlot = ( { timeSteps }: { timeSteps: number } ) => <FormattedMessage
14-
defaultMessage={ "Start time does not accommodate one time slot before the next day, reducing time slot size to {timeSteps} size." }
15-
values={ { timeSteps } }
16-
id="timetable.unfittingTimeSlotMessage"
17-
/>
18-
19-
export const TimeSlotColumnsNotFound = () => <FormattedMessage
20-
defaultMessage={ "Unable to find time slot columns for the time slot bars." }
21-
id="timetable.timeSlotColumnsNotFound"
22-
/>
23-
24-
export const TimeSlotSizeGreaterZero = () => <FormattedMessage
25-
defaultMessage={ "Time slot size must be greater than zero." }
26-
id="timetable.timeSlotSizeGreaterZero"
27-
/>
28-
29-
export const EndDateAfterStartDate = () => <FormattedMessage
30-
defaultMessage={ "The end date must be after start date." }
31-
id="timetable.endDateAfterStartDate"
32-
/>
33-
34-
export const NoHeaderTimeSlotRow = () => <FormattedMessage
35-
defaultMessage={ "No header time slot row found." }
36-
id="timetable.noHeaderTimeSlotRow"
37-
/>
5+
//#region
6+
export const ItemsOutsideDayTimeFrame = ({
7+
outsideItemCount,
8+
}: {
9+
outsideItemCount: number
10+
}) => (
11+
<FormattedMessage
12+
defaultMessage={
13+
"Found {outsideItemCount} outside of the valid time frame of each day."
14+
}
15+
values={{ outsideItemCount }}
16+
id="timetable.itemsOutsideTimeFrame"
17+
/>
18+
)
19+
20+
export const UnfittingTimeSlot = ({ timeSteps }: { timeSteps: number }) => (
21+
<FormattedMessage
22+
defaultMessage={
23+
"Start time does not accommodate one time slot before the next day, reducing time slot size to {timeSteps} size."
24+
}
25+
values={{ timeSteps }}
26+
id="timetable.unfittingTimeSlotMessage"
27+
/>
28+
)
29+
30+
export const TimeSlotColumnsNotFound = () => (
31+
<FormattedMessage
32+
defaultMessage={
33+
"Unable to find time slot columns for the time slot bars."
34+
}
35+
id="timetable.timeSlotColumnsNotFound"
36+
/>
37+
)
38+
39+
export const TimeSlotSizeGreaterZero = () => (
40+
<FormattedMessage
41+
defaultMessage={"Time slot size must be greater than zero."}
42+
id="timetable.timeSlotSizeGreaterZero"
43+
/>
44+
)
45+
46+
export const EndDateAfterStartDate = () => (
47+
<FormattedMessage
48+
defaultMessage={"The end date must be after start date."}
49+
id="timetable.endDateAfterStartDate"
50+
/>
51+
)
52+
53+
export const NoHeaderTimeSlotRow = () => (
54+
<FormattedMessage
55+
defaultMessage={"No header time slot row found."}
56+
id="timetable.noHeaderTimeSlotRow"
57+
/>
58+
)
3859
//#endregion
3960

40-
4161
/// TimeLineTable
42-
//#region
43-
44-
export const DeselectFromOuterBorder = () => <FormattedMessage
45-
defaultMessage={ "Please deselect from the outer borders of the time slot range." }
46-
id="timetable.deselectFromOuterBorder"
47-
/>
48-
49-
export const OnlySameGroupTimeSlots = () => <FormattedMessage
50-
defaultMessage={ "Please select only time slots in the same group." }
51-
id="timetable.onlySameGroupTimeSlots"
52-
/>
53-
54-
export const OnlySuccessiveTimeSlots = () => <FormattedMessage
55-
defaultMessage={ "Please select only successive time slots." }
56-
id="timetable.onlySuccessiveTimeSlots"
57-
/>
58-
59-
export const WeekendsDeactivated = () => <FormattedMessage
60-
defaultMessage={ "Weekends are deactivated." }
61-
id="timetable.weekendsDeactivated"
62-
/>
63-
64-
export const UnableToFindEarliestTS = () => <FormattedMessage
65-
defaultMessage={ "Unable to find the earliest time slot." }
66-
id="timetable.unableToFindEarliestTS"
67-
/>
68-
69-
70-
export const BookingsOutsideOfDayRange = ( { itemCount }: { itemCount: number } ) => <FormattedMessage
71-
defaultMessage={ "{itemCount} Bookings found out of day range of the available time slots." }
72-
values={ { itemCount } }
73-
id="timetable.bookingsOutsideOfDayRange"
74-
/>
62+
//#region
63+
64+
export const DeselectFromOuterBorder = () => (
65+
<FormattedMessage
66+
defaultMessage={
67+
"Please deselect from the outer borders of the time slot range."
68+
}
69+
id="timetable.deselectFromOuterBorder"
70+
/>
71+
)
72+
73+
export const OnlySuccessiveTimeSlots = () => (
74+
<FormattedMessage
75+
defaultMessage={"Please select only successive time slots."}
76+
id="timetable.onlySuccessiveTimeSlots"
77+
/>
78+
)
79+
80+
export const WeekendsDeactivated = () => (
81+
<FormattedMessage
82+
defaultMessage={"Weekends are deactivated."}
83+
id="timetable.weekendsDeactivated"
84+
/>
85+
)
86+
87+
export const UnableToFindEarliestTS = () => (
88+
<FormattedMessage
89+
defaultMessage={"Unable to find the earliest time slot."}
90+
id="timetable.unableToFindEarliestTS"
91+
/>
92+
)
93+
94+
export const BookingsOutsideOfDayRange = ({
95+
itemCount,
96+
}: {
97+
itemCount: number
98+
}) => (
99+
<FormattedMessage
100+
defaultMessage={
101+
"{itemCount} Bookings found out of day range of the available time slots."
102+
}
103+
values={{ itemCount }}
104+
id="timetable.bookingsOutsideOfDayRange"
105+
/>
106+
)
75107

76108
//#endregion
77-
78-
79-

0 commit comments

Comments
 (0)