<commit_before>/*
 * Copyright 2019 ThoughtWorks, Inc.
 *
 * 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.
 */

import * as Routes from "gen/ts-routes";
import {ErrorResponse} from "helpers/api_request_builder";
import {MithrilViewComponent} from "jsx/mithril-component";
import m from "mithril";
import Stream from "mithril/stream";
import {Errors} from "models/mixins/errors";
import {PipelineConfig} from "models/pipeline_configs/pipeline_config";
import * as Buttons from "views/components/buttons";
import {ServerErrors} from "views/pages/pipelines/server_errors";
import css from "./actions.scss";

interface Attrs {
  pipelineConfig: PipelineConfig;
  loc?: LocationHandler;
}

export interface LocationHandler {
  go: (url: string) => void;
}

class WindowLocation implements LocationHandler {
  go(url: string) {
    window.location.href = url;
  }
}

export class PipelineActions extends MithrilViewComponent<Attrs> {
  private location: LocationHandler = new WindowLocation();
  private globalError: Stream<string> = Stream();
  private globalErrorDetail: Stream<Errors> = Stream();

  oninit(vnode: m.Vnode<Attrs, {}>) {
    if (vnode.attrs.loc) {
      this.location = vnode.attrs.loc;
    }
  }

  view(vnode: m.Vnode<Attrs>): m.Children | void | null {
    return (
      <footer class={css.actions}>
        <Buttons.Cancel css={css} onclick={this.onCancel.bind(this)} small={false}>Cancel</Buttons.Cancel>
        <div class={css.saveBtns}>
          <ServerErrors message={this.globalError} details={this.globalErrorDetail}/>

          <Buttons.Secondary css={css} onclick={this.onSave.bind(this, true, vnode.attrs.pipelineConfig)} small={false}>Save + Edit Full Config</Buttons.Secondary>
          <Buttons.Primary css={css} onclick={this.onSave.bind(this, false, vnode.attrs.pipelineConfig)} small={false}>Save + Run This Pipeline</Buttons.Primary>
        </div>
      </footer>
    );
  }

  onCancel(event: Event): void {
    event.stopPropagation();
    this.location.go("/go/pipelines");
  }

  onSave(shouldPause: boolean, pipelineConfig: PipelineConfig, event: Event): void {
    event.stopPropagation();
    event.preventDefault();

    this.clearErrors();

    if (pipelineConfig.isValid()) {
      pipelineConfig.create(shouldPause).then((response) => {
        response.do(() => {
          if (shouldPause) {
            this.location.go(Routes.pipelineEditPath("pipelines", pipelineConfig.name(), "general"));
          } else  {
            pipelineConfig.run().then(() => {
              this.location.go(`/go/pipelines?new_pipeline_name=${pipelineConfig.name()}`);
            });
          }
        }, (err: ErrorResponse) => {
          this.globalError(err.message);
          if (err.body) {
            this.globalErrorDetail(pipelineConfig.consumeErrorsResponse(JSON.parse(err.body).data));
          }
        });
      }).catch((reason) => {
        this.globalError(reason);
      }).finally(m.redraw);
    } else {
      this.globalError("Please fix the validation errors above before proceeding.");
    }
  }<commit_msg>Show server error on Pipeline Config SPA (#6771)<commit_after>/*
 * Copyright 2019 ThoughtWorks, Inc.
 *
 * 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.
 */

import * as Routes from "gen/ts-routes";
import {ErrorResponse} from "helpers/api_request_builder";
import {MithrilViewComponent} from "jsx/mithril-component";
import m from "mithril";
import Stream from "mithril/stream";
import {Errors} from "models/mixins/errors";
import {PipelineConfig} from "models/pipeline_configs/pipeline_config";
import * as Buttons from "views/components/buttons";
import {ServerErrors} from "views/pages/pipelines/server_errors";
import css from "./actions.scss";

interface Attrs {
  pipelineConfig: PipelineConfig;
  loc?: LocationHandler;
}

export interface LocationHandler {
  go: (url: string) => void;
}

class WindowLocation implements LocationHandler {
  go(url: string) {
    window.location.href = url;
  }
}

export class PipelineActions extends MithrilViewComponent<Attrs> {
  private location: LocationHandler = new WindowLocation();
  private globalError: Stream<string> = Stream();
  private globalErrorDetail: Stream<Errors> = Stream();

  oninit(vnode: m.Vnode<Attrs, {}>) {
    if (vnode.attrs.loc) {
      this.location = vnode.attrs.loc;
    }
  }

  view(vnode: m.Vnode<Attrs>): m.Children | void | null {
    return (
      <footer class={css.actions}>
        <Buttons.Cancel css={css} onclick={this.onCancel.bind(this)} small={false}>Cancel</Buttons.Cancel>
        <div class={css.saveBtns}>
          <ServerErrors message={this.globalError} details={this.globalErrorDetail}/>

          <Buttons.Secondary css={css} onclick={this.onSave.bind(this, true, vnode.attrs.pipelineConfig)} small={false}>Save + Edit Full Config</Buttons.Secondary>
          <Buttons.Primary css={css} onclick={this.onSave.bind(this, false, vnode.attrs.pipelineConfig)} small={false}>Save + Run This Pipeline</Buttons.Primary>
        </div>
      </footer>
    );
  }

  onCancel(event: Event): void {
    event.stopPropagation();
    this.location.go("/go/pipelines");
  }

  onSave(shouldPause: boolean, pipelineConfig: PipelineConfig, event: Event): void {
    event.stopPropagation();
    event.preventDefault();

    this.clearErrors();

    if (pipelineConfig.isValid()) {
      pipelineConfig.create(shouldPause).then((response) => {
        response.do(() => {
          if (shouldPause) {
            this.location.go(Routes.pipelineEditPath("pipelines", pipelineConfig.name(), "general"));
          } else  {
            pipelineConfig.run().then(() => {
              this.location.go(`/go/pipelines?new_pipeline_name=${pipelineConfig.name()}`);
            });
          }
        }, (err: ErrorResponse) => {
          this.globalError(JSON.parse(err.body!).message);
          if (err.body) {
            this.globalErrorDetail(pipelineConfig.consumeErrorsResponse(JSON.parse(err.body).data));
          }
        });
      }).catch((reason) => {
        this.globalError(reason);
      }).finally(m.redraw);
    } else {
      this.globalError("Please fix the validation errors above before proceeding.");
    }
  }
{'fraction_non_alphanumeric': 0.131852879944483, 'fraction_numerical': 0.002775850104094379, 'mean_word_length': 3.5150375939849625, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 47, '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': '2277578', 'n_tokens_mistral': 2089, 'n_tokens_neox': 2086, 'n_words': 511}