add new page functionality to pages

test plan (course wiki and group wiki):
 - ensure that enable_draft is set for the account
 - navigate to the pages index
 * click the add Page button
   - ensure the page behaves as expected
   * editing permissions defaults to the course's setting
   * enter key (invokes the Save button, unless editing the body)
   * Save button (creates and navigates to the page)
   * Cancel button (navigates back to the index, hiding the sidebar)

fixes #CNVS-7167

Change-Id: Ib72f4c60e77420197d6e53efbe21ec46d4caf51f
Reviewed-on: https://gerrit.instructure.com/22701
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Reviewed-by: Sterling Cobb <sterling@instructure.com>
Product-Review: Matt Goodwin <mattg@instructure.com>
This commit is contained in:
Mark Severson 2013-07-26 16:34:06 -06:00
parent 4c913efc2e
commit da1c9dd97b
16 changed files with 300 additions and 39 deletions

View File

@ -15,4 +15,8 @@ require [
PAGE_RIGHTS: ENV.PAGE_RIGHTS
$('#content').append(wikiPageEditView.$el)
wikiPageEditView.on 'cancel', ->
html_url = wikiPage.get('html_url')
window.location.href = html_url if html_url
wikiPageEditView.render()

View File

@ -15,11 +15,13 @@ require [
view = new WikiPageIndexView
collection: new WikiPageCollection
contextAssetString: ENV.context_asset_string
default_editing_roles: ENV.DEFAULT_EDITING_ROLES
WIKI_RIGHTS: ENV.WIKI_RIGHTS
view.collection.fetch({data: {sort:'title',per_page:30}}).then ->
view.fetched = true
# Re-render after fetching is complete, but only if there are no pages in the collection
view.render() if view.collection.models.length == 0
$('#content').append(view.$el)
view.render()

View File

@ -9,7 +9,7 @@ define [
resourceName: 'pages'
@mixin DefaultUrlMixin
url: -> "#{@_defaultUrl()}/#{@get('url')}"
url: -> "#{@_defaultUrl()}" + if @get('url') then "/#{@get('url')}" else ''
initialize: (attributes, options) ->
super
@ -33,7 +33,7 @@ define [
# Returns a json representation suitable for presenting
present: ->
_.extend _.omit(@toJSON(), 'id'), contextName: @contextName, contextId: @contextId
_.extend _.omit(@toJSON(), 'id'), contextName: @contextName, contextId: @contextId, new_record: !@get('url')
# Uses the api to perform a publish on the page
publish: ->

View File

@ -23,7 +23,7 @@ define [
events:
'click a.switch_views': 'switchViews'
'click .delete_page': 'deleteWikiPage'
'click .form-actions .cancel': 'navigateToPageView'
'click .form-actions .cancel': 'cancel'
@optionProperty 'wiki_pages_path'
@optionProperty 'WIKI_RIGHTS'
@ -59,6 +59,8 @@ define [
wikiSidebar.init()
$.scrollSidebar()
wikiSidebar.attachToEditor(@$wikiPageBody).show()
$ ->
wikiSidebar.show()
switchViews: (event) ->
event?.preventDefault()
@ -79,10 +81,9 @@ define [
errors
navigateToPageView: (event) ->
cancel: (event) ->
event?.preventDefault()
html_url = @model.get('html_url')
window.location.href = html_url if html_url
@trigger('cancel')
deleteWikiPage: (event) ->
event?.preventDefault()

View File

@ -10,6 +10,7 @@ define [
@mixin
template: template
tagName: 'tr'
className: 'clickable'
attributes:
role: 'row'
els:

View File

@ -1,17 +1,19 @@
define [
'jquery'
'wikiSidebar'
'compiled/models/WikiPage'
'compiled/views/PaginatedCollectionView'
'compiled/views/wiki/WikiPageEditView'
'compiled/views/wiki/WikiPageIndexItemView'
'jst/wiki/WikiPageIndex'
'jquery'
'compiled/views/StickyHeaderMixin'
'compiled/str/splitAssetString'
'jquery.disableWhileLoading'
], (PaginatedCollectionView, itemView, template,$, StickyHeaderMixin, splitAssetString) ->
], ($, wikiSidebar, WikiPage, PaginatedCollectionView, WikiPageEditView, itemView, template, StickyHeaderMixin, splitAssetString) ->
class WikiPageIndexView extends PaginatedCollectionView
@mixin StickyHeaderMixin
@mixin
el: '#content'
template: template
itemView: itemView
@ -19,6 +21,11 @@ define [
'click .new_page': 'createNewPage'
'click .canvas-sortable-header-row a[data-sort-field]': 'sort'
els:
'.no-pages': '$noPages'
'.no-pages a:first-child': '$noPagesLink'
@optionProperty 'default_editing_roles'
@optionProperty 'WIKI_RIGHTS'
initialize: (options) ->
@ -37,10 +44,14 @@ define [
@itemViewOptions ||= {}
@itemViewOptions.WIKI_RIGHTS = @WIKI_RIGHTS
contextAssetString = options?.contextAssetString
[@contextName, @contextId] = splitAssetString(contextAssetString) if contextAssetString
@contextAssetString = options?.contextAssetString
[@contextName, @contextId] = splitAssetString(@contextAssetString) if @contextAssetString
@itemViewOptions.contextName = @contextName
afterRender: ->
super
@$noPages.redirectClickTo(@$noPagesLink)
sort: (event) ->
currentTarget = $(event.currentTarget)
currentSortField = @collection.options.params?.sort or "title"
@ -59,7 +70,30 @@ define [
createNewPage: (ev) ->
ev?.preventDefault()
alert('This will eventually create a new page')
@$el.hide()
$('body').removeClass('index')
$('body').addClass('edit')
@editModel = new WikiPage {editing_roles: @default_editing_roles}, contextAssetString: @contextAssetString
@editView = new WikiPageEditView
model: @editModel
wiki_pages_path: ENV.WIKI_PAGES_PATH
WIKI_RIGHTS: ENV.WIKI_RIGHTS
PAGE_RIGHTS:
update: ENV.WIKI_RIGHTS.update_page
update_content: ENV.WIKI_RIGHTS.update_page_content
@$el.parent().append(@editView.$el)
@editView.render()
# override the cancel behavior
@editView.on 'cancel', =>
@editView.$el.remove()
wikiSidebar.hide()
$('body').removeClass('edit')
$('body').addClass('index')
@$el.show()
toJSON: ->
json = super

View File

@ -1001,14 +1001,23 @@ class ApplicationController < ActionController::Base
:title => page_name.titleize,
:url => page_name.to_url
)
if @page.new_record?
if @domain_root_account.enable_draft? && !@context.is_a?(Group)
@page.workflow_state = 'unpublished'
else
@page.workflow_state = 'active'
end
initialize_wiki_page
end
# Initializes the state of @page, but only if it is a new page
def initialize_wiki_page
return unless @page.new_record? || @page.deleted?
is_privileged_user = is_authorized_action?(@page.wiki, @current_user, :manage)
if is_privileged_user && @domain_root_account.enable_draft? && !@context.is_a?(Group)
@page.workflow_state = 'unpublished'
else
@page.workflow_state = 'active'
end
if @page.is_front_page? && @page.new_record?
@page.editing_roles = (@context.default_wiki_editing_roles rescue nil) || @page.default_roles
if @page.is_front_page?
@page.body = t "#application.wiki_front_page_default_content_course", "Welcome to your new course wiki!" if @context.is_a?(Course)
@page.body = t "#application.wiki_front_page_default_content_group", "Welcome to your new group wiki!" if @context.is_a?(Group)
end

View File

@ -267,6 +267,8 @@ class WikiPagesApiController < ApplicationController
end
def get_update_params(allowed_fields=Set[])
initialize_wiki_page
# normalize parameters
page_params = params[:wiki_page] || {}

View File

@ -96,11 +96,8 @@ class WikiPagesController < ApplicationController
end
def perform_update
if @page.deleted? && @domain_root_account.enable_draft? && !@context.is_a?(Group)
@page.workflow_state = 'unpublished'
elsif @page.deleted?
@page.workflow_state = 'active'
end
initialize_wiki_page
if @page.update_attributes(params[:wiki_page].merge(:user_id => @current_user.id))
log_asset_access(@page, "wiki", @wiki, 'participate')
generate_new_page_view
@ -207,6 +204,7 @@ class WikiPagesController < ApplicationController
def set_js_wiki_data
hash = {}
hash[:DEFAULT_EDITING_ROLES] = @context.default_wiki_editing_roles if @context.respond_to?(:default_wiki_editing_roles)
hash[:WIKI_PAGES_PATH] = polymorphic_path([@context, :pages])
if @page

View File

@ -95,7 +95,7 @@ $shadow: 0 1px 0 rgba(0,0,0,0.15)
:background $item-background
:text-decoration inherit
:color inherit
&:hover
&.clickable:hover
:background $item-hover-background
:text-decoration inherit
:color inherit
@ -136,6 +136,9 @@ $shadow: 0 1px 0 rgba(0,0,0,0.15)
.icon-unpublished
:color $unpublished-icon-color
.table .no-pages .no-pages-cell
:border 1px dashed $border-color
.pages.show
.toolbar-buttons
.publish-button
@ -158,6 +161,9 @@ $shadow: 0 1px 0 rgba(0,0,0,0.15)
:color $published-text-color
.unpublished
:color $unpublished-text-color
.published, .unpublished
:display inline-block
:margin 5px 8px 5px 5px
.edit-form
:margin 0

View File

@ -25,12 +25,12 @@
<div class="edit-content">
<div class="edit-header">
{{#if PAGE_RIGHTS.update}}
{{#ifAny new_record PAGE_RIGHTS.update}}
<label for="wiki_page[title]" class="screenreader-only">{{#t "title_label"}}Page Title{{/t}}</label>
<input id="wiki_page[title]" name="wiki_page[title]" type="text" class="span4 title" value="{{title}}" autofocus>
<input id="wiki_page[title]" name="wiki_page[title]" type="text" class="span4 title" value="{{title}}" maxlength="255" autofocus>
{{else}}
<h2>{{title}}</h2>
{{/if}}
{{/ifAny}}
<a href="#" class="switch_views">{{#t "#editor.switch_views"}}Switch Views{{/t}}</a>
</div>
@ -72,7 +72,7 @@
<input id="notify_of_update" type="checkbox" name="wiki_page[notify_of_update]">
{{#t "notify_users_text"}}Notify users that this content has changed{{/t}}
</label>
<button class="btn cancel">{{#t "buttons.cancel"}}Cancel{{/t}}</button>
<a class="btn cancel" tabindex="0" role="button">{{#t "buttons.cancel"}}Cancel{{/t}}</a>
<button class="btn btn-primary submit">{{#t "buttons.save"}}Save{{/t}}</button>
</div>
</div>

View File

@ -1,7 +1,7 @@
<div class="toolbar-buttons clearfix" data-sticky>
<div class="right-buttons">
{{#if WIKI_RIGHTS.create_page}}
<button class="btn btn-primary new_page">{{#t 'buttons.new_page'}}New Page{{/t}}</button>
<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}}
</div>
</div>
@ -29,7 +29,7 @@
<tbody class="collectionViewItems">
{{#if fetched}}
{{#unless collection.length}}
<tr class="no-pages"><td colspan="{{#if WIKI_RIGHTS.manage}}5{{else}}3{{/if}}">{{#t 'no_pages'}}No pages created yet.{{/t}} <a class="new_page" href="#">{{#t 'add_page'}}Add one!{{/t}}</a></td></tr>
<tr class="no-pages{{#if WIKI_RIGHTS.create_page}} clickable{{/if}}"><td class="no-pages-cell" colspan="{{#if WIKI_RIGHTS.manage}}5{{else}}3{{/if}}">{{#t 'no_pages'}}No pages created yet.{{/t}}{{#if WIKI_RIGHTS.create_page}} <a class="new_page" href="#">{{#t 'add_page'}}Add one!{{/t}}</a>{{/if}}</td></tr>
{{/unless}}
{{/if}}
</tbody>

View File

@ -8,8 +8,4 @@
<% if reason = @page.locked_for?(@current_user, :context => @context) %>
<h2><%= @page.title %></h2>
<%= lock_explanation(reason, 'page', @context) %>
<% else %>
<div id="wiki_page_edit"></div>
<% end %>
<%= render :partial => "shared/sequence_footer", :locals => {:asset => @page} if @page.context_module_tag_for(@context) %>

View File

@ -1,4 +1,6 @@
<%
content_for :page_title, join_title(@context.name, t('titles.pages', 'Pages'))
content_for :right_side, render(:partial => "shared/wiki_sidebar")
jammit_css :tinymce
js_bundle :wiki_page_index
%>

View File

@ -194,4 +194,210 @@ describe ApplicationController do
@controller.send(:complete_request_uri).should == "https://example.com/api/v1/courses?password=[FILTERED]&test=5&Xaccess_token=13&access_token=[FILTERED]"
end
end
describe 'initialize_wiki_page' do
context 'course' do
before(:each) do
@domain_root_account = mock()
@stub_enable_draft = @domain_root_account.stubs(:enable_draft?)
course_with_teacher_logged_in
@page = @course.wiki.wiki_pages.build(:title => 'Front Page', :url => 'front-page')
@controller.instance_variable_set(:@domain_root_account, @domain_root_account)
@controller.instance_variable_set(:@current_user, @teacher)
@controller.instance_variable_set(:@context, @course)
@controller.instance_variable_set(:@wiki, @course.wiki)
@controller.instance_variable_set(:@page, @page)
end
it 'should set the front page body' do
@page.body.should be_nil
@controller.send :initialize_wiki_page
@page.body.should_not be_empty
end
context 'draft not enabled' do
before(:each) do
@stub_enable_draft.returns(false)
end
it 'should initialize a new page' do
@page.should be_new_record
@page.expects(:workflow_state=).with('active')
@controller.send :initialize_wiki_page
end
it 'should initialize a deleted page' do
@page.workflow_state = 'deleted'
@page.save!
@page.should be_deleted
@page.expects(:workflow_state=).with('active')
@controller.send :initialize_wiki_page
end
it 'should not initialize an unpublished page' do
@page.workflow_state = 'unpublished'
@page.save!
@page.should be_unpublished
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
it 'should not initialize an active page' do
@page.workflow_state = 'active'
@page.save!
@page.should be_active
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
end
context 'draft enabled' do
before(:each) do
@stub_enable_draft.returns(true)
end
it 'should initialize a new page' do
@page.should be_new_record
@page.expects(:workflow_state=).with('unpublished')
@controller.send :initialize_wiki_page
end
it 'should initialize a deleted page' do
@page.workflow_state = 'deleted'
@page.save!
@page.should be_deleted
@page.expects(:workflow_state=).with('unpublished')
@controller.send :initialize_wiki_page
end
it 'should not initialize an unpublished page' do
@page.workflow_state = 'unpublished'
@page.save!
@page.should be_unpublished
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
it 'should not initialize an active page' do
@page.workflow_state = 'active'
@page.save!
@page.should be_active
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
end
end
context 'group' do
before(:each) do
@domain_root_account = mock()
@stub_enable_draft = @domain_root_account.stubs(:enable_draft?)
group_with_user_logged_in
@page = @group.wiki.wiki_pages.build(:title => 'Front Page', :url => 'front-page')
@controller.instance_variable_set(:@domain_root_account, @domain_root_account)
@controller.instance_variable_set(:@current_user, @user)
@controller.instance_variable_set(:@context, @group)
@controller.instance_variable_set(:@wiki, @group.wiki)
@controller.instance_variable_set(:@page, @page)
end
it 'should set the front page body' do
@page.body.should be_nil
@controller.send :initialize_wiki_page
@page.body.should_not be_empty
end
context 'draft not enabled' do
before(:each) do
@stub_enable_draft.returns(false)
end
it 'should initialize a new page' do
@page.should be_new_record
@page.expects(:workflow_state=).with('active')
@controller.send :initialize_wiki_page
end
it 'should initialize a deleted page' do
@page.workflow_state = 'deleted'
@page.save!
@page.should be_deleted
@page.expects(:workflow_state=).with('active')
@controller.send :initialize_wiki_page
end
it 'should not initialize an unpublished page' do
@page.workflow_state = 'unpublished'
@page.save!
@page.should be_unpublished
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
it 'should not initialize an active page' do
@page.workflow_state = 'active'
@page.save!
@page.should be_active
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
end
context 'draft enabled' do
before(:each) do
@stub_enable_draft.returns(true)
end
it 'should initialize a new page' do
@page.should be_new_record
@page.expects(:workflow_state=).with('active')
@controller.send :initialize_wiki_page
end
it 'should initialize a deleted page' do
@page.workflow_state = 'deleted'
@page.save!
@page.should be_deleted
@page.expects(:workflow_state=).with('active')
@controller.send :initialize_wiki_page
end
it 'should not initialize an unpublished page' do
@page.workflow_state = 'unpublished'
@page.save!
@page.should be_unpublished
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
it 'should not initialize an active page' do
@page.workflow_state = 'active'
@page.save!
@page.should be_active
@page.expects(:workflow_state=).never
@controller.send :initialize_wiki_page
end
end
end
end
end

View File

@ -12,11 +12,11 @@ describe "Navigating to wiki pages" do
wikiPage = @course.wiki.wiki_pages.create!(:title => "Foo")
edit_url = course_edit_named_page_url(@course, wikiPage)
get course_named_page_path(@course, wikiPage)
f(".edit-wiki").click
wait_for_dom_ready do
check_domready.should be_true
driver.current_url.should == edit_url
expect_new_page_load do
f(".edit-wiki").click
end
driver.current_url.should == edit_url
end
end
end