<commit_before>/*
 * Copyright (C) 2017 - 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 I18n from 'i18n!shared_components'
import React, { Component } from 'react'
import { bool, node, string, func, shape, arrayOf, oneOf } from 'prop-types'
import cx from 'classnames'

import Heading from '@instructure/ui-core/lib/components/Heading'
import Checkbox from '@instructure/ui-core/lib/components/Checkbox'
import Container from '@instructure/ui-core/lib/components/Container'
import Avatar from '@instructure/ui-core/lib/components/Avatar'
import Badge from '@instructure/ui-core/lib/components/Badge'
import ScreenReaderContent from '@instructure/ui-core/lib/components/ScreenReaderContent'
import Text from '@instructure/ui-core/lib/components/Text'
import Button from '@instructure/ui-core/lib/components/Button'
import PopoverMenu from '@instructure/ui-core/lib/components/PopoverMenu'
import IconMore from 'instructure-icons/lib/Line/IconMoreLine'

import IconDragHandleLine from 'instructure-icons/lib/Line/IconDragHandleLine'
import IconPeerReviewLine from 'instructure-icons/lib/Line/IconPeerReviewLine'
import LockIconView from 'compiled/views/LockIconView'
import { author as authorShape } from '../proptypes/user'
import masterCourseDataShape from '../proptypes/masterCourseData'

export default class CourseItemRow extends Component {
  static propTypes = {
    actionsContent: arrayOf(node),
    metaContent: node,
    masterCourse: shape({
      courseData: masterCourseDataShape,
      getLockOptions: func.isRequired,
    }),
    author: authorShape,
    title: string.isRequired,
    body: node,
    isDragging: bool,
    connectDragSource: func,
    connectDropTarget: func,
    id: string,
    className: string,
    itemUrl: string,
    selectable: bool,
    draggable: bool,
    defaultSelected: bool,
    isRead: bool,
    showAvatar: bool,
    onSelectedChanged: func,
    peerReview: bool,
    icon: node,
    showManageMenu: bool,
    manageMenuOptions: arrayOf(node),
    onManageMenuSelect: func,
    sectionToolTip: node,
    replyButton: node,
    focusOn: oneOf(['title', 'manageMenu']),
    clearFocusDirectives: func, // Required if focusOn is provided
    hasReadBadge: bool,
  }

  static defaultProps = {
    actionsContent: null,
    body: null,
    metaContent: null,
    masterCourse: null,
    author: {
      id: null,
      display_name: '',
      html_url: '',
      avatar_image_url: null,
    },
    id: null,
    className: '',
    isDragging: false,
    itemUrl: null,
    selectable: false,
    draggable: false,
    peerReview: false,
    defaultSelected: false,
    isRead: true,
    icon: null,
    showAvatar: false,
    connectDragSource: (component) => component,
    connectDropTarget: (component) => component,
    onSelectedChanged () {},
    showManageMenu: false,
    manageMenuOptions: [],
    onManageMenuSelect () {},
    sectionToolTip: null,
    replyButton: null,
    focusOn: null,
    clearFocusDirectives: () => {},
    hasReadBadge: false
  }

  state = {
    isSelected: this.props.defaultSelected,
  }

  componentDidMount () {
    this.onFocusManage(this.props)
  }

  componentWillReceiveProps(nextProps) {
    this.onFocusManage(nextProps)
  }

  componentWillUnmount () {
    this.unmountMasterCourseLock()
  }

  onFocusManage(props) {
    if (props.focusOn) {
      switch (props.focusOn) {
        case 'title':
          this._titleElement.focus()
          break;
        case 'manageMenu':
          this._manageMenu.focus()<commit_msg>Fix "illegal focus flash message" from showing on delete<commit_after>/*
 * Copyright (C) 2017 - 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 I18n from 'i18n!shared_components'
import React, { Component } from 'react'
import { bool, node, string, func, shape, arrayOf, oneOf } from 'prop-types'
import cx from 'classnames'

import Heading from '@instructure/ui-core/lib/components/Heading'
import Checkbox from '@instructure/ui-core/lib/components/Checkbox'
import Container from '@instructure/ui-core/lib/components/Container'
import Avatar from '@instructure/ui-core/lib/components/Avatar'
import Badge from '@instructure/ui-core/lib/components/Badge'
import ScreenReaderContent from '@instructure/ui-core/lib/components/ScreenReaderContent'
import Text from '@instructure/ui-core/lib/components/Text'
import Button from '@instructure/ui-core/lib/components/Button'
import PopoverMenu from '@instructure/ui-core/lib/components/PopoverMenu'
import IconMore from 'instructure-icons/lib/Line/IconMoreLine'

import IconDragHandleLine from 'instructure-icons/lib/Line/IconDragHandleLine'
import IconPeerReviewLine from 'instructure-icons/lib/Line/IconPeerReviewLine'
import LockIconView from 'compiled/views/LockIconView'
import { author as authorShape } from '../proptypes/user'
import masterCourseDataShape from '../proptypes/masterCourseData'

export default class CourseItemRow extends Component {
  static propTypes = {
    actionsContent: arrayOf(node),
    metaContent: node,
    masterCourse: shape({
      courseData: masterCourseDataShape,
      getLockOptions: func.isRequired,
    }),
    author: authorShape,
    title: string.isRequired,
    body: node,
    isDragging: bool,
    connectDragSource: func,
    connectDropTarget: func,
    id: string,
    className: string,
    itemUrl: string,
    selectable: bool,
    draggable: bool,
    defaultSelected: bool,
    isRead: bool,
    showAvatar: bool,
    onSelectedChanged: func,
    peerReview: bool,
    icon: node,
    showManageMenu: bool,
    manageMenuOptions: arrayOf(node),
    onManageMenuSelect: func,
    sectionToolTip: node,
    replyButton: node,
    focusOn: oneOf(['title', 'manageMenu', 'toggleButton']),
    clearFocusDirectives: func, // Required if focusOn is provided
    hasReadBadge: bool,
  }

  static defaultProps = {
    actionsContent: null,
    body: null,
    metaContent: null,
    masterCourse: null,
    author: {
      id: null,
      display_name: '',
      html_url: '',
      avatar_image_url: null,
    },
    id: null,
    className: '',
    isDragging: false,
    itemUrl: null,
    selectable: false,
    draggable: false,
    peerReview: false,
    defaultSelected: false,
    isRead: true,
    icon: null,
    showAvatar: false,
    connectDragSource: (component) => component,
    connectDropTarget: (component) => component,
    onSelectedChanged () {},
    showManageMenu: false,
    manageMenuOptions: [],
    onManageMenuSelect () {},
    sectionToolTip: null,
    replyButton: null,
    focusOn: null,
    clearFocusDirectives: () => {},
    hasReadBadge: false
  }

  state = {
    isSelected: this.props.defaultSelected,
  }

  componentDidMount () {
    this.onFocusManage(this.props)
  }

  componentWillReceiveProps(nextProps) {
    this.onFocusManage(nextProps)
  }

  componentWillUnmount () {
    this.unmountMasterCourseLock()
  }

  onFocusManage(props) {
    if (props.focusOn) {
      switch (props.focusOn) {
        case 'title':
          this._titleElement.focus()
          break;
        case 'manageMenu':
          this._manageMenu.focus()
          break;
        case 'toggleButton':
{'fraction_non_alphanumeric': 0.09891679561956909, 'fraction_numerical': 0.002142602071182002, 'mean_word_length': 3.6292011019283748, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7577650', 'n_tokens_mistral': 2495, 'n_tokens_neox': 2448, 'n_words': 697}