<commit_before>/** @jsx React.DOM */

var React = require('react');
var Link = require('react-router').Link;
var EventStore = require('../../stores/EventStore');
var Time = require('../time');

var Feed = module.exports = React.createClass({

  getInitialState: function() {
    return {
      events: EventStore.all(),
      compressedMode: false
    };
  },

  update: function() {
    this.setState({events: EventStore.all()});
  },

  componentWillMount: function() {
    EventStore.fetch();
  },

  componentDidMount: function() {
    EventStore.addChangeListener(this.update);
  },

  componentWillUnmount: function() {
    EventStore.removeChangeListener(this.update);
  },

  toggleCompressedMode: function() {
    this.setState({compressedMode: !this.state.compressedMode});
  },

  render: function() {
    return (

Aktiviteter denne uken

        {this.state.events.slice(0,4).map(function(event) {
          return (
            <Link to='event' params={{eventId: event.id}} key={event.id}>

Noe med {event.name}

                  {event.description.slice(0, 140)}

                    <Time time={event.startsAt} format='MMMM Do YYYY, HH:mm' /> @ H3

            </Link>
          );
        })}

Aktiviterer senere

          {this.state.events.slice(4).map(function(event) {
            return (
              <Link to='event' params={{eventId: event.id}} key={event.id}>

Noe med {event.name}

                  {event.description.slice(0, 140)}

              </Link>
            );
          })}

    );
  }
});
<commit_msg>Add clock icon<commit_after>/** @jsx React.DOM */

var React = require('react');
var Link = require('react-router').Link;
var EventStore = require('../../stores/EventStore');
var Time = require('../time');
var Icon = require('../icon');

var Feed = module.exports = React.createClass({

  getInitialState: function() {
    return {
      events: EventStore.all(),
      compressedMode: false
    };
  },

  update: function() {
    this.setState({events: EventStore.all()});
  },

  componentWillMount: function() {
    EventStore.fetch();
  },

  componentDidMount: function() {
    EventStore.addChangeListener(this.update);
  },

  componentWillUnmount: function() {
    EventStore.removeChangeListener(this.update);
  },

  toggleCompressedMode: function() {
    this.setState({compressedMode: !this.state.compressedMode});
  },

  render: function() {
    return (

Aktiviteter denne uken

        {this.state.events.slice(0,4).map(function(event) {
          return (
            <Link to='event' params={{eventId: event.id}} key={event.id}>

Noe med {event.name}

                  {event.description.slice(0, 140)}

                    <Icon name='clock-o' /> <Time time={event.startsAt} format='MMMM Do YYYY, HH:mm' /> @ H3

            </Link>
          );
        })}

Aktiviterer senere

          {this.state.events.slice(4).map(function(event) {
            return (
              <Link to='event' params={{eventId: event.id}} key={event.id}>

Noe med {event.name}

                  {event.description.slice(0, 140)}

              </Link>
            );
          })}

    );
  }
});
<|endoftext|>


<commit_before>var Dropbox = require('../../../utils/nativeDropbox');
module.exports = {

	process : function(ctx, step, next) {
		var client = new Dropbox.DropBoxClient(step.token);
		// list folder
		var path = '/';
		console.log('dropbox listFolder path: ' + path);
		client.listFolder(path, function (result) {
            console.log('dropbox listFolder result: ');
			console.log(result);
		});
		setTimeout(next, 1);
	}
}<commit_msg>action listFolder step.path<commit_after>var Dropbox = require('../../../utils/nativeDropbox');
module.exports = {

	process : function(ctx, step, next) {
		var client = new Dropbox.DropBoxClient(step.token);
		// list folder
		var action = step.action;
		if(action == 'listFolder') {
			var path = step.path;
			console.log('dropbox listFolder path: ' + path);
			client.listFolder(path, function (result) {
				console.log('dropbox listFolder result: ');
				console.log(result);
			});
		}
		setTimeout(next, 1);
	}
}<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { FormControl } from 'react-bootstrap'
import _ from 'lodash'
import styled from 'styled-components'

import KontakteIntern from '../../containers/geschaeft/KontakteIntern'
import KontakteExtern from '../../containers/geschaeft/KontakteExtern'

const verwantwortlichOptions = (interneOptions) => {
  // sort interneOptions by kurzzeichen
  const interneOptionsSorted = _.sortBy(interneOptions, o => {
    const sort = `${o.name || 'zz'} ${o.vorname || 'zz'} (${o.kurzzeichen})`
    return sort.toLowerCase()
  })
  const options = interneOptionsSorted.map((o) => {
    const name = `${o.name || '(kein Name)'} ${o.vorname || '(kein Vorname)'} (${o.kurzzeichen})`
    return (
      <option
        key={o.id}
        value={o.kurzzeichen}
      >
        {name}
      </option>
    )
  })
  options.unshift(<option key={0} value="" />)
  return options
}

const verantwortlichData = (geschaeft, interneOptions) => {
  const data = interneOptions.find(o =>
    o.kurzzeichen === geschaeft.verantwortlich
  )
  if (!data) return ''
  const abt = data.abteilung ? `${data.abteilung}` : ''
  const emailHtml = (
    <a
      href={`mailto:${data.eMail}`}
    >
      {data.eMail}

  )
  const telefon = data.telefon ? `, ${data.telefon}` : ''
  if (data.eMail) {
    return (
      {`${abt}, `}{emailHtml}{`${telefon}`}
    )
  }
  return {`${abt}${telefon}`}
}

const AreaPersonen = ({
  geschaeft,
  nrOfFieldsBeforePersonen = 0,
  change,
  blur,
  interneOptions,
  isPrintPreview,
}) => {
  const Container = styled.div`
    grid-area: areaPersonen;
    background-color: ${isPrintPreview ? 'inherit' : 'rgb(246, 255, 245)'};
    border: ${isPrintPreview ? '1px solid #CCC' : 'inherit'};
  `
  const AreaPersonenDiv = styled.div`
    background-color: ${isPrintPreview ? 'inherit' : 'rgb(246, 255, 245)'};
    display: grid;
    grid-template-columns: ${isPrintPreview ? 'inherit' : '260px calc((100% - 10px) - 260px)'};
    grid-column-gap: 10px;
    grid-row-gap: 2px;
    padding: 8px;
    align-items: end;
  `
  const Title = styled.div`
    font-weight: 900;
    font-size: ${isPrintPreview ? '16px' : '16px'};
    grid-column: 1 / span 2;
  `
  const Subtitle = styled.div`
    font-weight: 900;
    font-size: ${isPrintPreview ? '10px' : '12px'};
    margin-top: 5px;
  `
  const SubTitle = styled(Subtitle)`
    grid-column: 1 / span 2;
  `
  const Verantwortlich = styled.div`
    grid-column: 1 / span 1;
    display: ${isPrintPreview ? 'none' : 'inherit'}
  `
  const VerantwortlichName = styled.div`
    grid-column: ${isPrintPreview ? '1 / span 1' : '2 / span 1'};
  `

  return (
    <Container>
      <AreaPersonenDiv>
        <Title>
          Personen
        </Title>
        <SubTitle>
          Verantwortlich
        </SubTitle>
        <Verantwortlich>
          <FormControl
            componentClass="select"
            value={geschaeft.verantwortlich || ''}
            name="verantwortlich"
            onChange={change}
            onBlur={blur}
            bsSize="small"
            tabIndex={1 + nrOfFieldsBeforePersonen}
          >
            {verwantwortlichOptions(interneOptions)}
          </FormControl>
        </Verantwortlich>
        <VerantwortlichName>
          <FormControl.Static>
            {verantwortlichData(geschaeft, interneOptions)}
          </FormControl.Static>
        </VerantwortlichName>
        <SubTitle>
          Interne Kontakte
        </SubTitle>
        <KontakteIntern
          tabIndex={nrOfFieldsBeforePersonen + 1}
        />
        <SubTitle>
          Externe Kontakte
        </SubTitle>
        <KontakteExtern
          tabIndex={nrOfFieldsBeforePersonen + 2}
        />
      </AreaPersonenDiv>
    </Container>
  )
}

AreaPersonen.displayName = 'AreaPersonen'

/**
 * do not make options required
 * as they may be loaded after the component
 */
AreaPersonen.propTypes = {
  geschaeft: PropTypes.object.isRequired,
  interneOptions: PropTypes.array,
  nrOfFieldsBeforePersonen: PropTypes.number.isRequired,
  change: PropTypes.func.isRequired,
  blur: PropTypes.func.isRequired,
  isPrintPreview: PropTypes.bool.isRequired,
}

export default AreaPersonen
<commit_msg>style pdf<commit_after>import React, { PropTypes } from 'react'
import { FormControl } from 'react-bootstrap'
import _ from 'lodash'
import styled from 'styled-components'

import KontakteIntern from '../../containers/geschaeft/KontakteIntern'
import KontakteExtern from '../../containers/geschaeft/KontakteExtern'

const verwantwortlichOptions = (interneOptions) => {
  // sort interneOptions by kurzzeichen
  const interneOptionsSorted = _.sortBy(interneOptions, o => {
    const sort = `${o.name || 'zz'} ${o.vorname || 'zz'} (${o.kurzzeichen})`
    return sort.toLowerCase()
  })
  const options = interneOptionsSorted.map((o) => {
    const name = `${o.name || '(kein Name)'} ${o.vorname || '(kein Vorname)'} (${o.kurzzeichen})`
    return (
      <option
        key={o.id}
        value={o.kurzzeichen}
      >
        {name}
      </option>
    )
  })
  options.unshift(<option key={0} value="" />)
  return options
}

const verantwortlichData = (geschaeft, interneOptions, isPrintPreview) => {
  const data = interneOptions.find(o =>
    o.kurzzeichen === geschaeft.verantwortlich
  )
  if (!data) return ''
  let name = ''
  if (isPrintPreview) {
    name = `${data.name || '(kein Name)'} ${data.vorname || '(kein Vorname)'}, `
  }
  const abt = data.abteilung ? `${data.abteilung}` : ''
  const emailHtml = (
    <a
      href={`mailto:${data.eMail}`}
    >
      {data.eMail}

  )
  const telefon = data.telefon ? `, ${data.telefon}` : ''
  if (data.eMail) {
    return (
      {`${name}${abt}, `}{emailHtml}{`${telefon}`}
    )
  }
  return {`${name}${abt}${telefon}`}
}

const AreaPersonen = ({
  geschaeft,
  nrOfFieldsBeforePersonen = 0,
  change,
  blur,
  interneOptions,
  isPrintPreview,
}) => {
  const Container = styled.div`
    grid-area: areaPersonen;
    background-color: ${isPrintPreview ? 'inherit' : 'rgb(246, 255, 245)'};
    border: ${isPrintPreview ? '1px solid #CCC' : 'inherit'};
  `
  const AreaPersonenDiv = styled.div`
    background-color: ${isPrintPreview ? 'inherit' : 'rgb(246, 255, 245)'};
    display: grid;
    grid-template-columns: ${isPrintPreview ? '100%' : '260px calc((100% - 10px) - 260px)'};
    grid-column-gap: 10px;
    grid-row-gap: 2px;
    padding: 8px;
    align-items: ${isPrintPreview ? 'flex-start' : 'end'};
  `
  const Title = styled.div`
    font-weight: 900;
    font-size: ${isPrintPreview ? '16px' : '16px'};
    grid-column: 1 / span 2;
  `
  const Subtitle = styled.div`
    font-weight: 900;
    font-size: ${isPrintPreview ? '10px' : '12px'};
    margin-top: 5px;
  `
  const SubTitle = styled(Subtitle)`
    grid-column: ${isPrintPreview ? '1' : '1 / span 2'};
  `
  const Verantwortlich = styled.div`
    grid-column: ${isPrintPreview ? '1' : '1 / span 1'};
    display: ${isPrintPreview ? 'none' : 'inherit'}
  `
  const VerantwortlichName = styled.div`
    grid-column: ${isPrintPreview ? '1' : '2 / span 1'};
  `

  return (
    <Container>
      <AreaPersonenDiv>
        <Title>
          Personen
        </Title>
        <SubTitle>
          Verantwortlich
        </SubTitle>
        <Verantwortlich>
          <FormControl
            componentClass="select"
            value={geschaeft.verantwortlich || ''}
            name="verantwortlich"
            onChange={change}
            onBlur={blur}
            bsSize="small"
            tabIndex={1 + nrOfFieldsBeforePersonen}
          >
            {verwantwortlichOptions(interneOptions)}
          </FormControl>
        </Verantwortlich>
        <VerantwortlichName>
          <FormControl.Static>
            {verantwortlichData(geschaeft, interneOptions, isPrintPreview)}
          </FormControl.Static>
        </VerantwortlichName>
        <SubTitle>
          Interne Kontakte
        </SubTitle>
        <KontakteIntern
          tabIndex={nrOfFieldsBeforePersonen + 1}
        />
        <SubTitle>
          Externe Kontakte
        </SubTitle>
        <KontakteExtern
          tabIndex={nrOfFieldsBeforePersonen + 2}
        />
      </AreaPersonenDiv>
    </Container>
  )
}

AreaPersonen.displayName = 'AreaPersonen'

/**
 * do not make options required
 * as they may be loaded after the component
 */
AreaPersonen.propTypes = {
  geschaeft: PropTypes.object.isRequired,
  interneOptions: PropTypes.array,
  nrOfFieldsBeforePersonen: PropTypes.number.isRequired,
  change: PropTypes.func.isRequired,
  blur: PropTypes.func.isRequired,
  isPrintPreview: PropTypes.bool.isRequired,
}

export default AreaPersonen
<|endoftext|>


<commit_before>import Ember from 'ember';
import NewOrEdit from 'ui/mixins/new-or-edit';

const HOSTNAME = 'externalhostname';
const IP = 'externalip';
const ALIAS = 'dnsservice';
const SELECTOR = 'selectorservice';

function modeToType(mode) {
  if ( mode === HOSTNAME || mode === IP ) {
    return 'externalservice';
  } else {
    return mode;
  }
}

export default Ember.Component.extend(NewOrEdit, {
  intl: Ember.inject.service(),

  record: null,
  editing: true,

  primaryResource: Ember.computed.alias('record'),

  mode: null,
  targetServicesAsMaps: null,
  targetIpArray: null,
  stack: null,
  stackErrors: null,

  actions: {
    done() {
      this.sendAction('done');
    },

    cancel() {
      this.sendAction('cancel');
    },

    setTargetServices(array, resources) {
      let store = this.get('store');
      this.set('record.serviceLinks', resources.map((r) => {
        return store.createRecord({
          type: 'link',
          name: r.serviceName,
        });
      }));
    },

    addTargetIp() {
      this.get('targetIpArray').pushObject({value: null});
    },

    removeTargetIp(obj) {
      this.get('targetIpArray').removeObject(obj);
    },
  },

  expand(item) {
    item.toggleProperty('expanded');
  },

  init() {
    this._super(...arguments);
    let record = this.get('originalModel').clone();
    let type = record.get('type').toLowerCase();
    let mode = type;

    if ( type === 'externalservice' ) {
      if ( record.get('hostname') ) {
        mode = HOSTNAME;
      } else {
        mode = IP;
      }
    }

    this.setProperties({
      record: record,
      mode: mode,
      targetServicesAsMaps: [], // Set by form-targets
      targetIpArray: (record.externalIpAddresses||[]).map((ip) => { return {value: ip}; }),
    });
  },

  canHealthCheck: function() {
    let mode = this.get('mode');
    return (mode === IP) || (mode === HOSTNAME);
  }.property('mode'),

  modeChanged: function() {
    let mode = this.get('mode');
    let type = modeToType(mode);
    let neu = this.get('store').createRecord(this.get('record').serialize(), {type: type});
    neu.set('type', type);
    this.set('record', neu);
  }.observes('mode'),

  targetIpArrayChanged: function() {
    this.set('record.externalIpAddresses', this.get('targetIpArray').map((x) => x.value).filter((x) => !!x));
  }.observes('targetIpArray.@each.value'),

  validate() {
    this._super(...arguments);
    let errors = this.get('errors')||[];

    switch ( this.get('mode') ) {
      case HOSTNAME:
        if ( !this.get('record.hostname') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.hostnameRequired'));
        }
        break;
      case ALIAS:
        if ( !this.get('targetServicesAsMaps.length') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.serviceRequired'));
        }
        break;
      case IP:
        if ( !this.get('record.externalIpAddresses.length') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.ipRequired'));
        }
        break;
      case SELECTOR:
        if ( !this.get('record.selector.length') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.selectorRequired'));
        }
        break;
    }

    errors.pushObjects(this.get('stackErrors')||[]);

    this.set('errors', errors);
    return errors.length === 0;
  },

  willSave() {
    if ( this.get('mode') === IP ) {
      this.set('record.hostname', null);
    } else if ( this.get('mode') === HOSTNAME ) {
      this.set('record.externalIpAddresses', null);
    }

    if ( !this.get('id') ) {
      // Set the stack ID
      if ( this.get('stack.id') ) {
        this.set('record.stackId', this.get('stack.id'));
      } else if ( this.get('stack') ) {
        return this.get('stack').save().then((newStack) => {
          this.set('record.stackId', newStack.get('id'));
        });
      }
    }

    return this._super(...arguments);
  },

  doneSaving() {
    this.send('cancel');
  },
});
<commit_msg>Focus DNS IP after clicking add<commit_after>import Ember from 'ember';
import NewOrEdit from 'ui/mixins/new-or-edit';

const HOSTNAME = 'externalhostname';
const IP = 'externalip';
const ALIAS = 'dnsservice';
const SELECTOR = 'selectorservice';

function modeToType(mode) {
  if ( mode === HOSTNAME || mode === IP ) {
    return 'externalservice';
  } else {
    return mode;
  }
}

export default Ember.Component.extend(NewOrEdit, {
  intl: Ember.inject.service(),

  record: null,
  editing: true,

  primaryResource: Ember.computed.alias('record'),

  mode: null,
  targetServicesAsMaps: null,
  targetIpArray: null,
  stack: null,
  stackErrors: null,

  actions: {
    done() {
      this.sendAction('done');
    },

    cancel() {
      this.sendAction('cancel');
    },

    setTargetServices(array, resources) {
      let store = this.get('store');
      this.set('record.serviceLinks', resources.map((r) => {
        return store.createRecord({
          type: 'link',
          name: r.serviceName,
        });
      }));
    },

    addTargetIp() {
      this.get('targetIpArray').pushObject({value: null});
      Ember.run.next(() => {
        this.$('.target-ip').last()[0].focus();
      });
    },

    removeTargetIp(obj) {
      this.get('targetIpArray').removeObject(obj);
    },
  },

  expand(item) {
    item.toggleProperty('expanded');
  },

  init() {
    this._super(...arguments);
    let record = this.get('originalModel').clone();
    let type = record.get('type').toLowerCase();
    let mode = type;

    if ( type === 'externalservice' ) {
      if ( record.get('hostname') ) {
        mode = HOSTNAME;
      } else {
        mode = IP;
      }
    }

    this.setProperties({
      record: record,
      mode: mode,
      targetServicesAsMaps: [], // Set by form-targets
      targetIpArray: (record.externalIpAddresses||[]).map((ip) => { return {value: ip}; }),
    });
  },

  canHealthCheck: function() {
    let mode = this.get('mode');
    return (mode === IP) || (mode === HOSTNAME);
  }.property('mode'),

  modeChanged: function() {
    let mode = this.get('mode');
    let type = modeToType(mode);
    let neu = this.get('store').createRecord(this.get('record').serialize(), {type: type});
    neu.set('type', type);
    this.set('record', neu);
  }.observes('mode'),

  targetIpArrayChanged: function() {
    this.set('record.externalIpAddresses', this.get('targetIpArray').map((x) => x.value).filter((x) => !!x));
  }.observes('targetIpArray.@each.value'),

  validate() {
    this._super(...arguments);
    let errors = this.get('errors')||[];

    switch ( this.get('mode') ) {
      case HOSTNAME:
        if ( !this.get('record.hostname') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.hostnameRequired'));
        }
        break;
      case ALIAS:
        if ( !this.get('targetServicesAsMaps.length') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.serviceRequired'));
        }
        break;
      case IP:
        if ( !this.get('record.externalIpAddresses.length') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.ipRequired'));
        }
        break;
      case SELECTOR:
        if ( !this.get('record.selector.length') ) {
          errors.pushObject(this.get('intl').t('editDns.errors.selectorRequired'));
        }
        break;
    }

    errors.pushObjects(this.get('stackErrors')||[]);

    this.set('errors', errors);
    return errors.length === 0;
  },

  willSave() {
    if ( this.get('mode') === IP ) {
      this.set('record.hostname', null);
    } else if ( this.get('mode') === HOSTNAME ) {
      this.set('record.externalIpAddresses', null);
    }

    if ( !this.get('id') ) {
      // Set the stack ID
      if ( this.get('stack.id') ) {
        this.set('record.stackId', this.get('stack.id'));
      } else if ( this.get('stack') ) {
        return this.get('stack').save().then((newStack) => {
          this.set('record.stackId', newStack.get('id'));
        });
      }
    }

    return this._super(...arguments);
  },

  doneSaving() {
    this.send('cancel');
  },
});
<|endoftext|>


<commit_before>// @flow
import React, {Component} from 'react'
import {findDOMNode} from 'react-dom'
import styled, {keyframes} from 'styled-components'
import CloseButton from 'components/common/CloseButton'
import Wrapper from './LazyImgWrapper'

type Size = {
	width: number | 'auto',
	height: number | 'auto'
}

function calcSize(width: number, height: number): Size {
	const {innerWidth, innerHeight} = window
	if (height > innerHeight && width > innerWidth) {
		return (width * innerHeight < height * innerWidth) ?
			{width: 'auto', height: innerHeight} :
			{
				width: innerWidth,
				height: 'auto',
			}
	}
	if (height > innerHeight) {
		return {width: 'auto', height: innerHeight}
	}
	if (width > innerWidth) {
		return {width: innerWidth, height: 'auto'}
	}

	return {width, height}
}

type Props = {
	from: string,
	to: string,
	width: number,
	height: number,
	isLoaded: bool,
	onLoad: () => void,
	onClose: () => void
}

type State = {
	isClicked: bool,
	fromMarginTop: number,
	toMarginTop: number
}

export default class LazyImg extends Component {
	props: Props;
	to: Component<*, *, *>
	from: Component<*, *, *>
	state: State = {
		isClicked: false,
		fromMarginTop: 0,
		toMarginTop: 0,
	};

	componentDidMount() {
		const to = this.calcMarginTop(findDOMNode(this.to))
		const from = this.calcMarginTop(findDOMNode(this.from))
		this.setState({
			toMarginTop: to,
			fromMarginTop: from,
		})
	}

	componentWillUpdate(nextProps: Props, nextState: State) {
		const to = this.calcMarginTop(findDOMNode(this.to))
		const from = this.calcMarginTop(findDOMNode(this.from))
		if (
			this.props.isLoaded !== nextProps.isLoaded ||
			nextState.isClicked !== this.state.isClicked ||
			nextState.fromMarginTop !== from ||
			nextState.toMarginTop !== to
		) {
			this.setState({
				toMarginTop: to,
				fromMarginTop: from,
			})
		}
	}

	handleLoad = () => {
		const img = new Image()
		const {to, onLoad} = this.props
		img.onload = () => {
			onLoad()
		}
		img.src = to
	}

	calcMarginTop(node: HTMLElement): number {
		if (node) {
			const height = node && node.clientHeight
			if (window.innerHeight > height) {
				const top = (window.innerHeight - height) / 2
				return top
			}
		}
		return 0
	}

	handleClick = (event: SyntheticEvent) => { // eslint-disable-line no-undef
		event.stopPropagation()
		this.setState({isClicked: !this.state.isClicked})
	}

	render() {
		const {width, height, isLoaded, onClose} = this.props
		const {isClicked} = this.state
		const fromStyle = calcSize(width, height)

		if (isLoaded) {
			return (
				<Wrapper>
					<CloseButton
						style={{color: '#676767', top: '10px', right: '10px'}}
						iconStyle={{fill: 'white'}}
						onClick={onClose}
						/>
					<Img
						src={this.props.to}
						width={width}
						height={height}
						marginTop={this.state.toMarginTop}
						isClicked={isClicked}
						onClick={this.handleClick}
						ref={c => { // eslint-disable-line react/jsx-no-bind
							this.to = c
						}}
						/>
				</Wrapper>
			)
		}

		return (
			<Wrapper>
				<CloseButton onClick={onClose} iconStyle={{fill: 'white'}}/>
				<FromImg
					src={this.props.from}
					marginTop={this.state.fromMarginTop}
					style={fromStyle}
					onLoad={this.handleLoad}
					ref={c => { // eslint-disable-line react/jsx-no-bind
						this.from = c
					}}
					/>
			</Wrapper>
		)
	}
}

const FromImg = styled.img`
	width: auto;
	height: auto;
	max-width: 100vw;
	max-height: 100vh;
	margin: auto;
	margin-top: ${props => props.marginTop}px;
	user-select: none;
	cursor: wait;
`

const fadeIn = keyframes`
	0% {
		filter: blur(1px);
	}

	100% {
		filter: none;
	}
`

const Img = styled.img`
	width: auto;
	height: auto;
	margin: auto;
	margin-top: ${props => props.marginTop}px;
	max-width: ${props => props.isClicked ? 'none' : '100vw'};
	max-height: ${props => props.isClicked ? 'none' : '100vh'};
	cursor: ${props => props.isClicked ? 'zoom-out' : 'zoom-in'};
	animation: ${fadeIn} 600ms forwards;
	user-select: none;
`
<commit_msg>Fix lint error<commit_after>// @flow
import React, {Component} from 'react'
import {findDOMNode} from 'react-dom'
import styled, {keyframes} from 'styled-components'
import CloseButton from 'components/common/CloseButton'
import Wrapper from './LazyImgWrapper'

type Size = {
	width: number | 'auto',
	height: number | 'auto'
}

function calcSize(width: number, height: number): Size {
	const {innerWidth, innerHeight} = window
	if (height > innerHeight && width > innerWidth) {
		return (width * innerHeight < height * innerWidth) ?
			{width: 'auto', height: innerHeight} :
		{
			width: innerWidth,
			height: 'auto',
		}
	}
	if (height > innerHeight) {
		return {width: 'auto', height: innerHeight}
	}
	if (width > innerWidth) {
		return {width: innerWidth, height: 'auto'}
	}

	return {width, height}
}

type Props = {
	from: string,
	to: string,
	width: number,
	height: number,
	isLoaded: bool,
	onLoad: () => void,
	onClose: () => void
}

type State = {
	isClicked: bool,
	fromMarginTop: number,
	toMarginTop: number
}

export default class LazyImg extends Component {
	props: Props;
	to: Component<*, *, *>
	from: Component<*, *, *>
	state: State = {
		isClicked: false,
		fromMarginTop: 0,
		toMarginTop: 0,
	};

	componentDidMount() {
		const to = this.calcMarginTop(findDOMNode(this.to))
		const from = this.calcMarginTop(findDOMNode(this.from))
		this.setState({
			toMarginTop: to,
			fromMarginTop: from,
		})
	}

	componentWillUpdate(nextProps: Props, nextState: State) {
		const to = this.calcMarginTop(findDOMNode(this.to))
		const from = this.calcMarginTop(findDOMNode(this.from))
		if (
			this.props.isLoaded !== nextProps.isLoaded ||
			nextState.isClicked !== this.state.isClicked ||
			nextState.fromMarginTop !== from ||
			nextState.toMarginTop !== to
		) {
			this.setState({
				toMarginTop: to,
				fromMarginTop: from,
			})
		}
	}

	handleLoad = () => {
		const img = new Image()
		const {to, onLoad} = this.props
		img.onload = () => {
			onLoad()
		}
		img.src = to
	}

	calcMarginTop(node: HTMLElement): number {
		if (node) {
			const height = node && node.clientHeight
			if (window.innerHeight > height) {
				const top = (window.innerHeight - height) / 2
				return top
			}
		}
		return 0
	}

	handleClick = (event: SyntheticEvent) => { // eslint-disable-line no-undef
		event.stopPropagation()
		this.setState({isClicked: !this.state.isClicked})
	}

	render() {
		const {width, height, isLoaded, onClose} = this.props
		const {isClicked} = this.state
		const fromStyle = calcSize(width, height)

		if (isLoaded) {
			return (
				<Wrapper>
					<CloseButton
						style={{color: '#676767', top: '10px', right: '10px'}}
						iconStyle={{fill: 'white'}}
						onClick={onClose}
						/>
					<Img
						src={this.props.to}
						width={width}
						height={height}
						marginTop={this.state.toMarginTop}
						isClicked={isClicked}
						onClick={this.handleClick}
						ref={c => { // eslint-disable-line react/jsx-no-bind
							this.to = c
						}}
						/>
				</Wrapper>
			)
		}

		return (
			<Wrapper>
				<CloseButton onClick={onClose} iconStyle={{fill: 'white'}}/>
				<FromImg
					src={this.props.from}
					marginTop={this.state.fromMarginTop}
					style={fromStyle}
					onLoad={this.handleLoad}
					ref={c => { // eslint-disable-line react/jsx-no-bind
						this.from = c
					}}
					/>
			</Wrapper>
		)
	}
}

const FromImg = styled.img`
	width: auto;
	height: auto;
	max-width: 100vw;
	max-height: 100vh;
	margin: auto;
	margin-top: ${props => props.marginTop}px;
	user-select: none;
	cursor: wait;
`

const fadeIn = keyframes`
	0% {
		filter: blur(1px);
	}

	100% {
		filter: none;
	}
`

const Img = styled.img`
	width: auto;
	height: auto;
	margin: auto;
	margin-top: ${props => props.marginTop}px;
	max-width: ${props => props.isClicked ? 'none' : '100vw'};
	max-height: ${props => props.isClicked ? 'none' : '100vh'};
	cursor: ${props => props.isClicked ? 'zoom-out' : 'zoom-in'};
	animation: ${fadeIn} 600ms forwards;
	user-select: none;
`
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Component.extend({
  store: Ember.inject.service(),
  apiCall : Ember.inject.service('api-call'),
  taleInstanceName : "",
  numberOfModels: 0,
  pageNumber: 1,
  totalPages:1,
  leftButtonState: "disabled",
  rightButtonState: "disabled",
  lastAnimationTime : 0,
  animationRefreshTime : 500, // min ms time between animation refreshes
  item : null,
  guid : null,
  init() {
    this._super(...arguments);
    console.log("Attributes updated");

    var modelsPromised = this.get("models");

    var component = this;

    modelsPromised.then(function(models) {
      if (component.get('addButtonName') != null){
        var paginateSize = Number(component.get('paginateOn'));
        component.set('paginateOn', paginateSize);
      }
      component.paginate(component, models);
    });

    this.set('addButtonLogo', '/icons/plus-sign.png');
  },
  didRender() {
    $('.selectable.cards .image').dimmer({
      on: 'hover'
    });
  },
  didUpdate() {

    var guid = this.get('guid');

    if (guid ==null) {
      guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
      this.set('guid', guid);
    }

    var d = new Date();
    var milliseconds = d.getTime();
    var lastMSTime = Number(this.get('lastAnimationTime'));

 //   console.log("MS: " + milliseconds );
   // console.log("Last MS: " + lastMSTime);
  //  console.log("Diff: " + (milliseconds-lastMSTime));
    //console.log("GUID: " + guid);

    if (milliseconds-lastMSTime > Number(this.get('animationRefreshTime'))) {
      $('.selectable.cards.' + guid + ' .image img')
        .transition('jiggle')
      ;
      this.set('lastAnimationTime', milliseconds);
    }

  },

  paginate(component, models) {

    var paginateSize = component.get('paginateOn');
    var pageNumber = component.get('pageNumber');
    var arraySize = models.get('length');

    var numberToShow = arraySize % paginateSize;
    var totalPages = arraySize / paginateSize;
    if (numberToShow>0)
      ++totalPages;

  //  console.log(models);
    component.set('numberOfModels', arraySize);

    //console.log("Number of models = " + component.get('numberOfModels'));
    if (models.get('length') === 0) return;

    component.set('totalPages', totalPages);

    //console.log("Paginating on = " + paginateSize);
    //console.log("NumberToShow = " + numberToShow);

    var modelsInView = [];
    var paginateArray = [];

    for (var i=1; i<=totalPages; ++i) {
      if (i==pageNumber)
        paginateArray[i] = {number: i, state: "active"};
      else
        paginateArray[i] = {number: i, state: ""};
    }

    component.set("paginateArray", paginateArray);

    var startingPosition = (pageNumber-1)*paginateSize;
    var endingPosition = ((pageNumber-1)*paginateSize)+paginateSize;
    var iterateNumber=0;

    if (pageNumber == 1)
      component.set('leftButtonState', "disabled");
    else
      component.set('leftButtonState', "");

    if (pageNumber == totalPages)
      component.set('rightButtonState', "disabled");
    else
      component.set('rightButtonState', "");

    models.forEach(function(model){
      if ((iterateNumber>=startingPosition) && (iterateNumber<endingPosition)) {
    //    console.log("Icon field is--" + model.get("icon") + "--");
        if (typeof model.get("icon") === "undefined" ) {
          if (typeof model.get("meta") !== "undefined") {
            var meta = model.get("meta");
      //      console.log("Checking meta fields: " + meta);
            if (meta['provider'] !== "DataONE")
              model['icon'] = "/icons/globus-logo-large.png";
            else
              model['icon'] = "/icons/d1-logo-large.png";
          } else {
            model['icon'] = "/images/whole_tale_logo.png";
          }
        }
        var title = model.get('title');

        var description = model.get('description');

        if ((description == null) ) {
          model.set('tagName', "No Description ...");
        } else {
          if (description.length > 200)
            model.set('tagName', description.substring(0,200) + "..");
          else
            model.set('tagName', description);
        }

        modelsInView.push(model);
      }

      ++iterateNumber;
    });

    component.set("modelsInView", modelsInView);

    //console.log(this.get("modelsInView"));

  },
  actions: {
    leftButtonClicked : function() {
      if (this.get('leftButtonState') === "disabled") return;
      this.set('pageNumber', this.get('pageNumber') -1);
      this.paginate(this, this.get('models'));
    },
    rightButtonClicked : function() {
      if (this.get('rightButtonState') === "disabled") return;
      this.set('pageNumber', this.get('pageNumber') +1);
      this.paginate(this, this.get('models'));
    },
    tabClicked : function(tabNumber) {
      // alert("Clicked " + tabNumber)
      this.set('pageNumber', tabNumber);
      this.paginate(this, this.get('models'));
    },
    searchFilter : function () {
      var searchStr = this.get('searchStr');
    //  console.log(searchStr);

      var modelsPromised = this.get("models");

      var component = this;

      modelsPromised.then(function(models) {
        var searchView = [];
        models.forEach(function(model) {
          var title = model.get('title');

          if (new RegExp(searchStr, "i").test(title))
              searchView.push(model);
        });

        component.paginate(component, searchView);
      });

    },
    select : function (model) {
      this.set('item', model);
      this.sendAction('action', model); // sends to compose.js controller, action itemSelected, based on template spec.
    },

    openDeleteModal: function(id) {
      var selector = '.ui.' + id + '.modal';
      console.log("Selector: " +  selector);
      $(selector).modal('show');
    },

    approveDelete: function(model) {
      console.log("Deleting model " + model.name);
      var component = this;

      model.destroyRecord({ reload: true }).then( function () {
        // refresh
//        component.get('store').findAll('tale', { reload: true }).then(function(tales) {
          component.paginate(component, component.get('models'));
  //      });
      });

      return false;
    },

    denyDelete: function() {
      return true;
    },

    addNew: function() {
        this.sendAction("onAddNew");
    },

    launchTale: function (tale) {
      var component = this;

      component.set("tale_instantiating_id", tale.id);
      component.set("tale_instantiating", true);

      var onSuccess = function(item) {
        console.log(item);
        component.set("tale_instantiating", false);
        component.set("tale_instantiated", true);

        var instance = Ember.Object.create(JSON.parse(item));

        component.set("instance", instance);

        Ember.run.later((function() {
          component.set("tale_instantiated", false);
        }), 30000);
      };

      var onFail = function(item) {
        // deal with the failure here
        component.set("tale_instantiating", false);
        component.set("tale_not_instantiated", true);
        item = JSON.parse(item);

        console.log(item);
        component.set("error_msg", item.message);

        Ember.run.later((function() {
          component.set("tale_not_instantiated", false);
        }), 10000);

      };

      // submit: API
      // httpCommand, taleid, imageId, folderId, instanceId, name, description, isPublic, config

      this.get("apiCall").postInstance(
        tale.get("_id"),
        tale.get("imageId"),
        null,
        onSuccess,
        onFail);
    },
  }
});
<commit_msg>Fixed search in tales page - when switching pages keep same search filter<commit_after>import Ember from 'ember';

export default Ember.Component.extend({
  store: Ember.inject.service(),
  apiCall : Ember.inject.service('api-call'),
  taleInstanceName : "",
  numberOfModels: 0,
  pageNumber: 1,
  totalPages:1,
  leftButtonState: "disabled",
  rightButtonState: "disabled",
  lastAnimationTime : 0,
  animationRefreshTime : 500, // min ms time between animation refreshes
  item : null,
  guid : null,
  init() {
    this._super(...arguments);
    console.log("Attributes updated");

    var modelsPromised = this.get("models");

    var component = this;

    modelsPromised.then(function(models) {
      if (component.get('addButtonName') != null){
        var paginateSize = Number(component.get('paginateOn'));
        component.set('paginateOn', paginateSize);
      }
      component.set('searchView', models);
      component.paginate(component, models);
    });

    this.set('addButtonLogo', '/icons/plus-sign.png');
  },
  didRender() {
    $('.selectable.cards .image').dimmer({
      on: 'hover'
    });
  },
  didUpdate() {

    var guid = this.get('guid');

    if (guid ==null) {
      guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
      this.set('guid', guid);
    }

    var d = new Date();
    var milliseconds = d.getTime();
    var lastMSTime = Number(this.get('lastAnimationTime'));

 //   console.log("MS: " + milliseconds );
   // console.log("Last MS: " + lastMSTime);
  //  console.log("Diff: " + (milliseconds-lastMSTime));
    //console.log("GUID: " + guid);

    if (milliseconds-lastMSTime > Number(this.get('animationRefreshTime'))) {
      $('.selectable.cards.' + guid + ' .image img')
        .transition('jiggle')
      ;
      this.set('lastAnimationTime', milliseconds);
    }

  },

  paginate(component, models) {

    var paginateSize = component.get('paginateOn');
    var pageNumber = component.get('pageNumber');
    var arraySize = models.get('length');

    var numberToShow = arraySize % paginateSize;
    var totalPages = arraySize / paginateSize;
    if (numberToShow>0)
      ++totalPages;

  //  console.log(models);
    component.set('numberOfModels', arraySize);

    //console.log("Number of models = " + component.get('numberOfModels'));
    if (models.get('length') === 0) return;

    component.set('totalPages', totalPages);

    //console.log("Paginating on = " + paginateSize);
    //console.log("NumberToShow = " + numberToShow);

    var modelsInView = [];
    var paginateArray = [];

    for (var i=1; i<=totalPages; ++i) {
      if (i==pageNumber)
        paginateArray[i] = {number: i, state: "active"};
      else
        paginateArray[i] = {number: i, state: ""};
    }

    component.set("paginateArray", paginateArray);

    var startingPosition = (pageNumber-1)*paginateSize;
    var endingPosition = ((pageNumber-1)*paginateSize)+paginateSize;
    var iterateNumber=0;

    if (pageNumber == 1)
      component.set('leftButtonState', "disabled");
    else
      component.set('leftButtonState', "");

    if (pageNumber == totalPages)
      component.set('rightButtonState', "disabled");
    else
      component.set('rightButtonState', "");

    models.forEach(function(model){
      if ((iterateNumber>=startingPosition) && (iterateNumber<endingPosition)) {
    //    console.log("Icon field is--" + model.get("icon") + "--");
        if (typeof model.get("icon") === "undefined" ) {
          if (typeof model.get("meta") !== "undefined") {
            var meta = model.get("meta");
      //      console.log("Checking meta fields: " + meta);
            if (meta['provider'] !== "DataONE")
              model['icon'] = "/icons/globus-logo-large.png";
            else
              model['icon'] = "/icons/d1-logo-large.png";
          } else {
            model['icon'] = "/images/whole_tale_logo.png";
          }
        }
        var title = model.get('title');

        var description = model.get('description');

        if ((description == null) ) {
          model.set('tagName', "No Description ...");
        } else {
          if (description.length > 200)
            model.set('tagName', description.substring(0,200) + "..");
          else
            model.set('tagName', description);
        }

        modelsInView.push(model);
      }

      ++iterateNumber;
    });

    component.set("modelsInView", modelsInView);

    //console.log(this.get("modelsInView"));

  },
  actions: {
    leftButtonClicked : function() {
      if (this.get('leftButtonState') === "disabled") return;
      this.set('pageNumber', this.get('pageNumber') -1);
      this.paginate(this, this.get('searchView'));
    },
    rightButtonClicked : function() {
      if (this.get('rightButtonState') === "disabled") return;
      this.set('pageNumber', this.get('pageNumber') +1);
      this.paginate(this, this.get('searchView'));
    },
    tabClicked : function(tabNumber) {
      // alert("Clicked " + tabNumber)
      this.set('pageNumber', tabNumber);
      this.paginate(this, this.get('searchView'));
    },
    searchFilter : function () {
      var searchStr = this.get('searchStr');
    //  console.log(searchStr);

      var modelsPromised = this.get("models");

      var component = this;

      modelsPromised.then(function(models) {
        var searchView = [];
        models.forEach(function(model) {
          var title = model.get('title');

          if (new RegExp(searchStr, "i").test(title))
              searchView.push(model);
        });

        component.set('searchView', searchView);
        component.paginate(component, searchView);
      });

    },
    select : function (model) {
      this.set('item', model);
      this.sendAction('action', model); // sends to compose.js controller, action itemSelected, based on template spec.
    },

    openDeleteModal: function(id) {
      var selector = '.ui.' + id + '.modal';
      console.log("Selector: " +  selector);
      $(selector).modal('show');
    },

    approveDelete: function(model) {
      console.log("Deleting model " + model.name);
      var component = this;

      model.destroyRecord({ reload: true }).then( function () {
        // refresh
//        component.get('store').findAll('tale', { reload: true }).then(function(tales) {
          component.paginate(component, component.get('models'));
  //      });
      });

      return false;
    },

    denyDelete: function() {
      return true;
    },

    addNew: function() {
        this.sendAction("onAddNew");
    },

    launchTale: function (tale) {
      var component = this;

      component.set("tale_instantiating_id", tale.id);
      component.set("tale_instantiating", true);

      var onSuccess = function(item) {
        console.log(item);
        component.set("tale_instantiating", false);
        component.set("tale_instantiated", true);

        var instance = Ember.Object.create(JSON.parse(item));

        component.set("instance", instance);

        Ember.run.later((function() {
          component.set("tale_instantiated", false);
        }), 30000);
      };

      var onFail = function(item) {
        // deal with the failure here
        component.set("tale_instantiating", false);
        component.set("tale_not_instantiated", true);
        item = JSON.parse(item);

        console.log(item);
        component.set("error_msg", item.message);

        Ember.run.later((function() {
          component.set("tale_not_instantiated", false);
        }), 10000);

      };

      // submit: API
      // httpCommand, taleid, imageId, folderId, instanceId, name, description, isPublic, config

      this.get("apiCall").postInstance(
        tale.get("_id"),
        tale.get("imageId"),
        null,
        onSuccess,
        onFail);
    },
  }
});
<|endoftext|>


<commit_before>/* eslint-disable no-console */

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
  noInfo: true,
  headers: {'Access-Control-Allow-Origin': '*'},
  stats: {
    colors: true
  }
}).listen(config.devServerPort, 'localhost', function errorCallback(err) {
  if (err) {
    console.error(err);
  }

  console.info(`==> 🚧  Webpack development server listening on port ${config.devServerPort}`);
});
<commit_msg>Don't depend on --harmony flag when running 'npm run client'<commit_after>/* eslint-disable no-console */

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
  noInfo: true,
  headers: {'Access-Control-Allow-Origin': '*'},
  stats: {
    colors: true
  }
}).listen(config.devServerPort, 'localhost', function errorCallback(err) {
  if (err) {
    console.error(err);
  }

  console.info('==> 🚧  Webpack development server listening on port ' + config.devServerPort);
});
<|endoftext|>


<commit_before>
/**
 * common header for map/table views
 */

var OptionsMenu = cdb.admin.DropdownMenu.extend({
  events: {
    'click .export':        '_export',
    'click .duplicate':     '_duplicate',
    'click .append':        '_append',
    'click .delete_table':  '_delete'
  },

  show: function() {
    this.render();
    this.constructor.__super__.show.apply(this);
  },

  _export: function(e){
    e.preventDefault();

    // Should check if query is applied and it is correct, if not, user can't
    // export anything...
    if (this.options.table.isInSQLView() && !this.options.dataLayer.get("query")) {
      return;
    }

    var export_dialog = new cdb.admin.ExportTableDialog({
      model: this.options.table,
      config: config,
      user_data: user_data
    });

    $("body").append(export_dialog.render().el);
    export_dialog.open();
  },

  _duplicate: function(e){
    e.preventDefault();

    // Should check if query is applied and it is correct, if not, user can't
    // duplicate a table or a query...
    if (this.options.table.isInSQLView() && !this.options.dataLayer.get("query")) {
      return;
    }

    var duplicate_dialog = new cdb.admin.DuplicateTable({
      model: this.options.table
    });

    $("body").append(duplicate_dialog.render().el);
    duplicate_dialog.open();
  },

  _append: function(e){
    e.preventDefault();
  },

  _delete: function(e){
    e.preventDefault();
    var delete_dialog = new cdb.admin.DeleteDialog({
      model: this.options.table,
      config: config,
      user_data: user_data,
      ok: function() {
        location = "/dashboard";
      }
    });

    $("body").append(delete_dialog.render().el);
    delete_dialog.open();
  }
});

cdb.admin.Header = cdb.core.View.extend({
  _TEXTS: {
    _DEFAULT_DESCRIPTION:         'add a description for this table...',
    _DEFAULT_QUERY_DESCRIPTION:   'There is no description...',
    _DEFAULT_ADD_TAG_BUTTON:      'add tags',
    _DEFAULT_EDIT_TAG_BUTTON:     'edit tags'
  },
  _PRIVACY_VALUES: [
    'public',
    'private'
  ],
  events: {
    'click .clearview':           'clearView',
    'click .status':              '_addPrivacySelector',
    'click .change_title':        '_changeTitle',
    'click .table_description p': '_changeDescription',
    'click .georeference':        'georeference',
    'click span.tags > *':        '_changeTags'
  },

  initialize: function(options) {
    var self = this;

    this.$body = this.options.body || $('body');
    this.table = this.model;
    this.globalError = this.options.globalError;
    this.createBindings();

    this.add_related_model(this.table);
    this.$('.clearview').hide();

    // Print all the information and don't
    // wait for table changes, it renders faster
    this.setTableInfo();
    this.createUserMenu();
    this.createOptionsMenu();

    // if(this.table.isInSQLView()) {
    //   this.onSQLView();
    // }
  },

  createBindings: function() {
    _.bindAll(this, '_changeTitle', '_setDescription', '_setTags', '_setNameAndStatus');
    this.table.bind('change:dataSource', this.onSQLView, this);
    this.table.bind('privacyUpdated', this._setNameAndStatus);
    this.bind('descriptionChanged', this._setDescription);
    this.bind('tagsChanged', this._setTags);
    this.table.bind('change:name', this._setNameAndStatus);
  },

  createUserMenu: function() {
    // User menu
    var user_menu = this.user_menu = new cdb.admin.DropdownMenu({
      target: $('a.account'),
      username: this.options.user.get('username'),
      host: this.options.config.account_host,
      template_base: 'common/views/settings_item'
    }).bind("onDropdownShown",function(ev) {
      cdb.god.unbind("closeDialogs", user_menu.hide, user_menu);
      cdb.god.trigger("closeDialogs");
      cdb.god.bind("closeDialogs", user_menu.hide, user_menu);
    });

    cdb.god.bind("closeDialogs", user_menu.hide, user_menu);
    this.$body.append(user_menu.render().el);
    this.addView(user_menu);
  },

  createOptionsMenu: function() {
    // Options menu
    var options_menu = this.options_menu = new OptionsMenu({
      target: $('a.options'),
      model: { username: this.options.user.get('username') },
      username: this.options.user.get('username'),
      table: this.table,
      template_base: 'table/views/header_table_options'
    }).bind("onDropdownShown",function(ev) {
      cdb.god.unbind("closeDialogs", options_menu.hide, options_menu);
      cdb.god.trigger("closeDialogs");
      cdb.god.bind("closeDialogs", options_menu.hide, options_menu);
    });
    cdb.god.bind("closeDialogs", options_menu.hide, options_menu);
    this.addView(options_menu);
  },

  setOptionsMenu: function(dl) {
    this.options_menu.options.dataLayer = dl;
    $('body').append(this.options_menu.render().el);
  },

  setDataLayer: function(dl) {
    this.dataLayer = dl;
    // Set the new datalayer to the options menu
    // due to the fact that we need for duplicating
    // dialog, export dialog, and so on...
    this.setOptionsMenu(dl);
  },

  georeference: function(e) {
    e.preventDefault();
    var dlg = new cdb.admin.GeoreferenceDialog({
      model: this.table,
      geocoder: this.options.geocoder
    });
    dlg.appendToBody().open();
  },

  setTableInfo: function() {
    this._setNameAndStatus();
    this._setDescription();
    this._setTags();
  },

  /**
   *  Set Name and status of the table
   */
  _setNameAndStatus: function() {

    this.$('h2.special a').html(this.table.get('name'));

    var $status = this.$('.status');

    for(var n in this._PRIVACY_VALUES) {
      var privacyName = this._PRIVACY_VALUES[n]
      $status.removeClass(privacyName);
    }

    $status
      .addClass(this.table.get('privacy').toLowerCase())
      .html(this.table.get('privacy'));
  },

  /**
   *  Set table description in the header
   */
  _setDescription: function() {
    var default_description = this._TEXTS._DEFAULT_DESCRIPTION;

    if(this.table.sqlView) {
      default_description = "" + this._TEXTS._DEFAULT_QUERY_DESCRIPTION + "";
    }

    this.$('.table_description p').html(this.table.get('description') || default_description);
  },

  /**
   *  Set table tags in the header
   */
  _setTags: function() {
    var tag_button_text = this._TEXTS._DEFAULT_ADD_TAG_BUTTON;
    if (this.table.get('tags')) {
      tag_button_text = this._TEXTS._DEFAULT_EDIT_TAG_BUTTON;
    }
    if (this.table.sqlView) {
      tag_button_text = '';
    }
    if (this.table.get('tags')) {
      var tags = this.table.get('tags').split(",")
        , html = '
';

      _.each(tags, function(tag,i) {
        html += "" + tag + "";
      });

      this.$('span.tags').html(html + "
");
      this.$('span.tags').append(""+tag_button_text+"");
    } else {
      this.$('span.tags').html(""+tag_button_text+"");
    }
  },

  onSQLView: function() {
    this.setTableInfo();
    if(this.table.isInSQLView()) {
      this.$('.clearview').show();
      this.$el.addClass('query');
      this.$('.status').hide();
      this.$('.georeference').parent().hide();
    } else {
      this.$('.clearview').hide();
      this.$el.removeClass('query');
      this.$('.status').show();
      this.$('.georeference').parent().show();
    }
  },

  clearView: function(e) {
    e.preventDefault();
    this.dataLayer && this.dataLayer.save({ query: undefined });
    $.faviconNotify('/favicons/cartofante_blue.png');
    return false;
  },

  _addPrivacySelector: function(ev) {
    ev.preventDefault();

    this.privacy && this.privacy.clean();
    cdb.god.trigger("closeDialogs");
        // Add privacy selector
    var privacy = this.privacy = new cdb.admin.PrivacySelector({
      model: this.table,
      limitation: !this.options.user.get("private_tables"),
      direction: 'down',
      upgrade_url: 'https://' + config.account_host + "/account/" + user_data.username + "/upgrade"
    });

    cdb.god.bind("closeDialogs", this.privacy.hide, this.privacy);

    this.$el.parent().append(this.privacy.render().el);

    this.privacy.show($(ev.target),"offset");

    return false;
  },

  _changeDescription: function(e) {
    var self = this;
    this.killEvent(e);
    if(!this.table.sqlView) {
      this.description_dialog && this.description_dialog.clean();
      cdb.god.trigger("closeDialogs");

      var description_dialog = this.description_dialog = new cdb.admin.EditTextDialog({
        initial_value: this.table.get('description') || '',
        template_name: 'table/views/edit_name',
        clean_on_hide: true,
        modal_class: 'edit_name_dialog',
        res: function(val) {
          if (val !== self.model.get('description')) {
            // Show a loader, and when saves the new description
            // Take into account we don't trigger save event to
            // avoid change the whole application
            self.globalError.showError('Saving ... ', 'load');
            $.when(self.model.save({ description:val }, { silent:true })).done(function() {
              self.trigger('descriptionChanged');
              self.globalError.showError('Saved', 'info', 3000);
            }).fail(function() {
              self.globalError.showError('Something has failed', 'error', 5000);
            });
          }
        }
      });

      cdb.god.bind("closeDialogs", description_dialog.hide, description_dialog);

      var pos = $(e.target).offset();
      pos.left -= $(window).scrollLeft();
      pos.top -= $(window).scrollTop();
      var w = Math.max($(e.target).width() + 100, 280);

      description_dialog.showAt(pos.left - 20, pos.top - 13, w);
    }
  },

  _changeTitle: function(e) {
    var self = this;
    this.killEvent(e);
    if(!this.table.sqlView) {
      this.title_dialog && this.title_dialog.clean();
      cdb.god.trigger("closeDialogs");
      var previousName = this.table.get('name');
      var title_dialog = this.title_dialog = new cdb.admin.EditTextDialog({
        initial_value: previousName,
        template_name: 'table/views/edit_name',
        clean_on_hide: true,
        modal_class: 'edit_name_dialog',
        res: function(val) {
          if(val !== self.model.get('name')) {
            var confirmation = new cdb.admin.RenameConfirmationDialog({
              model: self.table,
              globalError: self.globalError,
              newName: val
            });

            confirmation.appendToBody().open();
            var promise = confirmation.confirm();
            $.when(promise).done(self._renameTable.bind(self));
          }
        }
      });

      cdb.god.bind("closeDialogs", title_dialog.hide, title_dialog);

      // when the table has horizontal scroll for some reason
      // object offset returned has the scroll added
      var pos = $(e.target).offset();
      pos.left -= $(window).scrollLeft()
      pos.top -= $(window).scrollTop()
      var w = Math.max($(e.target).width() + 100, 280);
      title_dialog.showAt(pos.left - 20, pos.top - 6, w);
    }
  },

  _renameTable: function(newName) {
    var self = this;
    self.globalError.showError('Renaming your table ... ', 'load');
    $.when(self.model.save({ name: newName }, {wait: true})).done(function() {
      self.globalError.showError('Saved', 'info', 3000);
    });
  },

  _changeTags: function(e) {
    var self = this;
    e.preventDefault();
    e.stopPropagation();
    if(!this.table.sqlView) {
      this.tags_dialog && this.tags_dialog.clean();
      cdb.god.trigger("closeDialogs");

      var tags_dialog = this.tags_dialog = new cdb.admin.TagsDialog({
        initial_value: this.table.get('tags'),
        template_name: 'table/views/edit_name',
        clean_on_hide: false,
        modal_class: 'edit_name_dialog',
        res: function(val) {
          if (val !== self.model.get('tags')) {
            // Show a loader, and when saves new tags
            // Take into account we don't trigger save event to
            // avoid change the whole application (same as description)
            self.model.notice('Saving ... ', 'load');
            $.when(self.model.save({ tags:val }, { silent:true })).done(function() {
              self.trigger('tagsChanged');
              self.model.notice('Saved', 'info', 3000);
            }).fail(function() {
              self.model.notice('Something has failed', 'error', 5000);
            });
          }
        }
      });

      cdb.god.bind("closeDialogs", tags_dialog.hide, tags_dialog);

      // when the table has horizontal scroll for some reason
      // object offset returned has the scroll added
      var $tags = $(e.target).closest("span.tags")
      var pos = $tags.offset();
      pos.left -= $(window).scrollLeft();
      pos.top -= $(window).scrollTop() + 6;

      var w = Math.max($tags.find("p").width() + 100, 280);
      tags_dialog.showAt(pos.left - 20, pos.top - 8);
    }
  }
});
<commit_msg>initializing the editor with a max length<commit_after>
/**
 * common header for map/table views
 */

var OptionsMenu = cdb.admin.DropdownMenu.extend({
  events: {
    'click .export':        '_export',
    'click .duplicate':     '_duplicate',
    'click .append':        '_append',
    'click .delete_table':  '_delete'
  },

  show: function() {
    this.render();
    this.constructor.__super__.show.apply(this);
  },

  _export: function(e){
    e.preventDefault();

    // Should check if query is applied and it is correct, if not, user can't
    // export anything...
    if (this.options.table.isInSQLView() && !this.options.dataLayer.get("query")) {
      return;
    }

    var export_dialog = new cdb.admin.ExportTableDialog({
      model: this.options.table,
      config: config,
      user_data: user_data
    });

    $("body").append(export_dialog.render().el);
    export_dialog.open();
  },

  _duplicate: function(e){
    e.preventDefault();

    // Should check if query is applied and it is correct, if not, user can't
    // duplicate a table or a query...
    if (this.options.table.isInSQLView() && !this.options.dataLayer.get("query")) {
      return;
    }

    var duplicate_dialog = new cdb.admin.DuplicateTable({
      model: this.options.table
    });

    $("body").append(duplicate_dialog.render().el);
    duplicate_dialog.open();
  },

  _append: function(e){
    e.preventDefault();
  },

  _delete: function(e){
    e.preventDefault();
    var delete_dialog = new cdb.admin.DeleteDialog({
      model: this.options.table,
      config: config,
      user_data: user_data,
      ok: function() {
        location = "/dashboard";
      }
    });

    $("body").append(delete_dialog.render().el);
    delete_dialog.open();
  }
});

cdb.admin.Header = cdb.core.View.extend({
  _TEXTS: {
    _DEFAULT_DESCRIPTION:         'add a description for this table...',
    _DEFAULT_QUERY_DESCRIPTION:   'There is no description...',
    _DEFAULT_ADD_TAG_BUTTON:      'add tags',
    _DEFAULT_EDIT_TAG_BUTTON:     'edit tags'
  },
  _PRIVACY_VALUES: [
    'public',
    'private'
  ],
  _MAX_DESCRIPTION_LENGTH: 200,
  events: {
    'click .clearview':           'clearView',
    'click .status':              '_addPrivacySelector',
    'click .change_title':        '_changeTitle',
    'click .table_description p': '_changeDescription',
    'click .georeference':        'georeference',
    'click span.tags > *':        '_changeTags'
  },

  initialize: function(options) {
    var self = this;

    this.$body = this.options.body || $('body');
    this.table = this.model;
    this.globalError = this.options.globalError;
    this.createBindings();

    this.add_related_model(this.table);
    this.$('.clearview').hide();

    // Print all the information and don't
    // wait for table changes, it renders faster
    this.setTableInfo();
    this.createUserMenu();
    this.createOptionsMenu();

    // if(this.table.isInSQLView()) {
    //   this.onSQLView();
    // }
  },

  createBindings: function() {
    _.bindAll(this, '_changeTitle', '_setDescription', '_setTags', '_setNameAndStatus');
    this.table.bind('change:dataSource', this.onSQLView, this);
    this.table.bind('privacyUpdated', this._setNameAndStatus);
    this.bind('descriptionChanged', this._setDescription);
    this.bind('tagsChanged', this._setTags);
    this.table.bind('change:name', this._setNameAndStatus);
  },

  createUserMenu: function() {
    // User menu
    var user_menu = this.user_menu = new cdb.admin.DropdownMenu({
      target: $('a.account'),
      username: this.options.user.get('username'),
      host: this.options.config.account_host,
      template_base: 'common/views/settings_item'
    }).bind("onDropdownShown",function(ev) {
      cdb.god.unbind("closeDialogs", user_menu.hide, user_menu);
      cdb.god.trigger("closeDialogs");
      cdb.god.bind("closeDialogs", user_menu.hide, user_menu);
    });

    cdb.god.bind("closeDialogs", user_menu.hide, user_menu);
    this.$body.append(user_menu.render().el);
    this.addView(user_menu);
  },

  createOptionsMenu: function() {
    // Options menu
    var options_menu = this.options_menu = new OptionsMenu({
      target: $('a.options'),
      model: { username: this.options.user.get('username') },
      username: this.options.user.get('username'),
      table: this.table,
      template_base: 'table/views/header_table_options'
    }).bind("onDropdownShown",function(ev) {
      cdb.god.unbind("closeDialogs", options_menu.hide, options_menu);
      cdb.god.trigger("closeDialogs");
      cdb.god.bind("closeDialogs", options_menu.hide, options_menu);
    });
    cdb.god.bind("closeDialogs", options_menu.hide, options_menu);
    this.addView(options_menu);
  },

  setOptionsMenu: function(dl) {
    this.options_menu.options.dataLayer = dl;
    $('body').append(this.options_menu.render().el);
  },

  setDataLayer: function(dl) {
    this.dataLayer = dl;
    // Set the new datalayer to the options menu
    // due to the fact that we need for duplicating
    // dialog, export dialog, and so on...
    this.setOptionsMenu(dl);
  },

  georeference: function(e) {
    e.preventDefault();
    var dlg = new cdb.admin.GeoreferenceDialog({
      model: this.table,
      geocoder: this.options.geocoder
    });
    dlg.appendToBody().open();
  },

  setTableInfo: function() {
    this._setNameAndStatus();
    this._setDescription();
    this._setTags();
  },

  /**
   *  Set Name and status of the table
   */
  _setNameAndStatus: function() {

    this.$('h2.special a').html(this.table.get('name'));

    var $status = this.$('.status');

    for(var n in this._PRIVACY_VALUES) {
      var privacyName = this._PRIVACY_VALUES[n]
      $status.removeClass(privacyName);
    }

    $status
      .addClass(this.table.get('privacy').toLowerCase())
      .html(this.table.get('privacy'));
  },

  /**
   *  Set table description in the header
   */
  _setDescription: function() {
    var default_description = this._TEXTS._DEFAULT_DESCRIPTION;

    if(this.table.sqlView) {
      default_description = "" + this._TEXTS._DEFAULT_QUERY_DESCRIPTION + "";
    }

    this.$('.table_description p').html(this.table.get('description') || default_description);
  },

  /**
   *  Set table tags in the header
   */
  _setTags: function() {
    var tag_button_text = this._TEXTS._DEFAULT_ADD_TAG_BUTTON;
    if (this.table.get('tags')) {
      tag_button_text = this._TEXTS._DEFAULT_EDIT_TAG_BUTTON;
    }
    if (this.table.sqlView) {
      tag_button_text = '';
    }
    if (this.table.get('tags')) {
      var tags = this.table.get('tags').split(",")
        , html = '
';

      _.each(tags, function(tag,i) {
        html += "" + tag + "";
      });

      this.$('span.tags').html(html + "
");
      this.$('span.tags').append(""+tag_button_text+"");
    } else {
      this.$('span.tags').html(""+tag_button_text+"");
    }
  },

  onSQLView: function() {
    this.setTableInfo();
    if(this.table.isInSQLView()) {
      this.$('.clearview').show();
      this.$el.addClass('query');
      this.$('.status').hide();
      this.$('.georeference').parent().hide();
    } else {
      this.$('.clearview').hide();
      this.$el.removeClass('query');
      this.$('.status').show();
      this.$('.georeference').parent().show();
    }
  },

  clearView: function(e) {
    e.preventDefault();
    this.dataLayer && this.dataLayer.save({ query: undefined });
    $.faviconNotify('/favicons/cartofante_blue.png');
    return false;
  },

  _addPrivacySelector: function(ev) {
    ev.preventDefault();

    this.privacy && this.privacy.clean();
    cdb.god.trigger("closeDialogs");
        // Add privacy selector
    var privacy = this.privacy = new cdb.admin.PrivacySelector({
      model: this.table,
      limitation: !this.options.user.get("private_tables"),
      direction: 'down',
      upgrade_url: 'https://' + config.account_host + "/account/" + user_data.username + "/upgrade"
    });

    cdb.god.bind("closeDialogs", this.privacy.hide, this.privacy);

    this.$el.parent().append(this.privacy.render().el);

    this.privacy.show($(ev.target),"offset");

    return false;
  },

  _changeDescription: function(e) {
    var self = this;
    this.killEvent(e);
    if(!this.table.sqlView) {
      this.description_dialog && this.description_dialog.clean();
      cdb.god.trigger("closeDialogs");

      var description_dialog = this.description_dialog = new cdb.admin.EditTextDialog({
        initial_value: this.table.get('description') || '',
        template_name: 'table/views/edit_name',
        clean_on_hide: true,
        maxLength: self._MAX_DESCRIPTION_LENGTH,
        modal_class: 'edit_name_dialog',
        res: function(val) {
          // safety check
          val = val.substr(0, self._MAX_DESCRIPTION_LENGTH);
          if (val !== self.model.get('description')) {
            // Show a loader, and when saves the new description
            // Take into account we don't trigger save event to
            // avoid change the whole application
            self.globalError.showError('Saving ... ', 'load');
            $.when(self.model.save({ description:val }, { silent:true })).done(function() {
              self.trigger('descriptionChanged');
              self.globalError.showError('Saved', 'info', 3000);
            }).fail(function() {
              self.globalError.showError('Something has failed', 'error', 5000);
            });
          }
        }
      });

      cdb.god.bind("closeDialogs", description_dialog.hide, description_dialog);

      var pos = $(e.target).offset();
      pos.left -= $(window).scrollLeft();
      pos.top -= $(window).scrollTop();
      var w = Math.max($(e.target).width() + 100, 280);

      description_dialog.showAt(pos.left - 20, pos.top - 13, w);
    }
  },

  _changeTitle: function(e) {
    var self = this;
    this.killEvent(e);
    if(!this.table.sqlView) {
      this.title_dialog && this.title_dialog.clean();
      cdb.god.trigger("closeDialogs");
      var previousName = this.table.get('name');
      var title_dialog = this.title_dialog = new cdb.admin.EditTextDialog({
        initial_value: previousName,
        template_name: 'table/views/edit_name',
        clean_on_hide: true,
        modal_class: 'edit_name_dialog',
        res: function(val) {
          if(val !== self.model.get('name')) {
            var confirmation = new cdb.admin.RenameConfirmationDialog({
              model: self.table,
              globalError: self.globalError,
              newName: val
            });

            confirmation.appendToBody().open();
            var promise = confirmation.confirm();
            $.when(promise).done(self._renameTable.bind(self));
          }
        }
      });

      cdb.god.bind("closeDialogs", title_dialog.hide, title_dialog);

      // when the table has horizontal scroll for some reason
      // object offset returned has the scroll added
      var pos = $(e.target).offset();
      pos.left -= $(window).scrollLeft()
      pos.top -= $(window).scrollTop()
      var w = Math.max($(e.target).width() + 100, 280);
      title_dialog.showAt(pos.left - 20, pos.top - 6, w);
    }
  },

  _renameTable: function(newName) {
    var self = this;
    self.globalError.showError('Renaming your table ... ', 'load');
    $.when(self.model.save({ name: newName }, {wait: true})).done(function() {
      self.globalError.showError('Saved', 'info', 3000);
    });
  },

  _changeTags: function(e) {
    var self = this;
    e.preventDefault();
    e.stopPropagation();
    if(!this.table.sqlView) {
      this.tags_dialog && this.tags_dialog.clean();
      cdb.god.trigger("closeDialogs");

      var tags_dialog = this.tags_dialog = new cdb.admin.TagsDialog({
        initial_value: this.table.get('tags'),
        template_name: 'table/views/edit_name',
        clean_on_hide: false,
        modal_class: 'edit_name_dialog',
        res: function(val) {
          if (val !== self.model.get('tags')) {
            // Show a loader, and when saves new tags
            // Take into account we don't trigger save event to
            // avoid change the whole application (same as description)
            self.model.notice('Saving ... ', 'load');
            $.when(self.model.save({ tags:val }, { silent:true })).done(function() {
              self.trigger('tagsChanged');
              self.model.notice('Saved', 'info', 3000);
            }).fail(function() {
              self.model.notice('Something has failed', 'error', 5000);
            });
          }
        }
      });

      cdb.god.bind("closeDialogs", tags_dialog.hide, tags_dialog);

      // when the table has horizontal scroll for some reason
      // object offset returned has the scroll added
      var $tags = $(e.target).closest("span.tags")
      var pos = $tags.offset();
      pos.left -= $(window).scrollLeft();
      pos.top -= $(window).scrollTop() + 6;

      var w = Math.max($tags.find("p").width() + 100, 280);
      tags_dialog.showAt(pos.left - 20, pos.top - 8);
    }
  }
});
<|endoftext|>


<commit_before>/* global $ _ relEditor */
'use strict';
var meta = function() {
// ==UserScript==
// @name         MusicBrainz: Fill artist info from wikidata
// @namespace    mbz-loujine
// @author       loujine
// @version      2016.4.25
// @downloadURL  https://bitbucket.org/loujine/musicbrainz-scripts/raw/default/mbz-create_artist_from_wikidata.user.js
// @updateURL    https://bitbucket.org/loujine/musicbrainz-scripts/raw/default/mbz-create_artist_from_wikidata.user.js
// @supportURL   https://bitbucket.org/loujine/musicbrainz-scripts
// @icon         https://bitbucket.org/loujine/musicbrainz-scripts/raw/default/icon.png
// @description  musicbrainz.org: Fill artist info from wikidata
// @compatible   firefox+greasemonkey
// @licence      CC BY-NC-SA 3.0 (https://creativecommons.org/licenses/by-nc-sa/3.0/)
// @require      https://greasyfork.org/scripts/13747-mbz-loujine-common/code/mbz-loujine-common.js?version=125991
// @include      http*://*musicbrainz.org/artist/create*
// @include      http*://*musicbrainz.org/artist/*/edit
// @exclude      http*://*musicbrainz.org/artist/*/alias/*/edit
// @include      http*://*mbsandbox.org/artist/create*
// @include      http*://*mbsandbox.org/artist/*/edit
// @exclude      http*://*mbsandbox.org/artist/*/alias/*/edit
// @grant        none
// @run-at       document-end
// ==/UserScript==
};
if (meta && meta.toString && (meta = meta.toString())) {
    var meta = {'name': meta.match(/@name\s+(.+)/)[1],
                'version': meta.match(/@version\s+(.+)/)[1]};
}

// imported from mbz-loujine-common.js: wikidata, sidebar (for edit note)
var sidebar = sidebar,
    wikidata = wikidata;

function fieldInWikidata(entity, field) {
    return entity.claims[wikidata.fields[field]] !== undefined;
}

function valueFromField(entity, field) {
    return entity.claims[wikidata.fields[field]][0].mainsnak.datavalue.value;
}

function setValue(nodeId, value) {
    var node = document.getElementById(nodeId);
    if (!node.value) {
        node.value = value;
    } else if (node.value != value) {  // != to allow autocasting to int
        $(document.getElementById(nodeId)).parent()
        .append('
Wikidata suggests: "' + value + '"
')
        .css('color', 'red');
    }
}

function fillArea(data, place, nodeId, lang) {
    var entityArea = data.entities[place],
        input = document.getElementById('id-edit-artist.' + nodeId + '.name');
    if (!entityArea) {
        return;
    }
    if (fieldInWikidata(entityArea, 'mbidArea')) {
        input.value = valueFromField(entityArea, 'mbidArea');
        $(input).trigger('keydown');
    } else {
        input.value = entityArea.labels[lang].value;
    }
}

function fillDate(strDate, nodeId) {
    var date = new Date(strDate.slice(1)); // remove leading "+"
    setValue('id-edit-artist.period.' + nodeId + '.year', date.getFullYear());
    var yearInput = document.getElementById('id-edit-artist.period.' + nodeId + '.year');
    if (yearInput.getAttribute('class').contains('jesus2099')) {
            // jesus2099's EASY_DATE script is shifting the input node
            // containing the year but not its id
            yearInput.nextSibling.value = date.getFullYear();
    }
    setValue('id-edit-artist.period.' + nodeId + '.month', date.getMonth() + 1);
    setValue('id-edit-artist.period.' + nodeId + '.day', date.getDate());
}

function parseWikidata(entity) {
    var lang = wikidata.language,
        value;
    if (!(lang in entity.labels)) {
        lang = Object.keys(entity.labels)[0];
    }
    // name and sort name
    setValue('id-edit-artist.name', entity.labels[lang].value);
    document.getElementsByClassName('guesscase-title')[0].click();
    document.getElementsByClassName('guesscase-sortname')[0].click();

    // Disambiguation
    if (entity.descriptions[lang] && entity.descriptions[lang].value) {
        setValue('id-edit-artist.comment', entity.descriptions[lang].value);
    }

    // Type and gender
    if (fieldInWikidata(entity, 'type')) {
        var type = valueFromField(entity, 'type')['numeric-id'];
        switch(type) {
            case wikidata.entities.person:
                value = 1;
                break;
            case wikidata.entities.stringQuartet:
            case wikidata.entities.orchestra:
            case wikidata.entities.band:
            case wikidata.entities.rockBand:
                value = 2;
                break;
            default:
                value = 0;
                break;
        }
        setValue('id-edit-artist.type_id', value);
    }

    if (fieldInWikidata(entity, 'gender')) {
        var gender = valueFromField(entity, 'gender')['numeric-id'];
        switch(gender) {
            case wikidata.entities.male:
                value = 1;
                break;
            case wikidata.entities.female:
                value = 2;
                break;
            default:
                value = 3;
                break;
        }
        setValue('id-edit-artist.gender_id', value);
    }

    // Area
    if (fieldInWikidata(entity, 'citizen') || fieldInWikidata(entity, 'country')) {
        var field = fieldInWikidata(entity, 'citizen') ? 'citizen' : 'country';
        var area = 'Q' + valueFromField(entity, field)['numeric-id'];
        $.ajax({
            url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
                 + area + '&format=json',
            dataType: 'jsonp'
        }).done(function(data) {fillArea(data, area, 'area', lang)});
    }

    // ISNI
    if (fieldInWikidata(entity, 'isni')) {
        var isni = valueFromField(entity, 'isni');
        document.getElementsByName('edit-artist.isni_codes.0')[0].value = isni;
    }

    // Dates & places
    if (fieldInWikidata(entity, 'birthDate')
            || fieldInWikidata(entity, 'inceptionDate')) {
        var field = fieldInWikidata(entity, 'birthDate') ? 'birthDate' : 'inceptionDate';
        fillDate(valueFromField(entity, field).time, 'begin_date');
    }

    if (fieldInWikidata(entity, 'birthPlace')
            || fieldInWikidata(entity, 'formationLocation')) {
        var field = fieldInWikidata(entity, 'birthPlace') ? 'birthPlace' : 'formationLocation';
        var birthArea = 'Q' + valueFromField(entity, field)['numeric-id'];
        $.ajax({
            url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
                 + birthArea + '&format=json',
            dataType: 'jsonp'
        }).done(function(data) {fillArea(data, birthArea, 'begin_area', lang)});
    }

    if (fieldInWikidata(entity, 'deathDate')
            || fieldInWikidata(entity, 'dissolutionDate')) {
        var field = fieldInWikidata(entity, 'deathDate') ? 'deathDate' : 'dissolutionDate';
        fillDate(valueFromField(entity, field).time, 'end_date');
    }

    if (fieldInWikidata(entity, 'deathPlace')) {
        var deathArea = 'Q' + valueFromField(entity, 'deathPlace')['numeric-id'];
        $.ajax({
            url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
                 + deathArea + '&format=json',
            dataType: 'jsonp'
        }).done(function(data) {fillArea(data, deathArea, 'end_area', lang)});
    }

    Object.keys(wikidata.urls).forEach(function(externalLink) {
        if (fieldInWikidata(entity, externalLink)) {
            var inputs = document.getElementById('external-links-editor')
                         .getElementsByTagName('input'),
                input = inputs[inputs.length - 1];
            input.value = wikidata.urls[externalLink]
                          + valueFromField(entity, externalLink);
            input.dispatchEvent(new Event('input', {'bubbles': true}));
        }
    });

}

function fillForm(wikiId) {
    $.ajax({
        url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
             + wikiId + '&format=json',
        dataType: 'jsonp'
    }).done(function (data) {
        var entity = data.entities[wikiId];
        if (fieldInWikidata(entity, 'mbidArtist')) {
            var mbid = valueFromField(entity, 'mbidArtist');
            if (window.confirm('An artist already exists linked to this wikidata id, ' +
                               'click "ok" to redirect to their page')) {
                window.location.href='/artist/' + mbid;
            } else {
                parseWikidata(entity);
            }
        } else {
            parseWikidata(entity);
        }
    });
    setValue('id-edit-artist.edit_note', sidebar.editNote(meta));
}

(function displayToolbar(relEditor) {
    $('div.half-width').prepend(
        relEditor.container()
        .append(
            $('
You can first add the wikidata link to retrieve automatically some information
')
        )
    );
})(relEditor);

document.addEventListener('DOMContentLoaded', function () {
    var nodes = document.getElementById('external-links-editor-container')
                .getElementsByTagName('input');
    _.forEach(nodes, function(node) {
        node.addEventListener('input', function () {
            if (node.value.split('/')[2] === "www.wikidata.org") {
                fillForm(node.value.split('/')[4]);
            }
        }, false);
    });
    return false;
});

<commit_msg>[wikidata] Sanitize input and add error message if wikidata could not find the entity<commit_after>/* global $ _ relEditor */
'use strict';
var meta = function() {
// ==UserScript==
// @name         MusicBrainz: Fill artist info from wikidata
// @namespace    mbz-loujine
// @author       loujine
// @version      2016.7.3
// @downloadURL  https://bitbucket.org/loujine/musicbrainz-scripts/raw/default/mbz-create_artist_from_wikidata.user.js
// @updateURL    https://bitbucket.org/loujine/musicbrainz-scripts/raw/default/mbz-create_artist_from_wikidata.user.js
// @supportURL   https://bitbucket.org/loujine/musicbrainz-scripts
// @icon         https://bitbucket.org/loujine/musicbrainz-scripts/raw/default/icon.png
// @description  musicbrainz.org: Fill artist info from wikidata
// @compatible   firefox+greasemonkey
// @licence      CC BY-NC-SA 3.0 (https://creativecommons.org/licenses/by-nc-sa/3.0/)
// @require      https://greasyfork.org/scripts/13747-mbz-loujine-common/code/mbz-loujine-common.js?version=125991
// @include      http*://*musicbrainz.org/artist/create*
// @include      http*://*musicbrainz.org/artist/*/edit
// @exclude      http*://*musicbrainz.org/artist/*/alias/*/edit
// @include      http*://*mbsandbox.org/artist/create*
// @include      http*://*mbsandbox.org/artist/*/edit
// @exclude      http*://*mbsandbox.org/artist/*/alias/*/edit
// @grant        none
// @run-at       document-end
// ==/UserScript==
};
if (meta && meta.toString && (meta = meta.toString())) {
    var meta = {'name': meta.match(/@name\s+(.+)/)[1],
                'version': meta.match(/@version\s+(.+)/)[1]};
}

// imported from mbz-loujine-common.js: wikidata, sidebar (for edit note)
var sidebar = sidebar,
    wikidata = wikidata;

function fieldInWikidata(entity, field) {
    return entity.claims[wikidata.fields[field]] !== undefined;
}

function valueFromField(entity, field) {
    return entity.claims[wikidata.fields[field]][0].mainsnak.datavalue.value;
}

function setValue(nodeId, value) {
    var node = document.getElementById(nodeId);
    if (!node.value) {
        node.value = value;
    } else if (node.value != value) {  // != to allow autocasting to int
        $(document.getElementById(nodeId)).parent()
        .append('
Wikidata suggests: "' + value + '"
')
        .css('color', 'red');
    }
}

function fillArea(data, place, nodeId, lang) {
    var entityArea = data.entities[place],
        input = document.getElementById('id-edit-artist.' + nodeId + '.name');
    if (!entityArea) {
        return;
    }
    if (fieldInWikidata(entityArea, 'mbidArea')) {
        input.value = valueFromField(entityArea, 'mbidArea');
        $(input).trigger('keydown');
    } else {
        input.value = entityArea.labels[lang].value;
    }
}

function fillDate(strDate, nodeId) {
    var date = new Date(strDate.slice(1)); // remove leading "+"
    setValue('id-edit-artist.period.' + nodeId + '.year', date.getFullYear());
    var yearInput = document.getElementById('id-edit-artist.period.' + nodeId + '.year');
    if (yearInput.getAttribute('class').contains('jesus2099')) {
            // jesus2099's EASY_DATE script is shifting the input node
            // containing the year but not its id
            yearInput.nextSibling.value = date.getFullYear();
    }
    setValue('id-edit-artist.period.' + nodeId + '.month', date.getMonth() + 1);
    setValue('id-edit-artist.period.' + nodeId + '.day', date.getDate());
}

function parseWikidata(entity) {
    var lang = wikidata.language,
        value;
    if (!(lang in entity.labels)) {
        lang = Object.keys(entity.labels)[0];
    }
    // name and sort name
    setValue('id-edit-artist.name', entity.labels[lang].value);
    document.getElementsByClassName('guesscase-title')[0].click();
    document.getElementsByClassName('guesscase-sortname')[0].click();

    // Disambiguation
    if (entity.descriptions[lang] && entity.descriptions[lang].value) {
        setValue('id-edit-artist.comment', entity.descriptions[lang].value);
    }

    // Type and gender
    if (fieldInWikidata(entity, 'type')) {
        var type = valueFromField(entity, 'type')['numeric-id'];
        switch(type) {
            case wikidata.entities.person:
                value = 1;
                break;
            case wikidata.entities.stringQuartet:
            case wikidata.entities.orchestra:
            case wikidata.entities.band:
            case wikidata.entities.rockBand:
                value = 2;
                break;
            default:
                value = 0;
                break;
        }
        setValue('id-edit-artist.type_id', value);
    }

    if (fieldInWikidata(entity, 'gender')) {
        var gender = valueFromField(entity, 'gender')['numeric-id'];
        switch(gender) {
            case wikidata.entities.male:
                value = 1;
                break;
            case wikidata.entities.female:
                value = 2;
                break;
            default:
                value = 3;
                break;
        }
        setValue('id-edit-artist.gender_id', value);
    }

    // Area
    if (fieldInWikidata(entity, 'citizen') || fieldInWikidata(entity, 'country')) {
        var field = fieldInWikidata(entity, 'citizen') ? 'citizen' : 'country';
        var area = 'Q' + valueFromField(entity, field)['numeric-id'];
        $.ajax({
            url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
                 + area + '&format=json',
            dataType: 'jsonp'
        }).done(function(data) {fillArea(data, area, 'area', lang)});
    }

    // ISNI
    if (fieldInWikidata(entity, 'isni')) {
        var isni = valueFromField(entity, 'isni');
        document.getElementsByName('edit-artist.isni_codes.0')[0].value = isni;
    }

    // Dates & places
    if (fieldInWikidata(entity, 'birthDate')
            || fieldInWikidata(entity, 'inceptionDate')) {
        var field = fieldInWikidata(entity, 'birthDate') ? 'birthDate' : 'inceptionDate';
        fillDate(valueFromField(entity, field).time, 'begin_date');
    }

    if (fieldInWikidata(entity, 'birthPlace')
            || fieldInWikidata(entity, 'formationLocation')) {
        var field = fieldInWikidata(entity, 'birthPlace') ? 'birthPlace' : 'formationLocation';
        var birthArea = 'Q' + valueFromField(entity, field)['numeric-id'];
        $.ajax({
            url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
                 + birthArea + '&format=json',
            dataType: 'jsonp'
        }).done(function(data) {fillArea(data, birthArea, 'begin_area', lang)});
    }

    if (fieldInWikidata(entity, 'deathDate')
            || fieldInWikidata(entity, 'dissolutionDate')) {
        var field = fieldInWikidata(entity, 'deathDate') ? 'deathDate' : 'dissolutionDate';
        fillDate(valueFromField(entity, field).time, 'end_date');
    }

    if (fieldInWikidata(entity, 'deathPlace')) {
        var deathArea = 'Q' + valueFromField(entity, 'deathPlace')['numeric-id'];
        $.ajax({
            url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
                 + deathArea + '&format=json',
            dataType: 'jsonp'
        }).done(function(data) {fillArea(data, deathArea, 'end_area', lang)});
    }

    Object.keys(wikidata.urls).forEach(function(externalLink) {
        if (fieldInWikidata(entity, externalLink)) {
            var inputs = document.getElementById('external-links-editor')
                         .getElementsByTagName('input'),
                input = inputs[inputs.length - 1];
            input.value = wikidata.urls[externalLink]
                          + valueFromField(entity, externalLink);
            input.dispatchEvent(new Event('input', {'bubbles': true}));
        }
    });

}

function fillForm(wikiId) {
    $.ajax({
        url: 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids='
             + wikiId + '&format=json',
        dataType: 'jsonp'
    }).done(function (data) {
        if (data.error) {
            alert('wikidata returned an error:\n' +
                  'code: ' + data.error.code + '\n' +
                  'wikidata ID: "' + data.error.id + '"\n' +
                  'info: ' + data.error.info);
        }
        var entity = data.entities[wikiId];
        if (fieldInWikidata(entity, 'mbidArtist')) {
            var mbid = valueFromField(entity, 'mbidArtist');
            if (window.confirm('An artist already exists linked to this wikidata id, ' +
                               'click "ok" to redirect to their page')) {
                window.location.href='/artist/' + mbid;
            } else {
                parseWikidata(entity);
            }
        } else {
            parseWikidata(entity);
        }
    });
    setValue('id-edit-artist.edit_note', sidebar.editNote(meta));
}

(function displayToolbar(relEditor) {
    $('div.half-width').prepend(
        relEditor.container()
        .append(
            $('
You can first add the wikidata link to retrieve automatically some information
')
        )
    );
})(relEditor);

document.addEventListener('DOMContentLoaded', function () {
    var nodes = document.getElementById('external-links-editor-container')
                .getElementsByTagName('input');
    _.forEach(nodes, function(node) {
        node.addEventListener('input', function () {
            if (node.value.split('/')[2] === "www.wikidata.org") {
                fillForm(node.value.split('/')[4].trim());
            }
        }, false);
    });
    return false;
});

<|endoftext|>


<commit_before>'use strict';

module.exports = function(app) {
	var users = require('../../app/controllers/users');
	var reports = require('../../app/controllers/reports');

	// Reports Routes
	app.route('/reports')
		.get(users.requiresLogin, reports.list)
		.post(users.requiresLogin, reports.create);

	app.route('/reports/createNew')
		.get(users.requiresLogin, reports.getNew)
		.post(users.requiresLogin, reports.createNew);

	app.route('/reports/:reportId')
		.get(reports.read)
		.put(users.requiresLogin, reports.hasAuthorization, reports.update)
		.delete(users.requiresLogin, reports.hasAuthorization, reports.delete);

	app.route('/reportdownload/:reportId')
		.get(users.requiresLogin, reports.hasAuthorization,
			 reports.generateLatex, reports.generatePDF, reports.download);

	app.route('/reportdownload/:reportId/latex')
		.get(users.requiresLogin, reports.hasAuthorization,
			reports.generateLatex, reports.getLatex);

	// Finish by binding the Report middleware
	app.param('reportId', reports.reportByID);
};<commit_msg>added more functionality<commit_after>'use strict';

module.exports = function(app) {
	var users = require('../../app/controllers/users');
	var reports = require('../../app/controllers/reports');

	// Reports Routes
	app.route('/reports')
		.get(users.requiresLogin, reports.list)
		.post(users.requiresLogin, reports.create);

	app.route('/reports/createNew')
		.get(users.requiresLogin, reports.createNew);

	app.route('/reports/:reportId')
		.get(reports.read)
		.put(users.requiresLogin, reports.hasAuthorization, reports.update)
		.delete(users.requiresLogin, reports.hasAuthorization, reports.delete);

	app.route('/reportdownload/:reportId')
		.get(users.requiresLogin, reports.hasAuthorization,
			 reports.generateLatex, reports.generatePDF, reports.download);

	app.route('/reportdownload/:reportId/latex')
		.get(users.requiresLogin, reports.hasAuthorization,
			reports.generateLatex, reports.getLatex);

	// Finish by binding the Report middleware
	app.param('reportId', reports.reportByID);
};<|endoftext|>