adding tooltip with which class has conflicts
This commit is contained in:
@@ -34,6 +34,10 @@
|
|||||||
font-size: $x_small_size;
|
font-size: $x_small_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xx_small_size {
|
||||||
|
font-size: $xx_small_size;
|
||||||
|
}
|
||||||
|
|
||||||
.small_size {
|
.small_size {
|
||||||
font-size: $small_size;
|
font-size: $small_size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,37 @@
|
|||||||
|
|
||||||
.isConflict {
|
.isConflict {
|
||||||
* {
|
* {
|
||||||
color: $speedway_brick;
|
color: $speedway_brick !important;
|
||||||
text-decoration: line-through !important;
|
|
||||||
font-weight: normal !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 { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||||
import { Button } from '../../common/Button/Button';
|
import { Button } from '../../common/Button/Button';
|
||||||
import Icon from '../../common/Icon/Icon';
|
import Icon from '../../common/Icon/Icon';
|
||||||
|
import Text from '../../common/Text/Text';
|
||||||
import styles from './TableRow.module.scss';
|
import styles from './TableRow.module.scss';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -20,9 +21,13 @@ interface Props {
|
|||||||
export default function TableRow({ row, isSelected, activeSchedule, onClick }: Props): JSX.Element | null {
|
export default function TableRow({ row, isSelected, activeSchedule, onClick }: Props): JSX.Element | null {
|
||||||
const [container, setContainer] = useState<HTMLTableCellElement | null>(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;
|
const { element, course } = row;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
element.classList.add(styles.row);
|
||||||
const portalContainer = document.createElement('td');
|
const portalContainer = document.createElement('td');
|
||||||
const lastTableCell = element.querySelector('td:last-child');
|
const lastTableCell = element.querySelector('td:last-child');
|
||||||
lastTableCell!.after(portalContainer);
|
lastTableCell!.after(portalContainer);
|
||||||
@@ -30,6 +35,7 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
portalContainer.remove();
|
portalContainer.remove();
|
||||||
|
element.classList.remove(styles.row);
|
||||||
};
|
};
|
||||||
}, [element]);
|
}, [element]);
|
||||||
|
|
||||||
@@ -54,15 +60,20 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasConflicts = activeSchedule.courses.find(c => {
|
let conflicts: Course[] = [];
|
||||||
let conflicts = course.getConflicts(c);
|
|
||||||
return conflicts.length > 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
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 () => {
|
return () => {
|
||||||
element.classList.remove(styles.isConflict);
|
element.classList.remove(styles.isConflict);
|
||||||
|
setConflicts([]);
|
||||||
};
|
};
|
||||||
}, [activeSchedule, course]);
|
}, [activeSchedule, course]);
|
||||||
|
|
||||||
@@ -71,9 +82,22 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ReactDOM.createPortal(
|
return ReactDOM.createPortal(
|
||||||
|
<>
|
||||||
<Button className={styles.rowButton} onClick={onClick} type='secondary'>
|
<Button className={styles.rowButton} onClick={onClick} type='secondary'>
|
||||||
<Icon name='bar_chart' color='white' size='medium' />
|
<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
|
container
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ $semi_bold_weight: 600;
|
|||||||
$bold_weight: 700;
|
$bold_weight: 700;
|
||||||
$black_weight: 900;
|
$black_weight: 900;
|
||||||
|
|
||||||
|
$xx_small_size: 4px;
|
||||||
$x_small_size: 8px;
|
$x_small_size: 8px;
|
||||||
$small_size: 12px;
|
$small_size: 12px;
|
||||||
$medium_size: 16px;
|
$medium_size: 16px;
|
||||||
@@ -38,6 +39,7 @@ $xx_large_size: 48px;
|
|||||||
bold_weight: $bold_weight;
|
bold_weight: $bold_weight;
|
||||||
black_weight: $black_weight;
|
black_weight: $black_weight;
|
||||||
|
|
||||||
|
xx_small_size: $xx_small_size;
|
||||||
x_small_size: $x_small_size;
|
x_small_size: $x_small_size;
|
||||||
small_size: $small_size;
|
small_size: $small_size;
|
||||||
medium_size: $medium_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
|
* the type for all the size scss variables exported from fonts.module.scss
|
||||||
*/
|
*/
|
||||||
export interface ISizes {
|
export interface ISizes {
|
||||||
|
xx_small_size: number;
|
||||||
x_small_size: number;
|
x_small_size: number;
|
||||||
small_size: number;
|
small_size: number;
|
||||||
medium_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
|
- [ ] copy unique id quickly from browser action
|
||||||
- [x] Clickable links to buildings
|
- [x] Clickable links to buildings
|
||||||
- [ ] Count how many hours and # of classes in schedule
|
- [ ] 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
|
- [ ] Tooltip that says which classes conflict, maybe suggest a different section or time that doesn't conflict
|
||||||
- [ ] import / export schedules from JSON file
|
- [ ] import / export schedules from JSON file
|
||||||
- [ ] Search for classes from within extension
|
- [ ] Search for classes from within extension
|
||||||
|
|||||||
Reference in New Issue
Block a user