LISA Frontend
React + TypeScript frontend for the LISA Instructor Compliance Dashboard. Built with Vite.
Setup
npm install
Copy ../.env.example or set VITE_API_BASE in a .env file:
VITE_API_BASE=http://localhost:5001/api
In development, Vite proxies /api requests to the Flask backend so session cookies stay on the same origin. In production, Flask serves the compiled dist/ directly and no proxy is needed.
Running
# Development (Vite dev server on port 5173)
npm run dev
# Production build (output to dist/)
npm run build
Both the backend and frontend dev servers can be started together from the repo root with lisa_backend/scripts/launch_dev.sh.
Project Structure
lisa_frontend/src/
├── App.tsx # Root component — all shared state lives here
├── api.ts # Fetch wrappers for all backend endpoints
├── constants.ts # Named constants — re-exports from shared_config.json + frontend-only values (Canvas base URL)
├── utils.ts # Utility functions (e.g. sort direction toggle)
├── types/
│ └── types.ts # Shared TypeScript types
└── components/
├── LoginPage.tsx # LDAP login form
├── Input.tsx # Instructor name search input
├── TermSelect.tsx # Term dropdown
├── InstructorInfoTable.tsx # Grading compliance instructor table (formerly InfoTable.tsx)
├── InstructorCourses.tsx # Per-course grading detail (expandable row)
├── SubmissionsTable.tsx # Submission-level drill-down for a course
├── DiscussionInfoTable.tsx # Discussion compliance instructor table
├── DiscussionInstructorCourses.tsx # Per-course discussion detail (expandable row)
├── DiscussionResponsesTable.tsx # Response-level drill-down for a course
├── AnnouncementsInfoTable.tsx # Announcement compliance instructor table
├── AnnouncementInstructorCourses.tsx # Per-course announcement detail (expandable row)
├── GradeDistributionTable.tsx # Grade distribution view — per-assignment stats across sections
├── ExpandableInfoTable.tsx # Shared expandable row wrapper
├── CourseTable.tsx # Shared course-level table component
├── ExcludedTitlesFilter.tsx # UI for managing excluded assignment titles (grading view only)
├── FlagCell.tsx # Reusable flag button + count display; used in all compliance views
├── FlagsTable.tsx # Flags view table — lists violations with inline edit/delete and filtering
└── small_ui.tsx # Small reusable UI components (PageIndicator, LoadingIndicator)
Views
The dashboard has five views, toggled by tab buttons at the top:
Grading Compliance — lists instructors with counts of overdue ungraded submissions. Clicking a row expands per-course detail; clicking a course opens the full submissions table for that course.
Discussion Response Compliance — lists instructors with their discussion response rates and total discussion entries read. Response rates and entries-read counts are calculated per-discussion topic. Clicking a row expands per-course detail; clicking a course opens the discussion responses table.
Announcements — lists instructors with total announcement counts and scheduled announcement counts per course.
Flags — lists all recorded instructor flags (violations). Each row shows flag type (grading, discussions, announcements, other), term, date, and optional reason note. Flags can be edited or deleted inline. Filterable by term, instructor ID, flag type, reason text, and date range.
Grade Distribution — lists per-assignment grade distribution statistics (mean, median, mode, sample standard deviation, min/max percentage and raw scores) aggregated across all sections sharing an assignment template (via master_courses_child_subscriptions). Filterable by term, course code, and assignment title, with an option to group by individual section instead of merging them. Sortable and paginated like the other views, but has no flag column and isn't part of the shared filter bar (it has its own term/course-code/title filters).
The Grading, Discussion, and Announcements views each include a flag column showing the instructor's current-term flag count and total lifetime flag count. Clicking the flag button opens a dialog to record a new flag. They share the same filter controls: instructor name search, date range, term selector, and CE toggle.
Instructor names are rendered as mailto links. Email addresses are derived from the instructor's name (first initial + last name + @unity.edu) because the canvas database does not store email addresses.
Links are set to open in new tab by default (<base target="_blank" />) in index.html
State
All shared state (current term, filters, pagination, instructor lists, view toggle) lives in App.tsx. Components receive data and callbacks as props. The Go button triggers a fresh fetch; Prev/Next paginate the current result. A page indicator ("Page X of Y") is displayed in the main view alongside the pagination controls.
Syncing state is polled every 10 seconds after a manual sync is triggered, and the instructor data is automatically refreshed when the sync completes.