{"size": 8171, "ext": "js", "max_stars_repo_path": "frontend/src/components/Bot/Bot.js", "max_stars_repo_name": "grafolean/grafolean", "max_stars_repo_stars_event_min_datetime": "2019-12-31T17:20:11.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-21T03:51:12.000Z", "max_issues_repo_path": "frontend/src/components/Bot/Bot.js", "max_issues_repo_name": "grafolean/grafolean", "max_issues_repo_issues_event_min_datetime": "2020-10-11T16:20:40.000Z", "max_issues_repo_issues_event_max_datetime": "2021-07-02T16:14:11.000Z", "max_forks_repo_path": "frontend/src/components/Bot/Bot.js", "max_forks_repo_name": "grafolean/grafolean", "max_forks_repo_forks_event_min_datetime": "2020-10-02T14:02:32.000Z", "max_forks_repo_forks_event_max_datetime": "2020-10-02T14:02:32.000Z"}
{"max_stars_count": 22, "max_issues_count": 16, "max_forks_count": 1, "avg_line_length": 38.3615023474, "max_line_length": 113, "alphanum_fraction": 0.5098519153}
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import moment from 'moment-timezone';

import { PersistentFetcher } from '../../utils/fetch/PersistentFetcher';
import { SUPPORTED_PROTOCOLS } from '../../utils/protocols';
import { havePermission, fetchAuth } from '../../utils/fetch';
import { handleFetchErrors, ROOT_URL } from '../../store/actions';
import Loading from '../Loading';
import When from '../When';
import EditableLabel from '../EditableLabel';
import HelpSnippet from '../HelpSnippets/HelpSnippet';
import SNMPBotHelpSnippet from '../Bots/SNMPBotHelpSnippet';
import PingBotHelpSnippet from '../Bots/PingBotHelpSnippet';
import CustomBotHelpSnippet from '../Bots/CustomBotHelpSnippet';

import './Bot.scss';

/*
  This component is used for both account bots and for systemwide bots.
*/

class Bot extends React.Component {
  state = {
    bot: null,
    protocol: null,
    entitiesCount: null,
    entitiesWithCorrectProtocolCount: null,
    sensorsCount: null,
    credentialsWithCorrectProtocolCount: null,
  };

  onBotUpdate = json => {
    const protocol = SUPPORTED_PROTOCOLS.find(p => p.slug === json.protocol);
    this.setState({
      bot: json,
      protocol: protocol,
    });
  };

  onEntitiesUpdate = json => {
    const { bot } = this.state;
    const entitiesWithCorrectProtocol = json.list.filter(e => !!e.protocols[bot.protocol]);
    let sensorsCount = 0;
    entitiesWithCorrectProtocol.forEach(e => {
      sensorsCount += e.protocols[bot.protocol].sensors.length;
    });
    this.setState({
      entitiesCount: json.list.length,
      entitiesWithCorrectProtocolCount: entitiesWithCorrectProtocol.length,
      sensorsCount: sensorsCount,
    });
  };

  onCredentialsUpdate = json => {
    const { bot } = this.state;
    this.setState({
      credentialsWithCorrectProtocolCount: json.list.filter(c => c.protocol === bot.protocol).length,
    });
  };

  setBotName = async name => {
    const { accountId, botId } = this.props.match.params;
    const { bot } = this.state;
    const params = {
      name: name,
      protocol: bot.protocol,
    };
    fetchAuth(`${ROOT_URL}/accounts/${accountId}/bots/${botId}`, {
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      method: 'PUT',
      body: JSON.stringify(params),
    }).then(handleFetchErrors);
  };

  render() {
    const { accountId, botId } = this.props.match.params;
    const {
      bot,
      protocol,
      entitiesCount,
      entitiesWithCorrectProtocolCount,
      sensorsCount,
      credentialsWithCorrectProtocolCount,
    } = this.state;
    const { user } = this.props;
    const canEditBotName = havePermission(`accounts/${accountId}/bots/${botId}`, 'PUT', user.permissions);
    return (
      <>
        <PersistentFetcher resource={`accounts/${accountId}/bots/${botId}`} onUpdate={this.onBotUpdate} />

        {bot === null ? (
          <Loading overlayParent={true} />
        ) : (
          <>
            <PersistentFetcher resource={`accounts/${accountId}/entities`} onUpdate={this.onEntitiesUpdate} />
            <PersistentFetcher
              resource={`accounts/${accountId}/credentials`}
              onUpdate={this.onCredentialsUpdate}
            />
            <div className="frame">
              <span>
                Bot: <EditableLabel label={bot.name} onChange={this.setBotName} isEditable={canEditBotName} />
              </span>
            </div>

            {bot && (
              <>
                {bot.last_login === null ? (
                  <HelpSnippet title="The bot is not installed yet" className="first-steps">
                    <p>Bot has never (successfully) connected to Grafolean yet.</p>
                    <hr />
                    {bot.protocol === null ? (
                      <CustomBotHelpSnippet bot={bot} />
                    ) : (
                      <>
                        {protocol.slug === 'snmp' && <SNMPBotHelpSnippet bot={bot} />}
                        {protocol.slug === 'ping' && <PingBotHelpSnippet bot={bot} />}
                      </>
                    )}
                  </HelpSnippet>
                ) : entitiesCount === 0 && bot.protocol !== null ? (
                  <HelpSnippet title="There are no entities (devices) yet" className="first-steps">
                    <p>
                      <b>Entities</b> are the things you wish to monitor (for example devices, webpages,
                      apps,...).
                    </p>
                    <Link className="button green" to={`/accounts/${accountId}/entities/new`}>
                      <i className="fa fa-plus" /> Add an entity
                    </Link>
                  </HelpSnippet>
                ) : credentialsWithCorrectProtocolCount === 0 && bot.protocol !== null ? (
                  <HelpSnippet
                    title={`There are no credentials (protocol configurations) for ${protocol.label} yet`}
                    className="first-steps"
                  >
                    <p>
                      Protocol settings (<b>credentials</b>) must be entered.
                    </p>
                    <Link className="button green" to={`/accounts/${accountId}/credentials/new`}>
                      <i className="fa fa-plus" /> Add a credential
                    </Link>
                  </HelpSnippet>
                ) : entitiesWithCorrectProtocolCount === 0 && bot.protocol !== null ? (
                  <HelpSnippet
                    title={`None of the entities (devices) have ${protocol.label} credentials enabled yet`}
                    className="first-steps"
                  >
                    <p>
                      To monitor entities, credentials (protocol settings) must be set for entities. Open{' '}
                      <Link to={`/accounts/${accountId}/entities`}>entities</Link> page, select an entity and
                      fix its settings.
                    </p>
                  </HelpSnippet>
                ) : sensorsCount === 0 && bot.protocol !== null ? (
                  <HelpSnippet
                    title={`Last step: enable sensors for ${protocol.label} on entities`}
                    className="first-steps"
                  >
                    <p>
                      <b>Sensors</b> describe which data should be collected from each of the entities. Open{' '}
                      <Link to={`/accounts/${accountId}/entities`}>entities</Link> page, select an entity and
                      select sensors via "Settings" button.
                    </p>
                  </HelpSnippet>
                ) : null}

                {entitiesCount !== null && (
                  <div className="frame">
                    Protocol: {protocol ? protocol.label : 'custom'}
                    <br />
                    Last succesful login to this account:{' '}
                    {bot.last_login === null ? (
                      'never'
                    ) : (
                      <>
                        {moment(bot.last_login * 1000).format('YYYY-MM-DD HH:mm:ss z')} (
                        <When t={bot.last_login} />)
                      </>
                    )}
                    {protocol && (
                      <>
                        <br />
                        <br />
                        Entities: {entitiesCount}
                        <br />
                        Credentials for {protocol.label}: {credentialsWithCorrectProtocolCount}
                        <br />
                        Entities that have credentials for {protocol.label} enabled:{' '}
                        {entitiesWithCorrectProtocolCount}
                        <br />
                        Total number of sensors enabled on these entities: {sensorsCount}
                      </>
                    )}
                  </div>
                )}
              </>
            )}
          </>
        )}
      </>
    );
  }
}
const mapStoreToProps = store => ({
  user: store.user,
});
export default connect(mapStoreToProps)(Bot);
