<commit_before>/**
 * Created by ksinger on 24.08.2015.
 */
import angular from "angular";
import ngAnimate from "angular-animate";

import "ng-redux";
import labelledHrModule from "./labelled-hr.js";
import matchingContextModule from "./details/picker/matching-context-picker.js"; // TODO: should be renamed
import { getIn, attach, delay } from "../utils.js";
import { actionCreators } from "../actions/actions.js";
import { connect2Redux } from "../won-utils.js";
import { selectIsConnected } from "../selectors.js";

//TODO can't inject $scope with the angular2-router, preventing redux-cleanup
const serviceDependencies = [
  "$ngRedux",
  "$scope",
  "$element" /*'$routeParams' /*injections as strings here*/,
];

function genComponentConf() {
  const template = `
        <!-- HEADER: -->
        <div class="cp__header">
            <a class="cp__header__back clickable"
                ng-click="self.router__stateGoCurrent({useCase: undefined})">
                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon show-in-responsive">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>
                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon hide-in-responsive">
                    <use xlink:href="#ico36_close" href="#ico36_close"></use>
                </svg>
            </a>
            <svg class="cp__header__icon"
                title="Search"
                style="--local-primary:var(--won-primary-color);">
                    <use xlink:href="#ico36_search" href="#ico36_search"></use>
            </svg>
            <span class="cp__header__title">Search</span>
        </div>

        <!-- CONTENT: -->
        <div class="cp__content">

            <!-- ADD SEARCH STRING -->
            <won-title-picker
              on-update="::self.updateDetail(value)"
              initial-value="::self.draftObject.searchString">
            </won-title-picker>
            

            <!-- TUNE MATCHING -->
            <!-- TODO: when should this be shown as an option? -->
            <div class="cp__content__branchheader b detailPicker clickable"
                ng-click="self.toggleTuningOptions()">
                <span>Tune Matching Behaviour</span>
                <svg class="cp__content__branchheader__carret" ng-show="!self.showTuningOptions">
                    <use xlink:href="#ico16_arrow_down" href="#ico16_arrow_down"></use>
                </svg>
                <svg class="cp__content__branchheader__carret" ng-show="self.showTuningOptions">
                    <use xlink:href="#ico16_arrow_up" href="#ico16_arrow_up"></use>
                </svg>
            </div>
            <div class="cp__content__tuning">
                <div class="cp__content__tuning_matching-context">
                    <won-matching-context-picker
                      ng-if="self.showTuningOptions"
                      default-matching-context="::self.defaultMatchingContext"
                      on-matching-context-updated="::self.updateMatchingContext(matchingContext)">
                    </won-matching-context-picker>
                </div>
            </div>

            <!-- PUBLISH BUTTON - RESPONSIVE MODE -->
            <div class="cp__content__responsivebuttons show-in-responsive">
              <won-labelled-hr label="::'done?'" class="cp__content__labelledhr"></won-labelled-hr>
              <button type="submit" class="won-button--filled red cp__content__publish"
                      ng-disabled="!self.isValid()"
                      ng-click="::self.publish()">
                  <span ng-show="!self.pendingPublishing">
                      Publish
                  </span>
                  <span ng-show="self.pendingPublishing">
                      Publishing&nbsp;&hellip;
                  </span>
              </button>
            </div>
        </div>

        <!-- FOOTER: PUBLISH BUTTON - NON-RESPONSIVE MODE -->
        <div class="cp__footer hide-in-responsive" >
            <won-labelled-hr label="::'done?'" class="cp__footer__labelledhr"></won-labelled-hr>
            <button type="submit" class="won-button--filled red cp__footer__publish"
                    ng-disabled="!self.isValid()"
                    ng-click="::self.publish()">
                <span ng-show="!self.pendingPublishing">
                    Publish
                </span>
                <span ng-show="self.pendingPublishing">
                    Publishing&nbsp;&hellip;
                </span>
            </button>
        </div>
    `;

  class Controller {
    constructor(/* arguments <- serviceDependencies */) {
      attach(this, serviceDependencies, arguments);
      this.focusedElement = null;
      //TODO debug; deleteme
      window.cns4dbg = this;

      this.windowHeight = window.screen.height;
      this.scrollContainer().addEventListener("scroll", e => this.onResize(e));

      this.draftObject = {};
      this.draftObject.useCase = "search";
      this.draftObject.seeks = {};

      this.showTuningOptions = false;

      this.pendingPublishing = false;
      this.isNew = true;

      const selectFromState = state => {
        const defaultMatchingContextList = getIn(state, [
          "config",
          "theme",
          "defaultContext",
        ]);
        const defaultMatchingContext = defaultMatchingContextList
          ? defaultMatchingContextList.toJS()
          : [];

        return {
          connectionHasBeenLost: !selectIsConnected(state),
          defaultMatchingContext: defaultMatchingContext,
        };
      };

      delay(0).then(() => {
        this.updateMatchingContext(this.defaultMatchingContext);
      });

      // Using actionCreators like this means that every action defined there is available in the template.
      connect2Redux(selectFromState, actionCreators, [], this);
    }

    onResize() {
      if (this.focusedElement) {
        if (this.windowHeight < window.screen.height) {
          this.windowHeight < window.screen.height;
          this.scrollToBottom(this.focusedElement);
        } else {
          this.windowHeight = window.screen.height;
        }
      }
    }

    scrollToBottom(element) {
      this._programmaticallyScrolling = true;

      if (element) {
        let heightHeader =
          this.$element[0].querySelector(".cp__header").offsetHeight + 10;
        let scrollTop = this.$element[0].querySelector(element).offsetTop;
        this.scrollContainer().scrollTop = scrollTop - heightHeader;

        this.focusedElement = element;
      }
    }

    scrollContainer() {
      if (!this._scrollContainer) {
        this._scrollContainer = this.$element[0].querySelector(".cp__content");
      }
      return this._scrollContainer;
    }

    toggleTuningOptions() {
      this.showTuningOptions = !this.showTuningOptions;
    }

    isValid() {
      const draft = this.draftObject;
      const hasSearchString =
        this.draftObject &&
        this.draftObject.searchString &&
        this.draftObject.searchString.trim().length > 0;
      return !this.connectionHasBeenLost && !!draft && hasSearchString;
    }

    updateMatchingContext(matchingContext) {
      if (matchingContext) {
        this.draftObject.matchingContext = matchingContext;
      }
    }

    updateDetail(value) {
      if (this.isNew) {
        this.isNew = false;
      }
      this.draftObject.searchString = value;
    }

    publish() {
      // Post both needs
      if (!this.pendingPublishing) {
        this.pendingPublishing = true;

        this.needs__create(
          this.draftObject,
          this.$ngRedux.getState().getIn(["config", "defaultNodeUri"])
        );
      }
    }
  }

  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl<commit_msg>Fixes #2480: Creation of Search Needs<commit_after>/**
 * Created by ksinger on 24.08.2015.
 */
import angular from "angular";
import ngAnimate from "angular-animate";

import "ng-redux";
import labelledHrModule from "./labelled-hr.js";
import matchingContextModule from "./details/picker/matching-context-picker.js"; // TODO: should be renamed
import { getIn, attach, delay } from "../utils.js";
import { actionCreators } from "../actions/actions.js";
import { connect2Redux } from "../won-utils.js";
import { selectIsConnected } from "../selectors.js";

//TODO can't inject $scope with the angular2-router, preventing redux-cleanup
const serviceDependencies = [
  "$ngRedux",
  "$scope",
  "$element" /*'$routeParams' /*injections as strings here*/,
];

function genComponentConf() {
  const template = `
        <!-- HEADER: -->
        <div class="cp__header">
            <a class="cp__header__back clickable"
                ng-click="self.router__stateGoCurrent({useCase: undefined})">
                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon show-in-responsive">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>
                <svg style="--local-primary:var(--won-primary-color);"
                    class="cp__header__back__icon hide-in-responsive">
                    <use xlink:href="#ico36_close" href="#ico36_close"></use>
                </svg>
            </a>
            <svg class="cp__header__icon"
                title="Search"
                style="--local-primary:var(--won-primary-color);">
                    <use xlink:href="#ico36_search" href="#ico36_search"></use>
            </svg>
            <span class="cp__header__title">Search</span>
        </div>

        <!-- CONTENT: -->
        <div class="cp__content">

            <!-- ADD SEARCH STRING -->
            <won-title-picker
              on-update="::self.updateDetail(value)"
              initial-value="::self.draftObject.searchString">
            </won-title-picker>
            

            <!-- TUNE MATCHING -->
            <!-- TODO: when should this be shown as an option? -->
            <div class="cp__content__branchheader b detailPicker clickable"
                ng-click="self.toggleTuningOptions()">
                <span>Tune Matching Behaviour</span>
                <svg class="cp__content__branchheader__carret" ng-show="!self.showTuningOptions">
                    <use xlink:href="#ico16_arrow_down" href="#ico16_arrow_down"></use>
                </svg>
                <svg class="cp__content__branchheader__carret" ng-show="self.showTuningOptions">
                    <use xlink:href="#ico16_arrow_up" href="#ico16_arrow_up"></use>
                </svg>
            </div>
            <div class="cp__content__tuning">
                <div class="cp__content__tuning_matching-context">
                    <won-matching-context-picker
                      ng-if="self.showTuningOptions"
                      default-matching-context="::self.defaultMatchingContext"
                      on-matching-context-updated="::self.updateMatchingContext(matchingContext)">
                    </won-matching-context-picker>
                </div>
            </div>

            <!-- PUBLISH BUTTON - RESPONSIVE MODE -->
            <div class="cp__content__responsivebuttons show-in-responsive">
              <won-labelled-hr label="::'done?'" class="cp__content__labelledhr"></won-labelled-hr>
              <button type="submit" class="won-button--filled red cp__content__publish"
                      ng-disabled="!self.isValid()"
                      ng-click="::self.publish()">
                  <span ng-show="!self.pendingPublishing">
                      Publish
                  </span>
                  <span ng-show="self.pendingPublishing">
                      Publishing&nbsp;&hellip;
                  </span>
              </button>
            </div>
        </div>

        <!-- FOOTER: PUBLISH BUTTON - NON-RESPONSIVE MODE -->
        <div class="cp__footer hide-in-responsive" >
            <won-labelled-hr label="::'done?'" class="cp__footer__labelledhr"></won-labelled-hr>
            <button type="submit" class="won-button--filled red cp__footer__publish"
                    ng-disabled="!self.isValid()"
                    ng-click="::self.publish()">
                <span ng-show="!self.pendingPublishing">
                    Publish
                </span>
                <span ng-show="self.pendingPublishing">
                    Publishing&nbsp;&hellip;
                </span>
            </button>
        </div>
    `;

  class Controller {
    constructor(/* arguments <- serviceDependencies */) {
      attach(this, serviceDependencies, arguments);
      this.focusedElement = null;
      //TODO debug; deleteme
      window.cns4dbg = this;

      this.windowHeight = window.screen.height;
      this.scrollContainer().addEventListener("scroll", e => this.onResize(e));

      this.draftObject = {};
      this.draftObject.useCase = "search";
      this.draftObject.seeks = {};

      this.showTuningOptions = false;

      this.pendingPublishing = false;
      this.isNew = true;

      const selectFromState = state => {
        const defaultMatchingContextList = getIn(state, [
          "config",
          "theme",
          "defaultContext",
        ]);
        const defaultMatchingContext = defaultMatchingContextList
          ? defaultMatchingContextList.toJS()
          : [];

        return {
          connectionHasBeenLost: !selectIsConnected(state),
          defaultMatchingContext: defaultMatchingContext,
        };
      };

      delay(0).then(() => {
        this.updateMatchingContext(this.defaultMatchingContext);
      });

      // Using actionCreators like this means that every action defined there is available in the template.
      connect2Redux(selectFromState, actionCreators, [], this);
    }

    onResize() {
      if (this.focusedElement) {
        if (this.windowHeight < window.screen.height) {
          this.windowHeight < window.screen.height;
          this.scrollToBottom(this.focusedElement);
        } else {
          this.windowHeight = window.screen.height;
        }
      }
    }

    scrollToBottom(element) {
      this._programmaticallyScrolling = true;

      if (element) {
        let heightHeader =
          this.$element[0].querySelector(".cp__header").offsetHeight + 10;
        let scrollTop = this.$element[0].querySelector(element).offsetTop;
        this.scrollContainer().scrollTop = scrollTop - heightHeader;

        this.focusedElement = element;
      }
    }

    scrollContainer() {
      if (!this._scrollContainer) {
        this._scrollContainer = this.$element[0].querySelector(".cp__content");
      }
      return this._scrollContainer;
    }

    toggleTuningOptions() {
      this.showTuningOptions = !this.showTuningOptions;
    }

    isValid() {
      const draft = this.draftObject;
      const hasSearchString =
        this.draftObject &&
        this.draftObject.searchString &&
        this.draftObject.searchString.trim().length > 0;
      return !this.connectionHasBeenLost && !!draft && hasSearchString;
    }

    updateMatchingContext(matchingContext) {
      if (matchingContext) {
        this.draftObject.matchingContext = matchingContext;
      }
    }

    updateDetail(value) {
      if (this.isNew) {
        this.isNew = false;
      }
      this.draftObject.searchString = value;
    }

    publish() {
      // Post both needs
      if (!this.pendingPublishing) {
        this.pendingPublishing = true;

        this.needs__create(
          this.draftObject,
          undefined,
          this.$ngRedux.getState().getIn(["config", "defaultNodeUri"])
        );
      }
    }
  }

  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
{'fraction_non_alphanumeric': 0.12866115291337604, 'fraction_numerical': 0.005099185374043903, 'mean_word_length': 2.0235006580184245, 'pattern_counts': {'":': 16, '<': 143, '<?xml version=': 0, '>': 147, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '6205137', 'n_tokens_mistral': 4552, 'n_tokens_neox': 4280, 'n_words': 755}