diff --git a/.env b/.env deleted file mode 100644 index 706b300..0000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -GRADER_API_URL=http://localhost:8000 \ No newline at end of file diff --git a/.env.sample b/.env.sample index 706b300..037abf7 100644 --- a/.env.sample +++ b/.env.sample @@ -1 +1,13 @@ -GRADER_API_URL=http://localhost:8000 \ No newline at end of file +# Base URL of the Grader API +GRADER_API_URL=http://localhost:8000 +# User's onyen +USER_ONYEN=myonyen +# User's password +USER_AUTOGEN_PASSWORD=mypassword +# How far ahead of time to refresh the user's access token +# (proactively refreshing deals with issues such as latency and clock sync) +JWT_REFRESH_LEEWAY_SECONDS=60 +# How long to keep long-polling connections alive before dropping the client (Jupyter frontend). +LONG_POLLING_TIMEOUT_SECONDS=60 +# For polling that depends on unobservable data, how long to sleep in between data fetches. +LONG_POLLING_SLEEP_INTERVAL_SECONDS=5 \ No newline at end of file diff --git a/eduhelx_jupyterlab_student/config.py b/eduhelx_jupyterlab_student/config.py index 06de53d..b411794 100644 --- a/eduhelx_jupyterlab_student/config.py +++ b/eduhelx_jupyterlab_student/config.py @@ -18,6 +18,10 @@ class Config: # How far ahead of time the API should refresh the access token # (proactively refreshing using a buffer deals with issues such as latency and clock sync) JWT_REFRESH_LEEWAY_SECONDS: int = 60 + # How long to keep long-polling connections alive before dropping the client. + LONG_POLLING_TIMEOUT_SECONDS: int = 60 + # For polling that depends on unobservable data, how long to sleep in between data fetches. + LONG_POLLING_SLEEP_INTERVAL_SECONDS: int = 5 """ Map environment variables to class fields according to these rules: diff --git a/eduhelx_jupyterlab_student/handlers.py b/eduhelx_jupyterlab_student/handlers.py index 1541a55..04145ec 100644 --- a/eduhelx_jupyterlab_student/handlers.py +++ b/eduhelx_jupyterlab_student/handlers.py @@ -5,15 +5,19 @@ import tempfile import shutil import tornado +import time +import asyncio from jupyter_server.base.handlers import APIHandler from jupyter_server.utils import url_path_join from pathlib import Path +from collections.abc import Iterable from .config import ExtensionConfig from eduhelx_utils.git import ( InvalidGitRepositoryException, clone_repository, get_tail_commit_id, get_repo_name, add_remote, - stage_files, commit, push, get_commit_info + stage_files, commit, push, get_commit_info, + get_modified_paths ) from eduhelx_utils.api import Api from .student_repo import StudentClassRepo, NotStudentClassRepositoryException @@ -123,20 +127,60 @@ async def post(self): self.finish(json.dumps(os.path.join("/", frontend_cloned_path))) -class CourseAndStudentHandler(BaseHandler): +class PollCourseStudentHandler(BaseHandler): @tornado.web.authenticated async def get(self): + # If this is the first poll the client has made, the `current_value` argument will not be present. + # Note: we are not deserializing `current_value`; it is a JSON-serialized string. + current_value: str | None = None + if "current_value" in self.request.arguments: + current_value = self.get_argument("current_value") + + start = time.time() + while (elapsed := time.time() - start) < self.config.LONG_POLLING_TIMEOUT_SECONDS: + new_value = await CourseAndStudentHandler.get_value(self) + if new_value != current_value: + self.finish(new_value) + return + asyncio.sleep(self.config.LONG_POLLING_SLEEP_INTERVAL_SECONDS) + + self.finish(new_value) + +class CourseAndStudentHandler(BaseHandler): + async def get_value(self): student = await self.api.get_my_user() course = await self.api.get_course() - self.finish(json.dumps({ + return json.dumps({ "student": student, "course": course - })) + }) + + @tornado.web.authenticated + async def get(self): + self.finish(await self.get_value()) -class AssignmentsHandler(BaseHandler): +class PollAssignmentsHandler(BaseHandler): @tornado.web.authenticated async def get(self): current_path: str = self.get_argument("path") + # If this is the first poll the client has made, the `current_value` argument will not be present. + # Note: we are not deserializing `current_value`; it is a JSON-serialized string. + current_value: str | None = None + if "current_value" in self.request.arguments: + current_value = self.get_argument("current_value") + + start = time.time() + while (elapsed := time.time() - start) < self.config.LONG_POLLING_TIMEOUT_SECONDS: + new_value = await AssignmentsHandler.get_value(self, current_path) + if new_value != current_value: + self.finish(new_value) + return + asyncio.sleep(self.config.LONG_POLLING_SLEEP_INTERVAL_SECONDS) + + self.finish(new_value) + +class AssignmentsHandler(BaseHandler): + async def get_value(self, current_path: str): current_path_abs = os.path.realpath(current_path) student = await self.api.get_my_user() @@ -145,14 +189,13 @@ async def get(self): value = { "current_assignment": None, - "assignments": None + "assignments": None, } try: student_repo = StudentClassRepo(course, assignments, current_path_abs) except Exception: - self.finish(json.dumps(value)) - return + return json.dumps(value) # Add absolute path to assignment so that the frontend # extension knows how to open the assignment without having @@ -166,21 +209,40 @@ async def get(self): cwd ) # The cwd is the root in the frontend, so treat the path as such. + # NOTE: IMPORTANT: this field is NOT absolute on the server. It's only the absolute path for the webapp. assignment["absolute_directory_path"] = os.path.join("/", rel_assignment_path) value["assignments"] = assignments - # The student is in their repo, but we still need to check if they're actually in an assignment directory. current_assignment = student_repo.current_assignment - if current_assignment is not None: - submissions = await self.api.get_my_submissions(current_assignment["id"]) - for submission in submissions: - submission["commit"] = get_commit_info(submission["commit_id"], path=student_repo.repo_root) - current_assignment["submissions"] = submissions - - value["current_assignment"] = current_assignment - self.finish(json.dumps(value)) - else: - self.finish(json.dumps(value)) + # The student is in their repo, but we still need to check if they're actually in an assignment directory. + if current_assignment is None: + # If user is not in an assignment, we're done. Just leave current_assignment as None. + return json.dumps(value) + + submissions = await self.api.get_my_submissions(current_assignment["id"]) + for submission in submissions: + submission["commit"] = get_commit_info(submission["commit_id"], path=student_repo.repo_root) + current_assignment["submissions"] = submissions + current_assignment["staged_changes"] = [] + for modified_path in get_modified_paths(path=student_repo.repo_root): + full_modified_path = Path(student_repo.repo_root) / modified_path["path"] + abs_assn_path = Path(student_repo.repo_root) / assignment["directory_path"] + try: + path_relative_to_assn = full_modified_path.relative_to(abs_assn_path) + modified_path["path_from_repo"] = modified_path["path"] + modified_path["path_from_assn"] = str(path_relative_to_assn) + current_assignment["staged_changes"].append(modified_path) + except ValueError: + # This path is not part of the current assignment directory + pass + + value["current_assignment"] = current_assignment + return json.dumps(value) + + @tornado.web.authenticated + async def get(self): + current_path: str = self.get_argument("path") + self.finish(await self.get_value(current_path)) class SubmissionHandler(BaseHandler): @@ -256,14 +318,17 @@ def setup_handlers(server_app): base_url = web_app.settings["base_url"] handlers = [ ("assignments", AssignmentsHandler), + (("assignments", "poll"), PollAssignmentsHandler), ("course_student", CourseAndStudentHandler), + (("course_student", "poll"), PollCourseStudentHandler), ("submit_assignment", SubmissionHandler), ("clone_student_repository", CloneStudentRepositoryHandler), ("settings", SettingsHandler) ] + handlers_with_path = [ ( - url_path_join(base_url, "jupyterlab-eduhelx-submission", uri), + url_path_join(base_url, "eduhelx-jupyterlab-student", *(uri if not isinstance(uri, str) else [uri])), handler ) for (uri, handler) in handlers ] diff --git a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/lib_index_js.145449ba8616931d9a24.js b/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/lib_index_js.145449ba8616931d9a24.js deleted file mode 100644 index 0661590..0000000 --- a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/lib_index_js.145449ba8616931d9a24.js +++ /dev/null @@ -1,2158 +0,0 @@ -"use strict"; -(self["webpackChunkjupyterlab_eduhelx_submission"] = self["webpackChunkjupyterlab_eduhelx_submission"] || []).push([["lib_index_js"],{ - -/***/ "./lib/api/api.js": -/*!************************!*\ - !*** ./lib/api/api.js ***! - \************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ cloneStudentRepository: () => (/* binding */ cloneStudentRepository), -/* harmony export */ getAssignments: () => (/* binding */ getAssignments), -/* harmony export */ getServerSettings: () => (/* binding */ getServerSettings), -/* harmony export */ getStudentAndCourse: () => (/* binding */ getStudentAndCourse), -/* harmony export */ submitAssignment: () => (/* binding */ submitAssignment) -/* harmony export */ }); -/* harmony import */ var qs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! qs */ "webpack/sharing/consume/default/qs/qs"); -/* harmony import */ var qs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(qs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/services */ "webpack/sharing/consume/default/@jupyterlab/services"); -/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _handler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../handler */ "./lib/handler.js"); -/* harmony import */ var _assignment__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./assignment */ "./lib/api/assignment.js"); -/* harmony import */ var _student__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./student */ "./lib/api/student.js"); -/* harmony import */ var _course__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./course */ "./lib/api/course.js"); -/* harmony import */ var _server_settings__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./server-settings */ "./lib/api/server-settings.js"); - - - - - - - -async function getStudentAndCourse() { - const { student, course } = await (0,_handler__WEBPACK_IMPORTED_MODULE_2__.requestAPI)(`/course_student`, { - method: 'GET' - }); - return { - student: _student__WEBPACK_IMPORTED_MODULE_3__.Student.fromResponse(student), - course: _course__WEBPACK_IMPORTED_MODULE_4__.Course.fromResponse(course) - }; -} -async function getAssignments(path) { - const { assignments, current_assignment } = await (0,_handler__WEBPACK_IMPORTED_MODULE_2__.requestAPI)(`/assignments?${qs__WEBPACK_IMPORTED_MODULE_0___default().stringify({ path })}`, { - method: 'GET' - }); - return { - assignments: assignments ? assignments.map((data) => _assignment__WEBPACK_IMPORTED_MODULE_5__.Assignment.fromResponse(data)) : null, - currentAssignment: current_assignment ? _assignment__WEBPACK_IMPORTED_MODULE_5__.Assignment.fromResponse(current_assignment) : null - }; -} -async function getServerSettings() { - try { - const data = await (0,_handler__WEBPACK_IMPORTED_MODULE_2__.requestAPI)('/settings', { - method: 'GET' - }); - return _server_settings__WEBPACK_IMPORTED_MODULE_6__.ServerSettings.fromResponse(data); - } - catch (e) { - if (e instanceof _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.ResponseError) { - const response = e.response; - if (response.status === 404) { - const message = 'EduHeLx Submission server extension is unavailable. Please ensure you have installed the ' + - 'JupyterLab EduHeLx Submission server extension by running: pip install --upgrade jupyterlab_eduhelx_submission. ' + - 'To confirm that the server extension is installed, run: jupyter server extension list.'; - throw new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.ResponseError(response, message); - } - else { - const message = e.message; - console.error('Failed to get the server extension settings', message); - throw new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.ResponseError(response, message); - } - } - else { - throw e; - } - } -} -async function submitAssignment(currentPath, summary, description) { - const res = await (0,_handler__WEBPACK_IMPORTED_MODULE_2__.requestAPI)(`/submit_assignment`, { - method: 'POST', - body: JSON.stringify({ - summary, - description, - current_path: currentPath - }) - }); -} -async function cloneStudentRepository(repositoryUrl, currentPath) { - const repositoryRootPath = await (0,_handler__WEBPACK_IMPORTED_MODULE_2__.requestAPI)(`/clone_student_repository`, { - method: 'POST', - body: JSON.stringify({ - repository_url: repositoryUrl, - current_path: currentPath - }) - }); - return repositoryRootPath; -} - - -/***/ }), - -/***/ "./lib/api/assignment.js": -/*!*******************************!*\ - !*** ./lib/api/assignment.js ***! - \*******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Assignment: () => (/* binding */ Assignment) -/* harmony export */ }); -/* harmony import */ var _submission__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./submission */ "./lib/api/submission.js"); - -class Assignment { - constructor(_id, _name, _directoryPath, _absoluteDirectoryPath, _createdDate, _adjustedAvailableDate, _adjustedDueDate, _lastModifiedDate, _isDeferred, _isExtended, _isCreated, _isAvailable, _isClosed, _submissions) { - this._id = _id; - this._name = _name; - this._directoryPath = _directoryPath; - this._absoluteDirectoryPath = _absoluteDirectoryPath; - this._createdDate = _createdDate; - this._adjustedAvailableDate = _adjustedAvailableDate; - this._adjustedDueDate = _adjustedDueDate; - this._lastModifiedDate = _lastModifiedDate; - this._isDeferred = _isDeferred; - this._isExtended = _isExtended; - this._isCreated = _isCreated; - this._isAvailable = _isAvailable; - this._isClosed = _isClosed; - this._submissions = _submissions; - } - get id() { return this._id; } - get name() { return this._name; } - get directoryPath() { return this._directoryPath; } - get absoluteDirectoryPath() { return this._absoluteDirectoryPath; } - get createdDate() { return this._createdDate; } - get adjustedAvailableDate() { return this._adjustedAvailableDate; } - get adjustedDueDate() { return this._adjustedDueDate; } - get lastModifiedDate() { return this._lastModifiedDate; } - get isDeferred() { return this._isDeferred; } - get isExtended() { return this._isExtended; } - get isCreated() { return this._isCreated; } - get isAvailable() { return this._isAvailable; } - get isClosed() { return this._isClosed; } - get submissions() { return this._submissions; } - static fromResponse(data) { - var _a; - return new Assignment(data.id, data.name, data.directory_path, data.absolute_directory_path, new Date(data.created_date), data.adjusted_available_date ? new Date(data.adjusted_available_date) : null, data.adjusted_due_date ? new Date(data.adjusted_due_date) : null, new Date(data.last_modified_date), data.is_deferred, data.is_extended, data.is_created, data.is_available, data.is_closed, (_a = data.submissions) === null || _a === void 0 ? void 0 : _a.map((res) => _submission__WEBPACK_IMPORTED_MODULE_0__.Submission.fromResponse(res))); - } -} - - -/***/ }), - -/***/ "./lib/api/commit.js": -/*!***************************!*\ - !*** ./lib/api/commit.js ***! - \***************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Commit: () => (/* binding */ Commit) -/* harmony export */ }); -class Commit { - constructor(_id, _authorName, _authorEmail, _committerName, _committerEmail, _message) { - this._id = _id; - this._authorName = _authorName; - this._authorEmail = _authorEmail; - this._committerName = _committerName; - this._committerEmail = _committerEmail; - this._message = _message; - } - get id() { return this._id; } - get idShort() { return this._id.slice(0, 7); } - get authorName() { return this._authorName; } - get authorEmail() { return this._authorEmail; } - get committerName() { return this._committerName; } - get committerEmail() { return this._committerEmail; } - get message() { return this._message; } - get summary() { - const [summary, ...description] = this.message.split("\n"); - return summary; - } - get description() { - const [summary, ...description] = this.message.split("\n"); - return description.join("\n"); - } - static fromResponse(data) { - return new Commit(data.id, data.author_name, data.author_email, data.committer_name, data.committer_email, data.message); - } -} - - -/***/ }), - -/***/ "./lib/api/course.js": -/*!***************************!*\ - !*** ./lib/api/course.js ***! - \***************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Course: () => (/* binding */ Course) -/* harmony export */ }); -/* harmony import */ var _instructor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instructor */ "./lib/api/instructor.js"); - -class Course { - constructor(_id, _name, _masterRemoteUrl, _instructors) { - this._id = _id; - this._name = _name; - this._masterRemoteUrl = _masterRemoteUrl; - this._instructors = _instructors; - } - get id() { return this._id; } - get name() { return this._name; } - get masterRemoteUrl() { return this._masterRemoteUrl; } - get instructors() { return this._instructors; } - static fromResponse(data) { - return new Course(data.id, data.name, data.master_remote_url, data.instructors.map((res) => _instructor__WEBPACK_IMPORTED_MODULE_0__.Instructor.fromResponse(res))); - } -} - - -/***/ }), - -/***/ "./lib/api/instructor.js": -/*!*******************************!*\ - !*** ./lib/api/instructor.js ***! - \*******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Instructor: () => (/* binding */ Instructor) -/* harmony export */ }); -/* harmony import */ var _user__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./user */ "./lib/api/user.js"); - -class Instructor extends _user__WEBPACK_IMPORTED_MODULE_0__.User { - constructor(id, onyen, firstName, lastName, email) { - super(id, onyen, firstName, lastName, email); - } - static fromResponse(data) { - return new Instructor(data.id, data.onyen, data.first_name, data.last_name, data.email); - } -} - - -/***/ }), - -/***/ "./lib/api/server-settings.js": -/*!************************************!*\ - !*** ./lib/api/server-settings.js ***! - \************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ServerSettings: () => (/* binding */ ServerSettings) -/* harmony export */ }); -class ServerSettings { - constructor() { } - static fromResponse(data) { - return new ServerSettings(); - } -} - - -/***/ }), - -/***/ "./lib/api/student.js": -/*!****************************!*\ - !*** ./lib/api/student.js ***! - \****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Student: () => (/* binding */ Student) -/* harmony export */ }); -/* harmony import */ var _user__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./user */ "./lib/api/user.js"); - -class Student extends _user__WEBPACK_IMPORTED_MODULE_0__.User { - constructor(id, onyen, firstName, lastName, email, _joinDate, _exitDate) { - super(id, onyen, firstName, lastName, email); - this._joinDate = _joinDate; - this._exitDate = _exitDate; - } - get joinDate() { return this._joinDate; } - get exitDate() { return this._exitDate; } - static fromResponse(data) { - return new Student(data.id, data.onyen, data.first_name, data.last_name, data.email, new Date(data.join_date), data.exit_date ? new Date(data.exit_date) : null); - } -} - - -/***/ }), - -/***/ "./lib/api/submission.js": -/*!*******************************!*\ - !*** ./lib/api/submission.js ***! - \*******************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Submission: () => (/* binding */ Submission) -/* harmony export */ }); -/* harmony import */ var _commit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./commit */ "./lib/api/commit.js"); - -class Submission { - constructor(_id, _active, _submissionTime, _commit) { - this._id = _id; - this._active = _active; - this._submissionTime = _submissionTime; - this._commit = _commit; - } - get id() { return this._id; } - get active() { return this._active; } - get submissionTime() { return this._submissionTime; } - get commit() { return this._commit; } - static fromResponse(data) { - return new Submission(data.id, data.active, new Date(data.submission_time), _commit__WEBPACK_IMPORTED_MODULE_0__.Commit.fromResponse(data.commit)); - } -} - - -/***/ }), - -/***/ "./lib/api/user.js": -/*!*************************!*\ - !*** ./lib/api/user.js ***! - \*************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ User: () => (/* binding */ User) -/* harmony export */ }); -class User { - constructor(_id, _onyen, _firstName, _lastName, _email) { - this._id = _id; - this._onyen = _onyen; - this._firstName = _firstName; - this._lastName = _lastName; - this._email = _email; - } - get id() { return this._id; } - get onyen() { return this._onyen; } - get firstName() { return this._firstName; } - get lastName() { return this._lastName; } - get fullName() { return `${this.firstName} ${this.lastName}`; } - get email() { return this._email; } - static fromResponse(data) { - return new User(data.id, data.onyen, data.first_name, data.last_name, data.onyen); - } -} - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-content/assignment-content.js": -/*!**********************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-content/assignment-content.js ***! - \**********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentContent: () => (/* binding */ AssignmentContent) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/assignment-content/style.js"); -/* harmony import */ var _no_assignment_warning__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../no-assignment-warning */ "./lib/components/assignment-panel/no-assignment-warning/no-assignment-warning.js"); -/* harmony import */ var _assignment_info__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../assignment-info */ "./lib/components/assignment-panel/assignment-info/assignment-info.js"); -/* harmony import */ var _assignment_submissions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../assignment-submissions */ "./lib/components/assignment-panel/assignment-submissions/assignment-submissions.js"); -/* harmony import */ var _assignment_submit_form__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../assignment-submit-form */ "./lib/components/assignment-panel/assignment-submit-form/assignment-submit-form.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/assignment-context.js"); - - - - - - - - -const AssignmentContent = () => { - const { loading, path, assignment, student, assignments } = (0,_contexts__WEBPACK_IMPORTED_MODULE_2__.useAssignment)(); - /* - const [showSelectionView, setShowSelectionView] = useState(true) - - useEffect(() => { - // When the path / active assignment changes, - // if there's an active assignment, show the assignment view. - if (assignment) setShowSelectionView(false) - // If there isn't an assignment in the current directory, show the selection view. - else setShowSelectionView(true) - // Then, users can press a button while in the assignment view, users can press - // a back button to go back to the selection view. - }, [path, assignment?.id]) - */ - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_3__.containerClass }, loading ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_3__.loadingContainerClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.CircularProgress, { color: "inherit" }))) : assignments === null || assignment === null ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_no_assignment_warning__WEBPACK_IMPORTED_MODULE_4__.NoAssignmentWarning, { noRepository: assignments === null })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_3__.assignmentContainerClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_assignment_info__WEBPACK_IMPORTED_MODULE_5__.AssignmentInfo, null), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_assignment_submissions__WEBPACK_IMPORTED_MODULE_6__.AssignmentSubmissions, { style: { flexGrow: 1 } }), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_assignment_submit_form__WEBPACK_IMPORTED_MODULE_7__.AssignmentSubmitForm, null))))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-content/style.js": -/*!*********************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-content/style.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ assignmentContainerClass: () => (/* binding */ assignmentContainerClass), -/* harmony export */ containerClass: () => (/* binding */ containerClass), -/* harmony export */ loadingContainerClass: () => (/* binding */ loadingContainerClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const containerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - flexGrow: 1, - display: 'flex', - flexDirection: 'column' -}); -const loadingContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - margin: '36px 11px 4px 11px', - color: 'var(--md-blue-600)' -}); -const assignmentContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - flexDirection: 'column', - height: '100%' -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-info/assignment-info.js": -/*!****************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-info/assignment-info.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentInfo: () => (/* binding */ AssignmentInfo) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/assignment-info/style.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/assignment-context.js"); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../utils */ "./lib/utils/date-format.js"); - - - - -const MS_IN_HOURS = 3.6e6; -const AssignmentInfo = ({}) => { - const { assignment, student, course } = (0,_contexts__WEBPACK_IMPORTED_MODULE_1__.useAssignment)(); - if (!student || !assignment || !course) - return null; - const hoursUntilDue = assignment.isCreated ? ((assignment.adjustedDueDate.getTime() - Date.now()) / MS_IN_HOURS) : Infinity; - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("header", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentNameClass }, assignment.name), - assignment.isClosed ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h5", { style: { - margin: 0, - marginTop: 8, - fontSize: 13, - color: 'var(--jp-ui-font-color1)', - textTransform: 'uppercase', - letterSpacing: 0.75 - } }, "Closed")) : null), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoSectionClass, style: { marginTop: 16 } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h5", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoSectionHeaderClass }, "Student"), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, - student.firstName, - " ", - student.lastName)), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoSectionClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h5", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoSectionHeaderClass }, - "Professor", - course.instructors.length > 1 ? "s" : ""), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, course.instructors.map((ins) => ins.fullName).join(", "))), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoSectionClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h5", { className: _style__WEBPACK_IMPORTED_MODULE_2__.assignmentInfoSectionHeaderClass }, "Due date"), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, - assignment.isCreated ? (new _utils__WEBPACK_IMPORTED_MODULE_3__.DateFormat(assignment.adjustedDueDate).toBasicDatetime()) : (`To be determined`), - assignment.isExtended ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", null, "\u00A0(extended)")) : null), - assignment.isCreated && !assignment.isClosed && hoursUntilDue <= 2 ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { marginTop: 4, color: 'var(--jp-warn-color0)' } }, - "Warning: ", - new _utils__WEBPACK_IMPORTED_MODULE_3__.DateFormat(assignment.adjustedDueDate).toRelativeDatetime(), - " remaining")) : null))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-info/style.js": -/*!******************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-info/style.js ***! - \******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ assignmentInfoClass: () => (/* binding */ assignmentInfoClass), -/* harmony export */ assignmentInfoSectionClass: () => (/* binding */ assignmentInfoSectionClass), -/* harmony export */ assignmentInfoSectionHeaderClass: () => (/* binding */ assignmentInfoSectionHeaderClass), -/* harmony export */ assignmentNameClass: () => (/* binding */ assignmentNameClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const assignmentInfoClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - fontSize: 'var(--jp-ui-font-size1)', - color: 'var(--jp-ui-font-color2)', - display: 'flex', - flexDirection: 'column', - padding: '0 12px' -}); -const assignmentNameClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - flex: '0 0 auto', - color: 'var(--jp-ui-font-color1)', - fontSize: 'var(--jp-ui-font-size3)', - fontWeight: 600, - marginTop: 6, - padding: '8px 0', - marginBottom: 0, - paddingBottom: 0 -}); -const assignmentInfoSectionClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - color: 'var(--jp-ui-font-color1)', - marginBottom: 16, - '& > *:first-child': { - fontSize: 12 - }, - '& > *': { - fontSize: 14 - } -}); -const assignmentInfoSectionHeaderClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - margin: 0, - marginBottom: 4, - fontWeight: 600 -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-panel.js": -/*!*************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-panel.js ***! - \*************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentPanel: () => (/* binding */ AssignmentPanel) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/icons */ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons"); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_icons__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/style.js"); -/* harmony import */ var _assignment_content__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./assignment-content */ "./lib/components/assignment-panel/assignment-content/assignment-content.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../contexts */ "./lib/contexts/commands-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../contexts */ "./lib/contexts/assignment-context.js"); - - - - - -const AssignmentPanel = ({}) => { - const commands = (0,_contexts__WEBPACK_IMPORTED_MODULE_2__.useCommands)(); - const { course, assignment } = (0,_contexts__WEBPACK_IMPORTED_MODULE_3__.useAssignment)(); - const headerName = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => { - const headerFragments = []; - // if (assignment) headerFragments.push(assignment.name) - if (course) - headerFragments.push(course.name); - headerFragments.push('EduHeLx'); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, headerFragments.join(' • '))); - }, [course]); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_4__.panelWrapperClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("header", { className: _style__WEBPACK_IMPORTED_MODULE_4__.panelHeaderClass }, - assignment && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_1__.ArrowBackSharp, { onClick: () => commands.execute('filebrowser:go-to-path', { - path: `${assignment.absoluteDirectoryPath}/../`, - dontShowBrowser: true - }), style: { marginRight: 8, fontSize: 16, cursor: 'pointer' } })), - headerName), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_assignment_content__WEBPACK_IMPORTED_MODULE_5__.AssignmentContent, null))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-submissions/assignment-submissions.js": -/*!******************************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-submissions/assignment-submissions.js ***! - \******************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentSubmissions: () => (/* binding */ AssignmentSubmissions) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material-ui/icons */ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons"); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/assignment-submissions/style.js"); -/* harmony import */ var _text_divider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../text-divider */ "./lib/components/text-divider/text-divider.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/assignment-context.js"); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../utils */ "./lib/utils/date-format.js"); - - - - - - - -const AssignmentSubmissions = ({ ...props }) => { - const { assignment } = (0,_contexts__WEBPACK_IMPORTED_MODULE_3__.useAssignment)(); - const submissionSource = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => (assignment === null || assignment === void 0 ? void 0 : assignment.submissions.sort((a, b) => b.submissionTime.getTime() - a.submissionTime.getTime())), [assignment]); - if (!assignment) - return null; - if (assignment.submissions.length === 0) - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_4__.noSubmissionsTextContainerClass }, "You haven't made any submissions for this assignment yet. To submit your work, press the \"Submit\" button at the bottom of the page.")); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_4__.assignmentSubmissionsContainerClass, ...props }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_text_divider__WEBPACK_IMPORTED_MODULE_5__.TextDivider, { innerStyle: { fontSize: 'var(--jp-ui-font-size2)' }, style: { padding: '0 12px' } }, "Submissions"), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_4__.assignmentsListClass }, submissionSource.map((submission, i) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ExpansionPanel, { key: submission.id, square: true }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ExpansionPanelSummary, { expandIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__.ExpandMoreSharp, null) }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ListItem, null, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ListItemIcon, { style: { minWidth: 0, marginRight: 16 } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, `#${submissionSource.length - i}`)), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ListItemText, { disableTypography: true }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { fontSize: 12, color: 'var(--jp-ui-font-color2)', marginBottom: 4 } }, new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(submission.submissionTime).toBasicDatetime()), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { fontSize: 13 } }, submission.commit.summary)))), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ExpansionPanelDetails, null, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Card, { variant: "outlined" }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.CardContent, { style: { padding: 0 } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Typography, { variant: "h5", component: "h5", style: { fontSize: 13, fontFamily: "inherit" } }, submission.commit.authorName), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Typography, { style: { fontSize: 12, marginBottom: 4, fontFamily: "inherit" }, color: "textSecondary" }, submission.commit.idShort), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Typography, { variant: "body2", component: "p", style: { - fontSize: 12, - fontFamily: "inherit", - wordBreak: "break-word", - fontStyle: submission.commit.description ? "normal" : "italic" - } }, submission.commit.description || "No description")))))))))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-submissions/style.js": -/*!*************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-submissions/style.js ***! - \*************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ activateSubmissionButtonClass: () => (/* binding */ activateSubmissionButtonClass), -/* harmony export */ assignmentSubmissionsContainerClass: () => (/* binding */ assignmentSubmissionsContainerClass), -/* harmony export */ assignmentSubmissionsHeaderClass: () => (/* binding */ assignmentSubmissionsHeaderClass), -/* harmony export */ assignmentsListClass: () => (/* binding */ assignmentsListClass), -/* harmony export */ assignmentsTableClass: () => (/* binding */ assignmentsTableClass), -/* harmony export */ noSubmissionsTextContainerClass: () => (/* binding */ noSubmissionsTextContainerClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const assignmentSubmissionsContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - flexDirection: 'column' -}); -const assignmentSubmissionsHeaderClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - margin: '0', - marginBottom: '2px', - padding: '0 12px', - fontWeight: 600, - color: 'var(--jp-ui-font-color0)', - fontSize: 'var(--jp-ui-font-size2)' -}); -const noSubmissionsTextContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - width: '100%', - color: 'var(--jp-ui-font-color2)', - fontSize: 'var(--jp-ui-font-size1)', - lineHeight: 'var(--jp-content-line-height)', - textAlign: 'left', - padding: '0 12px', - flexGrow: 1 -}); -const assignmentsTableClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - '& th, & td': { - height: 42, - fontSize: 13, - } -}); -const activateSubmissionButtonClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - fontSize: 13, - backgroundColor: 'var(--jp-layout-color0)', - color: 'var(--jp-ui-font-color0)', - borderRadius: 3, - border: '1px solid var(--jp-border-color2)', - padding: '4px 10px', - cursor: 'pointer' -}); -const assignmentsListClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - flexGrow: 1, - height: 0, - overflowY: 'auto', - padding: 0, - /** Adjusting clashing styles caused by using accordion summaries as ListItem components */ - '& .MuiExpansionPanel-root, & .MuiExpansionPanel-root.Mui-expanded': { - boxShadow: 'none', - margin: 0, - }, - '& .MuiExpansionPanel-root::before, & > div.MuiExpansionPanel-root.Mui-expanded::before': { - top: -1, - left: 0, - right: 0, - height: 1, - content: '""', - opacity: 1, - position: 'absolute', - display: 'block !important' - }, - '& .MuiExpansionPanel-root:first-child::before, & > div.MuiExpansionPanel-root.Mui-expanded:first-child::before': { - display: 'none !important' - }, - '& .MuiExpansionPanelSummary-root, & .MuiExpansionPanelSummary-root.Mui-expanded': { - padding: 0, - minHeight: 'unset' - }, - '& .MuiExpansionPanelSummary-content, & .MuiExpansionPanelSummary-content.Mui-expanded': { - margin: 0 - }, - '& .MuiListItem-root': { - paddingLeft: 12, - paddingRight: 12 - }, - '& .MuiExpansionPanelSummary-expandIcon': { - marginRight: 0 - }, - '& .MuiExpansionPanelDetails-root': { - paddingLeft: 12, - paddingRight: 12 - }, - '& .MuiExpansionPanelDetails-root > .MuiCard-root': { - borderWidth: 0, - borderLeftWidth: '2px !important', - // So that the border aligns with the assignment number, - // and the text aligns with the commit summary - paddingLeft: 22, - marginLeft: 8, - borderRadius: 0 - }, - '& .MuiExpansionPanelDetails-root > .MuiCard-root > .MuiCardContent-root': { - paddingLeft: 0 - } -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.js": -/*!*********************************************************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.js ***! - \*********************************************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentSubmitButton: () => (/* binding */ AssignmentSubmitButton) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/icons */ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons"); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_icons__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/assignment-submit-form/assignment-submit-button/style.js"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../style */ "./lib/components/style.js"); - - - - - -const AssignmentSubmitButton = ({ onClick, disabled = false }) => { - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: (0,typestyle__WEBPACK_IMPORTED_MODULE_2__.classes)(_style__WEBPACK_IMPORTED_MODULE_3__.assignmentSubmitButton, disabled && _style__WEBPACK_IMPORTED_MODULE_4__.disabledButtonClass), disabled: disabled, onClick: onClick }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_1__.PublishSharp, { style: { fontSize: 22, marginRight: 4 } }), - " Submit Assignment")); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-submit-form/assignment-submit-button/style.js": -/*!**************************************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-submit-form/assignment-submit-button/style.js ***! - \**************************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ assignmentSubmitButton: () => (/* binding */ assignmentSubmitButton) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const assignmentSubmitButton = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - fontSize: 14, - backgroundColor: 'var(--md-blue-500)', - border: 0, - borderRadius: 3, - cursor: 'pointer', - color: 'white', - height: 30.75, - display: 'flex', - justifyContent: 'center', - alignItems: 'center' -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-submit-form/assignment-submit-form.js": -/*!******************************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-submit-form/assignment-submit-form.js ***! - \******************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentSubmitForm: () => (/* binding */ AssignmentSubmitForm) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _assignment_submit_button__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./assignment-submit-button */ "./lib/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.js"); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/assignment-submit-form/style.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/assignment-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/backdrop-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/snackbar-context.js"); -/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../api */ "./lib/api/api.js"); - - - - - - -const AssignmentSubmitForm = ({}) => { - const { assignment, path } = (0,_contexts__WEBPACK_IMPORTED_MODULE_2__.useAssignment)(); - const backdrop = (0,_contexts__WEBPACK_IMPORTED_MODULE_3__.useBackdrop)(); - const snackbar = (0,_contexts__WEBPACK_IMPORTED_MODULE_4__.useSnackbar)(); - const [summaryText, setSummaryText] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(""); - const [descriptionText, setDescriptionText] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(""); - const [submitting, setSubmitting] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false); - const disabled = submitting || summaryText === "" || !(assignment === null || assignment === void 0 ? void 0 : assignment.isAvailable) || (assignment === null || assignment === void 0 ? void 0 : assignment.isClosed); - const submitAssignment = async () => { - if (!path) { - // If this component is being rendered, this should never be possible. - console.log("Unknown cwd, can't submit"); - return; - } - setSubmitting(true); - try { - // Use undefined for descriptionText if it is an empty string. - const submission = await (0,_api__WEBPACK_IMPORTED_MODULE_5__.submitAssignment)(path, summaryText, descriptionText !== null && descriptionText !== void 0 ? descriptionText : undefined); - // Only clear summary/description if the submission goes through. - setSummaryText(""); - setDescriptionText(""); - snackbar.open({ - type: 'success', - message: 'Successfully submitted assignment!' - }); - } - catch (e) { - snackbar.open({ - type: 'error', - message: 'Failed to submit assignment!' - }); - } - setSubmitting(false); - }; - (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { - backdrop.setLoading(submitting); - }, [submitting]); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_6__.submitFormContainerClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Input, { className: _style__WEBPACK_IMPORTED_MODULE_6__.summaryClass, classes: { - root: _style__WEBPACK_IMPORTED_MODULE_6__.submitRootClass, - focused: _style__WEBPACK_IMPORTED_MODULE_6__.activeStyle, - disabled: _style__WEBPACK_IMPORTED_MODULE_6__.disabledStyle - }, type: "text", placeholder: "Summary", title: "Enter a summary for the submission (preferably less than 50 characters)", value: summaryText, onChange: (e) => setSummaryText(e.target.value), onKeyDown: (e) => { - if (disabled) - return; - if (e.key === 'Enter') - submitAssignment(); - }, disabled: submitting, required: true, disableUnderline: true, fullWidth: true }), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Input, { className: _style__WEBPACK_IMPORTED_MODULE_6__.descriptionClass, classes: { - root: _style__WEBPACK_IMPORTED_MODULE_6__.submitRootClass, - focused: _style__WEBPACK_IMPORTED_MODULE_6__.activeStyle, - disabled: _style__WEBPACK_IMPORTED_MODULE_6__.disabledStyle - }, multiline: true, rows: 5, rowsMax: 10, placeholder: "Description (optional)", title: "Enter a description for the submission", value: descriptionText, onChange: (e) => setDescriptionText(e.target.value), onKeyDown: (e) => { - // if (disabled) return - // if (e.key === 'Enter') submitAssignment() - }, disabled: submitting, disableUnderline: true, fullWidth: true }), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_assignment_submit_button__WEBPACK_IMPORTED_MODULE_7__.AssignmentSubmitButton, { onClick: submitAssignment, disabled: disabled }))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignment-submit-form/style.js": -/*!*************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignment-submit-form/style.js ***! - \*************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ activeStyle: () => (/* binding */ activeStyle), -/* harmony export */ descriptionClass: () => (/* binding */ descriptionClass), -/* harmony export */ disabledStyle: () => (/* binding */ disabledStyle), -/* harmony export */ submitFormContainerClass: () => (/* binding */ submitFormContainerClass), -/* harmony export */ submitRootClass: () => (/* binding */ submitRootClass), -/* harmony export */ summaryClass: () => (/* binding */ summaryClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const submitFormContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - flexDirection: 'column', - padding: '12px 8px', - borderTop: 'var(--jp-border-width) solid var(--jp-border-color2)' -}); -const submitRootClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - color: 'var(--jp-ui-font-color1) !important', - fontSize: 'var(--jp-ui-font-size1) !important', - fontFamily: 'var(--jp-ui-font-family) !important', - backgroundColor: 'var(--jp-layout-color1) !important' -}); -const summaryClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - height: '2em', - marginBottom: '1em', - padding: 'var(--jp-code-padding)', - outline: 'none', - overflowX: 'auto', - border: 'var(--jp-border-width) solid var(--jp-border-color2)', - borderRadius: 3, - $nest: { - '&.Mui-error': { - border: 'calc(2 * var(--jp-border-width)) solid var(--jp-error-color1)' - } - } -}); -const descriptionClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - marginBottom: '1em', - padding: 'var(--jp-code-padding)', - paddingLeft: '5px !important', - paddingRight: '5px !important', - outline: 'none', - overflowX: 'auto', - resize: 'none', - border: 'var(--jp-border-width) solid var(--jp-border-color2)', - borderRadius: 3, - $nest: { - '&>*::placeholder': { - color: 'var(--jp-ui-font-color3)' - }, - '&>*::-webkit-input-placeholder': { - color: 'var(--jp-ui-font-color3)' - }, - '&>*::-moz-placeholder': { - color: 'var(--jp-ui-font-color3)' - }, - '&>*::-ms-input-placeholder': { - color: 'var(--jp-ui-font-color3)' - } - } -}); -const activeStyle = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - outline: 'none', - border: 'var(--jp-border-width) solid var(--jp-brand-color1)' -}); -const disabledStyle = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - cursor: 'not-allowed !important', - color: 'var(--jp-ui-font-color2) !important', - backgroundColor: 'var(--jp-layout-color3) !important', - pointerEvents: 'auto !important' -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignments-list/assignments-list.js": -/*!******************************************************************************!*\ - !*** ./lib/components/assignment-panel/assignments-list/assignments-list.js ***! - \******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentsList: () => (/* binding */ AssignmentsList) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material-ui/icons */ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons"); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/assignments-list/style.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/commands-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/assignment-context.js"); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../utils */ "./lib/utils/date-format.js"); -/* harmony import */ var _assignment_submissions_style__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../assignment-submissions/style */ "./lib/components/assignment-panel/assignment-submissions/style.js"); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../style */ "./lib/components/style.js"); - - - - - - - - - -const ListItemAvatar = _material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ListItemAvatar; -const ListHeader = ({ title }) => { - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: _style__WEBPACK_IMPORTED_MODULE_4__.assignmentListHeaderClass }, title)); -}; -const AssignmentListItem = ({ assignment }) => { - const commands = (0,_contexts__WEBPACK_IMPORTED_MODULE_5__.useCommands)(); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ListItem, { key: assignment.id, className: _style__WEBPACK_IMPORTED_MODULE_4__.assignmentListItemClass, dense: true, style: { - padding: '4px 8px' - } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ListItemText, { disableTypography: true }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { fontSize: 14, fontWeight: 500, marginBottom: 4 } }, assignment.name), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { fontSize: 13, color: 'var(--jp-ui-font-color2' } }, !assignment.isCreated ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "No release date yet")) : - assignment.isClosed ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { title: new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedDueDate).toBasicDatetime() }, - "Closed on ", - new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedDueDate).toBasicDatetime())) : assignment.isAvailable ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { title: new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedDueDate).toBasicDatetime() }, - "Closes in ", - new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedDueDate).toRelativeDatetime(), - assignment.isExtended && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", null, "\u00A0(extended)")))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { display: 'flex', flexDirection: 'column' } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { title: new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedAvailableDate).toBasicDatetime() }, - "Opens in ", - new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedAvailableDate).toRelativeDatetime()), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { title: new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedDueDate).toBasicDatetime(), style: { marginTop: 4, fontSize: 12, display: 'flex', alignItems: 'center' } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__.QueryBuilderOutlined, { style: { fontSize: 16 } }), - "\u00A0Lasts ", - new _utils__WEBPACK_IMPORTED_MODULE_6__.DateFormat(assignment.adjustedDueDate).toRelativeDatetime(assignment.adjustedAvailableDate)))))), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ListItemAvatar, { style: { minWidth: 0, marginLeft: 16 } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Avatar, { variant: "square" }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: (0,typestyle__WEBPACK_IMPORTED_MODULE_3__.classes)(_style__WEBPACK_IMPORTED_MODULE_4__.downloadAssignmentButtonClass, !assignment.isCreated && _style__WEBPACK_IMPORTED_MODULE_7__.disabledButtonClass), disabled: !assignment.isCreated, onClick: () => commands.execute('filebrowser:go-to-path', { - path: assignment.absoluteDirectoryPath, - dontShowBrowser: true - }) }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__.OpenInNewSharp, null)))))); -}; -const AssignmentsBucket = ({ title, assignments, emptyText = "There are currently no assignments to work on.", defaultExpanded = false, }) => { - const [expanded, setExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(defaultExpanded); - const assignmentsSource = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => (assignments === null || assignments === void 0 ? void 0 : assignments.sort((a, b) => { var _a, _b, _c, _d; return ((_b = (_a = a.adjustedAvailableDate) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0) - ((_d = (_c = b.adjustedAvailableDate) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : 0); })), [assignments]); - const isEmpty = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => !assignmentsSource || assignmentsSource.length === 0, [assignmentsSource]); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ExpansionPanel, { className: _style__WEBPACK_IMPORTED_MODULE_4__.assignmentBucketContainerClass, square: true, expanded: expanded, onChange: () => setExpanded(!expanded) }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ExpansionPanelSummary, { expandIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__.ExpandMoreSharp, null), style: { paddingLeft: 11 } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ListHeader, { title: title })), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.ExpansionPanelDetails, { style: { display: 'flex', flexDirection: 'column', paddingTop: 0, paddingLeft: 11, paddingRight: 11 } }, !isEmpty ? (assignmentsSource === null || assignmentsSource === void 0 ? void 0 : assignmentsSource.map((assignment) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(AssignmentListItem, { key: assignment.id, assignment: assignment })))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { style: { color: 'var(--jp-ui-font-color1)' } }, emptyText))))); -}; -const AssignmentsList = () => { - const { assignments } = (0,_contexts__WEBPACK_IMPORTED_MODULE_8__.useAssignment)(); - const upcomingAssignments = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => assignments === null || assignments === void 0 ? void 0 : assignments.filter((assignment) => !assignment.isAvailable), [assignments]); - const activeAssignments = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => assignments === null || assignments === void 0 ? void 0 : assignments.filter((assignment) => assignment.isAvailable && !assignment.isClosed), [assignments]); - const pastAssignments = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => assignments === null || assignments === void 0 ? void 0 : assignments.filter((assignment) => assignment.isAvailable && assignment.isClosed), [assignments]); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { flexGrow: 1, display: 'flex', flexDirection: 'column', width: 'calc(100% + 22px)' } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _assignment_submissions_style__WEBPACK_IMPORTED_MODULE_9__.assignmentsListClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(AssignmentsBucket, { title: `Active${activeAssignments ? " (" + activeAssignments.length + ")" : ""}`, assignments: activeAssignments, emptyText: "There aren't any assignments available to work on at the moment.", defaultExpanded: true }), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(AssignmentsBucket, { title: `Upcoming${upcomingAssignments ? " (" + upcomingAssignments.length + ")" : ""}`, assignments: upcomingAssignments, emptyText: "There aren't any upcoming assignments right now.", defaultExpanded: true }), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(AssignmentsBucket, { title: `Past${pastAssignments ? " (" + pastAssignments.length + ")" : ""}`, assignments: pastAssignments, emptyText: "There aren't any past assignments.", defaultExpanded: false })))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/assignments-list/style.js": -/*!*******************************************************************!*\ - !*** ./lib/components/assignment-panel/assignments-list/style.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ assignmentBucketContainerClass: () => (/* binding */ assignmentBucketContainerClass), -/* harmony export */ assignmentListHeaderClass: () => (/* binding */ assignmentListHeaderClass), -/* harmony export */ assignmentListItemClass: () => (/* binding */ assignmentListItemClass), -/* harmony export */ downloadAssignmentButtonClass: () => (/* binding */ downloadAssignmentButtonClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const assignmentBucketContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - '& .MuiExpansionPanelSummary-expandIcon': { - paddingLeft: 6, - paddingRight: 6 - } -}); -const assignmentListItemClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - '&:first-child': { - paddingTop: '0 !important', - }, - '&:first-child > .MuiListItemText-root': { - marginTop: '0 !important' - } -}); -const assignmentListHeaderClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - color: 'var(--jp-ui-font-color0)', - fontSize: 13, - fontWeight: 500 -}); -const downloadAssignmentButtonClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - backgroundColor: 'var(--md-blue-500)', - border: 0, - borderRadius: 0, - cursor: 'pointer', - color: 'white', - fontSize: 'var(--jp-ui-font-size1)', - width: '100%', - height: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center' -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/no-assignment-warning/no-assignment-warning.js": -/*!****************************************************************************************!*\ - !*** ./lib/components/assignment-panel/no-assignment-warning/no-assignment-warning.js ***! - \****************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ NoAssignmentWarning: () => (/* binding */ NoAssignmentWarning) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material-ui/icons */ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons"); -/* harmony import */ var _material_ui_icons__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./style */ "./lib/components/assignment-panel/no-assignment-warning/style.js"); -/* harmony import */ var _assignments_list__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../assignments-list */ "./lib/components/assignment-panel/assignments-list/assignments-list.js"); -/* harmony import */ var _text_divider__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../text-divider */ "./lib/components/text-divider/text-divider.js"); -/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../api */ "./lib/api/api.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/commands-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../contexts */ "./lib/contexts/assignment-context.js"); -/* harmony import */ var _assignment_submit_form_style__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../assignment-submit-form/style */ "./lib/components/assignment-panel/assignment-submit-form/style.js"); - - - - - - - - - - -const NoAssignmentWarning = ({ noRepository }) => { - const commands = (0,_contexts__WEBPACK_IMPORTED_MODULE_4__.useCommands)(); - const { path } = (0,_contexts__WEBPACK_IMPORTED_MODULE_5__.useAssignment)(); - const [repositoryUrl, setRepositoryUrl] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(''); - const [loading, setLoading] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false); - const [errorMessage, setErrorMessage] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null); - const cloneRepository = async (repositoryUrl) => { - if (!path) { - console.log("Unknown cwd, can't clone"); - return; - } - setLoading(true); - try { - const repositoryRootPath = await (0,_api__WEBPACK_IMPORTED_MODULE_6__.cloneStudentRepository)(repositoryUrl, path); - commands.execute('filebrowser:go-to-path', { - path: repositoryRootPath, - dontShowBrowser: true - }); - } - catch (e) { - setErrorMessage(e.message); - } - setLoading(false); - }; - if (noRepository) - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_7__.containerClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { width: '100%', marginBottom: 4 } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { display: 'flex', alignItems: 'stretch', width: '100%' } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Input, { className: _assignment_submit_form_style__WEBPACK_IMPORTED_MODULE_8__.summaryClass, classes: { - root: _assignment_submit_form_style__WEBPACK_IMPORTED_MODULE_8__.submitRootClass, - focused: _assignment_submit_form_style__WEBPACK_IMPORTED_MODULE_8__.activeStyle, - // disabled: disabledStyle - }, style: { - borderRadius: 0, - borderRight: 'none', - marginBottom: 0, - flexGrow: 1, - height: '2.25em', - borderWidth: 1, - overflow: 'visible' - }, type: "url", placeholder: "Class repository URL", title: "Enter the URL to the class's git repository", error: errorMessage !== null, value: repositoryUrl, onChange: (e) => { - setErrorMessage(null); - setRepositoryUrl(e.target.value); - }, onKeyDown: (e) => { - if (loading) - return; - if (e.key === 'Enter') - cloneRepository(repositoryUrl); - }, - // disabled={ loading } - required: true, disableUnderline: true, fullWidth: true }), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: (0,typestyle__WEBPACK_IMPORTED_MODULE_3__.classes)(_style__WEBPACK_IMPORTED_MODULE_7__.openFileBrowserButtonClass, loading && _assignment_submit_form_style__WEBPACK_IMPORTED_MODULE_8__.disabledStyle), style: { - borderRadius: 0, - margin: 0, - width: '2.25em', - height: '2.25em', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - }, disabled: loading, onClick: () => cloneRepository(repositoryUrl) }, !loading ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_icons__WEBPACK_IMPORTED_MODULE_2__.GetAppSharp, { style: { fontSize: 20 } })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.CircularProgress, { color: "inherit", style: { width: 14, height: 14, color: 'white' } })))), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { color: 'var(--jp-error-color1)', marginTop: 8, marginBottom: 4, fontSize: '0.75rem', wordBreak: 'break-all' } }, errorMessage)), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_7__.textContainerClass }, "You are not currently in your class repository. If you haven't already cloned your class repository, you can download it here."), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_7__.warningTextContainerClass }, "Warning: Don't clone the repository again if you've already downloaded it! Navigate to the repository in the file browser."), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: _style__WEBPACK_IMPORTED_MODULE_7__.openFileBrowserButtonClass, onClick: () => commands.execute('filebrowser:toggle-main') }, "Open the FileBrowser"))); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_7__.containerClass }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: _style__WEBPACK_IMPORTED_MODULE_7__.textContainerClass }, "You are not currently in an assignment. To submit your work, navigate to an assignment in the filebrowser or open it here."), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_text_divider__WEBPACK_IMPORTED_MODULE_9__.TextDivider, { innerStyle: { fontSize: 15 }, style: { width: '100%', marginTop: 12 } }, "Assignments"), - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_assignments_list__WEBPACK_IMPORTED_MODULE_10__.AssignmentsList, null))); -}; - - -/***/ }), - -/***/ "./lib/components/assignment-panel/no-assignment-warning/style.js": -/*!************************************************************************!*\ - !*** ./lib/components/assignment-panel/no-assignment-warning/style.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ containerClass: () => (/* binding */ containerClass), -/* harmony export */ openFileBrowserButtonClass: () => (/* binding */ openFileBrowserButtonClass), -/* harmony export */ textContainerClass: () => (/* binding */ textContainerClass), -/* harmony export */ warningTextContainerClass: () => (/* binding */ warningTextContainerClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const containerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - flexGrow: 1, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - margin: '13px 11px 4px 11px', -}); -const textContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - width: '100%', - fontSize: 'var(--jp-ui-font-size1)', - lineHeight: 'var(--jp-content-line-height)', - textAlign: 'left', -}); -const openFileBrowserButtonClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - backgroundColor: 'var(--md-blue-500)', - border: 0, - borderRadius: 3, - cursor: 'pointer', - color: 'white', - fontSize: 'var(--jp-ui-font-size1)', - height: 28, - margin: '8px 0', - width: 200, -}); -const warningTextContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - fontSize: 12, - fontWeight: 500, - color: 'var(--jp-warn-color0)', - margin: '8px 0' -}); - - -/***/ }), - -/***/ "./lib/components/assignment-panel/style.js": -/*!**************************************************!*\ - !*** ./lib/components/assignment-panel/style.js ***! - \**************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ panelHeaderClass: () => (/* binding */ panelHeaderClass), -/* harmony export */ panelWrapperClass: () => (/* binding */ panelWrapperClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const panelWrapperClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - flexDirection: 'column', - height: '100%', - color: 'var(--jp-ui-font-color1)', - fontSize: 'var(--jp-ui-font-size1)', - background: 'var(--jp-layout-color1) !important', - '&, & *': { boxSizing: 'border-box' } -}); -const panelHeaderClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - alignItems: 'center', - borderBottom: 'var(--jp-border-width) solid var(--jp-border-color2)', - flex: '0 0 auto', - fontSize: 11, - fontWeight: 600, - letterSpacing: 1, - margin: 0, - // It appears slightly off-center vertically, so this is just a small adjustment to fix that. - marginTop: 2, - padding: '8px 12px', - textTransform: 'uppercase' -}); - - -/***/ }), - -/***/ "./lib/components/style.js": -/*!*********************************!*\ - !*** ./lib/components/style.js ***! - \*********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ disabledButtonClass: () => (/* binding */ disabledButtonClass), -/* harmony export */ textDividerClass: () => (/* binding */ textDividerClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const textDividerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({}); -const disabledButtonClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - cursor: 'not-allowed !important', - backgroundColor: 'var(--jp-layout-color3) !important', - pointerEvents: 'auto !important' -}); - - -/***/ }), - -/***/ "./lib/components/text-divider/style.js": -/*!**********************************************!*\ - !*** ./lib/components/text-divider/style.js ***! - \**********************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ textDividerContainerClass: () => (/* binding */ textDividerContainerClass), -/* harmony export */ textDividerTextClass: () => (/* binding */ textDividerTextClass) -/* harmony export */ }); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_0__); - -const textDividerContainerClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'flex', - alignItems: 'center', - color: 'var(--jp-ui-font-color0)', - fontWeight: 500, - textAlign: 'center', - '&::before, &::after': { - content: '""', - position: 'relative', - width: '100%', - borderBottom: 'var(--jp-border-width) solid var(--jp-border-color2)', - transform: 'translateY(50%)' - }, - // Left-align adjustments - '&.left::before': { - width: 'var(--orientation-margin)' - }, - // Right-align adjustmments' - '&.right::after': { - width: 'var(--orientation-margin)' - } -}); -const textDividerTextClass = (0,typestyle__WEBPACK_IMPORTED_MODULE_0__.style)({ - display: 'inline-block' -}); - - -/***/ }), - -/***/ "./lib/components/text-divider/text-divider.js": -/*!*****************************************************!*\ - !*** ./lib/components/text-divider/text-divider.js ***! - \*****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ TextDivider: () => (/* binding */ TextDivider) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! typestyle */ "webpack/sharing/consume/default/typestyle/typestyle"); -/* harmony import */ var typestyle__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(typestyle__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./style */ "./lib/components/text-divider/style.js"); - - - -const TextDivider = ({ orientation = 'left', orientationMargin = 0, innerStyle = {}, style = {}, children, ...props }) => { - const textStyle = orientation === 'left' ? { - marginLeft: orientationMargin, - paddingLeft: orientationMargin !== 0 ? 12 : 0, - paddingRight: 12 - } : orientation === 'right' ? { - marginRight: orientationMargin, - paddingRight: orientationMargin !== 0 ? 12 : 0, - paddingLeft: 12 - } : { - paddingLeft: 12, - paddingRight: 12 - }; - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: (0,typestyle__WEBPACK_IMPORTED_MODULE_1__.classes)(_style__WEBPACK_IMPORTED_MODULE_2__.textDividerContainerClass, orientation), style: { - '--orientation-margin': `${orientationMargin}px`, - ...style - }, ...props }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: _style__WEBPACK_IMPORTED_MODULE_2__.textDividerTextClass, style: { - ...textStyle, - ...innerStyle - } }, children))); -}; - - -/***/ }), - -/***/ "./lib/contexts/assignment-context.js": -/*!********************************************!*\ - !*** ./lib/contexts/assignment-context.js ***! - \********************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentContext: () => (/* binding */ AssignmentContext), -/* harmony export */ AssignmentProvider: () => (/* binding */ AssignmentProvider), -/* harmony export */ useAssignment: () => (/* binding */ useAssignment) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); - -const AssignmentContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(undefined); -const AssignmentProvider = ({ model, children }) => { - const [currentPath, setCurrentPath] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null); - const [currentAssignment, setCurrentAssignment] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined); - const [assignments, setAssignments] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined); - const [student, setStudent] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined); - const [course, setCourse] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined); - const loading = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => (currentAssignment === undefined || - assignments === undefined || - student === undefined || - course === undefined), [currentAssignment, assignments, student, course]); - (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { - setCurrentPath(model.currentPath); - setCurrentAssignment(model.currentAssignment); - setAssignments(model.assignments); - setStudent(model.student); - setCourse(model.course); - const onCurrentPathChanged = (model, change) => { - setCurrentPath(change.newValue); - }; - const onCurrentAssignmentChanged = (model, change) => { - setCurrentAssignment(change.newValue); - }; - const onAssignmentsChanged = (model, change) => { - setAssignments(change.newValue); - }; - const onStudentChanged = (model, change) => { - setStudent(change.newValue); - }; - const onCourseChanged = (model, change) => { - setCourse(change.newValue); - }; - model.currentPathChanged.connect(onCurrentPathChanged); - model.currentAssignmentChanged.connect(onCurrentAssignmentChanged); - model.assignmentsChanged.connect(onAssignmentsChanged); - model.studentChanged.connect(onStudentChanged); - model.courseChanged.connect(onCourseChanged); - return () => { - model.currentPathChanged.disconnect(onCurrentPathChanged); - model.currentAssignmentChanged.disconnect(onCurrentAssignmentChanged); - model.assignmentsChanged.disconnect(onAssignmentsChanged); - model.studentChanged.disconnect(onStudentChanged); - model.courseChanged.disconnect(onCourseChanged); - }; - }, [model]); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(AssignmentContext.Provider, { value: { - assignment: currentAssignment, - assignments, - student, - course, - path: currentPath, - loading - } }, children)); -}; -const useAssignment = () => (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(AssignmentContext); - - -/***/ }), - -/***/ "./lib/contexts/backdrop-context.js": -/*!******************************************!*\ - !*** ./lib/contexts/backdrop-context.js ***! - \******************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ BackdropContext: () => (/* binding */ BackdropContext), -/* harmony export */ BackdropProvider: () => (/* binding */ BackdropProvider), -/* harmony export */ useBackdrop: () => (/* binding */ useBackdrop) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); - - -const BackdropContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(undefined); -const BackdropProvider = ({ children }) => { - const [loading, setLoading] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false); - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(BackdropContext.Provider, { value: { - setLoading - } }, - children, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Modal, { open: loading, disableAutoFocus: true, disableEnforceFocus: true }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { - position: 'absolute', - top: '50%', - left: '50%', - color: 'var(--jp-ui-inverse-font-color0)', - textAlign: 'center' - } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.CircularProgress, { color: "inherit" }))))); -}; -const useBackdrop = () => (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(BackdropContext); - - -/***/ }), - -/***/ "./lib/contexts/commands-context.js": -/*!******************************************!*\ - !*** ./lib/contexts/commands-context.js ***! - \******************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CommandsContext: () => (/* binding */ CommandsContext), -/* harmony export */ CommandsProvider: () => (/* binding */ CommandsProvider), -/* harmony export */ useCommands: () => (/* binding */ useCommands) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); - -const CommandsContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(undefined); -const CommandsProvider = ({ commands, children }) => { - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(CommandsContext.Provider, { value: commands }, children)); -}; -const useCommands = () => (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(CommandsContext); - - -/***/ }), - -/***/ "./lib/contexts/settings-context.js": -/*!******************************************!*\ - !*** ./lib/contexts/settings-context.js ***! - \******************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ SettingsContext: () => (/* binding */ SettingsContext), -/* harmony export */ SettingsProvider: () => (/* binding */ SettingsProvider), -/* harmony export */ useSettings: () => (/* binding */ useSettings) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); - -const SettingsContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(undefined); -const SettingsProvider = ({ settings, children }) => { - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(SettingsContext.Provider, { value: settings }, children)); -}; -const useSettings = () => (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SettingsContext); - - -/***/ }), - -/***/ "./lib/contexts/snackbar-context.js": -/*!******************************************!*\ - !*** ./lib/contexts/snackbar-context.js ***! - \******************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ SnackbarContext: () => (/* binding */ SnackbarContext), -/* harmony export */ SnackbarProvider: () => (/* binding */ SnackbarProvider), -/* harmony export */ useSnackbar: () => (/* binding */ useSnackbar) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material-ui/core */ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99"); -/* harmony import */ var _material_ui_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _material_ui_lab__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material-ui/lab */ "webpack/sharing/consume/default/@material-ui/lab/@material-ui/lab"); -/* harmony import */ var _material_ui_lab__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_material_ui_lab__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! uuid */ "webpack/sharing/consume/default/uuid/uuid"); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_3__); - - - - -const SnackbarContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(undefined); -const SnackbarProvider = ({ children }) => { - const [snackbars, setSnackbars] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({}); - const createSnackbar = (props) => { - var _a, _b, _c; - props.duration = (_a = props.duration) !== null && _a !== void 0 ? _a : 2500; - props.key = (_b = props.key) !== null && _b !== void 0 ? _b : (0,uuid__WEBPACK_IMPORTED_MODULE_3__.v4)(); - props.alignment = (_c = props.alignment) !== null && _c !== void 0 ? _c : { vertical: 'bottom', horizontal: 'right' }; - console.log(props, props.type); - if (!props.content) - props.content = (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_lab__WEBPACK_IMPORTED_MODULE_2__.Alert, { variant: "filled", color: props.type, style: { - // Bug with Mui, Paper class overrides color/severity class styles - backgroundColor: props.type === 'error' ? 'rgb(253, 236, 234)' - : props.type === 'info' ? 'rgb(232, 244, 253)' - : props.type === 'success' ? 'rgb(237, 247, 237)' - : props.type === 'warning' ? 'rgb(255, 248, 230)' - : undefined, - color: props.type === 'error' ? 'rgb(97, 26, 21)' - : props.type === 'info' ? 'rgb(13, 60, 97)' - : props.type === 'success' ? 'rgb(30, 70, 32)' - : props.type === 'warning' ? 'rgb(102, 77, 2)' - : undefined - }, onClose: () => destroySnackbar(props.key) }, props.message)); - setSnackbars((prevSnackbars) => ({ - ...prevSnackbars, - [props.key]: props - })); - return props.key; - }; - const destroySnackbar = (key) => { - setSnackbars((prevSnackbars) => { - const newSnackbars = { ...prevSnackbars }; - delete newSnackbars[key]; - return newSnackbars; - }); - }; - window.open = createSnackbar; - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(SnackbarContext.Provider, { value: { - open: createSnackbar, - destroy: destroySnackbar - } }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, - children, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Portal, null, Object.keys(snackbars).map((key) => { - const { className, duration, alignment, content } = snackbars[key]; - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core__WEBPACK_IMPORTED_MODULE_1__.Snackbar, { key: key, className: className, open: true, autoHideDuration: duration, anchorOrigin: alignment, onClose: () => destroySnackbar(key) }, content)); - }))))); -}; -const useSnackbar = () => (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SnackbarContext); - - -/***/ }), - -/***/ "./lib/handler.js": -/*!************************!*\ - !*** ./lib/handler.js ***! - \************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ requestAPI: () => (/* binding */ requestAPI) -/* harmony export */ }); -/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/coreutils */ "webpack/sharing/consume/default/@jupyterlab/coreutils"); -/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/services */ "webpack/sharing/consume/default/@jupyterlab/services"); -/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__); - - -/** - * Call the API extension - * - * @param endPoint API REST end point for the extension - * @param init Initial values for the request - * @returns The response body interpreted as JSON - */ -async function requestAPI(endPoint = '', init = {}) { - // Make request to Jupyter API - const settings = _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.makeSettings(); - const requestUrl = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_0__.URLExt.join(settings.baseUrl, 'jupyterlab-eduhelx-submission', // API Namespace - endPoint); - let response; - try { - response = await _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.makeRequest(requestUrl, init, settings); - } - catch (error) { - throw new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.NetworkError(error); - } - let data = await response.text(); - if (data.length > 0) { - try { - data = JSON.parse(data); - } - catch (error) { - console.log('Not a JSON response body.', response); - } - } - if (!response.ok) { - throw new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_1__.ServerConnection.ResponseError(response, data.message || data); - } - return data; -} - - -/***/ }), - -/***/ "./lib/index.js": -/*!**********************!*\ - !*** ./lib/index.js ***! - \**********************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/application */ "webpack/sharing/consume/default/@jupyterlab/application"); -/* harmony import */ var _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _jupyterlab_filebrowser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/filebrowser */ "webpack/sharing/consume/default/@jupyterlab/filebrowser"); -/* harmony import */ var _jupyterlab_filebrowser__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_filebrowser__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils"); -/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./api */ "./lib/api/api.js"); -/* harmony import */ var _widgets__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./widgets */ "./lib/widgets/assignment-widget.js"); -/* harmony import */ var _model__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./model */ "./lib/model.js"); -/* harmony import */ var _style_icons__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./style/icons */ "./lib/style/icons.js"); - - - - - - - -async function activate(app, fileBrowser, restorer, shell) { - let serverSettings; - try { - serverSettings = await (0,_api__WEBPACK_IMPORTED_MODULE_3__.getServerSettings)(); - } - catch (e) { - console.error('Failed to load the eduhelx_jupyterlab_student extension settings', e); - (0,_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_2__.showErrorMessage)('Failed to load the jupyterlab_eduhelx_submission server extension', e.message, [_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_2__.Dialog.warnButton({ label: 'Dismiss' })]); - return; - } - // await (fileBrowser.model as any)._restored.promise - const model = new _model__WEBPACK_IMPORTED_MODULE_4__.EduhelxSubmissionModel(); - Promise.all([app.restored, fileBrowser.model.restored]).then(() => { - model.currentPath = fileBrowser.model.path; - }); - fileBrowser.model.pathChanged.connect((fileBrowserModel, change) => { - model.currentPath = change.newValue; - }); - const submissionWidget = new _widgets__WEBPACK_IMPORTED_MODULE_5__.AssignmentWidget(model, app.commands, serverSettings); - submissionWidget.id = 'jp-submission-widget'; - submissionWidget.title.icon = _style_icons__WEBPACK_IMPORTED_MODULE_6__.submissionIcon; - submissionWidget.title.caption = 'Submit assignments'; - restorer.add(submissionWidget, 'submission-widget'); - shell.add(submissionWidget, 'left', { rank: 200 }); -} -/** - * Initialization data for the jupyterlab_eduhelx_submission extension. - */ -const plugin = { - id: 'jupyterlab_eduhelx_submission:plugin', - description: 'A JupyterLab extension tfor submitting assignments in EduHeLx', - autoStart: true, - requires: [ - _jupyterlab_filebrowser__WEBPACK_IMPORTED_MODULE_1__.IDefaultFileBrowser, - _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__.ILayoutRestorer, - _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__.ILabShell, - ], - activate -}; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (plugin); - - -/***/ }), - -/***/ "./lib/model.js": -/*!**********************!*\ - !*** ./lib/model.js ***! - \**********************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EduhelxSubmissionModel: () => (/* binding */ EduhelxSubmissionModel) -/* harmony export */ }); -/* harmony import */ var _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lumino/signaling */ "webpack/sharing/consume/default/@lumino/signaling"); -/* harmony import */ var _lumino_signaling__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_lumino_signaling__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _lumino_polling__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lumino/polling */ "webpack/sharing/consume/default/@lumino/polling"); -/* harmony import */ var _lumino_polling__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_lumino_polling__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./api */ "./lib/api/api.js"); - - - -class EduhelxSubmissionModel { - constructor() { - this._isDisposed = false; - this._currentPath = null; - this._currentAssignment = undefined; - this._assignments = undefined; - this._student = undefined; - this._course = undefined; - this._currentPathChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__.Signal(this); - this._currentAssignmentChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__.Signal(this); - this._assignmentsChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__.Signal(this); - this._studentChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__.Signal(this); - this._courseChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__.Signal(this); - this._assignmentPoll = new _lumino_polling__WEBPACK_IMPORTED_MODULE_1__.Poll({ - factory: this._refreshModel.bind(this), - frequency: { - interval: 3000, - backoff: true, - max: 300 * 1000 - }, - standby: this._refreshStandby - }); - } - get isDisposed() { - return this._isDisposed; - } - get assignments() { - return this._assignments; - } - set assignments(v) { - const change = { - name: 'assignments', - newValue: v, - oldValue: this.assignments - }; - this._assignments = v; - this._assignmentsChanged.emit(change); - } - get assignmentsChanged() { - return this._assignmentsChanged; - } - get student() { - return this._student; - } - set student(v) { - const change = { - name: 'student', - newValue: v, - oldValue: this.student - }; - this._student = v; - this._studentChanged.emit(change); - } - get studentChanged() { - return this._studentChanged; - } - get course() { - return this._course; - } - set course(v) { - const change = { - name: 'course', - newValue: v, - oldValue: this.course - }; - this._course = v; - this._courseChanged.emit(change); - } - get courseChanged() { - return this._courseChanged; - } - // Undefined: loading, null: no current assignment - get currentAssignment() { - return this._currentAssignment; - } - set currentAssignment(v) { - const change = { - name: 'currentAssignment', - newValue: v, - oldValue: this.currentAssignment - }; - this._currentAssignment = v; - this._currentAssignmentChanged.emit(change); - } - get currentAssignmentChanged() { - return this._currentAssignmentChanged; - } - get currentPath() { - return this._currentPath; - } - set currentPath(v) { - const change = { - name: 'currentPath', - newValue: v, - oldValue: this.currentPath - }; - this._currentPath = v; - this._currentPathChanged.emit(change); - this.refreshAssignment(); - } - get currentPathChanged() { - return this._currentPathChanged; - } - async _loadAssignments() { - // If the currentPath is loading, the assignment is also loading. - if (this.currentPath === null) { - return undefined; - } - try { - return await (0,_api__WEBPACK_IMPORTED_MODULE_2__.getAssignments)(this.currentPath); - } - catch (e) { - console.error(e); - // If the request encouners an error, default to loading. - // Don't want to mislead and say an assignment directory isn't an assignment due to an error here. - return undefined; - } - } - async _loadStudentAndCourse() { - try { - return await (0,_api__WEBPACK_IMPORTED_MODULE_2__.getStudentAndCourse)(); - } - catch (e) { - console.error(e); - // If the request encouners an error, default to loading. - return undefined; - } - } - async refreshAssignment() { - // Set assignment to loading. - this.currentAssignment = undefined; - this.assignments = undefined; - this.student = undefined; - // await this._assignmentPoll.refresh() - this._refreshModel(); - await this._assignmentPoll.tick; - } - async _refreshModel() { - const [assignmentsResponse, studentAndCourseResponse] = await Promise.all([ - this._loadAssignments(), - this._loadStudentAndCourse() - ]); - if (assignmentsResponse === undefined) { - this.assignments = undefined; - this.currentAssignment = undefined; - } - else { - this.assignments = assignmentsResponse.assignments; - this.currentAssignment = assignmentsResponse.currentAssignment; - } - if (studentAndCourseResponse === undefined) { - this.student = undefined; - this.course = undefined; - } - else { - this.student = studentAndCourseResponse.student; - this.course = studentAndCourseResponse.course; - } - } - /** - * Determine if polling should temporarily suspend. - * - * Stand by, if: - * - webpage hidden - */ - _refreshStandby() { - // if (this.currentPath === null) return true - return 'when-hidden'; - } - dispose() { - if (this.isDisposed) - return; - this._isDisposed = true; - this._assignmentPoll.dispose(); - _lumino_signaling__WEBPACK_IMPORTED_MODULE_0__.Signal.clearData(this); - } -} - - -/***/ }), - -/***/ "./lib/style/icons.js": -/*!****************************!*\ - !*** ./lib/style/icons.js ***! - \****************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ submissionIcon: () => (/* binding */ submissionIcon) -/* harmony export */ }); -/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/ui-components */ "webpack/sharing/consume/default/@jupyterlab/ui-components"); -/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _style_icons_publish_svg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../style/icons/publish.svg */ "./style/icons/publish.svg"); - - -const submissionIcon = new _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__.LabIcon({ name: 'eduhelx-submission', svgstr: _style_icons_publish_svg__WEBPACK_IMPORTED_MODULE_1__ }); - - -/***/ }), - -/***/ "./lib/utils/date-format.js": -/*!**********************************!*\ - !*** ./lib/utils/date-format.js ***! - \**********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ DateFormat: () => (/* binding */ DateFormat) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! moment */ "webpack/sharing/consume/default/moment/moment"); -/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_1__); - - -const ReactiveTime = ({ getTime }) => { - const [time, setTime] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(getTime()); - (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { - // Doesn't need to precisely sync to the internal time or anything - // because the humanized moment is imprecise. - const interval = window.setInterval(() => { - setTime(getTime()); - }, 1000); - return () => { - window.clearInterval(interval); - }; - }, []); - return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, time); -}; -// The purpose of this is to standardize the date string formats used across the project. -class DateFormat { - constructor(date) { - this._date = date; - this._moment = moment__WEBPACK_IMPORTED_MODULE_1___default()(date); - } - toBasicDatetime() { - return this._moment.format("MMM DD [at] h[:]mm A"); - } - toRelativeDatetime(referenceTime) { - const getDuration = (date) => (0,moment__WEBPACK_IMPORTED_MODULE_1__.duration)(this._moment.diff(moment__WEBPACK_IMPORTED_MODULE_1___default()(date))).humanize(); - if (referenceTime) - return getDuration(referenceTime); - return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ReactiveTime, { getTime: () => getDuration(new Date()) }); - } -} - - -/***/ }), - -/***/ "./lib/widgets/assignment-widget.js": -/*!******************************************!*\ - !*** ./lib/widgets/assignment-widget.js ***! - \******************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AssignmentWidget: () => (/* binding */ AssignmentWidget) -/* harmony export */ }); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react"); -/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils"); -/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _material_ui_core_styles__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material-ui/core/styles */ "./node_modules/@material-ui/styles/esm/StylesProvider/StylesProvider.js"); -/* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../components */ "./lib/components/assignment-panel/assignment-panel.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../contexts */ "./lib/contexts/commands-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../contexts */ "./lib/contexts/settings-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../contexts */ "./lib/contexts/backdrop-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../contexts */ "./lib/contexts/snackbar-context.js"); -/* harmony import */ var _contexts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../contexts */ "./lib/contexts/assignment-context.js"); - - - - - -class AssignmentWidget extends _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.ReactWidget { - constructor(model, commands, serverSettings) { - super(); - this.model = model; - this.commands = commands; - this.serverSettings = serverSettings; - } - render() { - return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_material_ui_core_styles__WEBPACK_IMPORTED_MODULE_2__["default"], { injectFirst: true }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contexts__WEBPACK_IMPORTED_MODULE_3__.CommandsProvider, { commands: this.commands }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contexts__WEBPACK_IMPORTED_MODULE_4__.SettingsProvider, { settings: this.serverSettings }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contexts__WEBPACK_IMPORTED_MODULE_5__.BackdropProvider, null, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contexts__WEBPACK_IMPORTED_MODULE_6__.SnackbarProvider, null, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contexts__WEBPACK_IMPORTED_MODULE_7__.AssignmentProvider, { model: this.model }, - react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components__WEBPACK_IMPORTED_MODULE_8__.AssignmentPanel, null)))))))); - } -} - - -/***/ }), - -/***/ "./style/icons/publish.svg": -/*!*********************************!*\ - !*** ./style/icons/publish.svg ***! - \*********************************/ -/***/ ((module) => { - -module.exports = "\n \n\n"; - -/***/ }) - -}]); -//# sourceMappingURL=lib_index_js.145449ba8616931d9a24.js.map \ No newline at end of file diff --git a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/lib_index_js.145449ba8616931d9a24.js.map b/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/lib_index_js.145449ba8616931d9a24.js.map deleted file mode 100644 index 2df9f45..0000000 --- a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/lib_index_js.145449ba8616931d9a24.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"lib_index_js.145449ba8616931d9a24.js","mappings":"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","sources":["webpack://jupyterlab_eduhelx_submission/./src/api/api.ts","webpack://jupyterlab_eduhelx_submission/./src/api/assignment.ts","webpack://jupyterlab_eduhelx_submission/./src/api/commit.ts","webpack://jupyterlab_eduhelx_submission/./src/api/course.ts","webpack://jupyterlab_eduhelx_submission/./src/api/instructor.ts","webpack://jupyterlab_eduhelx_submission/./src/api/server-settings.ts","webpack://jupyterlab_eduhelx_submission/./src/api/student.ts","webpack://jupyterlab_eduhelx_submission/./src/api/submission.ts","webpack://jupyterlab_eduhelx_submission/./src/api/user.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-content/assignment-content.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-content/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-info/assignment-info.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-info/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-panel.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-submissions/assignment-submissions.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-submissions/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-submit-form/assignment-submit-button/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-submit-form/assignment-submit-form.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignment-submit-form/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignments-list/assignments-list.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/assignments-list/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/no-assignment-warning/no-assignment-warning.tsx","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/no-assignment-warning/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/assignment-panel/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/text-divider/style.ts","webpack://jupyterlab_eduhelx_submission/./src/components/text-divider/text-divider.tsx","webpack://jupyterlab_eduhelx_submission/./src/contexts/assignment-context.tsx","webpack://jupyterlab_eduhelx_submission/./src/contexts/backdrop-context.tsx","webpack://jupyterlab_eduhelx_submission/./src/contexts/commands-context.tsx","webpack://jupyterlab_eduhelx_submission/./src/contexts/settings-context.tsx","webpack://jupyterlab_eduhelx_submission/./src/contexts/snackbar-context.tsx","webpack://jupyterlab_eduhelx_submission/./src/handler.ts","webpack://jupyterlab_eduhelx_submission/./src/index.ts","webpack://jupyterlab_eduhelx_submission/./src/model.ts","webpack://jupyterlab_eduhelx_submission/./src/style/icons.ts","webpack://jupyterlab_eduhelx_submission/./src/utils/date-format.tsx","webpack://jupyterlab_eduhelx_submission/./src/widgets/assignment-widget.tsx"],"sourcesContent":["import qs from 'qs'\nimport { ServerConnection } from '@jupyterlab/services'\nimport { requestAPI } from '../handler'\nimport { IAssignment, Assignment, ICurrentAssignment } from './assignment'\nimport { IStudent, Student } from './student'\nimport { ISubmission, Submission } from './submission'\nimport { ICourse, Course } from './course'\nimport { IServerSettings, ServerSettings } from './server-settings'\nimport {\n AssignmentResponse,\n CourseResponse,\n StudentResponse,\n SubmissionResponse,\n ServerSettingsResponse,\n} from './api-responses'\n\nexport interface GetAssignmentsResponse {\n assignments: IAssignment[] | null\n currentAssignment: ICurrentAssignment | null\n}\n\nexport interface GetStudentAndCourseResponse {\n student: IStudent\n course: ICourse\n}\n\nexport async function getStudentAndCourse(): Promise {\n const { student, course } = await requestAPI<{\n student: StudentResponse\n course: CourseResponse\n }>(`/course_student`, {\n method: 'GET'\n })\n return {\n student: Student.fromResponse(student),\n course: Course.fromResponse(course)\n }\n}\n\n\nexport async function getAssignments(path: string): Promise {\n const { assignments, current_assignment } = await requestAPI<{\n assignments: AssignmentResponse[] | null\n current_assignment: AssignmentResponse | null\n }>(`/assignments?${ qs.stringify({ path }) }`, {\n method: 'GET'\n })\n return {\n assignments: assignments ? assignments.map((data) => Assignment.fromResponse(data)) : null,\n currentAssignment: current_assignment ? Assignment.fromResponse(current_assignment) as ICurrentAssignment : null\n }\n}\n\nexport async function getServerSettings(): Promise {\n try {\n const data = await requestAPI('/settings', {\n method: 'GET'\n })\n return ServerSettings.fromResponse(data)\n } catch (e) {\n if (e instanceof ServerConnection.ResponseError) {\n const response = e.response;\n if (response.status === 404) {\n const message =\n 'EduHeLx Submission server extension is unavailable. Please ensure you have installed the ' +\n 'JupyterLab EduHeLx Submission server extension by running: pip install --upgrade jupyterlab_eduhelx_submission. ' +\n 'To confirm that the server extension is installed, run: jupyter server extension list.'\n throw new ServerConnection.ResponseError(response, message);\n } else {\n const message = e.message;\n console.error('Failed to get the server extension settings', message);\n throw new ServerConnection.ResponseError(response, message);\n }\n } else {\n throw e;\n }\n }\n}\n\nexport async function submitAssignment(\n currentPath: string,\n summary: string,\n description?: string\n): Promise {\n const res = await requestAPI(`/submit_assignment`, {\n method: 'POST',\n body: JSON.stringify({\n summary,\n description,\n current_path: currentPath\n })\n })\n}\n\nexport async function cloneStudentRepository(repositoryUrl: string, currentPath: string): Promise {\n const repositoryRootPath = await requestAPI(`/clone_student_repository`, {\n method: 'POST',\n body: JSON.stringify({\n repository_url: repositoryUrl,\n current_path: currentPath\n })\n })\n return repositoryRootPath\n}","import { IStudent, Student } from './student'\nimport { ISubmission, Submission } from './submission'\nimport { AssignmentResponse } from './api-responses'\n\nexport interface IAssignment {\n readonly id: number\n readonly name: string\n readonly directoryPath: string\n // Added by serverextension so that we know what path to give the filebrowser\n // to open an assignment, even though we don't know where the repo root is.\n readonly absoluteDirectoryPath: string\n readonly createdDate: Date\n readonly adjustedAvailableDate: Date | null\n readonly adjustedDueDate: Date | null\n readonly lastModifiedDate: Date\n\n // Indicates that release date has been deferred to a later date for the student\n readonly isDeferred: boolean\n // Indicates that due date is extended to a later date for the student\n readonly isExtended: boolean\n // Indicates if an assignment has an available_date and a due_date assigned to it.\n readonly isCreated: boolean\n // Indicates if an assignment is available to work on (e.g. date is greater than adjusted_available_date)\n readonly isAvailable: boolean\n // Indicates if an assignment is no longer available to work on (e.g. date is greater than adjusted_due_date)\n readonly isClosed: boolean\n readonly submissions?: ISubmission[]\n}\n\n// Submissions are definitely defined in an ICurrentAssignment\nexport interface ICurrentAssignment extends IAssignment {\n readonly submissions: ISubmission[] \n}\n\nexport class Assignment implements IAssignment {\n constructor(\n private _id: number,\n private _name: string,\n private _directoryPath: string,\n private _absoluteDirectoryPath: string,\n private _createdDate: Date,\n private _adjustedAvailableDate: Date | null,\n private _adjustedDueDate: Date | null,\n private _lastModifiedDate: Date,\n\n private _isDeferred: boolean,\n private _isExtended: boolean,\n private _isCreated: boolean,\n private _isAvailable: boolean,\n private _isClosed: boolean,\n private _submissions?: ISubmission[]\n ) {}\n \n get id() { return this._id }\n get name() { return this._name }\n get directoryPath() { return this._directoryPath }\n get absoluteDirectoryPath() { return this._absoluteDirectoryPath }\n get createdDate() { return this._createdDate }\n get adjustedAvailableDate() { return this._adjustedAvailableDate }\n get adjustedDueDate() { return this._adjustedDueDate }\n get lastModifiedDate() { return this._lastModifiedDate }\n \n\n get isDeferred() { return this._isDeferred }\n get isExtended() { return this._isExtended }\n get isCreated() { return this._isCreated }\n get isAvailable() { return this._isAvailable }\n get isClosed() { return this._isClosed }\n\n get submissions() { return this._submissions }\n \n\n static fromResponse(data: AssignmentResponse): IAssignment {\n return new Assignment(\n data.id,\n data.name,\n data.directory_path,\n data.absolute_directory_path,\n new Date(data.created_date),\n data.adjusted_available_date ? new Date(data.adjusted_available_date) : null,\n data.adjusted_due_date ? new Date(data.adjusted_due_date) : null,\n new Date(data.last_modified_date),\n\n data.is_deferred,\n data.is_extended,\n data.is_created,\n data.is_available,\n data.is_closed,\n data.submissions?.map((res) => Submission.fromResponse(res))\n )\n }\n}","import { CommitResponse } from './api-responses'\n\nexport interface ICommit {\n id: string\n idShort: string\n // The author and committer should always be the same, but there is a practical distinction in the git spec.\n // The author is the person who originally wrote the changes for the commit.\n authorName: string\n authorEmail: string\n // The committer is the person who actually commits the changes.\n committerName: string\n committerEmail: string\n message: string\n // The summary is everything before the first newline character in the commit message.\n summary: string\n // The description is everything after the first newline character in the commit message.\n description: string\n}\n\nexport class Commit implements ICommit {\n constructor(\n private _id: string,\n private _authorName: string,\n private _authorEmail: string,\n private _committerName: string,\n private _committerEmail: string,\n private _message: string\n ) {}\n\n get id() { return this._id }\n get idShort() { return this._id.slice(0, 7) }\n get authorName() { return this._authorName }\n get authorEmail() { return this._authorEmail }\n get committerName() { return this._committerName }\n get committerEmail() { return this._committerEmail }\n get message() { return this._message }\n get summary() {\n const [summary, ...description] = this.message.split(\"\\n\")\n return summary\n }\n get description() {\n const [summary, ...description] = this.message.split(\"\\n\")\n return description.join(\"\\n\")\n }\n\n static fromResponse(data: CommitResponse): ICommit {\n return new Commit(\n data.id,\n data.author_name,\n data.author_email,\n data.committer_name,\n data.committer_email,\n data.message\n )\n }\n}","import { CourseResponse } from './api-responses'\nimport { IInstructor, Instructor } from './instructor'\n\nexport interface ICourse {\n id: number\n name: string\n masterRemoteUrl: string\n instructors: IInstructor[]\n}\n\nexport class Course implements ICourse {\n constructor(\n private _id: number,\n private _name: string,\n private _masterRemoteUrl: string,\n private _instructors: IInstructor[]\n ) {}\n\n get id() { return this._id }\n get name() { return this._name }\n get masterRemoteUrl() { return this._masterRemoteUrl }\n get instructors() { return this._instructors }\n\n static fromResponse(data: CourseResponse): ICourse {\n return new Course(\n data.id,\n data.name,\n data.master_remote_url,\n data.instructors.map((res) => Instructor.fromResponse(res))\n )\n }\n}","import { InstructorResponse } from './api-responses'\nimport { IUser, User } from './user'\n\nexport interface IInstructor extends IUser {\n}\n\nexport class Instructor extends User implements IInstructor {\n constructor(\n id: number,\n onyen: string,\n firstName: string,\n lastName: string,\n email: string\n ) {\n super(id, onyen, firstName, lastName, email)\n }\n\n static fromResponse(data: InstructorResponse): IInstructor {\n return new Instructor(\n data.id,\n data.onyen,\n data.first_name,\n data.last_name,\n data.email\n )\n }\n}","import { ServerSettingsResponse } from './api-responses'\n\nexport interface IServerSettings {}\nexport class ServerSettings implements IServerSettings {\n constructor() {}\n \n static fromResponse(data: ServerSettingsResponse): IServerSettings {\n return new ServerSettings()\n }\n}","import { StudentResponse } from './api-responses'\nimport { IUser, User } from './user'\n\nexport interface IStudent extends IUser {\n readonly joinDate: Date\n readonly exitDate: Date | null\n}\n\nexport class Student extends User implements IStudent {\n constructor(\n id: number,\n onyen: string,\n firstName: string,\n lastName: string,\n email: string,\n private _joinDate: Date,\n private _exitDate: Date | null\n ) {\n super(id, onyen, firstName, lastName, email)\n }\n get joinDate() { return this._joinDate }\n get exitDate() { return this._exitDate }\n\n static fromResponse(data: StudentResponse): IStudent {\n return new Student(\n data.id,\n data.onyen,\n data.first_name,\n data.last_name,\n data.email,\n new Date(data.join_date),\n data.exit_date ? new Date(data.exit_date) : null\n )\n }\n}","import moment from 'moment'\nimport { IStudent, Student } from './student'\nimport { ICommit, Commit } from './commit'\nimport { SubmissionResponse } from './api-responses'\n\nexport interface ISubmission {\n readonly id: number\n readonly active: boolean\n readonly submissionTime: Date\n readonly commit: ICommit\n}\n\nexport class Submission implements ISubmission {\n constructor(\n private _id: number,\n private _active: boolean,\n private _submissionTime: Date,\n private _commit: ICommit\n ) {}\n get id() { return this._id }\n get active() { return this._active }\n get submissionTime() { return this._submissionTime }\n get commit() { return this._commit }\n\n static fromResponse(data: SubmissionResponse): ISubmission {\n return new Submission(\n data.id,\n data.active,\n new Date(data.submission_time),\n Commit.fromResponse(data.commit)\n )\n }\n}","import { UserResponse } from './api-responses'\n\nexport interface IUser {\n id: number\n onyen: string\n firstName: string\n lastName: string\n fullName: string\n email: string\n}\n\nexport class User implements IUser {\n constructor(\n private _id: number,\n private _onyen: string,\n private _firstName: string,\n private _lastName: string,\n private _email: string\n ) {}\n\n get id() { return this._id }\n get onyen() { return this._onyen }\n get firstName() { return this._firstName }\n get lastName() { return this._lastName }\n get fullName() { return `${ this.firstName } ${ this.lastName }` }\n get email() { return this._email }\n\n static fromResponse(data: UserResponse): IUser {\n return new User(\n data.id,\n data.onyen,\n data.first_name,\n data.last_name,\n data.onyen\n )\n }\n}","import React, { Fragment, useEffect, useState } from 'react'\nimport { CircularProgress, Divider } from '@material-ui/core'\nimport { assignmentContainerClass, containerClass, loadingContainerClass } from './style'\nimport { NoAssignmentWarning } from '../no-assignment-warning'\nimport { AssignmentInfo } from '../assignment-info'\nimport { AssignmentSubmissions } from '../assignment-submissions'\nimport { AssignmentSubmitForm } from '../assignment-submit-form'\nimport { useAssignment } from '../../../contexts'\n\nexport const AssignmentContent = () => {\n const { loading, path, assignment, student, assignments } = useAssignment()!\n\n /*\n const [showSelectionView, setShowSelectionView] = useState(true)\n\n useEffect(() => {\n // When the path / active assignment changes,\n // if there's an active assignment, show the assignment view.\n if (assignment) setShowSelectionView(false)\n // If there isn't an assignment in the current directory, show the selection view.\n else setShowSelectionView(true)\n // Then, users can press a button while in the assignment view, users can press\n // a back button to go back to the selection view.\n }, [path, assignment?.id])\n */\n\n return (\n
\n {\n loading ? (\n
\n \n
\n ) : assignments === null || assignment === null ? (\n \n ) : (\n
\n \n \n \n
\n )\n }\n
\n )\n}","import { style } from 'typestyle'\n\nexport const containerClass = style({\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const loadingContainerClass = style({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n margin: '36px 11px 4px 11px',\n color: 'var(--md-blue-600)'\n})\n\nexport const assignmentContainerClass = style({\n display: 'flex',\n flexDirection: 'column',\n height: '100%'\n})","import React from 'react'\nimport { ArrowBackSharp } from '@material-ui/icons'\nimport { assignmentInfoClass, assignmentInfoSectionClass, assignmentInfoSectionHeaderClass, assignmentNameClass } from './style'\nimport { useAssignment } from '../../../contexts'\nimport { DateFormat } from '../../../utils'\n\nconst MS_IN_HOURS = 3.6e6\n\ninterface AssignmentInfoProps {\n}\n\nexport const AssignmentInfo = ({ }: AssignmentInfoProps) => {\n const { assignment, student, course } = useAssignment()!\n if (!student || !assignment || !course) return null\n\n const hoursUntilDue = assignment.isCreated ? (\n (assignment.adjustedDueDate!.getTime() - Date.now()) / MS_IN_HOURS\n ) : Infinity\n\n return (\n
\n
\n
{ assignment.name }
\n { assignment.isClosed ? (\n
\n Closed\n
\n ) : null }\n
\n
\n
Student
\n { student.firstName } { student.lastName }\n
\n
\n
\n Professor{ course.instructors.length > 1 ? \"s\" : \"\" }\n
\n { course.instructors.map((ins) => ins.fullName).join(\", \") }\n
\n
\n
Due date
\n
\n { assignment.isCreated ? (\n new DateFormat(assignment.adjustedDueDate!).toBasicDatetime()\n ) : (\n `To be determined`\n ) }\n { assignment.isExtended ? (\n  (extended)\n ) : null }\n
\n { assignment.isCreated && !assignment.isClosed && hoursUntilDue <= 2 ? (\n
\n Warning: { new DateFormat(assignment.adjustedDueDate!).toRelativeDatetime() } remaining\n
\n ) : null }\n
\n
\n )\n}","import { style } from 'typestyle'\n\nexport const assignmentInfoClass = style({\n fontSize: 'var(--jp-ui-font-size1)',\n color: 'var(--jp-ui-font-color2)',\n display: 'flex',\n flexDirection: 'column',\n padding: '0 12px'\n})\n\nexport const assignmentNameClass = style({\n flex: '0 0 auto',\n color: 'var(--jp-ui-font-color1)',\n fontSize: 'var(--jp-ui-font-size3)',\n fontWeight: 600,\n marginTop: 6,\n padding: '8px 0',\n marginBottom: 0,\n paddingBottom: 0\n})\n\nexport const assignmentInfoSectionClass = (style as any)({\n color: 'var(--jp-ui-font-color1)',\n marginBottom: 16,\n '& > *:first-child': {\n fontSize: 12\n },\n '& > *': {\n fontSize: 14\n }\n})\n\nexport const assignmentInfoSectionHeaderClass = style({\n margin: 0,\n marginBottom: 4,\n fontWeight: 600\n})\n","import React, { Fragment, ReactNode, useMemo } from 'react'\nimport { ArrowBackSharp } from '@material-ui/icons'\nimport {\n panelWrapperClass,\n panelHeaderClass\n} from './style'\nimport { AssignmentContent } from './assignment-content'\nimport { useAssignment, useCommands } from '../../contexts'\n\ninterface IAssignmentPanelProps {\n}\n\nexport const AssignmentPanel = ({}: IAssignmentPanelProps) => {\n const commands = useCommands()!\n const { course, assignment } = useAssignment()!\n const headerName = useMemo(() => {\n const headerFragments = []\n // if (assignment) headerFragments.push(assignment.name)\n if (course) headerFragments.push(course.name)\n headerFragments.push('EduHeLx')\n return (\n \n { headerFragments.join(' • ') }\n \n )\n }, [course])\n return (\n
\n
\n { assignment && (\n commands.execute('filebrowser:go-to-path', {\n path: `${ assignment.absoluteDirectoryPath }/../`,\n dontShowBrowser: true\n }) }\n style={{ marginRight: 8, fontSize: 16, cursor: 'pointer' }}\n />\n ) }\n { headerName }\n
\n \n
\n )\n}","import React, { Fragment, useMemo } from 'react'\nimport { \n Table, TableHead, TableBody, TableRow, TableCell,\n List, ListItem, ListItemText, ListItemIcon, Divider,\n ExpansionPanel, ExpansionPanelSummary, ExpansionPanelDetails,\n Card, CardContent, Typography\n} from '@material-ui/core'\nimport { CheckSharp, DescriptionSharp, ExpandMoreSharp, PersonSharp } from '@material-ui/icons'\nimport {\n noSubmissionsTextContainerClass, assignmentsTableClass,\n assignmentSubmissionsContainerClass, assignmentSubmissionsHeaderClass,\n activateSubmissionButtonClass,\n assignmentsListClass\n} from './style'\nimport { TextDivider } from '../../text-divider'\nimport { useAssignment } from '../../../contexts'\nimport { DateFormat } from '../../../utils'\n\ninterface AssignmentSubmissionsProps extends React.HTMLProps {\n\n}\n\nexport const AssignmentSubmissions = ({ ...props }: AssignmentSubmissionsProps) => {\n const { assignment } = useAssignment()!\n\n const submissionSource = useMemo(() => (\n assignment?.submissions.sort((a, b) => b.submissionTime.getTime() - a.submissionTime.getTime())\n ), [assignment])\n \n if (!assignment) return null\n if (assignment.submissions.length === 0) return (\n
\n You haven't made any submissions for this assignment yet.\n To submit your work, press the \"Submit\" button at the bottom of the page.\n
\n )\n return (\n
\n Submissions\n
\n { submissionSource!.map((submission, i) => (\n \n }>\n \n \n { `#${ submissionSource!.length - i }` }\n \n \n
\n { new DateFormat(submission.submissionTime).toBasicDatetime() }\n
\n
\n { submission.commit.summary } \n
\n
\n
\n
\n \n \n \n \n { submission.commit.authorName }\n \n \n { submission.commit.idShort }\n \n \n { submission.commit.description || \"No description\" }\n \n \n \n \n
\n )) }\n
\n {/* { assignment.submissions.map((submission) => (\n \n
\n \n { new DateFormat(submission.submissionTime).toBasicDatetime() }\n \n
\n { submission.commit.summary } \n
\n
\n \n
\n )) } */}\n
\n )\n}","import { style } from 'typestyle'\n\nexport const assignmentSubmissionsContainerClass = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const assignmentSubmissionsHeaderClass = style({\n margin: '0',\n marginBottom: '2px',\n padding: '0 12px',\n fontWeight: 600,\n color: 'var(--jp-ui-font-color0)',\n fontSize: 'var(--jp-ui-font-size2)'\n})\n\nexport const noSubmissionsTextContainerClass = style({\n width: '100%',\n color: 'var(--jp-ui-font-color2)',\n fontSize: 'var(--jp-ui-font-size1)',\n lineHeight: 'var(--jp-content-line-height)',\n textAlign: 'left',\n padding: '0 12px',\n flexGrow: 1\n})\n\nexport const assignmentsTableClass = (style as any)({\n '& th, & td': {\n height: 42,\n fontSize: 13,\n }\n})\n\nexport const activateSubmissionButtonClass = style({\n fontSize: 13,\n backgroundColor: 'var(--jp-layout-color0)',\n color: 'var(--jp-ui-font-color0)',\n borderRadius: 3,\n border: '1px solid var(--jp-border-color2)',\n padding: '4px 10px',\n cursor: 'pointer'\n})\n\nexport const assignmentsListClass = (style as any)({\n flexGrow: 1,\n height: 0,\n overflowY: 'auto',\n padding: 0,\n /** Adjusting clashing styles caused by using accordion summaries as ListItem components */\n '& .MuiExpansionPanel-root, & .MuiExpansionPanel-root.Mui-expanded': {\n boxShadow: 'none',\n margin: 0,\n },\n '& .MuiExpansionPanel-root::before, & > div.MuiExpansionPanel-root.Mui-expanded::before': {\n top: -1,\n left: 0,\n right: 0,\n height: 1,\n content: '\"\"',\n opacity: 1,\n position: 'absolute',\n display: 'block !important'\n },\n '& .MuiExpansionPanel-root:first-child::before, & > div.MuiExpansionPanel-root.Mui-expanded:first-child::before': {\n display: 'none !important'\n },\n '& .MuiExpansionPanelSummary-root, & .MuiExpansionPanelSummary-root.Mui-expanded': {\n padding: 0,\n minHeight: 'unset'\n },\n '& .MuiExpansionPanelSummary-content, & .MuiExpansionPanelSummary-content.Mui-expanded': {\n margin: 0\n },\n '& .MuiListItem-root': {\n paddingLeft: 12,\n paddingRight: 12\n },\n '& .MuiExpansionPanelSummary-expandIcon': {\n marginRight: 0\n },\n '& .MuiExpansionPanelDetails-root': {\n paddingLeft: 12,\n paddingRight: 12\n },\n '& .MuiExpansionPanelDetails-root > .MuiCard-root': {\n borderWidth: 0,\n borderLeftWidth: '2px !important',\n // So that the border aligns with the assignment number,\n // and the text aligns with the commit summary\n paddingLeft: 22,\n marginLeft: 8,\n borderRadius: 0\n },\n '& .MuiExpansionPanelDetails-root > .MuiCard-root > .MuiCardContent-root': {\n paddingLeft: 0\n }\n})","import React from 'react'\nimport { PublishSharp } from '@material-ui/icons'\nimport { assignmentSubmitButton } from './style'\nimport { useAssignment } from '../../../../contexts'\nimport { classes } from 'typestyle'\nimport { disabledButtonClass } from '../../../style'\n\ninterface AssignmentSubmitButtonProps {\n onClick: (e: any) => void\n disabled?: boolean\n}\n\nexport const AssignmentSubmitButton = ({ onClick, disabled=false }: AssignmentSubmitButtonProps) => {\n return (\n \n Submit Assignment\n \n )\n}","import { style } from 'typestyle'\n\nexport const assignmentSubmitButton = style({\n fontSize: 14,\n backgroundColor: 'var(--md-blue-500)',\n border: 0,\n borderRadius: 3,\n cursor: 'pointer',\n color: 'white',\n height: 30.75,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n})","import React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { Backdrop, CircularProgress, Input, Snackbar } from '@material-ui/core'\nimport { Alert } from '@material-ui/lab'\nimport { AssignmentSubmitButton } from './assignment-submit-button'\nimport {\n submitFormContainerClass, submitRootClass,\n summaryClass, descriptionClass,\n activeStyle, disabledStyle\n} from './style'\nimport { useAssignment, useBackdrop, useSnackbar } from '../../../contexts'\nimport { submitAssignment as apiSubmitAssignment } from '../../../api'\n\ninterface AssignmentSubmitFormProps {\n\n}\n\nexport const AssignmentSubmitForm = ({ }: AssignmentSubmitFormProps) => {\n const { assignment, path } = useAssignment()!\n const backdrop = useBackdrop()!\n const snackbar = useSnackbar()!\n\n const [summaryText, setSummaryText] = useState(\"\")\n const [descriptionText, setDescriptionText] = useState(\"\")\n const [submitting, setSubmitting] = useState(false)\n\n const disabled = submitting || summaryText === \"\" || !assignment?.isAvailable || assignment?.isClosed\n \n const submitAssignment = async () => {\n if (!path) {\n // If this component is being rendered, this should never be possible.\n console.log(\"Unknown cwd, can't submit\")\n return\n }\n setSubmitting(true)\n try {\n // Use undefined for descriptionText if it is an empty string.\n const submission = await apiSubmitAssignment(path, summaryText, descriptionText ?? undefined)\n // Only clear summary/description if the submission goes through.\n setSummaryText(\"\")\n setDescriptionText(\"\")\n\n snackbar.open({\n type: 'success',\n message: 'Successfully submitted assignment!'\n })\n } catch (e: any) {\n snackbar.open({\n type: 'error',\n message: 'Failed to submit assignment!'\n })\n }\n setSubmitting(false)\n }\n \n useEffect(() => {\n backdrop.setLoading(submitting)\n }, [submitting])\n \n return (\n
\n setSummaryText(e.target.value) }\n onKeyDown={ (e) => {\n if (disabled) return\n if (e.key === 'Enter') submitAssignment()\n } }\n disabled={ submitting }\n required\n disableUnderline\n fullWidth\n />\n setDescriptionText(e.target.value) }\n onKeyDown={ (e) => {\n // if (disabled) return\n // if (e.key === 'Enter') submitAssignment()\n } }\n disabled={ submitting }\n disableUnderline\n fullWidth\n />\n \n
\n )\n}","import { style } from 'typestyle'\n\nexport const submitFormContainerClass = style({\n display: 'flex',\n flexDirection: 'column',\n padding: '12px 8px',\n borderTop: 'var(--jp-border-width) solid var(--jp-border-color2)'\n})\n\nexport const submitRootClass = style({\n color: 'var(--jp-ui-font-color1) !important',\n fontSize: 'var(--jp-ui-font-size1) !important',\n fontFamily: 'var(--jp-ui-font-family) !important',\n backgroundColor: 'var(--jp-layout-color1) !important'\n})\n\nexport const summaryClass = style({\n height: '2em',\n\n marginBottom: '1em',\n padding: 'var(--jp-code-padding)',\n\n outline: 'none',\n overflowX: 'auto',\n\n border: 'var(--jp-border-width) solid var(--jp-border-color2)',\n borderRadius: 3,\n\n $nest: {\n '&.Mui-error': {\n border: 'calc(2 * var(--jp-border-width)) solid var(--jp-error-color1)'\n }\n }\n})\n\nexport const descriptionClass = style({\n marginBottom: '1em',\n padding: 'var(--jp-code-padding)',\n paddingLeft: '5px !important',\n paddingRight: '5px !important',\n\n outline: 'none',\n overflowX: 'auto',\n resize: 'none',\n\n border: 'var(--jp-border-width) solid var(--jp-border-color2)',\n borderRadius: 3,\n\n $nest: {\n '&>*::placeholder': {\n color: 'var(--jp-ui-font-color3)'\n },\n '&>*::-webkit-input-placeholder': {\n color: 'var(--jp-ui-font-color3)'\n },\n '&>*::-moz-placeholder': {\n color: 'var(--jp-ui-font-color3)'\n },\n '&>*::-ms-input-placeholder': {\n color: 'var(--jp-ui-font-color3)'\n }\n }\n})\n\nexport const activeStyle = style({\n outline: 'none',\n border: 'var(--jp-border-width) solid var(--jp-brand-color1)'\n})\n\nexport const disabledStyle = style({\n cursor: 'not-allowed !important',\n color: 'var(--jp-ui-font-color2) !important',\n backgroundColor: 'var(--jp-layout-color3) !important',\n pointerEvents: 'auto !important' as any\n});","import React, { Fragment, useMemo, useState } from 'react'\nimport {\n Avatar, List, ListItem, ListItemAvatar as _ListItemAvatar, ListItemText,\n ExpansionPanel, ExpansionPanelSummary, ExpansionPanelDetails\n} from '@material-ui/core'\nimport { OpenInNewSharp, QueryBuilderOutlined, ExpandMoreSharp } from '@material-ui/icons'\nimport { classes } from 'typestyle'\nimport { assignmentBucketContainerClass, assignmentListHeaderClass, assignmentListItemClass, downloadAssignmentButtonClass } from './style'\nimport { TextDivider } from '../../text-divider'\nimport { useAssignment, useCommands } from '../../../contexts'\nimport type { IAssignment } from '../../../api'\nimport { DateFormat } from '../../../utils'\nimport { assignmentsListClass } from '../assignment-submissions/style'\nimport { disabledButtonClass } from '../../style'\n\nconst ListItemAvatar = _ListItemAvatar as any\n\ninterface ListHeaderProps {\n title: string\n}\n\ninterface AssignmentListItemProps {\n assignment: IAssignment\n}\n\ninterface AssignmentsBucketProps {\n title: string\n assignments?: IAssignment[]\n emptyText?: string\n defaultExpanded?: boolean\n}\n\nconst ListHeader = ({ title }: ListHeaderProps) => {\n return (\n \n { title }\n \n )\n}\n\nconst AssignmentListItem = ({ assignment }: AssignmentListItemProps) => {\n const commands = useCommands()!\n return (\n \n \n
\n { assignment.name }\n
\n
\n {\n !assignment.isCreated ? (\n No release date yet\n ) :\n assignment.isClosed ? (\n \n Closed on { new DateFormat(assignment.adjustedDueDate!).toBasicDatetime() }\n \n ) : assignment.isAvailable ? (\n \n Closes in { new DateFormat(assignment.adjustedDueDate!).toRelativeDatetime() }\n { assignment.isExtended && (\n  (extended)\n ) }\n \n ) : (\n
\n \n Opens in { new DateFormat(assignment.adjustedAvailableDate!).toRelativeDatetime() }\n
\n \n \n  Lasts { new DateFormat(assignment.adjustedDueDate!).toRelativeDatetime(assignment.adjustedAvailableDate!) }\n
\n \n )\n }\n \n
\n \n \n commands.execute('filebrowser:go-to-path', {\n path: assignment.absoluteDirectoryPath,\n dontShowBrowser: true\n }) }\n >\n \n \n \n \n \n )\n}\n\nconst AssignmentsBucket = ({\n title,\n assignments,\n emptyText=\"There are currently no assignments to work on.\",\n defaultExpanded=false,\n}: AssignmentsBucketProps) => {\n const [expanded, setExpanded] = useState(defaultExpanded)\n\n const assignmentsSource = useMemo(() => (\n assignments?.sort((a, b) => (a.adjustedAvailableDate?.getTime() ?? 0) - (b.adjustedAvailableDate?.getTime() ?? 0))\n ), [assignments])\n\n const isEmpty = useMemo(() => !assignmentsSource || assignmentsSource.length === 0, [assignmentsSource])\n\n return (\n setExpanded(!expanded) }\n >\n }\n style={{ paddingLeft: 11 }}\n >\n \n \n \n { !isEmpty ? (\n assignmentsSource?.map((assignment) => (\n \n ))\n ) : (\n \n { emptyText }\n \n ) }\n \n \n )\n}\n\nexport const AssignmentsList = () => {\n const { assignments } = useAssignment()!\n\n const upcomingAssignments = useMemo(() => assignments?.filter((assignment) => !assignment.isAvailable), [assignments])\n const activeAssignments = useMemo(() => assignments?.filter((assignment) => assignment.isAvailable && !assignment.isClosed), [assignments])\n const pastAssignments = useMemo(() => assignments?.filter((assignment) => assignment.isAvailable && assignment.isClosed), [assignments])\n\n return (\n
\n
\n \n \n \n
\n
\n )\n}","import { style } from 'typestyle'\n\nexport const assignmentBucketContainerClass = (style as any)({\n '& .MuiExpansionPanelSummary-expandIcon': {\n paddingLeft: 6,\n paddingRight: 6\n }\n})\n\nexport const assignmentListItemClass = (style as any)({\n '&:first-child': {\n paddingTop: '0 !important',\n },\n '&:first-child > .MuiListItemText-root': {\n marginTop: '0 !important'\n }\n})\n\nexport const assignmentListHeaderClass = style({\n color: 'var(--jp-ui-font-color0)',\n fontSize: 13,\n fontWeight: 500\n})\n\nexport const downloadAssignmentButtonClass = style({\n backgroundColor: 'var(--md-blue-500)',\n border: 0,\n borderRadius: 0,\n cursor: 'pointer',\n color: 'white',\n fontSize: 'var(--jp-ui-font-size1)',\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n})","import React, { Fragment, useMemo, useState } from 'react'\nimport { List, ListItem, ListItemAvatar as _ListItemAvatar, ListItemText, Avatar, Input, CircularProgress } from '@material-ui/core'\nimport { GetAppSharp } from '@material-ui/icons'\nimport { classes } from 'typestyle'\nimport {\n containerClass, openFileBrowserButtonClass, textContainerClass,\n warningTextContainerClass\n} from './style'\nimport { AssignmentsList } from '../assignments-list'\nimport { TextDivider } from '../../text-divider'\nimport { cloneStudentRepository } from '../../../api'\nimport { useAssignment, useCommands } from '../../../contexts'\nimport { DateFormat } from '../../../utils'\nimport { activeStyle, disabledStyle, submitRootClass, summaryClass } from '../assignment-submit-form/style'\n\ninterface NoAssignmentWarningProps {\n noRepository: boolean\n}\n\nexport const NoAssignmentWarning = ({ noRepository }: NoAssignmentWarningProps) => {\n const commands = useCommands()!\n const { path } = useAssignment()!\n\n const [repositoryUrl, setRepositoryUrl] = useState('')\n const [loading, setLoading] = useState(false)\n const [errorMessage, setErrorMessage] = useState(null)\n\n const cloneRepository = async (repositoryUrl: string) => {\n if (!path) {\n console.log(\"Unknown cwd, can't clone\")\n return\n }\n setLoading(true)\n try {\n const repositoryRootPath = await cloneStudentRepository(repositoryUrl, path)\n commands.execute('filebrowser:go-to-path', {\n path: repositoryRootPath,\n dontShowBrowser: true\n })\n } catch (e: any) {\n setErrorMessage(e.message)\n }\n setLoading(false)\n }\n\n if (noRepository) return (\n
\n
\n
\n {\n setErrorMessage(null)\n setRepositoryUrl(e.target.value)\n }}\n onKeyDown={ (e) => {\n if (loading) return\n if (e.key === 'Enter') cloneRepository(repositoryUrl)\n }}\n // disabled={ loading }\n required\n disableUnderline\n fullWidth\n />\n cloneRepository(repositoryUrl) }\n >\n { !loading ? (\n \n ) : (\n \n ) }\n \n
\n
\n { errorMessage }\n
\n
\n
\n You are not currently in your class repository. If you haven't\n already cloned your class repository, you can download it here.\n
\n
\n Warning: Don't clone the repository again if you've already downloaded it!\n Navigate to the repository in the file browser.\n
\n commands.execute('filebrowser:toggle-main') }\n >\n Open the FileBrowser\n \n
\n )\n return (\n
\n
\n You are not currently in an assignment.\n To submit your work, navigate to an assignment\n in the filebrowser or open it here.\n
\n Assignments\n \n
\n )\n}","import { style } from 'typestyle'\n\nexport const containerClass = style({\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n margin: '13px 11px 4px 11px',\n})\n\nexport const textContainerClass = style({\n width: '100%',\n fontSize: 'var(--jp-ui-font-size1)',\n lineHeight: 'var(--jp-content-line-height)',\n textAlign: 'left',\n})\n\nexport const openFileBrowserButtonClass = style({\n backgroundColor: 'var(--md-blue-500)',\n border: 0,\n borderRadius: 3,\n cursor: 'pointer',\n color: 'white',\n fontSize: 'var(--jp-ui-font-size1)',\n height: 28,\n margin: '8px 0',\n width: 200,\n})\n\nexport const warningTextContainerClass = style({\n fontSize: 12,\n fontWeight: 500,\n color: 'var(--jp-warn-color0)',\n margin: '8px 0'\n})","import { style } from 'typestyle'\n\nexport const panelWrapperClass = (style as any)({\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n color: 'var(--jp-ui-font-color1)',\n fontSize: 'var(--jp-ui-font-size1)',\n background: 'var(--jp-layout-color1) !important',\n '&, & *': { boxSizing: 'border-box' } \n})\n\nexport const panelHeaderClass = style({\n display: 'flex',\n alignItems: 'center',\n borderBottom: 'var(--jp-border-width) solid var(--jp-border-color2)',\n flex: '0 0 auto',\n fontSize: 11,\n fontWeight: 600,\n letterSpacing: 1,\n margin: 0,\n // It appears slightly off-center vertically, so this is just a small adjustment to fix that.\n marginTop: 2,\n padding: '8px 12px',\n textTransform: 'uppercase'\n})","import { style } from 'typestyle'\n\nexport const textDividerClass = (style as any)({\n\n})\n\nexport const disabledButtonClass = style({\n cursor: 'not-allowed !important',\n backgroundColor: 'var(--jp-layout-color3) !important',\n pointerEvents: 'auto !important' as any\n});","import { style } from 'typestyle'\n\nexport const textDividerContainerClass = (style as any)({\n display: 'flex',\n alignItems: 'center',\n color: 'var(--jp-ui-font-color0)',\n fontWeight: 500,\n textAlign: 'center',\n\n '&::before, &::after': {\n content: '\"\"',\n position: 'relative',\n width: '100%',\n borderBottom: 'var(--jp-border-width) solid var(--jp-border-color2)',\n transform: 'translateY(50%)'\n },\n // Left-align adjustments\n '&.left::before': {\n width: 'var(--orientation-margin)'\n },\n // Right-align adjustmments'\n '&.right::after': {\n width: 'var(--orientation-margin)'\n }\n\n})\n\nexport const textDividerTextClass = style({\n display: 'inline-block'\n})","import React, { CSSProperties, ReactNode } from 'react'\nimport { classes } from 'typestyle'\nimport { textDividerContainerClass, textDividerTextClass } from './style'\n\n\n\ninterface TextDividerProps extends React.HTMLProps {\n orientation?: 'left' | 'right' | 'center'\n // Only valid if orientation isn't center\n orientationMargin?: number\n innerStyle?: CSSProperties\n children: ReactNode\n}\n\nexport const TextDivider = ({\n orientation='left',\n orientationMargin=0,\n innerStyle={},\n style={},\n children,\n ...props\n}: TextDividerProps) => {\n const textStyle = orientation === 'left' ? {\n marginLeft: orientationMargin,\n paddingLeft: orientationMargin !== 0 ? 12 : 0,\n paddingRight: 12\n } : orientation === 'right' ? {\n marginRight: orientationMargin,\n paddingRight: orientationMargin !== 0 ? 12 : 0,\n paddingLeft: 12\n } : {\n paddingLeft: 12,\n paddingRight: 12\n }\n return (\n \n \n { children }\n \n \n )\n}","import React, { createContext, useContext, ReactNode, useState, useMemo, useEffect } from 'react'\nimport { IChangedArgs } from '@jupyterlab/coreutils'\nimport { IEduhelxSubmissionModel } from '../tokens'\nimport { IAssignment, IStudent, ICurrentAssignment, ICourse } from '../api'\n\ninterface IAssignmentContext {\n assignments: IAssignment[] | null | undefined\n assignment: ICurrentAssignment | null | undefined\n student: IStudent | undefined\n course: ICourse | undefined\n path: string | null\n loading: boolean\n}\n\ninterface IAssignmentProviderProps {\n model: IEduhelxSubmissionModel\n children?: ReactNode\n}\n\nexport const AssignmentContext = createContext(undefined)\n\nexport const AssignmentProvider = ({ model, children }: IAssignmentProviderProps) => {\n const [currentPath, setCurrentPath] = useState(null)\n const [currentAssignment, setCurrentAssignment] = useState(undefined)\n const [assignments, setAssignments] = useState(undefined)\n const [student, setStudent] = useState(undefined)\n const [course, setCourse] = useState(undefined)\n\n const loading = useMemo(() => (\n currentAssignment === undefined ||\n assignments === undefined ||\n student === undefined ||\n course === undefined\n ), [currentAssignment, assignments, student, course])\n\n useEffect(() => {\n setCurrentPath(model.currentPath)\n setCurrentAssignment(model.currentAssignment)\n setAssignments(model.assignments)\n setStudent(model.student)\n setCourse(model.course)\n const onCurrentPathChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => {\n setCurrentPath(change.newValue)\n }\n const onCurrentAssignmentChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => {\n setCurrentAssignment(change.newValue)\n }\n const onAssignmentsChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => {\n setAssignments(change.newValue)\n }\n const onStudentChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => {\n setStudent(change.newValue)\n }\n const onCourseChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => {\n setCourse(change.newValue)\n }\n model.currentPathChanged.connect(onCurrentPathChanged)\n model.currentAssignmentChanged.connect(onCurrentAssignmentChanged)\n model.assignmentsChanged.connect(onAssignmentsChanged)\n model.studentChanged.connect(onStudentChanged)\n model.courseChanged.connect(onCourseChanged)\n return () => {\n model.currentPathChanged.disconnect(onCurrentPathChanged)\n model.currentAssignmentChanged.disconnect(onCurrentAssignmentChanged)\n model.assignmentsChanged.disconnect(onAssignmentsChanged)\n model.studentChanged.disconnect(onStudentChanged)\n model.courseChanged.disconnect(onCourseChanged)\n }\n }, [model])\n\n return (\n \n { children }\n \n )\n}\nexport const useAssignment = () => useContext(AssignmentContext)","import React, { createContext, useContext, ReactNode, useState } from 'react'\nimport { CircularProgress, Modal } from '@material-ui/core'\n\ninterface IBackdropContext {\n setLoading: (loading: boolean) => void\n}\n\ninterface IBackdropProviderProps {\n children?: ReactNode\n}\n\nexport const BackdropContext = createContext(undefined)\n\nexport const BackdropProvider = ({ children }: IBackdropProviderProps) => {\n const [loading, setLoading] = useState(false)\n return (\n \n { children }\n \n
\n \n
\n \n
\n )\n}\nexport const useBackdrop = () => useContext(BackdropContext)","import React, { createContext, useContext, ReactNode } from 'react'\nimport { CommandRegistry } from '@lumino/commands'\n\ninterface ICommandsProviderProps {\n commands: CommandRegistry\n children?: ReactNode\n}\n\nexport const CommandsContext = createContext(undefined)\n\nexport const CommandsProvider = ({ commands, children }: ICommandsProviderProps) => {\n return (\n \n { children }\n \n )\n}\nexport const useCommands = () => useContext(CommandsContext)","import React, { createContext, useContext, ReactNode } from 'react'\nimport { IServerSettings } from '../api'\n\ninterface ISettingsProviderProps {\n settings: IServerSettings\n children?: ReactNode\n}\n\nexport const SettingsContext = createContext(undefined)\n\nexport const SettingsProvider = ({ settings, children }: ISettingsProviderProps) => {\n return (\n \n { children }\n \n )\n}\nexport const useSettings = () => useContext(SettingsContext)","import React, { createContext, useContext, ReactNode, useState, Fragment } from 'react'\nimport { Portal, Snackbar, SnackbarOrigin } from '@material-ui/core'\nimport { Alert, Color } from '@material-ui/lab'\nimport { v4 as uuidv4 } from 'uuid'\n\ninterface CreateSnackbarProps {\n key?: string\n className?: string\n duration?: number\n type?: Color\n message?: string\n alignment?: SnackbarOrigin\n // Override type/message\n content?: ReactNode\n}\n\ninterface CreateSnackbar {\n (props: CreateSnackbarProps): string\n}\n\ninterface ISnackbarContext {\n open: CreateSnackbar\n destroy: (key: string) => void\n} \n\ninterface ISnackbarProviderProps {\n children?: ReactNode\n}\n\nexport const SnackbarContext = createContext(undefined)\n\nexport const SnackbarProvider = ({ children }: ISnackbarProviderProps) => {\n const [snackbars, setSnackbars] = useState<{\n [key: string]: CreateSnackbarProps\n }>({})\n\n const createSnackbar: CreateSnackbar = (props: CreateSnackbarProps) => {\n props.duration = props.duration ?? 2500\n props.key = props.key ?? uuidv4()\n props.alignment = props.alignment ?? { vertical: 'bottom', horizontal: 'right' }\n console.log(props, props.type)\n if (!props.content) props.content = (\n destroySnackbar(props.key!) }\n >\n { props.message }\n \n )\n setSnackbars((prevSnackbars) => ({\n ...prevSnackbars,\n [props.key!]: props\n }))\n return props.key\n }\n\n const destroySnackbar = (key: string) => {\n setSnackbars((prevSnackbars) => {\n const newSnackbars = { ...prevSnackbars }\n delete newSnackbars[key]\n return newSnackbars\n })\n }\n (window as any).open = createSnackbar\n \n return (\n \n \n { children }\n \n { Object.keys(snackbars).map((key) => {\n const { className, duration, alignment, content } = snackbars[key]\n return (\n destroySnackbar(key) }\n >\n { content }\n \n )\n }) }\n \n \n \n )\n}\nexport const useSnackbar = () => useContext(SnackbarContext)","import { URLExt } from '@jupyterlab/coreutils'\nimport { ServerConnection } from '@jupyterlab/services'\n\n/**\n * Call the API extension\n *\n * @param endPoint API REST end point for the extension\n * @param init Initial values for the request\n * @returns The response body interpreted as JSON\n */\nexport async function requestAPI(\n endPoint = '',\n init: RequestInit = {}\n): Promise {\n // Make request to Jupyter API\n const settings = ServerConnection.makeSettings()\n const requestUrl = URLExt.join(\n settings.baseUrl,\n 'jupyterlab-eduhelx-submission', // API Namespace\n endPoint\n )\n\n let response: Response\n try {\n response = await ServerConnection.makeRequest(requestUrl, init, settings)\n } catch (error) {\n throw new ServerConnection.NetworkError(error as any)\n }\n\n let data: any = await response.text()\n\n if (data.length > 0) {\n try {\n data = JSON.parse(data)\n } catch (error) {\n console.log('Not a JSON response body.', response)\n }\n }\n\n if (!response.ok) {\n throw new ServerConnection.ResponseError(response, data.message || data)\n }\n\n return data\n}\n","import {\n ILayoutRestorer,\n ILabShell,\n JupyterFrontEnd,\n JupyterFrontEndPlugin\n} from '@jupyterlab/application'\nimport { FileBrowserModel, IDefaultFileBrowser } from '@jupyterlab/filebrowser'\nimport { Dialog, showErrorMessage } from '@jupyterlab/apputils'\nimport { IChangedArgs } from '@jupyterlab/coreutils'\nimport { getServerSettings, IServerSettings } from './api'\nimport { AssignmentWidget } from './widgets'\nimport { EduhelxSubmissionModel } from './model'\nimport { submissionIcon } from './style/icons'\nimport { IFileBrowserFactory } from '@jupyterlab/filebrowser'\n\nasync function activate (\n app: JupyterFrontEnd,\n fileBrowser: IDefaultFileBrowser,\n restorer: ILayoutRestorer,\n shell: ILabShell,\n) {\n let serverSettings: IServerSettings\n try {\n serverSettings = await getServerSettings()\n } catch (e: any) {\n console.error('Failed to load the eduhelx_jupyterlab_student extension settings', e)\n showErrorMessage(\n 'Failed to load the jupyterlab_eduhelx_submission server extension',\n e.message,\n [Dialog.warnButton({ label: 'Dismiss' })]\n )\n return\n }\n // await (fileBrowser.model as any)._restored.promise\n const model = new EduhelxSubmissionModel()\n Promise.all([app.restored, fileBrowser.model.restored]).then(() => {\n model.currentPath = fileBrowser.model.path\n })\n fileBrowser.model.pathChanged.connect((fileBrowserModel: FileBrowserModel, change: IChangedArgs) => {\n model.currentPath = change.newValue\n })\n\n const submissionWidget = new AssignmentWidget(\n model,\n app.commands,\n serverSettings\n )\n submissionWidget.id = 'jp-submission-widget'\n submissionWidget.title.icon = submissionIcon\n submissionWidget.title.caption = 'Submit assignments'\n\n restorer.add(submissionWidget, 'submission-widget')\n shell.add(submissionWidget, 'left', { rank: 200 })\n}\n\n/**\n * Initialization data for the jupyterlab_eduhelx_submission extension.\n */\nconst plugin: JupyterFrontEndPlugin = {\n id: 'jupyterlab_eduhelx_submission:plugin',\n description: 'A JupyterLab extension tfor submitting assignments in EduHeLx',\n autoStart: true,\n requires: [\n IDefaultFileBrowser,\n ILayoutRestorer,\n ILabShell,\n ],\n activate\n};\n\nexport default plugin;\n","import { IChangedArgs } from '@jupyterlab/coreutils'\nimport { ISignal, Signal } from '@lumino/signaling'\nimport { Poll } from '@lumino/polling'\nimport { IEduhelxSubmissionModel } from './tokens'\nimport { getAssignments, IAssignment, IStudent, ICurrentAssignment, GetAssignmentsResponse, GetStudentAndCourseResponse, getStudentAndCourse, ICourse } from './api'\n\nexport class EduhelxSubmissionModel implements IEduhelxSubmissionModel {\n private _isDisposed: boolean = false\n private _currentPath: string | null = null\n private _currentAssignment: ICurrentAssignment | null | undefined = undefined\n private _assignments: IAssignment[] | null | undefined = undefined\n private _student: IStudent | undefined = undefined\n private _course: ICourse | undefined = undefined\n\n private _assignmentPoll: Poll\n\n private _currentPathChanged = new Signal<\n IEduhelxSubmissionModel,\n IChangedArgs\n >(this)\n private _currentAssignmentChanged = new Signal<\n IEduhelxSubmissionModel,\n IChangedArgs\n >(this)\n private _assignmentsChanged = new Signal<\n IEduhelxSubmissionModel,\n IChangedArgs\n >(this)\n private _studentChanged = new Signal<\n IEduhelxSubmissionModel,\n IChangedArgs\n >(this)\n private _courseChanged = new Signal<\n IEduhelxSubmissionModel,\n IChangedArgs\n >(this)\n\n constructor() {\n this._assignmentPoll = new Poll({\n factory: this._refreshModel.bind(this),\n frequency: {\n interval: 3000,\n backoff: true,\n max: 300 * 1000\n },\n standby: this._refreshStandby\n })\n }\n\n get isDisposed() {\n return this._isDisposed\n }\n\n get assignments(): IAssignment[] | null | undefined {\n return this._assignments\n }\n private set assignments(v: IAssignment[] | null | undefined) {\n const change: IChangedArgs = {\n name: 'assignments',\n newValue: v,\n oldValue: this.assignments\n }\n this._assignments = v\n this._assignmentsChanged.emit(change)\n }\n get assignmentsChanged(): ISignal> {\n return this._assignmentsChanged\n }\n\n get student(): IStudent | undefined {\n return this._student\n }\n private set student(v: IStudent | undefined) {\n const change: IChangedArgs = {\n name: 'student',\n newValue: v,\n oldValue: this.student\n }\n this._student = v\n this._studentChanged.emit(change)\n }\n get studentChanged(): ISignal> {\n return this._studentChanged\n }\n\n get course(): ICourse | undefined {\n return this._course\n }\n private set course(v: ICourse | undefined) {\n const change: IChangedArgs = {\n name: 'course',\n newValue: v,\n oldValue: this.course\n }\n this._course = v\n this._courseChanged.emit(change)\n }\n get courseChanged(): ISignal> {\n return this._courseChanged\n }\n\n // Undefined: loading, null: no current assignment\n get currentAssignment(): ICurrentAssignment | null | undefined {\n return this._currentAssignment\n }\n private set currentAssignment(v: ICurrentAssignment | null | undefined) {\n const change: IChangedArgs = {\n name: 'currentAssignment',\n newValue: v,\n oldValue: this.currentAssignment\n }\n this._currentAssignment = v\n this._currentAssignmentChanged.emit(change)\n }\n get currentAssignmentChanged(): ISignal> {\n return this._currentAssignmentChanged\n }\n \n get currentPath(): string | null {\n return this._currentPath\n }\n set currentPath(v: string | null) {\n const change: IChangedArgs = {\n name: 'currentPath',\n newValue: v,\n oldValue: this.currentPath\n }\n this._currentPath = v\n this._currentPathChanged.emit(change)\n this.refreshAssignment()\n }\n get currentPathChanged(): ISignal> {\n return this._currentPathChanged\n }\n\n private async _loadAssignments(): Promise {\n // If the currentPath is loading, the assignment is also loading.\n if (this.currentPath === null) {\n return undefined\n }\n try {\n return await getAssignments(this.currentPath)\n } catch (e: any) {\n console.error(e)\n // If the request encouners an error, default to loading.\n // Don't want to mislead and say an assignment directory isn't an assignment due to an error here.\n return undefined\n }\n }\n\n private async _loadStudentAndCourse(): Promise {\n try {\n return await getStudentAndCourse()\n } catch (e: any) {\n console.error(e)\n // If the request encouners an error, default to loading.\n return undefined\n }\n }\n\n async refreshAssignment() {\n // Set assignment to loading.\n this.currentAssignment = undefined\n this.assignments = undefined\n this.student = undefined\n // await this._assignmentPoll.refresh()\n this._refreshModel()\n await this._assignmentPoll.tick\n }\n\n private async _refreshModel(): Promise {\n const [\n assignmentsResponse,\n studentAndCourseResponse\n ] = await Promise.all([\n this._loadAssignments(),\n this._loadStudentAndCourse()\n ])\n if (assignmentsResponse === undefined) {\n this.assignments = undefined\n this.currentAssignment = undefined\n } else {\n this.assignments = assignmentsResponse.assignments\n this.currentAssignment = assignmentsResponse.currentAssignment\n }\n if (studentAndCourseResponse === undefined) {\n this.student = undefined\n this.course = undefined\n } else {\n this.student = studentAndCourseResponse.student\n this.course = studentAndCourseResponse.course\n }\n }\n\n /**\n * Determine if polling should temporarily suspend.\n * \n * Stand by, if:\n * - webpage hidden\n */\n private _refreshStandby(): boolean | Poll.Standby {\n // if (this.currentPath === null) return true\n return 'when-hidden'\n }\n\n dispose() {\n if (this.isDisposed) return\n this._isDisposed = true\n\n this._assignmentPoll.dispose()\n Signal.clearData(this)\n }\n}","import { LabIcon } from '@jupyterlab/ui-components'\nimport publishSvg from '../../style/icons/publish.svg'\n\nexport const submissionIcon = new LabIcon({ name: 'eduhelx-submission', svgstr: publishSvg })","import React, { Fragment, ReactNode, useEffect, useState } from 'react'\nimport moment, { Moment, duration } from 'moment'\n\ninterface IDateFormat {\n // E.g. Mar 5 at 11:59 PM\n toBasicDatetime(): string\n // E.g. in 3 months, 2 weeks\n // in 2 hours\n toRelativeDatetime(referenceTime?: Date): ReactNode | string\n}\n\nconst ReactiveTime = ({ getTime }: { getTime: () => string }) => {\n const [time, setTime] = useState(getTime())\n useEffect(() => {\n // Doesn't need to precisely sync to the internal time or anything\n // because the humanized moment is imprecise. \n const interval = window.setInterval(() => {\n setTime(getTime())\n }, 1000)\n return () => {\n window.clearInterval(interval)\n }\n }, [])\n return { time }\n}\n\n// The purpose of this is to standardize the date string formats used across the project.\nexport class DateFormat implements IDateFormat {\n private _date: Date\n private _moment: Moment\n constructor(date: Date) {\n this._date = date\n this._moment = moment(date)\n }\n\n toBasicDatetime(): string {\n return this._moment.format(\"MMM DD [at] h[:]mm A\")\n }\n\n toRelativeDatetime(referenceTime?: Date): ReactNode | string {\n const getDuration = (date: Date) => duration(this._moment.diff(moment(date))).humanize()\n if (referenceTime) return getDuration(referenceTime)\n return getDuration(new Date()) } />\n }\n}","import React from 'react'\nimport { ReactWidget } from '@jupyterlab/apputils'\nimport { CommandRegistry } from '@lumino/commands'\nimport { StylesProvider } from '@material-ui/core/styles'\nimport { AssignmentPanel } from '../components'\nimport { IServerSettings } from '../api'\nimport { AssignmentProvider, CommandsProvider, SettingsProvider, BackdropProvider, SnackbarProvider } from '../contexts'\nimport { IEduhelxSubmissionModel } from '../tokens'\n\nexport class AssignmentWidget extends ReactWidget {\n private model: IEduhelxSubmissionModel\n private commands: CommandRegistry\n private serverSettings: IServerSettings\n\n constructor(\n model: IEduhelxSubmissionModel,\n commands: CommandRegistry,\n serverSettings: IServerSettings\n ) {\n super()\n \n this.model = model\n this.commands = commands\n this.serverSettings = serverSettings\n }\n\n render() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n )\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/remoteEntry.17d261ce337cc1f4c0a6.js b/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/remoteEntry.17d261ce337cc1f4c0a6.js deleted file mode 100644 index ebda1de..0000000 --- a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/remoteEntry.17d261ce337cc1f4c0a6.js +++ /dev/null @@ -1,621 +0,0 @@ -var _JUPYTERLAB; -/******/ (() => { // webpackBootstrap -/******/ "use strict"; -/******/ var __webpack_modules__ = ({ - -/***/ "webpack/container/entry/jupyterlab_eduhelx_submission": -/*!***********************!*\ - !*** container entry ***! - \***********************/ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -var moduleMap = { - "./index": () => { - return Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js"), __webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("lib_index_js")]).then(() => (() => ((__webpack_require__(/*! ./lib/index.js */ "./lib/index.js"))))); - }, - "./extension": () => { - return Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js"), __webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("lib_index_js")]).then(() => (() => ((__webpack_require__(/*! ./lib/index.js */ "./lib/index.js"))))); - }, - "./style": () => { - return __webpack_require__.e("style_index_js").then(() => (() => ((__webpack_require__(/*! ./style/index.js */ "./style/index.js"))))); - } -}; -var get = (module, getScope) => { - __webpack_require__.R = getScope; - getScope = ( - __webpack_require__.o(moduleMap, module) - ? moduleMap[module]() - : Promise.resolve().then(() => { - throw new Error('Module "' + module + '" does not exist in container.'); - }) - ); - __webpack_require__.R = undefined; - return getScope; -}; -var init = (shareScope, initScope) => { - if (!__webpack_require__.S) return; - var name = "default" - var oldScope = __webpack_require__.S[name]; - if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope"); - __webpack_require__.S[name] = shareScope; - return __webpack_require__.I(name, initScope); -}; - -// This exports getters to disallow modifications -__webpack_require__.d(exports, { - get: () => (get), - init: () => (init) -}); - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ id: moduleId, -/******/ loaded: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.loaded = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = __webpack_modules__; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = __webpack_module_cache__; -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => (module['default']) : -/******/ () => (module); -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/ensure chunk */ -/******/ (() => { -/******/ __webpack_require__.f = {}; -/******/ // This file contains only the entry chunk. -/******/ // The chunk loading function for additional chunks -/******/ __webpack_require__.e = (chunkId) => { -/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { -/******/ __webpack_require__.f[key](chunkId, promises); -/******/ return promises; -/******/ }, [])); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/get javascript chunk filename */ -/******/ (() => { -/******/ // This function allow to reference async chunks -/******/ __webpack_require__.u = (chunkId) => { -/******/ // return url for filenames based on template -/******/ return "" + chunkId + "." + {"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js":"0a66b7a857eff04cfd3c","webpack_sharing_consume_default_react":"d9f39b0314904465e20e","lib_index_js":"145449ba8616931d9a24","style_index_js":"e6dbe76c4090a066b120","vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js":"9f28170428883e5db68f","vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de":"94d73718e3833fc805b9","vendors-node_modules_material-ui_core_esm_index_js":"85fcd77a00fe459adb40","webpack_sharing_consume_default_react-dom":"7648297e6e6b0457b0ca","vendors-node_modules_material-ui_icons_esm_index_js":"9f4b8347a3380b785aa7","vendors-node_modules_material-ui_lab_esm_index_js":"f15dc74ca1fbbcb7fc2e","webpack_sharing_consume_default_material-ui_core_material-ui_core":"98c533a5b38f6b524767","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-310b4c":"c0737f6cf9d820849fa3","node_modules_moment_locale_sync_recursive_":"0172cca19d5d67e0ee30","vendors-node_modules_qs_lib_index_js":"b88ea988ade9dc23c4f1","_09cc":"d254f18040b7f32da0cd","vendors-node_modules_typestyle_lib_es2015_index_js":"f73700843a4498ffc561","vendors-node_modules_uuid_dist_esm-browser_index_js":"3fe6d84b6eac82d6a30a"}[chunkId] + ".js"; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/global */ -/******/ (() => { -/******/ __webpack_require__.g = (function() { -/******/ if (typeof globalThis === 'object') return globalThis; -/******/ try { -/******/ return this || new Function('return this')(); -/******/ } catch (e) { -/******/ if (typeof window === 'object') return window; -/******/ } -/******/ })(); -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/load script */ -/******/ (() => { -/******/ var inProgress = {}; -/******/ var dataWebpackPrefix = "jupyterlab_eduhelx_submission:"; -/******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key, chunkId) => { -/******/ if(inProgress[url]) { inProgress[url].push(done); return; } -/******/ var script, needAttach; -/******/ if(key !== undefined) { -/******/ var scripts = document.getElementsByTagName("script"); -/******/ for(var i = 0; i < scripts.length; i++) { -/******/ var s = scripts[i]; -/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } -/******/ } -/******/ } -/******/ if(!script) { -/******/ needAttach = true; -/******/ script = document.createElement('script'); -/******/ -/******/ script.charset = 'utf-8'; -/******/ script.timeout = 120; -/******/ if (__webpack_require__.nc) { -/******/ script.setAttribute("nonce", __webpack_require__.nc); -/******/ } -/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); -/******/ -/******/ script.src = url; -/******/ } -/******/ inProgress[url] = [done]; -/******/ var onScriptComplete = (prev, event) => { -/******/ // avoid mem leaks in IE. -/******/ script.onerror = script.onload = null; -/******/ clearTimeout(timeout); -/******/ var doneFns = inProgress[url]; -/******/ delete inProgress[url]; -/******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => (fn(event))); -/******/ if(prev) return prev(event); -/******/ } -/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); -/******/ script.onerror = onScriptComplete.bind(null, script.onerror); -/******/ script.onload = onScriptComplete.bind(null, script.onload); -/******/ needAttach && document.head.appendChild(script); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/node module decorator */ -/******/ (() => { -/******/ __webpack_require__.nmd = (module) => { -/******/ module.paths = []; -/******/ if (!module.children) module.children = []; -/******/ return module; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/sharing */ -/******/ (() => { -/******/ __webpack_require__.S = {}; -/******/ var initPromises = {}; -/******/ var initTokens = {}; -/******/ __webpack_require__.I = (name, initScope) => { -/******/ if(!initScope) initScope = []; -/******/ // handling circular init calls -/******/ var initToken = initTokens[name]; -/******/ if(!initToken) initToken = initTokens[name] = {}; -/******/ if(initScope.indexOf(initToken) >= 0) return; -/******/ initScope.push(initToken); -/******/ // only runs once -/******/ if(initPromises[name]) return initPromises[name]; -/******/ // creates a new share scope if needed -/******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {}; -/******/ // runs all init snippets from all modules reachable -/******/ var scope = __webpack_require__.S[name]; -/******/ var warn = (msg) => { -/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg); -/******/ }; -/******/ var uniqueName = "jupyterlab_eduhelx_submission"; -/******/ var register = (name, version, factory, eager) => { -/******/ var versions = scope[name] = scope[name] || {}; -/******/ var activeVersion = versions[version]; -/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager }; -/******/ }; -/******/ var initExternal = (id) => { -/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err)); -/******/ try { -/******/ var module = __webpack_require__(id); -/******/ if(!module) return; -/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope)) -/******/ if(module.then) return promises.push(module.then(initFn, handleError)); -/******/ var initResult = initFn(module); -/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError)); -/******/ } catch(err) { handleError(err); } -/******/ } -/******/ var promises = []; -/******/ switch(name) { -/******/ case "default": { -/******/ register("@material-ui/core", "4.8.2", () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js"), __webpack_require__.e("vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de"), __webpack_require__.e("vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js"), __webpack_require__.e("vendors-node_modules_material-ui_core_esm_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("webpack_sharing_consume_default_react-dom")]).then(() => (() => (__webpack_require__(/*! ./node_modules/@material-ui/core/esm/index.js */ "./node_modules/@material-ui/core/esm/index.js")))))); -/******/ register("@material-ui/icons", "4.5.1", () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js"), __webpack_require__.e("vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js"), __webpack_require__.e("vendors-node_modules_material-ui_icons_esm_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react")]).then(() => (() => (__webpack_require__(/*! ./node_modules/@material-ui/icons/esm/index.js */ "./node_modules/@material-ui/icons/esm/index.js")))))); -/******/ register("@material-ui/lab", "4.0.0-alpha.39", () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js"), __webpack_require__.e("vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de"), __webpack_require__.e("vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js"), __webpack_require__.e("vendors-node_modules_material-ui_lab_esm_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("webpack_sharing_consume_default_react-dom"), __webpack_require__.e("webpack_sharing_consume_default_material-ui_core_material-ui_core")]).then(() => (() => (__webpack_require__(/*! ./node_modules/@material-ui/lab/esm/index.js */ "./node_modules/@material-ui/lab/esm/index.js")))))); -/******/ register("jupyterlab_eduhelx_submission", "0.1.0", () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js"), __webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("lib_index_js")]).then(() => (() => (__webpack_require__(/*! ./lib/index.js */ "./lib/index.js")))))); -/******/ register("moment", "2.29.4", () => (Promise.all([__webpack_require__.e("vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-310b4c"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_")]).then(() => (() => (__webpack_require__(/*! ./node_modules/moment/moment.js */ "./node_modules/moment/moment.js")))))); -/******/ register("qs", "6.11.2", () => (Promise.all([__webpack_require__.e("vendors-node_modules_qs_lib_index_js"), __webpack_require__.e("_09cc")]).then(() => (() => (__webpack_require__(/*! ./node_modules/qs/lib/index.js */ "./node_modules/qs/lib/index.js")))))); -/******/ register("typestyle", "2.4.0", () => (__webpack_require__.e("vendors-node_modules_typestyle_lib_es2015_index_js").then(() => (() => (__webpack_require__(/*! ./node_modules/typestyle/lib.es2015/index.js */ "./node_modules/typestyle/lib.es2015/index.js")))))); -/******/ register("uuid", "9.0.0", () => (__webpack_require__.e("vendors-node_modules_uuid_dist_esm-browser_index_js").then(() => (() => (__webpack_require__(/*! ./node_modules/uuid/dist/esm-browser/index.js */ "./node_modules/uuid/dist/esm-browser/index.js")))))); -/******/ } -/******/ break; -/******/ } -/******/ if(!promises.length) return initPromises[name] = 1; -/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1)); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/publicPath */ -/******/ (() => { -/******/ var scriptUrl; -/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + ""; -/******/ var document = __webpack_require__.g.document; -/******/ if (!scriptUrl && document) { -/******/ if (document.currentScript) -/******/ scriptUrl = document.currentScript.src; -/******/ if (!scriptUrl) { -/******/ var scripts = document.getElementsByTagName("script"); -/******/ if(scripts.length) { -/******/ var i = scripts.length - 1; -/******/ while (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src; -/******/ } -/******/ } -/******/ } -/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration -/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic. -/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser"); -/******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/"); -/******/ __webpack_require__.p = scriptUrl; -/******/ })(); -/******/ -/******/ /* webpack/runtime/consumes */ -/******/ (() => { -/******/ var parseVersion = (str) => { -/******/ // see webpack/lib/util/semver.js for original code -/******/ var p=p=>{return p.split(".").map((p=>{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r; -/******/ } -/******/ var versionLt = (a, b) => { -/******/ // see webpack/lib/util/semver.js for original code -/******/ a=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e { -/******/ // see webpack/lib/util/semver.js for original code -/******/ var r=range[0],n="";if(1===range.length)return"*";if(r+.5){n+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a { -/******/ // see webpack/lib/util/semver.js for original code -/******/ if(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f { -/******/ var scope = __webpack_require__.S[scopeName]; -/******/ if(!scope || !__webpack_require__.o(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName); -/******/ return scope; -/******/ }; -/******/ var findVersion = (scope, key) => { -/******/ var versions = scope[key]; -/******/ var key = Object.keys(versions).reduce((a, b) => { -/******/ return !a || versionLt(a, b) ? b : a; -/******/ }, 0); -/******/ return key && versions[key] -/******/ }; -/******/ var findSingletonVersionKey = (scope, key) => { -/******/ var versions = scope[key]; -/******/ return Object.keys(versions).reduce((a, b) => { -/******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a; -/******/ }, 0); -/******/ }; -/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => { -/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" -/******/ }; -/******/ var getSingleton = (scope, scopeName, key, requiredVersion) => { -/******/ var version = findSingletonVersionKey(scope, key); -/******/ return get(scope[key][version]); -/******/ }; -/******/ var getSingletonVersion = (scope, scopeName, key, requiredVersion) => { -/******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); -/******/ return get(scope[key][version]); -/******/ }; -/******/ var getStrictSingletonVersion = (scope, scopeName, key, requiredVersion) => { -/******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); -/******/ return get(scope[key][version]); -/******/ }; -/******/ var findValidVersion = (scope, key, requiredVersion) => { -/******/ var versions = scope[key]; -/******/ var key = Object.keys(versions).reduce((a, b) => { -/******/ if (!satisfy(requiredVersion, b)) return a; -/******/ return !a || versionLt(a, b) ? b : a; -/******/ }, 0); -/******/ return key && versions[key] -/******/ }; -/******/ var getInvalidVersionMessage = (scope, scopeName, key, requiredVersion) => { -/******/ var versions = scope[key]; -/******/ return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\n" + -/******/ "Available versions: " + Object.keys(versions).map((key) => { -/******/ return key + " from " + versions[key].from; -/******/ }).join(", "); -/******/ }; -/******/ var getValidVersion = (scope, scopeName, key, requiredVersion) => { -/******/ var entry = findValidVersion(scope, key, requiredVersion); -/******/ if(entry) return get(entry); -/******/ throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); -/******/ }; -/******/ var warn = (msg) => { -/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg); -/******/ }; -/******/ var warnInvalidVersion = (scope, scopeName, key, requiredVersion) => { -/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); -/******/ }; -/******/ var get = (entry) => { -/******/ entry.loaded = 1; -/******/ return entry.get() -/******/ }; -/******/ var init = (fn) => (function(scopeName, a, b, c) { -/******/ var promise = __webpack_require__.I(scopeName); -/******/ if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c)); -/******/ return fn(scopeName, __webpack_require__.S[scopeName], a, b, c); -/******/ }); -/******/ -/******/ var load = /*#__PURE__*/ init((scopeName, scope, key) => { -/******/ ensureExistence(scopeName, key); -/******/ return get(findVersion(scope, key)); -/******/ }); -/******/ var loadFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => { -/******/ return scope && __webpack_require__.o(scope, key) ? get(findVersion(scope, key)) : fallback(); -/******/ }); -/******/ var loadVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { -/******/ ensureExistence(scopeName, key); -/******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); -/******/ }); -/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key) => { -/******/ ensureExistence(scopeName, key); -/******/ return getSingleton(scope, scopeName, key); -/******/ }); -/******/ var loadSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { -/******/ ensureExistence(scopeName, key); -/******/ return getSingletonVersion(scope, scopeName, key, version); -/******/ }); -/******/ var loadStrictVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { -/******/ ensureExistence(scopeName, key); -/******/ return getValidVersion(scope, scopeName, key, version); -/******/ }); -/******/ var loadStrictSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { -/******/ ensureExistence(scopeName, key); -/******/ return getStrictSingletonVersion(scope, scopeName, key, version); -/******/ }); -/******/ var loadVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { -/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); -/******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); -/******/ }); -/******/ var loadSingletonFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => { -/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); -/******/ return getSingleton(scope, scopeName, key); -/******/ }); -/******/ var loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { -/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); -/******/ return getSingletonVersion(scope, scopeName, key, version); -/******/ }); -/******/ var loadStrictVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { -/******/ var entry = scope && __webpack_require__.o(scope, key) && findValidVersion(scope, key, version); -/******/ return entry ? get(entry) : fallback(); -/******/ }); -/******/ var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { -/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); -/******/ return getStrictSingletonVersion(scope, scopeName, key, version); -/******/ }); -/******/ var installedModules = {}; -/******/ var moduleToHandlerMapping = { -/******/ "webpack/sharing/consume/default/react": () => (loadSingletonVersionCheck("default", "react", [1,18,2,0])), -/******/ "webpack/sharing/consume/default/@jupyterlab/application": () => (loadSingletonVersionCheck("default", "@jupyterlab/application", [1,4,0,8])), -/******/ "webpack/sharing/consume/default/@jupyterlab/filebrowser": () => (loadSingletonVersionCheck("default", "@jupyterlab/filebrowser", [1,4,0,8])), -/******/ "webpack/sharing/consume/default/@jupyterlab/apputils": () => (loadSingletonVersionCheck("default", "@jupyterlab/apputils", [1,4,1,8])), -/******/ "webpack/sharing/consume/default/qs/qs": () => (loadStrictVersionCheckFallback("default", "qs", [1,6,11,2], () => (Promise.all([__webpack_require__.e("vendors-node_modules_qs_lib_index_js"), __webpack_require__.e("_09cc")]).then(() => (() => (__webpack_require__(/*! qs */ "./node_modules/qs/lib/index.js"))))))), -/******/ "webpack/sharing/consume/default/@jupyterlab/services": () => (loadSingletonVersionCheck("default", "@jupyterlab/services", [1,7,0,8])), -/******/ "webpack/sharing/consume/default/@jupyterlab/coreutils": () => (loadSingletonVersionCheck("default", "@jupyterlab/coreutils", [1,6,0,8])), -/******/ "webpack/sharing/consume/default/@lumino/signaling": () => (loadSingletonVersionCheck("default", "@lumino/signaling", [1,2,0,0])), -/******/ "webpack/sharing/consume/default/@lumino/polling": () => (loadSingletonVersionCheck("default", "@lumino/polling", [1,2,0,0])), -/******/ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99": () => (loadSingletonVersionCheckFallback("default", "@material-ui/core", [1,4,8,2], () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js"), __webpack_require__.e("vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de"), __webpack_require__.e("vendors-node_modules_material-ui_core_esm_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react-dom")]).then(() => (() => (__webpack_require__(/*! @material-ui/core */ "./node_modules/@material-ui/core/esm/index.js"))))))), -/******/ "webpack/sharing/consume/default/@material-ui/lab/@material-ui/lab": () => (loadSingletonVersionCheckFallback("default", "@material-ui/lab", [1,4,0,0,,"alpha",39], () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js"), __webpack_require__.e("vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de"), __webpack_require__.e("vendors-node_modules_material-ui_lab_esm_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react-dom"), __webpack_require__.e("webpack_sharing_consume_default_material-ui_core_material-ui_core")]).then(() => (() => (__webpack_require__(/*! @material-ui/lab */ "./node_modules/@material-ui/lab/esm/index.js"))))))), -/******/ "webpack/sharing/consume/default/uuid/uuid": () => (loadStrictVersionCheckFallback("default", "uuid", [1,9,0,0], () => (__webpack_require__.e("vendors-node_modules_uuid_dist_esm-browser_index_js").then(() => (() => (__webpack_require__(/*! uuid */ "./node_modules/uuid/dist/esm-browser/index.js"))))))), -/******/ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons": () => (loadSingletonVersionCheckFallback("default", "@material-ui/icons", [1,4,5,1], () => (Promise.all([__webpack_require__.e("vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js"), __webpack_require__.e("vendors-node_modules_material-ui_icons_esm_index_js")]).then(() => (() => (__webpack_require__(/*! @material-ui/icons */ "./node_modules/@material-ui/icons/esm/index.js"))))))), -/******/ "webpack/sharing/consume/default/typestyle/typestyle": () => (loadStrictVersionCheckFallback("default", "typestyle", [1,2,4,0], () => (__webpack_require__.e("vendors-node_modules_typestyle_lib_es2015_index_js").then(() => (() => (__webpack_require__(/*! typestyle */ "./node_modules/typestyle/lib.es2015/index.js"))))))), -/******/ "webpack/sharing/consume/default/moment/moment": () => (loadStrictVersionCheckFallback("default", "moment", [1,2,29,4], () => (Promise.all([__webpack_require__.e("vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-310b4c"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_")]).then(() => (() => (__webpack_require__(/*! moment */ "./node_modules/moment/moment.js"))))))), -/******/ "webpack/sharing/consume/default/@jupyterlab/ui-components": () => (loadSingletonVersionCheck("default", "@jupyterlab/ui-components", [1,4,0,8])), -/******/ "webpack/sharing/consume/default/react-dom": () => (loadSingletonVersionCheck("default", "react-dom", [1,18,2,0])), -/******/ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?fbe4": () => (loadSingletonVersionCheckFallback("default", "@material-ui/core", [1,4,7,0], () => (__webpack_require__.e("vendors-node_modules_material-ui_core_esm_index_js").then(() => (() => (__webpack_require__(/*! @material-ui/core */ "./node_modules/@material-ui/core/esm/index.js"))))))) -/******/ }; -/******/ // no consumes in initial chunks -/******/ var chunkMapping = { -/******/ "webpack_sharing_consume_default_react": [ -/******/ "webpack/sharing/consume/default/react" -/******/ ], -/******/ "lib_index_js": [ -/******/ "webpack/sharing/consume/default/@jupyterlab/application", -/******/ "webpack/sharing/consume/default/@jupyterlab/filebrowser", -/******/ "webpack/sharing/consume/default/@jupyterlab/apputils", -/******/ "webpack/sharing/consume/default/qs/qs", -/******/ "webpack/sharing/consume/default/@jupyterlab/services", -/******/ "webpack/sharing/consume/default/@jupyterlab/coreutils", -/******/ "webpack/sharing/consume/default/@lumino/signaling", -/******/ "webpack/sharing/consume/default/@lumino/polling", -/******/ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99", -/******/ "webpack/sharing/consume/default/@material-ui/lab/@material-ui/lab", -/******/ "webpack/sharing/consume/default/uuid/uuid", -/******/ "webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons", -/******/ "webpack/sharing/consume/default/typestyle/typestyle", -/******/ "webpack/sharing/consume/default/moment/moment", -/******/ "webpack/sharing/consume/default/@jupyterlab/ui-components" -/******/ ], -/******/ "webpack_sharing_consume_default_react-dom": [ -/******/ "webpack/sharing/consume/default/react-dom" -/******/ ], -/******/ "webpack_sharing_consume_default_material-ui_core_material-ui_core": [ -/******/ "webpack/sharing/consume/default/@material-ui/core/@material-ui/core?fbe4" -/******/ ] -/******/ }; -/******/ var startedInstallModules = {}; -/******/ __webpack_require__.f.consumes = (chunkId, promises) => { -/******/ if(__webpack_require__.o(chunkMapping, chunkId)) { -/******/ chunkMapping[chunkId].forEach((id) => { -/******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]); -/******/ if(!startedInstallModules[id]) { -/******/ var onFactory = (factory) => { -/******/ installedModules[id] = 0; -/******/ __webpack_require__.m[id] = (module) => { -/******/ delete __webpack_require__.c[id]; -/******/ module.exports = factory(); -/******/ } -/******/ }; -/******/ startedInstallModules[id] = true; -/******/ var onError = (error) => { -/******/ delete installedModules[id]; -/******/ __webpack_require__.m[id] = (module) => { -/******/ delete __webpack_require__.c[id]; -/******/ throw error; -/******/ } -/******/ }; -/******/ try { -/******/ var promise = moduleToHandlerMapping[id](); -/******/ if(promise.then) { -/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError)); -/******/ } else onFactory(promise); -/******/ } catch(e) { onError(e); } -/******/ } -/******/ }); -/******/ } -/******/ } -/******/ })(); -/******/ -/******/ /* webpack/runtime/jsonp chunk loading */ -/******/ (() => { -/******/ // no baseURI -/******/ -/******/ // object to store loaded and loading chunks -/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded -/******/ var installedChunks = { -/******/ "jupyterlab_eduhelx_submission": 0 -/******/ }; -/******/ -/******/ __webpack_require__.f.j = (chunkId, promises) => { -/******/ // JSONP chunk loading for javascript -/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; -/******/ if(installedChunkData !== 0) { // 0 means "already installed". -/******/ -/******/ // a Promise means "currently loading". -/******/ if(installedChunkData) { -/******/ promises.push(installedChunkData[2]); -/******/ } else { -/******/ if(!/^webpack_sharing_consume_default_(react(|\-dom)|material\-ui_core_material\-ui_core)$/.test(chunkId)) { -/******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); -/******/ promises.push(installedChunkData[2] = promise); -/******/ -/******/ // start chunk loading -/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId); -/******/ // create error before stack unwound to get useful stacktrace later -/******/ var error = new Error(); -/******/ var loadingEnded = (event) => { -/******/ if(__webpack_require__.o(installedChunks, chunkId)) { -/******/ installedChunkData = installedChunks[chunkId]; -/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; -/******/ if(installedChunkData) { -/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); -/******/ var realSrc = event && event.target && event.target.src; -/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; -/******/ error.name = 'ChunkLoadError'; -/******/ error.type = errorType; -/******/ error.request = realSrc; -/******/ installedChunkData[1](error); -/******/ } -/******/ } -/******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); -/******/ } else installedChunks[chunkId] = 0; -/******/ } -/******/ } -/******/ }; -/******/ -/******/ // no prefetching -/******/ -/******/ // no preloaded -/******/ -/******/ // no HMR -/******/ -/******/ // no HMR manifest -/******/ -/******/ // no on chunks loaded -/******/ -/******/ // install a JSONP callback for chunk loading -/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime] = data; -/******/ // add "moreModules" to the modules object, -/******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0; -/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) var result = runtime(__webpack_require__); -/******/ } -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ for(;i < chunkIds.length; i++) { -/******/ chunkId = chunkIds[i]; -/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ installedChunks[chunkId][0](); -/******/ } -/******/ installedChunks[chunkId] = 0; -/******/ } -/******/ -/******/ } -/******/ -/******/ var chunkLoadingGlobal = self["webpackChunkjupyterlab_eduhelx_submission"] = self["webpackChunkjupyterlab_eduhelx_submission"] || []; -/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); -/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ })(); -/******/ -/******/ /* webpack/runtime/nonce */ -/******/ (() => { -/******/ __webpack_require__.nc = undefined; -/******/ })(); -/******/ -/************************************************************************/ -/******/ -/******/ // module cache are used so entry inlining is disabled -/******/ // startup -/******/ // Load entry module and return exports -/******/ var __webpack_exports__ = __webpack_require__("webpack/container/entry/jupyterlab_eduhelx_submission"); -/******/ (_JUPYTERLAB = typeof _JUPYTERLAB === "undefined" ? {} : _JUPYTERLAB).jupyterlab_eduhelx_submission = __webpack_exports__; -/******/ -/******/ })() -; -//# sourceMappingURL=remoteEntry.17d261ce337cc1f4c0a6.js.map \ No newline at end of file diff --git a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/remoteEntry.17d261ce337cc1f4c0a6.js.map b/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/remoteEntry.17d261ce337cc1f4c0a6.js.map deleted file mode 100644 index 468343d..0000000 --- a/eduhelx_jupyterlab_student/jupyterlab_eduhelx_submission/labextension/static/remoteEntry.17d261ce337cc1f4c0a6.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"remoteEntry.17d261ce337cc1f4c0a6.js","mappings":";;;;;;;;;;;AAAA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;;;;;;UCpCD;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;;;;;WC/BA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,EAAE;WACF;;;;;WCRA;WACA;WACA;WACA,8BAA8B,iwCAAiwC;WAC/xC;;;;;WCJA;WACA;WACA;WACA;WACA,GAAG;WACH;WACA;WACA,CAAC;;;;;WCPD;;;;;WCAA;WACA;WACA;WACA;WACA,uBAAuB,4BAA4B;WACnD;WACA;WACA;WACA,iBAAiB,oBAAoB;WACrC;WACA,mGAAmG,YAAY;WAC/G;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,mEAAmE,iCAAiC;WACpG;WACA;WACA;WACA;;;;;WCzCA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;WACA;WACA;WACA;WACA;;;;;WCJA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,oJAAoJ;WACpJ;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,IAAI,aAAa;WACjB;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;WCpDA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;WClBA;WACA;WACA,WAAW,6BAA6B,iBAAiB,GAAG,qEAAqE;WACjI;WACA;WACA;WACA,qCAAqC,aAAa,EAAE,wDAAwD,2BAA2B,4BAA4B,2BAA2B,+CAA+C,mCAAmC;WAChR;WACA;WACA;WACA,qBAAqB,8BAA8B,SAAS,sDAAsD,gBAAgB,eAAe,KAAK,6DAA6D,SAAS,SAAS,QAAQ,eAAe,KAAK,eAAe,qGAAqG,WAAW,aAAa;WAC7Y;WACA;WACA;WACA,gBAAgB,8BAA8B,qBAAqB,YAAY,sBAAsB,SAAS,iDAAiD,6FAA6F,WAAW,uBAAuB,2BAA2B,wBAAwB,KAAK,oCAAoC,oBAAoB,wBAAwB,oBAAoB,SAAS,KAAK,yBAAyB,KAAK,gCAAgC,yBAAyB,QAAQ,eAAe,KAAK,eAAe,4DAA4D;WACtoB;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,EAAE;WACF;WACA;WACA;WACA;WACA;WACA;WACA,EAAE;WACF;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,EAAE;WACF;WACA;WACA;WACA;WACA;WACA;WACA;WACA,EAAE;WACF;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,CAAC;;WAED;WACA;WACA;WACA,CAAC;WACD;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA,CAAC;WACD;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM;WACN,KAAK,WAAW;WAChB;WACA,GAAG;WACH;WACA;;;;;WCtNA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA,iCAAiC;;WAEjC;WACA;WACA;WACA,KAAK;WACL;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM;WACN;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM,qBAAqB;WAC3B;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;WACA;WACA;;;;;WCrFA;;;;;UEAA;UACA;UACA;UACA","sources":["webpack://jupyterlab_eduhelx_submission/webpack/container-entry","webpack://jupyterlab_eduhelx_submission/webpack/bootstrap","webpack://jupyterlab_eduhelx_submission/webpack/runtime/compat get default export","webpack://jupyterlab_eduhelx_submission/webpack/runtime/define property getters","webpack://jupyterlab_eduhelx_submission/webpack/runtime/ensure chunk","webpack://jupyterlab_eduhelx_submission/webpack/runtime/get javascript chunk filename","webpack://jupyterlab_eduhelx_submission/webpack/runtime/global","webpack://jupyterlab_eduhelx_submission/webpack/runtime/hasOwnProperty shorthand","webpack://jupyterlab_eduhelx_submission/webpack/runtime/load script","webpack://jupyterlab_eduhelx_submission/webpack/runtime/make namespace object","webpack://jupyterlab_eduhelx_submission/webpack/runtime/node module decorator","webpack://jupyterlab_eduhelx_submission/webpack/runtime/sharing","webpack://jupyterlab_eduhelx_submission/webpack/runtime/publicPath","webpack://jupyterlab_eduhelx_submission/webpack/runtime/consumes","webpack://jupyterlab_eduhelx_submission/webpack/runtime/jsonp chunk loading","webpack://jupyterlab_eduhelx_submission/webpack/runtime/nonce","webpack://jupyterlab_eduhelx_submission/webpack/before-startup","webpack://jupyterlab_eduhelx_submission/webpack/startup","webpack://jupyterlab_eduhelx_submission/webpack/after-startup"],"sourcesContent":["var moduleMap = {\n\t\"./index\": () => {\n\t\treturn Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react\"), __webpack_require__.e(\"lib_index_js\")]).then(() => (() => ((__webpack_require__(/*! ./lib/index.js */ \"./lib/index.js\")))));\n\t},\n\t\"./extension\": () => {\n\t\treturn Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react\"), __webpack_require__.e(\"lib_index_js\")]).then(() => (() => ((__webpack_require__(/*! ./lib/index.js */ \"./lib/index.js\")))));\n\t},\n\t\"./style\": () => {\n\t\treturn __webpack_require__.e(\"style_index_js\").then(() => (() => ((__webpack_require__(/*! ./style/index.js */ \"./style/index.js\")))));\n\t}\n};\nvar get = (module, getScope) => {\n\t__webpack_require__.R = getScope;\n\tgetScope = (\n\t\t__webpack_require__.o(moduleMap, module)\n\t\t\t? moduleMap[module]()\n\t\t\t: Promise.resolve().then(() => {\n\t\t\t\tthrow new Error('Module \"' + module + '\" does not exist in container.');\n\t\t\t})\n\t);\n\t__webpack_require__.R = undefined;\n\treturn getScope;\n};\nvar init = (shareScope, initScope) => {\n\tif (!__webpack_require__.S) return;\n\tvar name = \"default\"\n\tvar oldScope = __webpack_require__.S[name];\n\tif(oldScope && oldScope !== shareScope) throw new Error(\"Container initialization failed as it has already been initialized with a different share scope\");\n\t__webpack_require__.S[name] = shareScope;\n\treturn __webpack_require__.I(name, initScope);\n};\n\n// This exports getters to disallow modifications\n__webpack_require__.d(exports, {\n\tget: () => (get),\n\tinit: () => (init)\n});","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// expose the module cache\n__webpack_require__.c = __webpack_module_cache__;\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".\" + {\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\":\"0a66b7a857eff04cfd3c\",\"webpack_sharing_consume_default_react\":\"d9f39b0314904465e20e\",\"lib_index_js\":\"145449ba8616931d9a24\",\"style_index_js\":\"e6dbe76c4090a066b120\",\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\":\"9f28170428883e5db68f\",\"vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de\":\"94d73718e3833fc805b9\",\"vendors-node_modules_material-ui_core_esm_index_js\":\"85fcd77a00fe459adb40\",\"webpack_sharing_consume_default_react-dom\":\"7648297e6e6b0457b0ca\",\"vendors-node_modules_material-ui_icons_esm_index_js\":\"9f4b8347a3380b785aa7\",\"vendors-node_modules_material-ui_lab_esm_index_js\":\"f15dc74ca1fbbcb7fc2e\",\"webpack_sharing_consume_default_material-ui_core_material-ui_core\":\"98c533a5b38f6b524767\",\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-310b4c\":\"c0737f6cf9d820849fa3\",\"node_modules_moment_locale_sync_recursive_\":\"0172cca19d5d67e0ee30\",\"vendors-node_modules_qs_lib_index_js\":\"b88ea988ade9dc23c4f1\",\"_09cc\":\"d254f18040b7f32da0cd\",\"vendors-node_modules_typestyle_lib_es2015_index_js\":\"f73700843a4498ffc561\",\"vendors-node_modules_uuid_dist_esm-browser_index_js\":\"3fe6d84b6eac82d6a30a\"}[chunkId] + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var inProgress = {};\nvar dataWebpackPrefix = \"jupyterlab_eduhelx_submission:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = (url, done, key, chunkId) => {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = (prev, event) => {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach((fn) => (fn(event)));\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = (module) => {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.S = {};\nvar initPromises = {};\nvar initTokens = {};\n__webpack_require__.I = (name, initScope) => {\n\tif(!initScope) initScope = [];\n\t// handling circular init calls\n\tvar initToken = initTokens[name];\n\tif(!initToken) initToken = initTokens[name] = {};\n\tif(initScope.indexOf(initToken) >= 0) return;\n\tinitScope.push(initToken);\n\t// only runs once\n\tif(initPromises[name]) return initPromises[name];\n\t// creates a new share scope if needed\n\tif(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {};\n\t// runs all init snippets from all modules reachable\n\tvar scope = __webpack_require__.S[name];\n\tvar warn = (msg) => {\n\t\tif (typeof console !== \"undefined\" && console.warn) console.warn(msg);\n\t};\n\tvar uniqueName = \"jupyterlab_eduhelx_submission\";\n\tvar register = (name, version, factory, eager) => {\n\t\tvar versions = scope[name] = scope[name] || {};\n\t\tvar activeVersion = versions[version];\n\t\tif(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };\n\t};\n\tvar initExternal = (id) => {\n\t\tvar handleError = (err) => (warn(\"Initialization of sharing external failed: \" + err));\n\t\ttry {\n\t\t\tvar module = __webpack_require__(id);\n\t\t\tif(!module) return;\n\t\t\tvar initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope))\n\t\t\tif(module.then) return promises.push(module.then(initFn, handleError));\n\t\t\tvar initResult = initFn(module);\n\t\t\tif(initResult && initResult.then) return promises.push(initResult['catch'](handleError));\n\t\t} catch(err) { handleError(err); }\n\t}\n\tvar promises = [];\n\tswitch(name) {\n\t\tcase \"default\": {\n\t\t\tregister(\"@material-ui/core\", \"4.8.2\", () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\"), __webpack_require__.e(\"vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de\"), __webpack_require__.e(\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\"), __webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_index_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react\"), __webpack_require__.e(\"webpack_sharing_consume_default_react-dom\")]).then(() => (() => (__webpack_require__(/*! ./node_modules/@material-ui/core/esm/index.js */ \"./node_modules/@material-ui/core/esm/index.js\"))))));\n\t\t\tregister(\"@material-ui/icons\", \"4.5.1\", () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\"), __webpack_require__.e(\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\"), __webpack_require__.e(\"vendors-node_modules_material-ui_icons_esm_index_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react\")]).then(() => (() => (__webpack_require__(/*! ./node_modules/@material-ui/icons/esm/index.js */ \"./node_modules/@material-ui/icons/esm/index.js\"))))));\n\t\t\tregister(\"@material-ui/lab\", \"4.0.0-alpha.39\", () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\"), __webpack_require__.e(\"vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de\"), __webpack_require__.e(\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\"), __webpack_require__.e(\"vendors-node_modules_material-ui_lab_esm_index_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react\"), __webpack_require__.e(\"webpack_sharing_consume_default_react-dom\"), __webpack_require__.e(\"webpack_sharing_consume_default_material-ui_core_material-ui_core\")]).then(() => (() => (__webpack_require__(/*! ./node_modules/@material-ui/lab/esm/index.js */ \"./node_modules/@material-ui/lab/esm/index.js\"))))));\n\t\t\tregister(\"jupyterlab_eduhelx_submission\", \"0.1.0\", () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_styles_esm_StylesProvider_StylesProvider_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react\"), __webpack_require__.e(\"lib_index_js\")]).then(() => (() => (__webpack_require__(/*! ./lib/index.js */ \"./lib/index.js\"))))));\n\t\t\tregister(\"moment\", \"2.29.4\", () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-310b4c\"), __webpack_require__.e(\"node_modules_moment_locale_sync_recursive_\")]).then(() => (() => (__webpack_require__(/*! ./node_modules/moment/moment.js */ \"./node_modules/moment/moment.js\"))))));\n\t\t\tregister(\"qs\", \"6.11.2\", () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_qs_lib_index_js\"), __webpack_require__.e(\"_09cc\")]).then(() => (() => (__webpack_require__(/*! ./node_modules/qs/lib/index.js */ \"./node_modules/qs/lib/index.js\"))))));\n\t\t\tregister(\"typestyle\", \"2.4.0\", () => (__webpack_require__.e(\"vendors-node_modules_typestyle_lib_es2015_index_js\").then(() => (() => (__webpack_require__(/*! ./node_modules/typestyle/lib.es2015/index.js */ \"./node_modules/typestyle/lib.es2015/index.js\"))))));\n\t\t\tregister(\"uuid\", \"9.0.0\", () => (__webpack_require__.e(\"vendors-node_modules_uuid_dist_esm-browser_index_js\").then(() => (() => (__webpack_require__(/*! ./node_modules/uuid/dist/esm-browser/index.js */ \"./node_modules/uuid/dist/esm-browser/index.js\"))))));\n\t\t}\n\t\tbreak;\n\t}\n\tif(!promises.length) return initPromises[name] = 1;\n\treturn initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1));\n};","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","var parseVersion = (str) => {\n\t// see webpack/lib/util/semver.js for original code\n\tvar p=p=>{return p.split(\".\").map((p=>{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:\\+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;\n}\nvar versionLt = (a, b) => {\n\t// see webpack/lib/util/semver.js for original code\n\ta=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r=b.length)return\"u\"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return\"o\"==n&&\"n\"==f||(\"s\"==f||\"u\"==n);if(\"o\"!=n&&\"u\"!=n&&e!=t)return e {\n\t// see webpack/lib/util/semver.js for original code\n\tvar r=range[0],n=\"\";if(1===range.length)return\"*\";if(r+.5){n+=0==r?\">=\":-1==r?\"<\":1==r?\"^\":2==r?\"~\":r>0?\"=\":\"!=\";for(var e=1,a=1;a0?\".\":\"\")+(e=2,t)}return n}var g=[];for(a=1;a {\n\t// see webpack/lib/util/semver.js for original code\n\tif(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i=version.length||\"o\"==(s=(typeof(f=version[n]))[0]))return!a||(\"u\"==g?i>e&&!r:\"\"==g!=r);if(\"u\"==s){if(!a||\"u\"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f {\n\tvar scope = __webpack_require__.S[scopeName];\n\tif(!scope || !__webpack_require__.o(scope, key)) throw new Error(\"Shared module \" + key + \" doesn't exist in shared scope \" + scopeName);\n\treturn scope;\n};\nvar findVersion = (scope, key) => {\n\tvar versions = scope[key];\n\tvar key = Object.keys(versions).reduce((a, b) => {\n\t\treturn !a || versionLt(a, b) ? b : a;\n\t}, 0);\n\treturn key && versions[key]\n};\nvar findSingletonVersionKey = (scope, key) => {\n\tvar versions = scope[key];\n\treturn Object.keys(versions).reduce((a, b) => {\n\t\treturn !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;\n\t}, 0);\n};\nvar getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => {\n\treturn \"Unsatisfied version \" + version + \" from \" + (version && scope[key][version].from) + \" of shared singleton module \" + key + \" (required \" + rangeToString(requiredVersion) + \")\"\n};\nvar getSingleton = (scope, scopeName, key, requiredVersion) => {\n\tvar version = findSingletonVersionKey(scope, key);\n\treturn get(scope[key][version]);\n};\nvar getSingletonVersion = (scope, scopeName, key, requiredVersion) => {\n\tvar version = findSingletonVersionKey(scope, key);\n\tif (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));\n\treturn get(scope[key][version]);\n};\nvar getStrictSingletonVersion = (scope, scopeName, key, requiredVersion) => {\n\tvar version = findSingletonVersionKey(scope, key);\n\tif (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));\n\treturn get(scope[key][version]);\n};\nvar findValidVersion = (scope, key, requiredVersion) => {\n\tvar versions = scope[key];\n\tvar key = Object.keys(versions).reduce((a, b) => {\n\t\tif (!satisfy(requiredVersion, b)) return a;\n\t\treturn !a || versionLt(a, b) ? b : a;\n\t}, 0);\n\treturn key && versions[key]\n};\nvar getInvalidVersionMessage = (scope, scopeName, key, requiredVersion) => {\n\tvar versions = scope[key];\n\treturn \"No satisfying version (\" + rangeToString(requiredVersion) + \") of shared module \" + key + \" found in shared scope \" + scopeName + \".\\n\" +\n\t\t\"Available versions: \" + Object.keys(versions).map((key) => {\n\t\treturn key + \" from \" + versions[key].from;\n\t}).join(\", \");\n};\nvar getValidVersion = (scope, scopeName, key, requiredVersion) => {\n\tvar entry = findValidVersion(scope, key, requiredVersion);\n\tif(entry) return get(entry);\n\tthrow new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));\n};\nvar warn = (msg) => {\n\tif (typeof console !== \"undefined\" && console.warn) console.warn(msg);\n};\nvar warnInvalidVersion = (scope, scopeName, key, requiredVersion) => {\n\twarn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));\n};\nvar get = (entry) => {\n\tentry.loaded = 1;\n\treturn entry.get()\n};\nvar init = (fn) => (function(scopeName, a, b, c) {\n\tvar promise = __webpack_require__.I(scopeName);\n\tif (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c));\n\treturn fn(scopeName, __webpack_require__.S[scopeName], a, b, c);\n});\n\nvar load = /*#__PURE__*/ init((scopeName, scope, key) => {\n\tensureExistence(scopeName, key);\n\treturn get(findVersion(scope, key));\n});\nvar loadFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => {\n\treturn scope && __webpack_require__.o(scope, key) ? get(findVersion(scope, key)) : fallback();\n});\nvar loadVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => {\n\tensureExistence(scopeName, key);\n\treturn get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));\n});\nvar loadSingleton = /*#__PURE__*/ init((scopeName, scope, key) => {\n\tensureExistence(scopeName, key);\n\treturn getSingleton(scope, scopeName, key);\n});\nvar loadSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => {\n\tensureExistence(scopeName, key);\n\treturn getSingletonVersion(scope, scopeName, key, version);\n});\nvar loadStrictVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => {\n\tensureExistence(scopeName, key);\n\treturn getValidVersion(scope, scopeName, key, version);\n});\nvar loadStrictSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => {\n\tensureExistence(scopeName, key);\n\treturn getStrictSingletonVersion(scope, scopeName, key, version);\n});\nvar loadVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => {\n\tif(!scope || !__webpack_require__.o(scope, key)) return fallback();\n\treturn get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));\n});\nvar loadSingletonFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => {\n\tif(!scope || !__webpack_require__.o(scope, key)) return fallback();\n\treturn getSingleton(scope, scopeName, key);\n});\nvar loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => {\n\tif(!scope || !__webpack_require__.o(scope, key)) return fallback();\n\treturn getSingletonVersion(scope, scopeName, key, version);\n});\nvar loadStrictVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => {\n\tvar entry = scope && __webpack_require__.o(scope, key) && findValidVersion(scope, key, version);\n\treturn entry ? get(entry) : fallback();\n});\nvar loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => {\n\tif(!scope || !__webpack_require__.o(scope, key)) return fallback();\n\treturn getStrictSingletonVersion(scope, scopeName, key, version);\n});\nvar installedModules = {};\nvar moduleToHandlerMapping = {\n\t\"webpack/sharing/consume/default/react\": () => (loadSingletonVersionCheck(\"default\", \"react\", [1,18,2,0])),\n\t\"webpack/sharing/consume/default/@jupyterlab/application\": () => (loadSingletonVersionCheck(\"default\", \"@jupyterlab/application\", [1,4,0,8])),\n\t\"webpack/sharing/consume/default/@jupyterlab/filebrowser\": () => (loadSingletonVersionCheck(\"default\", \"@jupyterlab/filebrowser\", [1,4,0,8])),\n\t\"webpack/sharing/consume/default/@jupyterlab/apputils\": () => (loadSingletonVersionCheck(\"default\", \"@jupyterlab/apputils\", [1,4,1,8])),\n\t\"webpack/sharing/consume/default/qs/qs\": () => (loadStrictVersionCheckFallback(\"default\", \"qs\", [1,6,11,2], () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_qs_lib_index_js\"), __webpack_require__.e(\"_09cc\")]).then(() => (() => (__webpack_require__(/*! qs */ \"./node_modules/qs/lib/index.js\"))))))),\n\t\"webpack/sharing/consume/default/@jupyterlab/services\": () => (loadSingletonVersionCheck(\"default\", \"@jupyterlab/services\", [1,7,0,8])),\n\t\"webpack/sharing/consume/default/@jupyterlab/coreutils\": () => (loadSingletonVersionCheck(\"default\", \"@jupyterlab/coreutils\", [1,6,0,8])),\n\t\"webpack/sharing/consume/default/@lumino/signaling\": () => (loadSingletonVersionCheck(\"default\", \"@lumino/signaling\", [1,2,0,0])),\n\t\"webpack/sharing/consume/default/@lumino/polling\": () => (loadSingletonVersionCheck(\"default\", \"@lumino/polling\", [1,2,0,0])),\n\t\"webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99\": () => (loadSingletonVersionCheckFallback(\"default\", \"@material-ui/core\", [1,4,8,2], () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\"), __webpack_require__.e(\"vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de\"), __webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_index_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react-dom\")]).then(() => (() => (__webpack_require__(/*! @material-ui/core */ \"./node_modules/@material-ui/core/esm/index.js\"))))))),\n\t\"webpack/sharing/consume/default/@material-ui/lab/@material-ui/lab\": () => (loadSingletonVersionCheckFallback(\"default\", \"@material-ui/lab\", [1,4,0,0,,\"alpha\",39], () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\"), __webpack_require__.e(\"vendors-node_modules_babel_runtime_helpers_esm_slicedToArray_js-node_modules_material-ui_core-6815de\"), __webpack_require__.e(\"vendors-node_modules_material-ui_lab_esm_index_js\"), __webpack_require__.e(\"webpack_sharing_consume_default_react-dom\"), __webpack_require__.e(\"webpack_sharing_consume_default_material-ui_core_material-ui_core\")]).then(() => (() => (__webpack_require__(/*! @material-ui/lab */ \"./node_modules/@material-ui/lab/esm/index.js\"))))))),\n\t\"webpack/sharing/consume/default/uuid/uuid\": () => (loadStrictVersionCheckFallback(\"default\", \"uuid\", [1,9,0,0], () => (__webpack_require__.e(\"vendors-node_modules_uuid_dist_esm-browser_index_js\").then(() => (() => (__webpack_require__(/*! uuid */ \"./node_modules/uuid/dist/esm-browser/index.js\"))))))),\n\t\"webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons\": () => (loadSingletonVersionCheckFallback(\"default\", \"@material-ui/icons\", [1,4,5,1], () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_SvgIcon_SvgIcon_js\"), __webpack_require__.e(\"vendors-node_modules_material-ui_icons_esm_index_js\")]).then(() => (() => (__webpack_require__(/*! @material-ui/icons */ \"./node_modules/@material-ui/icons/esm/index.js\"))))))),\n\t\"webpack/sharing/consume/default/typestyle/typestyle\": () => (loadStrictVersionCheckFallback(\"default\", \"typestyle\", [1,2,4,0], () => (__webpack_require__.e(\"vendors-node_modules_typestyle_lib_es2015_index_js\").then(() => (() => (__webpack_require__(/*! typestyle */ \"./node_modules/typestyle/lib.es2015/index.js\"))))))),\n\t\"webpack/sharing/consume/default/moment/moment\": () => (loadStrictVersionCheckFallback(\"default\", \"moment\", [1,2,29,4], () => (Promise.all([__webpack_require__.e(\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-310b4c\"), __webpack_require__.e(\"node_modules_moment_locale_sync_recursive_\")]).then(() => (() => (__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"))))))),\n\t\"webpack/sharing/consume/default/@jupyterlab/ui-components\": () => (loadSingletonVersionCheck(\"default\", \"@jupyterlab/ui-components\", [1,4,0,8])),\n\t\"webpack/sharing/consume/default/react-dom\": () => (loadSingletonVersionCheck(\"default\", \"react-dom\", [1,18,2,0])),\n\t\"webpack/sharing/consume/default/@material-ui/core/@material-ui/core?fbe4\": () => (loadSingletonVersionCheckFallback(\"default\", \"@material-ui/core\", [1,4,7,0], () => (__webpack_require__.e(\"vendors-node_modules_material-ui_core_esm_index_js\").then(() => (() => (__webpack_require__(/*! @material-ui/core */ \"./node_modules/@material-ui/core/esm/index.js\")))))))\n};\n// no consumes in initial chunks\nvar chunkMapping = {\n\t\"webpack_sharing_consume_default_react\": [\n\t\t\"webpack/sharing/consume/default/react\"\n\t],\n\t\"lib_index_js\": [\n\t\t\"webpack/sharing/consume/default/@jupyterlab/application\",\n\t\t\"webpack/sharing/consume/default/@jupyterlab/filebrowser\",\n\t\t\"webpack/sharing/consume/default/@jupyterlab/apputils\",\n\t\t\"webpack/sharing/consume/default/qs/qs\",\n\t\t\"webpack/sharing/consume/default/@jupyterlab/services\",\n\t\t\"webpack/sharing/consume/default/@jupyterlab/coreutils\",\n\t\t\"webpack/sharing/consume/default/@lumino/signaling\",\n\t\t\"webpack/sharing/consume/default/@lumino/polling\",\n\t\t\"webpack/sharing/consume/default/@material-ui/core/@material-ui/core?8d99\",\n\t\t\"webpack/sharing/consume/default/@material-ui/lab/@material-ui/lab\",\n\t\t\"webpack/sharing/consume/default/uuid/uuid\",\n\t\t\"webpack/sharing/consume/default/@material-ui/icons/@material-ui/icons\",\n\t\t\"webpack/sharing/consume/default/typestyle/typestyle\",\n\t\t\"webpack/sharing/consume/default/moment/moment\",\n\t\t\"webpack/sharing/consume/default/@jupyterlab/ui-components\"\n\t],\n\t\"webpack_sharing_consume_default_react-dom\": [\n\t\t\"webpack/sharing/consume/default/react-dom\"\n\t],\n\t\"webpack_sharing_consume_default_material-ui_core_material-ui_core\": [\n\t\t\"webpack/sharing/consume/default/@material-ui/core/@material-ui/core?fbe4\"\n\t]\n};\nvar startedInstallModules = {};\n__webpack_require__.f.consumes = (chunkId, promises) => {\n\tif(__webpack_require__.o(chunkMapping, chunkId)) {\n\t\tchunkMapping[chunkId].forEach((id) => {\n\t\t\tif(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);\n\t\t\tif(!startedInstallModules[id]) {\n\t\t\tvar onFactory = (factory) => {\n\t\t\t\tinstalledModules[id] = 0;\n\t\t\t\t__webpack_require__.m[id] = (module) => {\n\t\t\t\t\tdelete __webpack_require__.c[id];\n\t\t\t\t\tmodule.exports = factory();\n\t\t\t\t}\n\t\t\t};\n\t\t\tstartedInstallModules[id] = true;\n\t\t\tvar onError = (error) => {\n\t\t\t\tdelete installedModules[id];\n\t\t\t\t__webpack_require__.m[id] = (module) => {\n\t\t\t\t\tdelete __webpack_require__.c[id];\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tvar promise = moduleToHandlerMapping[id]();\n\t\t\t\tif(promise.then) {\n\t\t\t\t\tpromises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));\n\t\t\t\t} else onFactory(promise);\n\t\t\t} catch(e) { onError(e); }\n\t\t\t}\n\t\t});\n\t}\n}","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"jupyterlab_eduhelx_submission\": 0\n};\n\n__webpack_require__.f.j = (chunkId, promises) => {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(!/^webpack_sharing_consume_default_(react(|\\-dom)|material\\-ui_core_material\\-ui_core)$/.test(chunkId)) {\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = (event) => {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkjupyterlab_eduhelx_submission\"] = self[\"webpackChunkjupyterlab_eduhelx_submission\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","","// module cache are used so entry inlining is disabled\n// startup\n// Load entry module and return exports\nvar __webpack_exports__ = __webpack_require__(\"webpack/container/entry/jupyterlab_eduhelx_submission\");\n",""],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/eduhelx_jupyterlab_student/tests/test_handlers.py b/eduhelx_jupyterlab_student/tests/test_handlers.py index f3cb262..d0c470f 100644 --- a/eduhelx_jupyterlab_student/tests/test_handlers.py +++ b/eduhelx_jupyterlab_student/tests/test_handlers.py @@ -3,11 +3,11 @@ async def test_get_example(jp_fetch): # When - response = await jp_fetch("jupyterlab-eduhelx-submission", "get-example") + response = await jp_fetch("eduhelx-jupyterlab-student", "get-example") # Then assert response.code == 200 payload = json.loads(response.body) assert payload == { - "data": "This is /jupyterlab-eduhelx-submission/get-example endpoint!" + "data": "This is /eduhelx-jupyterlab-student/get-example endpoint!" } \ No newline at end of file diff --git a/package.json b/package.json index e810995..f5be780 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@lumino/disposable": "^2.1.2", "@lumino/signaling": "^2.1.2", "@lumino/widgets": "^2.2.0", - "@material-ui/core": "^4.8.2", + "@material-ui/core": "^4.12.4", "@material-ui/icons": "^4.5.1", "@material-ui/lab": "^4.0.0-alpha.39", "csx": "^10.0.2", diff --git a/src/api/api-responses.ts b/src/api/api-responses.ts index 934b6aa..c6f040c 100644 --- a/src/api/api-responses.ts +++ b/src/api/api-responses.ts @@ -31,6 +31,13 @@ export interface StudentResponse extends UserResponse { exit_date: string | null } +export interface StagedChangeResponse { + path_from_repo: string + path_from_assn: string + modification_type: string + type: "file" | "directory" +} + export interface SubmissionResponse { id: number active: boolean @@ -57,6 +64,7 @@ export interface AssignmentResponse { is_closed: boolean submissions?: SubmissionResponse[] + staged_changes?: StagedChangeResponse[] } export interface CourseResponse { diff --git a/src/api/api.ts b/src/api/api.ts index b79ab62..921af94 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -37,12 +37,41 @@ export async function getStudentAndCourse(): Promise { + const queryString = qs.stringify({ current_value: JSON.stringify(currentValue) }) + const { student, course } = await requestAPI<{ + student: StudentResponse + course: CourseResponse + }>(`/course_student/poll?${ queryString }`, { + method: 'GET' + }) + return { + student: Student.fromResponse(student), + course: Course.fromResponse(course) + } +} + export async function getAssignments(path: string): Promise { + const queryString = qs.stringify({ path }) + const { assignments, current_assignment } = await requestAPI<{ + assignments: AssignmentResponse[] | null + current_assignment: AssignmentResponse | null + }>(`/assignments?${ queryString }`, { + method: 'GET' + }) + return { + assignments: assignments ? assignments.map((data) => Assignment.fromResponse(data)) : null, + currentAssignment: current_assignment ? Assignment.fromResponse(current_assignment) as ICurrentAssignment : null + } +} + +export async function getAssignmentsPolled(path: string, currentValue?: object): Promise { + const queryString = qs.stringify({ path, current_value: JSON.stringify(currentValue) }) const { assignments, current_assignment } = await requestAPI<{ assignments: AssignmentResponse[] | null current_assignment: AssignmentResponse | null - }>(`/assignments?${ qs.stringify({ path }) }`, { + }>(`/assignments/poll?${ queryString }`, { method: 'GET' }) return { diff --git a/src/api/assignment.ts b/src/api/assignment.ts index f49d2f1..a580fee 100644 --- a/src/api/assignment.ts +++ b/src/api/assignment.ts @@ -1,6 +1,7 @@ import { IStudent, Student } from './student' import { ISubmission, Submission } from './submission' import { AssignmentResponse } from './api-responses' +import { IStagedChange, StagedChange } from './staged-change' export interface IAssignment { readonly id: number @@ -25,11 +26,17 @@ export interface IAssignment { // Indicates if an assignment is no longer available to work on (e.g. date is greater than adjusted_due_date) readonly isClosed: boolean readonly submissions?: ISubmission[] + // `null` if there are no submissions + readonly activeSubmission?: ISubmission | null + readonly stagedChanges?: IStagedChange[] } -// Submissions are definitely defined in an ICurrentAssignment +// Submissions and staged changes are definitely defined in an ICurrentAssignment export interface ICurrentAssignment extends IAssignment { - readonly submissions: ISubmission[] + readonly submissions: ISubmission[] + // `null` if there are no submissions + readonly activeSubmission: ISubmission | null + readonly stagedChanges: IStagedChange[] } export class Assignment implements IAssignment { @@ -48,7 +55,8 @@ export class Assignment implements IAssignment { private _isCreated: boolean, private _isAvailable: boolean, private _isClosed: boolean, - private _submissions?: ISubmission[] + private _submissions?: ISubmission[], + private _stagedChanges?: IStagedChange[] ) {} get id() { return this._id } @@ -68,6 +76,13 @@ export class Assignment implements IAssignment { get isClosed() { return this._isClosed } get submissions() { return this._submissions } + get activeSubmission() { + if (this._submissions === undefined) return undefined + if (this._submissions.length === 0) return null + return this._submissions.sort((a, b) => b.submissionTime.getTime() - a.submissionTime.getTime())[0] + } + + get stagedChanges() { return this._stagedChanges } static fromResponse(data: AssignmentResponse): IAssignment { @@ -86,7 +101,8 @@ export class Assignment implements IAssignment { data.is_created, data.is_available, data.is_closed, - data.submissions?.map((res) => Submission.fromResponse(res)) + data.submissions?.map((res) => Submission.fromResponse(res)), + data.staged_changes?.map((res) => StagedChange.fromResponse(res)) ) } } \ No newline at end of file diff --git a/src/api/staged-change.ts b/src/api/staged-change.ts new file mode 100644 index 0000000..c3abe1b --- /dev/null +++ b/src/api/staged-change.ts @@ -0,0 +1,31 @@ +import { StagedChangeResponse } from './api-responses' + +export interface IStagedChange { + readonly pathFromRepositoryRoot: string + readonly pathFromAssignmentRoot: string + readonly modificationType: string + readonly type: "file" | "directory" +} + +export class StagedChange implements IStagedChange { + constructor( + private _pathFromRepositoryRoot: string, + private _pathFromAssignmentRoot: string, + private _modificationType: string, + private _type: "file" | "directory" + ) {} + + get pathFromRepositoryRoot() { return this._pathFromRepositoryRoot } + get pathFromAssignmentRoot() { return this._pathFromAssignmentRoot } + get modificationType() { return this._modificationType } + get type() { return this._type } + + static fromResponse(data: StagedChangeResponse): IStagedChange { + return new StagedChange( + data.path_from_repo, + data.path_from_assn, + data.modification_type, + data.type + ) + } +} \ No newline at end of file diff --git a/src/components/assignment-panel/assignment-content/assignment-content.tsx b/src/components/assignment-panel/assignment-content/assignment-content.tsx index 208df00..9d3c418 100644 --- a/src/components/assignment-panel/assignment-content/assignment-content.tsx +++ b/src/components/assignment-panel/assignment-content/assignment-content.tsx @@ -5,7 +5,9 @@ import { NoAssignmentWarning } from '../no-assignment-warning' import { AssignmentInfo } from '../assignment-info' import { AssignmentSubmissions } from '../assignment-submissions' import { AssignmentSubmitForm } from '../assignment-submit-form' +import { AssignmentStagedChanges } from '../assignment-staged-changes' import { useAssignment } from '../../../contexts' +import { Tabs } from '../../tabs' export const AssignmentContent = () => { const { loading, path, assignment, student, assignments } = useAssignment()! @@ -36,7 +38,32 @@ export const AssignmentContent = () => { ) : (
- + + ), + containerProps: { style: { width: "100%" } } + }, + { + key: 1, + label: "Submissions", + content: , + containerProps: { style: { width: "100%" } } + } + ]} + style={{ flexGrow: 1 }} + /> + {/* + */}
) diff --git a/src/components/assignment-panel/assignment-info/assignment-info.tsx b/src/components/assignment-panel/assignment-info/assignment-info.tsx index 271b6e5..be7a849 100644 --- a/src/components/assignment-panel/assignment-info/assignment-info.tsx +++ b/src/components/assignment-panel/assignment-info/assignment-info.tsx @@ -1,6 +1,7 @@ -import React from 'react' +import React, { Fragment, useMemo } from 'react' +import moment from 'moment' import { ArrowBackSharp } from '@material-ui/icons' -import { assignmentInfoClass, assignmentInfoSectionClass, assignmentInfoSectionHeaderClass, assignmentNameClass } from './style' +import { assignmentInfoClass, assignmentInfoSectionClass, assignmentInfoSectionHeaderClass, assignmentInfoSectionWarningClass, assignmentNameClass, tagClass } from './style' import { useAssignment } from '../../../contexts' import { DateFormat } from '../../../utils' @@ -13,26 +14,97 @@ export const AssignmentInfo = ({ }: AssignmentInfoProps) => { const { assignment, student, course } = useAssignment()! if (!student || !assignment || !course) return null - const hoursUntilDue = assignment.isCreated ? ( - (assignment.adjustedDueDate!.getTime() - Date.now()) / MS_IN_HOURS - ) : Infinity + const hoursUntilDue = useMemo(() => ( + assignment.isCreated ? ( + (assignment.adjustedDueDate!.getTime() - Date.now()) / MS_IN_HOURS + ) : Infinity + ), [assignment]) + + const assignmentStatusTag = useMemo(() => { + let color = undefined + let backgroundColor = undefined + let text = undefined + let tooltip = undefined + let filled = false + if (!assignment.isCreated) { + // Upcoming assignment (doesn't have either an open or close date yet) + color = "white" + backgroundColor = "#1890ff" + text = "Upcoming" + tooltip = `Your instructor${ course.instructors.length > 1 ? "s" : "" } has not released this assignment yet` + filled = true + } + else if (assignment.isClosed) { + // Not available to work on anymore + if (assignment.activeSubmission) { + // Closed and submitted + color = "var(--jp-success-color1)" + backgroundColor = "var(--jp-success-color1)" + text = ( + + Submitted { new DateFormat(assignment.activeSubmission.submissionTime).toRelativeDatetimeNoArticle() } ago + + ) + tooltip = `You submitted this assignment before it closed. Please contact your instructor${ course.instructors.length > 1 ? "s" : "" } if you need to resubmit` + filled = false + } else { + // Closed and never submitted + color = "var(--jp-error-color1)" + backgroundColor = "var(--jp-error-color1)" + text = ( + + { new DateFormat(assignment.adjustedDueDate!).toRelativeDatetimeNoArticle() } past due + + ) + tooltip = `You never submitted this assignment. Please contact your instructor${ course.instructors.length > 1 ? "s" : "" } to request an extension` + filled = false + } + } else if (assignment.isAvailable) { + // Available + color = assignment.activeSubmission ? "var(--jp-success-color1)" : "white" + backgroundColor = assignment.activeSubmission ? "var(--jp-success-color1)" : "var(--jp-warn-color1)" + text = assignment.activeSubmission ? "Submitted" : "Not Submitted" + tooltip = assignment.activeSubmission ? `You have submitted this assignment` : `You haven't submitted this assignment yet` + filled = !assignment.activeSubmission + } + return ( + + { text } + + ) + }, [course, assignment, hoursUntilDue]) return (
{ assignment.name }
- { assignment.isClosed ? ( -
- Closed -
- ) : null } + { assignmentStatusTag } + { assignment.isCreated && !assignment.isClosed && hoursUntilDue <= 4 && ( + + Due in { new DateFormat(assignment.adjustedDueDate!).toRelativeDatetimeNoArticle() } + + ) }
Student
@@ -40,7 +112,7 @@ export const AssignmentInfo = ({ }: AssignmentInfoProps) => {
- Professor{ course.instructors.length > 1 ? "s" : "" } + Instructor{ course.instructors.length > 1 ? "s" : "" }
{ course.instructors.map((ins) => ins.fullName).join(", ") }
@@ -56,12 +128,20 @@ export const AssignmentInfo = ({ }: AssignmentInfoProps) => {  (extended) ) : null }
- { assignment.isCreated && !assignment.isClosed && hoursUntilDue <= 2 ? ( -
- Warning: { new DateFormat(assignment.adjustedDueDate!).toRelativeDatetime() } remaining -
- ) : null } + { assignment.isCreated && assignment.isClosed && ( +
+
+ Assignment is past due +
+
+ No further changes can be submitted. + Please contact your instructor{ course.instructors.length > 1 ? "s" : "" } for an extension. +
+
+ ) } ) } \ No newline at end of file diff --git a/src/components/assignment-panel/assignment-info/style.ts b/src/components/assignment-panel/assignment-info/style.ts index 568fcf6..9b15b58 100644 --- a/src/components/assignment-panel/assignment-info/style.ts +++ b/src/components/assignment-panel/assignment-info/style.ts @@ -33,5 +33,20 @@ export const assignmentInfoSectionClass = (style as any)({ export const assignmentInfoSectionHeaderClass = style({ margin: 0, marginBottom: 4, - fontWeight: 600 + fontWeight: 600, +}) + +export const assignmentInfoSectionWarningClass = style({ + color: "var(--jp-warn-color-normal)" +}) + +export const tagClass = style({ + height: "auto", + // border: "1px solid #d9d9d9", + borderRadius: 2, + display: "inline-block", + fontSize: 12, + lineHeight: "20px", + padding: "0 7px", + whiteSpace: "nowrap" }) diff --git a/src/components/assignment-panel/assignment-staged-changes/assignment-staged-changes.tsx b/src/components/assignment-panel/assignment-staged-changes/assignment-staged-changes.tsx new file mode 100644 index 0000000..62493bc --- /dev/null +++ b/src/components/assignment-panel/assignment-staged-changes/assignment-staged-changes.tsx @@ -0,0 +1,137 @@ +import React, { useEffect, useMemo, useState } from 'react' +import { folderIcon, fileIcon } from '@jupyterlab/ui-components' +import { assignmentStagedChangesClass, assignmentStagedChangesFolderIconClass, largeBulletClass, modifiedTypeBadgeClass, showMoreBtnClass, stagedChangeListItemClass, stagedChangesListClass } from './style' +import { TextDivider } from '../../text-divider' +import { useAssignment } from '../../../contexts' +import { IStagedChange } from '../../../api/staged-change' + +const SHOW_MORE_CUTOFF = Infinity + +interface ModifiedTypeBadgeProps { + modificationType: IStagedChange["modificationType"] +} + +interface AssignmentStagedChangesProps extends React.HTMLAttributes { +} + +const ModifiedTypeBadge = ({ modificationType }: ModifiedTypeBadgeProps) => { + const [text, title, color] = useMemo(() => { + switch (modificationType) { + case "??": { + return [ + +, + "Added (untracked)", + "var(--md-green-500)" + ] + } + case "M": { + return [ + , + "Modified", + undefined + ] + } + case "D": { + return [ + // Could also use a minus and boost its font-size to like 18px and make its line-height to 1 + // but its too small at normal font size + D, + "Deleted", + "var(--md-red-500)" + ] + } + default: { + return [ + modificationType.slice(0, 3), + modificationType, + undefined + ] + } + } + }, [modificationType]) + + return ( +
+ { text } +
+ ) +} + +export const AssignmentStagedChanges = ({ ...props }: AssignmentStagedChangesProps) => { + const { assignment } = useAssignment()! + const [showMore, setShowMore] = useState(false) + + const stagedChangesSource = useMemo(() => { + if (!assignment) return [] + return assignment.stagedChanges + }, [assignment?.stagedChanges, showMore]) + + const hideShowMoreButton = useMemo(() => !showMore && stagedChangesSource.length <= SHOW_MORE_CUTOFF, [showMore, stagedChangesSource]) + + useEffect(() => { + if (stagedChangesSource.length <= SHOW_MORE_CUTOFF) setShowMore(false) + }, [stagedChangesSource]) + + if (stagedChangesSource.length === 0) return ( +
+
+

+ No Changes +

+

+ Files you've changed since your last submission will appear here. +

+
+
+ ) + return ( +
+ {/* Unsubmitted changes */} +
+ { + stagedChangesSource.slice(0, showMore ? undefined : SHOW_MORE_CUTOFF).map((change) => ( +
+
+ { change.type === "directory" ? ( + + ) : ( + + ) } + + { !change.pathFromAssignmentRoot.startsWith("/") ? "/" : "" } + { change.pathFromAssignmentRoot } + { change.type === "directory" && !change.pathFromAssignmentRoot.endsWith("/") ? "/*" : "" } + +
+ +
+ )) + } + { assignment && !hideShowMoreButton && ( + + ) } +
+
+ ) +} \ No newline at end of file diff --git a/src/components/assignment-panel/assignment-staged-changes/index.ts b/src/components/assignment-panel/assignment-staged-changes/index.ts new file mode 100644 index 0000000..e8ebdcf --- /dev/null +++ b/src/components/assignment-panel/assignment-staged-changes/index.ts @@ -0,0 +1 @@ +export * from './assignment-staged-changes' \ No newline at end of file diff --git a/src/components/assignment-panel/assignment-staged-changes/style.ts b/src/components/assignment-panel/assignment-staged-changes/style.ts new file mode 100644 index 0000000..09193a4 --- /dev/null +++ b/src/components/assignment-panel/assignment-staged-changes/style.ts @@ -0,0 +1,69 @@ +import { style } from 'typestyle' + +export const assignmentStagedChangesClass = style({ + fontSize: 'var(--jp-ui-font-size1)', + color: 'var(--jp-ui-font-color0)', + display: 'flex', + flexDirection: 'column', + padding: '0 12px' +}) + +export const stagedChangesListClass = style({ + marginTop: 0, + marginBottom: 12 +}) + +export const stagedChangeListItemClass = (style as any)({ + display: "flex", + alignItems: "center", + justifyContent: "space-between", + marginBottom: 2, + + "&:last-child": { + marginBottom: 0 + } +}) + +export const modifiedTypeBadgeClass = style({ + width: 24, + height: "auto", + display: "flex", + justifyContent: "center", + alignItems: "center" +}) + +export const largeBulletClass = style({ + borderRadius: "50%", + display: "inline-block", + height: 6, + width: 6 +}) + +export const assignmentStagedChangesFolderIconClass = (style as any)({ + "& > svg > path": { + fill: "rgba(0, 0, 0, 0) !important", + stroke: "var(--jp-inverse-layout-color3)", + strokeWidth: "2.5px" + } +}) + +export const showMoreBtnClass = (style as any)({ + fontSize: "var(--jp-ui-font-size1)", + color: "#1890ff", + background: "transparent", + borderColor: "transparent", + boxShadow: "none", + cursor: "pointer", + display: "inline-block", + fontWeight: 400, + position: "relative", + textAlign: "center", + touchAction: "manipulation", + userSelect: "none", + whiteSpace: "nowrap", + padding: 0, + + "& > span": { + display: "inline-block" + } +}) \ No newline at end of file diff --git a/src/components/assignment-panel/assignment-submissions/assignment-submissions.tsx b/src/components/assignment-panel/assignment-submissions/assignment-submissions.tsx index 007708f..cb95154 100644 --- a/src/components/assignment-panel/assignment-submissions/assignment-submissions.tsx +++ b/src/components/assignment-panel/assignment-submissions/assignment-submissions.tsx @@ -30,13 +30,15 @@ export const AssignmentSubmissions = ({ ...props }: AssignmentSubmissionsProps) if (!assignment) return null if (assignment.submissions.length === 0) return (
- You haven't made any submissions for this assignment yet. - To submit your work, press the "Submit" button at the bottom of the page. +
+ You haven't made any submissions for this assignment yet. + To submit your work, press the "Submit" button at the bottom of the page. +
) return (
- Submissions + {/* Submissions */}
{ submissionSource!.map((submission, i) => ( diff --git a/src/components/assignment-panel/assignment-submissions/style.ts b/src/components/assignment-panel/assignment-submissions/style.ts index 65f4650..9d4b76a 100644 --- a/src/components/assignment-panel/assignment-submissions/style.ts +++ b/src/components/assignment-panel/assignment-submissions/style.ts @@ -43,7 +43,7 @@ export const activateSubmissionButtonClass = style({ export const assignmentsListClass = (style as any)({ flexGrow: 1, - height: 0, + // height: 0, overflowY: 'auto', padding: 0, /** Adjusting clashing styles caused by using accordion summaries as ListItem components */ diff --git a/src/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.tsx b/src/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.tsx index c4a1ff2..4b187f4 100644 --- a/src/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.tsx +++ b/src/components/assignment-panel/assignment-submit-form/assignment-submit-button/assignment-submit-button.tsx @@ -1,21 +1,22 @@ -import React from 'react' +import React, { ButtonHTMLAttributes } from 'react' import { PublishSharp } from '@material-ui/icons' import { assignmentSubmitButton } from './style' import { useAssignment } from '../../../../contexts' import { classes } from 'typestyle' import { disabledButtonClass } from '../../../style' -interface AssignmentSubmitButtonProps { +interface AssignmentSubmitButtonProps extends ButtonHTMLAttributes { onClick: (e: any) => void disabled?: boolean } -export const AssignmentSubmitButton = ({ onClick, disabled=false }: AssignmentSubmitButtonProps) => { +export const AssignmentSubmitButton = ({ onClick, disabled=false, ...props }: AssignmentSubmitButtonProps) => { return ( diff --git a/src/components/assignment-panel/assignment-submit-form/assignment-submit-form.tsx b/src/components/assignment-panel/assignment-submit-form/assignment-submit-form.tsx index 4eb69ad..d33da5b 100644 --- a/src/components/assignment-panel/assignment-submit-form/assignment-submit-form.tsx +++ b/src/components/assignment-panel/assignment-submit-form/assignment-submit-form.tsx @@ -15,7 +15,7 @@ interface AssignmentSubmitFormProps { } export const AssignmentSubmitForm = ({ }: AssignmentSubmitFormProps) => { - const { assignment, path } = useAssignment()! + const { assignment, course, path } = useAssignment()! const backdrop = useBackdrop()! const snackbar = useSnackbar()! @@ -24,6 +24,14 @@ export const AssignmentSubmitForm = ({ }: AssignmentSubmitFormProps) => { const [submitting, setSubmitting] = useState(false) const disabled = submitting || summaryText === "" || !assignment?.isAvailable || assignment?.isClosed + const disabledReason = disabled ? ( + !assignment ? undefined : + submitting ? `Currently uploading submission` : + !assignment.isAvailable ? `Assignment is not available for you to work on yet` : + assignment.isClosed ? + `Past due. Please contact your instructor${course!.instructors.length > 1 ? "s" : ""} if you need an extension` : + summaryText === "" ? `Please enter a summary for the submission` : undefined + ) : undefined const submitAssignment = async () => { if (!path) { @@ -103,6 +111,7 @@ export const AssignmentSubmitForm = ({ }: AssignmentSubmitFormProps) => { />
diff --git a/src/components/tabs/index.ts b/src/components/tabs/index.ts new file mode 100644 index 0000000..d47e431 --- /dev/null +++ b/src/components/tabs/index.ts @@ -0,0 +1 @@ +export * from './tabs' \ No newline at end of file diff --git a/src/components/tabs/style.ts b/src/components/tabs/style.ts new file mode 100644 index 0000000..cf653a6 --- /dev/null +++ b/src/components/tabs/style.ts @@ -0,0 +1,69 @@ +import { style } from 'typestyle' + +export const tabsClass = style({ + display: "flex", + flexDirection: "column" +}) + +export const tabsHeaderClass = style({ + display: 'flex', + alignItems: 'stretch', + color: 'var(--jp-ui-font-color0)', + position: 'relative', + padding: 2 +}) + +export const tabsHeaderTabClass = (style as any)({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + fontSize: 15, + fontWeight: 500, + padding: '8px 4px', + borderRadius: 4, + textAlign: 'center', + cursor: 'pointer', + border: 'none !important', +}) + +export const tabsHeaderTabActiveClass = (style as any)({ + position: "relative", + color: "var(--jp-ui-font-color0)", + border: "2px solid var(--jp-border-color2)", + borderBottomWidth: 0, + borderBottomLeftRadius: 0, + borderBottomRightRadius: 0, + + '&::before': { + content: '""', + position: 'absolute', + left: 0, + top: '100%', + width: '100%', + borderBottom: '2.5px solid #1890ff', + }, + + '&:first-child': { + borderLeftWidth: 0, + borderTopLeftRadius: 0 + }, + '&:last-child': { + borderRightWidth: 0, + borderTopRightRadius: 0 + } +}) + +export const tabsHeaderTabInactiveClass = (style as any)({ + position: "relative", + color: "var(--jp-ui-font-color2)", + + '&::before': { + content: '""', + position: 'absolute', + left: 0, + top: '100%', + width: '100%', + // borderBottom: 'var(--jp-border-width) solid var(--jp-border-color2)', + border: 'none !important' + } +}) \ No newline at end of file diff --git a/src/components/tabs/tabs.tsx b/src/components/tabs/tabs.tsx new file mode 100644 index 0000000..dd99a47 --- /dev/null +++ b/src/components/tabs/tabs.tsx @@ -0,0 +1,69 @@ +import React, { ReactNode, useMemo, useState } from 'react' +import { classes } from 'typestyle' +import { tabsClass, tabsHeaderClass, tabsHeaderTabActiveClass, tabsHeaderTabClass, tabsHeaderTabInactiveClass } from './style' + +interface TabItem { + key: string | number + label: ReactNode + content: ReactNode + containerProps?: React.HTMLAttributes +} + +interface TabItemProps extends React.HTMLAttributes { + tab: TabItem + active: boolean +} + +interface TabsHeaderProps { + tabs: TabItem[], + activeTabKey: string | number, + onChange: (tabKey: string | number) => void +} + +interface TabsProps extends React.HTMLAttributes { + tabs: TabItem[] + defaultActiveTabKey?: string | number +} + +const TabItem = ({ tab, active, ...props }: TabItemProps) => { + return ( + + { tab.label } + + ) +} + +const TabsHeader = ({ tabs, activeTabKey, onChange }: TabsHeaderProps) => { + return ( +
+ { tabs.map((tab) => ( + onChange(tab.key) } + /> + )) } +
+ ) +} + +export const Tabs = ({ tabs, defaultActiveTabKey, ...props }: TabsProps) => { + const [activeTabKey, setActiveTabKey] = useState(defaultActiveTabKey ?? tabs[0].key) + const activeTab = useMemo(() => tabs.find((tab) => tab.key === activeTabKey), [tabs, activeTabKey]) + + return ( +
+ + { activeTab?.content } +
+ ) +} \ No newline at end of file diff --git a/src/components/text-divider/style.ts b/src/components/text-divider/style.ts index a76a9c1..bb8fa83 100644 --- a/src/components/text-divider/style.ts +++ b/src/components/text-divider/style.ts @@ -6,6 +6,7 @@ export const textDividerContainerClass = (style as any)({ color: 'var(--jp-ui-font-color0)', fontWeight: 500, textAlign: 'center', + whiteSpace: 'nowrap', '&::before, &::after': { content: '""', diff --git a/src/contexts/assignment-context.tsx b/src/contexts/assignment-context.tsx index 79456fa..d897af5 100644 --- a/src/contexts/assignment-context.tsx +++ b/src/contexts/assignment-context.tsx @@ -1,7 +1,8 @@ import React, { createContext, useContext, ReactNode, useState, useMemo, useEffect } from 'react' import { IChangedArgs } from '@jupyterlab/coreutils' +import { FileBrowserModel, IDefaultFileBrowser } from '@jupyterlab/filebrowser' import { IEduhelxSubmissionModel } from '../tokens' -import { IAssignment, IStudent, ICurrentAssignment, ICourse } from '../api' +import { IAssignment, IStudent, ICurrentAssignment, ICourse, getAssignmentsPolled, GetAssignmentsResponse, getStudentAndCoursePolled } from '../api' interface IAssignmentContext { assignments: IAssignment[] | null | undefined @@ -13,13 +14,13 @@ interface IAssignmentContext { } interface IAssignmentProviderProps { - model: IEduhelxSubmissionModel + fileBrowser: IDefaultFileBrowser children?: ReactNode } export const AssignmentContext = createContext(undefined) -export const AssignmentProvider = ({ model, children }: IAssignmentProviderProps) => { +export const AssignmentProvider = ({ fileBrowser, children }: IAssignmentProviderProps) => { const [currentPath, setCurrentPath] = useState(null) const [currentAssignment, setCurrentAssignment] = useState(undefined) const [assignments, setAssignments] = useState(undefined) @@ -34,39 +35,82 @@ export const AssignmentProvider = ({ model, children }: IAssignmentProviderProps ), [currentAssignment, assignments, student, course]) useEffect(() => { - setCurrentPath(model.currentPath) - setCurrentAssignment(model.currentAssignment) - setAssignments(model.assignments) - setStudent(model.student) - setCourse(model.course) - const onCurrentPathChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => { + setCurrentPath(fileBrowser.model.path) + + const onCurrentPathChanged = (model: FileBrowserModel, change: IChangedArgs) => { setCurrentPath(change.newValue) } - const onCurrentAssignmentChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => { - setCurrentAssignment(change.newValue) - } - const onAssignmentsChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => { - setAssignments(change.newValue) - } - const onStudentChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => { - setStudent(change.newValue) + fileBrowser.model.pathChanged.connect(onCurrentPathChanged) + return () => { + fileBrowser.model.pathChanged.disconnect(onCurrentPathChanged) } - const onCourseChanged = (model: IEduhelxSubmissionModel, change: IChangedArgs) => { - setCourse(change.newValue) + }, [fileBrowser]) + + useEffect(() => { + setAssignments(undefined) + setCurrentAssignment(undefined) + + let cancelled = false + void async function poll(currentValue?: object) { + let newValue = undefined + let error = false + if (currentPath !== null) { + try { + newValue = await getAssignmentsPolled(currentPath, currentValue) + } catch (e: any) { + console.error(e) + error = true + } + } + if (cancelled) return + if (newValue !== undefined) { + setAssignments(newValue.assignments) + setCurrentAssignment(newValue.currentAssignment) + } else { + setAssignments(undefined) + setCurrentAssignment(undefined) + } + // This endpoint should never return an error, which means it will likely return it immediately. + // If we don't delay our next request upon erroring, it may immediately fail and rerequest, which is bad. + if (!error) poll(newValue) + else setTimeout(() => poll(newValue), 1000) + }() + return () => { + cancelled = true } - model.currentPathChanged.connect(onCurrentPathChanged) - model.currentAssignmentChanged.connect(onCurrentAssignmentChanged) - model.assignmentsChanged.connect(onAssignmentsChanged) - model.studentChanged.connect(onStudentChanged) - model.courseChanged.connect(onCourseChanged) + }, [currentPath]) + + useEffect(() => { + setCourse(undefined) + setStudent(undefined) + + let cancelled = false + void async function poll(currentValue?: object) { + let newValue = undefined + let error = false + try { + newValue = await getStudentAndCoursePolled(currentValue) + } catch (e: any) { + console.error(e) + error = true + } + if (cancelled) return + if (newValue !== undefined) { + setCourse(newValue.course) + setStudent(newValue.student) + } else { + setCourse(undefined) + setStudent(undefined) + } + // This endpoint should never return an error, which means it will likely return it immediately. + // If we don't delay our next request upon erroring, it may immediately fail and rerequest, which is bad. + if (!error) poll(newValue) + else setTimeout(() => poll(newValue), 1000) + }() return () => { - model.currentPathChanged.disconnect(onCurrentPathChanged) - model.currentAssignmentChanged.disconnect(onCurrentAssignmentChanged) - model.assignmentsChanged.disconnect(onAssignmentsChanged) - model.studentChanged.disconnect(onStudentChanged) - model.courseChanged.disconnect(onCourseChanged) + cancelled = true } - }, [model]) + }, []) return ( ( const settings = ServerConnection.makeSettings() const requestUrl = URLExt.join( settings.baseUrl, - 'jupyterlab-eduhelx-submission', // API Namespace + 'eduhelx-jupyterlab-student', // API Namespace endPoint ) diff --git a/src/index.ts b/src/index.ts index 5ccb164..27abbf4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,17 +31,14 @@ async function activate ( ) return } - // await (fileBrowser.model as any)._restored.promise - const model = new EduhelxSubmissionModel() - Promise.all([app.restored, fileBrowser.model.restored]).then(() => { - model.currentPath = fileBrowser.model.path - }) - fileBrowser.model.pathChanged.connect((fileBrowserModel: FileBrowserModel, change: IChangedArgs) => { - model.currentPath = change.newValue - }) + // const model = new EduhelxSubmissionModel() + // Promise.all([app.restored, fileBrowser.model.restored]).then(() => { + // model.currentPath = fileBrowser.model.path + // }) + const submissionWidget = new AssignmentWidget( - model, + fileBrowser, app.commands, serverSettings ) diff --git a/src/utils/date-format.tsx b/src/utils/date-format.tsx index 2a13258..31cae41 100644 --- a/src/utils/date-format.tsx +++ b/src/utils/date-format.tsx @@ -37,9 +37,30 @@ export class DateFormat implements IDateFormat { return this._moment.format("MMM DD [at] h[:]mm A") } - toRelativeDatetime(referenceTime?: Date): ReactNode | string { - const getDuration = (date: Date) => duration(this._moment.diff(moment(date))).humanize() + toRelativeDatetime( + referenceTime?: Date, + postprocess?: (humanizedDuration: string) => string + ): ReactNode | string { + if (!postprocess) postprocess = (s: string) => s + // For whatever reason TSC type-narrowing is completely broken here and still considers postprocess possibly undefined... + const getDuration = (date: Date) => postprocess!(duration(this._moment.diff(moment(date))).humanize()) + + // const getDuration = (date: Date) => postprocess(duration(this._moment.diff(moment(date))).humanize()) if (referenceTime) return getDuration(referenceTime) return getDuration(new Date()) } /> } + + toRelativeDatetimeNoArticle( + referenceTime?: Date, + postprocess?: (humanizedDuration: string) => string + ): ReactNode | string { + if (!postprocess) postprocess = (s: string) => s + const removeArticle = (s: string) => { + if (s.startsWith("a ")) return "1 " + s.substring(2) + if (s.startsWith("an ")) return "1 " + s.substring(3) + return s + } + // For whatever reason TSC type-narrowing is completely broken here and still considers postprocess possibly undefined... + return this.toRelativeDatetime(referenceTime, (s) => postprocess!(removeArticle(s))) + } } \ No newline at end of file diff --git a/src/widgets/assignment-widget.tsx b/src/widgets/assignment-widget.tsx index 1e052c4..beaa94c 100644 --- a/src/widgets/assignment-widget.tsx +++ b/src/widgets/assignment-widget.tsx @@ -1,5 +1,6 @@ import React from 'react' import { ReactWidget } from '@jupyterlab/apputils' +import { IDefaultFileBrowser } from '@jupyterlab/filebrowser' import { CommandRegistry } from '@lumino/commands' import { StylesProvider } from '@material-ui/core/styles' import { AssignmentPanel } from '../components' @@ -8,18 +9,18 @@ import { AssignmentProvider, CommandsProvider, SettingsProvider, BackdropProvide import { IEduhelxSubmissionModel } from '../tokens' export class AssignmentWidget extends ReactWidget { - private model: IEduhelxSubmissionModel + private fileBrowser: IDefaultFileBrowser private commands: CommandRegistry private serverSettings: IServerSettings constructor( - model: IEduhelxSubmissionModel, + fileBrowser: IDefaultFileBrowser, commands: CommandRegistry, serverSettings: IServerSettings ) { super() - - this.model = model + + this.fileBrowser = fileBrowser this.commands = commands this.serverSettings = serverSettings } @@ -31,7 +32,7 @@ export class AssignmentWidget extends ReactWidget { - +