adding tooltip with which class has conflicts
This commit is contained in:
@@ -34,6 +34,10 @@
|
||||
font-size: $x_small_size;
|
||||
}
|
||||
|
||||
.xx_small_size {
|
||||
font-size: $xx_small_size;
|
||||
}
|
||||
|
||||
.small_size {
|
||||
font-size: $small_size;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,37 @@
|
||||
|
||||
.isConflict {
|
||||
* {
|
||||
color: $speedway_brick;
|
||||
text-decoration: line-through !important;
|
||||
color: $speedway_brick !important;
|
||||
font-weight: normal !important;
|
||||
text-decoration: line-through !important;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
.conflictTooltip {
|
||||
position: relative;
|
||||
display: none;
|
||||
|
||||
.body {
|
||||
position: absolute;
|
||||
left: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: black;
|
||||
padding: 8px;
|
||||
width: 120px;
|
||||
border-radius: 0px 5px 5px 0px;
|
||||
opacity: 0.5;
|
||||
div {
|
||||
color: white !important;
|
||||
text-decoration: none !important;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.conflictTooltip {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Course, ScrapedRow } from 'src/shared/types/Course';
|
||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||
import { Button } from '../../common/Button/Button';
|
||||
import Icon from '../../common/Icon/Icon';
|
||||
import Text from '../../common/Text/Text';
|
||||
import styles from './TableRow.module.scss';
|
||||
|
||||
interface Props {
|
||||
@@ -20,9 +21,13 @@ interface Props {
|
||||
export default function TableRow({ row, isSelected, activeSchedule, onClick }: Props): JSX.Element | null {
|
||||
const [container, setContainer] = useState<HTMLTableCellElement | null>(null);
|
||||
|
||||
// the courses in the active schedule that conflict with the course for this row
|
||||
const [conflicts, setConflicts] = useState<Course[]>([]);
|
||||
|
||||
const { element, course } = row;
|
||||
|
||||
useEffect(() => {
|
||||
element.classList.add(styles.row);
|
||||
const portalContainer = document.createElement('td');
|
||||
const lastTableCell = element.querySelector('td:last-child');
|
||||
lastTableCell!.after(portalContainer);
|
||||
@@ -30,6 +35,7 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
|
||||
return () => {
|
||||
portalContainer.remove();
|
||||
element.classList.remove(styles.row);
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
@@ -54,15 +60,20 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
return;
|
||||
}
|
||||
|
||||
let hasConflicts = activeSchedule.courses.find(c => {
|
||||
let conflicts = course.getConflicts(c);
|
||||
return conflicts.length > 0;
|
||||
});
|
||||
let conflicts: Course[] = [];
|
||||
|
||||
element.classList[hasConflicts ? 'add' : 'remove'](styles.isConflict);
|
||||
for (const c of activeSchedule.courses) {
|
||||
if (c.uniqueId !== course.uniqueId && course.getConflicts(c).length > 0) {
|
||||
conflicts.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
element.classList[conflicts.length ? 'add' : 'remove'](styles.isConflict);
|
||||
setConflicts(conflicts);
|
||||
|
||||
return () => {
|
||||
element.classList.remove(styles.isConflict);
|
||||
setConflicts([]);
|
||||
};
|
||||
}, [activeSchedule, course]);
|
||||
|
||||
@@ -71,9 +82,22 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
}
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<>
|
||||
<Button className={styles.rowButton} onClick={onClick} type='secondary'>
|
||||
<Icon name='bar_chart' color='white' size='medium' />
|
||||
</Button>,
|
||||
</Button>
|
||||
{conflicts.length > 0 && (
|
||||
<div className={styles.conflictTooltip}>
|
||||
<div className={styles.body}>
|
||||
{conflicts.map(c => (
|
||||
<Text size='small' key={c.uniqueId}>
|
||||
{c.department} {c.number} ({c.uniqueId})
|
||||
</Text>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>,
|
||||
container
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ $semi_bold_weight: 600;
|
||||
$bold_weight: 700;
|
||||
$black_weight: 900;
|
||||
|
||||
$xx_small_size: 4px;
|
||||
$x_small_size: 8px;
|
||||
$small_size: 12px;
|
||||
$medium_size: 16px;
|
||||
@@ -38,6 +39,7 @@ $xx_large_size: 48px;
|
||||
bold_weight: $bold_weight;
|
||||
black_weight: $black_weight;
|
||||
|
||||
xx_small_size: $xx_small_size;
|
||||
x_small_size: $x_small_size;
|
||||
small_size: $small_size;
|
||||
medium_size: $medium_size;
|
||||
|
||||
1
src/views/styles/fonts.module.scss.d.ts
vendored
1
src/views/styles/fonts.module.scss.d.ts
vendored
@@ -14,6 +14,7 @@ export interface IWeights {
|
||||
* the type for all the size scss variables exported from fonts.module.scss
|
||||
*/
|
||||
export interface ISizes {
|
||||
xx_small_size: number;
|
||||
x_small_size: number;
|
||||
small_size: number;
|
||||
medium_size: number;
|
||||
|
||||
2
todo.md
2
todo.md
@@ -19,7 +19,7 @@ Last Updated: 03/4/2023
|
||||
- [ ] copy unique id quickly from browser action
|
||||
- [x] Clickable links to buildings
|
||||
- [ ] Count how many hours and # of classes in schedule
|
||||
- [ ] Conflict highlighting
|
||||
- [x] Conflict highlighting
|
||||
- [ ] Tooltip that says which classes conflict, maybe suggest a different section or time that doesn't conflict
|
||||
- [ ] import / export schedules from JSON file
|
||||
- [ ] Search for classes from within extension
|
||||
|
||||
Reference in New Issue
Block a user