Implement choose editor modal for page CRUD flows

closes RCX-2444
flag=block_editor

Test plan:
- Create a page and check the editor choice modal
  is opened up.
- Select the RCE and check the flow behaves normally
- Create a new page and select the block editor and
  check the block editor flow works like it should
- Create a page via module and edit it later, check
  the editor choice pops up, check both paths.
- Edit a page already with some content and check the
  editor choice does not popup.
- Try the page creation a couple times and check th
  remember my choice checkbox
- Check the modal no longer show up
- Clear the user preference that controls editor choice
- Try again and check the modal shows up like before

Change-Id: Ief8f5716ecca5e3f7d56a631c42cb3a284002ab5
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/360710
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ed Schiebel <eschiebel@instructure.com>
QA-Review: Ed Schiebel <eschiebel@instructure.com>
Product-Review: Luis Oliveira <luis.oliveira@instructure.com>
This commit is contained in:
Matheus Costa 2024-10-22 07:49:48 -03:00 committed by Luis Oliveira
parent 5a74bc95b8
commit b69e4c3bca
15 changed files with 396 additions and 42 deletions

View File

@ -1752,7 +1752,7 @@ class UsersController < ApplicationController
create_user
end
BOOLEAN_PREFS = %i[manual_mark_as_read collapse_global_nav collapse_course_nav hide_dashcard_color_overlays release_notes_badge_disabled comment_library_suggestions_enabled elementary_dashboard_disabled].freeze
BOOLEAN_PREFS = %i[manual_mark_as_read collapse_global_nav collapse_course_nav hide_dashcard_color_overlays release_notes_badge_disabled comment_library_suggestions_enabled elementary_dashboard_disabled default_to_block_editor].freeze
# @API Update user settings.
# Update an existing user's settings.
@ -1975,6 +1975,41 @@ class UsersController < ApplicationController
end
end
# @API Update text editor preference
# Updates a user's default choice for text editor. This allows
# the Choose an Editor propmts to preload the user's preference.
#
#
# @argument text_editor_preference [String, "block_editor"|"rce"|""]
# The identifier for the editor.
#
# @example_request
#
# curl 'https://<canvas>/api/v1/users/<user_id>/prefered_editor \
# -X PUT \
# -F 'text_editor_preference=rce'
# -H 'Authorization: Bearer <token>'
#
# @example_response
# {
# "text_editor_preference": "rce"
# }
def set_text_editor_preference
user = api_find(User, params[:id])
return unless authorized_action(user, @current_user, [:manage, :manage_user_details])
raise ActiveRecord::RecordInvalid if %w[rce block_editor].exclude?(params[:text_editor_preference]) && params[:text_editor_preference] != ""
params[:text_editor_preference] = nil if params[:text_editor_preference] == ""
if user.set_preference(:text_editor_preference, params[:text_editor_preference])
render(json: { text_editor_preference: user.reload.get_preference(:text_editor_preference) })
else
render(json: user.errors, status: :bad_request)
end
end
# @API Get dashboard positions
#
# Returns all dashboard positions that have been saved for a user.

View File

@ -141,6 +141,10 @@ class WikiPagesController < ApplicationController
end
end
def create_block_editor
BlockEditor.create! root_account_id: @page.root_account_id, context: @page, editor_version: BlockEditor::LATEST_VERSION, blocks: BlockEditor::BLANK_PAGE
end
def revisions
if @page.grants_right?(@current_user, session, :read_revisions)
if (!@context.conditional_release? && !Account.site_admin.feature_enabled?(:selective_release_backend)) || enforce_assignment_visible(@page)
@ -175,6 +179,7 @@ class WikiPagesController < ApplicationController
wiki_index_menu_tools: external_tools_display_hashes(:wiki_index_menu),
DISPLAY_SHOW_ALL_LINK: tab_enabled?(context.class::TAB_PAGES, no_render: true) && !@k5_details_view,
CAN_SET_TODO_DATE: context.grants_any_right?(@current_user, session, :manage_content, :manage_course_content_edit),
text_editor_preference: @current_user&.reload&.get_preference(:text_editor_preference)
}
if Account.site_admin.feature_enabled?(:permanent_page_links)
title_availability_path = context.is_a?(Course) ? api_v1_course_page_title_availability_path : api_v1_group_page_title_availability_path

View File

@ -24,6 +24,23 @@ class BlockEditor < ActiveRecord::Base
alias_attribute :version, :editor_version
LATEST_VERSION = "0.2"
BLANK_PAGE = {
ROOT: {
type: {
resolvedName: "PageBlock"
},
isCanvas: true,
props: {},
displayName: "Page",
custom: {},
hidden: false,
nodes: [],
linkedNodes: {}
}
}.freeze
def set_root_account_id
self.root_account_id = context&.root_account_id unless root_account_id
end

View File

@ -1995,6 +1995,10 @@ class User < ActiveRecord::Base
!!preferences[:collapse_course_nav]
end
def text_editor_preference
preferences[:text_editor_preference]
end
# ***** OHI If you're going to add a lot of data into `preferences` here maybe take a look at app/models/user_preference_value.rb instead ***
# it will store the data in a separate table on the db and lighten the load on poor `users`

View File

@ -60,6 +60,7 @@ class UserPreferenceValue < ActiveRecord::Base
add_user_preference :unread_rubric_comments, use_sub_keys: true
add_user_preference :module_links_default_new_tab
add_user_preference :viewed_auto_subscribed_account_calendars
add_user_preference :text_editor_preference
def self.settings
@preference_settings ||= {}

View File

@ -157,6 +157,7 @@ CanvasRails::Application.routes.draw do
concern :pages do
resources :wiki_pages, path: :pages, except: %i[update destroy new], constraints: { id: %r{[^/]+} } do
get "revisions" => "wiki_pages#revisions", :as => :revisions
put "create_block_editor" => "wiki_pages#create_block_editor", :as => :create_block_editor
end
get "wiki" => "wiki_pages#front_page", :as => :wiki
@ -1628,6 +1629,8 @@ CanvasRails::Application.routes.draw do
get "users/:id/colors/:asset_string", controller: "users", action: "get_custom_color"
put "users/:id/colors/:asset_string", controller: "users", action: "set_custom_color"
put "users/:id/text_editor_preference", controller: "users", action: "set_text_editor_preference"
get "users/:id/new_user_tutorial_statuses", action: "get_new_user_tutorial_statuses"
put "users/:id/new_user_tutorial_statuses/:page_name", action: "set_new_user_tutorial_status"

View File

@ -2047,6 +2047,8 @@
path: '/api/v1/users/:id/settings'
- verb: POST
path: '/api/v1/users/:id/split'
- verb: PUT
path: "/api/v1/users/:id/text_editor_preference"
- verb: GET
path: '/api/v1/users/:user_id/avatars'
- verb: GET

View File

@ -22,6 +22,8 @@ module BlockEditorPage
def create_wiki_page(course)
get "/courses/#{course.id}/pages"
f("a.new_page").click
click_INSTUI_Select_option(f("[data-testid=\"choose-an-editor-dropdown\"]"), "Try the Block Editor")
fj("button:contains('Continue')").click
wait_for_block_editor
end

View File

@ -22,6 +22,7 @@ import {useScope as useI18nScope} from '@canvas/i18n'
import WikiPage from '@canvas/wiki/backbone/models/WikiPage'
import PaginatedCollectionView from '@canvas/pagination/backbone/views/PaginatedCollectionView'
import WikiPageEditView from '@canvas/wiki/backbone/views/WikiPageEditView'
import renderChooseEditorModal from '@canvas/block-editor/react/renderChooseEditorModal'
import itemView from './WikiPageIndexItemView'
import template from '../../jst/WikiPageIndex.handlebars'
import {deletePages} from '../../react/apiClient'
@ -45,12 +46,15 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
this.mixin({
events: {
'click .delete_pages': 'confirmDeletePages',
'click .new_page': 'createNewPage',
'keyclick .new_page': 'createNewPage',
'click .new_page': 'openChooseEditorModalMaybe',
'keyclick .new_page': 'openChooseEditorModalMaybe',
'click .new_rce_page': 'openRCE',
'keyclick .new_rce_page': 'openRCE',
'click .new_block_editor_page': 'openBlockEditor',
'keyclick .new_block_editor_page': 'openBlockEditor',
'click .header-row a[data-sort-field]': 'sort',
'click .header-bar-right .menu_tool_link': 'openExternalTool',
'click .pages-mobile-header a[data-sort-mobile-field]': 'sortBySelect',
'click #toggle_block_editor': 'toggleBlockEditor',
},
els: {
@ -104,8 +108,6 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
if (!this.selectedPages) this.selectedPages = {}
this.itemViewOptions.selectedPages = this.selectedPages
this.createNewPageWithBlockEditor = !!ENV.FEATURES?.BLOCK_EDITOR
this.collection.on('fetch', () => {
if (!this.fetched) {
this.fetched = true
@ -148,6 +150,29 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
}
}
openRCE(e) {
e.preventDefault()
this.createNewPage(e, 'rce')
}
openBlockEditor(e) {
e.preventDefault()
this.createNewPage(e, 'block_editor')
}
openChooseEditorModalMaybe(e) {
if (window.ENV.text_editor_preference != null) {
return this.createNewPage(e, window.ENV.text_editor_preference)
}
const createPageAction = editor => {
this.createNewPage(e, editor)
}
ENV.FEATURES?.BLOCK_EDITOR
? renderChooseEditorModal(e, createPageAction)
: this.createNewPage(e)
}
sortBySelect(event) {
event.preventDefault()
const {sortMobileField, sortMobileKey} = event.target.dataset
@ -204,10 +229,6 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
}
}
toggleBlockEditor(ev) {
this.createNewPageWithBlockEditor = ev.target.checked
}
confirmDeletePages(ev) {
if (ev != null) {
ev.preventDefault()
@ -237,7 +258,7 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
$('.delete_pages').focus()
}
createNewPage(ev) {
createNewPage(ev, editor = 'rce') {
if (ev != null) {
ev.preventDefault()
}
@ -249,13 +270,14 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
this.editModel = new WikiPage(
{
editing_roles: this.default_editing_roles,
editor: this.createNewPageWithBlockEditor ? 'block_editor' : 'rce',
block_editor_attributes: this.createNewPageWithBlockEditor
? {
version: '1',
blocks: undefined,
}
: null,
editor,
block_editor_attributes:
editor !== 'rce'
? {
version: '0.2',
blocks: undefined,
}
: null,
},
{contextAssetString: this.contextAssetString}
)
@ -413,6 +435,10 @@ export default class WikiPageIndexView extends PaginatedCollectionView {
json.hasWikiIndexPlacements = this.wikiIndexPlacements.length > 0
json.wikiIndexPlacements = this.wikiIndexPlacements
json.block_editor_is_preferred = window.ENV.text_editor_preference === 'block_editor'
json.rce_is_preferred = window.ENV.text_editor_preference === 'rce'
json.no_preferred_editor = window.ENV.text_editor_preference === null
json.block_editor = !!ENV.FEATURES?.BLOCK_EDITOR
return json
}

View File

@ -4,31 +4,48 @@
<div class="sticky-toolbar-with-right-side" data-sticky>
<div class="header-bar">
<div class="header-bar-right">
{{#if block_editor}}
<label class="checkbox" for="toggle_block_editor" style="margin-inline-end: 4px;">
<input type="checkbox" value="1" id="toggle_block_editor" aria-label="toggle block editor" checked>
{{#t}}Create with block editor{{/t}}
</label>
{{/if}}
{{#if CAN.DELETE}}
<button class="btn delete_pages" tabindex="0" aria-label="{{#t}}Delete selected pages{{/t}}" disabled>
<i class="icon-trash" role="presentation"></i>
</button>
{{/if}}
{{#if CAN.CREATE}}
<a class="btn btn-primary icon-plus new_page" role="button" tabindex="0" aria-label="{{#t 'buttons.new_page_label'}}Add a page{{/t}}">{{#t 'buttons.new_page'}}Page{{/t}}</a>
{{#if hasWikiIndexPlacements}}
<div class="inline-block">
<a class="al-trigger btn" role="button" aria-haspopup="true" aria-owns="toolbar-1" href="#">
<i class="icon-more" aria-hidden="true"></i>
<span class="screenreader-only">{{#t}}Pages Settings{{/t}}</span>
</a>
<ul id="toolbar-1" class="al-options" role="menu" aria-hidden="true" aria-expanded="false">
{{>ui/shared/external-tools/jst/_external_tools_menu.handlebars wikiIndexPlacements}}
</ul>
</div>
<div>
{{#if CAN.DELETE}}
<button class="btn delete_pages" tabindex="0" aria-label="{{#t}}Delete selected pages{{/t}}" disabled>
<i class="icon-trash" role="presentation"></i>
</button>
{{/if}}
{{#if CAN.CREATE}}
<a class="btn btn-primary icon-plus new_page" role="button" tabindex="0" aria-label="{{#t 'buttons.new_page_label'}}Add a page{{/t}}">
{{#if block_editor_is_preferred }} {{#t 'buttons.new_page'}}Page{{/t}} {{/if}}
{{#if no_preferred_editor }} {{#t 'buttons.new_page'}}Page{{/t}} {{/if}}
{{#if rce_is_preferred }} {{#t 'buttons.new_rce_page'}}RCE Page{{/t}} {{/if}}
</a>
{{/if}}
</div>
{{#if CAN.CREATE}}
<div style="margin-top: 15px; text-align: right;">
{{#if block_editor_is_preferred }}
<a href="#" class="new_rce_page">
{{#t 'buttons.use_the_rce'}}Use the RCE{{/t}}
</a>
{{/if}}
{{#if rce_is_preferred }}
<a href="#" class="new_block_editor_page">
{{#t 'buttons.try_the_block_editor'}}Try the Block Editor{{/t}}
</a>
{{/if}}
</div>
{{/if}}
{{#if hasWikiIndexPlacements}}
<div class="inline-block">
<a class="al-trigger btn" role="button" aria-haspopup="true" aria-owns="toolbar-1" href="#">
<i class="icon-more" aria-hidden="true"></i>
<span class="screenreader-only">{{#t}}Pages Settings{{/t}}</span>
</a>
<ul id="toolbar-1" class="al-options" role="menu" aria-hidden="true" aria-expanded="false">
{{>ui/shared/external-tools/jst/_external_tools_menu.handlebars wikiIndexPlacements}}
</ul>
</div>
{{/if}}
</div>
</div>
@ -144,4 +161,5 @@
{{/unless}}
{{/if}}
</div>
<div id="choose-editor-mount-point"></div>
</div>

View File

@ -27,6 +27,7 @@ import template from '../../jst/WikiPage.handlebars'
import StickyHeaderMixin from '@canvas/wiki/backbone/views/StickyHeaderMixin'
import WikiPageDeleteDialog from '@canvas/wiki/backbone/views/WikiPageDeleteDialog'
import WikiPageReloadView from '@canvas/wiki/backbone/views/WikiPageReloadView'
import renderChooseEditorModal from '@canvas/block-editor/react/renderChooseEditorModal'
import PublishButtonView from '@canvas/publish-button-view'
import {useScope as useI18nScope} from '@canvas/i18n'
import htmlEscape from '@instructure/html-escape'
@ -37,6 +38,7 @@ import DirectShareUserModal from '@canvas/direct-sharing/react/components/Direct
import DirectShareCourseTray from '@canvas/direct-sharing/react/components/DirectShareCourseTray'
import {renderFrontPagePill} from '@canvas/wiki/react/renderFrontPagePill'
import ItemAssignToManager from '@canvas/context-modules/differentiated-modules/react/Item/ItemAssignToManager'
import doFetchApi from "@canvas/do-fetch-api-effect";
const I18n = useI18nScope('pages')
@ -55,6 +57,8 @@ export default class WikiPageView extends Backbone.View {
this.prototype.events = {
'click .delete_page': 'deleteWikiPage',
'click .edit-wiki': 'openChooseEditorModalMaybe',
'keyclick .edit-wiki': 'openChooseEditorModalMaybe',
'click .use-as-front-page-menu-item': 'useAsFrontPage',
'click .unset-as-front-page-menu-item': 'unsetAsFrontPage',
'click .direct-share-send-to-menu-item': 'openSendTo',
@ -179,6 +183,35 @@ export default class WikiPageView extends Backbone.View {
this.maybeRenderBlockEditorContent()
}
async openChooseEditorModalMaybe(e) {
if (
this.model.get('body') === null &&
!this.model.get('block_editor_attributes')?.blocks &&
ENV.FEATURES?.BLOCK_EDITOR
) {
if (window.ENV.text_editor_preference == null) {
renderChooseEditorModal(e, async editor => {
if (editor === 'block_editor') {
await doFetchApi({
path: `/courses/${this.course_id}/pages/${this.model.get('url')}/create_block_editor`,
method: 'PUT',
})
}
window.location.href = `${window.location.href.split('?')[0]}/edit?editor=${editor}`
})
} else if (window.ENV.text_editor_preference === 'block_editor') {
e.preventDefault();
await doFetchApi({
path: `/courses/${this.course_id}/pages/${this.model.get('url')}/create_block_editor`,
method: 'PUT',
})
window.location.href = `${window.location.href.split('?')[0]}/edit${
window.location.href.split('?')[1] ? `?${window.location.href.split('?')[1]}` : ''
}`
}
}
}
navigateToLinkAnchor() {
const anchor_name = window.location.hash.replace(/^#/, '')
if (anchor_name.length) {

View File

@ -110,4 +110,5 @@
{{convertApiUserContent body}}
{{/if}}
<div id="assign-to-mount-point"></div>
<div id="choose-editor-mount-point"></div>
</div>

View File

@ -0,0 +1,192 @@
/*
* Copyright (C) 2023 - 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/>.
*/
import React, {useState} from 'react'
import {useScope as useI18nScope} from '@canvas/i18n'
import {Modal} from '@instructure/ui-modal'
import {Button, CloseButton} from '@instructure/ui-buttons'
import {IconExternalLinkLine} from '@instructure/ui-icons'
import {Text} from '@instructure/ui-text'
import {View} from '@instructure/ui-view'
import {Heading} from '@instructure/ui-heading'
import {SimpleSelect} from '@instructure/ui-simple-select'
import {Checkbox} from '@instructure/ui-checkbox'
import {Flex} from '@instructure/ui-flex'
import {Link} from '@instructure/ui-link'
import {createRoot} from 'react-dom/client'
import doFetchApi from '@canvas/do-fetch-api-effect'
import type {ChooseEditorModalProps, EditorPrefEnv, EditorTypes} from './types'
import {type GlobalEnv} from '@canvas/global/env/GlobalEnv'
declare const ENV: GlobalEnv & EditorPrefEnv
const I18n = useI18nScope('block-editor')
const ChooseEditorModal = (props: ChooseEditorModalProps) => {
const [isOpen, setIsOpen] = useState<boolean>(true)
const [rememberMyChoice, setRememberMyChoice] = useState<boolean>(
ENV.text_editor_preference !== null
)
const [editorChoice, setEditorChoice] = useState<'rce' | 'block_editor' | ''>(
ENV.text_editor_preference || ''
)
const [erroredForm, setErroredForm] = useState<boolean>(false)
const close = () => {
setIsOpen(false)
props.onClose()
}
const validEditorChoice = () => {
if (['rce', 'block_editor'].includes(editorChoice)) {
return true
} else {
setErroredForm(true)
return false
}
}
const submitEditorChoice = async () => {
if (validEditorChoice()) {
await doFetchApi({
method: 'PUT',
path: `/api/v1/users/self/text_editor_preference`,
body: {text_editor_preference: rememberMyChoice ? editorChoice : ''},
})
props.createPageAction(editorChoice)
close()
}
}
return (
<Modal
label="New Way To Create"
open={isOpen}
onDismiss={close}
size="small"
themeOverride={{smallMaxWidth: '27.5rem'}}
shouldCloseOnDocumentClick={true}
>
<Modal.Header>
<Heading>{I18n.t('New Way to Create')}</Heading>
<CloseButton placement="end" onClick={close} screenReaderLabel="Close" />
</Modal.Header>
<Modal.Body>
<Heading level="h3" margin="0 0 small 0">
{I18n.t('Try the New Block Editor')}
</Heading>
<Text lineHeight="condensed">
<div>
{I18n.t(
"We've introduced a new editor to give you more flexibility and power in content creation. Choose the editor that best suits your workflow."
)}
</div>
</Text>
<View
as="div"
borderRadius="medium"
borderWidth="small"
padding="small"
margin="small 0 medium 0"
>
<Flex gap="small" justifyItems="space-between">
<Flex.Item shouldShrink={true}>
<Text size="x-small" lineHeight="condensed">
<div>
{I18n.t(
'Read about key features and discover what you can create using the Block Editor.'
)}
</div>
</Text>
</Flex.Item>
<Flex.Item>
<Link
href="https://community.canvaslms.com/t5/Block-Editor-Beta/gh-p/block_editor"
target="_blank"
>
<IconExternalLinkLine />
</Link>
</Flex.Item>
</Flex>
</View>
<SimpleSelect
onChange={(_e: React.SyntheticEvent, data: {value?: string | undefined | number}) => {
setErroredForm(false)
setEditorChoice(data.value as EditorTypes)
}}
renderLabel={
<Flex>
<Flex.Item>{I18n.t('Select an Editor')}</Flex.Item>
<Flex.Item>*</Flex.Item>
</Flex>
}
messages={erroredForm ? [{type: 'error', text: I18n.t('Please choose an editor')}] : []}
placeholder={I18n.t('Select One')}
defaultValue={editorChoice}
data-testid="choose-an-editor-dropdown"
>
<SimpleSelect.Option id="block_editor" value="block_editor">
{I18n.t('Try the Block Editor')}
</SimpleSelect.Option>
<SimpleSelect.Option id="rce" value="rce">
{I18n.t('Use the RCE')}
</SimpleSelect.Option>
</SimpleSelect>
<View as="div" padding="small 0 medium 0">
<Checkbox
checked={rememberMyChoice}
onChange={() => {
setRememberMyChoice(!rememberMyChoice)
}}
label={I18n.t('Remember my choice')}
value="remember_my_choice"
/>
</View>
</Modal.Body>
<Modal.Footer>
<Button margin="0 x-small 0 0" onClick={close}>
{I18n.t('Cancel')}
</Button>
<Button color="primary" onClick={submitEditorChoice}>
{I18n.t('Continue')}
</Button>
</Modal.Footer>
</Modal>
)
}
const renderChooseEditorModal = (e: React.SyntheticEvent, createPageAction: () => {}) => {
if (e != null) {
e.preventDefault()
}
const rootElement = document.querySelector('#choose-editor-mount-point')
if (rootElement) {
const root = createRoot(rootElement)
const editorModal = (
<ChooseEditorModal
createPageAction={createPageAction}
onClose={() => {
root.unmount()
}}
/>
)
root.render(editorModal)
return editorModal
}
}
export default renderChooseEditorModal

View File

@ -61,6 +61,11 @@ export type BlockTemplateGridItemProps = {
template?: BlockTemplate
}
export type ChooseEditorModalProps = {
createPageAction: any
onClose: any
}
export const SaveTemplateEvent = 'block-editor-save-block-template' as const
export const DeleteTemplateEvent = 'block-editor-delete-block-template' as const
export const PublishTemplateEvent = 'block-editor-publish-block-template' as const
@ -69,3 +74,8 @@ export const dispatchTemplateEvent = (event: CustomEvent) => {
const blockEditorEditor = document.querySelector('.block-editor-editor')
blockEditorEditor?.dispatchEvent(event)
}
export type EditorTypes = 'rce' | 'block_editor' | ''
export type EditorPrefEnv = {
text_editor_preference: EditorTypes
}

View File

@ -71,6 +71,7 @@ export default class WikiPageEditView extends ValidatedFormView {
super.initialize(...arguments)
if (!this.WIKI_RIGHTS) this.WIKI_RIGHTS = {}
if (!this.PAGE_RIGHTS) this.PAGE_RIGHTS = {}
this.queryParams = new URLSearchParams(window.location.search)
this.enableAssignTo =
window.ENV.FEATURES?.selective_release_ui_api &&
ENV.COURSE_ID != null &&
@ -148,6 +149,10 @@ export default class WikiPageEditView extends ValidatedFormView {
json.show_assign_to = this.enableAssignTo
json.edit_with_block_editor = this.model.get('editor') === 'block_editor'
if (this.queryParams.get('editor') === 'block_editor' && this.model.get('body') == null) {
json.edit_with_block_editor = true
}
return json
}