<commit_before>/*
 * Copyright 2018 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 {bind} from "classnames/bind";
import {ApiResult, ErrorResponse, ObjectWithEtag} from "helpers/api_request_builder";
import * as m from "mithril";
import {Stream} from "mithril/stream";
import * as stream from "mithril/stream";
import {ElasticAgentProfilesCRUD} from "models/elastic_profiles/elastic_agent_profiles_crud";
import {ClusterProfile, ClusterProfiles, ElasticAgentProfile, ProfileUsage} from "models/elastic_profiles/types";
import {ExtensionType} from "models/shared/plugin_infos_new/extension_type";
import {ElasticAgentSettings, Extension} from "models/shared/plugin_infos_new/extensions";
import {PluginInfo} from "models/shared/plugin_infos_new/plugin_info";
import * as Buttons from "views/components/buttons";
import {FlashMessage, MessageType} from "views/components/flash_message";
import {Form, FormHeader} from "views/components/forms/form";
import {SelectField, SelectFieldOptions, TextField} from "views/components/forms/input_fields";
import {Modal, Size} from "views/components/modal";
import {Spinner} from "views/components/spinner";
import {Table} from "views/components/table";
import * as styles from "views/pages/elastic_profiles/index.scss";
import * as foundationStyles from "views/pages/new_plugins/foundation_hax.scss";

const foundationClassNames = bind(foundationStyles);
const AngularPluginNew     = require("views/shared/angular_plugin_new");
import * as _ from "lodash";

enum ModalType {
  edit, clone, create
}

abstract class BaseElasticProfileModal extends Modal {
  protected elasticProfile: Stream<ElasticAgentProfile>;
  private readonly pluginInfo: Stream<PluginInfo<Extension>>;
  private readonly pluginInfos: Array<PluginInfo<Extension>>;
  private readonly modalType: ModalType;
  private errorMessage: string | undefined;
  private noClusterProfileError: string | undefined;
  private readonly clusterProfiles: ClusterProfiles;

  protected constructor(pluginInfos: Array<PluginInfo<Extension>>,
                        type: ModalType,
                        clusterProfiles: ClusterProfiles,
                        elasticProfile?: ElasticAgentProfile) {
    super(Size.extraLargeHackForEaProfiles);
    this.clusterProfiles = clusterProfiles;
    this.elasticProfile  = stream(elasticProfile);
    this.pluginInfos     = pluginInfos;
    this.pluginInfo      = stream();
    this.modalType       = type;
  }

  abstract performSave(): void;

  abstract modalTitle(): string;

  validateAndPerformSave() {
    if (!this.elasticProfile() || !this.elasticProfile().isValid()) {
      return;
    }
    this.performSave();
  }

  showErrors(apiResult: ApiResult<ObjectWithEtag<ElasticAgentProfile>>, errorResponse: ErrorResponse) {
    if (apiResult.getStatusCode() === 422 && errorResponse.body) {
      const profile = ElasticAgentProfile.fromJSON(JSON.parse(errorResponse.body).data);
      this.elasticProfile(profile);
    }
  }

  buttons() {
    return [
      <Buttons.Primary data-test-id="button-ok" onclick={this.validateAndPerformSave.bind(this)}>Save</Buttons.Primary>,
      <Buttons.Cancel data-test-id="button-cancel" onclick={this.close.bind(this)}>Cancel</Buttons.Cancel>,
    ];
  }

  body() {
    if (this.errorMessage) {
      return (<FlashMessage type={MessageType.alert} message={this.errorMessage}/>);<commit_msg>Fix invalid rendering of profile properties in case of validation errors (#6154)<commit_after>/*
 * Copyright 2018 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 {bind} from "classnames/bind";
import {ApiResult, ErrorResponse, ObjectWithEtag} from "helpers/api_request_builder";
import * as m from "mithril";
import {Stream} from "mithril/stream";
import * as stream from "mithril/stream";
import {ElasticAgentProfilesCRUD} from "models/elastic_profiles/elastic_agent_profiles_crud";
import {ClusterProfile, ClusterProfiles, ElasticAgentProfile, ProfileUsage} from "models/elastic_profiles/types";
import {ExtensionType} from "models/shared/plugin_infos_new/extension_type";
import {ElasticAgentSettings, Extension} from "models/shared/plugin_infos_new/extensions";
import {PluginInfo} from "models/shared/plugin_infos_new/plugin_info";
import * as Buttons from "views/components/buttons";
import {FlashMessage, MessageType} from "views/components/flash_message";
import {Form, FormHeader} from "views/components/forms/form";
import {SelectField, SelectFieldOptions, TextField} from "views/components/forms/input_fields";
import {Modal, Size} from "views/components/modal";
import {Spinner} from "views/components/spinner";
import {Table} from "views/components/table";
import * as styles from "views/pages/elastic_profiles/index.scss";
import * as foundationStyles from "views/pages/new_plugins/foundation_hax.scss";

const foundationClassNames = bind(foundationStyles);
const AngularPluginNew     = require("views/shared/angular_plugin_new");
import * as _ from "lodash";

enum ModalType {
  edit, clone, create
}

abstract class BaseElasticProfileModal extends Modal {
  protected elasticProfile: Stream<ElasticAgentProfile>;
  private readonly pluginInfo: Stream<PluginInfo<Extension>>;
  private readonly pluginInfos: Array<PluginInfo<Extension>>;
  private readonly modalType: ModalType;
  private errorMessage: string | undefined;
  private noClusterProfileError: string | undefined;
  private readonly clusterProfiles: ClusterProfiles;

  protected constructor(pluginInfos: Array<PluginInfo<Extension>>,
                        type: ModalType,
                        clusterProfiles: ClusterProfiles,
                        elasticProfile?: ElasticAgentProfile) {
    super(Size.extraLargeHackForEaProfiles);
    this.clusterProfiles = clusterProfiles;
    this.elasticProfile  = stream(elasticProfile);
    this.pluginInfos     = pluginInfos;
    this.pluginInfo      = stream();
    this.modalType       = type;
  }

  abstract performSave(): void;

  abstract modalTitle(): string;

  validateAndPerformSave() {
    if (!this.elasticProfile() || !this.elasticProfile().isValid()) {
      return;
    }
    this.performSave();
  }

  showErrors(apiResult: ApiResult<ObjectWithEtag<ElasticAgentProfile>>, errorResponse: ErrorResponse) {
    if (apiResult.getStatusCode() === 422 && errorResponse.body) {
      const profile = ElasticAgentProfile.fromJSON(JSON.parse(errorResponse.body).data);
      profile.pluginId(this.clusterProfiles.findCluster(profile.clusterProfileId()).pluginId());
      this.elasticProfile(profile);
    }
  }

  buttons() {
    return [
      <Buttons.Primary data-test-id="button-ok" onclick={this.validateAndPerformSave.bind(this)}>Save</Buttons.Primary>,
      <Buttons.Cancel data-test-id="button-cancel" onclick={this.close.bind(this)}>Cancel</Buttons.Cancel>,
    ];
  }

  body() {
    if (this.errorMessage) {
      return (<FlashMessage type={MessageType.alert} message={this.errorMessage}/>);
{'fraction_non_alphanumeric': 0.10609847538115472, 'fraction_numerical': 0.0032491877030742314, 'mean_word_length': 4.790882778581765, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, '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': '1225108', 'n_tokens_mistral': 2265, 'n_tokens_neox': 2198, 'n_words': 573}