@instructure/platform-widget-dashboard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +365 -0
  2. package/dist/components/CoursesTab.canvas.d.ts +5 -0
  3. package/dist/components/CoursesTab.canvas.d.ts.map +1 -0
  4. package/dist/components/CoursesTabWrapper.d.ts +5 -0
  5. package/dist/components/CoursesTabWrapper.d.ts.map +1 -0
  6. package/dist/components/DashboardNotifications.d.ts +5 -0
  7. package/dist/components/DashboardNotifications.d.ts.map +1 -0
  8. package/dist/components/DashboardTab.d.ts +5 -0
  9. package/dist/components/DashboardTab.d.ts.map +1 -0
  10. package/dist/components/DashboardTabs.d.ts +5 -0
  11. package/dist/components/DashboardTabs.d.ts.map +1 -0
  12. package/dist/components/EnrollmentInvitation.d.ts +22 -0
  13. package/dist/components/EnrollmentInvitation.d.ts.map +1 -0
  14. package/dist/components/FeedbackQuestionTile.d.ts +5 -0
  15. package/dist/components/FeedbackQuestionTile.d.ts.map +1 -0
  16. package/dist/components/NotificationAlert.d.ts +19 -0
  17. package/dist/components/NotificationAlert.d.ts.map +1 -0
  18. package/dist/components/WidgetDashboardContainer.d.ts +5 -0
  19. package/dist/components/WidgetDashboardContainer.d.ts.map +1 -0
  20. package/dist/components/WidgetGrid.d.ts +10 -0
  21. package/dist/components/WidgetGrid.d.ts.map +1 -0
  22. package/dist/components/WidgetRenderer.d.ts +8 -0
  23. package/dist/components/WidgetRenderer.d.ts.map +1 -0
  24. package/dist/components/shared/CourseCode.d.ts +18 -0
  25. package/dist/components/shared/CourseCode.d.ts.map +1 -0
  26. package/dist/components/shared/CourseFilterSelect.d.ts +14 -0
  27. package/dist/components/shared/CourseFilterSelect.d.ts.map +1 -0
  28. package/dist/components/shared/CourseName.d.ts +9 -0
  29. package/dist/components/shared/CourseName.d.ts.map +1 -0
  30. package/dist/components/shared/CourseWorkFilters.d.ts +23 -0
  31. package/dist/components/shared/CourseWorkFilters.d.ts.map +1 -0
  32. package/dist/components/shared/StatisticsCard.d.ts +10 -0
  33. package/dist/components/shared/StatisticsCard.d.ts.map +1 -0
  34. package/dist/components/shared/StatisticsCardsGrid.d.ts +14 -0
  35. package/dist/components/shared/StatisticsCardsGrid.d.ts.map +1 -0
  36. package/dist/components/shared/WidgetContextMenu.d.ts +12 -0
  37. package/dist/components/shared/WidgetContextMenu.d.ts.map +1 -0
  38. package/dist/components/widgets/AnnouncementsWidget/AnnouncementItem.d.ts +11 -0
  39. package/dist/components/widgets/AnnouncementsWidget/AnnouncementItem.d.ts.map +1 -0
  40. package/dist/components/widgets/AnnouncementsWidget/AnnouncementsWidget.d.ts +6 -0
  41. package/dist/components/widgets/AnnouncementsWidget/AnnouncementsWidget.d.ts.map +1 -0
  42. package/dist/components/widgets/AnnouncementsWidget/utils.d.ts +2 -0
  43. package/dist/components/widgets/AnnouncementsWidget/utils.d.ts.map +1 -0
  44. package/dist/components/widgets/CourseGradesWidget/CourseGradeCard.d.ts +6 -0
  45. package/dist/components/widgets/CourseGradesWidget/CourseGradeCard.d.ts.map +1 -0
  46. package/dist/components/widgets/CourseGradesWidget/CourseGradesWidget.d.ts +6 -0
  47. package/dist/components/widgets/CourseGradesWidget/CourseGradesWidget.d.ts.map +1 -0
  48. package/dist/components/widgets/CourseWorkSummaryWidget/CourseWorkSummaryWidget.d.ts +6 -0
  49. package/dist/components/widgets/CourseWorkSummaryWidget/CourseWorkSummaryWidget.d.ts.map +1 -0
  50. package/dist/components/widgets/CourseWorkSummaryWidget/index.d.ts +2 -0
  51. package/dist/components/widgets/CourseWorkSummaryWidget/index.d.ts.map +1 -0
  52. package/dist/components/widgets/CourseWorkWidget/CourseWorkWidget.d.ts +6 -0
  53. package/dist/components/widgets/CourseWorkWidget/CourseWorkWidget.d.ts.map +1 -0
  54. package/dist/components/widgets/CourseWorkWidget/utils.d.ts +15 -0
  55. package/dist/components/widgets/CourseWorkWidget/utils.d.ts.map +1 -0
  56. package/dist/components/widgets/InboxWidget/InboxWidget.d.ts +6 -0
  57. package/dist/components/widgets/InboxWidget/InboxWidget.d.ts.map +1 -0
  58. package/dist/components/widgets/InboxWidget/MessageItem.d.ts +9 -0
  59. package/dist/components/widgets/InboxWidget/MessageItem.d.ts.map +1 -0
  60. package/dist/components/widgets/PeopleWidget/PeopleWidget.d.ts +6 -0
  61. package/dist/components/widgets/PeopleWidget/PeopleWidget.d.ts.map +1 -0
  62. package/dist/components/widgets/PeopleWidget/index.d.ts +2 -0
  63. package/dist/components/widgets/PeopleWidget/index.d.ts.map +1 -0
  64. package/dist/components/widgets/ProgressOverviewWidget/CourseProgressBar.d.ts +19 -0
  65. package/dist/components/widgets/ProgressOverviewWidget/CourseProgressBar.d.ts.map +1 -0
  66. package/dist/components/widgets/ProgressOverviewWidget/CourseProgressItem.d.ts +9 -0
  67. package/dist/components/widgets/ProgressOverviewWidget/CourseProgressItem.d.ts.map +1 -0
  68. package/dist/components/widgets/ProgressOverviewWidget/ProgressOverviewWidget.d.ts +6 -0
  69. package/dist/components/widgets/ProgressOverviewWidget/ProgressOverviewWidget.d.ts.map +1 -0
  70. package/dist/components/widgets/ProgressOverviewWidget/index.d.ts +2 -0
  71. package/dist/components/widgets/ProgressOverviewWidget/index.d.ts.map +1 -0
  72. package/dist/components/widgets/RecentGradesWidget/GradeItem.d.ts +6 -0
  73. package/dist/components/widgets/RecentGradesWidget/GradeItem.d.ts.map +1 -0
  74. package/dist/components/widgets/RecentGradesWidget/RecentGradesWidget.d.ts +6 -0
  75. package/dist/components/widgets/RecentGradesWidget/RecentGradesWidget.d.ts.map +1 -0
  76. package/dist/components/widgets/TemplateWidget/TemplateWidget.d.ts +25 -0
  77. package/dist/components/widgets/TemplateWidget/TemplateWidget.d.ts.map +1 -0
  78. package/dist/components/widgets/TemplateWidget/index.d.ts +3 -0
  79. package/dist/components/widgets/TemplateWidget/index.d.ts.map +1 -0
  80. package/dist/components/widgets/TodoListWidget/CreateTodoModal.d.ts +26 -0
  81. package/dist/components/widgets/TodoListWidget/CreateTodoModal.d.ts.map +1 -0
  82. package/dist/components/widgets/TodoListWidget/TodoItem.d.ts +9 -0
  83. package/dist/components/widgets/TodoListWidget/TodoItem.d.ts.map +1 -0
  84. package/dist/components/widgets/TodoListWidget/TodoListWidget.d.ts +6 -0
  85. package/dist/components/widgets/TodoListWidget/TodoListWidget.d.ts.map +1 -0
  86. package/dist/components/widgets/TodoListWidget/api.d.ts +43 -0
  87. package/dist/components/widgets/TodoListWidget/api.d.ts.map +1 -0
  88. package/dist/components/widgets/TodoListWidget/hooks/usePlannerItems.d.ts +23 -0
  89. package/dist/components/widgets/TodoListWidget/hooks/usePlannerItems.d.ts.map +1 -0
  90. package/dist/components/widgets/TodoListWidget/types.d.ts +63 -0
  91. package/dist/components/widgets/TodoListWidget/types.d.ts.map +1 -0
  92. package/dist/components/widgets/TodoListWidget/utils.d.ts +8 -0
  93. package/dist/components/widgets/TodoListWidget/utils.d.ts.map +1 -0
  94. package/dist/constants/pagination.d.ts +10 -0
  95. package/dist/constants/pagination.d.ts.map +1 -0
  96. package/dist/hooks/useProgressOverview.d.ts +26 -0
  97. package/dist/hooks/useProgressOverview.d.ts.map +1 -0
  98. package/dist/hooks/useResponsiveContext.d.ts +16 -0
  99. package/dist/hooks/useResponsiveContext.d.ts.map +1 -0
  100. package/dist/hooks/useSharedCourses.d.ts +20 -0
  101. package/dist/hooks/useSharedCourses.d.ts.map +1 -0
  102. package/dist/hooks/useWidgetConfig.d.ts +13 -0
  103. package/dist/hooks/useWidgetConfig.d.ts.map +1 -0
  104. package/dist/index.d.ts +11 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +13387 -0
  107. package/dist/types/env.d.ts +54 -0
  108. package/dist/types/env.d.ts.map +1 -0
  109. package/dist/types/index.d.ts +3 -0
  110. package/dist/types/index.d.ts.map +1 -0
  111. package/dist/types/widget.d.ts +141 -0
  112. package/dist/types/widget.d.ts.map +1 -0
  113. package/dist/utils/graphql.d.ts +20 -0
  114. package/dist/utils/graphql.d.ts.map +1 -0
  115. package/dist/widgetRegistry.d.ts +4 -0
  116. package/dist/widgetRegistry.d.ts.map +1 -0
  117. package/package.json +86 -0
package/README.md ADDED
@@ -0,0 +1,365 @@
1
+ # Widget Dashboard
2
+
3
+ A flexible, extensible dashboard system for Canvas LMS that allows students to customize their learning experience with various widgets.
4
+
5
+ ## Overview
6
+
7
+ The widget dashboard provides a 3-column grid layout where different widgets can be positioned and sized according to configuration. The system is designed to be extensible, with a template-based architecture that makes creating new widgets straightforward.
8
+
9
+ ## Architecture
10
+
11
+ ### Core Components
12
+
13
+ - **TemplateWidget**: Base template providing consistent styling, loading states, and error handling
14
+ - **WidgetRegistry**: Central registry system that maps widget types to their React components
15
+ - **WidgetGrid**: Renders widgets in a CSS Grid layout based on configuration
16
+ - **Widget Types**: Defined constants and TypeScript interfaces for type safety
17
+
18
+ ### Current Widgets
19
+
20
+ - **CourseWorkSummaryWidget**: Displays upcoming assignments, missing work, and submitted assignments with filtering options
21
+
22
+ ## Creating a New Widget
23
+
24
+ ### Step 1: Create the Widget Component Structure
25
+
26
+ Create the directory structure for your new widget:
27
+
28
+ ```bash
29
+ mkdir -p ui/features/widget_dashboard/react/components/widgets/MyWidget/__tests__
30
+ ```
31
+
32
+ Create the main widget component:
33
+
34
+ ```tsx
35
+ // ui/features/widget_dashboard/react/components/widgets/MyWidget/MyWidget.tsx
36
+ import React, {useState, useEffect} from 'react'
37
+ import {useScope as createI18nScope} from '@canvas/i18n'
38
+ import {Button} from '@instructure/ui-buttons'
39
+ import {Text} from '@instructure/ui-text'
40
+ import TemplateWidget from '../TemplateWidget'
41
+ import type {BaseWidgetProps} from '../../../types'
42
+
43
+ const I18n = createI18nScope('widget_dashboard')
44
+
45
+ const MyWidget: React.FC<BaseWidgetProps> = ({widget, isLoading, error, onRetry}) => {
46
+ const [data, setData] = useState<string>('Loading...')
47
+
48
+ useEffect(() => {
49
+ // Your data fetching logic here
50
+ setTimeout(() => {
51
+ setData('Widget data loaded!')
52
+ }, 1000)
53
+ }, [])
54
+
55
+ const handleAction = () => {
56
+ console.log('Widget action clicked')
57
+ }
58
+
59
+ return (
60
+ <TemplateWidget
61
+ widget={widget}
62
+ title="Custom Widget Title" // Optional: Override widget.title
63
+ isLoading={isLoading}
64
+ error={error}
65
+ onRetry={onRetry}
66
+ showHeader={true} // Optional: Show/hide header (default: true)
67
+ headerActions={
68
+ <Button size="small" variant="ghost">
69
+ {I18n.t('Settings')}
70
+ </Button>
71
+ }
72
+ actions={
73
+ <Button onClick={handleAction} size="small">
74
+ {I18n.t('Widget Action')}
75
+ </Button>
76
+ }
77
+ >
78
+ <div>
79
+ <Text size="medium">{data}</Text>
80
+ <Text size="small" color="secondary">
81
+ {I18n.t('This is my custom widget content')}
82
+ </Text>
83
+ </div>
84
+ </TemplateWidget>
85
+ )
86
+ }
87
+
88
+ export default MyWidget
89
+ ```
90
+
91
+ Create an index file for clean exports:
92
+
93
+ ```tsx
94
+ // ui/features/widget_dashboard/react/components/widgets/MyWidget/index.ts
95
+ export {default} from './MyWidget'
96
+ ```
97
+
98
+ #### TemplateWidget Props Breakdown
99
+
100
+ The `TemplateWidget` component accepts the following props to provide a consistent widget experience:
101
+
102
+ | Prop | Type | Required | Default | Description |
103
+ |------|------|----------|---------|-------------|
104
+ | `widget` | `Widget` | ✅ Yes | - | Widget configuration object containing id, type, position, size, and title |
105
+ | `children` | `React.ReactNode` | ✅ Yes | - | The main content of your widget |
106
+ | `title` | `string` | ❌ No | `widget.title` | Override the widget title. If not provided, uses `widget.title` |
107
+ | `isLoading` | `boolean` | ❌ No | `false` | Shows loading spinner when true, hides children content |
108
+ | `error` | `string \| null` | ❌ No | `null` | Error message to display. When set, shows error state and hides children |
109
+ | `onRetry` | `() => void` | ❌ No | `undefined` | Callback for retry button. Only shows retry button if provided and error exists |
110
+ | `showHeader` | `boolean` | ❌ No | `true` | Whether to show the widget header with title |
111
+ | `headerActions` | `React.ReactNode` | ❌ No | `undefined` | Additional actions to display in the header (e.g., settings, info buttons) |
112
+ | `actions` | `React.ReactNode` | ❌ No | `undefined` | Action buttons to display at the bottom of the widget |
113
+
114
+ **State Priority**: The TemplateWidget renders content based on this priority:
115
+ 1. **Loading state** (when `isLoading={true}`) - Shows spinner, hides everything else
116
+ 2. **Error state** (when `error` is provided) - Shows error message and optional retry button
117
+ 3. **Normal state** - Shows `children` content and optional `actions`
118
+
119
+ **Layout Structure**:
120
+ ```
121
+ ┌─────────────────────────────────────┐
122
+ │ Header (if showHeader=true) │
123
+ │ ┌─────────────┐ ┌─────────────────┐ │
124
+ │ │ Title │ │ Header Actions │ │
125
+ │ └─────────────┘ └─────────────────┘ │
126
+ ├─────────────────────────────────────┤
127
+ │ │
128
+ │ Content Area │
129
+ │ (children | loading | error) │
130
+ │ │
131
+ ├─────────────────────────────────────┤
132
+ │ Actions (if provided) │
133
+ └─────────────────────────────────────┘
134
+ ```
135
+
136
+ ### Step 2: Define Widget Type Constants
137
+
138
+ Add your widget type to the constants file:
139
+
140
+ ```tsx
141
+ // ui/features/widget_dashboard/react/constants.ts
142
+ export const WIDGET_TYPES = {
143
+ COURSE_WORK_SUMMARY: 'course_work_summary',
144
+ MY_WIDGET: 'my_widget', // Add your new widget type here
145
+ } as const
146
+ ```
147
+
148
+ ### Step 3: Register Your Widget in the Registry
149
+
150
+ Update the widget registry to include your new widget:
151
+
152
+ ```tsx
153
+ // ui/features/widget_dashboard/react/components/WidgetRegistry.ts
154
+ import MyWidget from './widgets/MyWidget' // Import your widget
155
+
156
+ const widgetRegistry: WidgetRegistry = {
157
+ [WIDGET_TYPES.COURSE_WORK_SUMMARY]: {
158
+ component: CourseWorkSummaryWidget,
159
+ displayName: "Today's course work",
160
+ description: 'Shows summary of upcoming assignments and course work',
161
+ },
162
+ [WIDGET_TYPES.MY_WIDGET]: {
163
+ component: MyWidget,
164
+ displayName: 'My Custom Widget',
165
+ description: 'A custom widget that demonstrates the widget system',
166
+ },
167
+ }
168
+ ```
169
+
170
+ The registry entry includes:
171
+ - `component`: Your React component
172
+ - `displayName`: Human-readable name for the widget
173
+ - `description`: What the widget does (useful for admin interfaces later)
174
+
175
+ ### Step 4: Add Widget to Dashboard Configuration
176
+
177
+ Add your widget to the default configuration:
178
+
179
+ ```tsx
180
+ // ui/features/widget_dashboard/react/constants.ts
181
+ export const DEFAULT_WIDGET_CONFIG = {
182
+ columns: 3, // 3-column grid layout
183
+ widgets: [
184
+ {
185
+ id: 'course-work-widget',
186
+ type: WIDGET_TYPES.COURSE_WORK_SUMMARY,
187
+ position: {col: 1, row: 1}, // Column 1, Row 1
188
+ size: {width: 2, height: 1}, // Spans 2 columns, 1 row
189
+ title: "Today's course work",
190
+ },
191
+ {
192
+ id: 'my-custom-widget', // Unique identifier
193
+ type: WIDGET_TYPES.MY_WIDGET, // References your widget type
194
+ position: {col: 3, row: 1}, // Column 3, Row 1 (right side)
195
+ size: {width: 1, height: 1}, // Single column, single row
196
+ title: 'My Widget Title', // Will be displayed in header
197
+ },
198
+ ],
199
+ }
200
+ ```
201
+
202
+ ### Step 5: Create Tests for Your Widget
203
+
204
+ Create comprehensive tests following existing patterns:
205
+
206
+ ```tsx
207
+ // ui/features/widget_dashboard/react/components/widgets/MyWidget/__tests__/MyWidget.test.tsx
208
+ import React from 'react'
209
+ import {render, screen, fireEvent} from '@testing-library/react'
210
+ import MyWidget from '../MyWidget'
211
+ import type {BaseWidgetProps} from '../../../../types'
212
+ import type {Widget} from '../../../../types'
213
+
214
+ const mockWidget: Widget = {
215
+ id: 'test-my-widget',
216
+ type: 'my_widget',
217
+ position: {col: 1, row: 1},
218
+ size: {width: 1, height: 1},
219
+ title: 'Test My Widget',
220
+ }
221
+
222
+ const buildDefaultProps = (overrides: Partial<BaseWidgetProps> = {}): BaseWidgetProps => {
223
+ return {
224
+ widget: mockWidget,
225
+ ...overrides,
226
+ }
227
+ }
228
+
229
+ describe('MyWidget', () => {
230
+ it('renders widget content', () => {
231
+ render(<MyWidget {...buildDefaultProps()} />)
232
+ expect(screen.getByText('This is my custom widget content')).toBeInTheDocument()
233
+ expect(screen.getByRole('button', {name: 'Widget Action'})).toBeInTheDocument()
234
+ })
235
+
236
+ it('handles loading state', () => {
237
+ render(<MyWidget {...buildDefaultProps({isLoading: true})} />)
238
+
239
+ expect(screen.getByText('Loading widget data...')).toBeInTheDocument()
240
+ })
241
+
242
+ it('handles error state', () => {
243
+ const onRetry = vi.fn()
244
+ render(<MyWidget {...buildDefaultProps({error: 'Failed to load', onRetry})} />)
245
+
246
+ expect(screen.getByText('Failed to load')).toBeInTheDocument()
247
+ expect(screen.getByRole('button', {name: 'Retry'})).toBeInTheDocument()
248
+ })
249
+ })
250
+ ```
251
+
252
+ ### Step 6: Run Tests and Verify
253
+
254
+ After creating your widget, run the tests to ensure everything works:
255
+
256
+ ```bash
257
+ # Run your specific widget tests
258
+ npm test -- ui/features/widget_dashboard/react/components/widgets/MyWidget/__tests__/MyWidget.test.tsx
259
+
260
+ # Run all widget dashboard tests
261
+ npm test -- ui/features/widget_dashboard/
262
+
263
+ # Check TypeScript compilation
264
+ yarn check:ts
265
+ ```
266
+
267
+ ## Grid System
268
+
269
+ The dashboard uses CSS Grid with the following concepts:
270
+
271
+ - **Position**: `{col: 3, row: 1}` means column 3, row 1
272
+ - **Size**: `{width: 2, height: 1}` means spans 2 columns, 1 row height
273
+ - **Grid**: Currently 3 columns wide, unlimited rows
274
+
275
+ ### Positioning Examples
276
+
277
+ ```tsx
278
+ // Full width widget at top
279
+ position: {col: 1, row: 1}, size: {width: 3, height: 1}
280
+
281
+ // Left side widget
282
+ position: {col: 1, row: 2}, size: {width: 1, height: 1}
283
+
284
+ // Right side widget (spans 2 columns)
285
+ position: {col: 2, row: 2}, size: {width: 2, height: 1}
286
+ ```
287
+
288
+ ## Benefits of the Template System
289
+
290
+ ### What You Get for Free
291
+
292
+ By extending TemplateWidget, your widget automatically gets:
293
+ - Consistent padding, shadows, and border radius
294
+ - Loading spinner during data fetching
295
+ - Error states with retry buttons
296
+ - Header with title and optional actions
297
+ - Responsive design
298
+ - Accessibility features
299
+ - Test utilities and patterns
300
+
301
+ ### System Benefits
302
+
303
+ 1. **Consistent UI**: All widgets use the same TemplateWidget base for consistent styling
304
+ 2. **Built-in States**: Loading, error, and retry functionality comes free
305
+ 3. **Type Safety**: TypeScript ensures proper widget configuration
306
+ 4. **Testability**: Clear patterns for testing widgets
307
+ 5. **Scalability**: Easy to add new widgets without modifying core code
308
+ 6. **Future-Ready**: Designed to work with database-driven configuration
309
+
310
+ ## TypeScript Interfaces
311
+
312
+ ### BaseWidgetProps
313
+ ```tsx
314
+ interface BaseWidgetProps {
315
+ widget: Widget
316
+ isLoading?: boolean
317
+ error?: string | null
318
+ onRetry?: () => void
319
+ }
320
+ ```
321
+
322
+ ### Widget
323
+ ```tsx
324
+ interface Widget {
325
+ id: string
326
+ type: string
327
+ position: WidgetPosition
328
+ size: WidgetSize
329
+ title: string
330
+ }
331
+ ```
332
+
333
+ ### WidgetRenderer
334
+ ```tsx
335
+ interface WidgetRenderer {
336
+ component: React.ComponentType<BaseWidgetProps>
337
+ displayName: string
338
+ description: string
339
+ }
340
+ ```
341
+
342
+ ## Future Enhancements
343
+
344
+ - Database-driven widget configuration
345
+ - User customization of widget layout
346
+ - Widget-specific settings and preferences
347
+ - Drag-and-drop widget positioning
348
+ - Additional widget types for various Canvas features
349
+
350
+ ## Testing
351
+
352
+ The widget dashboard includes comprehensive test coverage:
353
+ - Unit tests for all components
354
+ - Integration tests for the widget registry
355
+ - Test utilities for creating new widget tests
356
+
357
+ Run the test suite with:
358
+
359
+ ```bash
360
+ npm test -- ui/features/widget_dashboard/
361
+ ```
362
+
363
+ ## Development
364
+
365
+ When developing widgets, your component only needs to focus on its core functionality. The TemplateWidget base handles all common UI patterns, state management, and user interactions, allowing you to concentrate on delivering value-specific features.
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const CoursesTab: React.FC;
4
+ export default CoursesTab;
5
+ //# sourceMappingURL=CoursesTab.canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoursesTab.canvas.d.ts","sourceRoot":"","sources":["../../src/components/CoursesTab.canvas.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAO1D,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAuFvB,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const CoursesTabStub: React.FC;
4
+ export default CoursesTabStub;
5
+ //# sourceMappingURL=CoursesTabWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoursesTabWrapper.d.ts","sourceRoot":"","sources":["../../src/components/CoursesTabWrapper.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAM3B,CAAA;AAED,eAAe,cAAc,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const DashboardNotifications: React.FC;
4
+ export default DashboardNotifications;
5
+ //# sourceMappingURL=DashboardNotifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardNotifications.d.ts","sourceRoot":"","sources":["../../src/components/DashboardNotifications.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAuDvC,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EA0FnC,CAAA;AAED,eAAe,sBAAsB,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const DashboardTab: React.FC;
4
+ export default DashboardTab;
5
+ //# sourceMappingURL=DashboardTab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardTab.d.ts","sourceRoot":"","sources":["../../src/components/DashboardTab.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EASzB,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const DashboardTabs: React.FC;
4
+ export default DashboardTabs;
5
+ //# sourceMappingURL=DashboardTabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardTabs.d.ts","sourceRoot":"","sources":["../../src/components/DashboardTabs.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAYzB,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EA6D1B,CAAA;AAED,eAAe,aAAa,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface EnrollmentInvitationData {
4
+ id: string;
5
+ uuid: string;
6
+ course: {
7
+ id: string;
8
+ name: string;
9
+ };
10
+ role: {
11
+ name: string;
12
+ };
13
+ roleLabel: string;
14
+ }
15
+ interface EnrollmentInvitationProps {
16
+ invitation: EnrollmentInvitationData;
17
+ onAccept?: (invitationId: string) => void;
18
+ onReject?: (invitationId: string) => void;
19
+ }
20
+ declare const EnrollmentInvitation: React.FC<EnrollmentInvitationProps>;
21
+ export default EnrollmentInvitation;
22
+ //# sourceMappingURL=EnrollmentInvitation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnrollmentInvitation.d.ts","sourceRoot":"","sources":["../../src/components/EnrollmentInvitation.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAgC1C,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,yBAAyB;IACjC,UAAU,EAAE,wBAAwB,CAAA;IACpC,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;CAC1C;AAED,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA6I7D,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const FeedbackQuestionTile: React.FC;
4
+ export default FeedbackQuestionTile;
5
+ //# sourceMappingURL=FeedbackQuestionTile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeedbackQuestionTile.d.ts","sourceRoot":"","sources":["../../src/components/FeedbackQuestionTile.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAMtC,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAiEjC,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface AccountNotificationData {
4
+ id: string;
5
+ subject: string;
6
+ message: string;
7
+ startAt: string;
8
+ endAt: string;
9
+ accountName?: string;
10
+ siteAdmin: boolean;
11
+ notificationType?: string;
12
+ }
13
+ interface NotificationAlertProps {
14
+ notification: AccountNotificationData;
15
+ onDismiss: (id: string) => void;
16
+ }
17
+ declare const NotificationAlert: React.FC<NotificationAlertProps>;
18
+ export default NotificationAlert;
19
+ //# sourceMappingURL=NotificationAlert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationAlert.d.ts","sourceRoot":"","sources":["../../src/components/NotificationAlert.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,UAAU,sBAAsB;IAC9B,YAAY,EAAE,uBAAuB,CAAA;IACrC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AA2BD,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA+CvD,CAAA;AAED,eAAe,iBAAiB,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+
3
+ declare const WidgetDashboardContainer: React.FC;
4
+ export default WidgetDashboardContainer;
5
+ //# sourceMappingURL=WidgetDashboardContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetDashboardContainer.d.ts","sourceRoot":"","sources":["../../src/components/WidgetDashboardContainer.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAoB,MAAM,OAAO,CAAA;AAUxC,QAAA,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAyGrC,CAAA;AAED,eAAe,wBAAwB,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { default as React } from 'react';
2
+ import { WidgetConfig } from '../types';
3
+
4
+ interface WidgetGridProps {
5
+ config?: WidgetConfig;
6
+ isEditMode?: boolean;
7
+ }
8
+ export declare const WidgetGrid: React.FC<WidgetGridProps>;
9
+ export {};
10
+ //# sourceMappingURL=WidgetGrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetGrid.d.ts","sourceRoot":"","sources":["../../src/components/WidgetGrid.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,UAAU,CAAA;AAGpD,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAwChD,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ import { BaseWidgetProps } from '../types';
3
+
4
+ interface WidgetRendererProps extends BaseWidgetProps {
5
+ }
6
+ export declare const WidgetRenderer: React.FC<WidgetRendererProps>;
7
+ export {};
8
+ //# sourceMappingURL=WidgetRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetRenderer.d.ts","sourceRoot":"","sources":["../../src/components/WidgetRenderer.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C,UAAU,mBAAoB,SAAQ,eAAe;CAEpD;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAWxD,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface CourseCodeProps {
4
+ courseId: string;
5
+ gridIndex?: number;
6
+ size?: 'x-small' | 'small' | 'medium';
7
+ className?: string;
8
+ overrideCode?: string;
9
+ overrideColor?: {
10
+ background: string;
11
+ textColor: string;
12
+ };
13
+ useCustomColors?: boolean;
14
+ maxWidth?: string;
15
+ }
16
+ export declare const CourseCode: React.FC<CourseCodeProps>;
17
+ export default CourseCode;
18
+ //# sourceMappingURL=CourseCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CourseCode.d.ts","sourceRoot":"","sources":["../../../src/components/shared/CourseCode.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAgChD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAA;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAoEhD,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface CourseFilterSelectProps {
4
+ selectedCourse: string;
5
+ onChange: (event: React.SyntheticEvent, data: {
6
+ value?: string | number;
7
+ id?: string;
8
+ }) => void;
9
+ disabled?: boolean;
10
+ renderLabel?: string;
11
+ }
12
+ declare const CourseFilterSelect: React.FC<CourseFilterSelectProps>;
13
+ export default CourseFilterSelect;
14
+ //# sourceMappingURL=CourseFilterSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CourseFilterSelect.d.ts","sourceRoot":"","sources":["../../../src/components/shared/CourseFilterSelect.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAKtC,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAkCzD,CAAA;AAED,eAAe,kBAAkB,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface CourseNameProps {
4
+ courseName: string;
5
+ maxLines?: number;
6
+ }
7
+ export declare const CourseName: React.FC<CourseNameProps>;
8
+ export default CourseName;
9
+ //# sourceMappingURL=CourseName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CourseName.d.ts","sourceRoot":"","sources":["../../../src/components/shared/CourseName.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA+BhD,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { default as React } from 'react';
2
+
3
+ export type DateFilterOption = 'not_submitted' | 'missing' | 'submitted';
4
+ export interface DateFilterConfig {
5
+ id: DateFilterOption;
6
+ label: string;
7
+ }
8
+ export declare function isValidDateFilterOption(value: unknown): value is DateFilterOption;
9
+ export interface CourseWorkFiltersProps {
10
+ selectedCourse: string;
11
+ selectedDateFilter: DateFilterOption;
12
+ onCourseChange: (event: React.SyntheticEvent, data: {
13
+ value?: string | number;
14
+ id?: string;
15
+ }) => void;
16
+ onDateFilterChange: (event: React.SyntheticEvent, data: {
17
+ value?: string | number;
18
+ id?: string;
19
+ }) => void;
20
+ }
21
+ declare const CourseWorkFilters: React.FC<CourseWorkFiltersProps>;
22
+ export default CourseWorkFilters;
23
+ //# sourceMappingURL=CourseWorkFilters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CourseWorkFilters.d.ts","sourceRoot":"","sources":["../../../src/components/shared/CourseWorkFilters.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAKtC,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,SAAS,GAAG,WAAW,CAAA;AAExE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,gBAAgB,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAKjF;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAA;IACtB,kBAAkB,EAAE,gBAAgB,CAAA;IACpC,cAAc,EAAE,CACd,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,KAC3C,IAAI,CAAA;IACT,kBAAkB,EAAE,CAClB,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,KAC3C,IAAI,CAAA;CACV;AAED,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAuCvD,CAAA;AAED,eAAe,iBAAiB,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface StatisticsCardProps {
4
+ count: number;
5
+ label: string;
6
+ backgroundColor: string;
7
+ }
8
+ declare const StatisticsCard: React.FC<StatisticsCardProps>;
9
+ export default StatisticsCard;
10
+ //# sourceMappingURL=StatisticsCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatisticsCard.d.ts","sourceRoot":"","sources":["../../../src/components/shared/StatisticsCard.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA4BjD,CAAA;AAED,eAAe,cAAc,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface StatisticsData {
4
+ due: number;
5
+ missing: number;
6
+ submitted: number;
7
+ }
8
+ export interface StatisticsCardsGridProps {
9
+ summary: StatisticsData;
10
+ margin?: string;
11
+ }
12
+ declare const StatisticsCardsGrid: React.FC<StatisticsCardsGridProps>;
13
+ export default StatisticsCardsGrid;
14
+ //# sourceMappingURL=StatisticsCardsGrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatisticsCardsGrid.d.ts","sourceRoot":"","sources":["../../../src/components/shared/StatisticsCardsGrid.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAKtC,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA2C3D,CAAA;AAED,eAAe,mBAAmB,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { default as React } from 'react';
2
+ import { Widget, WidgetConfig } from '../../types';
3
+
4
+ interface WidgetContextMenuProps {
5
+ trigger: React.ReactElement;
6
+ widget: Widget;
7
+ config: WidgetConfig;
8
+ onSelect?: (action: string) => void;
9
+ }
10
+ declare const WidgetContextMenu: React.FC<WidgetContextMenuProps>;
11
+ export default WidgetContextMenu;
12
+ //# sourceMappingURL=WidgetContextMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/shared/WidgetContextMenu.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEvD,UAAU,sBAAsB;IAC9B,OAAO,EAAE,KAAK,CAAC,YAAY,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,YAAY,CAAA;IACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC;AAeD,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAsDvD,CAAA;AAED,eAAe,iBAAiB,CAAA"}