<commit_before>/*
  Overview: Provided a grant name, will access the respective json file represnting that grant
    and retrieve the necessary info. There are helper variables in this class to assist in
    parsing the json file.

  The current structure of the JSON is to be as follows:
  {
    "Grants": [
      {
        "Grant_Name" : "NSF Career",
        "Grant_Columns" : [
          {
            "Column_Name" : "To Do",
            "Cards": [
              {
                "Card_Name": "Cover Sheet",
                "Modal_ID" : "Cover_Sheet",
                "Modal_Body": "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
                "Document_Link": "http://www.github.com"
              }
            ]
          },

          {
            "Column_Name" : "In Progress",
            "Cards": [
              {
                "Card_Name": "References Cited",
                "Modal_ID" : "References_Cited",
                "Modal_Body": "",
                "Document_Link": "http://www.github.com",
                "Assigned_People" : ["Waffles", "Waffles"]
              }
            ]
          },

          {
            "Column_Name" : "Complete",
            "Cards": [
              {
                "Card_Name": "Departmental Letter",
                "Modal_ID" : "Departmental_Letter",
                "Modal_Body": "",
                "Document_Link": "http://www.github.com",
                "Tag_List" : ["Under Review", "Complete"]
              }
            ]
          }
        ]
      }
    ]
  }

  NOTE:
    * Tag_List and Assigned_People are optional
    * Rest of the fields are required

  Current Status:
    * Dynamic column generation
    * Dynamic card generation
    * Displays body contents on In Progress or Complete column (People, Links, Tags)
    * Supported Tags for Complete column are, Under Review and Complete
    * Sick documentation @see above
  TODO:
    * Support Comments
    * Support additional tags

  @author: Morgan Nesbitt
*/

var cardTemplate;
var modalTemplate;
var grantName = "NSF Career";
var jsonInfo;

$.getJSON( "json/cards.json", {}, function( data ) {
  jsonInfo = data.Grants[0];
});

$.ajax({
    url: 'templates/full_card.html',
    dataType: 'html',
    method: 'GET',
    async: false,
    success: function(data) {
        cardTemplate = Handlebars.compile(data);
        $('#columnList').html(cardTemplate(jsonInfo));
    }
});

$.ajax({
    url: 'templates/card_modal.html',
    dataType: 'html',
    method: 'GET',
    async: false,
    success: function(data) {
        modalTemplate = Handlebars.compile(data);
        $('#cardModals').html(modalTemplate(jsonInfo));
    }
});
<commit_msg>Temporary GitHub Pages ONLY fix<commit_after>/*
  Overview: Provided a grant name, will access the respective json file represnting that grant
    and retrieve the necessary info. There are helper variables in this class to assist in
    parsing the json file.

  The current structure of the JSON is to be as follows:
  {
    "Grants": [
      {
        "Grant_Name" : "NSF Career",
        "Grant_Columns" : [
          {
            "Column_Name" : "To Do",
            "Cards": [
              {
                "Card_Name": "Cover Sheet",
                "Modal_ID" : "Cover_Sheet",
                "Modal_Body": "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
                "Document_Link": "http://www.github.com"
              }
            ]
          },

          {
            "Column_Name" : "In Progress",
            "Cards": [
              {
                "Card_Name": "References Cited",
                "Modal_ID" : "References_Cited",
                "Modal_Body": "",
                "Document_Link": "http://www.github.com",
                "Assigned_People" : ["Waffles", "Waffles"]
              }
            ]
          },

          {
            "Column_Name" : "Complete",
            "Cards": [
              {
                "Card_Name": "Departmental Letter",
                "Modal_ID" : "Departmental_Letter",
                "Modal_Body": "",
                "Document_Link": "http://www.github.com",
                "Tag_List" : ["Under Review", "Complete"]
              }
            ]
          }
        ]
      }
    ]
  }

  NOTE:
    * Tag_List and Assigned_People are optional
    * Rest of the fields are required

  Current Status:
    * Dynamic column generation
    * Dynamic card generation
    * Displays body contents on In Progress or Complete column (People, Links, Tags)
    * Supported Tags for Complete column are, Under Review and Complete
    * Sick documentation @see above
  TODO:
    * Support Comments
    * Support additional tags

  @author: Morgan Nesbitt
*/

var cardTemplate;
var modalTemplate;
var grantName = "NSF Career";
var jsonInfo = {
  Grants: [
    {
      Grant_Name : "NSF Career",
      Grant_Columns : [
        {
          Column_Name : "To Do",
          Cards: [
            {
              Card_Name: "Cover Sheet",
              Modal_ID : "Cover_Sheet",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com"
            },
            {
              Card_Name: "Project Description",
              Modal_ID : "Project_Description",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com"
            },
            {
              Card_Name: "Budget",
              Modal_ID : "Budget",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com"
            },
            {
              Card_Name: "Budget Justification",
              Modal_ID : "Budget_Justification",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com"
            }
          ]
        },

        {
          Column_Name : "In Progress",
          Cards: [
            {
              Card_Name: "References Cited",
              Modal_ID : "References_Cited",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com",
              Assigned_People : ["Waffles", "Waffles"]
            },
            {
              Card_Name: "Biosketch",
              Modal_ID : "Biosketch",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com",
              Assigned_People : ["Waffles"]
            }
          ]
        },

        {
          Column_Name : "Complete",
          Cards: [
            {
              Card_Name: "Departmental Letter",
              Modal_ID : "Departmental_Letter",
              Modal_Body: "
Required

Program Solicitation Number

NSF Unit of Consideration

Project Title

Co-PIs

PI eligibility information

",
              Document_Link: "http://www.github.com",
              Assigned_People : ["Waffles"],
              Tag_List : ["Under Review", "Complete"]
            }
          ]
        }
      ]
    }
  ]
};
/*
$.getJSON( "json/cards.json", {}, function( data ) {
  jsonInfo = data.Grants[0];
});
*/
$.ajax({
    url: 'templates/full_card.html',
    dataType: 'html',
    method: 'GET',
    async: false,
    success: function(data) {
        cardTemplate = Handlebars.compile(data);
        $('#columnList').html(cardTemplate(jsonInfo.Grants[0]));
    }
});

$.ajax({
    url: 'templates/card_modal.html',
    dataType: 'html',
    method: 'GET',
    async: false,
    success: function(data) {
        modalTemplate = Handlebars.compile(data);
        $('#cardModals').html(modalTemplate(jsonInfo.Grants[0]));
    }
});
<|endoftext|>


<commit_before>import React from 'react';

const plantCalendarAddBox = props => {
    const options = this.props.plantNames.map(plantName =>
        <option
            key={plantName}
            value={plantName} />);

    const handleClick = () => {
        const selectedPlant = this.refs.selectedPlant;
        const plantName = selectedPlant.selectedOptions[0].value;
        this.props.onAdd(plantName);
    };

    return (

            <select ref="selectedPlant">
                {options}
            </select>
            <button
                type="button"
                onClick={handleClick}>
                Add
            </button>

    );
};

plantCalendarAddBox.propTypes = {
    plantNames: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
    onAdd: React.PropTypes.func.isRequired
};

export default plantCalendarAddBox;<commit_msg>Too much `this`<commit_after>import React from 'react';

const plantCalendarAddBox = props => {
    const options = props.plantNames.map(plantName =>
        <option
            key={plantName}
            value={plantName} />);

    const handleClick = () => {
        const selectedPlant = this.refs.selectedPlant;
        const plantName = selectedPlant.selectedOptions[0].value;
        props.onAdd(plantName);
    };

    return (

            <select ref="selectedPlant">
                {options}
            </select>
            <button
                type="button"
                onClick={handleClick}>
                Add
            </button>

    );
};

plantCalendarAddBox.propTypes = {
    plantNames: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
    onAdd: React.PropTypes.func.isRequired
};

export default plantCalendarAddBox;<|endoftext|>


<commit_before>//Dependencies
import React, { Component , PropTypes} from 'react';
const propTypes = {
    number: PropTypes.number.isRequired,
    openCenter: PropTypes.func.isRequired
};

const NotificationCenterIcon = ({number, openCenter}) => {
    return (

                add_alert

{`you have ${number} notifications`}

    );
};

NotificationCenterIcon.propTypes = propTypes;
NotificationCenterIcon.displayName = 'NotificationCenterIcon';
NotificationCenterIcon.defaultProps = {
    hasDate: true
}
export default NotificationCenterIcon;
<commit_msg>]icon[ Remove badge when there is no notification. Fix #25<commit_after>//Dependencies
import React, { Component , PropTypes} from 'react';
const propTypes = {
    number: PropTypes.number.isRequired,
    openCenter: PropTypes.func.isRequired
};

const NotificationCenterIcon = ({number, openCenter}) => {
    const conditionnalProps = number > 0 ? {'data-badge': number} : {};
    return (

                add_alert

{`you have ${number} notifications`}

    );
};

NotificationCenterIcon.propTypes = propTypes;
NotificationCenterIcon.displayName = 'NotificationCenterIcon';
NotificationCenterIcon.defaultProps = {
    hasDate: true
}
export default NotificationCenterIcon;
<|endoftext|>


<commit_before>import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faGithub, faLinkedin } from '@fortawesome/free-brands-svg-icons';
import { faEnvelope } from '@fortawesome/free-regular-svg-icons';

import { StaticQuery, graphql } from 'gatsby';

import contactCardStyles from './ContactCard.module.css';

function ContactCard({ data }) {
  return (

        <a
          title={`${data.site.siteMetadata.social.github} on GitHub`}
          href={`https://github.com/${data.site.siteMetadata.social.github}`}
          aria-label="GitHub profile"
        >
          <FontAwesomeIcon
            icon={faGithub}
            className={contactCardStyles.icon}
            size="lg"
          />

        <a
          title={`${data.site.siteMetadata.social.linkedin} on LinkedIn`}
          href={`https://linkedin.com/in/${data.site.siteMetadata.social.linkedin}`}
          aria-label="LinkedIn profile"
        >
          <FontAwesomeIcon
            icon={faLinkedin}
            className={contactCardStyles.icon}
            size="lg"
          />

        <FontAwesomeIcon
          icon={faEnvelope}
          className={`${contactCardStyles.icon} ${contactCardStyles.email__icon}`}
        />
        <a
          href={`mailto:${ data.site.siteMetadata.contact.email }`}
        >
          { data.site.siteMetadata.contact.displayedEmail }

        hire me -

          here's my resume

  );
}

export default function ContactCardWithData() {
  return (
    <StaticQuery
      query={
        graphql`
          query {
            site {
              siteMetadata {
                contact {
                  name,
                  email,
                  displayedEmail,
                  resumeUrl,
                },
                social {
                  github,
                  linkedin,
                }
              }
            }
          }
        `
      }
      render={data => <ContactCard data={data} />}
    />
  );
}
<commit_msg>wrap envelope icon in link<commit_after>import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faGithub, faLinkedin } from '@fortawesome/free-brands-svg-icons';
import { faEnvelope } from '@fortawesome/free-regular-svg-icons';

import { StaticQuery, graphql } from 'gatsby';

import contactCardStyles from './ContactCard.module.css';

function ContactCard({ data }) {
  return (

        <a
          title={`${data.site.siteMetadata.social.github} on GitHub`}
          href={`https://github.com/${data.site.siteMetadata.social.github}`}
          aria-label="GitHub profile"
        >
          <FontAwesomeIcon
            icon={faGithub}
            className={contactCardStyles.icon}
            size="lg"
          />

        <a
          title={`${data.site.siteMetadata.social.linkedin} on LinkedIn`}
          href={`https://linkedin.com/in/${data.site.siteMetadata.social.linkedin}`}
          aria-label="LinkedIn profile"
        >
          <FontAwesomeIcon
            icon={faLinkedin}
            className={contactCardStyles.icon}
            size="lg"
          />

        <a
          href={`mailto:${ data.site.siteMetadata.contact.email }`}
        >
          <FontAwesomeIcon
            icon={faEnvelope}
            className={`${contactCardStyles.icon} ${contactCardStyles.email__icon}`}
          />
          { data.site.siteMetadata.contact.displayedEmail }

        hire me -

          here's my resume

  );
}

export default function ContactCardWithData() {
  return (
    <StaticQuery
      query={
        graphql`
          query {
            site {
              siteMetadata {
                contact {
                  name,
                  email,
                  displayedEmail,
                  resumeUrl,
                },
                social {
                  github,
                  linkedin,
                }
              }
            }
          }
        `
      }
      render={data => <ContactCard data={data} />}
    />
  );
}
<|endoftext|>


<commit_before>import React, { useState } from 'react';

import markdown from './README.mdx';
import Sidebar, {
  SidebarHeader,
  SidebarBackButton,
  SidebarScroll,
} from './Sidebar';
import DATA from './PHONEBOOK.json';
import User from '../User';
import { List, ListItem } from '../List';
import MainNavigation from '../MainNavigation';
import Item from '../Item';
import Empty from '../Empty';
import Search from '../Search';
import Tag from '../Tag';

export default {
  title: 'Components/Content Related/Sidebar',
  component: Sidebar,
  subcomponents: { SidebarHeader, SidebarBackButton, SidebarScroll },
  parameters: {
    status: 'released',
    mdx: markdown,
    previewWidth: 'full',
  },
};

export const Regular = (args) => {
  const [active, setActive] = useState(false);

  return (

      <MainNavigation pageWidth="full" />
      <Sidebar
        {...args}
        active={active}
        sidebar={
          <>
            <SidebarHeader>
              <Search />
            </SidebarHeader>
            <Item
              additional="Yesterday"
              hint={<Tag kind="wfp">Hint</Tag>}
              kind="horizontal"
              subContent="subcontent"
              title="A title is shown"
              wrapper="sidebar"
              onClick={() => setActive(true)}
            />
          </>
        }
        sidebarMobileHeader={
          <>
            <SidebarBackButton onClick={() => setActive(false)}>
              Back
            </SidebarBackButton>

Detail page

          </>
        }>
        {active ? (
          <Item
            additional="Yesterday"
            hint={<Tag kind="wfp">Hint</Tag>}
            kind="large"
            showAdditionalIcon
            subContent="This is the subContent. Lorem ipsum dolor sit amet, consetetur sadipscing elitr.  At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
            title="A title is shown"
            wrapper="button">
            nonumy eirmod tempor invidunt
          </Item>
        ) : (
          <Empty title="Content here">
            When an item is selected, its corresponding content will be shown
            here
          </Empty>
        )}
      </Sidebar>

  );
};

/*
export const Phonebook = (args) => {
  const [selectedUserId, setSelectedUserId] = useState(null);
  const [search, setSearch] = useState();
  const selectedUserData = DATA.find((e) => e.id === selectedUserId);

  const searchResults = search
    ? DATA.filter((e) =>
        e.full_name.toLocaleLowerCase().includes(search.toLocaleLowerCase())
      )
    : DATA;

  return (

      <MainNavigation pageWidth="full" />
      <Sidebar
        active={selectedUserId}
        sidebarMobileHeader={
          <>
            <SidebarBackButton onClick={() => setSelectedUserId()}>
              Back
            </SidebarBackButton>

Detail page

          </>
        }
        Sidebar={
          <>
            <SidebarHeader>
              <Search onChange={(e) => setSearch(e)} />
            </SidebarHeader>
            <SidebarScroll>
              {searchResults && searchResults.length > 0 ? (
                searchResults.map((user, key) => (
                  <Item
                    active={selectedUserId === user.id}
                    key={key}
                    image={
                      user.profile_image ? (

                      ) : undefined
                    }
                    title={user.full_name}
                    children={user.email}
                    subContent={user.phone_number}
                    kind="horizontal"
                    wrapper="sidebar"
                    onClick={() => setSelectedUserId(user.id)}
                    noImage
                  />
                ))
              ) : (
                <Empty title="No results">Please check your search</Empty>
              )}
            </SidebarScroll>
          </>
        }>
        {selectedUserData ? (

            <User
              id={selectedUserData.staff_id}
              alt="avatar"
              description={
                <List small>
                  <ListItem>{selectedUserData.job_title}</ListItem>
                </List>
              }
              image={selectedUserData.profile_image}
              name={selectedUserData.full_name}
              style={{
                borderBottom: '1px solid #edf1f3',
                padding: '1rem 0 2rem 0',
                marginBottom: '1rem',
              }}
            />

Bio

                <List small>
                  <ListItem>{selectedUserData.bio}</ListItem>
                </List>

Contact

                <List small>
                  <ListItem>email: {selectedUserData.email}</ListItem>
                  <ListItem>phone: {selectedUserData.phone_number}</ListItem>
                </List>

Location

                <List small>
                  <ListItem>country: {selectedUserData.country}</ListItem>
                </List>

        ) : (
          <Empty title="No user selected">Please select a user</Empty>
        )}
      </Sidebar>

  );
};
*/
<commit_msg>docs(Sidebar): restored phonebook example<commit_after>import React, { useState } from 'react';

import markdown from './README.mdx';
import Sidebar, {
  SidebarHeader,
  SidebarBackButton,
  SidebarScroll,
} from './Sidebar';
import DATA from './PHONEBOOK.json';
import User from '../User';
import { List, ListItem } from '../List';
import MainNavigation from '../MainNavigation';
import Item from '../Item';
import Empty from '../Empty';
import Search from '../Search';
import Tag from '../Tag';

export default {
  title: 'Components/Content Related/Sidebar',
  component: Sidebar,
  subcomponents: { SidebarHeader, SidebarBackButton, SidebarScroll },
  parameters: {
    status: 'released',
    mdx: markdown,
    previewWidth: 'full',
  },
};

export const Regular = (args) => {
  const [active, setActive] = useState(false);

  return (

      <MainNavigation pageWidth="full" />
      <Sidebar
        {...args}
        active={active}
        sidebar={
          <>
            <SidebarHeader>
              <Search />
            </SidebarHeader>
            <Item
              additional="Yesterday"
              hint={<Tag kind="wfp">Hint</Tag>}
              kind="horizontal"
              subContent="subcontent"
              title="A title is shown"
              wrapper="sidebar"
              onClick={() => setActive(true)}
            />
          </>
        }
        sidebarMobileHeader={
          <>
            <SidebarBackButton onClick={() => setActive(false)}>
              Back
            </SidebarBackButton>

Detail page

          </>
        }>
        {active ? (
          <Item
            additional="Yesterday"
            hint={<Tag kind="wfp">Hint</Tag>}
            kind="large"
            showAdditionalIcon
            subContent="This is the subContent. Lorem ipsum dolor sit amet, consetetur sadipscing elitr.  At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
            title="A title is shown"
            wrapper="button">
            nonumy eirmod tempor invidunt
          </Item>
        ) : (
          <Empty title="Content here">
            When an item is selected, its corresponding content will be shown
            here
          </Empty>
        )}
      </Sidebar>

  );
};

export const Phonebook = (args) => {
  const [selectedUserId, setSelectedUserId] = useState(null);
  const [search, setSearch] = useState();
  const selectedUserData = DATA.find((e) => e.id === selectedUserId);

  const searchResults = search
    ? DATA.filter((e) =>
        e.full_name.toLocaleLowerCase().includes(search.toLocaleLowerCase())
      )
    : DATA;
console.log("sdfghj", searchResults, DATA);
  return (

      <MainNavigation pageWidth="full" />
      <Sidebar
        active={selectedUserId}
        sidebarMobileHeader={
          <>
            <SidebarBackButton onClick={() => setSelectedUserId()}>
              Back
            </SidebarBackButton>

Detail page

          </>
        }
        sidebar={
          <>
            <SidebarHeader>
              <Search onChange={(e) => setSearch(e)} />
            </SidebarHeader>
            <SidebarScroll>
              {searchResults && searchResults.length > 0 ? (
                searchResults.map((user, key) => (
                  <Item
                    active={selectedUserId === user.id}
                    key={key}
                    image={
                      user.profile_image ? (

                      ) : undefined
                    }
                    title={user.full_name}
                    children={user.email}
                    subContent={user.phone_number}
                    kind="horizontal"
                    wrapper="sidebar"
                    onClick={() => setSelectedUserId(user.id)}
                    noImage
                  />
                ))
              ) : (
                <Empty title="No results">Please check your search</Empty>
              )}
            </SidebarScroll>
          </>
        }>
        {selectedUserData ? (

            <User
              id={selectedUserData.staff_id}
              alt="avatar"
              description={
                <List small>
                  <ListItem>{selectedUserData.job_title}</ListItem>
                </List>
              }
              image={selectedUserData.profile_image}
              name={selectedUserData.full_name}
              style={{
                borderBottom: '1px solid #edf1f3',
                padding: '1rem 0 2rem 0',
                marginBottom: '1rem',
              }}
            />

Bio

                <List small>
                  <ListItem>{selectedUserData.bio}</ListItem>
                </List>

Contact

                <List small>
                  <ListItem>email: {selectedUserData.email}</ListItem>
                  <ListItem>phone: {selectedUserData.phone_number}</ListItem>
                </List>

Location

                <List small>
                  <ListItem>country: {selectedUserData.country}</ListItem>
                </List>

        ) : (
          <Empty title="No user selected">Please select a user</Empty>
        )}
      </Sidebar>

  );
};

<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { contextTypes } from '../../../utils/decorators/withContext.js';
import withViewport from '../../../utils/decorators/withViewport.js';

import UserModel from '../../../models/UserModel.js';
import MatchModel from '../../../models/MatchModel.js';
import * as matchActions from '../../../actions/matchActions.js';
import { util as storeUtils } from '../../../store.js';

import MatchCardHeader from './MatchCardHeader.js';
import MatchPlayerResults from './MatchPlayerResults.js';
import IndividualMatches from './IndividualMatches.js';
import OpponentClubLocations from './OpponentClubLocations.js';
import SelectPlayersForm from './SelectPlayersForm.js';
import OpponentsLastMatches from './OpponentsLastMatches.js';
import OpponentsFormation from './OpponentsFormation.js';
import MatchReport from './MatchReport.js';
import Scoresheet from './Scoresheet.js';

import Icon from '../../controls/Icon.js';
import PlayersImageGallery from '../../players/PlayersImageGallery.js';

import CardText from 'material-ui/lib/card/card-text';
import Nav from 'react-bootstrap/lib/Nav';
import NavItem from 'react-bootstrap/lib/NavItem';
import PanelGroup from 'react-bootstrap/lib/PanelGroup';
import Panel from 'react-bootstrap/lib/Panel';

const tabEventKeys = {
  players: 1,
  individualMatches: 2,
  report: 3,
  opponentClub: 4,
  scoresheet: 5,
  opponentsRanking: 6,
  opponentsFormation: 7,
};

// TODO: request match if not yet present in store

@withViewport
@connect(state => {
  return {
    //config: state.config,
    user: state.user,
    // players: state.players,
    // clubs: state.clubs,
    // matches: state.matches,
    // teams: state.teams,
  };
}, matchActions)
export default class MatchCard extends Component {
  static contextTypes = contextTypes;
  static propTypes = {
    match: PropTypes.instanceOf(MatchModel).isRequired,
    user: PropTypes.instanceOf(UserModel).isRequired,
    getLastOpponentMatches: PropTypes.func.isRequired,
    viewport: PropTypes.object.isRequired,
  }

  constructor(props) {
    super(props);
    this.state = {
      openTabKey: tabEventKeys.players,
      forceEditPlayers: false
    };
  }

  componentDidMount() {
    // TODO: here check for matches using storeUtils - http request only if matches not yet present in state...
    this.props.getLastOpponentMatches(this.props.match.teamId, this.props.match.opponent);
  }

  _showAccordeon() {
    // Otherwise show tabs
    return this.props.viewport.width < 600;
  }

  render() {
    var match = this.props.match;
    const showIndividualMatches = match.games.size !== 0;
    const showOpponentClubLocation = !match.isHomeMatch && !match.isPlayed;
    const showScoresheet = match.scoreType === 'BeingPlayed';

    if (this._showAccordeon()) {
      return (
        <MatchCardHeader {...this.props} backgroundColor="#fafafa" isOpen={true} style={{margin: 50}}>
          <CardText expandable={true} style={{paddingTop: 0, paddingLeft: 5, paddingRight: 5}}>
            <PanelGroup activeKey={this.state.openTabKey} onSelect={::this._onTabSelect} accordion>
              {this._renderNavItem(tabEventKeys.players, 'players', this._getPlayersEditIcon())}
              {showIndividualMatches ? this._renderNavItem(tabEventKeys.individualMatches, 'matches') : null}
              {showOpponentClubLocation ? this._renderNavItem(tabEventKeys.opponentClub, 'club') : null}
              {showScoresheet ? this._renderNavItem(tabEventKeys.scoresheet, 'scoresheet') : null}
              {this._renderNavItem(tabEventKeys.opponentsRanking, 'opponentsRanking')}
              {this._renderNavItem(tabEventKeys.opponentsFormation, 'opponentsFormation')}
              {this._renderNavItem(tabEventKeys.report, 'report')}
              {this.props.user.isDev() ? this._renderNavItem('admin', 'admin') : null}
            </PanelGroup>
          </CardText>
        </MatchCardHeader>
      );
    }

    return (
      <MatchCardHeader {...this.props} backgroundColor="#fafafa" isOpen={true}>
        <CardText expandable={true} style={{paddingTop: 0}}>

            {this._renderNavItem(tabEventKeys.players, 'players', this._getPlayersEditIcon())}
            {showIndividualMatches ? this._renderNavItem(tabEventKeys.individualMatches, 'matches') : null}
            {showOpponentClubLocation ? this._renderNavItem(tabEventKeys.opponentClub, 'club') : null}
            {showScoresheet ? this._renderNavItem(tabEventKeys.scoresheet, 'scoresheet') : null}
            {this._renderNavItem(tabEventKeys.opponentsRanking, 'opponentsRanking')}
            {this._renderNavItem(tabEventKeys.opponentsFormation, 'opponentsFormation')}
            {this._renderNavItem(tabEventKeys.report, 'report')}
            {this.props.user.isDev() ? this._renderNavItem('admin', 'admin') : null}

            {this._renderTabContent()}

        </CardText>
      </MatchCardHeader>
    );
  }
  _getPlayersEditIcon() {
    var match = this.props.match;
    var isAllowedToEdit = this.props.user.canManageTeam(match.teamId);
    return isAllowedToEdit && !match.isSyncedWithFrenoy ? (
      <Icon fa="fa fa-pencil-square-o" onClick={::this._onStartEditPlayers} className="match-card-tab-icon" />) : null;
  }
  _onStartEditPlayers() {
    this.setState({forceEditPlayers: !this.state.forceEditPlayers});
  }
  _renderNavItem(eventKey, transKey, headerChildren = null) {
    if (!this._showAccordeon()) {
      // Tabs
      return (
        <NavItem eventKey={eventKey} title={this.context.t(`match.tabs.${transKey}Title`)}>
          {this.context.t(`match.tabs.${transKey}`)} {headerChildren}
        </NavItem>
      );
    }

    // Accordeon
    var header =
{this.context.t(`match.tabs.${transKey}Title`)} {headerChildren}
;
    return (
      <Panel header={header} eventKey={eventKey} className="match-card-panel">
        {this._renderTabContent(eventKey)}
      </Panel>
    );
  }
  _onTabSelect(eventKey) {
    this.setState({openTabKey: eventKey});
  }
  _renderTabContent(eventKey) {
    switch (eventKey || this.state.openTabKey) {
    case tabEventKeys.players:
      return this._renderPlayers();
    case tabEventKeys.individualMatches:
      return this._renderIndividualMatches();
    case tabEventKeys.report:
      return this._renderReport();
    case tabEventKeys.opponentClub:
      return this._renderOpponentClub();
    case tabEventKeys.scoresheet:
      return this._renderScoreSheet();
    case tabEventKeys.opponentsRanking:
      return this._renderOpponentsRanking();
    case tabEventKeys.opponentsFormation:
      return this._renderOpponentFormation();
    case 'admin':
      return
ID={this.props.match.id}
FrenoyId={this.props.match.frenoyMatchId}
;
    }
    return 'Unknown';
  }

  _renderOpponentClub() {
    return <OpponentClubLocations club={this.props.match.getOpponentClub()} t={this.context.t} />;
  }
  _renderIndividualMatches() {
    return <IndividualMatches match={this.props.match} ownPlayerId={this.props.user.playerId} t={this.context.t} />;
  }
  _renderOpponentsRanking() {
    return <OpponentsLastMatches match={this.props.match} />;
  }
  _renderOpponentFormation() {
    var formations = storeUtils.matches
      .getFormation(this.props.match)
      .sort((a, b) => a.count < b.count ? 1 : -1);
    return <OpponentsFormation formations={formations} />;
  }
  _renderScoreSheet() {
    return (<Scoresheet match={this.props.match} t={this.context.t} />);
  }
  _renderReport() {
    return <MatchReport match={this.props.match} t={this.context.t} user={this.props.user} />;
  }

  _renderPlayers() {
    var match = this.props.match;
    var team = match.getTeam();

    if (match.isSyncedWithFrenoy) {
      return <MatchPlayerResults match={match} team={match.getTeam()} t={this.context.t} />;
    }

    if (this.state.forceEditPlayers || (this.props.user.canManageTeam(match.teamId) && match.players.size < team.getTeamPlayerCount())) {
      return <SelectPlayersForm match={match} user={this.props.user} />;
    }

    if (match.players.size === 0 || !this.props.user.playerId) {
      let standardPlayers = team.getPlayers('standard').map(ply => ply.player);
      return <PlayersImageGallery players={standardPlayers} user={this.props.user} competition={team.competition} viewport={this.props.viewport} />;
    }

    return (
      <PlayersImageGallery
        players={match.getOwnPlayerModels()}
        user={this.props.user}
        competition={team.competition}
        viewport={this.props.viewport} />
    );
  }
}<commit_msg>match card on mobile: accordion headers completely clickable<commit_after>import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { contextTypes } from '../../../utils/decorators/withContext.js';
import withViewport from '../../../utils/decorators/withViewport.js';

import UserModel from '../../../models/UserModel.js';
import MatchModel from '../../../models/MatchModel.js';
import * as matchActions from '../../../actions/matchActions.js';
import { util as storeUtils } from '../../../store.js';

import MatchCardHeader from './MatchCardHeader.js';
import MatchPlayerResults from './MatchPlayerResults.js';
import IndividualMatches from './IndividualMatches.js';
import OpponentClubLocations from './OpponentClubLocations.js';
import SelectPlayersForm from './SelectPlayersForm.js';
import OpponentsLastMatches from './OpponentsLastMatches.js';
import OpponentsFormation from './OpponentsFormation.js';
import MatchReport from './MatchReport.js';
import Scoresheet from './Scoresheet.js';

import Icon from '../../controls/Icon.js';
import PlayersImageGallery from '../../players/PlayersImageGallery.js';

import CardText from 'material-ui/lib/card/card-text';
import Nav from 'react-bootstrap/lib/Nav';
import NavItem from 'react-bootstrap/lib/NavItem';
import PanelGroup from 'react-bootstrap/lib/PanelGroup';
import Panel from 'react-bootstrap/lib/Panel';

const tabEventKeys = {
  players: 1,
  individualMatches: 2,
  report: 3,
  opponentClub: 4,
  scoresheet: 5,
  opponentsRanking: 6,
  opponentsFormation: 7,
};

// TODO: request match if not yet present in store

@withViewport
@connect(state => {
  return {
    //config: state.config,
    user: state.user,
    // players: state.players,
    // clubs: state.clubs,
    // matches: state.matches,
    // teams: state.teams,
  };
}, matchActions)
export default class MatchCard extends Component {
  static contextTypes = contextTypes;
  static propTypes = {
    match: PropTypes.instanceOf(MatchModel).isRequired,
    user: PropTypes.instanceOf(UserModel).isRequired,
    getLastOpponentMatches: PropTypes.func.isRequired,
    viewport: PropTypes.object.isRequired,
  }

  constructor(props) {
    super(props);
    this.state = {
      openTabKey: tabEventKeys.players,
      forceEditPlayers: false
    };
  }

  componentDidMount() {
    // TODO: here check for matches using storeUtils - http request only if matches not yet present in state...
    this.props.getLastOpponentMatches(this.props.match.teamId, this.props.match.opponent);
  }

  _showAccordion() {
    // Otherwise show tabs
    return this.props.viewport.width < 600;
  }

  render() {
    var match = this.props.match;
    const showIndividualMatches = match.games.size !== 0;
    const showOpponentClubLocation = !match.isHomeMatch && !match.isPlayed;
    const showScoresheet = match.scoreType === 'BeingPlayed';

    if (this._showAccordion()) {
      return (
        <MatchCardHeader {...this.props} backgroundColor="#fafafa" isOpen={true} style={{margin: 50}}>
          <CardText expandable={true} style={{paddingTop: 0, paddingLeft: 5, paddingRight: 5}}>
            <PanelGroup activeKey={this.state.openTabKey} onSelect={::this._onTabSelect} accordion>
              {this._renderNavItem(tabEventKeys.players, 'players', this._getPlayersEditIcon())}
              {showIndividualMatches ? this._renderNavItem(tabEventKeys.individualMatches, 'matches') : null}
              {showOpponentClubLocation ? this._renderNavItem(tabEventKeys.opponentClub, 'club') : null}
              {showScoresheet ? this._renderNavItem(tabEventKeys.scoresheet, 'scoresheet') : null}
              {this._renderNavItem(tabEventKeys.opponentsRanking, 'opponentsRanking')}
              {this._renderNavItem(tabEventKeys.opponentsFormation, 'opponentsFormation')}
              {this._renderNavItem(tabEventKeys.report, 'report')}
              {this.props.user.isDev() ? this._renderNavItem('admin', 'admin') : null}
            </PanelGroup>
          </CardText>
        </MatchCardHeader>
      );
    }

    return (
      <MatchCardHeader {...this.props} backgroundColor="#fafafa" isOpen={true}>
        <CardText expandable={true} style={{paddingTop: 0}}>

            {this._renderNavItem(tabEventKeys.players, 'players', this._getPlayersEditIcon())}
            {showIndividualMatches ? this._renderNavItem(tabEventKeys.individualMatches, 'matches') : null}
            {showOpponentClubLocation ? this._renderNavItem(tabEventKeys.opponentClub, 'club') : null}
            {showScoresheet ? this._renderNavItem(tabEventKeys.scoresheet, 'scoresheet') : null}
            {this._renderNavItem(tabEventKeys.opponentsRanking, 'opponentsRanking')}
            {this._renderNavItem(tabEventKeys.opponentsFormation, 'opponentsFormation')}
            {this._renderNavItem(tabEventKeys.report, 'report')}
            {this.props.user.isDev() ? this._renderNavItem('admin', 'admin') : null}

            {this._renderTabContent()}

        </CardText>
      </MatchCardHeader>
    );
  }
  _getPlayersEditIcon() {
    var match = this.props.match;
    var isAllowedToEdit = this.props.user.canManageTeam(match.teamId);
    return isAllowedToEdit && !match.isSyncedWithFrenoy ? (
      <Icon fa="fa fa-pencil-square-o" onClick={::this._onStartEditPlayers} className="match-card-tab-icon" />) : null;
  }
  _onStartEditPlayers() {
    this.setState({forceEditPlayers: !this.state.forceEditPlayers});
  }
  _renderNavItem(eventKey, transKey, headerChildren = null) {
    if (!this._showAccordion()) {
      // Tabs
      return (
        <NavItem eventKey={eventKey} title={this.context.t(`match.tabs.${transKey}Title`)}>
          {this.context.t(`match.tabs.${transKey}`)} {headerChildren}
        </NavItem>
      );
    }

    // Accordion
    var header =
{this.context.t(`match.tabs.${transKey}Title`)} {headerChildren}
;
    return (
      <Panel header={header} eventKey={eventKey} className="match-card-panel clickable" onClick={this._onTabSelect.bind(this, eventKey)}>
        {this._renderTabContent(eventKey)}
      </Panel>
    );
  }
  _onTabSelect(eventKey) {
    this.setState({openTabKey: eventKey});
  }
  _renderTabContent(eventKey) {
    switch (eventKey || this.state.openTabKey) {
    case tabEventKeys.players:
      return this._renderPlayers();
    case tabEventKeys.individualMatches:
      return this._renderIndividualMatches();
    case tabEventKeys.report:
      return this._renderReport();
    case tabEventKeys.opponentClub:
      return this._renderOpponentClub();
    case tabEventKeys.scoresheet:
      return this._renderScoreSheet();
    case tabEventKeys.opponentsRanking:
      return this._renderOpponentsRanking();
    case tabEventKeys.opponentsFormation:
      return this._renderOpponentFormation();
    case 'admin':
      return
ID={this.props.match.id}
FrenoyId={this.props.match.frenoyMatchId}
;
    }
    return 'Unknown';
  }

  _renderOpponentClub() {
    return <OpponentClubLocations club={this.props.match.getOpponentClub()} t={this.context.t} />;
  }
  _renderIndividualMatches() {
    return <IndividualMatches match={this.props.match} ownPlayerId={this.props.user.playerId} t={this.context.t} />;
  }
  _renderOpponentsRanking() {
    return <OpponentsLastMatches match={this.props.match} />;
  }
  _renderOpponentFormation() {
    var formations = storeUtils.matches
      .getFormation(this.props.match)
      .sort((a, b) => a.count < b.count ? 1 : -1);
    return <OpponentsFormation formations={formations} />;
  }
  _renderScoreSheet() {
    return (<Scoresheet match={this.props.match} t={this.context.t} />);
  }
  _renderReport() {
    return <MatchReport match={this.props.match} t={this.context.t} user={this.props.user} />;
  }

  _renderPlayers() {
    var match = this.props.match;
    var team = match.getTeam();

    if (match.isSyncedWithFrenoy) {
      return <MatchPlayerResults match={match} team={match.getTeam()} t={this.context.t} />;
    }

    if (this.state.forceEditPlayers || (this.props.user.canManageTeam(match.teamId) && match.players.size < team.getTeamPlayerCount())) {
      return <SelectPlayersForm match={match} user={this.props.user} />;
    }

    if (match.players.size === 0 || !this.props.user.playerId) {
      let standardPlayers = team.getPlayers('standard').map(ply => ply.player);
      return <PlayersImageGallery players={standardPlayers} user={this.props.user} competition={team.competition} viewport={this.props.viewport} />;
    }

    return (
      <PlayersImageGallery
        players={match.getOwnPlayerModels()}
        user={this.props.user}
        competition={team.competition}
        viewport={this.props.viewport} />
    );
  }
}<|endoftext|>


<commit_before>'use strict';

// @ngInject
var SearchController = function ($scope, $location, NpdcLang, NpolarApiSecurity) {

  $scope.security = NpolarApiSecurity;
  $scope.q = $location.search().q;

  // Simplify facet array to facet object
  $scope.facet = function(farr) {
    let keys = Object.keys(farr);
    let key = keys[0];
    let facet = farr[key].map(f => {

      f.facet = key;
      return f;

    });

    return facet;

  };

  // Get search bit of API URI
  $scope.facetHref = function(uri) {
    return "?"+ uri.split("?")[1];
  };

  $scope.facetKey = function(facet) {
    return Object.keys(facet)[0];
  };

  $scope.entryHref = function(id) {
    if ((/[.]/).test(id)) {
      id += ".json";
    }
    // Get relative path of entry by removing hostname + appname from request URI
    let segments = $location.absUrl().split("//")[1].split("?")[0].split("/").filter(s => { return s !== "";}).slice(2);

    if (segments.length === 0) {
      // For apps at /something, we just need to link to the id
      return id;
    } else {
      // For apps at /cat, but with show/edit at /cat/lynx we link to `lynx/${id}`
      return segments.join("/")+'/'+id;
    }
  };

  $scope.title = (entry, key='title') => {

    let lang = NpdcLang.getLang();

    if (entry.titles) {

      return JSON.stringify(entry.titles.find(e => { return true; } ));
    }
    return entry.title || entry.name || entry.code || entry.id;
  };

  // Get facet object { term, uri, facet, count } from filter object like { "filter-term": "X" }
  $scope.facetObjectFromFilter = function(filter) {
    //let term = filter[ Object.keys(filter)[0] ];
    let key = $scope.facetKey(filter).replace(/^filter\-/, "");

    //
    let facets = $scope.feed.facets.find(facet => {
      //console.log(facet, term);
      return (facet.hasOwnProperty(key) && facet.hasOwnProperty(key) === "Tromsø");
    });

    //console.log(facet);
    return facets[key];

  };

};

module.exports = SearchController;
<commit_msg>Removed temp dependency<commit_after>'use strict';

// @ngInject
var SearchController = function ($scope, $location, NpolarApiSecurity) {

  $scope.security = NpolarApiSecurity;
  $scope.q = $location.search().q;

  // Simplify facet array to facet object
  $scope.facet = function(farr) {
    let keys = Object.keys(farr);
    let key = keys[0];
    let facet = farr[key].map(f => {

      f.facet = key;
      return f;

    });

    return facet;

  };

  // Get search bit of API URI
  $scope.facetHref = function(uri) {
    return "?"+ uri.split("?")[1];
  };

  $scope.facetKey = function(facet) {
    return Object.keys(facet)[0];
  };

  $scope.entryHref = function(id) {
    if ((/[.]/).test(id)) {
      id += ".json";
    }
    // Get relative path of entry by removing hostname + appname from request URI
    let segments = $location.absUrl().split("//")[1].split("?")[0].split("/").filter(s => { return s !== "";}).slice(2);

    if (segments.length === 0) {
      // For apps at /something, we just need to link to the id
      return id;
    } else {
      // For apps at /cat, but with show/edit at /cat/lynx we link to `lynx/${id}`
      return segments.join("/")+'/'+id;
    }
  };

  $scope.title = (entry, key='title') => {

    let lang = 'en';

    if (entry.titles) {

      return JSON.stringify(entry.titles.find(e => { return true; } ));
    }
    return entry.title || entry.name || entry.code || entry.id;
  };

  // Get facet object { term, uri, facet, count } from filter object like { "filter-term": "X" }
  $scope.facetObjectFromFilter = function(filter) {
    //let term = filter[ Object.keys(filter)[0] ];
    let key = $scope.facetKey(filter).replace(/^filter\-/, "");

    //
    let facets = $scope.feed.facets.find(facet => {
      //console.log(facet, term);
      return (facet.hasOwnProperty(key) && facet.hasOwnProperty(key) === "Tromsø");
    });

    //console.log(facet);
    return facets[key];

  };

};

module.exports = SearchController;
<|endoftext|>


<commit_before>/*
Copyright 2018 New Vector 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.
*/

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

export default class CookieBar extends React.Component {
    static propTypes = {
        policyUrl: PropTypes.string,
    }

    constructor() {
        super();
    }

    onUsageDataClicked() {
        Analytics.showDetailsModal();
    }

    onAccept() {
        dis.dispatch({
            action: 'accept_cookies',
        });
    }

    onReject() {
        dis.dispatch({
            action: 'reject_cookies',
        });
    }

    render() {
        const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
        const toolbarClasses = "mx_MatrixToolbar";
        return (

                    { this.props.policyUrl ? _t(
                        "Please help improve Riot.im by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
                        "This will use a cookie " +
                        "(please see our <PolicyLink>Cookie Policy</PolicyLink>).",
                        {},
                        {
                            'UsageDataLink': (sub) =>
                                { sub }
                            ,
                            // XXX: We need to link to the page that explains our cookies
                            'PolicyLink': (sub) =>
                                    { sub }

                            ,
                        },
                    ) : _t(
                        "Please help improve Riot.im by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
                        "This will use a cookie.",
                        {},
                        {
                            'UsageDataLink': (sub) =>
                                { sub }
                            ,
                        },
                    ) }

                <AccessibleButton element='button' className="mx_MatrixToolbar_action" onClick={this.onAccept}>
                    { _t("Yes, I want to help!") }
                </AccessibleButton>
                <AccessibleButton className="mx_MatrixToolbar_close" onClick={this.onReject}>

                </AccessibleButton>

        );
    }
}
<commit_msg>Custom cookie usage authorization disclaimer<commit_after>/*
Copyright 2018 New Vector 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.
*/

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

export default class CookieBar extends React.Component {
    static propTypes = {
        policyUrl: PropTypes.string,
    }

    constructor() {
        super();
    }

    onUsageDataClicked() {
        Analytics.showDetailsModal();
    }

    onAccept() {
        dis.dispatch({
            action: 'accept_cookies',
        });
    }

    onReject() {
        dis.dispatch({
            action: 'reject_cookies',
        });
    }

    render() {
        const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
        const toolbarClasses = "mx_MatrixToolbar";
        return (

                    { this.props.policyUrl ? _t(
                        "Allow sent stats to stats.igalia.com by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
                        "This will use a cookie " +
                        "(please see our <PolicyLink>Cookie Policy</PolicyLink>).",
                        {},
                        {
                            'UsageDataLink': (sub) =>
                                { sub }
                            ,
                            // XXX: We need to link to the page that explains our cookies
                            'PolicyLink': (sub) =>
                                    { sub }

                            ,
                        },
                    ) : _t(
                        "Allow to sent stats to stats.igalia.com by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
                        "This will use a cookie.",
                        {},
                        {
                            'UsageDataLink': (sub) =>
                                { sub }
                            ,
                        },
                    ) }

                <AccessibleButton element='button' className="mx_MatrixToolbar_action" onClick={this.onAccept}>
                    { _t("Yes, I want to help!") }
                </AccessibleButton>
                <AccessibleButton className="mx_MatrixToolbar_close" onClick={this.onReject}>

                </AccessibleButton>

        );
    }
}
<|endoftext|>


<commit_before>import React from 'react';
import easyGroup from '../easyGroup'
import randomColor from 'randomcolor'

export default class IndividualMacs extends React.Component {
  static defaultProps = { multiplier_x: (33+1/3), multiplier_y:10 };

  timestampToTime(timestamp) {
      let date = new Date(timestamp *1000)
      const hour = date.getHours()
      const minutes = date.getMinutes()
      const new_time = hour + minutes * 0.01
      return new_time
  }

  prepareData(index) {
    // let data = createSimpleArray(this.props.data)
    // let data = easyGroup(this.props.data)
    // let max = findMaxNew(data)
    // let dataCut = groupByPassedTime()
    let d = [`M ${this.props.x} ${this.props.y}`];
    let multiplier = this.props.height/(50)
    let collector = this.props.data[index].map(chunk => {
      let hour = this.timestampToTime(chunk.timestamp)
      console.log(hour)
      let xNext = this.props.x + hour * this.props.length/25;
      let yNext = this.props.y - (chunk.cellphone[0].rssi+100) * multiplier;
      if (chunk.cellphone[0].rssi != -100) {
        // console.log(chunk.cellphone[0].mac)
        // console.log(hour)
      }
      return `L ${xNext} ${yNext}`;
    });

    return d.concat(collector).join(' ');
  }

  render() {
    let users = []
    for (let i=0; i < this.props.data.length; i++){
    // for (let i=1; i < 2; i++){
      let mac = this.props.data[i][0].cellphone[0].mac
      mac = mac.split(':').join("");
      mac = mac.substr(mac.length - 6);
      users.push(
        <path d={this.prepareData(i)}
          key={`${i}key`}
          stroke={`#${mac}`}
          strokeWidth={1}
          fill="none"
        />
      )
    }
    return(
      <g>
      {users}
      </g>
    )
  }
}

// https://stackoverflow.com/questions/22876978/loop-inside-react-jsx

// [
//   [1, 3],
//   [2, 5],
//   [3, 2],
//   [4, 16],
//   [18, 5]
// ],

// {
//   "node": "wifi4garden1",
//   "cellphones": [
//     {
//       "rssi": -88.88888888888889,
//       "company": "Apple, Inc.",
//       "mac": "f0:d1:a9:18:2e:5d"
//     },
//     {
//       "rssi": -92.18181818181819,
//       "company": "Apple, Inc.",
//       "mac": "80:e6:50:e1:80:c0"
//     },
//     {
//       "rssi": -85.5,
//       "company": "Cambridge Industries(Group) Co.,Ltd.",
//       "mac": "4c:fa:ca:f7:70:c0"
//     },
//     {
//       "rssi": -90,
//       "company": "SAMSUNG ELECTRO-MECHANICS(THAILAND)",
//       "mac": "ac:5f:3e:ca:9b:41"
//     },
//     {
//       "rssi": -75,
//       "company": "Apple, Inc.",
//       "mac": "40:30:04:93:97:72"
//     },
//     {
//       "rssi": -85,
//       "company": "Apple, Inc.",
//       "mac": "8c:2d:aa:44:3d:df"
//     }
//   ],
//   "timestamp": 1504735342
// }
//
// ]
<commit_msg>better dummy for mac view<commit_after>import React from 'react';
import easyGroup from '../easyGroup'
import randomColor from 'randomcolor'

export default class IndividualMacs extends React.Component {
  static defaultProps = { multiplier_x: (33+1/3), multiplier_y:10 };

  timestampToTime(timestamp) {
      let date = new Date(timestamp *1000)
      const hour = date.getHours()
      const minutes = date.getMinutes()
      const new_time = hour + minutes * 0.01
      return new_time
  }

  prepareData(index) {
    // let data = createSimpleArray(this.props.data)
    // let data = easyGroup(this.props.data)
    // let max = findMaxNew(data)
    // let dataCut = groupByPassedTime()
    let d = [`M ${this.props.x} ${this.props.y}`];
    let multiplier = this.props.height/(50)
    let collector = this.props.data[index].map(chunk => {
      let hour = this.timestampToTime(chunk.timestamp)
      let xNext = this.props.x + hour * this.props.length/25;
      let yNext = this.props.y - (chunk.cellphone[0].rssi+100) * multiplier;
      if (chunk.cellphone[0].rssi != -100) {
        // console.log(chunk.cellphone[0].mac)
        // console.log(hour)
      }
      return `L ${xNext} ${yNext}`;
    });

    return d.concat(collector).join(' ');
  }

  render() {
    let users = []
    for (let i=0; i < this.props.data.length; i++){
    // for (let i=1; i < 2; i++){
      let mac = this.props.data[i][0].cellphone[0].mac
      mac = mac.split(':').join("");
      mac = mac.substr(mac.length - 6);
      users.push(
        <path d={this.prepareData(i)}
          key={`${i}key`}
          stroke={`#${mac}`}
          strokeWidth={1}
          fill="none"
        />
      )
    }
    return(
      <g>
      {users}
      </g>
    )
  }
}

// https://stackoverflow.com/questions/22876978/loop-inside-react-jsx

// [
//   [1, 3],
//   [2, 5],
//   [3, 2],
//   [4, 16],
//   [18, 5]
// ],

// {
//   "node": "wifi4garden1",
//   "cellphones": [
//     {
//       "rssi": -88.88888888888889,
//       "company": "Apple, Inc.",
//       "mac": "f0:d1:a9:18:2e:5d"
//     },
//     {
//       "rssi": -92.18181818181819,
//       "company": "Apple, Inc.",
//       "mac": "80:e6:50:e1:80:c0"
//     },
//     {
//       "rssi": -85.5,
//       "company": "Cambridge Industries(Group) Co.,Ltd.",
//       "mac": "4c:fa:ca:f7:70:c0"
//     },
//     {
//       "rssi": -90,
//       "company": "SAMSUNG ELECTRO-MECHANICS(THAILAND)",
//       "mac": "ac:5f:3e:ca:9b:41"
//     },
//     {
//       "rssi": -75,
//       "company": "Apple, Inc.",
//       "mac": "40:30:04:93:97:72"
//     },
//     {
//       "rssi": -85,
//       "company": "Apple, Inc.",
//       "mac": "8c:2d:aa:44:3d:df"
//     }
//   ],
//   "timestamp": 1504735342
// }
//
// ]
<|endoftext|>


<commit_before>/*
Copyright 2015, 2016 OpenMarket 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';

var React = require('react');
var ReactDOM = require('react-dom');
var dis = require('matrix-react-sdk/lib/dispatcher');

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

    propTypes: {
        // The tooltip is derived from either the room name or a label
        room: React.PropTypes.object,
        label: React.PropTypes.string,

        // The tooltip position can be tweaked by passing in additional positional information
        top: React.PropTypes.number,
        left: React.PropTypes.number,
    },

    // Create a wrapper for the tooltip outside the parent and attach it to the body element
    componentDidMount: function() {
        this.tooltipContainer = document.createElement("div");
        this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper";
        document.body.appendChild(this.tooltipContainer);

        this._renderTooltip();
    },

    componentDidUpdate: function() {
        this._renderTooltip();
    },

    // Remove the wrapper element, as the tooltip has finished using it
    componentWillUnmount: function() {
        dis.dispatch({
            action: 'view_tooltip',
            tooltip: null,
            parent: null,
        });

        ReactDOM.unmountComponentAtNode(this.tooltipContainer);
        document.body.removeChild(this.tooltipContainer);
    },

    _renderTooltip: function() {
        var label = this.props.room ? this.props.room.name : this.props.label;
        var style = {};
        if (this.props.top) { style.top = this.props.top; }
        if (this.props.left) { style.left = this.props.left; }

        // Add the parent's position to the tooltips, so it's correctly
        // positioned, also taking into account any window zoom
        // NOTE: The additional 6 pixels for the left position, is to take account of the
        // tooltips chevron
        var parent = ReactDOM.findDOMNode(this).parentElement;
        style.top = (+style.top || 0) + parent.getBoundingClientRect().top + window.pageYOffset;
        style.left = (+style.left || 0) + 6 + parent.getBoundingClientRect().right + window.pageXOffset;
        style.display = "block";

        var tooltip = (

                { label }

        );

        // Render the tooltip manually, as we wish it not to be rendered within the parent
        this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer);

        // Tell the roomlist about us so it can manipulate us if it wishes
        dis.dispatch({
            action: 'view_tooltip',
            tooltip: this.tooltip,
            parent: parent,
        });
    },

    render: function() {
        // Render a placeholder
        return (

        );
    }
});
<commit_msg>Small refactor, to make it clearer whats happening<commit_after>/*
Copyright 2015, 2016 OpenMarket 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';

var React = require('react');
var ReactDOM = require('react-dom');
var dis = require('matrix-react-sdk/lib/dispatcher');

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

    propTypes: {
        // The tooltip is derived from either the room name or a label
        room: React.PropTypes.object,
        label: React.PropTypes.string,

        // The tooltip position can be tweaked by passing in additional positional information
        top: React.PropTypes.number,
        left: React.PropTypes.number,
    },

    // Create a wrapper for the tooltip outside the parent and attach it to the body element
    componentDidMount: function() {
        this.tooltipContainer = document.createElement("div");
        this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper";
        document.body.appendChild(this.tooltipContainer);

        this._renderTooltip();
    },

    componentDidUpdate: function() {
        this._renderTooltip();
    },

    // Remove the wrapper element, as the tooltip has finished using it
    componentWillUnmount: function() {
        dis.dispatch({
            action: 'view_tooltip',
            tooltip: null,
            parent: null,
        });

        ReactDOM.unmountComponentAtNode(this.tooltipContainer);
        document.body.removeChild(this.tooltipContainer);
    },

    _renderTooltip: function() {
        var label = this.props.room ? this.props.room.name : this.props.label;

        // Add the parent's position to the tooltips, so it's correctly
        // positioned, also taking into account any window zoom
        // NOTE: The additional 6 pixels for the left position, is to take account of the
        // tooltips chevron
        var parent = ReactDOM.findDOMNode(this).parentElement;
        var style = {};
        style.top = parent.getBoundingClientRect().top + window.pageYOffset;
        style.left = 6 + parent.getBoundingClientRect().right + window.pageXOffset;
        style.display = "block";

        // Add any additional positional tweaks passed in to the tooltip
        if (this.props.top) { style.top += this.props.top; }
        if (this.props.left) { style.left += this.props.left; }

        var tooltip = (

                { label }

        );

        // Render the tooltip manually, as we wish it not to be rendered within the parent
        this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer);

        // Tell the roomlist about us so it can manipulate us if it wishes
        dis.dispatch({
            action: 'view_tooltip',
            tooltip: this.tooltip,
            parent: parent,
        });
    },

    render: function() {
        // Render a placeholder
        return (

        );
    }
});
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import c from 'classnames';
import {cloneDeep} from 'lodash';
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton';
import Dialog from 'material-ui/Dialog';
import IconMenu from 'material-ui/IconMenu';
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert';
import MenuItem from 'material-ui/MenuItem';
import IconButton from 'material-ui/IconButton';

import {setSnackBarParams} from './../../redux/modules/ui';
import {addFolder, listFolders} from './../../redux/modules/folder';
import AddFolderForm from './../../components/AddFolderForm/AddFolderForm';
import Pagination from './../../components/Pagination/Pagination';
import TopBar from './../../components/TopBar/TopBar';

import sortFolderContentFields from './../../main/helpers/sortFolderContentFields';
import injectF from './../../helpers/injectF';
import injectPush from './../../helpers/injectPush';
import resolve from './../../helpers/resolve';

const styles = require('./PageFolders.scss');

@connect(({folder}) => ({
  perpage: folder.get('perpage'),
  folders: folder.get('folders'),
  folderCount: folder.get('folderCount')
}), {listFolders, addFolder, setSnackBarParams})
@injectPush
@injectF
@resolve(({dispatch}, {perpage}) => {
  return dispatch(listFolders({page: 1, perpage}));
})
export default class PageFolders extends Component {

  static propTypes = {
    push: PropTypes.func.isRequired,
    f: PropTypes.func.isRequired,
    perpage: PropTypes.number.isRequired,
    addFolder: PropTypes.func.isRequired,
    folders: PropTypes.array.isRequired,
    folderCount: PropTypes.number.isRequired,
    listFolders: PropTypes.func.isRequired,
    setSnackBarParams: PropTypes.func.isRequired
  };

  constructor(props) {
    super(props);
    this.state = {
      page: 1,
      targetLanguages: [],
      isAddFolderDialogOpen: false
    };
  }

  componentWillUpdate(nextProps, nextState) {
    const {page} = this.state;
    const {perpage, listFolders} = this.props;
    if ((page !== nextState.page) || (perpage !== nextProps.perpage)) {
      listFolders({
        page: nextState.page,
        perpage: nextProps.perpage
      });
    }
  }

  openAddFolderDialog = () => {
    this.setState({
      targetLanguages: [],
      isAddFolderDialogOpen: true
    });
  };

  handleAddFolderDialogClose = () => this.setState({isAddFolderDialogOpen: false});

  handleSubmit = async (data) => {

    const {page} = this.state;
    const {f, addFolder, listFolders,
      perpage, setSnackBarParams} = this.props;

    data.contentFields = sortFolderContentFields(data.contentFields);

    await addFolder(data);
    await listFolders({page, perpage});

    setSnackBarParams(true, f('folder-has-been-created', {folderName: data.folderName}));
    this.setState({isAddFolderDialogOpen: false});
  };

  handleCancelButtonTouchTap = () => this.setState({isAddFolderDialogOpen: false});

  handleTargetLanguagesChange = (rawData) => {
    const data = cloneDeep(rawData);
    delete data.preventDefault;
    this.setState({targetLanguages: Object.values(data)});
  };

  renderAddFolderDialog() {

    const {targetLanguages, isAddFolderDialogOpen} = this.state;
    const {f} = this.props;

    return (
      <Dialog title={f('add-a-folder')} open={isAddFolderDialogOpen}
        bodyStyle={{paddingLeft: '8px', paddingRight: '8px', paddingBottom: '8px'}} autoScrollBodyContent
        onRequestClose={this.handleAddFolderDialogClose}>
        <AddFolderForm ref="addFolderForm" onSubmit={this.handleSubmit} targetLanguages={targetLanguages}
          onTargetLanguagesChange={this.handleTargetLanguagesChange}
          onCancelButtonTouchTap={this.handleCancelButtonTouchTap} />
      </Dialog>
    );
  }

  handleFolderAnchorTouchTap = (folderId) => {
    return () => this.props.push(`/folders/${folderId}/entries`);
  };

  handleFolderMenuItemTouchTap = (event, value) => {
    const {type, id} = value;
    switch (type) {
      case 'edit':
        return this.props.push(`/folders/${id}/edit`);
      case 'export':
      default:
    }
  };

  renderFolders() {
    const {f, folders} = this.props;
    const rows = folders.map((folder) => {
      const {id, name} = folder;
      return (
        <Paper className={styles.folder} key={`paper-${id}`}>
          {name}
          <IconMenu className={styles.folderIconMenu} style={{display: 'block', position: 'absolute'}}
            iconButtonElement={<IconButton><MoreVertIcon /></IconButton>}
            onChange={this.handleFolderMenuItemTouchTap}
            anchorOrigin={{horizontal: 'left', vertical: 'top'}}
            targetOrigin={{horizontal: 'left', vertical: 'top'}}>
            <MenuItem primaryText={f('edit')} value={{type: 'edit', id}} />
            <MenuItem primaryText={f('export')} value={{type: 'export', id}} />
          </IconMenu>
        </Paper>
      );
    });
    return
{rows}
;
  }

  handlePageButtonTouchTap = (page) => this.setState({page});

  render() {

    const {page} = this.state;
    const {f, perpage, folderCount} = this.props;

    return (

        <TopBar>

{f('folders')}

          <FlatButton icon={}
            label={f('add-folder')} primary onTouchTap={this.openAddFolderDialog} />
        </TopBar>
        {this.renderFolders()}
        {(folderCount > perpage) && <Pagination current={page} total={Math.ceil(folderCount / perpage)} onButtonTouchTap={this.handlePageButtonTouchTap} />}
        {this.renderAddFolderDialog()}

    );
  }
}
<commit_msg>add LinearProgress for importing folder<commit_after>import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import c from 'classnames';
import {cloneDeep} from 'lodash';
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton';
import Dialog from 'material-ui/Dialog';
import IconMenu from 'material-ui/IconMenu';
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert';
import MenuItem from 'material-ui/MenuItem';
import IconButton from 'material-ui/IconButton';
import LinearProgress from 'material-ui/LinearProgress';

import {setSnackBarParams} from './../../redux/modules/ui';
import {addFolder, listFolders} from './../../redux/modules/folder';
import AddFolderForm from './../../components/AddFolderForm/AddFolderForm';
import Pagination from './../../components/Pagination/Pagination';
import TopBar from './../../components/TopBar/TopBar';

import sortFolderContentFields from './../../main/helpers/sortFolderContentFields';
import injectF from './../../helpers/injectF';
import injectPush from './../../helpers/injectPush';
import resolve from './../../helpers/resolve';

const styles = require('./PageFolders.scss');

@connect(({folder}) => ({
  perpage: folder.get('perpage'),
  folders: folder.get('folders'),
  importingFolderId: folder.get('importingFolderId'),
  folderCount: folder.get('folderCount')
}), {listFolders, addFolder, setSnackBarParams})
@injectPush
@injectF
@resolve(({dispatch}, {perpage}) => {
  return dispatch(listFolders({page: 1, perpage}));
})
export default class PageFolders extends Component {

  static propTypes = {
    push: PropTypes.func.isRequired,
    f: PropTypes.func.isRequired,
    perpage: PropTypes.number.isRequired,
    addFolder: PropTypes.func.isRequired,
    folders: PropTypes.array.isRequired,
    folderCount: PropTypes.number.isRequired,
    listFolders: PropTypes.func.isRequired,
    importingFolderId: PropTypes.number,
    setSnackBarParams: PropTypes.func.isRequired
  };

  constructor(props) {
    super(props);
    this.state = {
      page: 1,
      targetLanguages: [],
      isAddFolderDialogOpen: false
    };
  }

  componentWillUpdate(nextProps, nextState) {
    const {page} = this.state;
    const {perpage, listFolders} = this.props;
    if ((page !== nextState.page) || (perpage !== nextProps.perpage)) {
      listFolders({
        page: nextState.page,
        perpage: nextProps.perpage
      });
    }
  }

  openAddFolderDialog = () => {
    this.setState({
      targetLanguages: [],
      isAddFolderDialogOpen: true
    });
  };

  handleAddFolderDialogClose = () => this.setState({isAddFolderDialogOpen: false});

  handleSubmit = async (data) => {

    const {page} = this.state;
    const {f, addFolder, listFolders,
      perpage, setSnackBarParams} = this.props;

    data.contentFields = sortFolderContentFields(data.contentFields);

    await addFolder(data);
    await listFolders({page, perpage});

    setSnackBarParams(true, f('folder-has-been-created', {folderName: data.folderName}));
    this.setState({isAddFolderDialogOpen: false});
  };

  handleCancelButtonTouchTap = () => this.setState({isAddFolderDialogOpen: false});

  handleTargetLanguagesChange = (rawData) => {
    const data = cloneDeep(rawData);
    delete data.preventDefault;
    this.setState({targetLanguages: Object.values(data)});
  };

  renderAddFolderDialog() {

    const {targetLanguages, isAddFolderDialogOpen} = this.state;
    const {f} = this.props;

    return (
      <Dialog title={f('add-a-folder')} open={isAddFolderDialogOpen}
        bodyStyle={{paddingLeft: '8px', paddingRight: '8px', paddingBottom: '8px'}} autoScrollBodyContent
        onRequestClose={this.handleAddFolderDialogClose}>
        <AddFolderForm ref="addFolderForm" onSubmit={this.handleSubmit} targetLanguages={targetLanguages}
          onTargetLanguagesChange={this.handleTargetLanguagesChange}
          onCancelButtonTouchTap={this.handleCancelButtonTouchTap} />
      </Dialog>
    );
  }

  handleFolderAnchorTouchTap = (folderId) => {
    return () => this.props.push(`/folders/${folderId}/entries`);
  };

  handleFolderMenuItemTouchTap = (event, value) => {
    const {type, id} = value;
    switch (type) {
      case 'edit':
        return this.props.push(`/folders/${id}/edit`);
      case 'export':
      default:
    }
  };

  renderFolders() {
    const {f, folders, importingFolderId} = this.props;
    const rows = folders.map((folder) => {
      const {id, name} = folder;
      const isImporting = (importingFolderId === folder.id);
      return (
        <Paper className={styles.folder} key={`paper-${id}`}>
          {isImporting && <LinearProgress mode="indeterminate" style={{marginBottom: '7px'}} />}
          {name}
          <IconMenu className={styles.folderIconMenu} style={{display: 'block', position: 'absolute'}}
            iconButtonElement={<IconButton><MoreVertIcon /></IconButton>}
            onChange={this.handleFolderMenuItemTouchTap}
            anchorOrigin={{horizontal: 'left', vertical: 'top'}}
            targetOrigin={{horizontal: 'left', vertical: 'top'}}>
            <MenuItem primaryText={f('edit')} value={{type: 'edit', id}} />
            <MenuItem primaryText={f('export')} value={{type: 'export', id}} />
          </IconMenu>
        </Paper>
      );
    });
    return
{rows}
;
  }

  handlePageButtonTouchTap = (page) => this.setState({page});

  render() {

    const {page} = this.state;
    const {f, perpage, folderCount} = this.props;

    return (

        <TopBar>

{f('folders')}

          <FlatButton icon={}
            label={f('add-folder')} primary onTouchTap={this.openAddFolderDialog} />
        </TopBar>
        {this.renderFolders()}
        {(folderCount > perpage) && <Pagination current={page} total={Math.ceil(folderCount / perpage)} onButtonTouchTap={this.handlePageButtonTouchTap} />}
        {this.renderAddFolderDialog()}

    );
  }
}
<|endoftext|>