<commit_before>// @flow

const fs = require('fs')
const ndjson = require('ndjson')
const objectPath = require('object-path')
const RestClient = require('../../api/RestClient')
import type { Readable } from 'stream'
import type { SimpleStatementMsg } from '../../../protobuf/types'

const BATCH_SIZE = 1000

type HandlerOptions = {
  namespace: string,
  apiUrl: string,
  idSelector: string,
  contentSelector: ?string,
  filename?: string,
  batchSize: number,
  idRegex?: string,
  contentFilters?: string,
  compound?: number,
  dryRun: boolean
}

module.exports = {
  command: 'publish <namespace> [filename]',
  description: 'publish a batch of statements from a batch of newline-delimited json. ' +
    'statements will be read from `filename` or stdin.\n',
  builder: {
    batchSize: { default: BATCH_SIZE },
    idSelector: {
      required: true,
      description: 'a dot-separated path to a field containing a well-known identifier, ' +
      'or, a string containing a JSON array of keys.  Use the latter if your keys contain "."\n'
    },
    contentSelector: {
      description: 'If present, use as a keypath to select a subset of the data to publish. ' +
        'If contentSelector is used, idSelector should be relative to it, not to the content root.\n'
    },
    contentFilters: {
      description: 'Key-paths to omit from content. Multiple keypaths can be joined with ",". \n'
    },
    idRegex: {
      description: 'if present, any capture groups will be used to extract a portion of the id. ' +
        'e.g. --idRegex \'(dpla_)http.*/(.*)\' would turn ' +
        '"dpla_http://dp.la/api/items/2e49bf374b1b55f71603aa9aa326a9d6" into ' +
        '"dpla_2e49bf374b1b55f71603aa9aa326a9d6"\n'
    },
    dryRun: {
      type: 'boolean',
      default: false,
      description: 'only extract ids and print to the console'
    },
    compound: {
      type: 'int',
      required: false,
      description: 'if present, publish compound statements of `compound` number of records. \n'
    }
  },

  handler: (opts: HandlerOptions) => {
    const {namespace, apiUrl, batchSize, filename, dryRun, compound} = opts
    const idSelector = parseSelector(opts.idSelector)
    const contentSelector = (opts.contentSelector != null) ? parseSelector(opts.contentSelector) : null
    const contentFilters = parseFilters(opts.contentFilters)
    const idRegex = (opts.idRegex != null) ? compileIdRegex(opts.idRegex) : null
    const streamName = 'standard input'

    const client = new RestClient({apiUrl})

    let inputStream: Readable
    if (filename) {
      inputStream = fs.createReadStream(filename)
    } else {
      inputStream = process.stdin
    }

    const publishOpts = {namespace, compound}
    let statementBodies: Array<Object> = []
    let statements: Array<SimpleStatementMsg> = []
    const publishPromises: Array<Promise<*>> = []

    inputStream.pipe(ndjson.parse())
      .on('data', obj => {
        if (contentSelector != null) {
          obj = objectPath.get(obj, contentSelector)
        }

        for (let filter of contentFilters) {
          objectPath.del(obj, filter)
        }

        let id = objectPath.get(obj, idSelector)
        if (idRegex != null) {
          id = extractId(id, idRegex)
        }

        if (id == null || id.length < 1) {
          throw new Error(
            `Unable to extract id using idSelector ${JSON.stringify(idSelector)}. Input record: \n` +
            JSON.stringify(obj, null, 2)
          )
        }
        const refs = [id]
        const tags = [] // TODO: support extracting tags

        if (dryRun) {
          console.log(`refs: ${JSON.stringify(refs)}, tags: ${JSON.stringify(tags)}`)
          return
        }

        const stmt = {object: obj, refs, tags}

        statementBodies.push(obj)
        statements.push(stmt)

        if (statementBodies.length >= batchSize) {
          publishPromises.push(
            publishBatch(client, publishOpts, statementBodies, statements)
          )
          statementBodies = []
          statements = []
        }
      })
      .on('error', err => console.error(`Error reading from ${streamName}: `, err))
      .on('end', () => {
        if (statementBodies.length > 0) {
          publishPromises.push(
            publishBatch(client, publishOpts, statementBodies, statements)
          )
        }

        Promise.all(publishPromises)
          .then(() => {
            if (!dryRun) {
              console.log('All statements published successfully')
            }
          })
      })
  },

  extractId
}

function publishBatch (client: RestClient,
                       publishOpts: {namespace: string, compound?: number},
                       statementBodies: Array<Object>,
                       statements: Array<Object>): Promise<*> {
  return client.putData(...statementBodies)
    .then(bodyHashes => {
      if (bodyHashes.length !== statements.length) {
        throw new Error(`Expected ${statements.length} results from putting data blobs, received ${bodyHashes.length}`)
      }
      statements = statements.map((s, i) => {
        s.object = bodyHashes[i]
        return s
      })

      return client.publish(publishOpts, ...statements)
        .then(statementIds => [bodyHashes, statementIds])
    })
    .then(([bodyHashes, statementIds]) => {
      printBatchResults(bodyHashes, statementIds, statements, publishOpts.compound || 1)
    })
    .catch(err => {
      console.error('Error publishing statements: ', err)
    })
}

function printBatchResults (bodyHashes: Array<string>, statementIds: Array<string>, statements: Array<Object>,
                            compoundSize: number) {
  for (let i = 0; i < statementIds.length; i++) {
    const objectRefs = bodyHashes.slice(i, i + compoundSize)
    const stmts = statements.slice(i, i + compoundSize)
    const bodies = stmts.map((s, idx) => ({
      object: objectRefs[idx],
      refs: s.refs,
      tags: s.tags
    }))

    console.log(`\nstatement id: ${statementIds[i]}`)
    console.log(bodies)
  }
}

function parseSelector (selector: string | Array<string>): Array<string> {
  if (Array.isArray(selector)) return selector.map(k => k.toString())

  selector = selector.trim()
  if (selector.startsWith('[')) {
    return parseSelector(JSON.parse(selector))
  }
  return selector.split('.')
}

function parseFilters (filterString: ?string): Array<Array<string>> {
  if (filterString == null) return []
  filterString = filterString.trim()
  if (filterString.startsWith('[')) {
    return JSON.parse(filterString).map(f => parseSelector(f))
  }

  const filters = filterString.split(',')
  return filters.map(s => parseSelector(s))
}

function compileIdRegex (idRegexStr: string): RegExp {
  if (!idRegexStr.startsWith('^')) idRegexStr = '^' + idRegexStr
  if (!idRegexStr.endsWith('$')) idRegexStr = idRegexStr + '$'
  return new RegExp(idRegexStr)
}

function extractId (fullId: string, idRegex: RegExp): string {
  const match = idRegex.exec(fullId)
  if (match == null) {
    throw new Error(`idRegex ${idRegex.toString()} failed to match on id string "${fullId}"`)
  }

  if (match.length === 1) {
    throw new Error(`idRegex must contain at least one capture group`)
  }

  let id = ''
  for (let i = 1; i < match.length; i++) {
    id += match[i]
  }
  return id
}
<commit_msg>flow: move stray ?<commit_after>// @flow

const fs = require('fs')
const ndjson = require('ndjson')
const objectPath = require('object-path')
const RestClient = require('../../api/RestClient')
import type { Readable } from 'stream'
import type { SimpleStatementMsg } from '../../../protobuf/types'

const BATCH_SIZE = 1000

type HandlerOptions = {
  namespace: string,
  apiUrl: string,
  idSelector: string,
  contentSelector?: string,
  filename?: string,
  batchSize: number,
  idRegex?: string,
  contentFilters?: string,
  compound?: number,
  dryRun: boolean
}

module.exports = {
  command: 'publish <namespace> [filename]',
  description: 'publish a batch of statements from a batch of newline-delimited json. ' +
    'statements will be read from `filename` or stdin.\n',
  builder: {
    batchSize: { default: BATCH_SIZE },
    idSelector: {
      required: true,
      description: 'a dot-separated path to a field containing a well-known identifier, ' +
      'or, a string containing a JSON array of keys.  Use the latter if your keys contain "."\n'
    },
    contentSelector: {
      description: 'If present, use as a keypath to select a subset of the data to publish. ' +
        'If contentSelector is used, idSelector should be relative to it, not to the content root.\n'
    },
    contentFilters: {
      description: 'Key-paths to omit from content. Multiple keypaths can be joined with ",". \n'
    },
    idRegex: {
      description: 'if present, any capture groups will be used to extract a portion of the id. ' +
        'e.g. --idRegex \'(dpla_)http.*/(.*)\' would turn ' +
        '"dpla_http://dp.la/api/items/2e49bf374b1b55f71603aa9aa326a9d6" into ' +
        '"dpla_2e49bf374b1b55f71603aa9aa326a9d6"\n'
    },
    dryRun: {
      type: 'boolean',
      default: false,
      description: 'only extract ids and print to the console'
    },
    compound: {
      type: 'int',
      required: false,
      description: 'if present, publish compound statements of `compound` number of records. \n'
    }
  },

  handler: (opts: HandlerOptions) => {
    const {namespace, apiUrl, batchSize, filename, dryRun, compound} = opts
    const idSelector = parseSelector(opts.idSelector)
    const contentSelector = (opts.contentSelector != null) ? parseSelector(opts.contentSelector) : null
    const contentFilters = parseFilters(opts.contentFilters)
    const idRegex = (opts.idRegex != null) ? compileIdRegex(opts.idRegex) : null
    const streamName = 'standard input'

    const client = new RestClient({apiUrl})

    let inputStream: Readable
    if (filename) {
      inputStream = fs.createReadStream(filename)
    } else {
      inputStream = process.stdin
    }

    const publishOpts = {namespace, compound}
    let statementBodies: Array<Object> = []
    let statements: Array<SimpleStatementMsg> = []
    const publishPromises: Array<Promise<*>> = []

    inputStream.pipe(ndjson.parse())
      .on('data', obj => {
        if (contentSelector != null) {
          obj = objectPath.get(obj, contentSelector)
        }

        for (let filter of contentFilters) {
          objectPath.del(obj, filter)
        }

        let id = objectPath.get(obj, idSelector)
        if (idRegex != null) {
          id = extractId(id, idRegex)
        }

        if (id == null || id.length < 1) {
          throw new Error(
            `Unable to extract id using idSelector ${JSON.stringify(idSelector)}. Input record: \n` +
            JSON.stringify(obj, null, 2)
          )
        }
        const refs = [id]
        const tags = [] // TODO: support extracting tags

        if (dryRun) {
          console.log(`refs: ${JSON.stringify(refs)}, tags: ${JSON.stringify(tags)}`)
          return
        }

        const stmt = {object: obj, refs, tags}

        statementBodies.push(obj)
        statements.push(stmt)

        if (statementBodies.length >= batchSize) {
          publishPromises.push(
            publishBatch(client, publishOpts, statementBodies, statements)
          )
          statementBodies = []
          statements = []
        }
      })
      .on('error', err => console.error(`Error reading from ${streamName}: `, err))
      .on('end', () => {
        if (statementBodies.length > 0) {
          publishPromises.push(
            publishBatch(client, publishOpts, statementBodies, statements)
          )
        }

        Promise.all(publishPromises)
          .then(() => {
            if (!dryRun) {
              console.log('All statements published successfully')
            }
          })
      })
  },

  extractId
}

function publishBatch (client: RestClient,
                       publishOpts: {namespace: string, compound?: number},
                       statementBodies: Array<Object>,
                       statements: Array<Object>): Promise<*> {
  return client.putData(...statementBodies)
    .then(bodyHashes => {
      if (bodyHashes.length !== statements.length) {
        throw new Error(`Expected ${statements.length} results from putting data blobs, received ${bodyHashes.length}`)
      }
      statements = statements.map((s, i) => {
        s.object = bodyHashes[i]
        return s
      })

      return client.publish(publishOpts, ...statements)
        .then(statementIds => [bodyHashes, statementIds])
    })
    .then(([bodyHashes, statementIds]) => {
      printBatchResults(bodyHashes, statementIds, statements, publishOpts.compound || 1)
    })
    .catch(err => {
      console.error('Error publishing statements: ', err)
    })
}

function printBatchResults (bodyHashes: Array<string>, statementIds: Array<string>, statements: Array<Object>,
                            compoundSize: number) {
  for (let i = 0; i < statementIds.length; i++) {
    const objectRefs = bodyHashes.slice(i, i + compoundSize)
    const stmts = statements.slice(i, i + compoundSize)
    const bodies = stmts.map((s, idx) => ({
      object: objectRefs[idx],
      refs: s.refs,
      tags: s.tags
    }))

    console.log(`\nstatement id: ${statementIds[i]}`)
    console.log(bodies)
  }
}

function parseSelector (selector: string | Array<string>): Array<string> {
  if (Array.isArray(selector)) return selector.map(k => k.toString())

  selector = selector.trim()
  if (selector.startsWith('[')) {
    return parseSelector(JSON.parse(selector))
  }
  return selector.split('.')
}

function parseFilters (filterString: ?string): Array<Array<string>> {
  if (filterString == null) return []
  filterString = filterString.trim()
  if (filterString.startsWith('[')) {
    return JSON.parse(filterString).map(f => parseSelector(f))
  }

  const filters = filterString.split(',')
  return filters.map(s => parseSelector(s))
}

function compileIdRegex (idRegexStr: string): RegExp {
  if (!idRegexStr.startsWith('^')) idRegexStr = '^' + idRegexStr
  if (!idRegexStr.endsWith('$')) idRegexStr = idRegexStr + '$'
  return new RegExp(idRegexStr)
}

function extractId (fullId: string, idRegex: RegExp): string {
  const match = idRegex.exec(fullId)
  if (match == null) {
    throw new Error(`idRegex ${idRegex.toString()} failed to match on id string "${fullId}"`)
  }

  if (match.length === 1) {
    throw new Error(`idRegex must contain at least one capture group`)
  }

  let id = ''
  for (let i = 1; i < match.length; i++) {
    id += match[i]
  }
  return id
}
<|endoftext|>


<commit_before>// @flow
import React from 'react'
import styled, { css } from 'styled-components'
import { colors, fonts, fontSize, media } from '../../styles/base'
import App from '../App'
import Section from '../Section'

const Header = styled.h1`
  font-size: ${fontSize.huge};
  font-family: ${fonts.heading};
  font-weight: 300;
  line-height: 1.2;
  color: ${colors.black};
  z-index: 200;
  margin-bottom: 4.8rem;

  ${media.mobile`
    font-size: ${fontSize.huge};
  `};
  ${media.tablet`
    margin-bottom: 0;
    letter-spacing: -1.1;
    color: ${colors.white};
    position: absolute;
    width: 60vw;
    top: 50%;
    transform: translateY(-50%);
    padding: 2vw;
    font-size: 3.6vw;
    width: 58vw;
    left: 20vw;
  `};

  & strong {
    font-weight: 700;
  }
`

const About = styled.p`
  color: ${colors.darkGray};
  // font-family: ${fonts.content};
  line-height: 2;
  font-size: ${fontSize.small};
  margin: 2.4rem 0;
  z-index: 200;
  ${media.tablet`
    color: ${colors.white};
    margin: 0;
    font-size: 1.2vw;
    position: absolute;
    left: 20vw;
    top: 50%;
    font-weight: 400;
    // transform: translateY(5.84vw);
    transform: translateY(4vw);
    padding: 2vw;
    width: 35vw;
  `};
`

const AppContainer = styled.div`
  height: 200px;
  ${media.tablet`
    display: block;
    position: absolute;
    z-index: 100;
    top: 50%;
    transform: translateY(-50%);
    left: 19vw;
    width: 62vw;
    height: 39vw;
  `};
`

const headerMixin = css`
  transition: transform 0s linear;

  ${media.tablet`
    position: relative;
    min-height: calc(100vh - 24rem);
    margin-bottom: 12rem;
  `};

  ${media.desktop`
    min-height: 100vh;
  `};
`

export default class Hero extends React.Component<*, *> {
  scrollY: number
  lock: boolean

  constructor() {
    super()
    this.state = { top: 0 }
    this.scrollY = 0
    this.lock = false
  }

  componentWillMount() {
    if (typeof window !== 'undefined') {
      window.addEventListener('scroll', this.onScroll)
    }
  }

  componentWillUnmount() {
    if (typeof window !== 'undefined') {
      window.addEventListener('scroll', this.onScroll)
    }
  }

  onScroll = () => {
    if (window.scrollY > window.innerHeight) {
      return
    }
    if (!this.lock) {
      window.requestAnimationFrame(() => {
        this.setState({ top: window.scrollY })
        this.lock = false
      })
      this.lock = true
    }
  }

  render() {
    const style = {
      transform: `translateY(${this.state.top * 0.4}px)`
    }

    return (

          I design and build{' '}
          high-performance user interfaces for the web.

        {/*
  <About>
    I craft elegant interfaces, engineer fast systems, and find simple
    solutions to complex problems.
  </About>
  */}
        <AppContainer>
          <App />
        </AppContainer>

    )
  }
}
<commit_msg>Fix handler not being removed on component unmount.<commit_after>// @flow
import React from 'react'
import styled, { css } from 'styled-components'
import { colors, fonts, fontSize, media } from '../../styles/base'
import App from '../App'
import Section from '../Section'

const Header = styled.h1`
  font-size: ${fontSize.huge};
  font-family: ${fonts.heading};
  font-weight: 300;
  line-height: 1.2;
  color: ${colors.black};
  z-index: 200;
  margin-bottom: 4.8rem;

  ${media.mobile`
    font-size: ${fontSize.huge};
  `};
  ${media.tablet`
    margin-bottom: 0;
    letter-spacing: -1.1;
    color: ${colors.white};
    position: absolute;
    width: 60vw;
    top: 50%;
    transform: translateY(-50%);
    padding: 2vw;
    font-size: 3.6vw;
    width: 58vw;
    left: 20vw;
  `};

  & strong {
    font-weight: 700;
  }
`

const About = styled.p`
  color: ${colors.darkGray};
  // font-family: ${fonts.content};
  line-height: 2;
  font-size: ${fontSize.small};
  margin: 2.4rem 0;
  z-index: 200;
  ${media.tablet`
    color: ${colors.white};
    margin: 0;
    font-size: 1.2vw;
    position: absolute;
    left: 20vw;
    top: 50%;
    font-weight: 400;
    // transform: translateY(5.84vw);
    transform: translateY(4vw);
    padding: 2vw;
    width: 35vw;
  `};
`

const AppContainer = styled.div`
  height: 200px;
  ${media.tablet`
    display: block;
    position: absolute;
    z-index: 100;
    top: 50%;
    transform: translateY(-50%);
    left: 19vw;
    width: 62vw;
    height: 39vw;
  `};
`

const headerMixin = css`
  transition: transform 0s linear;

  ${media.tablet`
    position: relative;
    min-height: calc(100vh - 24rem);
    margin-bottom: 12rem;
  `};

  ${media.desktop`
    min-height: 100vh;
  `};
`

export default class Hero extends React.Component<*, *> {
  scrollY: number
  lock: boolean

  constructor() {
    super()
    this.state = { top: 0 }
    this.scrollY = 0
    this.lock = false
  }

  componentWillMount() {
    if (typeof window !== 'undefined') {
      window.addEventListener('scroll', this.onScroll)
    }
  }

  componentWillUnmount() {
    if (typeof window !== 'undefined') {
      window.removeEventListener('scroll', this.onScroll)
    }
  }

  onScroll = () => {
    if (window.scrollY > window.innerHeight) {
      return
    }
    if (!this.lock) {
      window.requestAnimationFrame(() => {
        this.setState({ top: window.scrollY })
        this.lock = false
      })
      this.lock = true
    }
  }

  render() {
    const style = {
      transform: `translateY(${this.state.top * 0.4}px)`
    }

    return (

          I design and build{' '}
          high-performance user interfaces for the web.

        {/*
  <About>
    I craft elegant interfaces, engineer fast systems, and find simple
    solutions to complex problems.
  </About>
  */}
        <AppContainer>
          <App />
        </AppContainer>

    )
  }
}
<|endoftext|>


<commit_before>import classnames from 'classnames'
import Education from '../education/Education'
import Names from '../names/Names'
import React from 'react'
import {TabContent, TabPane, Nav, NavItem, NavLink} from 'reactstrap'

export default class Tabs extends React.Component {
  constructor(props) {
    super(props)
    this.tabs = ['Имя', 'Образование', 'Опыт работы', 'Результаты']

    this.toggle = this.toggle.bind(this)
    this.state = {
      activeTab: 0
    }
  }

  render() {
    return (

            {this.tabs.map((tab, idx) => (
                <NavItem key={tab}>
                  <NavLink
                      className={classnames({active: this.state.activeTab === idx})}
                      onClick={()=>this.toggle(idx)}>
                    {tab}
                  </NavLink>
                </NavItem>
            ))}

          <TabContent activeTab={this.state.activeTab}>
            <TabPane tabId={0}>
              <Names/>
            </TabPane>
            <TabPane tabId={1}>
              <Education/>
            </TabPane>
          </TabContent>

    )
  }

  toggle(tab) {
    if (this.state.activeTab !== tab) {
      this.setState({
        activeTab: tab
      })
    }
  }
}
<commit_msg>Move active class from link to tab<commit_after>import classnames from 'classnames'
import Education from '../education/Education'
import Names from '../names/Names'
import React from 'react'
import {TabContent, TabPane, Nav, NavItem, NavLink} from 'reactstrap'

export default class Tabs extends React.Component {
  constructor(props) {
    super(props)
    this.tabs = ['Имя', 'Образование', 'Опыт работы', 'Результаты']

    this.toggle = this.toggle.bind(this)
    this.state = {
      activeTab: 0
    }
  }

  render() {
    return (

            {this.tabs.map((tab, idx) => (
                <NavItem
                    key={tab}
                    className={classnames({active: this.state.activeTab === idx})}>
                  <NavLink
                      onClick={()=>this.toggle(idx)}>
                    {tab}
                  </NavLink>
                </NavItem>
            ))}

          <TabContent activeTab={this.state.activeTab}>
            <TabPane tabId={0}>
              <Names/>
            </TabPane>
            <TabPane tabId={1}>
              <Education/>
            </TabPane>
          </TabContent>

    )
  }

  toggle(tab) {
    if (this.state.activeTab !== tab) {
      this.setState({
        activeTab: tab
      })
    }
  }
}
<|endoftext|>


<commit_before>
<commit_msg>deleted<commit_after><|endoftext|>


<commit_before>/*
 * @flow
 */

import Axios from 'axios';
import Promise from 'bluebird';

import Logger from './utils/Logger';

import {
  getApiBaseUrl,
  EDM_API
} from './config/ApiEndpoints';

const LOG = new Logger('EntityDataModelApi');

const SCHEMA_PATH = 'schema';
const ENTITY_SET_PATH = 'entity/set';
const ENTITY_TYPE_PATH = 'entity/type';
const PROPERTY_TYPE_PATH = 'property/type';

/*
 *
 * EntityDataModel APIs
 *
 */

export function getEntityDataModel() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * Schema APIs
 *
 */

export function getSchema(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function getAllSchemas() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function getSchemasInNamespace(namespace :string) :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function createSchema(createSchemaRequest :Object) :Promise {

  return Axios
    .put(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}`, createSchemaRequest)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * EntitySet APIs
 *
 */

export function getEntitySets() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${ENTITY_SET_PATH}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function createEntitySets(entitySets :Array<Object>) :Promise {

  return Axios
    .post(`${getApiBaseUrl(EDM_API)}/${ENTITY_SET_PATH}`, entitySets)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * EntityType APIs
 *
 */

export function getEntityType(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${ENTITY_TYPE_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function getEntityTypes() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${ENTITY_TYPE_PATH}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function createEntityType(entityType :Object) :Promise {

  return Axios
    .post(`${getApiBaseUrl(EDM_API)}/${ENTITY_TYPE_PATH}`, entityType)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function deleteEntityType(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .delete(`${getApiBaseUrl(EDM_API)}/${ENTITY_SET_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function addEntityTypesToSchema(fullyQualifiedName :Object, entityTypes :Array<Object>) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .put(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}/${name}`, entityTypes)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function removeEntityTypesFromSchema(fullyQualifiedName :Object, entityTypes :Array<Object>) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .delete(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}/${name}`, entityTypes)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * PropertyType APIs
 *
 */

export function createPropertyType(propertyType :Object) :Promise {

  return Axios
    .post(`${getApiBaseUrl(EDM_API)}/${PROPERTY_TYPE_PATH}`, propertyType)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function deletePropertyType(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .delete(`${getApiBaseUrl(EDM_API)}/${PROPERTY_TYPE_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}
<commit_msg>fix removeEntityTypesFromSchema()<commit_after>/*
 * @flow
 */

import Axios from 'axios';
import Promise from 'bluebird';

import Logger from './utils/Logger';

import {
  getApiBaseUrl,
  EDM_API
} from './config/ApiEndpoints';

const LOG = new Logger('EntityDataModelApi');

const SCHEMA_PATH = 'schema';
const ENTITY_SET_PATH = 'entity/set';
const ENTITY_TYPE_PATH = 'entity/type';
const PROPERTY_TYPE_PATH = 'property/type';

/*
 *
 * EntityDataModel APIs
 *
 */

export function getEntityDataModel() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * Schema APIs
 *
 */

export function getSchema(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function getAllSchemas() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function getSchemasInNamespace(namespace :string) :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function createSchema(createSchemaRequest :Object) :Promise {

  return Axios
    .put(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}`, createSchemaRequest)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * EntitySet APIs
 *
 */

export function getEntitySets() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${ENTITY_SET_PATH}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function createEntitySets(entitySets :Array<Object>) :Promise {

  return Axios
    .post(`${getApiBaseUrl(EDM_API)}/${ENTITY_SET_PATH}`, entitySets)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * EntityType APIs
 *
 */

export function getEntityType(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${ENTITY_TYPE_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function getEntityTypes() :Promise {

  return Axios
    .get(`${getApiBaseUrl(EDM_API)}/${ENTITY_TYPE_PATH}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function createEntityType(entityType :Object) :Promise {

  return Axios
    .post(`${getApiBaseUrl(EDM_API)}/${ENTITY_TYPE_PATH}`, entityType)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function deleteEntityType(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .delete(`${getApiBaseUrl(EDM_API)}/${ENTITY_SET_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function addEntityTypesToSchema(fullyQualifiedName :Object, entityTypes :Array<Object>) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .put(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}/${name}`, entityTypes)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function removeEntityTypesFromSchema(fullyQualifiedName :Object, entityTypes :Array<Object>) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .delete(`${getApiBaseUrl(EDM_API)}/${SCHEMA_PATH}/${namespace}/${name}`, {
      data: entityTypes
    })
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

/*
 *
 * PropertyType APIs
 *
 */

export function createPropertyType(propertyType :Object) :Promise {

  return Axios
    .post(`${getApiBaseUrl(EDM_API)}/${PROPERTY_TYPE_PATH}`, propertyType)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}

export function deletePropertyType(fullyQualifiedName :Object) :Promise {

  const { namespace, name } = fullyQualifiedName;

  return Axios
    .delete(`${getApiBaseUrl(EDM_API)}/${PROPERTY_TYPE_PATH}/${namespace}/${name}`)
    .then((axiosResponse) => {
      return axiosResponse.data;
    })
    .catch((e) => {
      LOG.error(e);
    });
}
<|endoftext|>


<commit_before>import React from "react";
import {connect} from "react-redux";
import FlatButton from "material-ui/FlatButton";
import FormsyText from "formsy-material-ui/lib/FormsyText";
import {login} from "../../../actions/userActions";

@connect()
export default class Login extends React.Component {

  constructor() {
    super();
    this.state = {
      canSubmit: false,
    };
  };

  enableButton = () => {
    this.setState({
      canSubmit: true,
    });
  };

  disableButton = () => {
    this.setState({
      canSubmit: false,
    });
  };

  submit = () => {
    this.props.dispatch(login(this.refs.email.getValue(), this.refs.password.getValue()));
  };

  render() {
    return (
      <Formsy.Form
        onValid={this.enableButton}
        onInvalid={this.disableButton}
        onValidSubmit={this.submit}
        onInvalidSubmit={this.notifyFormError}
      >
        <FormsyText
          ref="email" type="text" name="email"
          required
          hintText="email"
        />
        <FormsyText
          ref="password" type="password" name="password"
          required
          hintText="password"
        />
        <FlatButton label="Login" type="submit"
                    disabled={!this.state.canSubmit}
        />

      </Formsy.Form>
    );
  }
}
<commit_msg>Using formsy for form validation<commit_after>import React from "react";
import {connect} from "react-redux";
import FlatButton from "material-ui/FlatButton";
import FormsyText from "formsy-material-ui/lib/FormsyText";
import {login} from "../../../actions/userActions";

@connect()
export default class Login extends React.Component {

  constructor() {
    super();
    this.state = {
      canSubmit: false,
    };
  };

  enableButton = () => {
    this.setState({
      canSubmit: true,
    });
  };

  disableButton = () => {
    this.setState({
      canSubmit: false,
    });
  };

  submit = () => {
    this.props.dispatch(login(this.refs.email.getValue(), this.refs.password.getValue()));
  };

  render() {
    return (
      <Formsy.Form
        onValid={this.enableButton}
        onInvalid={this.disableButton}
        onValidSubmit={this.submit}
      >
        <FormsyText
          ref="email" type="text" name="email"
          required
          hintText="email"
        />
        <FormsyText
          ref="password" type="password" name="password"
          required
          hintText="password"
        />
        <FlatButton label="Login" type="submit"
                    disabled={!this.state.canSubmit}
        />
      </Formsy.Form>
    );
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, $: false */

/**
 * Responsible for coordinating file seletion between views by permitting only one view
 * to show the current file selection at a time. Currently, only WorkingSetView and
 * ProjectManager can show file selection. In general the WorkingSetView takes higher
 * priority until the user selects a file in the ProjectManager.
 *
 * Current file selection rules in views:
 * - select a file in WorkingSetView > select in WorkingSetView
 * - add a file to the WorkingSetView > select in WorkingSetView
 * - select a file in ProjectManager > select in ProjectManager
 * - open a file from places other than the WorkingSetView or ProjectManager >
 *       select file in WorkignSetView if its in the working set, otherwise select in ProjectManager
 */

define(function (require, exports, module) {
    'use strict';

    // Load dependent modules
    var DocumentManager     = require("DocumentManager"),
        CommandManager      = require("CommandManager"),
        Commands            = require("Commands");

    /**
     * Tracks whether a "currentDocumentChange" notification occured due to a call to
     * openAndSelectDocument.
     * @see FileviewController.openAndSelectDocument
     * @private
     */
    var _curDocChangedDueToMe = false;
    var WORKING_SET_VIEW = "WorkingSetView";
    var PROJECT_MANAGER = "ProjectManager";

    /**
     * @private
     * @see FileViewController.getFileSelectionFocus()
     */
    var _fileSelectionFocus = PROJECT_MANAGER;

    /**
     * Change the doc selection to the working set when ever a new file is added to the working set
     */
    $(DocumentManager).on("workingSetAdd", function (event, addedDoc) {
        _fileSelectionFocus = WORKING_SET_VIEW;
        $(exports).triggerHandler("documentSelectionFocusChange");
    });

    /**
      * Update the file selection focus when ever the current document changes
      */
    $(DocumentManager).on("currentDocumentChange", function (event) {

        // The the cause of the doc change was not openAndSelectDocument, so pick the best fileSelectionFocus
        if (!_curDocChangedDueToMe) {
            var curDoc = DocumentManager.getCurrentDocument();
            if (curDoc !== null && DocumentManager.findInWorkingSet(curDoc.file.fullPath) !== -1) {
                _fileSelectionFocus = WORKING_SET_VIEW;
            } else {
                _fileSelectionFocus = PROJECT_MANAGER;
            }
        }

        $(exports).triggerHandler("documentSelectionFocusChange");
    });

    /**
     * Opens a document if it's not open and selects the file in the UI corresponding to
     * fileSelectionFocus
     * @param {!fullPath}
     * @param {string} - must be either WORKING_SET_VIEW or PROJECT_MANAGER
     * @returns {!Deferred}
     */
    function openAndSelectDocument(fullPath, fileSelectionFocus) {
        var result;

        if (fileSelectionFocus !== PROJECT_MANAGER && fileSelectionFocus !== WORKING_SET_VIEW) {
            throw new Error("Bad parameter passed to FileViewController.openAndSelectDocument");
        }

        // Opening files are asynchronous and we want to know when this function caused a file
        // to open so that _fileSelectionFocus is set appropriatly. _curDocChangedDueToMe is set here
        // and checked in the cyrrentDocumentChange handler
        _curDocChangedDueToMe = true;

        _fileSelectionFocus = fileSelectionFocus;

        // If fullPath corresonds to the current doc being viewed then opening the file won't
        // trigger a currentDocumentChanged event, so we need to trigger a documentSelectionFocusChange
        // in this case to signify the selection focus has changed even though the current document has not.
        var doc = DocumentManager.getDocumentForPath(fullPath);
        var curDoc = DocumentManager.getCurrentDocument();
        if (curDoc && curDoc === doc) {
            $(exports).triggerHandler("documentSelectionFocusChange");
            result = (new $.Deferred()).resolve();
        } else {
            result = CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath});
        }

        // clear after notification is done
        result.always(function () {
            _curDocChangedDueToMe = false;
        });

        return result;
    }

    /**
     * Opens the specified document if it's not already open, adds it to the working set,
     * and selects it in the WorkingSetView
     * @param {!fullPath}
     */
    function addToWorkingSetAndSelect(fullPath) {
        CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath});

        // This properly handles sending the right nofications in cases where the document
        // is already the curruent one. In that case we will want to notify with
        // documentSelectionFocusChange so the views change their selection
        openAndSelectDocument(fullPath, WORKING_SET_VIEW);
    }

    /**
     * returns either WORKING_SET_VIEW or PROJECT_MANAGER
     * @return {!String}
     */
    function getFileSelectionFocus() {
        return _fileSelectionFocus;
    }

    // Define public API
    exports.getFileSelectionFocus = getFileSelectionFocus;
    exports.openAndSelectDocument = openAndSelectDocument;
    exports.addToWorkingSetAndSelect = addToWorkingSetAndSelect;
    exports.WORKING_SET_VIEW = WORKING_SET_VIEW;
    exports.PROJECT_MANAGER = PROJECT_MANAGER;

});
<commit_msg>Make sure we always set focus to the editor when asked to select a document, even if it's a no-op.<commit_after>/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, $: false */

/**
 * Responsible for coordinating file seletion between views by permitting only one view
 * to show the current file selection at a time. Currently, only WorkingSetView and
 * ProjectManager can show file selection. In general the WorkingSetView takes higher
 * priority until the user selects a file in the ProjectManager.
 *
 * Current file selection rules in views:
 * - select a file in WorkingSetView > select in WorkingSetView
 * - add a file to the WorkingSetView > select in WorkingSetView
 * - select a file in ProjectManager > select in ProjectManager
 * - open a file from places other than the WorkingSetView or ProjectManager >
 *       select file in WorkignSetView if its in the working set, otherwise select in ProjectManager
 */

define(function (require, exports, module) {
    'use strict';

    // Load dependent modules
    var DocumentManager     = require("DocumentManager"),
        CommandManager      = require("CommandManager"),
        EditorManager       = require("EditorManager"),
        Commands            = require("Commands");

    /**
     * Tracks whether a "currentDocumentChange" notification occured due to a call to
     * openAndSelectDocument.
     * @see FileviewController.openAndSelectDocument
     * @private
     */
    var _curDocChangedDueToMe = false;
    var WORKING_SET_VIEW = "WorkingSetView";
    var PROJECT_MANAGER = "ProjectManager";

    /**
     * @private
     * @see FileViewController.getFileSelectionFocus()
     */
    var _fileSelectionFocus = PROJECT_MANAGER;

    /**
     * Change the doc selection to the working set when ever a new file is added to the working set
     */
    $(DocumentManager).on("workingSetAdd", function (event, addedDoc) {
        _fileSelectionFocus = WORKING_SET_VIEW;
        $(exports).triggerHandler("documentSelectionFocusChange");
    });

    /**
      * Update the file selection focus when ever the current document changes
      */
    $(DocumentManager).on("currentDocumentChange", function (event) {

        // The the cause of the doc change was not openAndSelectDocument, so pick the best fileSelectionFocus
        if (!_curDocChangedDueToMe) {
            var curDoc = DocumentManager.getCurrentDocument();
            if (curDoc !== null && DocumentManager.findInWorkingSet(curDoc.file.fullPath) !== -1) {
                _fileSelectionFocus = WORKING_SET_VIEW;
            } else {
                _fileSelectionFocus = PROJECT_MANAGER;
            }
        }

        $(exports).triggerHandler("documentSelectionFocusChange");
    });

    /**
     * Opens a document if it's not open and selects the file in the UI corresponding to
     * fileSelectionFocus
     * @param {!fullPath}
     * @param {string} - must be either WORKING_SET_VIEW or PROJECT_MANAGER
     * @returns {!Deferred}
     */
    function openAndSelectDocument(fullPath, fileSelectionFocus) {
        var result;

        if (fileSelectionFocus !== PROJECT_MANAGER && fileSelectionFocus !== WORKING_SET_VIEW) {
            throw new Error("Bad parameter passed to FileViewController.openAndSelectDocument");
        }

        // Opening files are asynchronous and we want to know when this function caused a file
        // to open so that _fileSelectionFocus is set appropriatly. _curDocChangedDueToMe is set here
        // and checked in the cyrrentDocumentChange handler
        _curDocChangedDueToMe = true;

        _fileSelectionFocus = fileSelectionFocus;

        // If fullPath corresonds to the current doc being viewed then opening the file won't
        // trigger a currentDocumentChanged event, so we need to trigger a documentSelectionFocusChange
        // in this case to signify the selection focus has changed even though the current document has not.
        var doc = DocumentManager.getDocumentForPath(fullPath);
        var curDoc = DocumentManager.getCurrentDocument();
        if (curDoc && curDoc === doc) {
            $(exports).triggerHandler("documentSelectionFocusChange");
            // Ensure the editor has focus even though we didn't open a new file.
            EditorManager.focusEditor();
            result = (new $.Deferred()).resolve();
        } else {
            result = CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath});
        }

        // clear after notification is done
        result.always(function () {
            _curDocChangedDueToMe = false;
        });

        return result;
    }

    /**
     * Opens the specified document if it's not already open, adds it to the working set,
     * and selects it in the WorkingSetView
     * @param {!fullPath}
     */
    function addToWorkingSetAndSelect(fullPath) {
        CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath});

        // This properly handles sending the right nofications in cases where the document
        // is already the curruent one. In that case we will want to notify with
        // documentSelectionFocusChange so the views change their selection
        openAndSelectDocument(fullPath, WORKING_SET_VIEW);
    }

    /**
     * returns either WORKING_SET_VIEW or PROJECT_MANAGER
     * @return {!String}
     */
    function getFileSelectionFocus() {
        return _fileSelectionFocus;
    }

    // Define public API
    exports.getFileSelectionFocus = getFileSelectionFocus;
    exports.openAndSelectDocument = openAndSelectDocument;
    exports.addToWorkingSetAndSelect = addToWorkingSetAndSelect;
    exports.WORKING_SET_VIEW = WORKING_SET_VIEW;
    exports.PROJECT_MANAGER = PROJECT_MANAGER;

});
<|endoftext|>


<commit_before>import classNames from "classnames";

import React from "react";

const METHODS_TO_BIND = ["handleChange"];

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

    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });
  }

  componentDidMount() {
    if (this.props.startValue === "indeterminate") {
      React.findDOMNode(this.refs.checkbox).indeterminate = true;
    }
  }

  handleChange() {
    let value = null;
    let checkbox = React.findDOMNode(this.refs.checkbox);

    if (checkbox.checked) {
      value = "checked";
    } else {
      value = "unchecked";
    }

    console.log("change", this.props.name, value);
    this.props.handleEvent("change", this.props.name, value);
  }

  getLabel() {
    if (this.props.label) {
      return (

          {this.props.label}

      );
    }

    return null;
  }

  render() {
    let attributes;
    let startValue = this.props.startValue;

    let labelClass = classNames({
      "form-row-element form-element-checkbox": true,
      [this.props.labelClass]: true
    });

    if (startValue === "checked" || startValue === "unchecked") {
      attributes = {
        checked: startValue === "checked"
      };
    }

    return (

        <input ref="checkbox" type="checkbox"
          onChange={this.handleChange}
          {...attributes} />

          <svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
            <g className="icon icon-svg-checkbox-indeterminate">
              <path d="M5,9.75 L11,9.75 C11.4142136,9.75 11.75,9.41421356 11.75,9 C11.75,8.58578644 11.4142136,8.25 11,8.25 L5,8.25 C4.58578644,8.25 4.25,8.58578644 4.25,9 C4.25,9.41421356 4.58578644,9.75 5,9.75 L5,9.75 Z" fill="#000000" fillOpacity="0.13"></path>
              <path d="M5,8.75 L11,8.75 C11.4142136,8.75 11.75,8.41421356 11.75,8 C11.75,7.58578644 11.4142136,7.25 11,7.25 L5,7.25 C4.58578644,7.25 4.25,7.58578644 4.25,8 C4.25,8.41421356 4.58578644,8.75 5,8.75 L5,8.75 Z" fill="#ffffff"></path>
            </g>
            <g className="icon icon-svg-checkbox-checked">
              <path d="M6.37547375,12.4433526 C6.66651906,12.8810343 7.30583183,12.8913338 7.61082475,12.4632544 L12.0274757,6.26416941 C12.2678262,5.92682021 12.1891933,5.45850202 11.8518441,5.21815145 C11.5144949,4.97780088 11.0461767,5.0564338 10.8058262,5.393783 L7.02648971,10.7134266 L5.62452625,8.60511675 C5.39516713,8.26020042 4.92962491,8.1665228 4.58470858,8.39588191 C4.23979226,8.62524103 4.14611463,9.09078326 4.37547375,9.43569958 L6.37547375,12.4433526 Z" fill="#000000" fillOpacity="0.13"></path>
              <path d="M6.37547375,11.4433526 C6.66651906,11.8810343 7.30583183,11.8913338 7.61082475,11.4632544 L12.0274757,5.26416941 C12.2678262,4.92682021 12.1891933,4.45850202 11.8518441,4.21815145 C11.5144949,3.97780088 11.0461767,4.0564338 10.8058262,4.393783 L7.02648971,9.71342659 L5.62452625,7.60511675 C5.39516713,7.26020042 4.92962491,7.1665228 4.58470858,7.39588191 C4.23979226,7.62524103 4.14611463,8.09078326 4.37547375,8.43569958 L6.37547375,11.4433526 Z" fill="#ffffff"></path>
            </g>
          </svg>

        {this.getLabel()}

    );
  }
}
<commit_msg>Remove console.log :anguished:<commit_after>import classNames from "classnames";

import React from "react";

const METHODS_TO_BIND = ["handleChange"];

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

    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });
  }

  componentDidMount() {
    if (this.props.startValue === "indeterminate") {
      React.findDOMNode(this.refs.checkbox).indeterminate = true;
    }
  }

  handleChange() {
    let value = null;
    let checkbox = React.findDOMNode(this.refs.checkbox);

    if (checkbox.checked) {
      value = "checked";
    } else {
      value = "unchecked";
    }

    this.props.handleEvent("change", this.props.name, value);
  }

  getLabel() {
    if (this.props.label) {
      return (

          {this.props.label}

      );
    }

    return null;
  }

  render() {
    let attributes;
    let startValue = this.props.startValue;

    let labelClass = classNames({
      "form-row-element form-element-checkbox": true,
      [this.props.labelClass]: true
    });

    if (startValue === "checked" || startValue === "unchecked") {
      attributes = {
        checked: startValue === "checked"
      };
    }

    return (

        <input ref="checkbox" type="checkbox"
          onChange={this.handleChange}
          {...attributes} />

          <svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
            <g className="icon icon-svg-checkbox-indeterminate">
              <path d="M5,9.75 L11,9.75 C11.4142136,9.75 11.75,9.41421356 11.75,9 C11.75,8.58578644 11.4142136,8.25 11,8.25 L5,8.25 C4.58578644,8.25 4.25,8.58578644 4.25,9 C4.25,9.41421356 4.58578644,9.75 5,9.75 L5,9.75 Z" fill="#000000" fillOpacity="0.13"></path>
              <path d="M5,8.75 L11,8.75 C11.4142136,8.75 11.75,8.41421356 11.75,8 C11.75,7.58578644 11.4142136,7.25 11,7.25 L5,7.25 C4.58578644,7.25 4.25,7.58578644 4.25,8 C4.25,8.41421356 4.58578644,8.75 5,8.75 L5,8.75 Z" fill="#ffffff"></path>
            </g>
            <g className="icon icon-svg-checkbox-checked">
              <path d="M6.37547375,12.4433526 C6.66651906,12.8810343 7.30583183,12.8913338 7.61082475,12.4632544 L12.0274757,6.26416941 C12.2678262,5.92682021 12.1891933,5.45850202 11.8518441,5.21815145 C11.5144949,4.97780088 11.0461767,5.0564338 10.8058262,5.393783 L7.02648971,10.7134266 L5.62452625,8.60511675 C5.39516713,8.26020042 4.92962491,8.1665228 4.58470858,8.39588191 C4.23979226,8.62524103 4.14611463,9.09078326 4.37547375,9.43569958 L6.37547375,12.4433526 Z" fill="#000000" fillOpacity="0.13"></path>
              <path d="M6.37547375,11.4433526 C6.66651906,11.8810343 7.30583183,11.8913338 7.61082475,11.4632544 L12.0274757,5.26416941 C12.2678262,4.92682021 12.1891933,4.45850202 11.8518441,4.21815145 C11.5144949,3.97780088 11.0461767,4.0564338 10.8058262,4.393783 L7.02648971,9.71342659 L5.62452625,7.60511675 C5.39516713,7.26020042 4.92962491,7.1665228 4.58470858,7.39588191 C4.23979226,7.62524103 4.14611463,8.09078326 4.37547375,8.43569958 L6.37547375,11.4433526 Z" fill="#ffffff"></path>
            </g>
          </svg>

        {this.getLabel()}

    );
  }
}
<|endoftext|>


<commit_before>(function() {
  'use strict';

  // Polls controller
  angular
    .module('polls')
    .controller('PollsController', PollsController);

  PollsController.$inject = [
    '$scope',
    '$state',
    '$window',
    'Authentication',
    'pollResolve',
    'PollsApi',
    'TagsService',
    '$aside',
    'CmtsService',
    'VotesService',
    'VotesApi',
    'OptsService',
    'LikesService',
  ];

  function PollsController($scope, $state, $window, Authentication, poll, PollsApi, Tags, $aside, Cmts, Votes, VotesApi, Opts, Likes) {
    var vm = this;

    vm.authentication = Authentication;
    vm.poll = poll;
    vm.poll.close = (vm.poll.close) ? moment(vm.poll.close) : vm.poll.close;
    vm.error = null;
    vm.form = {};
    vm.cmt_sorts = [
      { val: '-updated', name: 'Newest to oldest' },
      { val: 'updated', name: 'Oldest to newest' },
      { val: '-likeCnt', name: 'Most likes' }
    ];
    vm.cmt_sort = '-updated';

    vm.poll.tags = [];
    vm.like = {};
    vm.opts = [];
    vm.cmts = [];
    vm.votes = [];
    vm.voteopts = [];
    vm.votedTotal = 0;

    if (vm.poll._id) {
      // Get all Opts
      PollsApi.findOpts(poll._id)
        .then(res => {
          vm.opts = _.where(res.data, { status: 1 });
          return PollsApi.findVoteopts(poll._id);
        })
        .then(res => {
          vm.votes = res.data.votes || [];
          vm.voteopts = res.data.voteopts || [];
          vm.votedTotal = vm.voteopts.length;
          vm.opts.forEach(opt => {
            opt.voteCnt = _.where(vm.voteopts, { opt: opt._id }).length || 0;
          });
        })
        .catch(err => {
          alert('error' + err);
        });
      // Get all Cmts
      PollsApi.findCmts(poll._id)
        .then(res => {
          vm.cmts = res.data;
        })
        .catch(err => {
          alert('error' + err);
        });
      // Get all Tags
      PollsApi.findTags(poll._id)
        .then(res => {
          angular.forEach(res.data, (polltag, index) => {
            vm.poll.tags.push(polltag.tag);
          });
        })
        .catch(err => {
          alert('error' + err);
        });
    }

    // Remove existing Poll
    vm.remove = () => {
      if ($window.confirm('Are you sure you want to delete?')) {
        vm.poll.$remove($state.go('polls.list'));
      }
    };

    // Save Poll
    vm.save = (isValid) => {
      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'vm.form.pollForm');
        return false;
      }
      // TODO: move create/update logic to service
      if (vm.poll._id) {
        vm.poll.$update(successCallback, errorCallback);
      } else {
        vm.poll.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        $state.go('polls.view', {
          pollId: res._id
        });
      }

      function errorCallback(res) {
        vm.error = res.data.message;
      }
    };

    // Discard edit or add poll
    vm.discard = () => {
      if (angular.equals(vm.poll, vm.bk_poll)) {
        handle_discard();
      } else {
        if ($window.confirm('Are you sure you want to discard?')) {
          handle_discard();
        }
      }
    };

    // Back to before screen
    function handle_discard() {
      if (vm.poll._id) {
        $state.go('polls.view', { pollId: vm.poll._id });
      } else {
        $state.go('polls.list');
      }
    }

    // LIKES
    if (vm.poll._id && vm.authentication.user) {
      PollsApi.findPollLike(poll._id)
        .then(res => {
          vm.like = res.data || {};
        })
        .catch(err => {
          alert('error' + err);
        });
    }
    var liking = false;
    var cnt = 0;
    vm.like_poll = () => {
      if (!vm.authentication.user) {
        return alert('You must login to like this poll.');
      }
      if (liking) {
        return alert('You cannot interact continuously.');
      }
      var _like;
      liking = true;
      if (vm.like._id) {
        switch (vm.like.type) {
          case 0:
            cnt = 1;
            vm.like.type = 1;
            break;
          case 1:
            cnt = -1;
            vm.like.type = 0;
            break;
          case 2:
            cnt = 2;
            vm.like.type = 1;
            break;
        }
        vm.poll.likeCnt += cnt;
        _like = new Likes(vm.like);
        _like.cnt = cnt;
        _like.$update(successCallback, errorCallback);
      } else {
        cnt = 1;
        vm.poll.likeCnt += cnt;
        _like = new Likes({ poll: vm.poll._id, user: vm.authentication.user._id, type: 1 });
        _like.cnt = cnt;
        _like.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        vm.like = res.like;
        vm.poll.likeCnt = res.likeCnt;
        liking = false;
        console.log("liked");
      }

      function errorCallback(err) {
        vm.poll.likeCnt -= cnt;
        liking = false;
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    vm.dislike_poll = () => {
      if (!vm.authentication.user) {
        return alert("You must login to dislike this poll.");
      }
      if (liking) {
        return alert('You cannot interact continuously.');
      }
      var _dislike, cnt;
      liking = true;
      if (vm.like._id) {
        switch (vm.like.type) {
          case 0:
            cnt = -1;
            vm.like.type = 2;
            break;
          case 1:
            cnt = -2;
            vm.like.type = 2;
            break;
          case 2:
            cnt = 1;
            vm.like.type = 0;
            break;
        }
        vm.poll.likeCnt += cnt;
        _dislike = new Likes(vm.like);
        _dislike.cnt = cnt;
        _dislike.$update(successCallback, errorCallback);
      } else {
        cnt = -1;
        vm.poll.likeCnt -= cnt;
        _dislike = new Likes({ poll: vm.poll._id, user: vm.authentication.user._id, type: 2 });
        _dislike.cnt = cnt;
        _dislike.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        vm.like = res;
        vm.poll.likeCnt = res.likeCnt;
        liking = false;
        console.log("disliked");
      }

      function errorCallback(err) {
        vm.poll.likeCnt -= cnt;
        liking = false;
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    // OPTIONS
    vm.option = {};
    var opt_aside = $aside({
      scope: $scope,
      controllerAs: vm,
      templateUrl: 'modules/opts/client/views/new-opt-in-poll.client.view.html',
      title: vm.poll.title,
      placement: 'bottom',
      animation: 'am-fade-and-slide-bottom',
      show: false
    });
    // Click button add option
    vm.input_opt = (opt) => {
      vm.option = (!opt) ? new Opts({ poll: vm.poll._id, title: '', body: '', image: 'modules/opts/client/img/option.png', status: 2 }) : new Opts(opt);
      opt_aside.$promise.then(opt_aside.show);
    };
    // Click button save option
    vm.save_opt = (isValid) => {
      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'vm.form.optForm');
        return false;
      }
      vm.option.$save(successCallback, errorCallback);

      function successCallback(res) {
        opt_aside.$promise.then(opt_aside.hide);
        alert('Your option is waiting for approve. Thanks.');
      }

      function errorCallback(err) {
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    // Comment
    var comment_aside = $aside({
      scope: $scope,
      controllerAs: vm,
      templateUrl: 'modules/cmts/client/views/new-cmt-in-poll.client.view.html',
      title: vm.poll.title,
      placement: 'bottom',
      animation: 'am-fade-and-slide-bottom',
      show: false
    });
    vm.comment = {};

    vm.aside_full_screen = () => {
      alert(1);
    };

    vm.input_cmt = (cmt) => {
      if (vm.authentication.user) {
        vm.comment = (!cmt) ? new Cmts() : new Cmts(cmt);
        comment_aside.$promise.then(comment_aside.show);
      } else {
        $state.go('authentication.signin');
      }
    };

    vm.save_cmt = ($form) => {
      if (!$form.$valid) {
        $scope.$broadcast('show-errors-check-validity', 'vm.form.cmtForm');
        return false;
      }
      if (vm.comment._id) {
        vm.comment.isEdited = true;
        vm.comment.updated = new Date();
        vm.comment.$update(successCallback, errorCallback);
      } else {
        vm.comment.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        comment_aside.$promise.then(comment_aside.hide);
        $state.reload();
      }

      function errorCallback(err) {
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    vm.reply_cmt = (cmt) => {
      alert('reply_cmt');
    };

    vm.edit_cmt = (cmt) => {
      vm.input_cmt(cmt);
    };

    vm.delete_cmt = (cmt) => {
      alert('delete_cmt');
    };

    vm.like_cmt = (cmt) => {
      alert('like_cmt');
    };

    vm.dislike_cmt = (cmt) => {
      alert('dislike_cmt');
    };

    // VOTE
    if (vm.poll._id) {
      // Get Voted
      PollsApi.findOwnerVote(poll._id)
        .then(res => {
          if (res.data) {
            vm.ownVote = new Votes(res.data);
            return VotesApi.findOpts(vm.ownVote._id);
          } else {
            vm.ownVote = new Votes({ poll: vm.poll._id });
          }
        })
        .then(res => {
          vm.votedOpts = (res && res.data) ? _.pluck(res.data, 'opt') : [];
          vm.selectedOpts = (res && res.data) ? _.pluck(res.data, 'opt') : [];
        })
        .catch(err => {
          // alert('error' + err);
          console.log(err);
        });
    }

    vm.checked = function(id) {
      if (_.contains(vm.selectedOpts, id)) {
        vm.selectedOpts = _.without(vm.selectedOpts, id);
      } else {
        vm.selectedOpts.push(id);
      }
    };
    vm.is_voted = function(id) {
      return _.contains(vm.selectedOpts, id);
    };
    vm.voted_title = function() {
      return _.pluck(_.filter(vm.opts, function(opt) {
        return _.contains(vm.votedOpts, opt._id);
      }), 'title');
    };
    vm.save_vote = () => {
      if (!vm.authentication.user && !vm.poll.allow_guest) {
        return $state.go('authentication.signin');
      }
      if (!vm.selectedOpts.length || vm.selectedOpts.length === 0) {
        return alert('You must vote at least one option.');
      }
      vm.ownVote.opts = vm.selectedOpts;
      if (vm.ownVote._id) {
        vm.ownVote.updateCnt += 1;
        vm.ownVote.$update(successCallback, errorCallback);
      } else {
        vm.ownVote.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        $state.reload();
      }

      function errorCallback(res) {
        vm.selectedOpts = angular.copy(vm.votedOpts) || [];
        alert('Vote failed');
      }
    };
  }
}());
<commit_msg>Commited from lenh at 2017年 6月 21日 水曜日 15:43:45<commit_after>(function() {
  'use strict';

  // Polls controller
  angular
    .module('polls')
    .controller('PollsController', PollsController);

  PollsController.$inject = [
    '$scope',
    '$state',
    '$window',
    'Authentication',
    'pollResolve',
    'PollsApi',
    'TagsService',
    '$aside',
    'CmtsService',
    'VotesService',
    'VotesApi',
    'OptsService',
    'LikesService',
  ];

  function PollsController($scope, $state, $window, Authentication, poll, PollsApi, Tags, $aside, Cmts, Votes, VotesApi, Opts, Likes) {
    var vm = this;

    vm.authentication = Authentication;
    vm.poll = poll;
    vm.poll.close = (vm.poll.close) ? moment(vm.poll.close) : vm.poll.close;
    vm.error = null;
    vm.form = {};
    vm.cmt_sorts = [
      { val: '-updated', name: 'Newest to oldest' },
      { val: 'updated', name: 'Oldest to newest' },
      { val: '-likeCnt', name: 'Most likes' }
    ];
    vm.cmt_sort = '-updated';

    vm.poll.tags = [];
    vm.like = {};
    vm.opts = [];
    vm.cmts = [];
    vm.votes = [];
    vm.voteopts = [];
    vm.votedTotal = 0;

    if (vm.poll._id) {
      // Get all Opts
      PollsApi.findOpts(poll._id)
        .then(res => {
          vm.opts = _.where(res.data, { status: 1 });
          return PollsApi.findVoteopts(poll._id);
        })
        .then(res => {
          vm.votes = res.data.votes || [];
          vm.voteopts = res.data.voteopts || [];
          vm.votedTotal = vm.voteopts.length;
          vm.opts.forEach(opt => {
            opt.voteCnt = _.where(vm.voteopts, { opt: opt._id }).length || 0;
          });
        })
        .catch(err => {
          alert('error' + err);
        });
      // Get all Cmts
      PollsApi.findCmts(poll._id)
        .then(res => {
          vm.cmts = res.data;
        })
        .catch(err => {
          alert('error' + err);
        });
      // Get all Tags
      PollsApi.findTags(poll._id)
        .then(res => {
          angular.forEach(res.data, (polltag, index) => {
            vm.poll.tags.push(polltag.tag);
          });
        })
        .catch(err => {
          alert('error' + err);
        });
    }

    // Remove existing Poll
    vm.remove = () => {
      if ($window.confirm('Are you sure you want to delete?')) {
        vm.poll.$remove($state.go('polls.list'));
      }
    };

    // Save Poll
    vm.save = (isValid) => {
      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'vm.form.pollForm');
        return false;
      }
      // TODO: move create/update logic to service
      if (vm.poll._id) {
        vm.poll.$update(successCallback, errorCallback);
      } else {
        vm.poll.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        $state.go('polls.view', {
          pollId: res._id
        });
      }

      function errorCallback(res) {
        vm.error = res.data.message;
      }
    };

    // Discard edit or add poll
    vm.discard = () => {
      if (angular.equals(vm.poll, vm.bk_poll)) {
        handle_discard();
      } else {
        if ($window.confirm('Are you sure you want to discard?')) {
          handle_discard();
        }
      }
    };

    // Back to before screen
    function handle_discard() {
      if (vm.poll._id) {
        $state.go('polls.view', { pollId: vm.poll._id });
      } else {
        $state.go('polls.list');
      }
    }

    // LIKES
    if (vm.poll._id && vm.authentication.user) {
      PollsApi.findPollLike(poll._id)
        .then(res => {
          vm.like = res.data || {};
        })
        .catch(err => {
          alert('error' + err);
        });
    }
    var liking = false;
    var cnt = 0;
    vm.like_poll = () => {
      if (!vm.authentication.user) {
        return alert('You must login to like this poll.');
      }
      if (liking) {
        return alert('You cannot interact continuously.');
      }
      var _like;
      liking = true;
      if (vm.like._id) {
        switch (vm.like.type) {
          case 0:
            cnt = 1;
            vm.like.type = 1;
            break;
          case 1:
            cnt = -1;
            vm.like.type = 0;
            break;
          case 2:
            cnt = 2;
            vm.like.type = 1;
            break;
        }
        vm.poll.likeCnt += cnt;
        _like = new Likes(vm.like);
        _like.cnt = cnt;
        _like.$update(successCallback, errorCallback);
      } else {
        cnt = 1;
        vm.poll.likeCnt += cnt;
        _like = new Likes({ poll: vm.poll._id, user: vm.authentication.user._id, type: 1 });
        _like.cnt = cnt;
        _like.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        vm.like = res.like;
        vm.poll.likeCnt = res.likeCnt;
        liking = false;
        console.log("liked");
      }

      function errorCallback(err) {
        vm.poll.likeCnt -= cnt;
        liking = false;
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    vm.dislike_poll = () => {
      if (!vm.authentication.user) {
        return alert("You must login to dislike this poll.");
      }
      if (liking) {
        return alert('You cannot interact continuously.');
      }
      var _dislike, cnt;
      liking = true;
      if (vm.like._id) {
        switch (vm.like.type) {
          case 0:
            cnt = -1;
            vm.like.type = 2;
            break;
          case 1:
            cnt = -2;
            vm.like.type = 2;
            break;
          case 2:
            cnt = 1;
            vm.like.type = 0;
            break;
        }
        vm.poll.likeCnt += cnt;
        _dislike = new Likes(vm.like);
        _dislike.cnt = cnt;
        _dislike.$update(successCallback, errorCallback);
      } else {
        cnt = -1;
        vm.poll.likeCnt += cnt;
        _dislike = new Likes({ poll: vm.poll._id, user: vm.authentication.user._id, type: 2 });
        _dislike.cnt = cnt;
        _dislike.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        vm.like = res;
        vm.poll.likeCnt = res.likeCnt;
        liking = false;
        console.log("disliked");
      }

      function errorCallback(err) {
        vm.poll.likeCnt -= cnt;
        liking = false;
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    // OPTIONS
    vm.option = {};
    var opt_aside = $aside({
      scope: $scope,
      controllerAs: vm,
      templateUrl: 'modules/opts/client/views/new-opt-in-poll.client.view.html',
      title: vm.poll.title,
      placement: 'bottom',
      animation: 'am-fade-and-slide-bottom',
      show: false
    });
    // Click button add option
    vm.input_opt = (opt) => {
      vm.option = (!opt) ? new Opts({ poll: vm.poll._id, title: '', body: '', image: 'modules/opts/client/img/option.png', status: 2 }) : new Opts(opt);
      opt_aside.$promise.then(opt_aside.show);
    };
    // Click button save option
    vm.save_opt = (isValid) => {
      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'vm.form.optForm');
        return false;
      }
      vm.option.$save(successCallback, errorCallback);

      function successCallback(res) {
        opt_aside.$promise.then(opt_aside.hide);
        alert('Your option is waiting for approve. Thanks.');
      }

      function errorCallback(err) {
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    // Comment
    var comment_aside = $aside({
      scope: $scope,
      controllerAs: vm,
      templateUrl: 'modules/cmts/client/views/new-cmt-in-poll.client.view.html',
      title: vm.poll.title,
      placement: 'bottom',
      animation: 'am-fade-and-slide-bottom',
      show: false
    });
    vm.comment = {};

    vm.aside_full_screen = () => {
      alert(1);
    };

    vm.input_cmt = (cmt) => {
      if (vm.authentication.user) {
        vm.comment = (!cmt) ? new Cmts() : new Cmts(cmt);
        comment_aside.$promise.then(comment_aside.show);
      } else {
        $state.go('authentication.signin');
      }
    };

    vm.save_cmt = ($form) => {
      if (!$form.$valid) {
        $scope.$broadcast('show-errors-check-validity', 'vm.form.cmtForm');
        return false;
      }
      if (vm.comment._id) {
        vm.comment.isEdited = true;
        vm.comment.updated = new Date();
        vm.comment.$update(successCallback, errorCallback);
      } else {
        vm.comment.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        comment_aside.$promise.then(comment_aside.hide);
        $state.reload();
      }

      function errorCallback(err) {
        console.log(err);
        //vm.error = res.data.message;
      }
    };

    vm.reply_cmt = (cmt) => {
      alert('reply_cmt');
    };

    vm.edit_cmt = (cmt) => {
      vm.input_cmt(cmt);
    };

    vm.delete_cmt = (cmt) => {
      alert('delete_cmt');
    };

    vm.like_cmt = (cmt) => {
      alert('like_cmt');
    };

    vm.dislike_cmt = (cmt) => {
      alert('dislike_cmt');
    };

    // VOTE
    if (vm.poll._id) {
      // Get Voted
      PollsApi.findOwnerVote(poll._id)
        .then(res => {
          if (res.data) {
            vm.ownVote = new Votes(res.data);
            return VotesApi.findOpts(vm.ownVote._id);
          } else {
            vm.ownVote = new Votes({ poll: vm.poll._id });
          }
        })
        .then(res => {
          vm.votedOpts = (res && res.data) ? _.pluck(res.data, 'opt') : [];
          vm.selectedOpts = (res && res.data) ? _.pluck(res.data, 'opt') : [];
        })
        .catch(err => {
          // alert('error' + err);
          console.log(err);
        });
    }

    vm.checked = function(id) {
      if (_.contains(vm.selectedOpts, id)) {
        vm.selectedOpts = _.without(vm.selectedOpts, id);
      } else {
        vm.selectedOpts.push(id);
      }
    };
    vm.is_voted = function(id) {
      return _.contains(vm.selectedOpts, id);
    };
    vm.voted_title = function() {
      return _.pluck(_.filter(vm.opts, function(opt) {
        return _.contains(vm.votedOpts, opt._id);
      }), 'title');
    };
    vm.save_vote = () => {
      if (!vm.authentication.user && !vm.poll.allow_guest) {
        return $state.go('authentication.signin');
      }
      if (!vm.selectedOpts.length || vm.selectedOpts.length === 0) {
        return alert('You must vote at least one option.');
      }
      vm.ownVote.opts = vm.selectedOpts;
      if (vm.ownVote._id) {
        vm.ownVote.updateCnt += 1;
        vm.ownVote.$update(successCallback, errorCallback);
      } else {
        vm.ownVote.$save(successCallback, errorCallback);
      }

      function successCallback(res) {
        $state.reload();
      }

      function errorCallback(res) {
        vm.selectedOpts = angular.copy(vm.votedOpts) || [];
        alert('Vote failed');
      }
    };
  }
}());
<|endoftext|>


<commit_before>import { Entity } from '@alephdata/followthemoney';
import { Colors } from '@blueprintjs/core';

const colorOptions = [
  Colors.BLUE1, Colors.TURQUOISE1, Colors.VIOLET1, Colors.ORANGE1, Colors.GREEN1, Colors.RED1,
];

class MappingList {
  constructor(model, mappingData) {
    this.model = model;
    this.mappingItems = new Map();

    if (mappingData) {
      Object.entries(mappingData).forEach(([id, { schema, keys, properties }], i) => {
        this.mappingItems.set(id, {
          color: this.assignColor(i),
          id,
          schema: model.getSchema(schema),
          keys,
          properties: properties || {},
        });
      });
    }
  }

  assignColor(i) {
    const colorIndex = i || this.getMappingsCount();
    return colorOptions[colorIndex % colorOptions.length];
  }

  assignId(schema) {
    const schemaCount = this.getSchemaCount(schema);
    return schemaCount ? `${schema.label} ${schemaCount + 1}` : schema.label;
  }

  getValues() {
    return Array.from(this.mappingItems.values());
  }

  getSchemaCount(schemaToAssign) {
    return this.getValues().filter(({ schema }) => schema === schemaToAssign).length;
  }

  getMappingsCount() {
    return this.mappingItems.size;
  }

  getMapping(id) {
    return this.mappingItems.get(id);
  }

  // returns pseudo-entity for mapping, in order to be allow Entity ftm components to be used
  getMappingAsEntity(id) {
    const { properties, schema } = this.getMapping(id);
    const formattedProps = {};

    // convert properties to Entity > properties format
    Object.entries(properties)
      .filter(([key, value]) => value.literal)
      .forEach(([key, value]) => { formattedProps[key] = value.literal });

    return new Entity(this.model, { id, schema, properties: formattedProps });
  }

  getThingMappings() {
    return this.getValues().filter(({ schema }) => schema?.isThing());
  }

  getNonThingMappings() {
    return this.getValues().filter(({ schema }) => !schema?.isThing());
  }

  // getMappingsAsEntities() {
  //   const toReturn = new Map();
  //   this.getValues().forEach(({ id, schema, properties }) => {
  //     toReturn.set(id, new Entity(this.model, { id, schema }));
  //   });
  //
  //   return toReturn;
  // }

  addMapping(schema) {
    const id = this.assignId(schema);

    const newMapping = {
      id,
      color: this.assignColor(),
      schema,
      keys: [],
      properties: {},
    };
    this.mappingItems.set(id, newMapping);
    return this;
  }

  removeMapping(id) {
    this.mappingItems.delete(id);
    return this;
  }

  addKey(id, key) {
    const mapping = this.getMapping(id);
    mapping.keys.push(key);
    return this;
  }

  removeKey(id, key) {
    const mapping = this.getMapping(id);
    const index = mapping.keys.indexOf(key);
    if (index !== -1) {
      mapping.keys.splice(index, 1);
    }
    return this;
  }

  addProperty(id, propName, value) {
    const mapping = this.getMapping(id);
    mapping.properties[propName] = value;
    return this;
  }

  removeProperty(id, propName) {
    const mapping = this.getMapping(id);
    delete mapping.properties[propName];
    return this;
  }

  getColumnAssignments() {
    const columnAssignments = new Map();

    this.mappingItems.forEach(({ id, schema, properties }) => {
      if (properties) {
        Array.from(Object.entries(properties)).forEach(([propKey, propValue]) => {
          if (propValue && propValue.column) {
            columnAssignments.set(propValue.column, {
              id, schema, property: schema.getProperty(propKey),
            });
          }
        });
      }
    });

    return columnAssignments;
  }

  validate() {
    const errors = [];
    this.mappingItems.forEach(({ id, keys, properties, schema }) => {
      if (keys.length === 0) {
        errors.push({ error: 'keyError', values: { id } });
      }
      if (schema.isEdge) {
        const { source, target } = schema.edge;

        if (!properties[source] || !properties[target]) {
          errors.push({ error: 'relationshipError', values: { id, source, target } });
        }
      }
    });
    return errors;
  }

  clone() {
    return MappingList.fromData(this.model, this.mappingItems);
  }

  toApiFormat() {
    const query = {};

    this.mappingItems.forEach(({ id, schema, keys, properties }) => {
      query[id] = {
        schema: schema.name,
        keys,
        properties,
      };
    });

    return query;
  }

  static fromApiFormat(model, mappingData) {
    return new MappingList(model, mappingData);
  }
}

export default MappingList;
<commit_msg>fixed mapping color assign<commit_after>import { Entity } from '@alephdata/followthemoney';
import { Colors } from '@blueprintjs/core';

const colorOptions = [
  Colors.BLUE1, Colors.TURQUOISE1, Colors.VIOLET1, Colors.ORANGE1, Colors.GREEN1, Colors.RED1,
];

class MappingList {
  constructor(model, mappingData) {
    this.model = model;
    this.mappingItems = new Map();

    if (mappingData) {
      Object.entries(mappingData).forEach(([id, { schema, keys, properties }], i) => {
        this.mappingItems.set(id, {
          color: this.assignColor(i),
          id,
          schema: model.getSchema(schema),
          keys,
          properties: properties || {},
        });
      });
    }
  }

  assignColor(i) {
    const colorIndex = this.getValues()
      .map(mapping => colorOptions.indexOf(mapping.color))
      .sort()
      .reduce((acc, currentValue) => (
        acc === currentValue ? acc + 1 : acc
      ), 0);

    return colorOptions[colorIndex % colorOptions.length];
  }

  assignId(schema) {
    const schemaCount = this.getSchemaCount(schema);
    return schemaCount ? `${schema.label} ${schemaCount + 1}` : schema.label;
  }

  getValues() {
    return Array.from(this.mappingItems.values());
  }

  getSchemaCount(schemaToAssign) {
    return this.getValues().filter(({ schema }) => schema === schemaToAssign).length;
  }

  getMappingsCount() {
    return this.mappingItems.size;
  }

  getMapping(id) {
    return this.mappingItems.get(id);
  }

  // returns pseudo-entity for mapping, in order to be allow Entity ftm components to be used
  getMappingAsEntity(id) {
    const { properties, schema } = this.getMapping(id);
    const formattedProps = {};

    // convert properties to Entity > properties format
    Object.entries(properties)
      .filter(([key, value]) => value.literal)
      .forEach(([key, value]) => { formattedProps[key] = value.literal });

    return new Entity(this.model, { id, schema, properties: formattedProps });
  }

  getThingMappings() {
    return this.getValues().filter(({ schema }) => schema?.isThing());
  }

  getNonThingMappings() {
    return this.getValues().filter(({ schema }) => !schema?.isThing());
  }

  // getMappingsAsEntities() {
  //   const toReturn = new Map();
  //   this.getValues().forEach(({ id, schema, properties }) => {
  //     toReturn.set(id, new Entity(this.model, { id, schema }));
  //   });
  //
  //   return toReturn;
  // }

  addMapping(schema) {
    const id = this.assignId(schema);

    const newMapping = {
      id,
      color: this.assignColor(),
      schema,
      keys: [],
      properties: {},
    };
    this.mappingItems.set(id, newMapping);
    return this;
  }

  removeMapping(id) {
    this.mappingItems.delete(id);
    return this;
  }

  addKey(id, key) {
    const mapping = this.getMapping(id);
    mapping.keys.push(key);
    return this;
  }

  removeKey(id, key) {
    const mapping = this.getMapping(id);
    const index = mapping.keys.indexOf(key);
    if (index !== -1) {
      mapping.keys.splice(index, 1);
    }
    return this;
  }

  addProperty(id, propName, value) {
    const mapping = this.getMapping(id);
    mapping.properties[propName] = value;
    return this;
  }

  removeProperty(id, propName) {
    const mapping = this.getMapping(id);
    delete mapping.properties[propName];
    return this;
  }

  getColumnAssignments() {
    const columnAssignments = new Map();

    this.mappingItems.forEach(({ id, schema, properties }) => {
      if (properties) {
        Array.from(Object.entries(properties)).forEach(([propKey, propValue]) => {
          if (propValue && propValue.column) {
            columnAssignments.set(propValue.column, {
              id, schema, property: schema.getProperty(propKey),
            });
          }
        });
      }
    });

    return columnAssignments;
  }

  validate() {
    const errors = [];
    this.mappingItems.forEach(({ id, keys, properties, schema }) => {
      if (keys.length === 0) {
        errors.push({ error: 'keyError', values: { id } });
      }
      if (schema.isEdge) {
        const { source, target } = schema.edge;

        if (!properties[source] || !properties[target]) {
          errors.push({ error: 'relationshipError', values: { id, source, target } });
        }
      }
    });
    return errors;
  }

  clone() {
    return MappingList.fromData(this.model, this.mappingItems);
  }

  toApiFormat() {
    const query = {};

    this.mappingItems.forEach(({ id, schema, keys, properties }) => {
      query[id] = {
        schema: schema.name,
        keys,
        properties,
      };
    });

    return query;
  }

  static fromApiFormat(model, mappingData) {
    return new MappingList(model, mappingData);
  }
}

export default MappingList;
<|endoftext|>


<commit_before>import React from "react";
import { View, ScrollView, Button, TouchableOpacity } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import glamorous from "glamorous-native";

export default context => {
  const AutoCompleteLocation = require("components/AutoCompleteLocation").default(
    context
  );

  const JobInfo = require("./JobInfo").default(context);
  const JobPicture = require("./JobPicture").default(context);
  const SectorList = require("components/SectorList").default(context);
  const JobEdit = require("./JobEdit").default(context);
  const CompanyInfo = require("./CompanyInfo").default(context);
  const EmploymentType = require("./EmploymentType").default(context);
  const Salary = require("./Salary").default(context);
  const Urgencies = require("./Urgencies").default(context);

  const Header = glamorous.view({
    padding: 10,
    marginBottom: 8,
    backgroundColor: "white",
    justifyContent: "space-between",
    flexDirection: "row",
    alignItems: "center"
  });

  const HeaderTitle = glamorous.text({
    fontWeight: "bold",
    fontSize: 18
  });

  const wizardConfig = {
    header: ({
      title,
      //isFirst,
      onPrevious,
      isLast,
      onNext,
      nextAllowed = true
    }) => (
      <Header>
        <TouchableOpacity
          onPress={() => {
            onPrevious();
          }}
        >
          <Icon name="chevron-left" size={20} color="grey" />
        </TouchableOpacity>

        <HeaderTitle>{title}</HeaderTitle>
        {!isLast ? (
          <Button
            style={{ width: 100 }}
            disabled={!nextAllowed}
            color="blue"
            title="Next"
            onPress={onNext}
          />
        ) : (
          <View />
        )}
      </Header>
    ),
    steps: [
      {
        title: "Urgencies",
        content: ({ currentJob, store }) => (
          <Urgencies currentJob={currentJob} onNext={store.next} />
        ),
        nextAllowed: () => true
      },
      {
        title: "Job Type",
        content: JobInfo,
        nextAllowed: ({ currentJob }) => currentJob.isValid()
      },
      {
        title: "Sector",
        content: ({ currentJob, store }) => (
          <SectorList
            onPress={sector => {
              currentJob.map.set("sector", sector);
              store.next();
            }}
          />
        )
      },
      {
        title: "Urgencies",
        content: ({ currentJob, store }) => (
          <Urgencies currentJob={currentJob} onNext={store.next} />
        ),
        nextAllowed: () => true
      },
      {
        title: "Where ?",
        content: ({ currentJob, store }) => (
          <AutoCompleteLocation
            onLocation={location => currentJob.setLocation(location)}
            store={store}
          />
        ),
        nextAllowed: ({ currentJob }) => currentJob.hasLocation()
      },
      {
        title: "Employment Type",
        content: EmploymentType,
        nextAllowed: () => true
      },
      {
        title: "Salary",
        content: Salary,
        nextAllowed: () => true
      },
      {
        title: "Company Info",
        content: CompanyInfo,
        nextAllowed: ({ currentJob }) => currentJob.isCompanyInfoValid()
      },
      {
        title: "Picture",
        content: JobPicture
      },
      {
        title: "Final Review",
        content: ({ onJobCreated, store, ...props }) => (
          <ScrollView>
            <Button
              color="blue"
              title="Create Job Post Now"
              onPress={() => {
                store.reset();
                onJobCreated();
              }}
            />
            <JobEdit {...props} />
          </ScrollView>
        )
      }
    ]
  };

  const Wizard = require("components/Wizard").default(context, wizardConfig);

  return Wizard.View;
};
<commit_msg>Urgencies after sector<commit_after>import React from "react";
import { View, ScrollView, Button, TouchableOpacity } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import glamorous from "glamorous-native";

export default context => {
  const AutoCompleteLocation = require("components/AutoCompleteLocation").default(
    context
  );

  const JobInfo = require("./JobInfo").default(context);
  const JobPicture = require("./JobPicture").default(context);
  const SectorList = require("components/SectorList").default(context);
  const JobEdit = require("./JobEdit").default(context);
  const CompanyInfo = require("./CompanyInfo").default(context);
  const EmploymentType = require("./EmploymentType").default(context);
  const Salary = require("./Salary").default(context);
  const Urgencies = require("./Urgencies").default(context);

  const Header = glamorous.view({
    padding: 10,
    marginBottom: 8,
    backgroundColor: "white",
    justifyContent: "space-between",
    flexDirection: "row",
    alignItems: "center"
  });

  const HeaderTitle = glamorous.text({
    fontWeight: "bold",
    fontSize: 18
  });

  const wizardConfig = {
    header: ({
      title,
      //isFirst,
      onPrevious,
      isLast,
      onNext,
      nextAllowed = true
    }) => (
      <Header>
        <TouchableOpacity
          onPress={() => {
            onPrevious();
          }}
        >
          <Icon name="chevron-left" size={20} color="grey" />
        </TouchableOpacity>

        <HeaderTitle>{title}</HeaderTitle>
        {!isLast ? (
          <Button
            style={{ width: 100 }}
            disabled={!nextAllowed}
            color="blue"
            title="Next"
            onPress={onNext}
          />
        ) : (
          <View />
        )}
      </Header>
    ),
    steps: [
      {
        title: "Job Type",
        content: JobInfo,
        nextAllowed: ({ currentJob }) => currentJob.isValid()
      },
      {
        title: "Sector",
        content: ({ currentJob, store }) => (
          <SectorList
            onPress={sector => {
              currentJob.map.set("sector", sector);
              store.next();
            }}
          />
        )
      },
      {
        title: "Urgencies",
        content: ({ currentJob, store }) => (
          <Urgencies currentJob={currentJob} onNext={store.next} />
        ),
        nextAllowed: () => true
      },
      {
        title: "Where ?",
        content: ({ currentJob, store }) => (
          <AutoCompleteLocation
            onLocation={location => currentJob.setLocation(location)}
            store={store}
          />
        ),
        nextAllowed: ({ currentJob }) => currentJob.hasLocation()
      },
      {
        title: "Employment Type",
        content: EmploymentType,
        nextAllowed: () => true
      },
      {
        title: "Salary",
        content: Salary,
        nextAllowed: () => true
      },
      {
        title: "Company Info",
        content: CompanyInfo,
        nextAllowed: ({ currentJob }) => currentJob.isCompanyInfoValid()
      },
      {
        title: "Picture",
        content: JobPicture
      },
      {
        title: "Final Review",
        content: ({ onJobCreated, store, ...props }) => (
          <ScrollView>
            <Button
              color="blue"
              title="Create Job Post Now"
              onPress={() => {
                store.reset();
                onJobCreated();
              }}
            />
            <JobEdit {...props} />
          </ScrollView>
        )
      }
    ]
  };

  const Wizard = require("components/Wizard").default(context, wizardConfig);

  return Wizard.View;
};
<|endoftext|>


<commit_before>//Filter experiment or computation templates

Application.Filters.filter('byKey', function () {
    return function (items, key, value) {
        var matches = [];
        if (items) {
            if (key === 'assigned_to') {
                items.forEach(function (item) {
                    var i = _.indexOf(item[key], function (entry) {
                        return value === entry;
                    });
                    if (i > -1) {
                        matches.push(item);
                    }
                });
            } else {
                items.forEach(function (item) {
                    if (item[key] === value) {
                        matches.push(item);
                    }
                });
            }
        }
        return matches;
    };
});

Application.Filters.filter('removeKey', function () {
    return function (properties, keyToRemove) {
        var matches = {};
        if (properties) {
            angular.forEach(properties, function (value, key) {
                if (key !== keyToRemove) {
                    matches[key] = value;
                }
            });
        }
        return matches;
    };
});
<commit_msg>update to the filer<commit_after>//Filter experiment or computation templates

Application.Filters.filter('byKey', function () {
    return function (items, key, value) {
        var matches = [];
        if (items) {
            if (key === 'assigned_to') { //assigned_to field is an array.
                items.forEach(function (item) {
                    var i = _.indexOf(item[key], function (entry) {
                        return value === entry;
                    });
                    if (i > -1) {
                        if(item.status === 'open'){
                            matches.push(item);
                        }
                    }
                });
            } else {
                items.forEach(function (item) {
                    if (item[key] === value) {
                        matches.push(item);
                    }
                });
            }
        }
        return matches;
    };
});

Application.Filters.filter('removeKey', function () {
    return function (properties, keyToRemove) {
        var matches = {};
        if (properties) {
            angular.forEach(properties, function (value, key) {
                if (key !== keyToRemove) {
                    matches[key] = value;
                }
            });
        }
        return matches;
    };
});
<|endoftext|>