diff --git a/demos/demo_multiple_classes/jupyterhub_config.py b/demos/demo_multiple_classes/jupyterhub_config.py index 9f2e0a6ef..b91d252e5 100644 --- a/demos/demo_multiple_classes/jupyterhub_config.py +++ b/demos/demo_multiple_classes/jupyterhub_config.py @@ -101,8 +101,8 @@ 'user': 'grader-course101', 'cwd': '/home/grader-course101', 'environment': { - # specify formgrader as default landing page - 'JUPYTERHUB_DEFAULT_URL': '/formgrader' + # specify lab as default landing page + 'JUPYTERHUB_DEFAULT_URL': '/lab' }, 'api_token': '{{course101_token}}', }, @@ -116,8 +116,8 @@ 'user': 'grader-course123', 'cwd': '/home/grader-course123', 'environment': { - # specify formgrader as default landing page - 'JUPYTERHUB_DEFAULT_URL': '/formgrader' + # specify lab as default landing page + 'JUPYTERHUB_DEFAULT_URL': '/lab' }, 'api_token': '{{course123_token}}', }, diff --git a/demos/demo_one_class_multiple_graders/jupyterhub_config.py b/demos/demo_one_class_multiple_graders/jupyterhub_config.py index 678f05830..0f249be2c 100644 --- a/demos/demo_one_class_multiple_graders/jupyterhub_config.py +++ b/demos/demo_one_class_multiple_graders/jupyterhub_config.py @@ -65,8 +65,8 @@ ], 'user': 'grader-course101', 'environment': { - # specify formgrader as default landing page - 'JUPYTERHUB_DEFAULT_URL': '/formgrader' + # specify lab as default landing page + 'JUPYTERHUB_DEFAULT_URL': '/lab' }, 'cwd': '/home/grader-course101', } diff --git a/demos/formgrader_workspace.json b/demos/formgrader_workspace.json deleted file mode 100644 index ec022ab7d..000000000 --- a/demos/formgrader_workspace.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "data": { - "layout-restorer:data": { - "main": { - "dock": { - "type": "tab-area", - "currentIndex": 0, - "widgets": [ - "nbgrader-formgrader:nbgrader-formgrader" - ] - }, - "current": "nbgrader-formgrader:nbgrader-formgrader" - }, - "down": { - "size": 0, - "widgets": [] - } - }, - "nbgrader-formgrader:nbgrader-formgrader": { - "data": {} - } - }, - "metadata": { - "id": "formgrader" - } -} diff --git a/demos/utils.sh b/demos/utils.sh index d5259342b..f2b1d60ee 100644 --- a/demos/utils.sh +++ b/demos/utils.sh @@ -42,10 +42,6 @@ setup_nbgrader () { ${runas} mkdir -p "${HOME}/.jupyter" ${runas} cp "${config}" "${HOME}/.jupyter/nbgrader_config.py" ${runas} chown "${USER}:${USER}" "${HOME}/.jupyter/nbgrader_config.py" - - cp "/root/formgrader_workspace.json" "${HOME}/formgrader_workspace.json" - chown "${USER}:${USER}" "${HOME}/formgrader_workspace.json" - ${runas} jupyter lab workspaces import "${HOME}/formgrader_workspace.json" } setup_jupyterhub () { diff --git a/nbgrader/server_extensions/assignment_list/handlers.py b/nbgrader/server_extensions/assignment_list/handlers.py index 49b00288c..2e83aa1a8 100644 --- a/nbgrader/server_extensions/assignment_list/handlers.py +++ b/nbgrader/server_extensions/assignment_list/handlers.py @@ -383,11 +383,7 @@ def load_jupyter_server_extension(nbapp): webapp = nbapp.web_app webapp.settings['assignment_list_manager'] = AssignmentList(parent=nbapp) - # compatibility between notebook.notebookapp.NotebookApp and jupyter_server.serverapp.ServerApp - if nbapp.name == 'jupyter-notebook': - webapp.settings['assignment_list_manager'].root_dir = nbapp.notebook_dir - else: - webapp.settings['assignment_list_manager'].root_dir = nbapp.root_dir + webapp.settings['assignment_list_manager'].root_dir = nbapp.root_dir base_url = webapp.settings['base_url'] webapp.add_handlers(".*$", [ diff --git a/nbgrader/server_extensions/course_list/handlers.py b/nbgrader/server_extensions/course_list/handlers.py index a06f9bd3b..302ece002 100644 --- a/nbgrader/server_extensions/course_list/handlers.py +++ b/nbgrader/server_extensions/course_list/handlers.py @@ -79,7 +79,7 @@ def check_for_local_formgrader(self, config): if status: raise gen.Return([{ 'course_id': coursedir.course_id, - 'url': base_url + '/formgrader', + 'url': base_url + '/lab', 'kind': 'local' }]) @@ -102,7 +102,7 @@ def check_for_noauth_jupyterhub_formgraders(self, config): if not coursedir.course_id: raise gen.Return([]) - url = self.get_base_url() + "/services/" + coursedir.course_id + "/formgrader" + url = self.get_base_url() + "/services/" + coursedir.course_id auth = get_jupyterhub_authorization() http_client = AsyncHTTPClient() try: @@ -113,7 +113,7 @@ def check_for_noauth_jupyterhub_formgraders(self, config): courses = [{ 'course_id': coursedir.course_id, - 'url': url, + 'url': url + "/lab", 'kind': 'jupyterhub' }] raise gen.Return(courses) @@ -156,7 +156,7 @@ def check_for_jupyterhub_formgraders(self, config): service = services[course] courses.append({ 'course_id': course, - 'url': self.get_base_url() + service['prefix'].rstrip('/') + "/formgrader", + 'url': self.get_base_url() + service['prefix'].rstrip('/') + "/lab", 'kind': 'jupyterhub' }) @@ -233,11 +233,7 @@ def load_jupyter_server_extension(nbapp): webapp = nbapp.web_app base_url = webapp.settings['base_url'] - # compatibility between notebook.notebookapp.NotebookApp and jupyter_server.serverapp.ServerApp - if nbapp.name == 'jupyter-notebook': - webapp.settings['assignment_dir'] = nbapp.notebook_dir - else: - webapp.settings['assignment_dir'] = nbapp.root_dir + webapp.settings['assignment_dir'] = nbapp.root_dir webapp.add_handlers(".*$", [ (ujoin(base_url, pat), handler) diff --git a/nbgrader/server_extensions/formgrader/formgrader.py b/nbgrader/server_extensions/formgrader/formgrader.py index d5806dfb6..ff032db55 100644 --- a/nbgrader/server_extensions/formgrader/formgrader.py +++ b/nbgrader/server_extensions/formgrader/formgrader.py @@ -107,16 +107,9 @@ def load_jupyter_server_extension(nbapp): nbapp.log.info("Loading the formgrader nbgrader serverextension") webapp = nbapp.web_app - # Save which kind of application is running : Jupyterlab like or classic Notebook - webapp.settings['is_jlab'] = not (nbapp.name == 'jupyter-notebook') - formgrader = FormgradeExtension(parent=nbapp) - # compatibility between notebook.notebookapp.NotebookApp and jupyter_server.serverapp.ServerApp - if nbapp.name == 'jupyter-notebook': - formgrader.root_dir = nbapp.notebook_dir - else: - formgrader.root_dir = nbapp.root_dir + formgrader.root_dir = nbapp.root_dir formgrader.log = nbapp.log formgrader.initialize([]) diff --git a/nbgrader/server_extensions/formgrader/handlers.py b/nbgrader/server_extensions/formgrader/handlers.py index e8e6f5f41..fb65eea8e 100644 --- a/nbgrader/server_extensions/formgrader/handlers.py +++ b/nbgrader/server_extensions/formgrader/handlers.py @@ -17,7 +17,6 @@ def get(self): "manage_assignments.tpl", url_prefix=self.url_prefix, base_url=self.base_url, - is_lab=int(self.settings['is_jlab']), windows=(sys.prefix == 'win32'), course_id=self.api.course_id, exchange=self.api.exchange_root, diff --git a/nbgrader/server_extensions/formgrader/static/js/manage_assignments.js b/nbgrader/server_extensions/formgrader/static/js/manage_assignments.js index 531c64eb8..cd8632bc9 100644 --- a/nbgrader/server_extensions/formgrader/static/js/manage_assignments.js +++ b/nbgrader/server_extensions/formgrader/static/js/manage_assignments.js @@ -34,7 +34,6 @@ var AssignmentUI = Backbone.View.extend({ this.listenTo(this.model, "request", this.animateSaving); this.listenTo(this.model, "sync", this.closeModal); - this.is_lab = options.is_lab || false; this.render(); }, @@ -102,17 +101,17 @@ var AssignmentUI = Backbone.View.extend({ var name = this.model.get("name") this.$name.attr("data-order", name); - /* Append link with : - * - href if this is a Notebook<7 environment - * - click listener to send message to iframe parent if this is Jupyter Lab environment - */ + // Append link with a listener to send message to iframe parent. + // NOTE: the formgrade UI is embedded in an iframe. this.$name.append($("") .text(name) - .attr("target", self.is_lab ? undefined : "_blank") - .attr("href", self.is_lab ? undefined : base_url + "/tree/" + url_prefix + "/" + this.model.get("source_path")) - .click(self.is_lab ? function(){ - window.parent.postMessage(jlab_go_to_path(url_prefix + "/" + this_assignment.model.get("source_path")), '*'); - } : undefined) + .attr("href", "#") + .click(function() { + window.parent.postMessage( + jlab_go_to_path(url_prefix + "/" + this_assignment.model.get("source_path")), + '*' + ); + }) ); // duedate @@ -141,7 +140,9 @@ var AssignmentUI = Backbone.View.extend({ .click(_.bind(this.openModal, this)) .append($("") .addClass("glyphicon glyphicon-pencil") - .attr("aria-hidden", "true"))); + .attr("aria-hidden", "true") + ) + ); // generate student version this.$assign.append($("") @@ -149,24 +150,28 @@ var AssignmentUI = Backbone.View.extend({ .click(_.bind(this.assign, this)) .append($("") .addClass("glyphicon glyphicon-education") - .attr("aria-hidden", "true"))); + .attr("aria-hidden", "true") + ) + ); // preview student version var release_path = this.model.get("release_path"); if (release_path) { - /* Append link with : - * - href if this is a Notebook<7 environment - * - click listener to send message to iframe parent if this is Jupyter Lab environment - */ + // Append link with a listener to send message to iframe parent. + // NOTE: the formgrade UI is embedded in an iframe. this.$preview.append($("") - .attr("target", self.is_lab ? undefined : "_blank") - .attr("href", self.is_lab ? undefined : base_url + "/tree/" + url_prefix + "/" + release_path) - .click(self.is_lab ? function(){ - window.parent.postMessage(jlab_go_to_path(url_prefix + "/" + release_path), '*'); - } : undefined) + .attr("href", "#") + .click(function() { + window.parent.postMessage( + jlab_go_to_path(url_prefix + "/" + release_path), + '*' + ); + }) .append($("") .addClass("glyphicon glyphicon-search") - .attr("aria-hidden", "true"))); + .attr("aria-hidden", "true") + ) + ); } // release @@ -178,14 +183,18 @@ var AssignmentUI = Backbone.View.extend({ .click(_.bind(this.release, this)) .append($("") .addClass("glyphicon glyphicon-cloud-upload") - .attr("aria-hidden", "true"))); + .attr("aria-hidden", "true") + ) + ); } else { this.$release.append($("") .attr("href", "#") .click(_.bind(this.unrelease, this)) .append($("") .addClass("glyphicon glyphicon-remove") - .attr("aria-hidden", "true"))); + .attr("aria-hidden", "true") + ) + ); } } @@ -197,7 +206,9 @@ var AssignmentUI = Backbone.View.extend({ .click(_.bind(this.collect, this)) .append($("") .addClass("glyphicon glyphicon-cloud-download") - .attr("aria-hidden", "true"))); + .attr("aria-hidden", "true") + ) + ); } } @@ -209,27 +220,32 @@ var AssignmentUI = Backbone.View.extend({ } else { this.$num_submissions.append($("") .attr("href", base_url + "/formgrader/manage_submissions/" + this.model.get("name")) - .text(num_submissions)); + .text(num_submissions) + ); } // generate feedback if (num_submissions > 0) { this.$generate_feedback.append($("") - .attr("href", "#") + .attr("href", "#") .click(_.bind(this.generate_feedback, this)) - .append($("") - .addClass("glyphicon glyphicon-comment") - .attr("aria-hidden", "true"))); + .append($("") + .addClass("glyphicon glyphicon-comment") + .attr("aria-hidden", "true") + ) + ); } // feedback if (num_submissions > 0) { this.$release_feedback.append($("") - .attr("href", "#") + .attr("href", "#") .click(_.bind(this.release_feedback, this)) - .append($("") - .addClass("glyphicon glyphicon-envelope") - .attr("aria-hidden", "true"))); + .append($("") + .addClass("glyphicon glyphicon-envelope") + .attr("aria-hidden", "true") + ) + ); } }, @@ -579,7 +595,7 @@ var createAssignmentModal = function () { modal = createModal("add-assignment-modal", "Add New Assignment", body, footer); }; -var loadAssignments = function (is_lab=false) { +var loadAssignments = function () { var tbl = $("#main-table"); models = new Assignments(); @@ -591,8 +607,7 @@ var loadAssignments = function (is_lab=false) { models.each(function (model) { var view = new AssignmentUI({ "model": model, - "el": insertRow(tbl), - "is_lab": is_lab + "el": insertRow(tbl) }); views.push(view); }); @@ -605,8 +620,7 @@ var loadAssignments = function (is_lab=false) { var models = undefined; var views = []; -var is_lab = is_lab || false; $(window).on('load', function () { - loadAssignments(is_lab); + loadAssignments(); }); diff --git a/nbgrader/server_extensions/formgrader/templates/formgrade/formgrade_macros.html.j2 b/nbgrader/server_extensions/formgrader/templates/formgrade/formgrade_macros.html.j2 index e014b1f2e..cf8a9475e 100644 --- a/nbgrader/server_extensions/formgrader/templates/formgrade/formgrade_macros.html.j2 +++ b/nbgrader/server_extensions/formgrader/templates/formgrade/formgrade_macros.html.j2 @@ -64,20 +64,12 @@ function jlab_open_notebook(notebook_path) {
  • {{ resources.notebook_id }}
  • Submission #{{ resources.index + 1 }} {%- if resources.last_name and resources.first_name -%} {{ resources.last_name }}, {{ resources.first_name }} diff --git a/nbgrader/server_extensions/formgrader/templates/manage_assignments.tpl b/nbgrader/server_extensions/formgrader/templates/manage_assignments.tpl index 1fb2ab3cf..51b6969f8 100644 --- a/nbgrader/server_extensions/formgrader/templates/manage_assignments.tpl +++ b/nbgrader/server_extensions/formgrader/templates/manage_assignments.tpl @@ -3,7 +3,6 @@ {%- block head -%} diff --git a/nbgrader/server_extensions/validate_assignment/handlers.py b/nbgrader/server_extensions/validate_assignment/handlers.py index c48e6aac5..475ecc82c 100644 --- a/nbgrader/server_extensions/validate_assignment/handlers.py +++ b/nbgrader/server_extensions/validate_assignment/handlers.py @@ -139,11 +139,7 @@ def load_jupyter_server_extension(nbapp): webapp = nbapp.web_app base_url = webapp.settings['base_url'] - # compatibility between notebook.notebookapp.NotebookApp and jupyter_server.serverapp.ServerApp - if nbapp.name == 'jupyter-notebook': - webapp.settings['root_dir'] = nbapp.notebook_dir - else: - webapp.settings['root_dir'] = nbapp.root_dir + webapp.settings['root_dir'] = nbapp.root_dir webapp.add_handlers(".*$", [ (ujoin(base_url, pat), handler) diff --git a/src/course_list/courselist.ts b/src/course_list/courselist.ts index b3667cf73..3979e2371 100644 --- a/src/course_list/courselist.ts +++ b/src/course_list/courselist.ts @@ -41,7 +41,7 @@ export async function requestAPI( return data; } -function createElementFromCourse(data: any, app: JupyterFrontEnd) { +function createElementFromCourse(data: any, app: JupyterFrontEnd, isNotebook:boolean) { var element = document.createElement('div') as HTMLDivElement; element.classList.add('list_item','row'); @@ -54,16 +54,18 @@ function createElementFromCourse(data: any, app: JupyterFrontEnd) { var anchor = document.createElement('a') as HTMLAnchorElement; anchor.href = '#'; anchor.innerText = data['course_id']; - if (data['kind'] == 'local') { anchor.href = '#'; anchor.onclick = function() { app.commands.execute(commandIDs.openFormgrader, data); } - } - else { + } else { const url = data['url'] as string; - anchor.href = URLExt.join(url.replace(/formgrader$/, 'lab'), 'workspaces', 'formgrader'); + if (isNotebook) { + anchor.href = URLExt.join(url.replace(/lab\/?$/, 'tree')); + } else { + anchor.href = url + } anchor.target = 'blank'; } @@ -85,9 +87,15 @@ export class CourseList { listerror: HTMLDivElement; listerrortext: HTMLDivElement; app: JupyterFrontEnd; + private _isNotebook: boolean; - constructor(public course_list_element: HTMLDivElement, app: JupyterFrontEnd) { + constructor( + public course_list_element: HTMLDivElement, + app: JupyterFrontEnd, + isNotebook: boolean + ) { this.app = app; + this._isNotebook = isNotebook; this.listplaceholder = document.createElement('div') as HTMLDivElement; this.listplaceholder.id = 'formgrader_list_placeholder'; this.listplaceholder.classList.add('list_placeholder'); @@ -170,7 +178,9 @@ export class CourseList { this.listplaceholder.hidden = true; } for (var i=0; i = { label: 'Course List', execute: () => { if (!widget || widget.isDisposed) { - const content = new CourseListWidget(app); + const content = new CourseListWidget(app, notebookTree !== null); widget = new MainAreaWidget({content}); widget.id = 'nbgrader-course-list'; widget.addClass('nbgrader-mainarea-widget');