<commit_before>/*
 * Copyright © 2015 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

var alertpromise;
angular.module(PKG.name + '.feature.adapters')
  .controller('AdaptersListController', function($scope, myAdapterApi, $stateParams, GLOBALS, mySettings, $state, $alert, $timeout, myAlert, myHelpers, myWorkFlowApi, myWorkersApi, MyDataSource) {

    var dataSrc = new MyDataSource($scope);

    var vm = this;

    vm.adaptersList = [];
    vm.currentPage = 1;
    vm.statusCount = {
      running: 0,
      scheduled: 0,
      suspended: 0,
      draft: 0
    };

    vm.GLOBALS = GLOBALS;

    var realtime = [],
        batch = [];

    vm.statusMap = {};

    myAdapterApi.list({
      namespace: $stateParams.namespace
    })
      .$promise
      .then(function success(res) {
        vm.adaptersList = res;

        fetchDrafts();

        angular.forEach(vm.adaptersList, function (app) {
          app._stats = {};

          fetchRunsInfo(app);
        });

        fetchStatus();

      });

    function fetchRunsInfo(app) {
      var params = {
        namespace: $state.params.namespace,
        appId: app.id,
        scope: $scope
      };

      var api;

      if (app.artifact.name === GLOBALS.etlBatch) {
        api = myWorkFlowApi;
        params.workflowId = 'ETLWorkflow';

        batch.push({
          appId: app.id,
          programType: 'Workflow',
          programId: 'ETLWorkflow'
        });
      } else {
        api = myWorkersApi;
        params.workerId = 'ETLWorker';

        realtime.push({
          appId: app.id,
          programType: 'Worker',
          programId: 'ETLWorker'
        });
      }

      api.runs(params)
        .$promise
        .then(function (runs) {
          app._stats.numRuns = runs.length;
          app._stats.lastStartTime = runs.length > 0 ? runs[0].start : 'N/A';

          for (var i = 0; i < runs.length; i++) {
            if (runs[i].status !== 'RUNNING') {
              app._latest = runs[i];
              break;
            }
          }

        });
    }

    function fetchStatus() {
      // fetching ETL Batch statuses
      dataSrc.request({
        _cdapNsPath: '/status',
        method: 'POST',
        body: batch
      })
      .then(function (res) {
        angular.forEach(res, function (app) {
          if (app.status === 'RUNNING') {
            vm.statusMap[app.appId] = 'Running';
            vm.statusCount.running++;
          } else {

            myWorkFlowApi.getScheduleStatus({
              namespace: $state.params.namespace,
              appId: app.appId,
              scheduleId: 'etlWorkflow',
              scope: $scope
            })
              .$promise
              .then(function (schedule) {
                if (schedule.status === 'SCHEDULED') {
                  vm.statusMap[app.appId] = 'Scheduled';
                  vm.statusCount.scheduled++;
                } else {
                  vm.statusMap[app.appId] = 'Suspended';
                  vm.statusCount.suspended++;
                }
              });
          }
        });
      }); // end of ETL Batch

      //fetching ETL Realtime statuses
      dataSrc.request({
        _cdapNsPath: '/status',
        method: 'POST',
        body: realtime
      })
      .then(function (res) {
        angular.forEach(res, function (app) {
          if (app.status === 'RUNNING') {
            vm.statusMap[app.appId] = 'Running';
            vm.statusCount.running++;
          } else {
            vm.statusMap[app.appId] = 'Suspended';
            vm.statusCount.suspended++;
          }
        });
      });

    }

    function fetchDrafts() {
      mySettings.get('adapterDrafts')
        .then(function(res) {
          if (res && Object.keys(res).length) {
            angular.forEach(res, function(value, key) {

              vm.statusCount.draft++;

              vm.adaptersList.push({
                isDraft: true,
                name: key,
                artifact: value.artifact,
                status: '-',
                description: myHelpers.objectQuery(value, 'description'),
                _stats: {
                  numRuns: 'N/A',
                  lastStartTime: 'N/A'
                }
              });

              vm.statusMap[key] = 'Draft';
            });

          }
        });
    }

    vm.deleteDraft = function(draftName) {
      mySettings.get('adapterDrafts')
        .then(function(res) {
          if (res[draftName]) {
            delete res[draftName];
          }
          return mySettings.set('adapterDrafts', res);
        })
        .then(
          function success() {
            var alertObj = {
              type: 'success',
              content: 'Adapter draft ' + draftName + ' delete successfully'
            }, e;
            if (!alertpromise) {
              alertpromise = $alert(alertObj);
              e = $scope.$on('alert.hide', function() {
                alertpromise = null;
                e(); // un-register from listening to the hide event of a closed alert.
              });
            }
            $state.reload();
          },
          function error() {
            var alertObj = {
              type: 'danger',
              content: 'Adapter draft ' + draftName + ' delete failed'
            }, e;
            if (!alertpromise) {
              alertpromise = $alert(alertObj);
              e = $scope.$on('alert.hide', function() {
                alertpromise = null;
                e();
              });
            }
            $state.reload();
          });
    };
  });
<commit_msg>fix grammatical error message<commit_after>/*
 * Copyright © 2015 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

var alertpromise;
angular.module(PKG.name + '.feature.adapters')
  .controller('AdaptersListController', function($scope, myAdapterApi, $stateParams, GLOBALS, mySettings, $state, $alert, $timeout, myAlert, myHelpers, myWorkFlowApi, myWorkersApi, MyDataSource) {

    var dataSrc = new MyDataSource($scope);

    var vm = this;

    vm.adaptersList = [];
    vm.currentPage = 1;
    vm.statusCount = {
      running: 0,
      scheduled: 0,
      suspended: 0,
      draft: 0
    };

    vm.GLOBALS = GLOBALS;

    var realtime = [],
        batch = [];

    vm.statusMap = {};

    myAdapterApi.list({
      namespace: $stateParams.namespace
    })
      .$promise
      .then(function success(res) {
        vm.adaptersList = res;

        fetchDrafts();

        angular.forEach(vm.adaptersList, function (app) {
          app._stats = {};

          fetchRunsInfo(app);
        });

        fetchStatus();

      });

    function fetchRunsInfo(app) {
      var params = {
        namespace: $state.params.namespace,
        appId: app.id,
        scope: $scope
      };

      var api;

      if (app.artifact.name === GLOBALS.etlBatch) {
        api = myWorkFlowApi;
        params.workflowId = 'ETLWorkflow';

        batch.push({
          appId: app.id,
          programType: 'Workflow',
          programId: 'ETLWorkflow'
        });
      } else {
        api = myWorkersApi;
        params.workerId = 'ETLWorker';

        realtime.push({
          appId: app.id,
          programType: 'Worker',
          programId: 'ETLWorker'
        });
      }

      api.runs(params)
        .$promise
        .then(function (runs) {
          app._stats.numRuns = runs.length;
          app._stats.lastStartTime = runs.length > 0 ? runs[0].start : 'N/A';

          for (var i = 0; i < runs.length; i++) {
            if (runs[i].status !== 'RUNNING') {
              app._latest = runs[i];
              break;
            }
          }

        });
    }

    function fetchStatus() {
      // fetching ETL Batch statuses
      dataSrc.request({
        _cdapNsPath: '/status',
        method: 'POST',
        body: batch
      })
      .then(function (res) {
        angular.forEach(res, function (app) {
          if (app.status === 'RUNNING') {
            vm.statusMap[app.appId] = 'Running';
            vm.statusCount.running++;
          } else {

            myWorkFlowApi.getScheduleStatus({
              namespace: $state.params.namespace,
              appId: app.appId,
              scheduleId: 'etlWorkflow',
              scope: $scope
            })
              .$promise
              .then(function (schedule) {
                if (schedule.status === 'SCHEDULED') {
                  vm.statusMap[app.appId] = 'Scheduled';
                  vm.statusCount.scheduled++;
                } else {
                  vm.statusMap[app.appId] = 'Suspended';
                  vm.statusCount.suspended++;
                }
              });
          }
        });
      }); // end of ETL Batch

      //fetching ETL Realtime statuses
      dataSrc.request({
        _cdapNsPath: '/status',
        method: 'POST',
        body: realtime
      })
      .then(function (res) {
        angular.forEach(res, function (app) {
          if (app.status === 'RUNNING') {
            vm.statusMap[app.appId] = 'Running';
            vm.statusCount.running++;
          } else {
            vm.statusMap[app.appId] = 'Suspended';
            vm.statusCount.suspended++;
          }
        });
      });

    }

    function fetchDrafts() {
      mySettings.get('adapterDrafts')
        .then(function(res) {
          if (res && Object.keys(res).length) {
            angular.forEach(res, function(value, key) {

              vm.statusCount.draft++;

              vm.adaptersList.push({
                isDraft: true,
                name: key,
                artifact: value.artifact,
                status: '-',
                description: myHelpers.objectQuery(value, 'description'),
                _stats: {
                  numRuns: 'N/A',
                  lastStartTime: 'N/A'
                }
              });

              vm.statusMap[key] = 'Draft';
            });

          }
        });
    }

    vm.deleteDraft = function(draftName) {
      mySettings.get('adapterDrafts')
        .then(function(res) {
          if (res[draftName]) {
            delete res[draftName];
          }
          return mySettings.set('adapterDrafts', res);
        })
        .then(
          function success() {
            var alertObj = {
              type: 'success',
              content: 'Adapter draft ' + draftName + ' deleted successfully'
            }, e;
            if (!alertpromise) {
              alertpromise = $alert(alertObj);
              e = $scope.$on('alert.hide', function() {
                alertpromise = null;
                e(); // un-register from listening to the hide event of a closed alert.
              });
            }
            $state.reload();
          },
          function error() {
            var alertObj = {
              type: 'danger',
              content: 'Adapter draft ' + draftName + ' delete failed'
            }, e;
            if (!alertpromise) {
              alertpromise = $alert(alertObj);
              e = $scope.$on('alert.hide', function() {
                alertpromise = null;
                e();
              });
            }
            $state.reload();
          });
    };
  });
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Link } from 'react-router';
import { Map, List, fromJS } from 'immutable';
import glamorous from 'glamorous';
import Swipeable from 'react-swipeable';
import * as _ from 'lodash';
import AnalyticsService from '../analytics/AnalyticsService';

import ProductBadge from './ProductBadge';
import SellingAidsBadge from './SellingAidsBadge';
import FilterBar from './FilterBar';

export default class Catalogue extends Component {
  static propTypes = {
    params: PropTypes.shape({ categoryCode: PropTypes.string.isRequired }).isRequired,
    requestFetchCategory: PropTypes.func.isRequired,
    clearProductList: PropTypes.func.isRequired,
    categoryInfo: ImmutablePropTypes.map,
    products: ImmutablePropTypes.list,
    filterMap: ImmutablePropTypes.map.isRequired,
    toggleAid: PropTypes.func.isRequired,
    toggleFilter: PropTypes.func.isRequired,
    toggleAvailability: PropTypes.func.isRequired,
    resetFilters: PropTypes.func.isRequired,
    initFilters: PropTypes.func.isRequired,
    toggleFiltersDialog: PropTypes.func.isRequired,
    resetTempFilters: PropTypes.func.isRequired,
    isDialogOpen: PropTypes.bool.isRequired,
    setAnalyticsProductClick: PropTypes.func.isRequired,
    trackCatalogueProductsChunk: PropTypes.func.isRequired,
    routingData: ImmutablePropTypes.map.isRequired
  };

  static defaultProps = {
    categoryInfo: Map(),
    products: List()
  };

  constructor(prop) {
    super(prop);
    this.chunkSize = 4;
    this.productsChunk = List();
    this.onBadgeClick = this.onBadgeClick.bind(this);
    this.onLeftSwipe = this.onLeftSwipe.bind(this);
    this.onRightSwipe = this.onRightSwipe.bind(this);
    this.chunkerizeProductList = this.chunkerizeProductList.bind(this);
    this.getChunks = this.getChunks.bind(this);
    this.state = {
      currentChunkIndex: 0,
      appendChunkIndex: 1
    };
  }

  componentWillMount() {
    const { params: { categoryCode }, requestFetchCategory, initFilters } = this.props;
    initFilters();
    requestFetchCategory(categoryCode);
  }

  componentWillReceiveProps(nextProps) {
    const { params: { categoryCode }, requestFetchCategory, initFilters } = nextProps;
    if (categoryCode !== this.props.params.categoryCode) {
      initFilters();
      requestFetchCategory(categoryCode);
    }

    if (nextProps.products.size > 0) {
      this.chunkerizeProductList(nextProps.products);
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const chunkHasChanged = prevState !== this.state;
    const componentReceiveProduct = !prevProps.products.size > 0 && this.props.products.size > 0;

    if (componentReceiveProduct || chunkHasChanged) {
      const currentChunk = this.getChunks().setSize(this.chunkSize);
      const positionIndex = this.chunkSize * this.state.currentChunkIndex;
      this.props.trackCatalogueProductsChunk();
      // Can't use redux-saga https://stackoverflow.com/questions/45435094/redux-saga-takeevery-miss-catch-event
      const path = _.trimStart(this.props.routingData.get('pathname'), '/');
      const pathArray = _.split(path, '/');
      AnalyticsService.setRelatedProduct({
        products: currentChunk,
        pathArray,
        positionIndex
      });
      setTimeout(() => AnalyticsService.track('view'), 500);
    }
  }

  componentWillUnmount() {
    this.props.clearProductList();
  }

  onBadgeClick(product, index) {
    this.props.setAnalyticsProductClick({ product, index });
  }

  onLeftSwipe() {
    let { currentChunkIndex, appendChunkIndex } = this.state;
    if (appendChunkIndex < this.productsChunk.size - 1) {
      const currentIndex = currentChunkIndex += 1;
      const appendIndex = appendChunkIndex += 1;
      this.setState({
        currentChunkIndex: currentIndex,
        appendChunkIndex: appendIndex
      });
    }
  }

  onRightSwipe() {
    let { currentChunkIndex, appendChunkIndex } = this.state;
    if (currentChunkIndex > 0) {
      const currentIndex = currentChunkIndex -= 1;
      const appendIndex = appendChunkIndex -= 1;
      this.setState({
        currentChunkIndex: currentIndex,
        appendChunkIndex: appendIndex
      });
    }
  }

  getChunks() {
    let chunks = List();

    if (this.productsChunk.size > 0) {
      const { currentChunkIndex, appendChunkIndex } = this.state;
      const currentChunk = this.productsChunk.getIn([currentChunkIndex]);
      const appendChunk = this.productsChunk.getIn([appendChunkIndex]);

      chunks = appendChunk ? currentChunk.concat(appendChunk) : currentChunk;
    }
    return chunks;
  }

  chunkerizeProductList(productList) {
    this.productsChunk = fromJS(_.chunk(productList.toJS(), this.chunkSize));
  }

  renderProducts() {
    const products = this.getChunks();
    return products.map((p, index) =>
      <Link onClick={() => this.onBadgeClick(p, index)} to={`product/${p.get('code')}`} key={p.get('code')}>
        <ProductBadge productInfo={p} />
      </Link>
    );
  }

  render() {
    const {
      categoryInfo,
      filterMap,
      toggleAid,
      resetFilters,
      toggleAvailability,
      toggleFilter,
      toggleFiltersDialog,
      isDialogOpen,
      resetTempFilters
    } = this.props;

    if (categoryInfo.isEmpty()) {
      return null;
    }

    const catName = categoryInfo.get('name');
    const sellingAids = categoryInfo.getIn(['sellingAidsProducts', 0]) || Map();
    const facetFilters = categoryInfo.get('facetFilters') || List();
    const filterGroups = facetFilters.filterNot(g => g.get('group') === 'Prezzo');
    const activeAid = filterMap.get('aid');
    const swipeableConfig = {
      flickThreshold: 0.6,
      preventDefaultTouchmoveEvent: true,
      delta: 50
    };

    return (

{catName}

        <SellingAidsBadge sellingAids={sellingAids} onToggle={toggleAid} activeAid={activeAid} />
        <FilterBar
          filterGroups={filterGroups}
          resetFilters={resetFilters}
          filterMap={filterMap}
          toggleFilter={toggleFilter}
          toggleAvailability={toggleAvailability}
          toggleFiltersDialog={toggleFiltersDialog}
          isDialogOpen={isDialogOpen}
          resetTempFilters={resetTempFilters}
        />
        <Swipeable
          onSwipingLeft={this.onLeftSwipe}
          onSwipingRight={this.onRightSwipe}
          {...swipeableConfig}
        >
          <ProductSlider opacity={isDialogOpen}>
            {this.renderProducts()}
          </ProductSlider>
        </Swipeable>

    );
  }
}

const Header = glamorous.div({
  width: '100%',
  height: '184px',
  background: '#f7f7f7',
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  '&>h1': {
    fontSize: '48px'
  }
});

const ProductSlider = glamorous.div(({ opacity = false }) => ({
  marginTop: '5%',
  display: 'flex',
  overflowX: 'hidden',
  flexFlow: 'column wrap',
  alignContent: 'flex-start',
  height: '1246px',
  opacity: opacity ? 0.17 : 1,
  '&>a': {
    width: '405px',
    height: '593px',
    marginRight: '20px',
    '&:nth-child(odd)': {
      marginBottom: '60px'
    }
  }
}));

<commit_msg>quick fix for wrong chunk index.<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Link } from 'react-router';
import { Map, List, fromJS } from 'immutable';
import glamorous from 'glamorous';
import Swipeable from 'react-swipeable';
import * as _ from 'lodash';
import AnalyticsService from '../analytics/AnalyticsService';

import ProductBadge from './ProductBadge';
import SellingAidsBadge from './SellingAidsBadge';
import FilterBar from './FilterBar';

export default class Catalogue extends Component {
  static propTypes = {
    params: PropTypes.shape({ categoryCode: PropTypes.string.isRequired }).isRequired,
    requestFetchCategory: PropTypes.func.isRequired,
    clearProductList: PropTypes.func.isRequired,
    categoryInfo: ImmutablePropTypes.map,
    products: ImmutablePropTypes.list,
    filterMap: ImmutablePropTypes.map.isRequired,
    toggleAid: PropTypes.func.isRequired,
    toggleFilter: PropTypes.func.isRequired,
    toggleAvailability: PropTypes.func.isRequired,
    resetFilters: PropTypes.func.isRequired,
    initFilters: PropTypes.func.isRequired,
    toggleFiltersDialog: PropTypes.func.isRequired,
    resetTempFilters: PropTypes.func.isRequired,
    isDialogOpen: PropTypes.bool.isRequired,
    setAnalyticsProductClick: PropTypes.func.isRequired,
    trackCatalogueProductsChunk: PropTypes.func.isRequired,
    routingData: ImmutablePropTypes.map.isRequired
  };

  static defaultProps = {
    categoryInfo: Map(),
    products: List()
  };

  constructor(prop) {
    super(prop);
    this.chunkSize = 4;
    this.productsChunk = List();
    this.onBadgeClick = this.onBadgeClick.bind(this);
    this.onLeftSwipe = this.onLeftSwipe.bind(this);
    this.onRightSwipe = this.onRightSwipe.bind(this);
    this.chunkerizeProductList = this.chunkerizeProductList.bind(this);
    this.getChunks = this.getChunks.bind(this);
    this.state = {
      currentChunkIndex: 0,
      appendChunkIndex: 1
    };
  }

  componentWillMount() {
    const { params: { categoryCode }, requestFetchCategory, initFilters } = this.props;
    initFilters();
    requestFetchCategory(categoryCode);
  }

  componentWillReceiveProps(nextProps) {
    const { params: { categoryCode }, requestFetchCategory, initFilters } = nextProps;
    if (categoryCode !== this.props.params.categoryCode) {
      initFilters();
      requestFetchCategory(categoryCode);
    }

    if (nextProps.products.size > 0) {
      this.chunkerizeProductList(nextProps.products);
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const chunkHasChanged = prevState !== this.state;
    const componentReceiveProduct = !prevProps.products.size > 0 && this.props.products.size > 0;

    if (componentReceiveProduct || chunkHasChanged) {
      const currentChunk = this.getChunks().setSize(this.chunkSize);
      const positionIndex = this.chunkSize * this.state.currentChunkIndex;
      this.props.trackCatalogueProductsChunk();
      // Can't use redux-saga https://stackoverflow.com/questions/45435094/redux-saga-takeevery-miss-catch-event
      const path = _.trimStart(this.props.routingData.get('pathname'), '/');
      const pathArray = _.split(path, '/');
      AnalyticsService.setRelatedProduct({
        products: currentChunk,
        pathArray,
        positionIndex
      });
      setTimeout(() => AnalyticsService.track('view'), 500);
    }
  }

  componentWillUnmount() {
    this.props.clearProductList();
  }

  onBadgeClick(product, index) {
    this.props.setAnalyticsProductClick({ product, index });
  }

  onLeftSwipe() {
    let { currentChunkIndex, appendChunkIndex } = this.state;
    if (appendChunkIndex < this.productsChunk.size - 1) {
      const currentIndex = currentChunkIndex += 1;
      const appendIndex = appendChunkIndex += 1;
      this.setState({
        currentChunkIndex: currentIndex,
        appendChunkIndex: appendIndex
      });
    }
  }

  onRightSwipe() {
    let { currentChunkIndex, appendChunkIndex } = this.state;
    if (currentChunkIndex > 0) {
      const currentIndex = currentChunkIndex -= 1;
      const appendIndex = appendChunkIndex -= 1;
      this.setState({
        currentChunkIndex: currentIndex,
        appendChunkIndex: appendIndex
      });
    }
  }

  getChunks() {
    let chunks = List();

    if (this.productsChunk.size > 0) {
      const { currentChunkIndex, appendChunkIndex } = this.state;
      const isProductListFiltered = this.props.filterMap.get('filters').size > 0;
      let currentChunk = this.productsChunk.getIn([currentChunkIndex]);
      let appendChunk = this.productsChunk.getIn([appendChunkIndex]);

      if (isProductListFiltered) {
        currentChunk = this.productsChunk.getIn([0]);
        appendChunk = this.productsChunk.getIn([1]);
      }

      chunks = appendChunk ? currentChunk.concat(appendChunk) : currentChunk;
    }
    // eslint-disable-next-line
    return chunks ? chunks : List();
  }

  chunkerizeProductList(productList) {
    this.productsChunk = fromJS(_.chunk(productList.toJS(), this.chunkSize));
  }

  renderProducts() {
    const products = this.getChunks();
    return products.map((p, index) =>
      <Link onClick={() => this.onBadgeClick(p, index)} to={`product/${p.get('code')}`} key={p.get('code')}>
        <ProductBadge productInfo={p} />
      </Link>
    );
  }

  render() {
    const {
      categoryInfo,
      filterMap,
      toggleAid,
      resetFilters,
      toggleAvailability,
      toggleFilter,
      toggleFiltersDialog,
      isDialogOpen,
      resetTempFilters
    } = this.props;

    if (categoryInfo.isEmpty()) {
      return null;
    }

    const catName = categoryInfo.get('name');
    const sellingAids = categoryInfo.getIn(['sellingAidsProducts', 0]) || Map();
    const facetFilters = categoryInfo.get('facetFilters') || List();
    const filterGroups = facetFilters.filterNot(g => g.get('group') === 'Prezzo');
    const activeAid = filterMap.get('aid');
    const swipeableConfig = {
      flickThreshold: 0.6,
      preventDefaultTouchmoveEvent: true,
      delta: 50
    };

    return (

{catName}

        <SellingAidsBadge sellingAids={sellingAids} onToggle={toggleAid} activeAid={activeAid} />
        <FilterBar
          filterGroups={filterGroups}
          resetFilters={resetFilters}
          filterMap={filterMap}
          toggleFilter={toggleFilter}
          toggleAvailability={toggleAvailability}
          toggleFiltersDialog={toggleFiltersDialog}
          isDialogOpen={isDialogOpen}
          resetTempFilters={resetTempFilters}
        />
        <Swipeable
          onSwipingLeft={this.onLeftSwipe}
          onSwipingRight={this.onRightSwipe}
          {...swipeableConfig}
        >
          <ProductSlider opacity={isDialogOpen}>
            {this.renderProducts()}
          </ProductSlider>
        </Swipeable>

    );
  }
}

const Header = glamorous.div({
  width: '100%',
  height: '184px',
  background: '#f7f7f7',
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  '&>h1': {
    fontSize: '48px'
  }
});

const ProductSlider = glamorous.div(({ opacity = false }) => ({
  marginTop: '5%',
  display: 'flex',
  overflowX: 'hidden',
  flexFlow: 'column wrap',
  alignContent: 'flex-start',
  height: '1246px',
  opacity: opacity ? 0.17 : 1,
  '&>a': {
    width: '405px',
    height: '593px',
    marginRight: '20px',
    '&:nth-child(odd)': {
      marginBottom: '60px'
    }
  }
}));

<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';

const Dashboard = _ => (

467m

landing in 37s

);

export default connect(store => ({

}))(Dashboard);<commit_msg>Add testing button to Dashboard<commit_after>import React from 'react';
import { connect } from 'react-redux';
import { addPacket } from '../helpers';

const ex_packet = '5,16.8,997,420,50,N,60,E,4,-55,3,2000,0.5,0,1,2,4,8,16,32,64';

const Dashboard = _ => (

        <button onClick={e => addPacket(ex_packet)}>Generate</button>

467m

landing in 37s

);

export default connect(store => ({

}))(Dashboard);
<|endoftext|>


<commit_before>import React, {
  Component
} from 'react';
import PropTypes from 'prop-types';
import Settings from 'electron-settings';
import MilestoneStyles from './Milestone.css';
import Issue from './Issue';

export default class MainPage extends Component {

  static propTypes = {
    milestone: PropTypes.object,
    repo: PropTypes.object
  };

  constructor() {
    super();
    this._getIssues = this._getIssues.bind(this);
    this._issuesReceived = this._issuesReceived.bind(this);
    this._renderIssue = this._renderIssue.bind(this);
    this._renderPagination = this._renderPagination.bind(this);
    this._changePage = this._changePage.bind(this);
    this.state = {
      issues: [],
      page: 1
    }
  }

  componentDidMount() {
    this.setState({milestone:this.props.milestone, issues:[], lastPage:-1}, this._getIssues);
  }

  componentWillReceiveProps(nextProps) {
    this.setState({milestone:nextProps.milestone, issues:[], lastPage:-1}, this._getIssues);
  }

  _getIssues() {
    this.props.repo.issues({
      milestone: this.state.milestone.number,
      state: 'all',
      page: this.state.page
    }, this._issuesReceived);
  }

  _issuesReceived(error, issues, headers) {
    const lastPage = this._loadLastPage(headers);
    this.setState({issues, headers, lastPage});
  }

  _loadLastPage(headers) {
    let lastPage = this.state.lastPage;
    let links = headers.link.split(',');
    links.forEach(function(link) {
      const [url, rel] = link.split(';').map(function(linkPart) {
        return linkPart
          .replace('rel="', '')
          .replace(/[<>"]/g, '')
          .trim();
      });
      if (rel === 'last') {
        lastPage = parseInt(url.replace(/.*page=(\d+).*/g, '$1'), 10);
      }
    });

    return lastPage;
  }

  render() {
    return (

          {this.props.milestone.title}

            {this.props.milestone.open_issues} open issues
            {this.props.milestone.closed_issues > 0 &&
              , {this.props.milestone.closed_issues} closed.
            }

          {
            this.state.issues.map(this._renderIssue)
          }

          {this._renderPagination()}

    );
  }

  _renderIssue(issue, index) {
    return (
      <Issue issue={issue} index={index} key={issue.id}/>
    )
  }

  _renderPagination() {
    if (!this.state.headers) {
      return;
    }
    console.log('lastPage', this.state.lastPage);
    let buttons = [];
    for (let i = 1; i <= this.state.lastPage; i++) {
      buttons.push(this._getPaginationButton(i));
    }
    buttons.unshift(this._getPaginationButton(this.state.page - 1, 'Previous'));
    buttons.push(   this._getPaginationButton(this.state.page + 1, 'Next'));
    return buttons;
  }

  _getPaginationButton(page, text) {
    let options = {
      className: [
        MilestoneStyles.__pagination_button
      ]
    };

    if (text !== undefined) {
      options.className.push(MilestoneStyles.__pagination_button_text);
    } else {
      text = page;
    }

    if (page === this.state.page) {
      options.className.push(MilestoneStyles.__pagination_button_current);
    }
    if (page > 0 && page <= this.state.lastPage) {
      options.onClick = this._changePage;
    } else {
      options.className.push(MilestoneStyles.__pagination_button_disabled);
      options.disabled = true;
    }
    options.className = options.className.join(' ');

    return (
      <button {...options} data-page={page}>
        {text}
      </button>
    );
  }

  _changePage(e) {
    e.target.blur();
    var page = parseInt(e.target.getAttribute('data-page'), 10);
    this.setState({issues:[], page}, this._getIssues);
  }

}
<commit_msg>Adding key to pagination buttons<commit_after>import React, {
  Component
} from 'react';
import PropTypes from 'prop-types';
import Settings from 'electron-settings';
import MilestoneStyles from './Milestone.css';
import Issue from './Issue';

export default class MainPage extends Component {

  static propTypes = {
    milestone: PropTypes.object,
    repo: PropTypes.object
  };

  constructor() {
    super();
    this._getIssues = this._getIssues.bind(this);
    this._issuesReceived = this._issuesReceived.bind(this);
    this._renderIssue = this._renderIssue.bind(this);
    this._renderPagination = this._renderPagination.bind(this);
    this._changePage = this._changePage.bind(this);
    this.state = {
      issues: [],
      page: 1
    }
  }

  componentDidMount() {
    this.setState({milestone:this.props.milestone, issues:[], lastPage:-1}, this._getIssues);
  }

  componentWillReceiveProps(nextProps) {
    this.setState({milestone:nextProps.milestone, issues:[], lastPage:-1}, this._getIssues);
  }

  _getIssues() {
    this.props.repo.issues({
      milestone: this.state.milestone.number,
      state: 'all',
      page: this.state.page
    }, this._issuesReceived);
  }

  _issuesReceived(error, issues, headers) {
    const lastPage = this._loadLastPage(headers);
    this.setState({issues, headers, lastPage});
  }

  _loadLastPage(headers) {
    let lastPage = this.state.lastPage;
    let links = headers.link.split(',');
    links.forEach(function(link) {
      const [url, rel] = link.split(';').map(function(linkPart) {
        return linkPart
          .replace('rel="', '')
          .replace(/[<>"]/g, '')
          .trim();
      });
      if (rel === 'last') {
        lastPage = parseInt(url.replace(/.*page=(\d+).*/g, '$1'), 10);
      }
    });

    return lastPage;
  }

  render() {
    return (

          {this.props.milestone.title}

            {this.props.milestone.open_issues} open issues
            {this.props.milestone.closed_issues > 0 &&
              , {this.props.milestone.closed_issues} closed.
            }

          {
            this.state.issues.map(this._renderIssue)
          }

          {this._renderPagination()}

    );
  }

  _renderIssue(issue, index) {
    return (
      <Issue issue={issue} index={index} key={issue.id}/>
    )
  }

  _renderPagination() {
    if (!this.state.headers) {
      return;
    }
    console.log('lastPage', this.state.lastPage);
    let buttons = [];
    for (let i = 1; i <= this.state.lastPage; i++) {
      buttons.push(this._getPaginationButton(i));
    }
    buttons.unshift(this._getPaginationButton(this.state.page - 1, 'Previous'));
    buttons.push(   this._getPaginationButton(this.state.page + 1, 'Next'));
    return buttons;
  }

  _getPaginationButton(page, text) {
    let options = {
      className: [
        MilestoneStyles.__pagination_button
      ]
    };

    if (text !== undefined) {
      options.className.push(MilestoneStyles.__pagination_button_text);
    } else {
      text = page;
    }

    if (page === this.state.page) {
      options.className.push(MilestoneStyles.__pagination_button_current);
    }
    if (page > 0 && page <= this.state.lastPage) {
      options.onClick = this._changePage;
    } else {
      options.className.push(MilestoneStyles.__pagination_button_disabled);
      options.disabled = true;
    }
    options.className = options.className.join(' ');
    options.key = `button-${page}-${text}`;
    return (
      <button {...options} data-page={page}>
        {text}
      </button>
    );
  }

  _changePage(e) {
    e.target.blur();
    var page = parseInt(e.target.getAttribute('data-page'), 10);
    this.setState({issues:[], page}, this._getIssues);
  }

}
<|endoftext|>


<commit_before>var BarChartComponent = Ember.Component.extend({
    tagName: 'svg',
    classNames: ['bar-chart'],

    draw: function() {
      var data = this.get('data');
      if (Ember.isEmpty(data)) { return; }

      var el = this.get('element');
      var width = parseInt(d3.select(el).style('width'), 10);
      var height = parseInt(d3.select(el).style('height'), 10);
      var headerSpace = 20;
      var xAxisSpace = 50;
      var yAxisSpace = 50;
      var barsWidth = width - yAxisSpace;
      var barsHeight = height - headerSpace - xAxisSpace;

      var yFormat = window.d3.format(".2s");

      var svg = window.d3.select(el);
      var x0 = window.d3.scale.ordinal().rangeRoundBands([0, barsWidth], 0.1);
      var x1 = window.d3.scale.ordinal();
      var y = window.d3.scale.linear().range([barsHeight, 0]);
      var color = window.d3.scale.ordinal().range(["#999", "white"]);

      var xAxis = window.d3.svg.axis().scale(x0).orient("bottom");
      var yAxis = window.d3.svg.axis().scale(y).orient("left").tickFormat(yFormat);

      var legendNames = data[0].values.map(function(d) { return d.legend; });
      x0.domain(data.map(function(d) { return d.group; }));
      x1.domain(legendNames).rangeRoundBands([0, x0.rangeBand()]);
      var maxY = window.d3.max(data, function(d) {
        return window.d3.max(d.values, function(d) {return d.yValue;});
      });
      y.domain([0, maxY]);

      svg.select(".x.axis")
        .attr("transform", "translate("+yAxisSpace+","+(headerSpace+barsHeight)+")")
        .call(xAxis);

      svg.selectAll(".x.axis text")
        .style("text-anchor", "start")
        .attr("transform", "translate(-20,0) rotate(22)");

      var yAxisNode = svg.select(".y.axis");
      svg.select(".y.axis .axis-title")
        .attr("transform", "translate("+(-yAxisSpace)+",-5)");
      yAxisNode.attr("transform", "translate("+yAxisSpace+","+headerSpace+")");
      yAxisNode.call(yAxis);

      // Grouped bars
      var group = svg.selectAll(".group")
          .data(data, function(d) { return d.group; });

      group.enter().append("g").attr("class", "group");

      group.attr("transform", function(d) {
          var xOffset = x0(d.group) + yAxisSpace;
          return "translate(" + xOffset + ",0)";
        });

      // Main bars
      var bars = group.selectAll("rect")
          .data(function(d) { return d.values; });

      bars.enter().append("rect");

      bars.attr("width", x1.rangeBand())
          .attr("rx", 6)
          .attr("yx", 6)
          .attr("x", function(d) { return x1(d.legend); })
          .attr("y", function(d) { return headerSpace + y(d.yValue); })
          .attr("height", function(d) { return barsHeight - y(d.yValue); })
          .style("fill", function(d) { return color(d.legend); });

      bars.exit().remove();

      // Legend rendering
      var legend = svg.selectAll(".legend")
          .data(legendNames.slice());

      var legendEnterGroup = legend.enter().append("g");
      legendEnterGroup.attr("class", "legend");
      legendEnterGroup.append("rect");
      legendEnterGroup.append("text");

      legend.attr("transform", function(d, i) {
        return "translate(" + i * 100 + ", 0)";
      });

      legend.selectAll("rect")
          .attr("rx", 6)
          .attr("yx", 6)
          .attr("x", yAxisSpace)
          .attr("width", 16)
          .attr("height", 16)
          .style("fill", color);

      legend.selectAll("text")
          .attr("x", yAxisSpace+20)
          .attr("dy", "1em")
          .style("text-anchor", "start")
          .text(function(d) { return d; });

    }.observes("data.@each"),

    didInsertElement: function() {
      window.d3.select(window).on('resize', this.draw.bind(this));
    }
  });

export default BarChartComponent;<commit_msg>Code cleanup; shortcut `d3`<commit_after>var BarChartComponent = Ember.Component.extend({
    tagName: 'svg',
    classNames: ['bar-chart'],

    draw: function() {
      var data = this.get('data');
      if (Ember.isEmpty(data)) { return; }

      var d3 = window.d3;
      var el = this.get('element');
      var width = parseInt(d3.select(el).style('width'), 10);
      var height = parseInt(d3.select(el).style('height'), 10);
      var headerSpace = 20;
      var xAxisSpace = 50;
      var yAxisSpace = 50;
      var barsWidth = width - yAxisSpace;
      var barsHeight = height - headerSpace - xAxisSpace;

      var yFormat = d3.format(".2s");

      var svg = d3.select(el);
      var x0 = d3.scale.ordinal().rangeRoundBands([0, barsWidth], 0.1);
      var x1 = d3.scale.ordinal();
      var y = d3.scale.linear().range([barsHeight, 0]);
      var color = d3.scale.ordinal().range(["#999", "white"]);

      var xAxis = d3.svg.axis().scale(x0).orient("bottom");
      var yAxis = d3.svg.axis().scale(y).orient("left").tickFormat(yFormat);

      var legendNames = data[0].values.map(function(d) { return d.legend; });
      x0.domain(data.map(function(d) { return d.group; }));
      x1.domain(legendNames).rangeRoundBands([0, x0.rangeBand()]);
      var maxY = d3.max(data, function(d) {
        return d3.max(d.values, function(d) {return d.yValue;});
      });
      y.domain([0, maxY]);

      svg.select(".x.axis")
        .attr("transform", "translate("+yAxisSpace+","+(headerSpace+barsHeight)+")")
        .call(xAxis);

      svg.selectAll(".x.axis text")
        .style("text-anchor", "start")
        .attr("transform", "translate(-20,0) rotate(22)");

      var yAxisNode = svg.select(".y.axis");
      svg.select(".y.axis .axis-title")
        .attr("transform", "translate("+(-yAxisSpace)+",-5)");
      yAxisNode.attr("transform", "translate("+yAxisSpace+","+headerSpace+")");
      yAxisNode.call(yAxis);

      // Grouped bars
      var group = svg.selectAll(".group")
          .data(data, function(d) { return d.group; });

      group.enter().append("g").attr("class", "group");

      group.attr("transform", function(d) {
          var xOffset = x0(d.group) + yAxisSpace;
          return "translate(" + xOffset + ",0)";
        });

      // Main bars
      var bars = group.selectAll("rect")
          .data(function(d) { return d.values; });

      bars.enter().append("rect");

      bars.attr("width", x1.rangeBand())
          .attr("rx", 6)
          .attr("yx", 6)
          .attr("x", function(d) { return x1(d.legend); })
          .attr("y", function(d) { return headerSpace + y(d.yValue); })
          .attr("height", function(d) { return barsHeight - y(d.yValue); })
          .style("fill", function(d) { return color(d.legend); });

      bars.exit().remove();

      // Legend rendering
      var legend = svg.selectAll(".legend")
          .data(legendNames.slice());

      var legendEnterGroup = legend.enter().append("g");
      legendEnterGroup.attr("class", "legend");
      legendEnterGroup.append("rect");
      legendEnterGroup.append("text");

      legend.attr("transform", function(d, i) {
        return "translate(" + i * 100 + ", 0)";
      });

      legend.selectAll("rect")
          .attr("rx", 6)
          .attr("yx", 6)
          .attr("x", yAxisSpace)
          .attr("width", 16)
          .attr("height", 16)
          .style("fill", color);

      legend.selectAll("text")
          .attr("x", yAxisSpace+20)
          .attr("dy", "1em")
          .style("text-anchor", "start")
          .text(function(d) { return d; });

    }.observes("data.@each"),

    didInsertElement: function() {
      window.d3.select(window).on('resize', this.draw.bind(this));
    }
  });

export default BarChartComponent;<|endoftext|>


<commit_before>import React from 'react';
import Relay from 'react-relay';
import DocumentTitle from 'react-document-title';

import Button from '../shared/Button';
import Icon from '../shared/Icon';
import Panel from '../shared/Panel';
import PageHeader from '../shared/PageHeader';
import Spinner from '../shared/Spinner';

class SSOIndex extends React.PureComponent {
  static propTypes = {
    organization: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      slug: React.PropTypes.string.isRequired,
      sso: React.PropTypes.object
    }).isRequired,
    relay: React.PropTypes.object.isRequired
  };

  componentDidMount() {
    this.props.relay.forceFetch({ isMounted: true });
  }

  render() {
    return (
      <DocumentTitle title={`SSO · ${this.props.organization.name}`}>

          {/* this is a custom PageHeader body. *
            * you may not like it,              *
            * but this is what that looks like  */}

              <Icon
                icon="sso"
                className="align-middle mr2"
                style={{ width: 40, height: 40 }}
              />

              <PageHeader.Title>
                Single Sign On
              </PageHeader.Title>
              <PageHeader.Description>
                Manage your organization’s Single Sign On settings
              </PageHeader.Description>

          {this.renderDetailsPanel()}

      </DocumentTitle>
    );
  }

  renderLoginLink() {
    const url = `/login?org=${this.props.organization.slug}`;

    return {url};
  }

  renderDetailsPanel() {
    if (!this.props.organization.sso) {
      return (
        <Panel>
          <Panel.Section className="center">
            <Spinner />
          </Panel.Section>
        </Panel>
      );
    }

    if (this.props.organization.sso.isEnabled) {
      return (
        <Panel>
          <Panel.Section>

Single Sign On is enabled using {this.props.organization.sso.provider.name}

Anyone with {this.props.organization.sso.provider.emailDomain} email address address can login to Buildkite by entering their email address on the login page.

Your organization specific login URL is: {this.renderLoginLink()}

          </Panel.Section>
        </Panel>
      );
    } else {
      return (

          <Panel>
            <Panel.Section>

Single Sign On allows you require users to login to Buildkite using your own third-party authentication server. Once enabled, you’ll no longer have to invite users, as they’ll be automatically added to your organization when they go to login.

Supported SSO systems:

Bitium

Okta

Google Apps

SAML

ADFS (SAML)

              <Button href="mailto:support@buildkite.com?subject=Please enable SSO for my account!">Contact Support to Enable SSO</Button>
            </Panel.Section>
          </Panel>
          <Panel className="mt4">
            <Panel.Section>

Frequently Asked SSO Questions

How does user billing work with SSO?

When a user signs in with SSO, the additional user is added to your account and will be charged immediately, just as if you had invited them to the account.

What type of encryption is supported?

We support AE256 and all types of great encryption. In addition, you can use the ROT13 algorithm for extra security.

Can I use multiple email domains?

We currently only support a single email domain (e.g. example.com) for an organization.

Can I set up SSO for additional organizations?

We support setting up SSO for additional organizations, but one of the organizations will be the default. To login to the secondary organizations, you can add ?asd to your organization’s login URL.

            </Panel.Section>
          </Panel>

      );
    }
  }
}

export default Relay.createContainer(SSOIndex, {
  initialVariables: {
    isMounted: false
  },

  fragments: {
    organization: () => Relay.QL`
      fragment on Organization {
        name
        slug
        sso @include(if: $isMounted) {
          isEnabled
          provider {
            name
            ...on SSOProviderGoogle {
              emailDomain
            }
            ...on SSOProviderSAML {
              emailDomain
            }
          }
        }
      }
    `
  }
});
<commit_msg>Remove linefeed characters copied from Sketch(?!)<commit_after>import React from 'react';
import Relay from 'react-relay';
import DocumentTitle from 'react-document-title';

import Button from '../shared/Button';
import Icon from '../shared/Icon';
import Panel from '../shared/Panel';
import PageHeader from '../shared/PageHeader';
import Spinner from '../shared/Spinner';

class SSOIndex extends React.PureComponent {
  static propTypes = {
    organization: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      slug: React.PropTypes.string.isRequired,
      sso: React.PropTypes.object
    }).isRequired,
    relay: React.PropTypes.object.isRequired
  };

  componentDidMount() {
    this.props.relay.forceFetch({ isMounted: true });
  }

  render() {
    return (
      <DocumentTitle title={`SSO · ${this.props.organization.name}`}>

          {/* this is a custom PageHeader body. *
            * you may not like it,              *
            * but this is what that looks like  */}

              <Icon
                icon="sso"
                className="align-middle mr2"
                style={{ width: 40, height: 40 }}
              />

              <PageHeader.Title>
                Single Sign On
              </PageHeader.Title>
              <PageHeader.Description>
                Manage your organization’s Single Sign On settings
              </PageHeader.Description>

          {this.renderDetailsPanel()}

      </DocumentTitle>
    );
  }

  renderLoginLink() {
    const url = `/login?org=${this.props.organization.slug}`;

    return {url};
  }

  renderDetailsPanel() {
    if (!this.props.organization.sso) {
      return (
        <Panel>
          <Panel.Section className="center">
            <Spinner />
          </Panel.Section>
        </Panel>
      );
    }

    if (this.props.organization.sso.isEnabled) {
      return (
        <Panel>
          <Panel.Section>

Single Sign On is enabled using {this.props.organization.sso.provider.name}

Anyone with {this.props.organization.sso.provider.emailDomain} email address address can login to Buildkite by entering their email address on the login page.

Your organization specific login URL is: {this.renderLoginLink()}

          </Panel.Section>
        </Panel>
      );
    } else {
      return (

          <Panel>
            <Panel.Section>

Single Sign On allows you require users to login to Buildkite using your own third-party authentication server. Once enabled, you’ll no longer have to invite users, as they’ll be automatically added to your organization when they go to login.

Supported SSO systems:

Bitium

Okta

Google Apps

SAML

ADFS (SAML)

              <Button href="mailto:support@buildkite.com?subject=Please enable SSO for my account!">Contact Support to Enable SSO</Button>
            </Panel.Section>
          </Panel>
          <Panel className="mt4">
            <Panel.Section>

Frequently Asked SSO Questions

How does user billing work with SSO?

When a user signs in with SSO, the additional user is added to your account and will be charged immediately, just as if you had invited them to the account.

What type of encryption is supported?

We support AE256 and all types of great encryption. In addition, you can use the ROT13 algorithm for extra security.

Can I use multiple email domains?

We currently only support a single email domain (e.g. example.com) for an organization.

Can I set up SSO for additional organizations?

We support setting up SSO for additional organizations, but one of the organizations will be the default. To login to the secondary organizations, you can add ?asd to your organization’s login URL.

            </Panel.Section>
          </Panel>

      );
    }
  }
}

export default Relay.createContainer(SSOIndex, {
  initialVariables: {
    isMounted: false
  },

  fragments: {
    organization: () => Relay.QL`
      fragment on Organization {
        name
        slug
        sso @include(if: $isMounted) {
          isEnabled
          provider {
            name
            ...on SSOProviderGoogle {
              emailDomain
            }
            ...on SSOProviderSAML {
              emailDomain
            }
          }
        }
      }
    `
  }
});
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp')

.config(['$stateProvider', function($stateProvider) {
    $stateProvider
        .state('app.team_new', {
            url: 'team/new',
            templateUrl: 'components/team/team.html',
            controller: 'TeamCtrl'
        })

    .state('app.team_edit', {
        url: 'team/id/:teamid',
        templateUrl: 'components/team/team.html',
        controller: 'TeamCtrl'
            // params: {
            //     teamid: { value: 0 }
            // }
    });
}])

.controller('TeamCtrl', ['TeamServe', '$stateParams', '$scope', '$http', '$rootScope', '$uibModal', '$log', '$filter', '$state',
    function(TeamServe, $stateParams, $scope, $http, $rootScope, $uibModal, $log, $filter, $state) {
        console.log('now in TeamCtrl...');
        //显示列表
        if (!$stateParams.teamid) {
            TeamServe.query(function(resp) {
                console.log(resp);
                if (resp.code == '50000') {
                    $scope.teamlist = resp.data.teams;
                    $scope.userlist = resp.data.users;
                }
            });
        } else {
            // 单个编辑
            TeamServe.get({ session_id: $rootScope.session.session_id, team_id: $stateParams.teamid }, function(resp) {
                console.log(resp);
                $scope.team = resp.data.teams[0];
                console.log($scope.team);
            });
        }

        //添加/编辑团队
        $scope.saveTeam = function() {
            console.log('post new team');
            if ($scope.newteamForm.$valid) {
                console.log('save...');
                console.log($rootScope.session);
                console.log('$rootScope.session.session_id:' + $rootScope.session.session_id);

                var teamResource = new TeamServe($scope.team);
                console.log(teamResource);
                teamResource.$save({ session_id: $rootScope.session.session_id }, function(data) {
                    console.log(data);
                    console.log('添加/编辑团队成功');
                }, function() {
                    console.log('添加/编辑团队失败');
                })
            }
        };

        //删除团队
        $scope.deleteTeam = function(team_id) {
            console.log('删除团队...');
            var teamResource = new TeamServe($scope.team);
            teamResource.remove({ session_id: $rootScope.session.session_id }, function(resp) {
                console.log(resp);
                console.log('删除成功');

                //本地数据移除删除掉的team
                $scope.teamlist = $filter('filter', $scope.teamlist, { id: '!' + team_id });
            });
        };

        //dialog代码
        var $ctrl = this;
        $ctrl.items = ['item1', 'item2', 'item3'];

        $ctrl.open = function(size) {
            var modalInstance = $uibModal.open({
                animation: true,
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                templateUrl: '/components/team/addMenber.html',
                controller: 'ModalInstanceCtrl',
                controllerAs: '$ctrl',
                size: size,
                resolve: {
                    items: function() {
                        return $ctrl.items;
                    }
                }
            });

            modalInstance.result.then(function(selectedItem) {
                $ctrl.selected = selectedItem;
            }, function() {
                $log.info('Modal dismissed at: ' + new Date());
            });
        };

        // $ctrl.openComponentModal = function() {
        //     var modalInstance = $uibModal.open({
        //         animation: true,
        //         component: 'modalComponent',
        //         resolve: {
        //             items: function() {
        //                 return $ctrl.items;
        //             }
        //         }
        //     });

        //     modalInstance.result.then(function(selectedItem) {
        //         $ctrl.selected = selectedItem;
        //     }, function() {
        //         $log.info('modal-component dismissed at: ' + new Date());
        //     });
        // };
        //end dialog
    }
])

// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
.controller('ModalInstanceCtrl', ['$uibModalInstance', 'items', function($uibModalInstance, items) {
    var $ctrl = this;
    $ctrl.items = items;
    $ctrl.selected = {
        item: $ctrl.items[0]
    };

    $ctrl.ok = function() {
        $uibModalInstance.close($ctrl.selected.item);
    };

    $ctrl.cancel = function() {
        $uibModalInstance.dismiss('cancel');
    };
}])

// // Please note that the close and dismiss bindings are from $uibModalInstance.
// .component('modalComponent', {
//     templateUrl: '/components/team/addMenber.html',
//     bindings: {
//         resolve: '<',
//         close: '&',
//         dismiss: '&'
//     },
//     controller: function() {
//         var $ctrl = this;

//         $ctrl.$onInit = function() {
//             $ctrl.items = $ctrl.resolve.items;
//             $ctrl.selected = {
//                 item: $ctrl.items[0]
//             };
//         };

//         $ctrl.ok = function() {
//             $ctrl.close({ $value: $ctrl.selected.item });
//         };

//         $ctrl.cancel = function() {
//             $ctrl.dismiss({ $value: 'cancel' });
//         };
//     }
// });
<commit_msg>delete done<commit_after>'use strict';

angular.module('myApp')

.config(['$stateProvider', function($stateProvider) {
    $stateProvider
        .state('app.team_new', {
            url: 'team/new',
            templateUrl: 'components/team/team.html',
            controller: 'TeamCtrl'
        })

    .state('app.team_edit', {
        url: 'team/id/:teamid',
        templateUrl: 'components/team/team.html',
        controller: 'TeamCtrl'
            // params: {
            //     teamid: { value: 0 }
            // }
    });
}])

.controller('TeamCtrl', ['TeamServe', '$stateParams', '$scope', '$http', '$rootScope', '$uibModal', '$log', '$filter', '$state',
    function(TeamServe, $stateParams, $scope, $http, $rootScope, $uibModal, $log, $filter, $state) {
        console.log('now in TeamCtrl...');
        //显示列表
        if (!$stateParams.teamid) {
            console.log('get team list...');
            TeamServe.query(function(resp) {
                console.log(resp);
                if (resp.code == '50000') {
                    $scope.teamlist = resp.data.teams;
                    $scope.userlist = resp.data.users;
                }
            });
        } else {
            // 单个编辑
            TeamServe.get({ session_id: $rootScope.session.session_id, team_id: $stateParams.teamid }, function(resp) {
                console.log(resp);
                $scope.team = resp.data.teams[0];
                console.log($scope.team);
            });
        }

        //添加/编辑团队
        $scope.saveTeam = function() {
            console.log('post new team');
            if ($scope.newteamForm.$valid) {
                console.log('save...');
                console.log($rootScope.session);
                console.log('$rootScope.session.session_id:' + $rootScope.session.session_id);

                var teamResource = new TeamServe($scope.team);
                console.log(teamResource);
                teamResource.$save({ session_id: $rootScope.session.session_id }, function(data) {
                    console.log(data);
                    console.log('添加/编辑团队成功');
                    $state.go('app.team');
                }, function() {
                    console.log('添加/编辑团队失败');
                })
            }
        };

        //删除团队
        $scope.deleteTeam = function(team_id) {
            console.log('删除团队...');
            var teamResource = new TeamServe($scope.team);
            teamResource.$remove({ session_id: $rootScope.session.session_id, id: team_id }, function(resp) {
                console.log(resp);
                console.log('删除成功');

                //本地数据移除删除掉的team
                $scope.teamlist = $filter('filter')($scope.teamlist, { id: '!' + team_id });
            });
        };

        //dialog代码
        var $ctrl = this;
        $ctrl.items = ['item1', 'item2', 'item3'];

        $ctrl.open = function(size) {
            var modalInstance = $uibModal.open({
                animation: true,
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                templateUrl: '/components/team/addMenber.html',
                controller: 'ModalInstanceCtrl',
                controllerAs: '$ctrl',
                size: size,
                resolve: {
                    items: function() {
                        return $ctrl.items;
                    }
                }
            });

            modalInstance.result.then(function(selectedItem) {
                $ctrl.selected = selectedItem;
            }, function() {
                $log.info('Modal dismissed at: ' + new Date());
            });
        };

        // $ctrl.openComponentModal = function() {
        //     var modalInstance = $uibModal.open({
        //         animation: true,
        //         component: 'modalComponent',
        //         resolve: {
        //             items: function() {
        //                 return $ctrl.items;
        //             }
        //         }
        //     });

        //     modalInstance.result.then(function(selectedItem) {
        //         $ctrl.selected = selectedItem;
        //     }, function() {
        //         $log.info('modal-component dismissed at: ' + new Date());
        //     });
        // };
        //end dialog
    }
])

// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
.controller('ModalInstanceCtrl', ['$uibModalInstance', 'items', function($uibModalInstance, items) {
    var $ctrl = this;
    $ctrl.items = items;
    $ctrl.selected = {
        item: $ctrl.items[0]
    };

    $ctrl.ok = function() {
        $uibModalInstance.close($ctrl.selected.item);
    };

    $ctrl.cancel = function() {
        $uibModalInstance.dismiss('cancel');
    };
}])

// // Please note that the close and dismiss bindings are from $uibModalInstance.
// .component('modalComponent', {
//     templateUrl: '/components/team/addMenber.html',
//     bindings: {
//         resolve: '<',
//         close: '&',
//         dismiss: '&'
//     },
//     controller: function() {
//         var $ctrl = this;

//         $ctrl.$onInit = function() {
//             $ctrl.items = $ctrl.resolve.items;
//             $ctrl.selected = {
//                 item: $ctrl.items[0]
//             };
//         };

//         $ctrl.ok = function() {
//             $ctrl.close({ $value: $ctrl.selected.item });
//         };

//         $ctrl.cancel = function() {
//             $ctrl.dismiss({ $value: 'cancel' });
//         };
//     }
// });
<|endoftext|>


<commit_before>app
  .controller('mainCtrl', function(players, $scope, apiFactory, firebaseFactory) {
    console.log('mainCtrl firing')
    $scope.weeks = ["Week 1", "Week 2", "Week 3", "Week 4", "Week 5", "Week 6", "Week 7", "Week 8", "Week 9", "Week 10", "Week 11", "Week 12", "Week 13", "Week 14", "Week 15", "Week 16"]

    $scope.playerList = players;

    $scope.playerNames = {}  // making an object with just player names
    for (let j = 0; j < players.length; j++) {
      let name = ($scope.playerList[j].player.FirstName + " " + $scope.playerList[j].player.LastName)
      $scope.playerNames[name] = null
    }

      // _____ bar chart labels _____
    $scope.labels = ["Projected Season Pts", "Actual Season Pts", "Projected Weekly Pts", "Actual Weekly Pts"]

      // ____ auto-complete function ____
    $('input.autocomplete').autocomplete({
      data: $scope.playerNames,  // list of player names
      limit: 5,  // max amount of results
    });

    $scope.juxtaPose = function() {
      $scope.inputx = document.querySelector('.input-x').value  // capture the autocomplete values
      $scope.inputy = document.querySelector('.input-y').value  // capture the autocomplete values

      $scope.setPlayers('inputx', 'playerX', 'nameX');
      $scope.setPlayers('inputy', 'playerY', 'nameY');

      $scope.showJuxtaposition();
      $scope.series = [$scope.playerX.player.FirstName, $scope.playerY.player.FirstName]  // setting series names for bar chart

      $scope.showProjections($scope.nameX, 'projectionsX');  // find playerX projections, set obj to var
      $scope.showProjections($scope.nameY, 'projectionsY');  // find playerY projections, set obj to var

      $scope.showRankings($scope.nameX, 'rankingsX', 'positionXrank')
      $scope.showRankings($scope.nameY, 'rankingsY', 'positionYrank')

      $scope.showStats($scope.nameX, 'seasonProjectedX', 'seasonPtsX', 'weekProjectedX', 'weekPtsX')
      $scope.showStats($scope.nameY, 'seasonProjectedY', 'seasonPtsY', 'weekProjectedY', 'weekPtsY')
    }

    $scope.setPlayers = function (input, output, name) {
    // ____ find input player in playerList, set player object to output ____
      for (let i = 0; i < $scope.playerList.length; i++) {
        if ($scope[input] === ($scope.playerList[i].player.FirstName + " " + $scope.playerList[i].player.LastName)) {
          $scope[output] = $scope.playerList[i]
          $scope[name] = ($scope.playerList[i].player.FirstName + " " + $scope.playerList[i].player.LastName)
          console.log('name:', $scope[name])
          console.log('player:', $scope[output]['player'])
        }
      }
    }

    $scope.showJuxtaposition = function () {
      if ($scope.playerX === undefined || $scope.playerY === undefined) {
        alert("To see comparison, enter two valid Player names")
      }
      else {
        document.querySelector('.player-versus').removeAttribute('hidden')
        document.querySelector('.table').removeAttribute('hidden')
        document.querySelector('.carousel-slider').removeAttribute('hidden')
        document.querySelector('.choice-btn').removeAttribute('hidden')
        document.querySelector('.player-search').setAttribute('hidden', 'hidden')
      }
    }

    $scope.showProjections = function (guy, letter) {
      apiFactory.getNerdProjections()  // (guy.Position, [week#])
        .then((projections) => {
          for (i = 0; i < projections.length; i++) {
            if (projections[i].displayName === guy) {   // find matching player
              $scope[letter] = projections[i]
              console.log($scope[letter])
              console.log('good')
            }
          }
        })
    }

    $scope.showRankings = function (dude, letter, pos) {
      apiFactory.getNerdRankings() // (dude, [week#])
        .then((rankings) => {
          for (j = 0; j < rankings.length; j++) {
            if (rankings[j].name === dude) {   // find matching player
              $scope[letter] = rankings[j]
              $scope[pos] = j + 1
              console.log('position rank:', $scope[pos], 'rankings: ', $scope[letter])
            }
          }
        })
    }

    $scope.showStats = function (guy, seasonProj, season, weekProj, week) {
      apiFactory.getNflStats()
        .then((stats) => {
          for (k = 0; k < stats.length; k++) {
            if (stats[k].name === guy) {  // find matching player
              $scope[seasonProj] = stats[k].seasonProjectedPts
              $scope[season] = stats[k].seasonPts
              $scope[weekProj] = stats[k].weekProjectedPts
              $scope[week] = stats[k].weekPts

              $scope.data = [
                [$scope.seasonProjectedX, $scope.seasonPtsX, $scope.weekProjectedX, $scope.weekPtsX],
                [$scope.seasonProjectedY, $scope.seasonPtsY, $scope.weekProjectedY, $scope.weekPtsY]
              ]

              console.log($scope[seasonProj], $scope[season], $scope[weekProj], $scope[week])
            }
          }
        })
    }

      // _______ post to firebase _______
    $scope.postComparison = function (pick) {
      firebaseFactory.postComp($scope.nameX, $scope.nameY, pick, )
    }

    // _____ materialize stuff _____
    $('select').material_select();

    $('.carousel.carousel-slider').carousel({fullWidth: true});

  })
<commit_msg>added uid to posts<commit_after>app
  .controller('mainCtrl', function(players, $scope, apiFactory, firebaseFactory) {
    console.log('mainCtrl firing')
    $scope.weeks = ["Week 1", "Week 2", "Week 3", "Week 4", "Week 5", "Week 6", "Week 7", "Week 8", "Week 9", "Week 10", "Week 11", "Week 12", "Week 13", "Week 14", "Week 15", "Week 16"]

    $scope.playerList = players;

    $scope.playerNames = {}  // making an object with just player names for auto-complete function
    for (let j = 0; j < players.length; j++) {
      let name = ($scope.playerList[j].player.FirstName + " " + $scope.playerList[j].player.LastName)
      $scope.playerNames[name] = null
    }

      // ____ auto-complete function ____
    $('input.autocomplete').autocomplete({
      data: $scope.playerNames,  // list of player names
      limit: 5,  // max amount of results
    });

      // _____ bar chart labels _____
    $scope.labels = ["Projected Season Pts", "Actual Season Pts", "Projected Weekly Pts", "Actual Weekly Pts"]

    $scope.juxtaPose = function() {
      $scope.inputx = document.querySelector('.input-x').value  // capture the autocomplete values
      $scope.inputy = document.querySelector('.input-y').value  // capture the autocomplete values

      $scope.setPlayers('inputx', 'playerX', 'nameX');
      $scope.setPlayers('inputy', 'playerY', 'nameY');

      $scope.showJuxtaposition();
      $scope.series = [$scope.playerX.player.FirstName, $scope.playerY.player.FirstName]  // setting series names for bar chart

      $scope.showProjections($scope.nameX, 'projectionsX');  // find playerX projections, set obj to var
      $scope.showProjections($scope.nameY, 'projectionsY');  // find playerY projections, set obj to var

      $scope.showRankings($scope.nameX, 'rankingsX', 'positionXrank')
      $scope.showRankings($scope.nameY, 'rankingsY', 'positionYrank')

      $scope.showStats($scope.nameX, 'seasonProjectedX', 'seasonPtsX', 'weekProjectedX', 'weekPtsX')
      $scope.showStats($scope.nameY, 'seasonProjectedY', 'seasonPtsY', 'weekProjectedY', 'weekPtsY')
    }

    $scope.setPlayers = function (input, output, name) {
    // ____ find input player in playerList, set player object to output ____
      for (let i = 0; i < $scope.playerList.length; i++) {
        if ($scope[input] === ($scope.playerList[i].player.FirstName + " " + $scope.playerList[i].player.LastName)) {
          $scope[output] = $scope.playerList[i]
          $scope[name] = ($scope.playerList[i].player.FirstName + " " + $scope.playerList[i].player.LastName)
          console.log('name:', $scope[name])
          console.log('player:', $scope[output]['player'])
        }
      }
    }

    $scope.showJuxtaposition = function () {
      if ($scope.playerX === undefined || $scope.playerY === undefined) {
        alert("To see comparison, enter two valid Player names")
      }
      else {
        document.querySelector('.player-versus').removeAttribute('hidden')
        document.querySelector('.table').removeAttribute('hidden')
        document.querySelector('.carousel-slider').removeAttribute('hidden')
        document.querySelector('.choice-btn').removeAttribute('hidden')
        document.querySelector('.player-search').setAttribute('hidden', 'hidden')
      }
    }

    $scope.showProjections = function (guy, letter) {
      apiFactory.getNerdProjections()  // (guy.Position, [week#])
        .then((projections) => {
          for (i = 0; i < projections.length; i++) {
            if (projections[i].displayName === guy) {   // find matching player
              $scope[letter] = projections[i]
              console.log($scope[letter])
              console.log('good')
            }
          }
        })
    }

    $scope.showRankings = function (dude, letter, pos) {
      apiFactory.getNerdRankings() // (dude, [week#])
        .then((rankings) => {
          for (j = 0; j < rankings.length; j++) {
            if (rankings[j].name === dude) {   // find matching player
              $scope[letter] = rankings[j]
              $scope[pos] = j + 1
              console.log('position rank:', $scope[pos], 'rankings: ', $scope[letter])
            }
          }
        })
    }

    $scope.showStats = function (guy, seasonProj, season, weekProj, week) {
      apiFactory.getNflStats()
        .then((stats) => {
          for (k = 0; k < stats.length; k++) {
            if (stats[k].name === guy) {  // find matching player
              $scope[seasonProj] = stats[k].seasonProjectedPts
              $scope[season] = stats[k].seasonPts
              $scope[weekProj] = stats[k].weekProjectedPts
              $scope[week] = stats[k].weekPts

              $scope.data = [
                [$scope.seasonProjectedX, $scope.seasonPtsX, $scope.weekProjectedX, $scope.weekPtsX],
                [$scope.seasonProjectedY, $scope.seasonPtsY, $scope.weekProjectedY, $scope.weekPtsY]
              ]

              console.log($scope[seasonProj], $scope[season], $scope[weekProj], $scope[week])
            }
          }
        })
    }

      // _______ post to firebase _______
    $scope.postComparison = function (pick) {
      let uid = firebase.auth().currentUser.uid;
      firebaseFactory.postComp($scope.nameX, $scope.nameY, pick, uid)
    }

    // _____ materialize stuff _____
    $('select').material_select();

    $('.carousel.carousel-slider').carousel({fullWidth: true});

  })
<|endoftext|>


<commit_before>app.directive('graph', function() {
    return {
        restrict: 'EA',
        template: "

",
        controller : "LineCtrl"
    }
});

app.controller("LineCtrl", function($scope, $element, $interval, $window, dashboardService, d3Service) {
    var telemetry = dashboardService.telemetry;
    var parseTime = d3Service.timeParse("%Y-%m-%dT%H:%M:%S.%LZ");
    var prevSettings;

    $scope.data = [[0]];
    $scope.opts = {
        axes: {
            x: {
                drawGrid: true
            },
            y: {
                drawAxis: true
            }
        },
        //dateWindow: [0, 1],
        legend: "always",
        xlabel: "",
        axisLabelWidth : 80,
        xLabelHeight : 16,
        yLabelWidth : 16,
    };

    var graph = new Dygraph($element[0].firstChild, $scope.data, $scope.opts );

    $scope.interval = $interval(updatePlot, 1000);

    $scope.plotData =[];

    function updatePlot() {
        graph.resize();
        console.log("going")
        if($scope.widget.settings.data){
            if($scope.widget.settings.data.value !== "" && $scope.widget.settings.data.vehicles.length > 0) {
                var paramY = $scope.widget.settings.data.value;
                var vehicles = $scope.widget.settings.data.vehicles;
                var labels = ["x"]

                //reset plotData when there is a change in settings
                if (JSON.stringify(prevSettings) !== JSON.stringify($scope.widget.settings.data)){
                    for(v in vehicles){
                        var vehicle = vehicles[v];
                        if(!$scope.plotData){
                            $scope.plotData = new Array();
                        } else {
                            $scope.plotData = [];
                        }
                    }
                }

                for(var v in vehicles){
                    var vehicle = vehicles[v];

                    if(telemetry[vehicle.name] !== undefined){
                        var tTemp = parseTime(telemetry['time']);
                        var currentData = dashboardService.getData(vehicle.key);
                        if(currentData){
                            var xTemp = parseFloat(currentData.value.toFixed(4));
                            var category = currentData.category;
                            var yUnits = currentData.units;
                            $scope.plotData.push([tTemp, xTemp]);

                            if ($scope.plotData.length > 100) {
                                $scope.plotData.shift();
                            };
                        }
                    }

                    labels.push(vehicle.name);
                }

                if(category && paramY){
                    var ylabel = category+" [ "+paramY+ " ] " + yUnits + " "
                }

                graph.updateOptions({
                    file: $scope.plotData,
                    ylabel: ylabel,
                    xlabel: "timestamp",
                    labels: labels,
                    axes: {
                        y: {
                            //drawGrid: true,
                            valueFormatter: function(y) {
                                return parseFloat(y.toFixed(4));
                            },
                            axisLabelFormatter: function(y) {
                                return parseFloat(y.toFixed(4));
                            }
                        }
                    },
                    drawPoints: true
                });

                prevSettings = angular.copy($scope.widget.settings.data);
            }
        }
    }

    $scope.$on("$destroy",
        function(event) {
            $interval.cancel( $scope.interval );
        }
    );
});<commit_msg>cleaned code for dygraph line plot<commit_after>app.directive('graph', function() {
    return {
        restrict: 'EA',
        template: "

",
        controller : "LineCtrl"
    }
});

app.controller("LineCtrl", function($scope, $element, $interval, $window, dashboardService, d3Service) {
    var telemetry = dashboardService.telemetry;
    var parseTime = d3Service.timeParse("%Y-%m-%dT%H:%M:%S.%LZ");
    var prevSettings;

    $scope.data = [[0]];
    $scope.opts = {
        axes: {
            x: {
                drawGrid: true
            },
            y: {
                drawAxis: true
            }
        },
        //dateWindow: [0, 1],
        legend: "always",
        xlabel: "timestamp",
        axisLabelWidth : 80,
        xLabelHeight : 16,
        yLabelWidth : 16,
    };

    var graph = new Dygraph($element[0].firstChild, $scope.data, $scope.opts );

    $scope.interval = $interval(updatePlot, 1000);

    $scope.plotData =[];

    function updatePlot() {
        graph.resize();

        if($scope.widget.settings.data){
            if($scope.widget.settings.data.value !== "" && $scope.widget.settings.data.vehicles.length > 0) {
                var paramY = $scope.widget.settings.data.value;
                var vehicles = $scope.widget.settings.data.vehicles;
                var labels = ["x"]

                //reset plotData when there is a change in settings
                if (JSON.stringify(prevSettings) !== JSON.stringify($scope.widget.settings.data)){
                    for(v in vehicles){
                        var vehicle = vehicles[v];
                        if(!$scope.plotData){
                            $scope.plotData = new Array();
                        } else {
                            $scope.plotData = [];
                        }
                    }
                }

                for(var v in vehicles){
                    var vehicle = vehicles[v];

                    if(telemetry[vehicle.name] !== undefined){
                        var tTemp = parseTime(telemetry['time']);
                        var currentData = dashboardService.getData(vehicle.key);
                        if(currentData){
                            var xTemp = parseFloat(currentData.value.toFixed(4));
                            var category = currentData.category;
                            var yUnits = currentData.units;
                            $scope.plotData.push([tTemp, xTemp]);

                            if ($scope.plotData.length > 100) {
                                $scope.plotData.shift();
                            };
                        }
                    }

                    labels.push(vehicle.name);
                }

                if(category && paramY){
                    var ylabel = category+" [ "+paramY+ " ] " + yUnits + " "
                }

                graph.updateOptions({
                    file: $scope.plotData,
                    ylabel: ylabel,
                    xlabel: "timestamp",
                    labels: labels,
                    axes: {
                        y: {
                            //drawGrid: true,
                            valueFormatter: function(y) {
                                return parseFloat(y.toFixed(4));
                            },
                            axisLabelFormatter: function(y) {
                                return parseFloat(y.toFixed(4));
                            }
                        }
                    },
                    drawPoints: true
                });

                prevSettings = angular.copy($scope.widget.settings.data);
            }
        }
    }

    $scope.$on("$destroy",
        function(event) {
            $interval.cancel( $scope.interval );
        }
    );
});<|endoftext|>


<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

'use strict';

var request = require('request');
var through = require('through');
var duplexer = require('duplexer');
var _ = require('underscore');
var Constants = require('./constants');

var HttpVerbs = Constants.HttpVerbs;

//
// Request pipelines are functions that allow you to
// add filters to modify requests and responses
// before / after the actual HTTP request.
//

/**
 *
 * create a new http client pipeline that ends with a call to the
 * request library using the given sink function to actually make
 * the http request.
 *
 * @return function(request, callback) - function to make a request.
 *
 */
exports.createWithSink = function(sink) {
  var pipeline = sink;

  // The function that actually runs the pipeline. It starts simple
  function runFilteredRequest(options, callback) {
    return pipeline(options, callback);
  }

  function makeFilteredPipeline(filter) {
    var currentPipeline = pipeline;
    return function (options, callback) {
      return filter(options, currentPipeline, callback);
    };
  }

  // Add 'add' method so we can add filters.
  runFilteredRequest.add = function () {
    _.each(arguments, function (filter) {
      pipeline = makeFilteredPipeline(filter);
    });
  };

  // Add verb specific helper methods
  var verbs = _.values(HttpVerbs);
  verbs.forEach(function (method) {
    runFilteredRequest[method] = (function (m) {
      return function (options, callback) {
        options.method = m;
        return pipeline(options, callback);
      };
    })(method);
  });

  // If user passed any other parameters, assume they're filters
  // and add them.
  for(var i = 1; i < arguments.length; ++i) {
    runFilteredRequest.add(arguments[i]);
  }

  return runFilteredRequest;
};

/**
 * This function acts as the final sink for a request, actually
 * going out over the wire.
 *
 * @param {Object} [requestOptions] - The request options
 * {@link https://github.com/request/request#requestoptions-callback Options doc}
 *
 * @private
 * @param options The request to perform
 * @param callback function(err, result, response, body) callback function that
 * will be called at completion of the request.
 */
exports.requestLibrarySink = function (requestOptions) {

  return function (options, callback) {
    request = request.defaults(requestOptions);
    var requestStream;
    var bodyStream;
    if (options.headersOnly) {
      var requestHeaderStream = request(options);
      requestHeaderStream.on('error', function (err) {
        return callback(err);
      });
      requestHeaderStream.on('response', function (response) {
        requestHeaderStream.on('end', function () {
          return callback(null, response);
        });
      });
      return requestHeaderStream;
    } else if (options.streamedResponse) {
      if (options.body && typeof options.body.pipe === 'function') {
        bodyStream = options.body;
        options.body = null;
        requestStream = bodyStream.pipe(request(options));
      } else {
        requestStream = request(options);
      }
      requestStream.on('error', function (err) {
        return callback(err);
      });
      requestStream.on('response', function (response) {
        return callback(null, response);
      });
      return requestStream;
    } else if (options.body && typeof options.body.pipe === 'function') {
      bodyStream = options.body;
      options.body = null;
      return bodyStream.pipe(request(options, function (err, response, body) {
        if (err) { return callback(err); }
        return callback(null, response, body);
      }));
    } else {
      return request(options, function (err, response, body) {
        if (err) { return callback(err); }
        return callback(null, response, body);
      });
    }
  };
};

/**
 *
 * create a new http client pipeline that ends with a call to the
 * request library.
 *
 * @param {Object} [requestOptions] - The request options
 * {@link https://github.com/request/request#requestoptions-callback Options doc}
 *
 * @return function(request, callback) - function to make a request.
 *
 */
exports.create = function (requestOptions) {
  return function () {
    if (arguments.length === 0) {
      return exports.createWithSink(exports.requestLibrarySink);
    }
    // User passed filters to add to the pipeline.
    // build up appropriate arguments and call exports.createWithSink
    return exports.createWithSink.apply(null, [exports.requestLibrarySink(requestOptions)].concat(_.toArray(arguments)));
  };
};

/**
 * Create a new filter that's a combination of all the filters
 * given on the arguments list.
 *
 * @param {varargs} filters to run. First filter in the list is closest to
 * the sink, so last to run before the request, first to run on the response:
 * exactly the same as if you called pipeline.add or passed the list to
 * pipeline.create.
 *
 * @return the new filter.
 */
exports.createCompositeFilter = function() {
  var filter = arguments[0];

  function makePairedFilter(filterA, filterB) {
    return function(options, next, callback) {
      function callFilterA(o, cb) {
        return filterA(o, next, cb);
      }
      return filterB(options, callFilterA, callback);
    };
  }

  for(var i = 1; i < arguments.length; ++i) {
    filter = makePairedFilter(filter, arguments[i]);
  }
  return filter;
};

/**
 * Creates an interim stream which can be returned to the
 * caller synchronously, so that async operations can still
 * hook up to the streaming output afterwards. Used when
 * filters need to do async work before they can call the rest
 * of the pipeline.
 *
 * @param setPipe function(input, output)
 *    this function is invoked synchronously, to pass the two
 *    underlying streams. input should be piped to the result of
 *    the next filter. The result of next should be piped to output.
 *    It's common to pause the input stream to prevent data loss
 *    before actually returning the real stream to hook up to.
 *
 * @returns a duplex stream that writes to the input stream and
 * produces data from the output stream.
 */
exports.interimStream = function(setPipes) {
  var input = through();
  var output = through();
  var duplex = duplexer(input, output);
  setPipes(input, output);
  return duplex;
};

exports = module.exports;<commit_msg>requestLibrarySink should be called with requestOptions if no additional arguments specified. (#1108)<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

'use strict';

var request = require('request');
var through = require('through');
var duplexer = require('duplexer');
var _ = require('underscore');
var Constants = require('./constants');

var HttpVerbs = Constants.HttpVerbs;

//
// Request pipelines are functions that allow you to
// add filters to modify requests and responses
// before / after the actual HTTP request.
//

/**
 *
 * create a new http client pipeline that ends with a call to the
 * request library using the given sink function to actually make
 * the http request.
 *
 * @return function(request, callback) - function to make a request.
 *
 */
exports.createWithSink = function(sink) {
  var pipeline = sink;

  // The function that actually runs the pipeline. It starts simple
  function runFilteredRequest(options, callback) {
    return pipeline(options, callback);
  }

  function makeFilteredPipeline(filter) {
    var currentPipeline = pipeline;
    return function (options, callback) {
      return filter(options, currentPipeline, callback);
    };
  }

  // Add 'add' method so we can add filters.
  runFilteredRequest.add = function () {
    _.each(arguments, function (filter) {
      pipeline = makeFilteredPipeline(filter);
    });
  };

  // Add verb specific helper methods
  var verbs = _.values(HttpVerbs);
  verbs.forEach(function (method) {
    runFilteredRequest[method] = (function (m) {
      return function (options, callback) {
        options.method = m;
        return pipeline(options, callback);
      };
    })(method);
  });

  // If user passed any other parameters, assume they're filters
  // and add them.
  for(var i = 1; i < arguments.length; ++i) {
    runFilteredRequest.add(arguments[i]);
  }

  return runFilteredRequest;
};

/**
 * This function acts as the final sink for a request, actually
 * going out over the wire.
 *
 * @param {Object} [requestOptions] - The request options
 * {@link https://github.com/request/request#requestoptions-callback Options doc}
 *
 * @private
 * @param options The request to perform
 * @param callback function(err, result, response, body) callback function that
 * will be called at completion of the request.
 */
exports.requestLibrarySink = function (requestOptions) {

  return function (options, callback) {
    request = request.defaults(requestOptions);
    var requestStream;
    var bodyStream;
    if (options.headersOnly) {
      var requestHeaderStream = request(options);
      requestHeaderStream.on('error', function (err) {
        return callback(err);
      });
      requestHeaderStream.on('response', function (response) {
        requestHeaderStream.on('end', function () {
          return callback(null, response);
        });
      });
      return requestHeaderStream;
    } else if (options.streamedResponse) {
      if (options.body && typeof options.body.pipe === 'function') {
        bodyStream = options.body;
        options.body = null;
        requestStream = bodyStream.pipe(request(options));
      } else {
        requestStream = request(options);
      }
      requestStream.on('error', function (err) {
        return callback(err);
      });
      requestStream.on('response', function (response) {
        return callback(null, response);
      });
      return requestStream;
    } else if (options.body && typeof options.body.pipe === 'function') {
      bodyStream = options.body;
      options.body = null;
      return bodyStream.pipe(request(options, function (err, response, body) {
        if (err) { return callback(err); }
        return callback(null, response, body);
      }));
    } else {
      return request(options, function (err, response, body) {
        if (err) { return callback(err); }
        return callback(null, response, body);
      });
    }
  };
};

/**
 *
 * create a new http client pipeline that ends with a call to the
 * request library.
 *
 * @param {Object} [requestOptions] - The request options
 * {@link https://github.com/request/request#requestoptions-callback Options doc}
 *
 * @return function(request, callback) - function to make a request.
 *
 */
exports.create = function (requestOptions) {
  return function () {
    if (arguments.length === 0) {
      return exports.createWithSink(exports.requestLibrarySink(requestOptions));
    }
    // User passed filters to add to the pipeline.
    // build up appropriate arguments and call exports.createWithSink
    return exports.createWithSink.apply(null, [exports.requestLibrarySink(requestOptions)].concat(_.toArray(arguments)));
  };
};

/**
 * Create a new filter that's a combination of all the filters
 * given on the arguments list.
 *
 * @param {varargs} filters to run. First filter in the list is closest to
 * the sink, so last to run before the request, first to run on the response:
 * exactly the same as if you called pipeline.add or passed the list to
 * pipeline.create.
 *
 * @return the new filter.
 */
exports.createCompositeFilter = function() {
  var filter = arguments[0];

  function makePairedFilter(filterA, filterB) {
    return function(options, next, callback) {
      function callFilterA(o, cb) {
        return filterA(o, next, cb);
      }
      return filterB(options, callFilterA, callback);
    };
  }

  for(var i = 1; i < arguments.length; ++i) {
    filter = makePairedFilter(filter, arguments[i]);
  }
  return filter;
};

/**
 * Creates an interim stream which can be returned to the
 * caller synchronously, so that async operations can still
 * hook up to the streaming output afterwards. Used when
 * filters need to do async work before they can call the rest
 * of the pipeline.
 *
 * @param setPipe function(input, output)
 *    this function is invoked synchronously, to pass the two
 *    underlying streams. input should be piped to the result of
 *    the next filter. The result of next should be piped to output.
 *    It's common to pause the input stream to prevent data loss
 *    before actually returning the real stream to hook up to.
 *
 * @returns a duplex stream that writes to the input stream and
 * produces data from the output stream.
 */
exports.interimStream = function(setPipes) {
  var input = through();
  var output = through();
  var duplex = duplexer(input, output);
  setPipes(input, output);
  return duplex;
};

exports = module.exports;
<|endoftext|>