<commit_before>'use strict';
var React = require('react');
var _ = require('underscore');
var moment = require('moment');
var globals = require('./globals');
var fetched = require('./fetched');
var form = require('../libs/bootstrap/form');
var panel = require('../libs/bootstrap/panel');
var parseAndLogError = require('./mixins').parseAndLogError;
var RestMixin = require('./rest').RestMixin;
var CuratorHistory = require('./curator_history');

var Form = form.Form;
var FormMixin = form.FormMixin;
var Input = form.Input;
var Panel = panel.Panel;
var external_url_map = globals.external_url_map;
var userMatch = globals.userMatch;

var Dashboard = React.createClass({
    mixins: [RestMixin, CuratorHistory],

    getInitialState: function() {
        return {
            userName: '',
            userStatus: '',
            lastLogin: '',
            gdmList: [],
            histories: []
        };
    },

    cleanGdmGeneDiseaseName: function(gene, disease) {
        return gene + "–" + disease;
    },

    cleanGdmModelName: function(model) {
        // remove (HP:#######) from model name
        return model.indexOf('(') > -1 ? model.substring(0, model.indexOf('(') - 1) : model;
    },

    gdmMappingLoop: function(gdmMapping, gdmSubItem, gdmUuid, geneSymbol, diseaseTerm, modeInheritance, extraInfo) {
        // loop through an gdmSubItem and map its subitems' UUIDs to the GDM UUID and Disease/Gene/Mode data
        if (gdmSubItem.length > 0) {
            for (var i = 0; i < gdmSubItem.length; i++) {
                // create mapping object
                gdmMapping[gdmSubItem[i].uuid] = {
                    uuid: gdmUuid,
                    displayName: this.cleanGdmGeneDiseaseName(geneSymbol, diseaseTerm),
                    displayName2: this.cleanGdmModelName(modeInheritance),
                    extraInfo: extraInfo
                };
                // recursively loop through the annotations' groups, families, individuals
                if (gdmSubItem[i].individuals) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].individuals,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].families) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].families,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].groups) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].groups,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].experimentalData) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].experimentalData,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].familyIncluded) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].familyIncluded,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, _.extend({}, extraInfo, {parent: gdmSubItem[i].label, parentUrl: gdmSubItem[i]['@id'], parentType: gdmSubItem[i]['@type'][0]}));
                if (gdmSubItem[i].individualIncluded) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].individualIncluded,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, _.extend({}, extraInfo, {parent: gdmSubItem[i].label, parentUrl: gdmSubItem[i]['@id'], parentType: gdmSubItem[i]['@type'][0]}));
            }
        }
        return gdmMapping;
    },

    setUserData: function(props) {
        // sets the display name and curator status
        this.setState({
            userName: props.first_name,
            userStatus: props.job_title,
            lastLogin: ''
        });
    },

    getData: function(session) {
        // Retrieve all GDMs and other objects related to user via search
        this.getRestDatas(['/gdm/', '/search/?type=gdm&limit=10&submitted_by.uuid=' + session.user_properties.uuid], [function() {}, function() {}]).then(data => {
            // Search objects successfully retrieved; process results
            // GDM results; finds GDMs created by user, and also creates PMID-GDM mapping table
            // (stopgap measure until article -> GDM mapping ability is incorporated)
            var tempGdmList = [], tempRecentHistory = [];
            var gdmMapping = {};
            for (var i = 0; i < data[0]['@graph'].length; i++) {
                // loop through GDMs
                var gdm = data[0]['@graph'][i];
                if (userMatch(gdm.submitted_by, session)) {
                    tempGdmList.push({
                        uuid: gdm.uuid,
                        gdmGeneDisease: this.cleanGdmGeneDiseaseName(gdm.gene.symbol, gdm.disease.term),
                        gdmModel: this.cleanGdmModelName(gdm.modeInheritance),
                        status: gdm.gdm_status,
                        date_created: gdm.date_created
                    });
                }
                // loop through annotations, if they exist, and map annotation UUIDs to GDMs
                if (gdm.annotations) gdmMapping = this.gdmMappingLoop(gdmMapping, gdm.annotations, gdm.uuid,
                    gdm.gene.symbol, gdm.disease.term, gdm.modeInheritance, null);
            }

            // Set states for cleaned results
            this.setState({gdmList: tempGdmList});
        }).catch(parseAndLogError.bind(undefined, 'putRequest'));
    },

    componentDidMount: function() {
        if (this.props.session.user_properties) {
            this.setUserData(this.props.session.user_properties);
            this.getData(this.props.session);
        }
        this.getHistories(this.props.session.user_properties, 10).then(histories => {
            if (histories) {
                this.setState({histories: histories});
            }
        });
    },

    componentWillReceiveProps: function(nextProps) {
        if (typeof nextProps.session.user_properties !== undefined && nextProps.session.user_properties != this.props.session.user_properties) {
            this.setUserData(nextProps.session.user_properties);
            this.getData(nextProps.session);
            this.getHistories(this.props.session.user_properties, 10).then(histories => {
                if (histories) {
                    this.setState({histories: histories});
                }
            });
        }
    },

    render: function() {
        return (

Welcome, {this.state.userName}!

Your status: {this.state.userStatus}

                        <Panel panelClassName="panel-dashboard">

Tools

Select Variant for Variant Curation

Create Gene-Disease Record

View list of all Gene-Disease Records

                        </Panel>
                        <Panel panelClassName="panel-dashboard">

Your Recent History

                            {this.state.histories.length ?

                                    {this.state.histories.map(history => {
                                        // Call the history display view based on the primary object
                                        var HistoryView = this.getHistoryView(history);
                                        return
<HistoryView history={history} user={this.props.session && this.props.session.user_properties} />
;
                                    })}

                            :

You have no activity to display.

                            }
                        </Panel>

                        <Panel panelClassName="panel-dashboard">

Your Gene-Disease Records

                            {this.state.gdmList.length > 0 ?

                                {this.state.gdmList.map(function(item) {
                                    return (

                                        {item.gdmGeneDisease}–{item.gdmModel}

                                        Status: {item.status}

                                        Creation Date: {moment(item.date_created).format("YYYY MMM DD, h:mm a")}

                                    );
                                })}

                            :
You have not created any Gene-Disease-Mode of Inheritance entries.
}
                        </Panel>

        );
    }
});

globals.curator_page.register(Dashboard, 'curator_page', 'dashboard');
<commit_msg>update componentwillreceiveprops in dashboard to get rid of setstate errors<commit_after>'use strict';
var React = require('react');
var _ = require('underscore');
var moment = require('moment');
var globals = require('./globals');
var fetched = require('./fetched');
var form = require('../libs/bootstrap/form');
var panel = require('../libs/bootstrap/panel');
var parseAndLogError = require('./mixins').parseAndLogError;
var RestMixin = require('./rest').RestMixin;
var CuratorHistory = require('./curator_history');

var Form = form.Form;
var FormMixin = form.FormMixin;
var Input = form.Input;
var Panel = panel.Panel;
var external_url_map = globals.external_url_map;
var userMatch = globals.userMatch;

var Dashboard = React.createClass({
    mixins: [RestMixin, CuratorHistory],

    getInitialState: function() {
        return {
            userName: '',
            userStatus: '',
            lastLogin: '',
            gdmList: [],
            histories: []
        };
    },

    cleanGdmGeneDiseaseName: function(gene, disease) {
        return gene + "–" + disease;
    },

    cleanGdmModelName: function(model) {
        // remove (HP:#######) from model name
        return model.indexOf('(') > -1 ? model.substring(0, model.indexOf('(') - 1) : model;
    },

    gdmMappingLoop: function(gdmMapping, gdmSubItem, gdmUuid, geneSymbol, diseaseTerm, modeInheritance, extraInfo) {
        // loop through an gdmSubItem and map its subitems' UUIDs to the GDM UUID and Disease/Gene/Mode data
        if (gdmSubItem.length > 0) {
            for (var i = 0; i < gdmSubItem.length; i++) {
                // create mapping object
                gdmMapping[gdmSubItem[i].uuid] = {
                    uuid: gdmUuid,
                    displayName: this.cleanGdmGeneDiseaseName(geneSymbol, diseaseTerm),
                    displayName2: this.cleanGdmModelName(modeInheritance),
                    extraInfo: extraInfo
                };
                // recursively loop through the annotations' groups, families, individuals
                if (gdmSubItem[i].individuals) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].individuals,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].families) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].families,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].groups) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].groups,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].experimentalData) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].experimentalData,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, {pmid: gdmSubItem[i].article.pmid, pmidUuid: gdmSubItem[i].uuid});
                if (gdmSubItem[i].familyIncluded) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].familyIncluded,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, _.extend({}, extraInfo, {parent: gdmSubItem[i].label, parentUrl: gdmSubItem[i]['@id'], parentType: gdmSubItem[i]['@type'][0]}));
                if (gdmSubItem[i].individualIncluded) gdmMapping = this.gdmMappingLoop(gdmMapping, gdmSubItem[i].individualIncluded,
                    gdmUuid, geneSymbol, diseaseTerm, modeInheritance, _.extend({}, extraInfo, {parent: gdmSubItem[i].label, parentUrl: gdmSubItem[i]['@id'], parentType: gdmSubItem[i]['@type'][0]}));
            }
        }
        return gdmMapping;
    },

    setUserData: function(props) {
        // sets the display name and curator status
        this.setState({
            userName: props.first_name,
            userStatus: props.job_title,
            lastLogin: ''
        });
    },

    getData: function(session) {
        // Retrieve all GDMs and other objects related to user via search
        this.getRestDatas(['/gdm/', '/search/?type=gdm&limit=10&submitted_by.uuid=' + session.user_properties.uuid], [function() {}, function() {}]).then(data => {
            // Search objects successfully retrieved; process results
            // GDM results; finds GDMs created by user, and also creates PMID-GDM mapping table
            // (stopgap measure until article -> GDM mapping ability is incorporated)
            var tempGdmList = [], tempRecentHistory = [];
            var gdmMapping = {};
            for (var i = 0; i < data[0]['@graph'].length; i++) {
                // loop through GDMs
                var gdm = data[0]['@graph'][i];
                if (userMatch(gdm.submitted_by, session)) {
                    tempGdmList.push({
                        uuid: gdm.uuid,
                        gdmGeneDisease: this.cleanGdmGeneDiseaseName(gdm.gene.symbol, gdm.disease.term),
                        gdmModel: this.cleanGdmModelName(gdm.modeInheritance),
                        status: gdm.gdm_status,
                        date_created: gdm.date_created
                    });
                }
                // loop through annotations, if they exist, and map annotation UUIDs to GDMs
                if (gdm.annotations) gdmMapping = this.gdmMappingLoop(gdmMapping, gdm.annotations, gdm.uuid,
                    gdm.gene.symbol, gdm.disease.term, gdm.modeInheritance, null);
            }

            // Set states for cleaned results
            this.setState({gdmList: tempGdmList});
        }).catch(parseAndLogError.bind(undefined, 'putRequest'));
    },

    componentDidMount: function() {
        if (this.props.session.user_properties) {
            this.setUserData(this.props.session.user_properties);
            this.getData(this.props.session);
        }
        this.getHistories(this.props.session.user_properties, 10).then(histories => {
            if (histories) {
                this.setState({histories: histories});
            }
        });
    },

    componentWillReceiveProps: function(nextProps) {
        if (nextProps.session.user_properties && nextProps.href.indexOf('dashboard') > -1 && !_.isEqual(nextProps.session.user_properties, this.props.session.user_properties)) {
            this.setUserData(nextProps.session.user_properties);
            this.getData(nextProps.session);
            this.getHistories(nextProps.session.user_properties, 10).then(histories => {
                if (histories) {
                    this.setState({histories: histories});
                }
            });
        }
    },

    render: function() {
        return (

Welcome, {this.state.userName}!

Your status: {this.state.userStatus}

                        <Panel panelClassName="panel-dashboard">

Tools

Select Variant for Variant Curation

Create Gene-Disease Record

View list of all Gene-Disease Records

                        </Panel>
                        <Panel panelClassName="panel-dashboard">

Your Recent History

                            {this.state.histories.length ?

                                    {this.state.histories.map(history => {
                                        // Call the history display view based on the primary object
                                        var HistoryView = this.getHistoryView(history);
                                        return
<HistoryView history={history} user={this.props.session && this.props.session.user_properties} />
;
                                    })}

                            :

You have no activity to display.

                            }
                        </Panel>

                        <Panel panelClassName="panel-dashboard">

Your Gene-Disease Records

                            {this.state.gdmList.length > 0 ?

                                {this.state.gdmList.map(function(item) {
                                    return (

                                        {item.gdmGeneDisease}–{item.gdmModel}

                                        Status: {item.status}

                                        Creation Date: {moment(item.date_created).format("YYYY MMM DD, h:mm a")}

                                    );
                                })}

                            :
You have not created any Gene-Disease-Mode of Inheritance entries.
}
                        </Panel>

        );
    }
});

globals.curator_page.register(Dashboard, 'curator_page', 'dashboard');
<|endoftext|>


<commit_before>'use strict';

var srlog = SIREPO.srlog;
var srdbg = SIREPO.srdbg;

SIREPO.app.config(function() {
    SIREPO.appReportTypes  = ['analysis', 'general', 'plan'].map((t) => {
	return `<div data-ng-switch-when="${t}Metadata" data-metadata-table="" data-type="${t}"></div>`;
    }).join('');
});

SIREPO.app.factory('raydataService', function(appState) {
    const self = {};
    appState.setAppService(self);
    return self;
});

SIREPO.app.controller('AnalysisController', function(appState, frameCache, persistentSimulation, $scope) {
    const self = this;
    self.appState = appState;
    self.simScope = $scope;
    self.simComputeModel = 'analysisAnimation';
    self.simHandleStatus = function (data) {
        if (data.frameCount) {
            frameCache.setFrameCount(data.frameCount);
        }
    };
    self.simState = persistentSimulation.initSimulationState(self);
    return self;
});

SIREPO.app.controller('MetadataController', function(appState, frameCache, persistentSimulation, $scope) {
    const self = this;
    return self;
});

SIREPO.app.directive('appFooter', function() {
    return {
        restrict: 'A',
        scope: {
            nav: '=appFooter',
        },
        template: `
            '

'
        `
    };
});

SIREPO.app.directive('appHeader', function(appState, panelState) {
    return {
	restrict: 'A',
	scope: {
            nav: '=appHeader',
	},
        template: `

              <app-header-right-sim-loaded>

 Metadata

 Analysis

              </app-header-right-sim-loaded>

        `
    };
});

SIREPO.app.directive('metadataTable', function() {
    return {
        restrict: 'A',
        scope: {
	    type: '@'
	},
        template: `

                    Field
                    Value

                    {{ k }}
                    {{ v }}
                    <button class="glyphicon glyphicon-plus" data-ng-if="isOverflown(k)" data-ng-click="toggleExpanded(k)">
                    <button class="glyphicon glyphicon-minus" data-ng-if="expanded[k]" data-ng-click="toggleExpanded(k)">

        `,
        controller: function(appState, requestSender, $sce, $scope) {
	    $scope.data = null;
	    $scope.expanded = {};

	    $scope.isOverflown = function(key) {
		// Id's may be malformed (spaces) so use this jquery syntax
		// to cover them
		const e = $(`[id='metadata-table-${key}']`);
		return e.prop('clientWidth') < e.prop('scrollWidth');
	    };

	    $scope.toggleExpanded = function(key) {
		const e = $(`[id='metadata-table-${key}']`);
		if (!(key in $scope.expanded)) {
		    $scope.expanded[key] = false;
		}
		$scope.expanded[key] = ! $scope.expanded[key];
		e.toggleClass('raydata-overflow-text');
	    };

	    requestSender.statelessCompute(
		appState,
		{
		    method: $scope.type + '_metadata'
		},
		(data) => {
		    $scope.data = data.data;
		}
	    );
        },
    };
});
<commit_msg>indentation<commit_after>'use strict';

var srlog = SIREPO.srlog;
var srdbg = SIREPO.srdbg;

SIREPO.app.config(function() {
    SIREPO.appReportTypes  = ['analysis', 'general', 'plan'].map((t) => {
	return `<div data-ng-switch-when="${t}Metadata" data-metadata-table="" data-type="${t}"></div>`;
    }).join('');
});

SIREPO.app.factory('raydataService', function(appState) {
    const self = {};
    appState.setAppService(self);
    return self;
});

SIREPO.app.controller('AnalysisController', function(appState, frameCache, persistentSimulation, $scope) {
    const self = this;
    self.appState = appState;
    self.simScope = $scope;
    self.simComputeModel = 'analysisAnimation';
    self.simHandleStatus = function (data) {
        if (data.frameCount) {
            frameCache.setFrameCount(data.frameCount);
        }
    };
    self.simState = persistentSimulation.initSimulationState(self);
    return self;
});

SIREPO.app.controller('MetadataController', function(appState, frameCache, persistentSimulation, $scope) {
    const self = this;
    return self;
});

SIREPO.app.directive('appFooter', function() {
    return {
        restrict: 'A',
        scope: {
            nav: '=appFooter',
        },
        template: `
            '

'
        `
    };
});

SIREPO.app.directive('appHeader', function(appState, panelState) {
    return {
	restrict: 'A',
	scope: {
            nav: '=appHeader',
	},
        template: `

              <app-header-right-sim-loaded>

 Metadata

 Analysis

              </app-header-right-sim-loaded>

        `
    };
});

SIREPO.app.directive('metadataTable', function() {
    return {
        restrict: 'A',
        scope: {
	    type: '@'
	},
        template: `

                    Field
                    Value

                    {{ k }}
                    {{ v }}
                    <button class="glyphicon glyphicon-plus" data-ng-if="isOverflown(k)" data-ng-click="toggleExpanded(k)">
                    <button class="glyphicon glyphicon-minus" data-ng-if="expanded[k]" data-ng-click="toggleExpanded(k)">

	`,
	controller: function(appState, requestSender, $sce, $scope) {
	    $scope.data = null;
	    $scope.expanded = {};

	    $scope.isOverflown = function(key) {
		// Id's may be malformed (spaces) so use this jquery syntax
		// to cover them
		const e = $(`[id='metadata-table-${key}']`);
		return e.prop('clientWidth') < e.prop('scrollWidth');
	    };

	    $scope.toggleExpanded = function(key) {
		const e = $(`[id='metadata-table-${key}']`);
		if (!(key in $scope.expanded)) {
		    $scope.expanded[key] = false;
		}
		$scope.expanded[key] = ! $scope.expanded[key];
		e.toggleClass('raydata-overflow-text');
	    };

	    requestSender.statelessCompute(
		appState,
		{
		    method: $scope.type + '_metadata'
		},
		(data) => {
		    $scope.data = data.data;
		}
	    );
        },
    };
});
<|endoftext|>


<commit_before>import React from 'react';
import LinearGradient from 'react-native-linear-gradient';

import Styles from './resources/styles';
import { Components } from '../../global/globalIncludes';

const { Text } = Components.Text;

class SessionSectionHeader extends React.Component {
    props: {
        title: string;
    };

    render() {
        return (
            <LinearGradient colors={['#F4F6F7', '#EBEEF1']} style={Styles.header}>
                <Text style={Styles.label}>
                    {this.props.title}
                </Text>
            </LinearGradient>
        );
    }
}

module.exports = SessionSectionHeader;
<commit_msg>Sessionsectionheader refactor<commit_after>/* eslint-disable import/no-unresolved */
import React from 'react';
import LinearGradient from 'react-native-linear-gradient';

import Styles from './resources/styles';
import { Components } from '../../global/globalIncludes';

const { Text } = Components.Text;

class SessionSectionHeader extends React.Component {
    props: {
        title: string;
    };

    render() {
        return (
            <LinearGradient colors={['#F4F6F7', '#EBEEF1']} style={Styles.header}>
                <Text style={Styles.label}>
                    {this.props.title}
                </Text>
            </LinearGradient>
        );
    }
}

module.exports = SessionSectionHeader;
<|endoftext|>


<commit_before>/**
 * Menu position
 *
 * @mixin
 *
 * Used for calculating an automatic position (used for VSelect)
 * Will position the VMenu content properly over the VSelect
 */
export default {
  methods: {
    // Revisit this
    calculateScroll () {
      if (this.selectedIndex === null) return

      let scrollTop = 0

      if (this.selectedIndex >= this.stopIndex) {
        scrollTop = this.$refs.content.scrollHeight
      } else if (this.selectedIndex > this.startIndex) {
        scrollTop = (
          (this.selectedIndex * (this.defaultOffset * 6)) -
          (this.defaultOffset * 7)
        )
      }

      this.$refs.content.scrollTop = scrollTop
    },
    calcLeftAuto () {
      if (this.isAttached) return 0

      return parseInt(this.dimensions.activator.left - this.defaultOffset * 2)
    },
    calcTopAuto () {
      const selectedIndex = Array.from(this.tiles)
        .findIndex(n => n.classList.contains('v-list__tile--active'))

      if (selectedIndex === -1) {
        this.selectedIndex = null

        return this.computedTop
      }

      this.selectedIndex = selectedIndex
      let actingIndex = selectedIndex

      let offsetPadding = -(this.defaultOffset * 2)
      // #708 Stop index should vary by tile length
      this.stopIndex = this.tiles.length > 4
        ? this.tiles.length - 4
        : this.tiles.length

      if (selectedIndex > this.startIndex && selectedIndex < this.stopIndex) {
        actingIndex = 2
        offsetPadding = (this.defaultOffset * 3)
      } else if (selectedIndex >= this.stopIndex) {
        offsetPadding = -(this.defaultOffset)
        actingIndex = selectedIndex - this.stopIndex
      }

      return (
        this.computedTop +
        offsetPadding -
        (actingIndex * (this.defaultOffset * 6))
      )
    }
  }
}
<commit_msg>fix(v-menu): fix auto calculations<commit_after>/**
 * Menu position
 *
 * @mixin
 *
 * Used for calculating an automatic position (used for VSelect)
 * Will position the VMenu content properly over the VSelect
 */
export default {
  methods: {
    // Revisit this
    calculateScroll () {
      if (this.selectedIndex === null) return

      let scrollTop = 0

      if (this.selectedIndex >= this.stopIndex) {
        scrollTop = this.$refs.content.scrollHeight
      } else if (this.selectedIndex > this.startIndex) {
        scrollTop = (
          (this.selectedIndex * (this.defaultOffset * 6)) -
          (this.defaultOffset * 7)
        )
      }

      this.$refs.content.scrollTop = scrollTop
    },
    calcLeftAuto () {
      if (this.isAttached) return 0

      return parseInt(this.dimensions.activator.left - this.defaultOffset * 2)
    },
    calcTopAuto () {
      const selectedIndex = Array.from(this.tiles)
        .findIndex(n => n.classList.contains('v-list__tile--active'))

      if (selectedIndex === -1) {
        this.selectedIndex = null

        return this.computedTop
      }

      this.selectedIndex = selectedIndex
      let actingIndex = selectedIndex

      let offsetPadding = -(this.defaultOffset * 6)
      // #708 Stop index should vary by tile length
      this.stopIndex = this.tiles.length > 4
        ? this.tiles.length - 4
        : this.tiles.length

      if (selectedIndex > this.startIndex && selectedIndex < this.stopIndex) {
        actingIndex = 2
        offsetPadding = -this.defaultOffset
      } else if (selectedIndex >= this.stopIndex) {
        offsetPadding = -(this.defaultOffset * 5)
        actingIndex = selectedIndex - this.stopIndex
      }

      return (
        this.computedTop +
        offsetPadding -
        (actingIndex * (this.defaultOffset * 6))
      )
    }
  }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './MapContainer.css'

class MapContainer extends Component {

	constructor(props) {
		super(props)
		this.state = {
			lat: -37.9722342,
			lon: 144.7729551
		}
		this.getUserLocation = this.getUserLocation.bind(this)

		// this.getUserLocation()
	}

	getUserLocation() {
		global.getUserLocation((data) => {
			const lat = data.latitude
			const lon = data.longitude
			this.setState({
				lat: lat,
				lon: lon
			})
		})
	}

	render() {
		var lat = this.state.lat
		var lon = this.state.lon
		return (

						<input id="sf-map-input-postcode" type="text" placeholder="Postcode"/>

				{lat && <GoogleMapReact
					defaultCenter={{lat: lat, lng: lon}}
					defaultZoom={9}
				/>}

		)
	}
}

export default MapContainer<commit_msg>add handler for postcode input field<commit_after>import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './MapContainer.css'

class MapContainer extends Component {

	constructor(props) {
		super(props)
		this.state = {
			lat: -37.9722342,
			lon: 144.7729551
		}
		this.getUserLocation = this.getUserLocation.bind(this)
		this.getResults = this.getResults.bind(this)
		// this.getUserLocation()
	}

	getUserLocation() {
		global.getUserLocation((data) => {
			const lat = data.latitude
			const lon = data.longitude
			this.setState({
				lat: lat,
				lon: lon
			})
		})
	}

	getResults(e) {
		if (e.key === 'Enter') {
			const postcode = e.target.value
			console.log(`${postcode} entered`)
		}
	}

	render() {
		var lat = this.state.lat
		var lon = this.state.lon
		return (

						<input id="sf-map-input-postcode" type="text" placeholder="Postcode" onKeyPress={this.getResults}/>

				{lat && <GoogleMapReact
					defaultCenter={{lat: lat, lng: lon}}
					defaultZoom={9}
				/>}

		)
	}
}

export default MapContainer<|endoftext|>


<commit_before>/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd

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.
*/

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
import dis from '../../../dispatcher';
import classNames from 'classnames';
import { _t } from '../../../languageHandler';

const MessageCase = Object.freeze({
    NotLoggedIn: "NotLoggedIn",
    Joining: "Joining",
    Loading: "Loading",
    Rejecting: "Rejecting",
    Kicked: "Kicked",
    Banned: "Banned",
    OtherThreePIDError: "OtherThreePIDError",
    InvitedEmailMismatch: "InvitedEmailMismatch",
    Invite: "Invite",
    ViewingRoom: "ViewingRoom",
    RoomNotFound: "RoomNotFound",
    OtherError: "OtherError",
});

module.exports = React.createClass({
    displayName: 'RoomPreviewBar',

    propTypes: {
        onJoinClick: PropTypes.func,
        onRejectClick: PropTypes.func,
        onForgetClick: PropTypes.func,
        onSignInClick: PropTypes.func,
        onSignUpClick: PropTypes.func,

        // if inviterName is specified, the preview bar will shown an invite to the room.
        // You should also specify onRejectClick if specifiying inviterName
        inviterName: PropTypes.string,

        // If invited by 3rd party invite, the email address the invite was sent to
        invitedEmail: PropTypes.string,

        // A standard client/server API error object. If supplied, indicates that the
        // caller was unable to fetch details about the room for the given reason.
        error: PropTypes.object,

        canPreview: PropTypes.bool,
        room: PropTypes.object,

        // When a spinner is present, a spinnerState can be specified to indicate the
        // purpose of the spinner.
        spinner: PropTypes.bool,
        spinnerState: PropTypes.oneOf(["joining"]),

        // The alias that was used to access this room, if appropriate
        // If given, this will be how the room is referred to (eg.
        // in error messages).
        roomAlias: PropTypes.string,
    },

    getDefaultProps: function() {
        return {
            onJoinClick: function() {},
        };
    },

    getInitialState: function() {
        return {
            busy: false,
        };
    },

    componentWillMount: function() {
        // If this is an invite and we've been told what email
        // address was invited, fetch the user's list of Threepids
        // so we can check them against the one that was invited
        if (this.props.inviterName && this.props.invitedEmail) {
            this.setState({busy: true});
            MatrixClientPeg.get().lookupThreePid(
                'email', this.props.invitedEmail,
            ).finally(() => {
                this.setState({busy: false});
            }).done((result) => {
                this.setState({invitedEmailMxid: result.mxid});
            }, (err) => {
                this.setState({threePidFetchError: err});
            });
        }
    },

    _getMessageCase() {
        if (this.props.joining) {
            return MessageCase.Joining;
        } else if (this.props.rejecting) {
            return MessageCase.Rejecting;
        } else if (this.props.loading) {
            return MessageCase.Loading;
        }
        const isGuest = MatrixClientPeg.get().isGuest();
        const myMember = !isGuest && this.props.room ?
            this.props.room.getMember(MatrixClientPeg.get().getUserId()) :
            null;

        if (isGuest) {
            return MessageCase.NotLoggedIn;
        } else if (this.props.inviterName) {
            if (this.props.invitedEmail) {
                if (this.state.threePidFetchError) {
                    return MessageCase.OtherThreePIDError;
                } else if (this.state.invitedEmailMxid != MatrixClientPeg.get().credentials.userId) {
                    return MessageCase.InvitedEmailMismatch;
                }
            }
            return MessageCase.Invite;
        } else if (myMember && myMember.isKicked()) {
            return MessageCase.Kicked;
        } else if (myMember && myMember && myMember.membership == 'ban') {
            return MessageCase.Banned;
        } else if (this.props.error) {
            if (this.props.error.errcode == 'M_NOT_FOUND') {
                return MessageCase.RoomNotFound;
            } else {
                return MessageCase.OtherError;
            }
        } else {
            return MessageCase.ViewingRoom;
        }
    },

    _getKickOrBanInfo() {
        const myMember = this.props.room ?
            this.props.room.getMember(MatrixClientPeg.get().getUserId()) :
            null;
        if (!myMember) {
            return {};
        }
        const kickerMember = this.props.room.currentState.getMember(
            myMember.events.member.getSender(),
        );
        const memberName = kickerMember ?
            kickerMember.name : myMember.events.member.getSender();
        const reason = myMember.events.member.getContent().reason;
        return {memberName, reason};
    },

    _joinRule: function() {
        const room = this.props.room;
        if (room) {
            const joinRules = room.currentState.getStateEvents('m.room.join_rules', '');
            if (joinRules) {
                return joinRules.getContent().join_rule;
            }
        }
    },

    _roomName: function() {
        return this.props.room ? this.props.room.name : (this.props.room_alias || _t("This room"));
    },

    onLoginClick: function() {
        dis.dispatch({ action: 'start_login' });
    },

    onRegisterClick: function() {
        dis.dispatch({ action: 'start_registration' });
    },

    render: function() {
        let showSpinner = false;
        let darkStyle = false;
        let title;
        let subTitle;
        let primaryActionHandler;
        let primaryActionLabel;
        let secondaryActionHandler;
        let secondaryActionLabel;

        switch (this._getMessageCase()) {
            case MessageCase.Joining: {
                title = _t("Joining room …");
                showSpinner = true;
                break;
            }
            case MessageCase.Loading: {
                title = _t("Loading …");
                showSpinner = true;
                break;
            }
            case MessageCase.Rejecting: {
                title = _t("Rejecting invite …");
                showSpinner = true;
                break;
            }
            case MessageCase.NotLoggedIn: {
                darkStyle = true;
                title = _t("Join the conversation with an account");
                primaryActionLabel = _t("Sign Up");
                primaryActionHandler = this.onRegisterClick;
                secondaryActionLabel = _t("Sign In");
                secondaryActionHandler = this.onLoginClick;
                break;
            }
            case MessageCase.Kicked: {
                const {memberName, reason} = this._getKickOrBanInfo();
                title = _t("You were kicked from this room by %(memberName)s", {memberName});
                subTitle = _t("Reason: %(reason)s", {reason});
                primaryActionLabel = _t("Re-join");
                primaryActionHandler = this.props.onJoinClick;
                secondaryActionLabel = _t("Forget this room");
                secondaryActionHandler = this.props.onForgetClick;
                break;
            }
            case MessageCase.Banned: {
                const {memberName, reason} = this._getKickOrBanInfo();
                title = _t("You were banned from this room by %(memberName)s", {memberName});
                subTitle = _t("Reason: %(reason)s", {reason});
                primaryActionLabel = _t("Forget this room");
                primaryActionHandler = this.props.onForgetClick;
                break;
            }
            case MessageCase.OtherThreePIDError: {
                title = _t("Something went wrong with your invite to this room");
                const joinRule = this._joinRule();
                const errCodeMessage = _t("%(errcode)s was returned while trying to valide your invite. You could try to pass this information on to a room admin.",
                    {errcode: this.state.threePidFetchError.errcode},
                );
                switch (joinRule) {
                    case "invite":
                        subTitle = [
                            _t("You can only join it with a working invite."),
                            errCodeMessage,
                        ];
                        break;
                    case "public":
                        subTitle = _t("You can still join it because this is a public room.");
                        primaryActionLabel = _t("Join the discussion");
                        primaryActionHandler = this.props.onJoinClick;
                        break;
                    default:
                        subTitle = errCodeMessage;
                        primaryActionLabel = _t("Try to join anyway");
                        primaryActionHandler = this.props.onJoinClick;
                        break;
                }
                break;
            }
            case MessageCase.InvitedEmailMismatch: {
                title = _t("The room invite wasn't sent to your account");
                const joinRule = this._joinRule();
                if (joinRule === "public") {
                    subTitle = _t("You can still join it because this is a public room.");
                    primaryActionLabel = _t("Join the discussion");
                    primaryActionHandler = this.props.onJoinClick;
                } else {
                    subTitle = _t("Sign in with a different account, ask for another invite, or add the e-mail address %(email)s to this account.", {email: this.props.invitedEmail});
                    if (joinRule !== "invite") {
                        primaryActionLabel = _t("Try to join anyway");
                        primaryActionHandler = this.props.onJoinClick;
                    }
                }
                break;
            }
            case MessageCase.Invite: {
                if (this.props.canPreview) {
                    title = _t("%(memberName)s invited you to this room", {memberName: this.props.inviterName});
                } else {
                    title = _t("Do you want to join this room?");
                    subTitle = _t("%(memberName)s invited you", {memberName: this.props.inviterName});
                }
                primaryActionLabel = _t("Accept");
                primaryActionHandler = this.props.onJoinClick;
                secondaryActionLabel = _t("Reject");
                secondaryActionHandler = this.props.onRejectClick;
                break;
            }
            case MessageCase.ViewingRoom: {
                if (this.props.canPreview) {
                    title = _t("You're previewing this room. Want to join it?");
                } else {
                    title = _t("This room can't be previewed. Do you want to join it?");
                }
                primaryActionLabel = _t("Join the discussion");
                primaryActionHandler = this.props.onJoinClick;
                break;
            }
            case MessageCase.RoomNotFound: {
                title = _t("%(roomName)s does not exist.", {roomName: this._roomName()});
                subTitle = _t("This room doesn't exist. Are you sure you're at the right place?");
                break;
            }
            case MessageCase.OtherError: {
                title = _t("%(roomName)s is not accessible at this time.", {roomName: this._roomName()});
                subTitle = [
                    _t("Try again later, or ask a room admin to check if you have access."),
                    _t("%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please <issueLink>submit a bug report</issueLink>.",
                        { errcode: this.props.error.errcode },
                        { issueLink: label => { label } },
                    ),
                ];
                break;
            }
        }

        const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
        const Spinner = sdk.getComponent('elements.Spinner');

        let subTitleElements;
        if (subTitle) {
            if (!Array.isArray(subTitle)) {
                subTitle = [subTitle];
            }
            subTitleElements = subTitle.map((t, i) => <p key={`subTitle${i}`}>{t}
);
        }

        let titleElement;
        if (showSpinner) {
            titleElement =
<Spinner />{ title }
;
        } else {
            titleElement =
{ title }
;
        }

        let primaryButton;
        if (primaryActionHandler) {
            primaryButton = (
                <AccessibleButton kind="primary" onClick={primaryActionHandler}>
                    { primaryActionLabel }
                </AccessibleButton>
            );
        }

        let secondaryButton;
        if (secondaryActionHandler) {
            secondaryButton = (
                <AccessibleButton kind="secondary" onClick={secondaryActionHandler}>
                    { secondaryActionLabel }
                </AccessibleButton>
            );
        }

        const classes = classNames("mx_RoomPreviewBar", "dark-panel", {
            "mx_RoomPreviewBar_panel": this.props.canPreview,
            "mx_RoomPreviewBar_dialog": !this.props.canPreview,
            "mx_RoomPreviewBar_dark": darkStyle,
        });

        return (

                    { titleElement }
                    { subTitleElements }

                    { secondaryButton }
                    { primaryButton }

        );
    },
});
<commit_msg>saner order for message case detection (can't be joining when kicked)<commit_after>/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd

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.
*/

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
import dis from '../../../dispatcher';
import classNames from 'classnames';
import { _t } from '../../../languageHandler';

const MessageCase = Object.freeze({
    NotLoggedIn: "NotLoggedIn",
    Joining: "Joining",
    Loading: "Loading",
    Rejecting: "Rejecting",
    Kicked: "Kicked",
    Banned: "Banned",
    OtherThreePIDError: "OtherThreePIDError",
    InvitedEmailMismatch: "InvitedEmailMismatch",
    Invite: "Invite",
    ViewingRoom: "ViewingRoom",
    RoomNotFound: "RoomNotFound",
    OtherError: "OtherError",
});

module.exports = React.createClass({
    displayName: 'RoomPreviewBar',

    propTypes: {
        onJoinClick: PropTypes.func,
        onRejectClick: PropTypes.func,
        onForgetClick: PropTypes.func,
        onSignInClick: PropTypes.func,
        onSignUpClick: PropTypes.func,

        // if inviterName is specified, the preview bar will shown an invite to the room.
        // You should also specify onRejectClick if specifiying inviterName
        inviterName: PropTypes.string,

        // If invited by 3rd party invite, the email address the invite was sent to
        invitedEmail: PropTypes.string,

        // A standard client/server API error object. If supplied, indicates that the
        // caller was unable to fetch details about the room for the given reason.
        error: PropTypes.object,

        canPreview: PropTypes.bool,
        room: PropTypes.object,

        // When a spinner is present, a spinnerState can be specified to indicate the
        // purpose of the spinner.
        spinner: PropTypes.bool,
        spinnerState: PropTypes.oneOf(["joining"]),

        // The alias that was used to access this room, if appropriate
        // If given, this will be how the room is referred to (eg.
        // in error messages).
        roomAlias: PropTypes.string,
    },

    getDefaultProps: function() {
        return {
            onJoinClick: function() {},
        };
    },

    getInitialState: function() {
        return {
            busy: false,
        };
    },

    componentWillMount: function() {
        // If this is an invite and we've been told what email
        // address was invited, fetch the user's list of Threepids
        // so we can check them against the one that was invited
        if (this.props.inviterName && this.props.invitedEmail) {
            this.setState({busy: true});
            MatrixClientPeg.get().lookupThreePid(
                'email', this.props.invitedEmail,
            ).finally(() => {
                this.setState({busy: false});
            }).done((result) => {
                this.setState({invitedEmailMxid: result.mxid});
            }, (err) => {
                this.setState({threePidFetchError: err});
            });
        }
    },

    _getMessageCase() {
        const isGuest = MatrixClientPeg.get().isGuest();

        if (isGuest) {
            return MessageCase.NotLoggedIn;
        }

        const myMember = this.props.room &&
            this.props.room.getMember(MatrixClientPeg.get().getUserId());

        if (myMember) {
            if (myMember.isKicked()) {
                return MessageCase.Kicked;
            } else if (myMember.membership === "ban") {
                return MessageCase.Banned;
            }
        }

        if (this.props.joining) {
            return MessageCase.Joining;
        } else if (this.props.rejecting) {
            return MessageCase.Rejecting;
        } else if (this.props.loading) {
            return MessageCase.Loading;
        }

        if (this.props.inviterName) {
            if (this.props.invitedEmail) {
                if (this.state.threePidFetchError) {
                    return MessageCase.OtherThreePIDError;
                } else if (this.state.invitedEmailMxid != MatrixClientPeg.get().credentials.userId) {
                    return MessageCase.InvitedEmailMismatch;
                }
            }
            return MessageCase.Invite;
        } else if (this.props.error) {
            if (this.props.error.errcode == 'M_NOT_FOUND') {
                return MessageCase.RoomNotFound;
            } else {
                return MessageCase.OtherError;
            }
        } else {
            return MessageCase.ViewingRoom;
        }
    },

    _getKickOrBanInfo() {
        const myMember = this.props.room ?
            this.props.room.getMember(MatrixClientPeg.get().getUserId()) :
            null;
        if (!myMember) {
            return {};
        }
        const kickerMember = this.props.room.currentState.getMember(
            myMember.events.member.getSender(),
        );
        const memberName = kickerMember ?
            kickerMember.name : myMember.events.member.getSender();
        const reason = myMember.events.member.getContent().reason;
        return {memberName, reason};
    },

    _joinRule: function() {
        const room = this.props.room;
        if (room) {
            const joinRules = room.currentState.getStateEvents('m.room.join_rules', '');
            if (joinRules) {
                return joinRules.getContent().join_rule;
            }
        }
    },

    _roomName: function() {
        return this.props.room ? this.props.room.name : (this.props.room_alias || _t("This room"));
    },

    onLoginClick: function() {
        dis.dispatch({ action: 'start_login' });
    },

    onRegisterClick: function() {
        dis.dispatch({ action: 'start_registration' });
    },

    render: function() {
        let showSpinner = false;
        let darkStyle = false;
        let title;
        let subTitle;
        let primaryActionHandler;
        let primaryActionLabel;
        let secondaryActionHandler;
        let secondaryActionLabel;

        switch (this._getMessageCase()) {
            case MessageCase.Joining: {
                title = _t("Joining room …");
                showSpinner = true;
                break;
            }
            case MessageCase.Loading: {
                title = _t("Loading …");
                showSpinner = true;
                break;
            }
            case MessageCase.Rejecting: {
                title = _t("Rejecting invite …");
                showSpinner = true;
                break;
            }
            case MessageCase.NotLoggedIn: {
                darkStyle = true;
                title = _t("Join the conversation with an account");
                primaryActionLabel = _t("Sign Up");
                primaryActionHandler = this.onRegisterClick;
                secondaryActionLabel = _t("Sign In");
                secondaryActionHandler = this.onLoginClick;
                break;
            }
            case MessageCase.Kicked: {
                const {memberName, reason} = this._getKickOrBanInfo();
                title = _t("You were kicked from this room by %(memberName)s", {memberName});
                subTitle = _t("Reason: %(reason)s", {reason});
                primaryActionLabel = _t("Re-join");
                primaryActionHandler = this.props.onJoinClick;
                secondaryActionLabel = _t("Forget this room");
                secondaryActionHandler = this.props.onForgetClick;
                break;
            }
            case MessageCase.Banned: {
                const {memberName, reason} = this._getKickOrBanInfo();
                title = _t("You were banned from this room by %(memberName)s", {memberName});
                subTitle = _t("Reason: %(reason)s", {reason});
                primaryActionLabel = _t("Forget this room");
                primaryActionHandler = this.props.onForgetClick;
                break;
            }
            case MessageCase.OtherThreePIDError: {
                title = _t("Something went wrong with your invite to this room");
                const joinRule = this._joinRule();
                const errCodeMessage = _t("%(errcode)s was returned while trying to valide your invite. You could try to pass this information on to a room admin.",
                    {errcode: this.state.threePidFetchError.errcode},
                );
                switch (joinRule) {
                    case "invite":
                        subTitle = [
                            _t("You can only join it with a working invite."),
                            errCodeMessage,
                        ];
                        break;
                    case "public":
                        subTitle = _t("You can still join it because this is a public room.");
                        primaryActionLabel = _t("Join the discussion");
                        primaryActionHandler = this.props.onJoinClick;
                        break;
                    default:
                        subTitle = errCodeMessage;
                        primaryActionLabel = _t("Try to join anyway");
                        primaryActionHandler = this.props.onJoinClick;
                        break;
                }
                break;
            }
            case MessageCase.InvitedEmailMismatch: {
                title = _t("The room invite wasn't sent to your account");
                const joinRule = this._joinRule();
                if (joinRule === "public") {
                    subTitle = _t("You can still join it because this is a public room.");
                    primaryActionLabel = _t("Join the discussion");
                    primaryActionHandler = this.props.onJoinClick;
                } else {
                    subTitle = _t("Sign in with a different account, ask for another invite, or add the e-mail address %(email)s to this account.", {email: this.props.invitedEmail});
                    if (joinRule !== "invite") {
                        primaryActionLabel = _t("Try to join anyway");
                        primaryActionHandler = this.props.onJoinClick;
                    }
                }
                break;
            }
            case MessageCase.Invite: {
                if (this.props.canPreview) {
                    title = _t("%(memberName)s invited you to this room", {memberName: this.props.inviterName});
                } else {
                    title = _t("Do you want to join this room?");
                    subTitle = _t("%(memberName)s invited you", {memberName: this.props.inviterName});
                }
                primaryActionLabel = _t("Accept");
                primaryActionHandler = this.props.onJoinClick;
                secondaryActionLabel = _t("Reject");
                secondaryActionHandler = this.props.onRejectClick;
                break;
            }
            case MessageCase.ViewingRoom: {
                if (this.props.canPreview) {
                    title = _t("You're previewing this room. Want to join it?");
                } else {
                    title = _t("This room can't be previewed. Do you want to join it?");
                }
                primaryActionLabel = _t("Join the discussion");
                primaryActionHandler = this.props.onJoinClick;
                break;
            }
            case MessageCase.RoomNotFound: {
                title = _t("%(roomName)s does not exist.", {roomName: this._roomName()});
                subTitle = _t("This room doesn't exist. Are you sure you're at the right place?");
                break;
            }
            case MessageCase.OtherError: {
                title = _t("%(roomName)s is not accessible at this time.", {roomName: this._roomName()});
                subTitle = [
                    _t("Try again later, or ask a room admin to check if you have access."),
                    _t("%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please <issueLink>submit a bug report</issueLink>.",
                        { errcode: this.props.error.errcode },
                        { issueLink: label => { label } },
                    ),
                ];
                break;
            }
        }

        const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
        const Spinner = sdk.getComponent('elements.Spinner');

        let subTitleElements;
        if (subTitle) {
            if (!Array.isArray(subTitle)) {
                subTitle = [subTitle];
            }
            subTitleElements = subTitle.map((t, i) => <p key={`subTitle${i}`}>{t}
);
        }

        let titleElement;
        if (showSpinner) {
            titleElement =
<Spinner />{ title }
;
        } else {
            titleElement =
{ title }
;
        }

        let primaryButton;
        if (primaryActionHandler) {
            primaryButton = (
                <AccessibleButton kind="primary" onClick={primaryActionHandler}>
                    { primaryActionLabel }
                </AccessibleButton>
            );
        }

        let secondaryButton;
        if (secondaryActionHandler) {
            secondaryButton = (
                <AccessibleButton kind="secondary" onClick={secondaryActionHandler}>
                    { secondaryActionLabel }
                </AccessibleButton>
            );
        }

        const classes = classNames("mx_RoomPreviewBar", "dark-panel", {
            "mx_RoomPreviewBar_panel": this.props.canPreview,
            "mx_RoomPreviewBar_dialog": !this.props.canPreview,
            "mx_RoomPreviewBar_dark": darkStyle,
        });

        return (

                    { titleElement }
                    { subTitleElements }

                    { secondaryButton }
                    { primaryButton }

        );
    },
});
<|endoftext|>


<commit_before>/*
Copyright 2019 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import request from 'browser-request';
import url from 'url';
import React from 'react';
import {_t} from "../../../languageHandler";
import sdk from '../../../index';
import MatrixClientPeg from "../../../MatrixClientPeg";
import SdkConfig from "../../../SdkConfig";
import Field from "../elements/Field";

/**
 * If a url has no path component, etc. abbreviate it to just the hostname
 *
 * @param {string} u The url to be abbreviated
 * @returns {string} The abbreviated url
 */
function abbreviateUrl(u) {
    if (!u) return '';

    const parsedUrl = url.parse(u);
    // if it's something we can't parse as a url then just return it
    if (!parsedUrl) return u;

    if (parsedUrl.path == '/') {
        // we ignore query / hash parts: these aren't relevant for IS server URLs
        return parsedUrl.host;
    }

    return u;
}

function unabbreviateUrl(u) {
    if (!u) return '';

    let longUrl = u;
    if (!u.startsWith('https://')) longUrl = 'https://' + u;
    const parsed = url.parse(longUrl);
    if (parsed.hostname === null) return u;

    return longUrl;
}

/**
 * Check an IS URL is valid, including liveness check
 *
 * @param {string} isUrl The url to check
 * @returns {string} null if url passes all checks, otherwise i18ned error string
 */
async function checkIsUrl(isUrl) {
    const parsedUrl = url.parse(isUrl);

    if (parsedUrl.protocol !== 'https:') return _t("Identity Server URL must be HTTPS");

    // XXX: duplicated logic from js-sdk but it's quite tied up in the validation logic in the
    // js-sdk so probably as easy to duplicate it than to separate it out so we can reuse it
    return new Promise((resolve) => {
        request(
            // also XXX: we don't really know whether to hit /v1 or /v2 for this: we
            // probably want a /versions endpoint like the C/S API.
            { method: "GET", url: isUrl + '/_matrix/identity/api/v1' },
            (err, response, body) => {
                if (err) {
                    resolve(_t("Could not connect to ID Server"));
                } else if (response.status < 200 || response.status >= 300) {
                    resolve(_t("Not a valid ID Server (status code %(code)s)", {code: response.status}));
                } else {
                    resolve(null);
                }
            },
        );
    });
}

export default class SetIdServer extends React.Component {
    constructor() {
        super();

        let defaultIdServer = abbreviateUrl(MatrixClientPeg.get().getIdentityServerUrl());
        if (!defaultIdServer) {
            defaultIdServer = abbreviateUrl(SdkConfig.get()['validated_server_config']['idServer']) || '';
        }

        this.state = {
            currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(),
            idServer: defaultIdServer,
            error: null,
            busy: false,
        };
    }

    _onIdentityServerChanged = (ev) => {
        const u = ev.target.value;

        this.setState({idServer: u});
    };

    _getTooltip = () => {
        if (this.state.busy) {
            const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
            return

                <InlineSpinner />
                { _t("Checking Server") }

;
        } else if (this.state.error) {
            return this.state.error;
        } else {
            return null;
        }
    };

    _idServerChangeEnabled = () => {
        return !!this.state.idServer && !this.state.busy;
    };

    _saveIdServer = async () => {
        this.setState({busy: true});

        const fullUrl = unabbreviateUrl(this.state.idServer);

        const errStr = await checkIsUrl(fullUrl);

        let newFormValue = this.state.idServer;
        if (!errStr) {
            MatrixClientPeg.get().setIdentityServerUrl(fullUrl);
            localStorage.removeItem("mx_is_access_token");
            localStorage.setItem("mx_is_url", fullUrl);
            newFormValue = '';
        }
        this.setState({
            busy: false,
            error: errStr,
            currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(),
            idServer: newFormValue,
        });
    };

    render() {
        const idServerUrl = this.state.currentClientIdServer;
        let sectionTitle;
        let bodyText;
        if (idServerUrl) {
            sectionTitle = _t("Identity Server (%(server)s)", { server: abbreviateUrl(idServerUrl) });
            bodyText = _t(
                "You are currently using <server></server> to discover and be discoverable by " +
                "existing contacts you know. You can change your identity server below.",
                {},
                { server: sub => {abbreviateUrl(idServerUrl)} },
            );
        } else {
            sectionTitle = _t("Identity Server");
            bodyText = _t(
                "You are not currently using an Identity Server. " +
                "To discover and be discoverable by existing contacts you know, " +
                "add one below",
            );
        }

        return (
            <form className="mx_SettingsTab_section mx_SetIdServer" onSubmit={this._saveIdServer}>

                    {sectionTitle}

                    {bodyText}

                <Field label={_t("Identity Server")}
                    id="mx_SetIdServer_idServer"
                    type="text" value={this.state.idServer} autoComplete="off"
                    onChange={this._onIdentityServerChanged}
                    tooltip={this._getTooltip()}
                />
                <input className="mx_Dialog_primary"
                    type="submit" value={_t("Change")}
                    disabled={!this._idServerChangeEnabled()}
                />
            </form>
        );
    }
}
<commit_msg>write Identity Server out in full to be less confusing<commit_after>/*
Copyright 2019 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import request from 'browser-request';
import url from 'url';
import React from 'react';
import {_t} from "../../../languageHandler";
import sdk from '../../../index';
import MatrixClientPeg from "../../../MatrixClientPeg";
import SdkConfig from "../../../SdkConfig";
import Field from "../elements/Field";

/**
 * If a url has no path component, etc. abbreviate it to just the hostname
 *
 * @param {string} u The url to be abbreviated
 * @returns {string} The abbreviated url
 */
function abbreviateUrl(u) {
    if (!u) return '';

    const parsedUrl = url.parse(u);
    // if it's something we can't parse as a url then just return it
    if (!parsedUrl) return u;

    if (parsedUrl.path == '/') {
        // we ignore query / hash parts: these aren't relevant for IS server URLs
        return parsedUrl.host;
    }

    return u;
}

function unabbreviateUrl(u) {
    if (!u) return '';

    let longUrl = u;
    if (!u.startsWith('https://')) longUrl = 'https://' + u;
    const parsed = url.parse(longUrl);
    if (parsed.hostname === null) return u;

    return longUrl;
}

/**
 * Check an IS URL is valid, including liveness check
 *
 * @param {string} isUrl The url to check
 * @returns {string} null if url passes all checks, otherwise i18ned error string
 */
async function checkIdentityServerUrl(url) {
    const parsedUrl = url.parse(isUrl);

    if (parsedUrl.protocol !== 'https:') return _t("Identity Server URL must be HTTPS");

    // XXX: duplicated logic from js-sdk but it's quite tied up in the validation logic in the
    // js-sdk so probably as easy to duplicate it than to separate it out so we can reuse it
    return new Promise((resolve) => {
        request(
            // also XXX: we don't really know whether to hit /v1 or /v2 for this: we
            // probably want a /versions endpoint like the C/S API.
            { method: "GET", url: isUrl + '/_matrix/identity/api/v1' },
            (err, response, body) => {
                if (err) {
                    resolve(_t("Could not connect to Identity Server"));
                } else if (response.status < 200 || response.status >= 300) {
                    resolve(_t("Not a valid Identity Server (status code %(code)s)", {code: response.status}));
                } else {
                    resolve(null);
                }
            },
        );
    });
}

export default class SetIdServer extends React.Component {
    constructor() {
        super();

        let defaultIdServer = abbreviateUrl(MatrixClientPeg.get().getIdentityServerUrl());
        if (!defaultIdServer) {
            defaultIdServer = abbreviateUrl(SdkConfig.get()['validated_server_config']['idServer']) || '';
        }

        this.state = {
            currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(),
            idServer: defaultIdServer,
            error: null,
            busy: false,
        };
    }

    _onIdentityServerChanged = (ev) => {
        const u = ev.target.value;

        this.setState({idServer: u});
    };

    _getTooltip = () => {
        if (this.state.busy) {
            const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
            return

                <InlineSpinner />
                { _t("Checking Server") }

;
        } else if (this.state.error) {
            return this.state.error;
        } else {
            return null;
        }
    };

    _idServerChangeEnabled = () => {
        return !!this.state.idServer && !this.state.busy;
    };

    _saveIdServer = async () => {
        this.setState({busy: true});

        const fullUrl = unabbreviateUrl(this.state.idServer);

        const errStr = await checkIsUrl(fullUrl);

        let newFormValue = this.state.idServer;
        if (!errStr) {
            MatrixClientPeg.get().setIdentityServerUrl(fullUrl);
            localStorage.removeItem("mx_is_access_token");
            localStorage.setItem("mx_is_url", fullUrl);
            newFormValue = '';
        }
        this.setState({
            busy: false,
            error: errStr,
            currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(),
            idServer: newFormValue,
        });
    };

    render() {
        const idServerUrl = this.state.currentClientIdServer;
        let sectionTitle;
        let bodyText;
        if (idServerUrl) {
            sectionTitle = _t("Identity Server (%(server)s)", { server: abbreviateUrl(idServerUrl) });
            bodyText = _t(
                "You are currently using <server></server> to discover and be discoverable by " +
                "existing contacts you know. You can change your identity server below.",
                {},
                { server: sub => {abbreviateUrl(idServerUrl)} },
            );
        } else {
            sectionTitle = _t("Identity Server");
            bodyText = _t(
                "You are not currently using an Identity Server. " +
                "To discover and be discoverable by existing contacts you know, " +
                "add one below",
            );
        }

        return (
            <form className="mx_SettingsTab_section mx_SetIdServer" onSubmit={this._saveIdServer}>

                    {sectionTitle}

                    {bodyText}

                <Field label={_t("Identity Server")}
                    id="mx_SetIdServer_idServer"
                    type="text" value={this.state.idServer} autoComplete="off"
                    onChange={this._onIdentityServerChanged}
                    tooltip={this._getTooltip()}
                />
                <input className="mx_Dialog_primary"
                    type="submit" value={_t("Change")}
                    disabled={!this._idServerChangeEnabled()}
                />
            </form>
        );
    }
}
<|endoftext|>


<commit_before>// @flow
import path from 'path';

type FilterKatasDirType = {
  findFilenames: () => Promise<FilenameListType>;
  rootDir: DirnameType;
};
type FilterKatasDirReturnType = {
  forMetadataFiles: () => Promise<FilenameListType>;
  forKataFiles: () => Promise<FilenameListType>;
};

export const FilterKatasDir = (
  {findFilenames, rootDir}: FilterKatasDirType
): FilterKatasDirReturnType => {
  const isMetadataFile = (file) =>
    file.endsWith('__raw-metadata__.js') &&
    file !== './__raw-metadata__.js' &&
    file !== '__raw-metadata__.js'
  ;
  const isKataFile = (file) => {
    const parsed = path.parse(file);
    const isRootDir = parsed.dir === rootDir;
    return file.endsWith('.js') && !isRootDir && !isMetadataFile(file);
  };
  const findMetadataFiles = (files) =>
    files.filter(isMetadataFile);
  const findKataFiles = (files) =>
    files.filter(isKataFile);
  return {
    forMetadataFiles: () => findFilenames()
      .then((files) => findMetadataFiles(files)),
    forKataFiles: () => findFilenames()
      .then((files) => findKataFiles(files)),
  };
};
<commit_msg>Remove some verbosity.<commit_after>// @flow
import path from 'path';

type FilterKatasDirType = {
  findFilenames: () => Promise<FilenameListType>;
  rootDir: DirnameType;
};
type FilterKatasDirReturnType = {
  forMetadataFiles: () => Promise<FilenameListType>;
  forKataFiles: () => Promise<FilenameListType>;
};

export const FilterKatasDir = (
  {findFilenames, rootDir}: FilterKatasDirType
): FilterKatasDirReturnType => {
  const isMetadataFile = (file) =>
    file.endsWith('__raw-metadata__.js') &&
    file !== './__raw-metadata__.js' &&
    file !== '__raw-metadata__.js'
  ;
  const isKataFile = (file) => {
    const parsed = path.parse(file);
    const isRootDir = parsed.dir === rootDir;
    return file.endsWith('.js') && !isRootDir && !isMetadataFile(file);
  };
  const findMetadataFiles = (files) => files.filter(isMetadataFile);
  const findKataFiles = (files) => files.filter(isKataFile);
  return {
    forMetadataFiles: () => findFilenames().then(findMetadataFiles),
    forKataFiles: () => findFilenames().then(findKataFiles),
  };
};
<|endoftext|>


<commit_before>import angular from 'angular';
import _ from 'lodash';
import * as utils from './utils';

// Use factory() instead service() for multiple datasources support.
// Each datasource instance must initialize its own cache.

/** @ngInject */
angular.module('grafana.services').factory('ZabbixCachingProxy', function($q, $interval) {

  class ZabbixCachingProxy {
    constructor(zabbixAPI, ttl) {
      this.zabbixAPI = zabbixAPI;
      this.ttl = ttl;

      this.$q = $q;

      // Internal objects for data storing
      this._groups        = undefined;
      this._hosts         = undefined;
      this._applications  = undefined;
      this._items         = undefined;
      this.storage = {
        history: {},
        trends: {}
      };

      // Check is a service initialized or not
      this._initialized = undefined;

      this.refreshPromise = false;
      this.historyPromises = {};

      // Wrap _refresh() method to call it once.
      this.refresh = callOnce(this._refresh, this.refreshPromise);

      // Update cache periodically
      $interval(_.bind(this.refresh, this), this.ttl);

      // Don't run duplicated history requests
      this.getHistory = callHistoryOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI),
                                        this.historyPromises);

      this.groupPromises = {};
      this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI),
                                              this.groupPromises);

      this.hostPromises = {};
      this.getHostsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getHosts, this.zabbixAPI),
                                             this.hostPromises);

      this.appPromises = {};
      this.getAppsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getApps, this.zabbixAPI),
                                            this.appPromises);

      this.itemPromises = {};
      this.getItemsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getItems, this.zabbixAPI),
                                             this.itemPromises);
    }

    _refresh() {
      var self = this;
      var promises = [
        this.zabbixAPI.getGroups()
      ];

      return this.$q.all(promises).then(function(results) {
        if (results.length) {
          self._groups = results[0];
        }
        self._initialized = true;
      });
    }

    getGroups() {
      var self = this;
      if (this._groups) {
        return this.$q.when(self._groups);
      } else {
        return this.getGroupsOnce()
          .then(groups => {
            self._groups = groups;
            return self._groups;
          });
      }
    }

    getHosts(groupids) {
      var self = this;
      return this.getHostsOnce(groupids)
        .then(hosts => {
          self._hosts = _.union(self._hosts, hosts);
          return hosts;
        });
    }

    getApps(hostids) {
      return this.getAppsOnce(hostids)
        .then(apps => {
          return apps;
        });
    }

    getItems(hostids, appids) {
      var self = this;
      return this.getItemsOnce(hostids, appids)
        .then(items => {
          self._items = _.union(self._items, items);
          return items;
        });
    }

    _getHosts() {
      var self = this;
      if (this._hosts) {
        return this.$q.when(self._hosts);
      } else {
        return this.refresh().then(function() {
          return self._hosts;
        });
      }
    }

    getIndexedHosts() {
      var self = this;
      if (this._idx_hosts) {
        return this.$q.when(self._idx_hosts);
      } else {
        return this.refresh().then(function() {
          return self._idx_hosts;
        });
      }
    }

    getIndexedApplications() {
      var self = this;
      if (this._idx_apps) {
        return this.$q.when(self._idx_apps);
      } else {
        return this.refresh().then(function() {
          return self._idx_apps;
        });
      }
    }

    getApplications() {
      var self = this;
      if (this._applications) {
        return this.$q.when(self._applications);
      } else {
        return this.refresh().then(function() {
          return self._applications;
        });
      }
    }

    _getItems(type) {
      var self = this;
      if (this._items) {
        return this.$q.when(filterItems(self._items, type));
      } else {
        return this.refresh().then(function() {
          return filterItems(self._items, type);
        });
      }
    }

    getHistoryFromCache(items, time_from, time_till) {
      var deferred  = this.$q.defer();
      var historyStorage = this.storage.history;
      var full_history;
      var expired = _.filter(_.indexBy(items, 'itemid'), function(item, itemid) {
        return !historyStorage[itemid];
      });
      if (expired.length) {
        this.zabbixAPI.getHistory(expired, time_from, time_till).then(function(history) {
          var grouped_history = _.groupBy(history, 'itemid');
          _.forEach(expired, function(item) {
            var itemid = item.itemid;
            historyStorage[itemid] = item;
            historyStorage[itemid].time_from = time_from;
            historyStorage[itemid].time_till = time_till;
            historyStorage[itemid].history = grouped_history[itemid];
          });
          full_history = _.map(items, function(item) {
            return historyStorage[item.itemid].history;
          });
          deferred.resolve(_.flatten(full_history, true));
        });
      } else {
        full_history = _.map(items, function(item) {
          return historyStorage[item.itemid].history;
        });
        deferred.resolve(_.flatten(full_history, true));
      }
      return deferred.promise;
    }

    getHistoryFromAPI(items, time_from, time_till) {
      return this.zabbixAPI.getHistory(items, time_from, time_till);
    }

    getHost(hostid) {
      return _.find(this._hosts, {'hostid': hostid});
    }

    getItem(itemid) {
      return _.find(this._items, {'itemid': itemid});
    }
  }

  function callAPIRequestOnce(func, promiseKeeper) {
    return function() {
      var itemids = _.map(arguments[0], 'itemid');
      var stamp = itemids.join() + arguments[1] + arguments[2];
      var hash = stamp.getHash();

      var deferred  = $q.defer();
      if (!promiseKeeper[hash]) {
        promiseKeeper[hash] = deferred.promise;
        func.apply(this, arguments).then(function(result) {
          deferred.resolve(result);
          promiseKeeper[hash] = null;
        });
      } else {
        return promiseKeeper[hash];
      }
      return deferred.promise;
    };
  }

  function callHistoryOnce(func, promiseKeeper) {
    return function() {
      var itemids = _.map(arguments[0], 'itemid');
      var stamp = itemids.join() + arguments[1] + arguments[2];
      var hash = stamp.getHash();

      var deferred  = $q.defer();
      if (!promiseKeeper[hash]) {
        promiseKeeper[hash] = deferred.promise;
        func.apply(this, arguments).then(function(result) {
          deferred.resolve(result);
          promiseKeeper[hash] = null;
        });
      } else {
        return promiseKeeper[hash];
      }
      return deferred.promise;
    };
  }

  function callOnce(func, promiseKeeper) {
    return function() {
      var deferred  = $q.defer();
      if (!promiseKeeper) {
        promiseKeeper = deferred.promise;
        func.apply(this, arguments).then(function(result) {
          deferred.resolve(result);
          promiseKeeper = null;
        });
      } else {
        return promiseKeeper;
      }
      return deferred.promise;
    };
  }

  return ZabbixCachingProxy;
});

/**
 * Convert host.get response to cache format
 * host.groups - array of group ids
 */
function convertHosts(hosts) {
  return _.forEach(hosts, function(host) {
    host.groups = _.map(host.groups, 'groupid');
    return host;
  });
}

function convertGroups(groups) {
  return _.forEach(groups, function(group) {
    group.hosts = _.map(group.hosts, 'hostid');
    return group;
  });
}

/**
 * Group Zabbix applications by name
 * host.hosts - array of host ids
 */
function convertApplications(applications) {
  return _.map(_.groupBy(applications, 'name'), function(value, key) {
    //console.log(value);
    // Hack for supporting different apis (2.2 vs 2.4 vs 3.0)
    var hostField = 'host';
    if (value[0] && value[0]['hosts']) {
      // For Zabbix 2.2
      hostField = 'hosts';
    }

    return {
      name: key,
      applicationids: _.map(value, 'applicationid'),
      itemids: _.uniq(_.map(_.flatten(value, 'items'), 'itemid')),
      hosts: _.uniq(_.map(_.flatten(value, hostField), 'hostid'))
    };
  });
}

function indexHosts(hosts) {
  return _.indexBy(_.map(hosts, function(host) {

    // Expand item names
    host.items = _.forEach(host.items, function(item) {
      item.item = item.name;
      item.name = utils.expandItemName(item.item, item.key_);
      return item;
    });

    host.applications = _.map(host.applications, 'applicationid');
    host.idx_items = indexItems(host.items);
    host.items = _.map(host.items, 'itemid');
    return host;
  }), 'hostid');
}

function indexApps(applications) {
  return _.indexBy(_.map(applications, function(app) {
    return {
      name: app.name,
      applicationid: app.applicationid,
      host: _.first(_.map(app.hosts, 'hostid')),
      itemids: _.map(app.items, 'itemid')
    };
  }), 'applicationid');
}

function indexItems(items) {
  return _.indexBy(_.map(items, function(item) {
    return item;
  }), 'itemid');
}

/**
 * Convert item.get response to cache format
 * item.applications - array of application ids
 * item.item - original item name returned by api (ie "CPU $2 time")
 * item.name - expanded name (ie "CPU system time")
 */
function convertItems(items) {
  return _.forEach(items, function(item) {
    item.applications = _.map(item.applications, 'applicationid');
    item.item = item.name;
    item.name = utils.expandItemName(item.item, item.key_);
    return item;
  });
}

function filterItems(items, type) {
  switch (type) {
    case 'num':
      return _.filter(items, function(item) {
        return (item.value_type === '0' ||
                item.value_type === '3');
      });
    case 'text':
      return _.filter(items, function(item) {
        return (item.value_type === '1' ||
                item.value_type === '2' ||
                item.value_type === '4');
      });
    default:
      return items;
  }
}

String.prototype.getHash = function() {
  var hash = 0, i, chr, len;
  if (this.length === 0) {
    return hash;
  }
  for (i = 0, len = this.length; i < len; i++) {
    chr   = this.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
};
<commit_msg>Removed unused functions from zabbixCache.service.js<commit_after>import angular from 'angular';
import _ from 'lodash';
import * as utils from './utils';

// Use factory() instead service() for multiple datasources support.
// Each datasource instance must initialize its own cache.

/** @ngInject */
angular.module('grafana.services').factory('ZabbixCachingProxy', function($q, $interval) {

  class ZabbixCachingProxy {
    constructor(zabbixAPI, ttl) {
      this.zabbixAPI = zabbixAPI;
      this.ttl = ttl;

      this.$q = $q;

      // Internal objects for data storing
      this._groups        = undefined;
      this._hosts         = undefined;
      this._applications  = undefined;
      this._items         = undefined;
      this.storage = {
        history: {},
        trends: {}
      };

      // Check is a service initialized or not
      this._initialized = undefined;

      this.refreshPromise = false;
      this.historyPromises = {};

      // Wrap _refresh() method to call it once.
      this.refresh = callOnce(this._refresh, this.refreshPromise);

      // Update cache periodically
      $interval(_.bind(this.refresh, this), this.ttl);

      // Don't run duplicated history requests
      this.getHistory = callHistoryOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI),
                                        this.historyPromises);

      this.groupPromises = {};
      this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI),
                                              this.groupPromises);

      this.hostPromises = {};
      this.getHostsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getHosts, this.zabbixAPI),
                                             this.hostPromises);

      this.appPromises = {};
      this.getAppsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getApps, this.zabbixAPI),
                                            this.appPromises);

      this.itemPromises = {};
      this.getItemsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getItems, this.zabbixAPI),
                                             this.itemPromises);
    }

    _refresh() {
      var self = this;
      var promises = [
        this.zabbixAPI.getGroups()
      ];

      return this.$q.all(promises).then(function(results) {
        if (results.length) {
          self._groups = results[0];
        }
        self._initialized = true;
      });
    }

    getGroups() {
      var self = this;
      if (this._groups) {
        return this.$q.when(self._groups);
      } else {
        return this.getGroupsOnce()
          .then(groups => {
            self._groups = groups;
            return self._groups;
          });
      }
    }

    getHosts(groupids) {
      var self = this;
      return this.getHostsOnce(groupids)
        .then(hosts => {
          self._hosts = _.union(self._hosts, hosts);
          return hosts;
        });
    }

    getApps(hostids) {
      return this.getAppsOnce(hostids)
        .then(apps => {
          return apps;
        });
    }

    getItems(hostids, appids) {
      var self = this;
      return this.getItemsOnce(hostids, appids)
        .then(items => {
          self._items = _.union(self._items, items);
          return items;
        });
    }

    getHistoryFromCache(items, time_from, time_till) {
      var deferred  = this.$q.defer();
      var historyStorage = this.storage.history;
      var full_history;
      var expired = _.filter(_.indexBy(items, 'itemid'), function(item, itemid) {
        return !historyStorage[itemid];
      });
      if (expired.length) {
        this.zabbixAPI.getHistory(expired, time_from, time_till).then(function(history) {
          var grouped_history = _.groupBy(history, 'itemid');
          _.forEach(expired, function(item) {
            var itemid = item.itemid;
            historyStorage[itemid] = item;
            historyStorage[itemid].time_from = time_from;
            historyStorage[itemid].time_till = time_till;
            historyStorage[itemid].history = grouped_history[itemid];
          });
          full_history = _.map(items, function(item) {
            return historyStorage[item.itemid].history;
          });
          deferred.resolve(_.flatten(full_history, true));
        });
      } else {
        full_history = _.map(items, function(item) {
          return historyStorage[item.itemid].history;
        });
        deferred.resolve(_.flatten(full_history, true));
      }
      return deferred.promise;
    }

    getHistoryFromAPI(items, time_from, time_till) {
      return this.zabbixAPI.getHistory(items, time_from, time_till);
    }

    getHost(hostid) {
      return _.find(this._hosts, {'hostid': hostid});
    }

    getItem(itemid) {
      return _.find(this._items, {'itemid': itemid});
    }
  }

  function callAPIRequestOnce(func, promiseKeeper) {
    return function() {
      var itemids = _.map(arguments[0], 'itemid');
      var stamp = itemids.join() + arguments[1] + arguments[2];
      var hash = stamp.getHash();

      var deferred  = $q.defer();
      if (!promiseKeeper[hash]) {
        promiseKeeper[hash] = deferred.promise;
        func.apply(this, arguments).then(function(result) {
          deferred.resolve(result);
          promiseKeeper[hash] = null;
        });
      } else {
        return promiseKeeper[hash];
      }
      return deferred.promise;
    };
  }

  function callHistoryOnce(func, promiseKeeper) {
    return function() {
      var itemids = _.map(arguments[0], 'itemid');
      var stamp = itemids.join() + arguments[1] + arguments[2];
      var hash = stamp.getHash();

      var deferred  = $q.defer();
      if (!promiseKeeper[hash]) {
        promiseKeeper[hash] = deferred.promise;
        func.apply(this, arguments).then(function(result) {
          deferred.resolve(result);
          promiseKeeper[hash] = null;
        });
      } else {
        return promiseKeeper[hash];
      }
      return deferred.promise;
    };
  }

  function callOnce(func, promiseKeeper) {
    return function() {
      var deferred  = $q.defer();
      if (!promiseKeeper) {
        promiseKeeper = deferred.promise;
        func.apply(this, arguments).then(function(result) {
          deferred.resolve(result);
          promiseKeeper = null;
        });
      } else {
        return promiseKeeper;
      }
      return deferred.promise;
    };
  }

  return ZabbixCachingProxy;
});

String.prototype.getHash = function() {
  var hash = 0, i, chr, len;
  if (this.length === 0) {
    return hash;
  }
  for (i = 0, len = this.length; i < len; i++) {
    chr   = this.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
};
<|endoftext|>


<commit_before>/**
 *
 *  Base64 encode / decode
 *  http://www.webtoolkit.info
 *  http://www.webtoolkit.info/license
 *
 **/

var Base64 = {

  // private property
  _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

  // public method for encoding
  encode : function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    input = Base64._utf8_encode(input);

    while (i < input.length) {

      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }

      output = output +
      this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
      this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

    }

    return output;
  },

  // public method for decoding
  decode : function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;

    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

    while (i < input.length) {

      enc1 = this._keyStr.indexOf(input.charAt(i++));
      enc2 = this._keyStr.indexOf(input.charAt(i++));
      enc3 = this._keyStr.indexOf(input.charAt(i++));
      enc4 = this._keyStr.indexOf(input.charAt(i++));

      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
        output = output + String.fromCharCode(chr3);
      }

    }

    output = Base64._utf8_decode(output);

    return output;

  },

  // private method for UTF-8 encoding
  _utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    for (var n = 0; n < string.length; n++) {

      var c = string.charCodeAt(n);

      if (c < 128) {
        utftext += String.fromCharCode(c);
      }
      else if((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      }
      else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }

    }

    return utftext;
  },

  // private method for UTF-8 decoding
  _utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

      c = utftext.charCodeAt(i);

      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      }
      else if((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i+1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      }
      else {
        c2 = utftext.charCodeAt(i+1);
        c3 = utftext.charCodeAt(i+2);
        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
      }

    }

    return string;
  }

}
<commit_msg>Add a missing semicolon at the end of base64.js<commit_after>/**
 *
 *  Base64 encode / decode
 *  http://www.webtoolkit.info
 *  http://www.webtoolkit.info/license
 *
 **/

var Base64 = {

  // private property
  _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

  // public method for encoding
  encode : function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    input = Base64._utf8_encode(input);

    while (i < input.length) {

      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }

      output = output +
      this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
      this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

    }

    return output;
  },

  // public method for decoding
  decode : function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;

    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

    while (i < input.length) {

      enc1 = this._keyStr.indexOf(input.charAt(i++));
      enc2 = this._keyStr.indexOf(input.charAt(i++));
      enc3 = this._keyStr.indexOf(input.charAt(i++));
      enc4 = this._keyStr.indexOf(input.charAt(i++));

      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
        output = output + String.fromCharCode(chr3);
      }

    }

    output = Base64._utf8_decode(output);

    return output;

  },

  // private method for UTF-8 encoding
  _utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    for (var n = 0; n < string.length; n++) {

      var c = string.charCodeAt(n);

      if (c < 128) {
        utftext += String.fromCharCode(c);
      }
      else if((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      }
      else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }

    }

    return utftext;
  },

  // private method for UTF-8 decoding
  _utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

      c = utftext.charCodeAt(i);

      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      }
      else if((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i+1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      }
      else {
        c2 = utftext.charCodeAt(i+1);
        c3 = utftext.charCodeAt(i+2);
        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
      }

    }

    return string;
  }

};
<|endoftext|>