<commit_before>import * as React from 'react';
import { $q } from 'ngimport';
import { flatten, has, isEqual, map, uniq, xor } from 'lodash';

import { IAccount } from 'core/account';
import { AccountService } from 'core/account/AccountService';

export interface IAccountSelectFieldProps {
  accounts: IAccount[] | string[];
  component: { [key: string]: any };
  field: string;
  provider: string;
  loading?: boolean;
  onChange?: (account: string) => void;
  labelColumns?: number;
  readOnly?: boolean;
}

export interface IAccountSelectFieldState {
  accountContainsExpression: boolean;
  mergedAccounts: string[];
  primaryAccounts: string[];
  secondaryAccounts: string[];
}

const isExpression = (account: string) => !!account && account.includes('${');

export class AccountSelectField extends React.Component<IAccountSelectFieldProps, IAccountSelectFieldState> {
  public state: IAccountSelectFieldState = {
    accountContainsExpression: false,
    mergedAccounts: [],
    primaryAccounts: [],
    secondaryAccounts: [],
  };

  private groupAccounts = (accounts: IAccount[] | string[]) => {
    const { component, field, onChange, provider } = this.props;

    if (!accounts || !accounts.length) {
      return;
    }
    if (has(component, field) && isExpression(component[field])) {
      this.setState({ accountContainsExpression: true });
      return;
    }

    const accountsAreObjects = Boolean((accounts[0] as IAccount).name);
    let getAccountDetails = $q.when([]);
    if (provider) {
      if (accountsAreObjects) {
        const providers = uniq(map(accounts as IAccount[], 'type'));
        getAccountDetails = $q
          .all(providers.map(p => AccountService.getAllAccountDetailsForProvider(p)))
          .then(details => flatten(details));
      } else {
        getAccountDetails = AccountService.getAllAccountDetailsForProvider(provider);
      }
    }

    getAccountDetails.then(details => {
      const accountNames: string[] = accountsAreObjects ? map(accounts as IAccount[], 'name') : (accounts as any);
      let mergedAccounts = accountNames;
      let primaryAccounts: string[] = [];
      let secondaryAccounts: string[] = [];

      if (accountNames) {
        primaryAccounts = accountNames.sort();
      }
      if (accountNames && accountNames.length && details.length) {
        primaryAccounts = accountNames
          .filter(account => {
            return details.some(detail => detail.name === account && detail.primaryAccount);
          })
          .sort();
        secondaryAccounts = xor(accountNames, primaryAccounts).sort();
        mergedAccounts = flatten([primaryAccounts, secondaryAccounts]);
      }

      if (component) {
        if (!mergedAccounts.includes(component[field])) {
          onChange('');
        }
      }

      this.setState({ mergedAccounts, primaryAccounts, secondaryAccounts });
    });
  };

  public componentWillReceiveProps(nextProps: IAccountSelectFieldProps) {
    if (!isEqual(nextProps.accounts, this.props.accounts)) {<commit_msg>fix(core/account): Fixed AccountSelectField missing state initialization (#5860)<commit_after>import * as React from 'react';
import { $q } from 'ngimport';
import { flatten, has, isEqual, map, uniq, xor } from 'lodash';

import { IAccount } from 'core/account';
import { AccountService } from 'core/account/AccountService';

export interface IAccountSelectFieldProps {
  accounts: IAccount[] | string[];
  component: { [key: string]: any };
  field: string;
  provider: string;
  loading?: boolean;
  onChange?: (account: string) => void;
  labelColumns?: number;
  readOnly?: boolean;
}

export interface IAccountSelectFieldState {
  accountContainsExpression: boolean;
  mergedAccounts: string[];
  primaryAccounts: string[];
  secondaryAccounts: string[];
}

const isExpression = (account: string) => !!account && account.includes('${');

export class AccountSelectField extends React.Component<IAccountSelectFieldProps, IAccountSelectFieldState> {
  public state: IAccountSelectFieldState = {
    accountContainsExpression: false,
    mergedAccounts: [],
    primaryAccounts: [],
    secondaryAccounts: [],
  };

  private groupAccounts = (accounts: IAccount[] | string[]) => {
    const { component, field, onChange, provider } = this.props;

    if (!accounts || !accounts.length) {
      return;
    }
    if (has(component, field) && isExpression(component[field])) {
      this.setState({ accountContainsExpression: true });
      return;
    }

    const accountsAreObjects = Boolean((accounts[0] as IAccount).name);
    let getAccountDetails = $q.when([]);
    if (provider) {
      if (accountsAreObjects) {
        const providers = uniq(map(accounts as IAccount[], 'type'));
        getAccountDetails = $q
          .all(providers.map(p => AccountService.getAllAccountDetailsForProvider(p)))
          .then(details => flatten(details));
      } else {
        getAccountDetails = AccountService.getAllAccountDetailsForProvider(provider);
      }
    }

    getAccountDetails.then(details => {
      const accountNames: string[] = accountsAreObjects ? map(accounts as IAccount[], 'name') : (accounts as any);
      let mergedAccounts = accountNames;
      let primaryAccounts: string[] = [];
      let secondaryAccounts: string[] = [];

      if (accountNames) {
        primaryAccounts = accountNames.sort();
      }
      if (accountNames && accountNames.length && details.length) {
        primaryAccounts = accountNames
          .filter(account => {
            return details.some(detail => detail.name === account && detail.primaryAccount);
          })
          .sort();
        secondaryAccounts = xor(accountNames, primaryAccounts).sort();
        mergedAccounts = flatten([primaryAccounts, secondaryAccounts]);
      }

      if (component) {
        if (!mergedAccounts.includes(component[field])) {
          onChange('');
        }
      }

      this.setState({ mergedAccounts, primaryAccounts, secondaryAccounts });
    });
  };

  public componentDidMount() {
    this.groupAccounts(this.props.accounts);
  }

  public componentWillReceiveProps(nextProps: IAccountSelectFieldProps) {
    if (!isEqual(nextProps.accounts, this.props.accounts)) {
{'fraction_non_alphanumeric': 0.12810183693200128, 'fraction_numerical': 0.0009668063164679343, 'mean_word_length': 3.580811808118081, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, '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': '6437715', 'n_tokens_mistral': 1708, 'n_tokens_neox': 1705, 'n_words': 389}