Skip to content

Commit

Permalink
TASK-387 Sort shifts in dropdown (#282)
Browse files Browse the repository at this point in the history
  • Loading branch information
net-runner authored and prenc committed Mar 22, 2021
1 parent 2684d66 commit 27c48a8
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 142 deletions.
63 changes: 39 additions & 24 deletions src/assets/styles/styles/custom/_autocomplete.scss
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

/*
?Styling for shift autocomplete component
*/
.more-left-margin {
margin-left: -6px !important;
}

.autoSeparator {
flex: 1;
width: 90%;
background-color: $gray-400;
height: 1.25px;
display: flex;
align-self: center;
margin-top: 10px;
margin-bottom: 10px;
}
.listbox {
position: absolute;
padding: 10px 0;
margin: -5px 0 0 -2px;
z-index: 1;
list-style: none;
overflow: auto;
font-family: $font-family-primary;
font-size: $font-size-lg;
line-height: 175%;
text-align: left;
color: $primary;
background-color: $white;
font-weight: $font-weight-normal;
box-shadow: 0 4px 7px rgba(16, 32, 70, 0.2);
max-height: 500px;
border-radius: 7px;
min-width: 250px;
min-width: 260px;
z-index: 300;

& li {
clear: both;
min-height: 25px;
& > div {
display: flex;
margin-left: 0.6em;
flex: 1;
flex-direction: row;
flex-wrap: nowrap;
letter-spacing: 0.75px;
align-content: center;
justify-items: center;
justify-content: left;
&:hover {
font-style: italic;
font-weight: $font-weight-extra-bold;
Expand All @@ -37,23 +54,21 @@
&[data-focus="true"] {
cursor: pointer;
}

.container {
display: block;
margin-left: 15px;

.colorSample {
width: 9px;
height: 9px;
border-radius: 50%;
float: left;
margin: 8.5px 20px 0 10px;
}

.optionLabel {
float: left;
clear: both;
}
> .optionLabel {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin-right: 0.2em;
word-wrap: normal;
overflow-wrap: normal;
}
> .colorSamplee {
display: flex;
width: 9px;
height: 9px;
border-radius: 50%;
margin: 0 0;
align-self: center;
}
}
}

This file was deleted.

1 change: 0 additions & 1 deletion src/components/common-components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
export * from "./header/header.component";
export * from "./autocomplete/autocomplete.component";
export * from "./button-component/button.component";
export * from "./month-switch/month-switch.component";
export * from "./snackbar/snackbar.component";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,133 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import React from "react";
import { SHIFTS as shifts } from "../../../../../../common-models/shift-info.model";
import { AutocompleteComponent } from "../../../../../common-components";
import { useAutocomplete } from "@material-ui/lab";
import _ from "lodash";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { usePopper } from "react-popper";
import { useSelector } from "react-redux";
import { ShiftCode, SHIFTS as shifts } from "../../../../../../common-models/shift-info.model";
import { ApplicationStateModel } from "../../../../../../state/models/application-state.model";
import { BaseCellInputOptions } from "../base-cell/base-cell-input.component";
import classNames from "classnames/bind";

const ShiftCodeSelectItems = Object.values(shifts).map((shift) => {
return {
name: `${shift.name} ${shift.isWorkingShift ? `(${shift.from}-${shift.to})` : ""}`,
symbol: shift.code,
code: shift.code,
color: shift.color ? shift.color : "$white",
"data-cy": `autocomplete-${shift.code}`,
};
});

const ShiftCodeSelectItems = _.sortBy(
Object.values(shifts).map((shift) => {
return {
name: `${shift.name} ${shift.isWorkingShift ? `(${shift.from}-${shift.to})` : ""}`,
symbol: shift.code,
from: shift.from,
to: shift.to,
isWorkingShift: shift!.isWorkingShift,
code: shift.code,
color: shift.color ? shift.color : "$white",
"data-cy": `autocomplete-${shift.code}`,
};
}),
["from", "to", "name"]
);
type ShiftCodeSelectItem = typeof ShiftCodeSelectItems[0];
/**
* @description Input & MaterialAutocomplete component for rendering employees shifts
* @param inputOptions : BaseCellInputOptions
* @returns JSX.Element
*/
export function ShiftAutocompleteComponent(inputOptions: BaseCellInputOptions): JSX.Element {
const inputRef = useRef(null);
const tooltipRef = useRef(null);
const { styles } = usePopper(inputRef.current, tooltipRef.current, {
placement: "right-end",
});
const onValueChange = useCallback((option): void => inputOptions.onValueChange(option.code), [
inputOptions,
]);
const getOptionLabel = (option): string => option.name;
const getOptionColor = (option): string => option.color;
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => inputOptions.onKeyDown(e);
const [value, setValue] = useState();
useEffect(() => {
if (value) {
onValueChange(value);
}
}, [value, onValueChange]);

const {
getRootProps,
getInputProps,
getListboxProps,
getOptionProps,
groupedOptions,
} = useAutocomplete({
options: ShiftCodeSelectItems,
getOptionLabel,
open: true,
});
const shiftTypes = useSelector(
(state: ApplicationStateModel) => state.actualState.persistentSchedule.present.shift_types
);

/**
* @description Small element for rendering shift info & shift color circle
* @returns JSX.Element
*/
const getNonWorkingShifts = (shift: ShiftCodeSelectItem): ShiftCodeSelectItem | undefined => {
if (shift.name.trim() !== shiftTypes[ShiftCode.W].name) {
if (!shift.isWorkingShift) return shift;
}
};
const nonWorkingShifts = groupedOptions.filter(getNonWorkingShifts);
const LabelComponent = ({ option, index }): JSX.Element => {
return (
<div
{...getOptionProps({ option, index })}
data-cy={option["data-cy"]}
onClick={(e: React.MouseEvent): void => {
e.stopPropagation();
setValue(option);
}}
>
<div className="optionLabel">{getOptionLabel(option)}</div>
<div className="colorSamplee" style={{ backgroundColor: `#${getOptionColor(option)}` }} />
</div>
);
};
return (
<AutocompleteComponent
className={inputOptions.className}
options={ShiftCodeSelectItems}
getOptionLabel={(option): string => option.name}
getOptionColor={(option): string => option.color}
onValueChange={(option): void => inputOptions.onValueChange(option.code)}
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>): void => inputOptions.onKeyDown(e)}
/>
<div ref={inputRef} data-cy="shiftDropdown">
<div {...getRootProps()}>
<input
className={inputOptions.className}
autoFocus={true}
value={value && getOptionLabel(value)}
{...getInputProps()}
onKeyDown={onKeyDown}
/>
</div>
{shiftTypes && groupedOptions.length > 0 && (
<div
ref={tooltipRef}
className={classNames("listbox")}
style={styles.popper}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onMouseDown={(getListboxProps() as any).onMouseDown}
>
{groupedOptions.map((option, index) => {
if (option.name.trim() === shiftTypes[ShiftCode.W].name) {
return <LabelComponent option={option} index={index} />;
}
return null;
})}
{groupedOptions.map((option, index) => {
if (option.isWorkingShift) {
return <LabelComponent option={option} index={index} />;
}
return null;
})}
{nonWorkingShifts.length > 0 && <div className="autoSeparator" />}
{nonWorkingShifts.map((option, index) => (
<LabelComponent option={option} index={index} />
))}
</div>
)}
</div>
);
}

0 comments on commit 27c48a8

Please sign in to comment.