<commit_before><!doctype html>
<!--
  ~ Copyright 2017 <NAME>, S.A.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<template>
  <style>
    @import "css/{skin}.css";
  </style>
  <div class="btn-group" role="group">
    <div id="search-dashboard" class="dropdown">
      <input class="typeahead form-control" type="text" placeholder="Find a dashboard...">
    </div>

    <button type="button" onclick="return Utils.openFeedbackForm()" class="dropdown__button btn"><i class="fa fa-commenting-o" aria-hidden="true"></i></button>

    <div class="dropdown btn-group">
      <button id="menuBtn" class="dropdown__button btn" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
        <i class="fa fa-bars" aria-hidden="true"></i>
      </button>
      <ul class="dropdown-menu" aria-labelledby="menuBtn">
        <li class="dropdown-header">Manage</li>
        <li><a href="backoffice/index.html" onclick="return Utils.openBackOffice()"><i class="fa fa-cogs" aria-hidden="true"></i> Admin Console </a></li>
        <li rv-if="config"><a href="backoffice/index.html" onclick="return Utils.openBackOffice(Utils.getDashboardId());"><i class="fa fa-pencil-square-o" aria-hidden="true"></i> Edit this dashboard</a></li>
        <li class="dropdown-header">Recent dashboards</li>
        <li rv-each-board="recentDashboards">
          <a rv-href="board.url">{board.name}</a>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
  MGComponent({
    name: 'menu-component',
    lightDOM: true,
    parent: BaseComponent,
    attributeChangedCallback: function(
      attributeName, oldValue, newValue, namespace) {
      BaseComponent.prototype.attributeChangedCallback.call(this, arguments);
      if(attributeName === 'config') {
        this.getModel().config = JSON.parse(newValue);
      }
    },
    onCreated: function () {
      var model = this.getModel();

      var dashboardsService = Service.get(Service.types.dashboards);
      dashboardsService.addListener(function (response) {
        dashboardsService.removeListener(this);
        model.dashboards = [];
        model.dashboardMap = {};
        model.recentDashboards = [];
        if (response) {
          var dashboards = JSON.parse(response);
          var recent = getRecent();

          for (i in dashboards) {
            dashboard = dashboards[i];
            model.dashboardMap[dashboard.name] = dashboard;
            if(dashboard.displayName){
              model.dashboardMap[dashboard.displayName] = dashboard;
            }
            model.dashboards.push(dashboard.name);
          }
          for (i of recent) {
            dashboard = model.dashboardMap[i];
            if(dashboard) {
              model.recentDashboards.push({
                url: '?board=' + encodeURIComponent(dashboard.name),
                name: (dashboard.displayName || dashboard.name)
              })
            }
          }
        }

        function getRecent() {
          var recent = localStorage.recentDashboards ? JSON.parse(localStorage.recentDashboards) : [];
          var currentPos = recent.indexOf(Utils.getDashboardId());
          if (currentPos >= 0) {
            recent.splice(currentPos,1);
          }
          recent.unshift(Utils.getDashboardId());
          if (recent.length > 8) {
            recent.pop();
          }
          localStorage.recentDashboards = JSON.stringify(recent);
          return recent;
        }

        $('.typeahead').typeahead('destroy');

        var substringMatcher = function(strs) {
          return function findMatches(q, cb) {
            var matches, substringRegex;

            matches = [];

            substrRegex = new RegExp(q, 'i');

            $.each(strs, function(i, str) {
              if (substrRegex.test(str)) {
                matches.push(str);
              }
            });

            cb(matches);
          };
        };

        $('#search-dashboard .typeahead').typeahead({
          hint: true,
          highlight: true,
          minLength: 1
        },
        {
          name: 'dashboards',
          source: substringMatcher(model.dashboards),
          limit: Number.MAX_VALUE,
          templates: {<commit_msg>fix(visualization): add displayName validation to search input box<commit_after><!doctype html>
<!--
  ~ Copyright 2017 <NAME>, S.A.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<template>
  <style>
    @import "css/{skin}.css";
  </style>
  <div class="btn-group" role="group">
    <div id="search-dashboard" class="dropdown">
      <input class="typeahead form-control" type="text" placeholder="Find a dashboard...">
    </div>

    <button type="button" onclick="return Utils.openFeedbackForm()" class="dropdown__button btn"><i class="fa fa-commenting-o" aria-hidden="true"></i></button>

    <div class="dropdown btn-group">
      <button id="menuBtn" class="dropdown__button btn" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
        <i class="fa fa-bars" aria-hidden="true"></i>
      </button>
      <ul class="dropdown-menu" aria-labelledby="menuBtn">
        <li class="dropdown-header">Manage</li>
        <li><a href="backoffice/index.html" onclick="return Utils.openBackOffice()"><i class="fa fa-cogs" aria-hidden="true"></i> Admin Console </a></li>
        <li rv-if="config"><a href="backoffice/index.html" onclick="return Utils.openBackOffice(Utils.getDashboardId());"><i class="fa fa-pencil-square-o" aria-hidden="true"></i> Edit this dashboard</a></li>
        <li class="dropdown-header">Recent dashboards</li>
        <li rv-each-board="recentDashboards">
          <a rv-href="board.url">{board.name}</a>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
  MGComponent({
    name: 'menu-component',
    lightDOM: true,
    parent: BaseComponent,
    attributeChangedCallback: function(
      attributeName, oldValue, newValue, namespace) {
      BaseComponent.prototype.attributeChangedCallback.call(this, arguments);
      if(attributeName === 'config') {
        this.getModel().config = JSON.parse(newValue);
      }
    },
    onCreated: function () {
      var model = this.getModel();

      var dashboardsService = Service.get(Service.types.dashboards);
      dashboardsService.addListener(function (response) {
        dashboardsService.removeListener(this);
        model.dashboards = [];
        model.dashboardMap = {};
        model.recentDashboards = [];
        if (response) {
          var dashboards = JSON.parse(response);
          var recent = getRecent();

          for (i in dashboards) {
            dashboard = dashboards[i];
            model.dashboardMap[dashboard.name] = dashboard;
            model.dashboards.push(dashboard);
          }
          for (i of recent) {
            dashboard = model.dashboardMap[i];
            if(dashboard) {
              model.recentDashboards.push({
                url: '?board=' + encodeURIComponent(dashboard.name),
                name: (dashboard.displayName || dashboard.name)
              })
            }
          }
        }

        function getRecent() {
          var recent = localStorage.recentDashboards ? JSON.parse(localStorage.recentDashboards) : [];
          var currentPos = recent.indexOf(Utils.getDashboardId());
          if (currentPos >= 0) {
            recent.splice(currentPos,1);
          }
          recent.unshift(Utils.getDashboardId());
          if (recent.length > 8) {
            recent.pop();
          }
          localStorage.recentDashboards = JSON.stringify(recent);
          return recent;
        }

        $('.typeahead').typeahead('destroy');

        var dashboardMatcher = function(dashboards) {
          return function findMatches(query, cb) {
            var matches = [];
            var substringRegex = new RegExp(query, 'i');

            dashboards.forEach(function(dashboard){
              if (substringRegex.test(dashboard.name) || substringRegex.test(dashboard.displayName)) {
                matches.push(dashboard.name);
              }
            });

            cb(matches);
          };
        };

        $('#search-dashboard .typeahead').typeahead({
          hint: true,
          highlight: true,
          minLength: 1
        },
        {
          name: 'dashboards',
          source: dashboardMatcher(model.dashboards),
          limit: Number.MAX_VALUE,
          templates: {
{'fraction_non_alphanumeric': 0.13500685581689695, 'fraction_numerical': 0.0025313785465668178, 'mean_word_length': 2.409564904710536, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 97, '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': '370746', 'n_tokens_mistral': 2702, 'n_tokens_neox': 2640, 'n_words': 590}