<commit_before>import parent from '../render/dom/parent'
import { property } from '../render/static'

const injectable = {}

export default injectable

injectable.props = {
  attr: {
    type: 'property',
    render: {
      static: property,
      state (t, state, type, subs, tree, id, pid) {
        const pnode = parent(tree, pid)
        if (pnode && !pnode._propsStaticParsed) {
          property(t, pnode)
          pnode._propsStaticParsed = true
        }
      }
    },
    props: {
      type: null,
      default: {
        props: { name: true },
        render: {
          static (t, pnode) {
            const val = t.compute()
            if (val === t || val === void 0) {
              pnode.removeAttribute(t.name || t.key)
            } else {
              pnode.setAttribute(t.name || t.key, val)
            }
          },
          state (t, state, type, subs, tree, id, pid) {
            const pnode = parent(tree, pid)
            const key = t.name || t.key
            if (type === 'remove') {
              if (pnode) {
                pnode.removeAttribute(key)
              }
            } else {
              let val = t.compute(state)
              const type = typeof val
              if (type === 'boolean') { val = val + '' }
              if ((type === 'object' && val.inherits) || val === void 0) {
                if (pnode.getAttribute(key)) {
                  pnode.removeAttribute(key) // missing
                }
              } else {
                if (pnode.getAttribute(key) != val) { // eslint-disable-line
                  pnode.setAttribute(key, val)
                }
              }
            }
          }
        }
      },
      value: {
        render: {
          static (t, pnode) {
            const val = t.compute() // missing
            pnode.value = val // missing (needs a way on server this does not work)
          },
          state (t, state, type, subs, tree, id, pid) {
            const pnode = parent(tree, pid)
            if (type === 'remove') {
              if (pnode) { pnode.value = '' } // missing
            } else {
              const val = t.compute(state)
              if (val != pnode.value) { // eslint-disable-line
                pnode.value = val === t ? '' : val
              }
            }
          }
        }
      }
    }
  }
}
<commit_msg>pass state to compute in attributes<commit_after>import parent from '../render/dom/parent'
import { property } from '../render/static'

const injectable = {}

export default injectable

injectable.props = {
  attr: {
    type: 'property',
    render: {
      static: property,
      state (t, state, type, subs, tree, id, pid) {
        const pnode = parent(tree, pid)
        if (pnode && !pnode._propsStaticParsed) {
          property(t, pnode)
          pnode._propsStaticParsed = true
        }
      }
    },
    props: {
      type: null,
      default: {
        props: { name: true },
        render: {
          static (t, pnode) {
            const val = t.compute()
            if (val === t || val === void 0) {
              pnode.removeAttribute(t.name || t.key)
            } else {
              pnode.setAttribute(t.name || t.key, val)
            }
          },
          state (t, state, type, subs, tree, id, pid) {
            const pnode = parent(tree, pid)
            const key = t.name || t.key
            if (type === 'remove') {
              if (pnode) {
                pnode.removeAttribute(key)
              }
            } else {
              let val = t.compute(state, state)
              const type = typeof val
              if (type === 'boolean') { val = val + '' }
              if ((type === 'object' && val.inherits) || val === void 0) {
                if (pnode.getAttribute(key)) {
                  pnode.removeAttribute(key) // missing
                }
              } else {
                if (pnode.getAttribute(key) != val) { // eslint-disable-line
                  pnode.setAttribute(key, val)
                }
              }
            }
          }
        }
      },
      value: {
        render: {
          static (t, pnode) {
            const val = t.compute() // missing
            pnode.value = val // missing (needs a way on server this does not work)
          },
          state (t, state, type, subs, tree, id, pid) {
            const pnode = parent(tree, pid)
            if (type === 'remove') {
              if (pnode) { pnode.value = '' } // missing
            } else {
              const val = t.compute(state, state)
              if (val != pnode.value) { // eslint-disable-line
                pnode.value = val === t ? '' : val
              }
            }
          }
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>
var parseDom = require("./parse-dom")

module.exports = function(el) {
  parseDom(el || document)
}
<commit_msg>fix(refresh): use `this.parseDOM` for refresh<commit_after>module.exports = function(el) {
  this.parseDOM(el || document)
}
<|endoftext|>


<commit_before>/* eslint-disable no-underscore-dangle */
const loadSuggestions = (searchForm) => {
  searchForm._props.storedSuggestions = JSON.parse(sessionStorage.getItem(`storedSuggestions_${searchForm._props.type}`));
  const now = new Date();
  if (!searchForm._props.storedSuggestions
    || now.getTime() > searchForm._props.storedSuggestions.expires) {
    const promise = fetch(searchForm._props.suggestionsTop, { cache: 'no-cache' })
      .then(response => response.json())
      .then((data) => {
        const suggestions = {
          expires: now.getTime() + (15 * 60000),
          data
        };
        searchForm._props.storedSuggestions = suggestions;
        sessionStorage.setItem(`storedSuggestions_${searchForm._props.type}`, JSON.stringify(searchForm._props.storedSuggestions));
      })
      .catch(e => console.error(e.name, e.message)); // eslint-disable-line no-console
    return promise;
  }
  return Promise.resolve(true);
};

const trackAutosuggest = (e) => {
  window.dataLayer.push({
    event: e.target.tracking.event,
    eventCategory: e.target.tracking.eventCategory,
    eventAction: e.target.tracking.eventAction,
    eventLabel: e.target.tracking.eventLabel
  });
};

Array.from(document.querySelectorAll('.js-search-site, .js-search-etc-gateway'), (searchForm) => {
  const searchInput = searchForm.querySelector('.b-search-form__input');

  if (searchForm.classList.contains('js-search-site')) {
    /* Main site search */
    searchForm._props = {
      type: 'siteSearch'
    };
    const searchUnderscore = searchForm.querySelector('.b-search-form__underscore');
    const searchSubmit = searchForm.querySelector('.b-search-form__submit');
    const searchClear = searchForm.querySelector('.b-search-form__clear');

    const searchDecorate = () => {
      /* underline input field value */
      searchUnderscore.innerHTML = searchInput.value.replace(/\s/g, ' ');
    };

    const searchActivate = () => {
      searchClear.classList.add('b-search-form__clear--hidden');
      if (searchInput.value.length) {
        searchSubmit.classList.remove('b-search-form__submit--hidden');
      } else {
        searchSubmit.classList.add('b-search-form__submit--hidden');
      }
    };

    const searchReset = () => {
      searchClear.classList.add('b-search-form__clear--hidden');
      searchInput.value = '';
      searchDecorate();
    };

    if (searchInput.value.length) {
      searchClear.classList.remove('b-search-form__clear--hidden');
    } else {
      searchSubmit.classList.add('b-search-form__submit--hidden');
    }
    searchInput.focus();
    searchDecorate();
    searchInput.addEventListener('input', () => {
      searchDecorate();
      searchActivate();
    }, false);
    searchClear.addEventListener('click', searchReset, false);
  } else if (searchForm.classList.contains('js-search-etc-gateway')) {
    /* EtC landing pg search */
    searchForm._props = {
      type: 'etcGatewaySearch',
      suggestionsTop: 'http://vam-etc-test.azureedge.net/assets/data/suggestions.json',
      suggestionsAPI: 'http://vam-etc-test-api.azureedge.net/api/v2/sayt/search'
    };

    const suggestionsEl = searchForm.querySelector('.b-search-form__suggestions');

    const autoSuggest = (term, suggestion) => {
      const suggestEl = document.createElement('a');
      if (suggestionsEl.childElementCount < 10) {
        const url = suggestion.uniqueID;
        const title = suggestion.displayName || suggestion.displayTerm;
        suggestEl.className = 'b-search-form__suggestion';
        suggestEl.href = url;
        suggestEl.tabindex = 0;
        suggestEl.role = 'option';
        suggestEl.innerHTML = `

            ${suggestion.index}

          ${title}
        `;
        suggestEl.tracking = {
          event: 'autosuggest EtC landing',
          eventCategory: `search - autosuggest - ${suggestion.index}`,
          eventAction: term,
          eventLabel: url
        };
        suggestEl.addEventListener('click', trackAutosuggest);
        suggestionsEl.appendChild(suggestEl);
      }
    };

    loadSuggestions(searchForm)
      .then(() => {
        let aborter = null;
        searchInput.addEventListener('input', () => {
          searchForm.removeAttribute('suggesting');
          suggestionsEl.innerHTML = '';
          if (searchInput.value.length) {
            const term = searchInput.value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
            /* title (or one of the pipe delimited terms for hot-topics)
             * begins with search term */
            let regExStart = '(^|\\|)';
            if (searchInput.value.length > 2) {
              /* any word in the title begins with search term
               * (all hot-topic terms get tested since pipe delimiters count as word-boundaries) */
              regExStart = '\\b';
            }
            const regEx = new RegExp(`${regExStart}${term}.*`, 'i');
            Array.from(searchForm._props.storedSuggestions.data, (result) => {
              Array.from(result.suggestions, (suggestion) => {
                const name = suggestion.displayName;
                if (regEx.test(name)) {
                  searchForm.setAttribute('suggesting', true);
                  autoSuggest(searchInput.value, suggestion);
                }
                return true;
              });
              return true;
            });
            if (searchInput.value.length > 4) {
              // cancel pending request if any
              if (aborter) aborter.abort();
              // make our request cancellable
              aborter = new window.AbortController();
              setTimeout(() => aborter.abort(), 500);
              fetch(`${searchForm._props.suggestionsAPI}?q=${encodeURI(term)}&page_size=10`, { signal: aborter.signal })
                .then(response => response.json())
                .then((data) => {
                  if (data.info.totalrecords > 0) {
                    searchForm.setAttribute('suggesting', true);
                    Array.from(data.records, (suggestion) => {
                      autoSuggest(searchInput.value, suggestion);
                      return true;
                    });
                  }
                })
                .catch(e => console.error(e.name, e.message)); // eslint-disable-line no-console
            }
          }
        }, false);
      })
      .catch(e => console.error(e.name, e.message)); // eslint-disable-line no-console

    Array.from(searchForm.querySelectorAll('.b-search-form__filter-toggle'), (toggle) => {
      toggle.addEventListener('click', () => {
        toggle.closest('.b-search-form__filter-toggle-set').toggleAttribute('active');
      }, false);
      return true;
    });
  }
  return true;
});
/* eslint-enable no-underscore-dangle */
<commit_msg>search-form etc API updates<commit_after>/* eslint-disable no-underscore-dangle */
const loadSuggestions = (searchForm) => {
  searchForm._props.storedSuggestions = JSON.parse(sessionStorage.getItem(`storedSuggestions_${searchForm._props.type}`));
  const now = new Date();
  if (!searchForm._props.storedSuggestions
    || now.getTime() > searchForm._props.storedSuggestions.expires) {
    const promise = fetch(searchForm._props.suggestionsTop, { cache: 'no-cache' })
      .then(response => response.json())
      .then((data) => {
        const suggestions = {
          expires: now.getTime() + (15 * 60000),
          data
        };
        searchForm._props.storedSuggestions = suggestions;
        sessionStorage.setItem(`storedSuggestions_${searchForm._props.type}`, JSON.stringify(searchForm._props.storedSuggestions));
      })
      .catch(e => console.error(e.name, e.message)); // eslint-disable-line no-console
    return promise;
  }
  return Promise.resolve(true);
};

const trackAutosuggest = (e) => {
  window.dataLayer.push({
    event: e.target.tracking.event,
    eventCategory: e.target.tracking.eventCategory,
    eventAction: e.target.tracking.eventAction,
    eventLabel: e.target.tracking.eventLabel
  });
};

Array.from(document.querySelectorAll('.js-search-site, .js-search-etc-gateway'), (searchForm) => {
  const searchInput = searchForm.querySelector('.b-search-form__input');

  if (searchForm.classList.contains('js-search-site')) {
    /* Main site search */
    searchForm._props = {
      type: 'siteSearch'
    };
    const searchUnderscore = searchForm.querySelector('.b-search-form__underscore');
    const searchSubmit = searchForm.querySelector('.b-search-form__submit');
    const searchClear = searchForm.querySelector('.b-search-form__clear');

    const searchDecorate = () => {
      /* underline input field value */
      searchUnderscore.innerHTML = searchInput.value.replace(/\s/g, ' ');
    };

    const searchActivate = () => {
      searchClear.classList.add('b-search-form__clear--hidden');
      if (searchInput.value.length) {
        searchSubmit.classList.remove('b-search-form__submit--hidden');
      } else {
        searchSubmit.classList.add('b-search-form__submit--hidden');
      }
    };

    const searchReset = () => {
      searchClear.classList.add('b-search-form__clear--hidden');
      searchInput.value = '';
      searchDecorate();
    };

    if (searchInput.value.length) {
      searchClear.classList.remove('b-search-form__clear--hidden');
    } else {
      searchSubmit.classList.add('b-search-form__submit--hidden');
    }
    searchInput.focus();
    searchDecorate();
    searchInput.addEventListener('input', () => {
      searchDecorate();
      searchActivate();
    }, false);
    searchClear.addEventListener('click', searchReset, false);
  } else if (searchForm.classList.contains('js-search-etc-gateway')) {
    /* EtC landing pg search */
    searchForm._props = {
      type: 'etcGatewaySearch',
      suggestionsTop: 'http://vam-etc-test.azureedge.net/assets/data/suggestions.json',
      suggestionsAPI: 'http://vam-etc-test-api.azureedge.net/api/v2/sayt/search'
    };

    const suggestionsEl = searchForm.querySelector('.b-search-form__suggestions');

    const autoSuggest = (term, suggestion) => {
      const suggestEl = document.createElement('a');
      if (suggestionsEl.childElementCount < 10) {
        const title = suggestion.displayName || suggestion.displayTerm;
        const url = `http://vam-etc-test.azureedge.net/search/?id_${suggestion.index.toLowerCase()}=${suggestion.uniqueID}`;
        suggestEl.className = 'b-search-form__suggestion';
        suggestEl.href = url;
        suggestEl.tabindex = 0;
        suggestEl.role = 'option';
        suggestEl.innerHTML = `

            ${suggestion.index}

          ${title}
        `;
        suggestEl.tracking = {
          event: 'autosuggest EtC landing',
          eventCategory: `search - autosuggest - ${suggestion.index}`,
          eventAction: term,
          eventLabel: url
        };
        suggestEl.addEventListener('click', trackAutosuggest);
        suggestionsEl.appendChild(suggestEl);
      }
    };

    loadSuggestions(searchForm)
      .then(() => {
        let aborter = null;
        searchInput.addEventListener('input', () => {
          searchForm.removeAttribute('suggesting');
          suggestionsEl.innerHTML = '';
          if (searchInput.value.length) {
            const term = searchInput.value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
            /* title (or one of the pipe delimited terms for hot-topics)
             * begins with search term */
            let regExStart = '(^|\\|)';
            if (searchInput.value.length > 2) {
              /* any word in the title begins with search term
               * (all hot-topic terms get tested since pipe delimiters count as word-boundaries) */
              regExStart = '\\b';
            }
            const regEx = new RegExp(`${regExStart}${term}.*`, 'i');
            Array.from(searchForm._props.storedSuggestions.data, (result) => {
              Array.from(result.suggestions, (suggestion) => {
                const name = suggestion.displayName;
                if (regEx.test(name)) {
                  searchForm.setAttribute('suggesting', true);
                  autoSuggest(searchInput.value, suggestion);
                }
                return true;
              });
              return true;
            });
            if (searchInput.value.length > 4) {
              // cancel pending request if any
              if (aborter) aborter.abort();
              // make our request cancellable
              aborter = new window.AbortController();
              setTimeout(() => aborter.abort(), 500);
              fetch(`${searchForm._props.suggestionsAPI}?q=${encodeURI(term)}&page_size=10`, { signal: aborter.signal })
                .then(response => response.json())
                .then((data) => {
                  if (data.info.totalrecords > 0) {
                    searchForm.setAttribute('suggesting', true);
                    Array.from(data.records, (suggestion) => {
                      autoSuggest(searchInput.value, suggestion);
                      return true;
                    });
                  }
                })
                .catch(e => console.error(e.name, e.message)); // eslint-disable-line no-console
            }
          }
        }, false);
      })
      .catch(e => console.error(e.name, e.message)); // eslint-disable-line no-console

    Array.from(searchForm.querySelectorAll('.b-search-form__filter-toggle'), (toggle) => {
      toggle.addEventListener('click', () => {
        toggle.closest('.b-search-form__filter-toggle-set').toggleAttribute('active');
      }, false);
      return true;
    });
  }
  return true;
});
/* eslint-enable no-underscore-dangle */
<|endoftext|>


<commit_before>// Copyright 2014, Renasar Technologies Inc.
/* jshint: node:true */

'use strict';

var di = require('di');

module.exports = taskProtocolFactory;

di.annotate(taskProtocolFactory, new di.Provide('Protocol.Task'));
di.annotate(taskProtocolFactory,
    new di.Inject(
        'Q',
        'Assert',
        'Constants',
        'Services.Messenger',
        '_',
        'Result'
    )
);

function taskProtocolFactory (Q, assert, Constants, messenger, _, Result) {
    function TaskProtocol() {
    }

    TaskProtocol.prototype.run = function (taskId, args) {
        assert.uuid(taskId);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'run' + '.' + taskId,
            new Result({ value: args || {} })
        );
    };

    TaskProtocol.prototype.cancel = function (taskId, args) {
        assert.uuid(taskId);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'cancel' + '.' + taskId,
            new Result({ value: args || {} })
        );
    };

    TaskProtocol.prototype.publishCommandResults = function (routingKey, results) {
        assert.string(routingKey);
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            routingKey,
            new Result({ value: results })
        );
    };

    TaskProtocol.prototype.requestProfile = function (id, args) {
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProfile' + '.' + id,
            args || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.requestProperties = function requestProperties(id, args) {
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProperties' + '.' + id,
            args || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.requestCommands = function requestCommands(id, args) {
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestCommands' + '.' + id,
            args || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.respondCommands = function respondCommands(id, data) {
        assert.string(id);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.respondCommands' + '.' + id,
            new Result({ value: data || {} })
        );
    };

    TaskProtocol.prototype.getBootFile = function (nodeId, options) {
        assert.isMongoId(nodeId);
        assert.object(options, 'options');

        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.getBootFile' + '.' + nodeId,
            options || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.activeTaskExists = function (nodeId) {
        assert.isMongoId(nodeId);

        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.activeTaskExists' + '.' + nodeId,
            nodeId
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.subscribeRun = function(taskId, callback) {
        assert.ok(taskId);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'run' + '.' + taskId,
            callback
        );
    };

    TaskProtocol.prototype.subscribeCancel = function(taskId, callback) {
        assert.ok(taskId);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'cancel' + '.' + taskId,
            callback
        );
    };

    TaskProtocol.prototype.subscribeRequestProperties = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProperties' + '.' + identifier,
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    return message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    return message.reject(error);
                });
            }
        );
    };

    TaskProtocol.prototype.subscribeRequestProfile = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProfile' + '.' + identifier,
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    return message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    return message.reject(error);
                });
            }
        );
    };

    TaskProtocol.prototype.subscribeRequestCommands = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestCommands' + '.' + identifier,
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    return message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    return message.reject(error);
                });
            }
        );
    };

    TaskProtocol.prototype.subscribeRespondCommands = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.respondCommands' + '.' + identifier,
            callback
        );
    };

    // NOTE: subscribes onto the events exchange
    TaskProtocol.prototype.subscribeDhcpBoundLease = function (nodeId, callback) {
        assert.isMongoId(nodeId);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Events.Name,
            'dhcp.bind.success' + '.' + nodeId,
            callback
        );
    };

    // NOTE: subscribes onto the events exchange
    TaskProtocol.prototype.subscribeTftpSuccess = function (nodeId, callback) {
        assert.isMongoId(nodeId);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Events.Name,
            'tftp.success' + '.' + nodeId,
            callback
        );
    };

    // NOTE: subscribes onto the events exchange
    TaskProtocol.prototype.subscribeHttpResponse = function (nodeId, callback) {
        assert.isMongoId(nodeId);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Events.Name,
            'http.response' + '.' + nodeId,
            callback
        );
    };

    TaskProtocol.prototype.publishRunIpmiCommand = function (uuid, command, data) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.object(data);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, uuid].join('.'),
            new Result({ value: data })
        );
    };

    TaskProtocol.prototype.subscribeRunIpmiCommand = function (uuid, command, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, uuid].join('.'),
            callback
        );
    };

    TaskProtocol.prototype.subscribeIpmiCommandResult = function (uuid, command, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, 'result', uuid].join('.'),
            callback
        );
    };

    TaskProtocol.prototype.publishIpmiCommandResult = function (uuid, command, results) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, 'result', uuid].join('.'),
            new Result({ value: results })
        );
    };

    TaskProtocol.prototype.publishRunSnmpCommand = function (uuid, data) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.object(data);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'run.snmp.command' + '.' + uuid,
            new Result({ value: data })
        );
    };

    TaskProtocol.prototype.subscribeRunSnmpCommand = function (uuid, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'run.snmp.command' + '.' + uuid,
            callback
        );
    };

    TaskProtocol.prototype.subscribeSnmpCommandResult = function (uuid, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'snmp.command.result' + '.' + uuid,
            callback
        );
    };

    TaskProtocol.prototype.publishSnmpCommandResult = function (uuid, results) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'snmp.command.result' + '.' + uuid,
            new Result({ value: results })
        );
    };

    // NOTE: publishes onto the events exchange
    TaskProtocol.prototype.publishPollerAlert = function (uuid, results) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Events.Name,
            'poller.alert' + '.' + uuid,
            new Result({ value: results })
        );
    };

    return new TaskProtocol();
}
<commit_msg>Add poller cache protocol methods<commit_after>// Copyright 2014, Renasar Technologies Inc.
/* jshint: node:true */

'use strict';

var di = require('di');

module.exports = taskProtocolFactory;

di.annotate(taskProtocolFactory, new di.Provide('Protocol.Task'));
di.annotate(taskProtocolFactory,
    new di.Inject(
        'Q',
        'Assert',
        'Constants',
        'Services.Messenger',
        '_',
        'Result'
    )
);

function taskProtocolFactory (Q, assert, Constants, messenger, _, Result) {
    function TaskProtocol() {
    }

    TaskProtocol.prototype.run = function (taskId, args) {
        assert.uuid(taskId);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'run' + '.' + taskId,
            new Result({ value: args || {} })
        );
    };

    TaskProtocol.prototype.cancel = function (taskId, args) {
        assert.uuid(taskId);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'cancel' + '.' + taskId,
            new Result({ value: args || {} })
        );
    };

    TaskProtocol.prototype.publishCommandResults = function (routingKey, results) {
        assert.string(routingKey);
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            routingKey,
            new Result({ value: results })
        );
    };

    TaskProtocol.prototype.requestProfile = function (id, args) {
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProfile' + '.' + id,
            args || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.requestProperties = function requestProperties(id, args) {
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProperties' + '.' + id,
            args || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.requestCommands = function requestCommands(id, args) {
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestCommands' + '.' + id,
            args || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.respondCommands = function respondCommands(id, data) {
        assert.string(id);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.respondCommands' + '.' + id,
            new Result({ value: data || {} })
        );
    };

    TaskProtocol.prototype.getBootFile = function (nodeId, options) {
        assert.isMongoId(nodeId);
        assert.object(options, 'options');

        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.getBootFile' + '.' + nodeId,
            options || {}
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.activeTaskExists = function (nodeId) {
        assert.isMongoId(nodeId);

        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.activeTaskExists' + '.' + nodeId,
            nodeId
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.subscribeRun = function(taskId, callback) {
        assert.ok(taskId);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'run' + '.' + taskId,
            callback
        );
    };

    TaskProtocol.prototype.subscribeCancel = function(taskId, callback) {
        assert.ok(taskId);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'cancel' + '.' + taskId,
            callback
        );
    };

    TaskProtocol.prototype.subscribeRequestProperties = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProperties' + '.' + identifier,
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    return message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    return message.reject(error);
                });
            }
        );
    };

    TaskProtocol.prototype.subscribeRequestProfile = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestProfile' + '.' + identifier,
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    return message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    return message.reject(error);
                });
            }
        );
    };

    TaskProtocol.prototype.subscribeRequestCommands = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestCommands' + '.' + identifier,
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    return message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    return message.reject(error);
                });
            }
        );
    };

    TaskProtocol.prototype.subscribeRespondCommands = function (identifier, callback) {
        assert.ok(identifier);
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.respondCommands' + '.' + identifier,
            callback
        );
    };

    // NOTE: subscribes onto the events exchange
    TaskProtocol.prototype.subscribeDhcpBoundLease = function (nodeId, callback) {
        assert.isMongoId(nodeId);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Events.Name,
            'dhcp.bind.success' + '.' + nodeId,
            callback
        );
    };

    // NOTE: subscribes onto the events exchange
    TaskProtocol.prototype.subscribeTftpSuccess = function (nodeId, callback) {
        assert.isMongoId(nodeId);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Events.Name,
            'tftp.success' + '.' + nodeId,
            callback
        );
    };

    // NOTE: subscribes onto the events exchange
    TaskProtocol.prototype.subscribeHttpResponse = function (nodeId, callback) {
        assert.isMongoId(nodeId);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Events.Name,
            'http.response' + '.' + nodeId,
            callback
        );
    };

    TaskProtocol.prototype.publishRunIpmiCommand = function (uuid, command, data) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.object(data);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, uuid].join('.'),
            new Result({ value: data })
        );
    };

    TaskProtocol.prototype.subscribeRunIpmiCommand = function (uuid, command, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, uuid].join('.'),
            callback
        );
    };

    TaskProtocol.prototype.subscribeIpmiCommandResult = function (uuid, command, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, 'result', uuid].join('.'),
            callback
        );
    };

    TaskProtocol.prototype.publishIpmiCommandResult = function (uuid, command, results) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.string(command);
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            ['ipmi', 'command', command, 'result', uuid].join('.'),
            new Result({ value: results })
        );
    };

    TaskProtocol.prototype.publishRunSnmpCommand = function (uuid, data) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.object(data);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'run.snmp.command' + '.' + uuid,
            new Result({ value: data })
        );
    };

    TaskProtocol.prototype.subscribeRunSnmpCommand = function (uuid, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'run.snmp.command' + '.' + uuid,
            callback
        );
    };

    TaskProtocol.prototype.subscribeSnmpCommandResult = function (uuid, callback) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.func(callback, 'callback');

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'snmp.command.result' + '.' + uuid,
            callback
        );
    };

    TaskProtocol.prototype.publishSnmpCommandResult = function (uuid, results) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Task.Name,
            'snmp.command.result' + '.' + uuid,
            new Result({ value: results })
        );
    };

    // NOTE: publishes onto the events exchange
    TaskProtocol.prototype.publishPollerAlert = function (uuid, results) {
        assert.uuid(uuid, 'routing key uuid suffix');
        assert.object(results);

        return messenger.publish(
            Constants.Protocol.Exchanges.Events.Name,
            'poller.alert' + '.' + uuid,
            new Result({ value: results })
        );
    };

    TaskProtocol.prototype.requestPollerCache = function requestPollerCache(workItemId) {
        assert.string(workItemId);
        return messenger.request(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestPollerCache',
            new Result({ value: workItemId })
        ).then(function (data) {
            return data.value;
        });
    };

    TaskProtocol.prototype.subscribeRequestPollerCache = function (callback) {
        assert.func(callback);

        return messenger.subscribe(
            Constants.Protocol.Exchanges.Task.Name,
            'methods.requestPollerCache',
            function(data, message) {
                Q.resolve(
                    callback()
                ).then(function (result) {
                    message.resolve(
                        new Result({ value: result })
                    );
                }).catch(function (error) {
                    message.reject(error);
                });
            }
        );
    };

    return new TaskProtocol();
}
<|endoftext|>


<commit_before>import React from "react";
import { shallow } from "enzyme";
import * as actions from "../../actions/fuelSavingsActions";
import ConnectedFuelSavingsPage, { FuelSavingsPage } from "./FuelSavingsPage";
import FuelSavingsForm from "../FuelSavingsForm";
import { fuelSavings } from "../../types/index";

describe("<FuelSavingsPage />", () => {
  it("should contain <FuelSavingsForm />", () => {
    const actions = {
      saveFuelSavings: () => {},
      calculateFuelSavings: () => {}
    };
    const fuelSavings = {};
    const wrapper = shallow(
      <FuelSavingsPage actions={actions} fuelSavings={fuelSavings} />
    );

    expect(wrapper.find(FuelSavingsForm).length).toEqual(1);
  });

  // App integration test
  it("should display results when populated", () => {
    const wrapper = shallow(
      <ConnectedFuelSavingsPage actions={actions} fuelSavings={fuelSavings} />
    ).dive(); // Use dive to get reference to child component.
    expect(wrapper.find(".results")).toBe(true);
  });
});
<commit_msg>Remove experimental test - accidentally committed<commit_after>import React from "react";
import { shallow } from "enzyme";
import {FuelSavingsPage} from "./FuelSavingsPage";
import FuelSavingsForm from "../FuelSavingsForm";

describe("<FuelSavingsPage />", () => {
  it("should contain <FuelSavingsForm />", () => {
    const actions = {
      saveFuelSavings: () => {},
      calculateFuelSavings: () => {}
    };
    const fuelSavings = {};
    const wrapper = shallow(
      <FuelSavingsPage actions={actions} fuelSavings={fuelSavings} />
    );

    expect(wrapper.find(FuelSavingsForm).length).toEqual(1);
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { ValidationsContext } from './form-with-validations.hoc';
import validator from '../../utils/validations/validator';
import VALIDATION_TYPES from './validation-types.config';
import ValidationIcon from './validation-icon.component';
import OptionsHelper from '../../utils/helpers/options-helper/options-helper';

const { validationTypes } = OptionsHelper;
const validationShape = PropTypes.shape({
  message: PropTypes.func,
  validate: PropTypes.func
});
const validationsPropTypes = PropTypes.oneOfType([
  PropTypes.func,
  PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, validationShape]))
]);

const withValidation = (WrappedComponent) => {
  class WithValidation extends React.Component {
    state = {
      errorMessage: '',
      warningMessage: '',
      infoMessage: '',
      value: ''
    };

    componentDidMount() {
      this.updateFormState(this.props.value || this.state.value);

      if (this.checkValidations()) {
        this.context.addInput(this.props.name, this.validate);
      }
    }

    componentWillUnmount() {
      if (this.checkContext('removeInput')) this.context.removeInput(this.props.name);
    }

    componentDidUpdate(prevProps) {
      const isUpdateForced = prevProps.forceUpdateTriggerToggle !== this.props.forceUpdateTriggerToggle;

      if (this.isUpdatedValidationProps(prevProps) && this.checkValidations()) {
        this.context.addInput(this.props.name, this.validate);
        this.updateFormState(this.props.value || this.state.value);
      }

      if (isUpdateForced || prevProps.value !== this.props.value) {
        this.validate();
      }
    }

    isUpdatedValidationProps(prevProps) {
      let updated = false;

      if (this.props.validations !== prevProps.validations) updated = true;

      return updated;
    }

    checkValidations() {
      if (!this.checkContext('addInput')) return false;

      let hasValidations = false;
      validationTypes.forEach((validationType) => {
        const type = VALIDATION_TYPES[validationType];
        const validation = this.props[type];
        const isArray = Array.isArray(validation);
        const isPopulatedArray = isArray && validation.length;
        const isDefined = typeof validation !== 'undefined';
        if (isPopulatedArray || (!isArray && isDefined)) {
          hasValidations = true;
        }
      });

      return hasValidations;
    }

    checkContext(contextProp) {
      return this.context && this.context[contextProp];
    }

    validate = (types = validationTypes, isOnSubmit) => {
      if (!isOnSubmit && this.blockValidation) return new Promise(resolve => resolve(true));

      const validationPromises = [];
      types.forEach((type) => {
        const validationPromise = this.runValidation(type);
        if (validationPromise) validationPromises.push(validationPromise);
      });
      return Promise.all(validationPromises).then((results) => {
        return !results.includes(false);
      });
    }

    updateValidationStatus(type, newMessage = '') {
      if (type === 'error') this.updateErrorStatus(newMessage);
      if (type === 'warning') this.updateWarningStatus(newMessage);
      if (type === 'info') this.updateInfoStatus(newMessage);
    }

    updateErrorStatus(newMessage) {
      const hasErrorMessage = this.state.errorMessage !== '';

      this.adjustFormValidationCount('error', newMessage, hasErrorMessage);
      this.setState({ errorMessage: newMessage });
    }

    updateWarningStatus(newMessage) {
      const hasWarningMessage = this.state.warningMessage !== '';
      const hasErrorMessage = this.state.errorMessage !== '';

      if (hasErrorMessage) return;

      this.adjustFormValidationCount('warning', newMessage, hasWarningMessage);
      this.setState({ warningMessage: newMessage });
    }

    updateInfoStatus(newMessage) {
      const hasinfoMessage = this.state.infoMessage !== '';
      const hasErrorMessage = this.state.errorMessage !== '';

      if (hasErrorMessage) return;

      this.adjustFormValidationCount('info', newMessage, hasinfoMessage);
      this.setState({ infoMessage: newMessage });
    }

    adjustFormValidationCount(type, newMessage, hasExistingMessage) {
      const hasNewMessage = newMessage !== '';

      if (!this.context || !this.context.adjustCount) return;

      if (hasNewMessage && !hasExistingMessage) {
        this.context.adjustCount(type, true);
      } else if (!hasNewMessage && hasExistingMessage) {
        this.context.adjustCount(type);
      }
    }

    runValidation(validationType) {
      const type = VALIDATION_TYPES[validationType];
      if (typeof this.props[type] === 'undefined') return null;
      if (Array.isArray(this.props[type]) && this.props[type].length === 0) return null;

      return new Promise((resolve) => {
        setTimeout(() => {
          validator(this.props[type])(this.props.value || this.state.value, this.props)
            .then(() => {
              this.updateValidationStatus(validationType);
              return resolve(true);
            })
            .catch((error) => {
              this.updateValidationStatus(validationType, error.message);
              return resolve(false);
            });
        }, 100); // allow 100ms delay to accommodate for browser events
      });
    }

    renderValidationMarkup() {
      const validationIconProps = this.getValidationIconProps();

      if (!validationIconProps) return null;

      return (
        <ValidationIcon { ...validationIconProps } />
      );
    }

    getValidationIconProps() {
      const { errorMessage, warningMessage, infoMessage } = this.state;
      let validationIconProps;

      if (errorMessage) {
        validationIconProps = {
          type: 'error',
          message: errorMessage
        };
      } else if (warningMessage) {
        validationIconProps = {
          type: 'warning',
          message: warningMessage
        };
      } else if (infoMessage) {
        validationIconProps = {
          type: 'info',
          message: infoMessage
        };
      }

      return validationIconProps;
    }

    handleBlur = (ev) => {
      this.blockValidation = false;
      this.validate();

      if (this.props.onBlur) this.props.onBlur(ev);
    }

    handleChange = (ev) => {
      this.blockValidation = true;
      this.resetValidation();

      this.setState(
        { value: ev.target.value },
        () => this.updateFormState()
      );

      if (this.props.onChange) {
        this.props.onChange(ev);
      }
    }

    resetValidation() {
      if (this.state.errorMessage) {
        this.updateValidationStatus('error');
        this.setState({ errorMessage: '' });
      }

      if (this.state.warningMessage) {
        this.updateValidationStatus('warning');
        this.setState({ warningMessage: '' });
      }

      if (this.state.infoMessage) {
        this.updateValidationStatus('info');
        this.setState({ infoMessage: '' });
      }
    }

    updateFormState(value = this.state.value) {
      if (this.props.addInputToFormState) {
        this.props.addInputToFormState(this.props.name, value);
      }
    }

    getValidationStatuses() {
      return {
        hasError: !!this.state.errorMessage,
        hasWarning: !!this.state.warningMessage,
        hasInfo: !!this.state.infoMessage
      };
    }

    render() {
      return (
        <WrappedComponent
          { ...this.getValidationStatuses() }
          { ...this.props }
          onBlur={ this.handleBlur }
          onChange={ this.handleChange }
        >
          { this.props.children }
          { this.renderValidationMarkup() }
        </WrappedComponent>
      );
    }
  }

  WithValidation.contextType = ValidationsContext;

  WithValidation.propTypes = {
    children: PropTypes.node, // Children elements
    name: PropTypes.string.isRequired, // Name to uniquely identify the component
    value: PropTypes.string, // The current value of the component
    onBlur: PropTypes.func, // Custom function to be called when the component blurs
    onChange: PropTypes.func, // Custom function called when component value changes
    validations: validationsPropTypes,
    warnings: validationsPropTypes,
    info: validationsPropTypes,
    forceUpdateTriggerToggle: PropTypes.bool, // triggers validation when it's boolean value changes
    addInputToFormState: PropTypes.func
  };

  WithValidation.defaultProps = {
    validations: [],
    warnings: [],
    info: []
  };

  const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
  WithValidation.displayName = `WithValidation(${displayName})`;

  return WithValidation;
};

export { validationsPropTypes };
export default withValidation;
<commit_msg>(FE-1844) Fix bug FE-1848: `withValidation`: incorrect `value` propType<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { ValidationsContext } from './form-with-validations.hoc';
import validator from '../../utils/validations/validator';
import VALIDATION_TYPES from './validation-types.config';
import ValidationIcon from './validation-icon.component';
import OptionsHelper from '../../utils/helpers/options-helper/options-helper';

const { validationTypes } = OptionsHelper;
const validationShape = PropTypes.shape({
  message: PropTypes.func,
  validate: PropTypes.func
});
const validationsPropTypes = PropTypes.oneOfType([
  PropTypes.func,
  PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, validationShape]))
]);

const withValidation = (WrappedComponent) => {
  class WithValidation extends React.Component {
    state = {
      errorMessage: '',
      warningMessage: '',
      infoMessage: '',
      value: ''
    };

    componentDidMount() {
      this.updateFormState(this.props.value || this.state.value);

      if (this.checkValidations()) {
        this.context.addInput(this.props.name, this.validate);
      }
    }

    componentWillUnmount() {
      if (this.checkContext('removeInput')) this.context.removeInput(this.props.name);
    }

    componentDidUpdate(prevProps) {
      const isUpdateForced = prevProps.forceUpdateTriggerToggle !== this.props.forceUpdateTriggerToggle;

      if (this.isUpdatedValidationProps(prevProps) && this.checkValidations()) {
        this.context.addInput(this.props.name, this.validate);
        this.updateFormState(this.props.value || this.state.value);
      }

      if (isUpdateForced || prevProps.value !== this.props.value) {
        this.validate();
      }
    }

    isUpdatedValidationProps(prevProps) {
      let updated = false;

      if (this.props.validations !== prevProps.validations) updated = true;

      return updated;
    }

    checkValidations() {
      if (!this.checkContext('addInput')) return false;

      let hasValidations = false;
      validationTypes.forEach((validationType) => {
        const type = VALIDATION_TYPES[validationType];
        const validation = this.props[type];
        const isArray = Array.isArray(validation);
        const isPopulatedArray = isArray && validation.length;
        const isDefined = typeof validation !== 'undefined';
        if (isPopulatedArray || (!isArray && isDefined)) {
          hasValidations = true;
        }
      });

      return hasValidations;
    }

    checkContext(contextProp) {
      return this.context && this.context[contextProp];
    }

    validate = (types = validationTypes, isOnSubmit) => {
      if (!isOnSubmit && this.blockValidation) return new Promise(resolve => resolve(true));

      const validationPromises = [];
      types.forEach((type) => {
        const validationPromise = this.runValidation(type);
        if (validationPromise) validationPromises.push(validationPromise);
      });
      return Promise.all(validationPromises).then((results) => {
        return !results.includes(false);
      });
    }

    updateValidationStatus(type, newMessage = '') {
      if (type === 'error') this.updateErrorStatus(newMessage);
      if (type === 'warning') this.updateWarningStatus(newMessage);
      if (type === 'info') this.updateInfoStatus(newMessage);
    }

    updateErrorStatus(newMessage) {
      const hasErrorMessage = this.state.errorMessage !== '';

      this.adjustFormValidationCount('error', newMessage, hasErrorMessage);
      this.setState({ errorMessage: newMessage });
    }

    updateWarningStatus(newMessage) {
      const hasWarningMessage = this.state.warningMessage !== '';
      const hasErrorMessage = this.state.errorMessage !== '';

      if (hasErrorMessage) return;

      this.adjustFormValidationCount('warning', newMessage, hasWarningMessage);
      this.setState({ warningMessage: newMessage });
    }

    updateInfoStatus(newMessage) {
      const hasinfoMessage = this.state.infoMessage !== '';
      const hasErrorMessage = this.state.errorMessage !== '';

      if (hasErrorMessage) return;

      this.adjustFormValidationCount('info', newMessage, hasinfoMessage);
      this.setState({ infoMessage: newMessage });
    }

    adjustFormValidationCount(type, newMessage, hasExistingMessage) {
      const hasNewMessage = newMessage !== '';

      if (!this.context || !this.context.adjustCount) return;

      if (hasNewMessage && !hasExistingMessage) {
        this.context.adjustCount(type, true);
      } else if (!hasNewMessage && hasExistingMessage) {
        this.context.adjustCount(type);
      }
    }

    runValidation(validationType) {
      const type = VALIDATION_TYPES[validationType];
      if (typeof this.props[type] === 'undefined') return null;
      if (Array.isArray(this.props[type]) && this.props[type].length === 0) return null;

      return new Promise((resolve) => {
        setTimeout(() => {
          validator(this.props[type])(this.props.value || this.state.value, this.props)
            .then(() => {
              this.updateValidationStatus(validationType);
              return resolve(true);
            })
            .catch((error) => {
              this.updateValidationStatus(validationType, error.message);
              return resolve(false);
            });
        }, 100); // allow 100ms delay to accommodate for browser events
      });
    }

    renderValidationMarkup() {
      const validationIconProps = this.getValidationIconProps();

      if (!validationIconProps) return null;

      return (
        <ValidationIcon { ...validationIconProps } />
      );
    }

    getValidationIconProps() {
      const { errorMessage, warningMessage, infoMessage } = this.state;
      let validationIconProps;

      if (errorMessage) {
        validationIconProps = {
          type: 'error',
          message: errorMessage
        };
      } else if (warningMessage) {
        validationIconProps = {
          type: 'warning',
          message: warningMessage
        };
      } else if (infoMessage) {
        validationIconProps = {
          type: 'info',
          message: infoMessage
        };
      }

      return validationIconProps;
    }

    handleBlur = (ev) => {
      this.blockValidation = false;
      this.validate();

      if (this.props.onBlur) this.props.onBlur(ev);
    }

    handleChange = (ev) => {
      this.blockValidation = true;
      this.resetValidation();

      this.setState(
        { value: ev.target.value },
        () => this.updateFormState()
      );

      if (this.props.onChange) {
        this.props.onChange(ev);
      }
    }

    resetValidation() {
      if (this.state.errorMessage) {
        this.updateValidationStatus('error');
        this.setState({ errorMessage: '' });
      }

      if (this.state.warningMessage) {
        this.updateValidationStatus('warning');
        this.setState({ warningMessage: '' });
      }

      if (this.state.infoMessage) {
        this.updateValidationStatus('info');
        this.setState({ infoMessage: '' });
      }
    }

    updateFormState(value = this.state.value) {
      if (this.props.addInputToFormState) {
        this.props.addInputToFormState(this.props.name, value);
      }
    }

    getValidationStatuses() {
      return {
        hasError: !!this.state.errorMessage,
        hasWarning: !!this.state.warningMessage,
        hasInfo: !!this.state.infoMessage
      };
    }

    render() {
      return (
        <WrappedComponent
          { ...this.getValidationStatuses() }
          { ...this.props }
          onBlur={ this.handleBlur }
          onChange={ this.handleChange }
        >
          { this.props.children }
          { this.renderValidationMarkup() }
        </WrappedComponent>
      );
    }
  }

  WithValidation.contextType = ValidationsContext;

  WithValidation.propTypes = {
    children: PropTypes.node, // Children elements
    name: PropTypes.string.isRequired, // Name to uniquely identify the component
    value: PropTypes.oneOfType([ // The current value of the component
      PropTypes.string,
      PropTypes.array
    ]),
    onBlur: PropTypes.func, // Custom function to be called when the component blurs
    onChange: PropTypes.func, // Custom function called when component value changes
    validations: validationsPropTypes,
    warnings: validationsPropTypes,
    info: validationsPropTypes,
    forceUpdateTriggerToggle: PropTypes.bool, // triggers validation when it's boolean value changes
    addInputToFormState: PropTypes.func
  };

  WithValidation.defaultProps = {
    validations: [],
    warnings: [],
    info: []
  };

  const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
  WithValidation.displayName = `WithValidation(${displayName})`;

  return WithValidation;
};

export { validationsPropTypes };
export default withValidation;
<|endoftext|>


<commit_before>import React, {Component, Fragment} from "react";
import gql from "graphql-tag.macro";
import {graphql, withApollo} from "react-apollo";
import {Container, Row, Col, Button, Input} from "helpers/reactstrap";
import {TypingField} from "../../generic/core";
import SubscriptionHelper from "helpers/subscriptionHelper";
import {FaSyncAlt} from "react-icons/fa";
const SYSTEMS_SUB = gql`
  subscription DamagedSystemsUpdate($simulatorId: ID) {
    systemsUpdate(simulatorId: $simulatorId, extra: true) {
      id
      name
      displayName
      damage {
        damaged
        report
        requested
        reactivationCode
        neededReactivationCode
        currentStep
        validate
        which
      }
      simulatorId
      type
    }
  }
`;

const extra = [
  "Co2 Scrubbers",
  "Fire",
  "Life Support",
  "Power Adjustment",
  "Transporter Buffer",
  "Turbolift Malfunction",
  "Antimatter Containment",
  "Gravity Systems",
  "Hull Breach",
  "Temperature",
  "Holodeck",
  "Brig Force Field",
  "Oxygen Generators",
  "Warp Field Realignment",
  "Computer Power",
  "Particle Detector",
  "Deuterium Fuel",
  "Water Pipes",
  "Food Replicators",
  "Zoology Pens Force Fields",
];

class DamageReportCore extends Component {
  constructor(props) {
    super(props);
    this.systemSub = null;
    this.state = {
      deck: null,
      room: null,
      selectedSystem: null,
      selectedReport: "",
    };
  }
  selectSystem(id, sent) {
    const systems = this.props.data.systems;
    const selectedSystem = systems.find(s => s.id === id);
    this.setState({
      sent: sent ? true : false,
      selectedSystem: id,
      selectedReport: selectedSystem.damage.report || "",
    });
  }
  systemStyle(sys) {
    const obj = {
      listStyle: "none",
      cursor: "pointer",
    };
    if (sys.damage.damaged) {
      obj.color = "red";
    }
    if (!sys.name) {
      obj.color = "purple";
    }
    return obj;
  }
  systemName(sys) {
    if (sys.type === "Shield" && sys.name !== "Shields") {
      return `${sys.name} Shields`;
    }
    return sys.displayName || sys.name;
  }
  loadReport(e) {
    const self = this;
    var reader = new FileReader();
    reader.onload = function() {
      const result = this.result.replace(/\r/gi, "\n");
      self.setState({
        sent: false,
        selectedReport: result,
      });
    };
    e.target.files[0] && reader.readAsText(e.target.files[0]);
  }
  sendReport = () => {
    this.setState({sent: true});
    const mutation = gql`
      mutation DamageReport($systemId: ID!, $report: String!) {
        damageReport(systemId: $systemId, report: $report)
      }
    `;
    const variables = {
      systemId: this.state.selectedSystem,
      report: this.state.selectedReport,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
    setTimeout(() => {
      this.selectSystem(this.state.selectedSystem, true);
    }, 500);
  };
  reactivationCodeResponse = response => {
    const mutation = gql`
      mutation ReactivationCodeResponse($systemId: ID!, $response: Boolean!) {
        systemReactivationCodeResponse(systemId: $systemId, response: $response)
      }
    `;
    const variables = {
      systemId: this.state.selectedSystem,
      response: response,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  createExtraSystem = (sysName, which) => {
    const name = sysName || prompt("What is the name of the system?");
    const systems = this.props.data.systems;
    if (systems.find(s => s.name === name)) {
      this.breakSystem(systems.find(s => s.name === name).id);
      return;
    }
    const mutation = gql`
      mutation CreateExtraSystem($simulatorId: ID!, $params: String!) {
        addSystemToSimulator(
          simulatorId: $simulatorId
          className: "System"
          params: $params
        )
      }
    `;
    const variables = {
      simulatorId: this.props.simulator.id,
      params: JSON.stringify({
        name,
        extra: true,
        damage: {damaged: true, which},
      }),
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  breakSystem = sys => {
    const variables = {
      systemId: sys,
    };
    // Break it
    const mutation = gql`
      mutation DamageSystem($systemId: ID!) {
        damageSystem(systemId: $systemId)
      }
    `;
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  repairSystem = () => {
    const {selectedSystem} = this.state;
    const variables = {
      systemId: selectedSystem,
    };
    // Fix it
    const mutation = gql`
      mutation RepairSystem($systemId: ID!) {
        repairSystem(systemId: $systemId)
      }
    `;
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  generateReport = steps => {
    const mutation = gql`
      mutation GenerateReport($systemId: ID!, $steps: Int) {
        generateDamageReport(systemId: $systemId, steps: $steps)
      }
    `;
    const variables = {systemId: this.state.selectedSystem, steps};
    this.props.client
      .mutate({
        mutation,
        variables,
      })
      .then(res => {
        this.setState({
          sent: false,
          selectedReport: res.data.generateDamageReport,
        });
      });
  };
  rejectStep = () => {
    const mutation = gql`
      mutation SetDamageStepValidation($id: ID!) {
        setDamageStepValidation(id: $id, validation: false)
      }
    `;
    const variables = {
      id: this.state.selectedSystem,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  acceptStep = () => {
    const mutation = gql`
      mutation ValidateDamageStep($id: ID!) {
        validateDamageStep(id: $id)
      }
    `;
    const variables = {
      id: this.state.selectedSystem,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  render() {
    if (this.props.data.loading) return null;
    const systems = this.props.data.systems;
    if (!systems) return null;
    const {selectedReport, selectedSystem, sent} = this.state;
    const selectedSystemObj = systems.find(s => s.id === selectedSystem);
    return (
      <Container fluid className="damageReport-core">
        <SubscriptionHelper
          subscribe={() =>
            this.props.data.subscribeToMore({
              document: SYSTEMS_SUB,
              variables: {
                simulatorId: this.props.simulator.id,
              },
              updateQuery: (previousResult, {subscriptionData}) => {
                return Object.assign({}, previousResult, {
                  systems: subscriptionData.data.systemsUpdate,
                });
              },
            })
          }
        />
        <Row style={{height: "100%"}}>
          <Col
            sm={4}
            className="left-side"
            style={{display: "flex", flexDirection: "column"}}
          >

              {systems
                .filter(s => s.damage.damaged)
                .map(s => (
                  <p
                    key={s.id}
                    className={`${selectedSystem === s.id ? "selected" : ""}  ${
                      s.damage.requested ? "requested" : ""
                    } ${s.damage.report ? "report" : ""} ${
                      s.damage.reactivationCode ? "reactivation" : ""
                    } ${s.damage.validate ? "validate" : ""} ${s.damage.which}`}
                    title={`${s.damage.requested ? "Report Requested : " : ""}${
                      s.damage.report ? "Report Sent : " : ""
                    }${
                      s.damage.reactivationCode
                        ? "Reactivation Code Requested : "
                        : ""
                    }${s.damage.validate ? "Validation Requested : " : ""}`}
                    onClick={this.selectSystem.bind(this, s.id)}
                  >
                    {s.damage.validate ? (
                      <FaSyncAlt className="fa-spin" />
                    ) : null}{" "}
                    {this.systemName(s)} - {s.damage.currentStep + 1} /{" "}
                    {s.damage.report
                      ? s.damage.report
                          .split(/Step [0-9]+:\n/gi)
                          .filter(st => st && st !== "\n").length
                      : 0}

                ))}

            <Input
              type="select"
              value={"top"}
              size="sm"
              style={{height: "20px"}}
              onChange={evt => this.createExtraSystem(evt.target.value)}
            >
              <option disabled value="top">
                Extra Damage
              </option>
              {extra.map(e => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
              <option value="">Add System</option>
            </Input>
            <Input
              type="select"
              value={"top"}
              size="sm"
              className="btn-warning"
              style={{height: "20px"}}
              onChange={evt => this.createExtraSystem(evt.target.value, "rnd")}
            >
              <option disabled value="top">
                Extra {"R&D"}
              </option>
              {extra.map(e => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
              <option value="">Add System</option>
            </Input>
            <Input
              type="select"
              value={"top"}
              size="sm"
              className="btn-primary"
              style={{height: "20px"}}
              onChange={evt =>
                this.createExtraSystem(evt.target.value, "engineering")
              }
            >
              <option disabled value="top">
                Extra Engineering
              </option>
              {extra.map(e => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
              <option value="">Add System</option>
            </Input>
          </Col>
          <Col sm={8} style={{display: "flex", flexDirection: "column"}}>
            <TypingField
              value={selectedReport}
              style={{
                textAlign: "left",
                height: "auto",
                fontFamily: "monospace",
                flex: 1,
              }}
              rows={8}
              controlled={true}
              onChange={e => {
                this.setState({
                  sent: false,
                  selectedReport: e.target.value,
                });
              }}
            />
            {selectedSystemObj && selectedSystemObj.damage.reactivationCode ? (

                <Row style={{margin: 0}}>
                  <Col sm={3}>Code:</Col>
                  <Col sm={9}>{selectedSystemObj.damage.reactivationCode}</Col>
                </Row>
                <Row style={{margin: 0}}>
                  <Col sm={3}>Actual:</Col>
                  <Col sm={9}>
                    {selectedSystemObj.damage.neededReactivationCode}
                  </Col>
                </Row>
                <Row style={{margin: 0}}>
                  <Col sm={8}>
                    <Button
                      onClick={() => {
                        this.reactivationCodeResponse(true);
                      }}
                      size={"sm"}
                      color="success"
                      block
                    >
                      Accept & Fix
                    </Button>
                  </Col>
                  <Col sm={4}>
                    <Button
                      onClick={() => {
                        this.reactivationCodeResponse(false);
                      }}
                      size={"sm"}
                      color="danger"
                      block
                    >
                      Deny
                    </Button>
                  </Col>
                </Row>

            ) : (
              selectedSystem && (
                <Fragment>
                  <Row style={{margin: 0}}>
                    <Col sm={4}>
                      <Button
                        size={"sm"}
                        block
                        color="success"
                        onClick={this.repairSystem}
                      >
                        Repair
                      </Button>
                    </Col>
                    <Col sm={4}>
                      <Input
                        onChange={this.loadReport.bind(this)}
                        style={{position: "absolute", opacity: 0}}
                        value={""}
                        type="file"
                        name="file"
                        id="exampleFile"
                      />
                      <Button size={"sm"} block color="info">
                        Load Report
                      </Button>
                    </Col>
                    <Col sm={4}>
                      <select
                        className="btn btn-warning btn-sm btn-block"
                        onChange={evt => {
                          if (evt.target.value === "set") {
                            const count = window.prompt("How many steps?");
                            if (
                              isNaN(parseInt(count, 10)) ||
                              parseInt(count, 10) <= 0
                            )
                              return;
                            this.generateReport(parseInt(count, 10));

                            return;
                          }
                          this.generateReport(parseInt(evt.target.value, 10));
                        }}
                        value={"select"}
                      >
                        <option value="select">Generate</option>
                        <option value="set">Enter Step Count</option>
                        <option value="3">Superficial</option>
                        <option value="5">Short</option>
                        <option value="8">Medium</option>
                        <option value="12">Long</option>
                      </select>
                    </Col>
                  </Row>
                  <Row style={{margin: 0}}>
                    {selectedSystemObj && selectedSystemObj.damage.validate ? (
                      <Fragment>
                        <Col sm={4}>

                            Validate Step:{" "}
                            {selectedSystemObj.damage.currentStep + 1}

                        </Col>
                        <Col sm={2}>
                          <Button
                            size={"sm"}
                            block
                            color="secondary"
                            onClick={this.acceptStep}
                          >
                            Accept Step
                          </Button>
                        </Col>
                        <Col sm={2}>
                          <Button
                            size={"sm"}
                            block
                            color="danger"
                            onClick={this.rejectStep}
                          >
                            Reject Step
                          </Button>
                        </Col>
                      </Fragment>
                    ) : (
                      <Col sm={8} />
                    )}
                    <Col sm={4}>
                      <Button
                        size={"sm"}
                        block
                        color="primary"
                        disabled={sent}
                        onClick={this.sendReport}
                      >
                        Send
                      </Button>
                    </Col>
                  </Row>
                </Fragment>
              )
            )}
          </Col>
        </Row>
      </Container>
    );
  }
}
const SYSTEMS_QUERY = gql`
  query DamagedSystems($simulatorId: ID) {
    systems(simulatorId: $simulatorId, extra: true) {
      id
      name
      displayName
      damage {
        damaged
        report
        requested
        reactivationCode
        neededReactivationCode
        currentStep
        validate
        which
      }
      simulatorId
      type
    }
  }
`;

export default graphql(SYSTEMS_QUERY, {
  options: ownProps => ({
    fetchPolicy: "cache-and-network",
    variables: {simulatorId: ownProps.simulator.id},
  }),
})(withApollo(DamageReportCore));
<commit_msg>Fixes issues with damage report core.<commit_after>import React, {Component, Fragment} from "react";
import gql from "graphql-tag.macro";
import {graphql, withApollo} from "react-apollo";
import {Container, Row, Col, Button, Input} from "helpers/reactstrap";
import {TypingField} from "../../generic/core";
import SubscriptionHelper from "helpers/subscriptionHelper";
import {FaSyncAlt} from "react-icons/fa";
import "./style.scss";

const SYSTEMS_SUB = gql`
  subscription DamagedSystemsUpdate($simulatorId: ID) {
    systemsUpdate(simulatorId: $simulatorId, extra: true) {
      id
      name
      displayName
      damage {
        damaged
        report
        requested
        reactivationCode
        neededReactivationCode
        currentStep
        validate
        which
      }
      simulatorId
      type
    }
  }
`;

const extra = [
  "Co2 Scrubbers",
  "Fire",
  "Life Support",
  "Power Adjustment",
  "Transporter Buffer",
  "Turbolift Malfunction",
  "Antimatter Containment",
  "Gravity Systems",
  "Hull Breach",
  "Temperature",
  "Holodeck",
  "Brig Force Field",
  "Oxygen Generators",
  "Warp Field Realignment",
  "Computer Power",
  "Particle Detector",
  "Deuterium Fuel",
  "Water Pipes",
  "Food Replicators",
  "Zoology Pens Force Fields",
];

class DamageReportCore extends Component {
  constructor(props) {
    super(props);
    this.systemSub = null;
    this.state = {
      deck: null,
      room: null,
      selectedSystem: null,
      selectedReport: "",
    };
  }
  selectSystem(id, sent) {
    const systems = this.props.data.systems;
    const selectedSystem = systems.find(s => s.id === id);
    this.setState({
      sent: sent ? true : false,
      selectedSystem: id,
      selectedReport: selectedSystem.damage.report || "",
    });
  }
  systemStyle(sys) {
    const obj = {
      listStyle: "none",
      cursor: "pointer",
    };
    if (sys.damage.damaged) {
      obj.color = "red";
    }
    if (!sys.name) {
      obj.color = "purple";
    }
    return obj;
  }
  systemName(sys) {
    if (sys.type === "Shield" && sys.name !== "Shields") {
      return `${sys.name} Shields`;
    }
    return sys.displayName || sys.name;
  }
  loadReport(e) {
    const self = this;
    var reader = new FileReader();
    reader.onload = function() {
      const result = this.result.replace(/\r/gi, "\n");
      self.setState({
        sent: false,
        selectedReport: result,
      });
    };
    e.target.files[0] && reader.readAsText(e.target.files[0]);
  }
  sendReport = () => {
    this.setState({sent: true});
    const mutation = gql`
      mutation DamageReport($systemId: ID!, $report: String!) {
        damageReport(systemId: $systemId, report: $report)
      }
    `;
    const variables = {
      systemId: this.state.selectedSystem,
      report: this.state.selectedReport,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
    setTimeout(() => {
      this.selectSystem(this.state.selectedSystem, true);
    }, 500);
  };
  reactivationCodeResponse = response => {
    const mutation = gql`
      mutation ReactivationCodeResponse($systemId: ID!, $response: Boolean!) {
        systemReactivationCodeResponse(systemId: $systemId, response: $response)
      }
    `;
    const variables = {
      systemId: this.state.selectedSystem,
      response: response,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  createExtraSystem = (sysName, which) => {
    const name = sysName || prompt("What is the name of the system?");
    const systems = this.props.data.systems;
    if (systems.find(s => s.name === name)) {
      this.breakSystem(systems.find(s => s.name === name).id);
      return;
    }
    const mutation = gql`
      mutation CreateExtraSystem($simulatorId: ID!, $params: String!) {
        addSystemToSimulator(
          simulatorId: $simulatorId
          className: "System"
          params: $params
        )
      }
    `;
    const variables = {
      simulatorId: this.props.simulator.id,
      params: JSON.stringify({
        name,
        extra: true,
        damage: {damaged: true, which},
      }),
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  breakSystem = sys => {
    const variables = {
      systemId: sys,
    };
    // Break it
    const mutation = gql`
      mutation DamageSystem($systemId: ID!) {
        damageSystem(systemId: $systemId)
      }
    `;
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  repairSystem = () => {
    const {selectedSystem} = this.state;
    const variables = {
      systemId: selectedSystem,
    };
    // Fix it
    const mutation = gql`
      mutation RepairSystem($systemId: ID!) {
        repairSystem(systemId: $systemId)
      }
    `;
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  generateReport = steps => {
    const mutation = gql`
      mutation GenerateReport($systemId: ID!, $steps: Int) {
        generateDamageReport(systemId: $systemId, steps: $steps)
      }
    `;
    const variables = {systemId: this.state.selectedSystem, steps};
    this.props.client
      .mutate({
        mutation,
        variables,
      })
      .then(res => {
        this.setState({
          sent: false,
          selectedReport: res.data.generateDamageReport,
        });
      });
  };
  rejectStep = () => {
    const mutation = gql`
      mutation SetDamageStepValidation($id: ID!) {
        setDamageStepValidation(id: $id, validation: false)
      }
    `;
    const variables = {
      id: this.state.selectedSystem,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  acceptStep = () => {
    const mutation = gql`
      mutation ValidateDamageStep($id: ID!) {
        validateDamageStep(id: $id)
      }
    `;
    const variables = {
      id: this.state.selectedSystem,
    };
    this.props.client.mutate({
      mutation,
      variables,
    });
  };
  render() {
    if (this.props.data.loading) return null;
    const systems = this.props.data.systems;
    if (!systems) return null;
    const {selectedReport, selectedSystem, sent} = this.state;
    const selectedSystemObj = systems.find(s => s.id === selectedSystem);
    return (
      <Container fluid className="damageReport-core">
        <SubscriptionHelper
          subscribe={() =>
            this.props.data.subscribeToMore({
              document: SYSTEMS_SUB,
              variables: {
                simulatorId: this.props.simulator.id,
              },
              updateQuery: (previousResult, {subscriptionData}) => {
                return Object.assign({}, previousResult, {
                  systems: subscriptionData.data.systemsUpdate,
                });
              },
            })
          }
        />
        <Row style={{height: "100%"}}>
          <Col
            sm={4}
            className="left-side"
            style={{display: "flex", flexDirection: "column"}}
          >

              {systems
                .filter(s => s.damage.damaged)
                .map(s => (
                  <p
                    key={s.id}
                    className={`${selectedSystem === s.id ? "selected" : ""}  ${
                      s.damage.requested ? "requested" : ""
                    } ${s.damage.report ? "report" : ""} ${
                      s.damage.reactivationCode ? "reactivation" : ""
                    } ${s.damage.validate ? "validate" : ""} ${s.damage.which}`}
                    title={`${s.damage.requested ? "Report Requested : " : ""}${
                      s.damage.report ? "Report Sent : " : ""
                    }${
                      s.damage.reactivationCode
                        ? "Reactivation Code Requested : "
                        : ""
                    }${s.damage.validate ? "Validation Requested : " : ""}`}
                    onClick={this.selectSystem.bind(this, s.id)}
                  >
                    {s.damage.validate ? (
                      <FaSyncAlt className="fa-spin" />
                    ) : null}{" "}
                    {this.systemName(s)} - {s.damage.currentStep + 1} /{" "}
                    {s.damage.report
                      ? s.damage.report
                          .split(/Step [0-9]+:\n/gi)
                          .filter(st => st && st !== "\n").length
                      : 0}

                ))}

            <Input
              type="select"
              value={"top"}
              size="sm"
              style={{height: "20px"}}
              onChange={evt => this.createExtraSystem(evt.target.value)}
            >
              <option disabled value="top">
                Extra Damage
              </option>
              {extra.map(e => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
              <option value="">Add System</option>
            </Input>
            <Input
              type="select"
              value={"top"}
              size="sm"
              className="btn-warning"
              style={{height: "20px"}}
              onChange={evt => this.createExtraSystem(evt.target.value, "rnd")}
            >
              <option disabled value="top">
                Extra {"R&D"}
              </option>
              {extra.map(e => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
              <option value="">Add System</option>
            </Input>
            <Input
              type="select"
              value={"top"}
              size="sm"
              className="btn-primary"
              style={{height: "20px"}}
              onChange={evt =>
                this.createExtraSystem(evt.target.value, "engineering")
              }
            >
              <option disabled value="top">
                Extra Engineering
              </option>
              {extra.map(e => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
              <option value="">Add System</option>
            </Input>
          </Col>
          <Col sm={8} style={{display: "flex", flexDirection: "column"}}>
            <TypingField
              value={selectedReport}
              style={{
                textAlign: "left",
                height: "auto",
                fontFamily: "monospace",
                flex: 1,
              }}
              rows={8}
              controlled={true}
              onChange={e => {
                this.setState({
                  sent: false,
                  selectedReport: e.target.value,
                });
              }}
            />
            {selectedSystemObj && selectedSystemObj.damage.reactivationCode ? (

                <Row style={{margin: 0}}>
                  <Col sm={3}>Code:</Col>
                  <Col sm={9}>{selectedSystemObj.damage.reactivationCode}</Col>
                </Row>
                <Row style={{margin: 0}}>
                  <Col sm={3}>Actual:</Col>
                  <Col sm={9}>
                    {selectedSystemObj.damage.neededReactivationCode}
                  </Col>
                </Row>
                <Row style={{margin: 0}}>
                  <Col sm={8}>
                    <Button
                      onClick={() => {
                        this.reactivationCodeResponse(true);
                      }}
                      size={"sm"}
                      color="success"
                      block
                    >
                      Accept & Fix
                    </Button>
                  </Col>
                  <Col sm={4}>
                    <Button
                      onClick={() => {
                        this.reactivationCodeResponse(false);
                      }}
                      size={"sm"}
                      color="danger"
                      block
                    >
                      Deny
                    </Button>
                  </Col>
                </Row>

            ) : (
              selectedSystem && (
                <Fragment>
                  <Row style={{margin: 0}}>
                    <Col sm={4}>
                      <Button
                        size={"sm"}
                        block
                        color="success"
                        onClick={this.repairSystem}
                      >
                        Repair
                      </Button>
                    </Col>
                    <Col sm={4}>
                      <Input
                        onChange={this.loadReport.bind(this)}
                        style={{position: "absolute", opacity: 0}}
                        value={""}
                        type="file"
                        name="file"
                        id="exampleFile"
                      />
                      <Button size={"sm"} block color="info">
                        Load Report
                      </Button>
                    </Col>
                    <Col sm={4}>
                      <select
                        className="btn btn-warning btn-sm btn-block"
                        onChange={evt => {
                          if (evt.target.value === "set") {
                            const count = window.prompt("How many steps?");
                            if (
                              isNaN(parseInt(count, 10)) ||
                              parseInt(count, 10) <= 0
                            )
                              return;
                            this.generateReport(parseInt(count, 10));

                            return;
                          }
                          this.generateReport(parseInt(evt.target.value, 10));
                        }}
                        value={"select"}
                      >
                        <option value="select">Generate</option>
                        <option value="set">Enter Step Count</option>
                        <option value="3">Superficial</option>
                        <option value="5">Short</option>
                        <option value="8">Medium</option>
                        <option value="12">Long</option>
                      </select>
                    </Col>
                  </Row>
                  <Row style={{margin: 0}}>
                    {selectedSystemObj && selectedSystemObj.damage.validate ? (
                      <Fragment>
                        <Col sm={4}>

                            Validate Step:{" "}
                            {selectedSystemObj.damage.currentStep + 1}

                        </Col>
                        <Col sm={2}>
                          <Button
                            size={"sm"}
                            block
                            color="secondary"
                            onClick={this.acceptStep}
                          >
                            Accept Step
                          </Button>
                        </Col>
                        <Col sm={2}>
                          <Button
                            size={"sm"}
                            block
                            color="danger"
                            onClick={this.rejectStep}
                          >
                            Reject Step
                          </Button>
                        </Col>
                      </Fragment>
                    ) : (
                      <Col sm={8} />
                    )}
                    <Col sm={4}>
                      <Button
                        size={"sm"}
                        block
                        color="primary"
                        disabled={sent}
                        onClick={this.sendReport}
                      >
                        Send
                      </Button>
                    </Col>
                  </Row>
                </Fragment>
              )
            )}
          </Col>
        </Row>
      </Container>
    );
  }
}
const SYSTEMS_QUERY = gql`
  query DamagedSystems($simulatorId: ID) {
    systems(simulatorId: $simulatorId, extra: true) {
      id
      name
      displayName
      damage {
        damaged
        report
        requested
        reactivationCode
        neededReactivationCode
        currentStep
        validate
        which
      }
      simulatorId
      type
    }
  }
`;

export default graphql(SYSTEMS_QUERY, {
  options: ownProps => ({
    fetchPolicy: "cache-and-network",
    variables: {simulatorId: ownProps.simulator.id},
  }),
})(withApollo(DamageReportCore));
<|endoftext|>