launch the platform speedgrader
When the feature flag is enabled, and when the param platform_sg is passed in the URL, launch the platform speedgrader instead of default speedgrader. This will allow for easily testing between classic speedgrader and platform speedgrader. flag=platform_service_speedgrader test plan: - Have a course with some students and an assignment - Enable the feature flag - Either have a local module federation server running or supply a URL to dynamic configuration for the launch url - Go to the assignment and click on speedgrader - Note that classic sg loads - add "&platform_sg=true" to the URL and refresh - Note the new hotness Change-Id: I6341406f563256c54cc009589a22b93019600373 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/340885 Reviewed-by: Cameron Ray <cameron.ray@instructure.com> Reviewed-by: Aaron Shafovaloff <ashafovaloff@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Aaron Shafovaloff <ashafovaloff@instructure.com> Product-Review: Aaron Shafovaloff <ashafovaloff@instructure.com>
This commit is contained in:
parent
f59d0736c7
commit
6629e7c1ed
|
@ -367,6 +367,7 @@ class ApplicationController < ActionController::Base
|
||||||
enhanced_rubrics
|
enhanced_rubrics
|
||||||
multiselect_gradebook_filters
|
multiselect_gradebook_filters
|
||||||
assignment_edit_placement_not_on_announcements
|
assignment_edit_placement_not_on_announcements
|
||||||
|
platform_service_speedgrader
|
||||||
].freeze
|
].freeze
|
||||||
JS_ENV_ROOT_ACCOUNT_FEATURES = %i[
|
JS_ENV_ROOT_ACCOUNT_FEATURES = %i[
|
||||||
product_tours
|
product_tours
|
||||||
|
|
|
@ -1162,6 +1162,18 @@ class GradebooksController < ApplicationController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if Account.site_admin.feature_enabled?(:platform_service_speedgrader) && params[:platform_sg].present?
|
||||||
|
|
||||||
|
@page_title = t("SpeedGrader")
|
||||||
|
@body_classes << "full-width padless-content"
|
||||||
|
|
||||||
|
remote_env(speedgrader: Services::PlatformServiceSpeedgrader.launch_url)
|
||||||
|
|
||||||
|
js_env(env)
|
||||||
|
deferred_js_bundle :platform_speedgrader
|
||||||
|
|
||||||
|
render html: "".html_safe, layout: "bare"
|
||||||
|
else
|
||||||
append_sis_data(env)
|
append_sis_data(env)
|
||||||
js_env(env)
|
js_env(env)
|
||||||
|
|
||||||
|
@ -1169,6 +1181,7 @@ class GradebooksController < ApplicationController
|
||||||
anonymize_students: @assignment.anonymize_students?
|
anonymize_students: @assignment.anonymize_students?
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
render json: SpeedGrader::Assignment.new(
|
render json: SpeedGrader::Assignment.new(
|
||||||
|
|
|
@ -516,6 +516,13 @@ module ApplicationHelper
|
||||||
global_inst_object
|
global_inst_object
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remote_env(hash = nil)
|
||||||
|
@remote_env ||= {}
|
||||||
|
@remote_env.merge!(hash) if hash
|
||||||
|
|
||||||
|
@remote_env
|
||||||
|
end
|
||||||
|
|
||||||
def editor_buttons
|
def editor_buttons
|
||||||
# called outside of Lti::ContextToolFinder to make sure that
|
# called outside of Lti::ContextToolFinder to make sure that
|
||||||
# @context is non-nil and also a type of Context that would have
|
# @context is non-nil and also a type of Context that would have
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
INST = <%= benchmark("rendering INST") { raw(inst_env.to_json) } %>;
|
INST = <%= benchmark("rendering INST") { raw(inst_env.to_json) } %>;
|
||||||
ENV = <%= benchmark("rendering ENV") { raw(render_js_env) } %>;
|
ENV = <%= benchmark("rendering ENV") { raw(render_js_env) } %>;
|
||||||
BRANDABLE_CSS_HANDLEBARS_INDEX = <%= benchmark("rendering BRANDABLE_CSS_HANDLEBARS_INDEX") { raw(BrandableCSS.handlebars_index_json) } %>
|
BRANDABLE_CSS_HANDLEBARS_INDEX = <%= benchmark("rendering BRANDABLE_CSS_HANDLEBARS_INDEX") { raw(BrandableCSS.handlebars_index_json) } %>
|
||||||
|
REMOTES = <%= benchmark("rendering REMOTES") { raw(remote_env.to_json) } %>;
|
||||||
</script>
|
</script>
|
||||||
<%= benchmark("include_head_js") { include_head_js } %>
|
<%= benchmark("include_head_js") { include_head_js } %>
|
||||||
<% @xhrs_to_prefetch_from_controller&.each do |(args, kwargs)| -%>
|
<% @xhrs_to_prefetch_from_controller&.each do |(args, kwargs)| -%>
|
||||||
|
|
|
@ -3111,6 +3111,13 @@ describe GradebooksController do
|
||||||
expect(response).not_to be_redirect
|
expect(response).not_to be_redirect
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "loads the platform speedgreader when the feature flag is on and the platform_sg flag is passed" do
|
||||||
|
@assignment.publish
|
||||||
|
Account.site_admin.enable_feature!(:platform_service_speedgrader)
|
||||||
|
get "speed_grader", params: { course_id: @course, assignment_id: @assignment.id, platform_sg: true }
|
||||||
|
expect(response).to render_template(:bare, locals: { anonymous_grading: false })
|
||||||
|
end
|
||||||
|
|
||||||
describe "js_env" do
|
describe "js_env" do
|
||||||
let(:js_env) { assigns[:js_env] }
|
let(:js_env) { assigns[:js_env] }
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ const featureBundles: {
|
||||||
past_global_alert: () => import('./features/past_global_alert/index'),
|
past_global_alert: () => import('./features/past_global_alert/index'),
|
||||||
past_global_announcements: () => import('./features/past_global_announcements/index'),
|
past_global_announcements: () => import('./features/past_global_announcements/index'),
|
||||||
permissions: () => import('./features/permissions/index'),
|
permissions: () => import('./features/permissions/index'),
|
||||||
|
platform_speedgrader: () => import('./features/speed_grader/index'),
|
||||||
plugins: () => import('./features/plugins/index'),
|
plugins: () => import('./features/plugins/index'),
|
||||||
prerequisites_lookup: () => import('./features/prerequisites_lookup/index'),
|
prerequisites_lookup: () => import('./features/prerequisites_lookup/index'),
|
||||||
profile_show: () => import('./features/profile_show/index'),
|
profile_show: () => import('./features/profile_show/index'),
|
||||||
|
|
|
@ -28,9 +28,10 @@ import {captureException} from '@sentry/browser'
|
||||||
const I18n = useI18nScope('speed_grader')
|
const I18n = useI18nScope('speed_grader')
|
||||||
|
|
||||||
ready(() => {
|
ready(() => {
|
||||||
if (window.ENV.FEATURES.platform_service_speedgrader) {
|
// The feature must be enabled AND we must be handed the speedgrader platform URL
|
||||||
|
if (window.ENV.FEATURES.platform_service_speedgrader && window.REMOTES?.speedgrader) {
|
||||||
const theme = getCurrentTheme()
|
const theme = getCurrentTheme()
|
||||||
const mountPoint = document.querySelector('#content')
|
const mountPoint = document.querySelector('#react-router-portals')
|
||||||
import('speedgrader/appInjector')
|
import('speedgrader/appInjector')
|
||||||
.then(module => {
|
.then(module => {
|
||||||
module.render(mountPoint, theme)
|
module.render(mountPoint, theme)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
import {sendMessageStudentsWho} from './shared/grading/messageStudentsWhoHelper'
|
import {sendMessageStudentsWho} from './shared/grading/messageStudentsWhoHelper'
|
||||||
import type {GlobalEnv} from '@canvas/global/env/GlobalEnv.d'
|
import type {GlobalEnv} from '@canvas/global/env/GlobalEnv.d'
|
||||||
import {GlobalInst} from '@canvas/global/inst/GlobalInst'
|
import {GlobalInst} from '@canvas/global/inst/GlobalInst'
|
||||||
|
import {GlobalRemotes} from '@canvas/global/remotes/GlobalRemotes'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Global {
|
interface Global {
|
||||||
|
@ -32,6 +33,11 @@ declare global {
|
||||||
* some by client code.
|
* some by client code.
|
||||||
*/
|
*/
|
||||||
readonly INST?: GlobalInst
|
readonly INST?: GlobalInst
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote locations for various pure front-end functionality.
|
||||||
|
*/
|
||||||
|
readonly REMOTES?: GlobalRemotes
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -70,6 +76,11 @@ declare global {
|
||||||
*/
|
*/
|
||||||
const INST: GlobalInst
|
const INST: GlobalInst
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote locations for various pure front-end functionality.
|
||||||
|
*/
|
||||||
|
const REMOTES: GlobalRemotes
|
||||||
|
|
||||||
type ShowIf = {
|
type ShowIf = {
|
||||||
(bool?: boolean): JQuery<HTMLElement>
|
(bool?: boolean): JQuery<HTMLElement>
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 - present Instructure, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of Canvas.
|
||||||
|
*
|
||||||
|
* Canvas is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
* Software Foundation, version 3 of the License.
|
||||||
|
*
|
||||||
|
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type GlobalRemotes = Partial<{
|
||||||
|
speedgrader: string
|
||||||
|
}>
|
Loading…
Reference in New Issue