MoveItemTray.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (C) 2017 - present Instructure, Inc.
  3. *
  4. * This file is part of Canvas.
  5. *
  6. * Canvas is free software: you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License as published by the Free
  8. * Software Foundation, version 3 of the License.
  9. *
  10. * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
  11. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. * details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. import I18n from 'i18n!move_item_tray'
  19. import axios from 'axios'
  20. import React from 'react'
  21. import { string, func } from 'prop-types'
  22. import Tray from 'instructure-ui/lib/components/Tray'
  23. import Heading from 'instructure-ui/lib/components/Heading'
  24. import Container from 'instructure-ui/lib/components/Container'
  25. import { showFlashError } from 'jsx/shared/FlashAlert'
  26. import { itemShape, moveOptionsType } from './propTypes'
  27. import MoveSelect from './MoveSelect'
  28. export default class MoveItemTray extends React.Component {
  29. static propTypes = {
  30. title: string,
  31. item: itemShape.isRequired,
  32. moveOptions: moveOptionsType.isRequired,
  33. focusOnExit: func,
  34. formatSaveUrl: func,
  35. formatSaveData: func,
  36. onMoveSuccess: func,
  37. onExited: func,
  38. applicationElement: func,
  39. }
  40. static defaultProps = {
  41. title: I18n.t('Move Item'),
  42. focusOnExit: () => null,
  43. formatSaveUrl: () => null,
  44. formatSaveData: (order) => ({ order: order.join(',') }),
  45. onExited: () => {},
  46. onMoveSuccess: () => {},
  47. applicationElement: () => document.getElementById('application'),
  48. }
  49. state = {
  50. open: true,
  51. }
  52. onExited = () => {
  53. setTimeout(() => {
  54. const focusTo = this.props.focusOnExit(this.props.item)
  55. if (focusTo) focusTo.focus()
  56. })
  57. if (this.props.onExited) this.props.onExited()
  58. }
  59. onMoveSelect = ({ order, itemId, groupId }) => {
  60. const saveUrl = this.props.formatSaveUrl({ itemId, groupId })
  61. const promise = saveUrl
  62. ? axios.post(saveUrl, this.props.formatSaveData(order))
  63. : Promise.resolve({ data: order })
  64. promise.then(res => {
  65. this.props.onMoveSuccess({ data: res.data, groupId, itemId })
  66. this.close()
  67. })
  68. .catch(showFlashError(I18n.t('Move Item Failed')))
  69. }
  70. open = () => {
  71. this.setState({ open: true })
  72. }
  73. close = () => {
  74. this.setState({ open: false })
  75. }
  76. render () {
  77. return (
  78. <Tray
  79. label={this.props.title}
  80. open={this.state.open}
  81. onDismiss={this.close}
  82. onExited={this.onExited}
  83. closeButtonLabel={I18n.t('close move tray')}
  84. placement="end"
  85. applicationElement={this.props.applicationElement}
  86. closeButtonVariant="icon"
  87. shouldContainFocus>
  88. <Heading margin="small xx-large" level="h4">{this.props.title}</Heading>
  89. <Container display="block" padding="medium medium large">
  90. <MoveSelect
  91. item={this.props.item}
  92. moveOptions={this.props.moveOptions}
  93. onSelect={this.onMoveSelect}
  94. />
  95. </Container>
  96. </Tray>
  97. )
  98. }
  99. }