dialog adapter accepts content and buttons

closes CNVS-14912

test plan:
  - vist new files
  - verify that restriction modal still displays correctly
  - verify that name conflict modal (when adding files) continues to
    work

Conflicts:
	app/coffeescripts/react_files/components/DialogAdapter.coffee

Change-Id: Iedfde2bc15733b3bb90639f2f8bf5582d0f5d139
Reviewed-on: https://gerrit.instructure.com/39640
Reviewed-by: Sterling Cobb <sterling@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Product-Review: Jason Madsen <jmadsen@instructure.com>
QA-Review: Jason Madsen <jmadsen@instructure.com>
This commit is contained in:
Jason Madsen 2014-08-19 14:53:18 -06:00
parent 73e07a9f10
commit 2df699e137
9 changed files with 123 additions and 39 deletions

View File

@ -3,9 +3,11 @@ define [
'react'
'compiled/react/shared/utils/withReactDOM'
'i18n!restrict_student_access'
'./DialogContent'
'./DialogButtons'
'jqueryui/dialog'
], ($, React, withReactDOM, I18n) ->
], ($, React, withReactDOM, I18n, DialogContent, DialogButtons) ->
DialogAdapter = React.createClass
propTypes:
open: React.PropTypes.bool.isRequired
@ -23,17 +25,45 @@ define [
handlePropsChanged: (props) ->
props ?= @props
React.renderComponent(
React.Children.only(props.children),
@node
)
@forceBuildDialog(props)
if props.open
@dialog.open()
else
@dialog.close()
forceBuildDialog: (props) ->
content = null
buttons = null
if React.Children.count(props.children) == 1
content = props.children
else
{content, buttons} = @processMultipleChildren(props)
@addContent(content)
@addButtons(buttons)
processMultipleChildren: (props) ->
content = null
buttons = null
React.Children.forEach props.children, (child) ->
if child.type == DialogContent.type
content = child
if child.type == DialogButtons.type
buttons = child
{content: content, buttons: buttons}
addContent: (content) ->
React.renderComponent(content, @node)
addButtons: (buttons) ->
# hack to get buttons to render to buttonset ui
if buttons?
buttonSet = $(@node).parent().find('.ui-dialog-buttonset').html('').get(0)
React.renderComponent(buttons, buttonSet)
else
$(@node).parent().find('.ui-dialog-buttonpane').hide()
componentWillUnmount: ->
@dialog.destroy()
@ -46,6 +76,7 @@ define [
open: @props.onOpen
title: @props.title
autoOpen: false
buttons: [{text: ''}] # force buttonset ui to be created
@dialog = $(@node).dialog(options).data('dialog')
@handlePropsChanged()

View File

@ -0,0 +1,9 @@
define [
'react'
'compiled/react/shared/utils/withReactDOM'
], (React, withReactDOM) ->
DialogButtons = React.createClass
render: withReactDOM ->
div {}, @props.children

View File

@ -0,0 +1,9 @@
define [
'react'
'compiled/react/shared/utils/withReactDOM'
], (React, withReactDOM) ->
DialogContent = React.createClass
render: withReactDOM ->
div {}, @props.children

View File

@ -2,7 +2,10 @@ define [
'i18n!file_rename_form'
'react'
'compiled/react/shared/utils/withReactDOM'
], (I18n, React, withReactDOM) ->
'./DialogAdapter'
'./DialogContent'
'./DialogButtons'
], (I18n, React, withReactDOM, DialogAdapter, DialogContent, DialogButtons) ->
FileRenameForm = React.createClass
@ -31,27 +34,54 @@ define [
handleChangeClick: ->
@props.onNameConflictResolved({file: @state.fileOptions.file, dup: 'rename', name: @refs.newName.getDOMNode().value})
handleFormSubmit: (e) ->
e.preventDefault()
@handleChangeClick()
getPrompt: withReactDOM ->
buildContent: withReactDOM ->
nameToUse = @state.fileOptions?.name || @state.fileOptions?.file.name
div {},
p {}, I18n.t('message','An item named "%{name}" already existings in this location. Do you want to replace the existing file?', {name: nameToUse})
button ref: 'renameBtn' ,onClick: @handleRenameClick, (I18n.t('change_name', 'Change Name'))
button ref: 'replaceBtn', onClick: @handleReplaceClick, (I18n.t('replace', 'Replace'))
if !@state.isEditing
div {},
p {}, I18n.t('message','An item named "%{name}" already existings in this location. Do you want to replace the existing file?', {name: nameToUse})
else
div {},
p {}, I18n.t('prompt', 'Changee "%{name}" to', {name: nameToUse})
form onSubmit: @handleFormSubmit,
label className: 'file-rename-form__form-label',
I18n.t('name', 'Name')
input type: 'text', defaultValue: nameToUse, ref: 'newName'
buildButtons: withReactDOM ->
if !@state.isEditing
div {},
button
ref: 'renameBtn'
className: 'btn'
onClick: @handleRenameClick,
(I18n.t('change_name', 'Change Name'))
button
ref: 'replaceBtn'
className: 'btn btn-primary'
onClick: @handleReplaceClick,
(I18n.t('replace', 'Replace'))
else
div {},
button
ref: 'backBtn'
className: 'btn'
onClick: @handleBackClick,
I18n.t('back', 'Back')
button
ref: 'commitChangeBtn'
className: 'btn btn-primary'
onClick: @handleChangeClick,
I18n.t('change', 'Change')
getForm: withReactDOM ->
nameToUse = @state.fileOptions?.name || @state.fileOptions?.file.name
div {},
p {}, I18n.t('prompt', 'Changee "%{name}" to', {name: nameToUse})
label {}, I18n.t('name', 'Name')
input type: 'text', defaultValue: nameToUse, ref: 'newName'
button ref: 'backBtn', onClick: @handleBackClick, I18n.t('back', 'Back')
button ref: 'commitChangeBtn', onClick: @handleChangeClick, I18n.t('change', 'Change')
render: withReactDOM ->
div {},
if !@state.isEditing
@getPrompt()
else
@getForm()
DialogAdapter open: @props.fileOptions?, title: I18n.t('rename_title', 'Copy'), onClose: @props.onClose,
DialogContent {},
@buildContent()
DialogButtons {},
@buildButtons()

View File

@ -7,7 +7,9 @@ define [
'./RestrictedDialogForm'
'./DialogAdapter'
'i18n!react_files'
], (React, withReactDOM, preventDefault, Folder, File, RestrictedDialogForm, $DialogAdapter, I18n) ->
'./DialogContent'
'./DialogButtons'
], (React, withReactDOM, preventDefault, Folder, File, RestrictedDialogForm, $DialogAdapter, I18n, DialogContent, DialogButtons) ->
# Expects @props.model to be either a folder or a file collection/backbone model
ItemCog = React.createClass
@ -40,7 +42,11 @@ define [
div null,
$DialogAdapter open: @state.restrictedDialogOpen, title: I18n.t("title.limit_student_access", "Limit student access"),
RestrictedDialogForm closeDialog: @closeRestrictedDialog
DialogContent {},
RestrictedDialogForm {}
DialogButtons {},
input type: 'button', onClick: @closeRestrictedDialog, className: "btn", value: I18n.t("button_text.cancel", "Cancel")
input type: "submit", className: "btn btn-primary", value: I18n.t("button_text.update", "Update")
div className:'ef-hover-options',
a href:'#', className: 'adminCog-download-link',

View File

@ -9,9 +9,6 @@ define [
getInitialState: ->
calendarOption: false
propTypes:
closeDialog: React.PropTypes.func.isRequired
handleSubmit: (event) ->
event.preventDefault()
@ -36,7 +33,7 @@ define [
render: withReactDOM ->
form onSubmit: this.handleSubmit, className: 'form-horizontal form-dialog', title: I18n.t("title.limit_student_access", "Limit student access"),
form onSubmit: this.handleSubmit, className: 'form-horizontal', title: I18n.t("title.limit_student_access", "Limit student access"),
div className: "radio",
label {},
input type: 'radio', name: 'restrict_access', value: 'true', onChange: @radioSelected, defaultChecked: true
@ -49,10 +46,6 @@ define [
@displayOption()
div className:"form-controls",
input type: 'button', onClick: @props.closeDialog, className: "btn", value: I18n.t("button_text.cancel", "Cancel")
input type: "submit", className: "btn btn-primary", value: I18n.t("button_text.update", "Update")
displayOption: ->
if @state.calendarOption
[

View File

@ -96,5 +96,4 @@ define [
button className:'btn btn-primary', onClick: @handleAddFilesClick,
i className:'icon-plus'
I18n.t('files', 'Files')
DialogAdapter open: @state.nameCollisions[0]?, title: I18n.t('rename_title', 'Copy'), onClose: @onClose,
FileRenameForm fileOptions: @state.nameCollisions[0], onNameConflictResolved: @onNameConflictResolved
FileRenameForm fileOptions: @state.nameCollisions[0], onNameConflictResolved: @onNameConflictResolved, onClose: @onClose

View File

@ -307,3 +307,8 @@ $border: #e5e4e4;
top: 0;
right: 0;
}
.file-rename-form__form-label {
float: left;
margin-top: 5px;
padding-right: 5px;
}

View File

@ -18,7 +18,9 @@ define [
@form = React.renderComponent(FileRenameForm(props), $('<div>').appendTo('body')[0])
teardown: ->
React.unmountComponentAtNode(@form.getDOMNode().parentNode)
#TODO: oddness with the current modal implementation makes teardown not work
#as the DOM has been mutated. Hopefully we can ease this pain with a react modal
#React.unmountComponentAtNode(@form.getDOMNode().parentNode)
test 'switches to editing file name state with button click', ->
Simulate.click(@form.refs.renameBtn.getDOMNode())