PageHeader.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import React from 'react';
  2. import { observer } from 'mobx-react';
  3. import { NavModel, NavModelItem } from '../../nav_model_srv';
  4. import classNames from 'classnames';
  5. import appEvents from 'app/core/app_events';
  6. export interface IProps {
  7. model: NavModel;
  8. }
  9. const SelectNav = observer(({ main, customCss }: { main: NavModelItem; customCss: string }) => {
  10. const defaultSelectedItem = main.children.find(navItem => {
  11. return navItem.active === true;
  12. });
  13. const gotoUrl = evt => {
  14. var element = evt.target;
  15. var url = element.options[element.selectedIndex].value;
  16. appEvents.emit('location-change', { href: url });
  17. };
  18. return (
  19. <div className={`gf-form-select-wrapper width-20 ${customCss}`}>
  20. <label className={`gf-form-select-icon ${defaultSelectedItem.icon}`} htmlFor="page-header-select-nav" />
  21. {/* Label to make it clickable */}
  22. <select
  23. className="gf-select-nav gf-form-input"
  24. value={defaultSelectedItem.url}
  25. onChange={gotoUrl}
  26. id="page-header-select-nav"
  27. >
  28. {main.children.map((navItem: NavModelItem) => {
  29. if (navItem.hideFromTabs) {
  30. // TODO: Rename hideFromTabs => hideFromNav
  31. return null;
  32. }
  33. return (
  34. <option key={navItem.url} value={navItem.url}>
  35. {navItem.text}
  36. </option>
  37. );
  38. })}
  39. </select>
  40. </div>
  41. );
  42. });
  43. const Tabs = observer(({ main, customCss }: { main: NavModelItem; customCss: string }) => {
  44. return (
  45. <ul className={`gf-tabs ${customCss}`}>
  46. {main.children.map((tab, idx) => {
  47. if (tab.hideFromTabs) {
  48. return null;
  49. }
  50. const tabClasses = classNames({
  51. 'gf-tabs-link': true,
  52. active: tab.active,
  53. });
  54. return (
  55. <li className="gf-tabs-item" key={tab.url}>
  56. <a className={tabClasses} target={tab.target} href={tab.url}>
  57. <i className={tab.icon} />
  58. {tab.text}
  59. </a>
  60. </li>
  61. );
  62. })}
  63. </ul>
  64. );
  65. });
  66. const Navigation = ({ main }: { main: NavModelItem }) => {
  67. return (
  68. <nav>
  69. <SelectNav customCss="page-header__select-nav" main={main} />
  70. <Tabs customCss="page-header__tabs" main={main} />
  71. </nav>
  72. );
  73. };
  74. @observer
  75. export default class PageHeader extends React.Component<IProps, any> {
  76. constructor(props) {
  77. super(props);
  78. }
  79. renderTitle(title: string, breadcrumbs: any[]) {
  80. if (!title && (!breadcrumbs || breadcrumbs.length === 0)) {
  81. return null;
  82. }
  83. if (!breadcrumbs || breadcrumbs.length === 0) {
  84. return <h1 className="page-header__title">{title}</h1>;
  85. }
  86. const breadcrumbsResult = [];
  87. for (let i = 0; i < breadcrumbs.length; i++) {
  88. const bc = breadcrumbs[i];
  89. if (bc.url) {
  90. breadcrumbsResult.push(
  91. <a className="text-link" key={i} href={bc.url}>
  92. {bc.title}
  93. </a>
  94. );
  95. } else {
  96. breadcrumbsResult.push(<span key={i}> / {bc.title}</span>);
  97. }
  98. }
  99. breadcrumbsResult.push(<span key={breadcrumbs.length + 1}> / {title}</span>);
  100. return <h1 className="page-header__title">{breadcrumbsResult}</h1>;
  101. }
  102. renderHeaderTitle(main) {
  103. return (
  104. <div className="page-header__inner">
  105. <span className="page-header__logo">
  106. {main.icon && <i className={`page-header__icon ${main.icon}`} />}
  107. {main.img && <img className="page-header__img" src={main.img} />}
  108. </span>
  109. <div className="page-header__info-block">
  110. {this.renderTitle(main.text, main.breadcrumbs)}
  111. {main.subTitle && <div className="page-header__sub-title">{main.subTitle}</div>}
  112. {main.subType && (
  113. <div className="page-header__stamps">
  114. <i className={main.subType.icon} />
  115. {main.subType.text}
  116. </div>
  117. )}
  118. </div>
  119. </div>
  120. );
  121. }
  122. render() {
  123. const { model } = this.props;
  124. if (!model) {
  125. return null;
  126. }
  127. return (
  128. <div className="page-header-canvas">
  129. <div className="page-container">
  130. <div className="page-header">
  131. {this.renderHeaderTitle(model.main)}
  132. {model.main.children && <Navigation main={model.main} />}
  133. </div>
  134. </div>
  135. </div>
  136. );
  137. }
  138. }