Breadcrumbs.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (C) 2015 - 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 React from 'react'
  19. import I18n from 'i18n!react_files'
  20. import classnames from 'classnames'
  21. import Breadcrumbs from 'compiled/react_files/components/Breadcrumbs'
  22. import filesEnv from 'compiled/react_files/modules/filesEnv'
  23. import BreadcrumbCollapsedContainer from 'jsx/files/BreadcrumbCollapsedContainer'
  24. import splitAssetString from 'compiled/str/splitAssetString'
  25. var MAX_CRUMB_WIDTH = 500
  26. var MIN_CRUMB_WIDTH = 80;
  27. Breadcrumbs.renderSingleCrumb = function (folder, isLastCrumb, isRootCrumb) {
  28. const [contextType, contextId] = splitAssetString(this.props.contextAssetString, false);
  29. const isContextRoot = !!(folder && (folder.get("context_type") || "").toLowerCase() === contextType && (folder.get("context_id") || -1).toString() === contextId);
  30. const name = (isRootCrumb && isContextRoot) ? I18n.t('files', 'Files') : folder && (folder.get('custom_name') || folder.get('name'));
  31. return (
  32. <li key={name}>
  33. <a
  34. href={(isRootCrumb && isContextRoot) ? filesEnv.baseUrl : `${filesEnv.baseUrl}/folder/${(folder) ? folder.urlPath(): null}`}
  35. // only add title tooltips if there's a chance they could be ellipsized
  36. title={(this.state.maxCrumbWidth < 500) ? name : null}
  37. >
  38. <span
  39. className='ellipsis'
  40. style={{maxWidth: (isLastCrumb) ? null : this.state.maxCrumbWidth}}
  41. >
  42. {name}
  43. </span>
  44. </a>
  45. </li>
  46. );
  47. };
  48. Breadcrumbs.renderDynamicCrumbs = function () {
  49. if (this.props.showingSearchResults) {
  50. return [
  51. this.renderSingleCrumb(null, !'isLastCrumb', !!'isRootCrumb'),
  52. <li key='searchLink'>
  53. <a href="/search">
  54. <span className='ellipsis'>
  55. {this.props.query.search_term &&
  56. I18n.t('search_results_for', 'search results for "%{search_term}"', {search_term: this.props.query.search_term})
  57. }
  58. </span>
  59. </a>
  60. </li>
  61. ];
  62. } else {
  63. if (!this.props.rootTillCurrentFolder || !this.props.rootTillCurrentFolder.length) {
  64. return [];
  65. }
  66. // Formerly, in CoffeeScript [...foldersInMiddle, lastFolder] = this.props.rootTillCurrentFolder
  67. var foldersInMiddle = this.props.rootTillCurrentFolder.slice(0, this.props.rootTillCurrentFolder.length - 1)
  68. var lastFolder = this.props.rootTillCurrentFolder[this.props.rootTillCurrentFolder.length - 1]
  69. if (this.state.maxCrumbWidth > MIN_CRUMB_WIDTH) {
  70. return this.props.rootTillCurrentFolder.map((folder, i) => {
  71. return this.renderSingleCrumb(folder, folder === lastFolder, i === 0)
  72. });
  73. } else {
  74. return [
  75. <BreadcrumbCollapsedContainer foldersToContain={foldersInMiddle} />,
  76. this.renderSingleCrumb(lastFolder, true)
  77. ]
  78. }
  79. }
  80. };
  81. Breadcrumbs.render = function () {
  82. return (
  83. <nav
  84. aria-label='breadcrumbs'
  85. role='navigation'
  86. id='breadcrumbs'
  87. ref='breadcrumbs'
  88. >
  89. <ul>
  90. <li className='home'>
  91. <a href='/'>
  92. <i className='icon-home standalone-icon' title={this.state.homeName}>
  93. <span className='screenreader-only'>{this.state.homeName}</span>
  94. </i>
  95. </a>
  96. </li>
  97. <li>
  98. <a href={this.state.contextUrl}>
  99. <span className='ellipsible'>
  100. {this.state.contextName}
  101. </span>
  102. </a>
  103. </li>
  104. {this.renderDynamicCrumbs()}
  105. </ul>
  106. </nav>
  107. );
  108. };
  109. export default React.createClass(Breadcrumbs)