github.com/replicatedhq/ship@v0.55.0/web/init/src/components/shared/Sidebar.jsx (about)

     1  import * as React from "react";
     2  import assign from "object-assign";
     3  import SidebarItem from "./SidebarItem";
     4  
     5  export default class Sidebar extends React.Component {
     6    constructor() {
     7      super();
     8      this.state = {
     9        activeSub: "",
    10      }
    11    }
    12  
    13    isActive = (link, pathname = "") => {
    14      if (!link) return false;
    15      return pathname.indexOf(`${link}`) > -1;
    16    }
    17  
    18    buildSubItems = (items) => {
    19      const { activeSub } = this.state;
    20      const _items = items.filter(Boolean).map((item) => {
    21        return assign(item, {
    22          isActive: activeSub === item.id,
    23        });
    24      });
    25      return _items;
    26    }
    27  
    28    getSidebarItems = (configOnly) => {
    29      if (configOnly) {
    30        const { configRouteId } = this.props;
    31        return [{
    32          id: 0,
    33          linkTo: `/${configRouteId}`,
    34          label: "Application settings",
    35          position: "top",
    36          subItems: this.buildSubItems(this.props.appSettingsFieldsList)
    37        },
    38        ];
    39      } else {
    40        return [{
    41          id: 0,
    42          linkTo: "/config",
    43          label: "Application settings",
    44          position: "top",
    45          subItems: this.buildSubItems(this.props.appSettingsFieldsList)
    46        }, {
    47          id: 1,
    48          linkTo: `/support`,
    49          label: "Support",
    50          position: "top",
    51        }, {
    52          id: 2,
    53          linkTo: `/cluster`,
    54          label: "Cluster",
    55          position: "top",
    56        }, {
    57          id: 4,
    58          linkTo: `/releases`,
    59          label: "Releases",
    60          position: "top",
    61        }, {
    62          id: 5,
    63          linkTo: `/snapshots`,
    64          label: "Snapshots",
    65          position: "top",
    66        }, {
    67          id: 6,
    68          linkTo: `/view-license`,
    69          label: "View license",
    70          position: "top",
    71        }, {
    72          id: 7,
    73          linkTo: `/console-settings`,
    74          label: "Console settings",
    75          position: "top",
    76          subItems: this.buildSubItems(this.props.consoleSettingsFieldsList)
    77        },
    78        ];
    79      }
    80    }
    81  
    82    scrollToSection = (id) => {
    83      const el = document.getElementById(id);
    84      if (!el) return;
    85      setTimeout(() => {
    86        el.scrollIntoView({ behavior: "smooth", block: "start" });
    87        this.setState({ activeSub: id });
    88      }, 50);
    89    }
    90  
    91    componentDidUpdate(lastProps) {
    92      const { location } = this.props;
    93      if (lastProps.location.hash !== location.hash && location.hash) {
    94        this.scrollToSection(location.hash.replace("#", ""));
    95      }
    96    }
    97  
    98    onClick = (item) => {
    99      this.setState({ route: item.linkTo });
   100      if (item.subItems) {
   101        this.setState({ activeSub: "" });
   102      }
   103      return (e, ...rest) => {
   104        if (typeof item.onClick === "function") {
   105          item.onClick(e, ...rest);
   106          return;
   107        }
   108      };
   109    }
   110  
   111    render() {
   112      const { configOnly } = this.props;
   113      const items = this.getSidebarItems(configOnly);
   114      const sidebarItems = items.map(item => {
   115        const active = this.isActive(item.linkTo, window.location.pathname);
   116        return assign(item, {
   117          isActive: active,
   118        });
   119      });
   120      const renderItem = item => {
   121        return (
   122          <div key={item.id}>
   123            <SidebarItem
   124              {...item}
   125              onClick={() => this.onClick(item)}
   126            />
   127            {item.isActive && item.subItems ?
   128              item.subItems.map((item) => (
   129                <SidebarItem
   130                  key={item.id}
   131                  className="SubItem"
   132                  activeSub={this.state.activeSub}
   133                  subItemLinkTo={`${this.props.location.pathname}#${item.id}`}
   134                  {...item}
   135                  onClick={() => this.scrollToSection(item.id)}
   136                />
   137              ))
   138              : null}
   139          </div>
   140        );
   141      };
   142  
   143      return (
   144        <div className="SidebarContent-wrapper flex flex1 u-minHeight--full">
   145          <div className="flex-column u-width--full">
   146            <div className="SidebarElements-wrapper flex-column flex-1-auto u-overflow--auto">
   147              {sidebarItems
   148                .filter(i => i.position === "top")
   149                .map(renderItem)
   150              }
   151            </div>
   152          </div>
   153        </div>
   154      );
   155    }
   156  }