PageHeader.tsx 3.5 KB

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