<commit_before>React = require 'react'
FileButton = require '../../../components/file-button'
alert = require '../../../lib/alert'
Details = require '../../../components/details'
TriggeredModalForm = require 'modal-form/triggered'
surveyEditorHelp = require './editor-help'
AutoSave = require '../../../components/auto-save'
handleInputChange = require '../../../lib/handle-input-change'
NextTaskSelector = require '../next-task-selector'
MediaArea = require '../../../components/media-area'
PromiseRenderer = require '../../../components/promise-renderer'
{Markdown} = require 'markdownz'
Papa = require 'papaparse'
apiClient = require 'panoptes-client/lib/api-client'
putFile = require '../../../lib/put-file'
Utility = require './utility'

module.exports = React.createClass
  displayName: 'SurveyTaskEditor'

  getInitialState: ->
    importErrors: []
    resettingMedia: false

  getDefaultProps: ->
    workflow: null
    task: null
    taskPrefix: ''

  render: ->
    window.editingSurveyTask = @props.task

    <div className="workflow-task-editor">
      <p><span className="form-label">Import task data</span></p>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" accept=".csv, .tsv" multiple onSelect={@handleFiles.bind this, @addChoice, null}>Add choices CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.choices}
        </TriggeredModalForm>
      </div>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" accept=".csv, .tsv" multiple onSelect={@handleFiles.bind this, @addCharacteristics, null}>Add characteristics CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.characteristics}
        </TriggeredModalForm>
      </div>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" accept=".csv, .tsv" multiple onSelect={@handleFiles.bind this, @addConfusion, null}>Add confused pairs CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.confusions}
        </TriggeredModalForm>
      </div>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" multiple onSelect={@handleFiles.bind this, @addQuestion, @cleanQuestions}>Add questions CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.questions}
        </TriggeredModalForm>
      </div>

      <hr />

      {unless @state.importErrors.length is 0
        <div>
          <p className="form-label">Import errors</p>
          {for {error, file, row}, i in @state.importErrors
            <p key={i}>
              <strong>{error.message}</strong>
              <br />
              <span className="form-help">
                {if file?
                  <span>{file?.name} </span>}
                {if row? or error.row?
                  <span>Row {(row ? error.row) + 1} </span>}
              </span>
            </p>}
          <hr />
        </div>}

      <div>
        <span className="form-label">Survey images</span>{' '}
        <AutoSave resource={@props.workflow}>
          <button type="button" disabled={@state.resettingMedia} onClick={@resetMedia}>Delete all</button>
          {if @state.resettingMedia
            <i className="fa fa-spinner fa-spin"></i>}
        </AutoSave>
      </div>

      <MediaArea
        resource={@props.workflow}
        metadata={prefix: @props.taskPrefix}
        style={maxHeight: '90vh'}
        onAdd={@handleImageAdd}
        onDelete={@handleImageDelete}
      />

      <hr />

      <p>
        <AutoSave resource={@props.workflow}>
          <span className="form-label">Next task</span>
          <br />
          <NextTaskSelector workflow={@props.workflow} name="#{@props.taskPrefix}.next" value={@props.task.next ? ''} onChange={handleInputChange.bind @props.workflow} />
        </AutoSave>
      </p>

      <hr />

      <div>
        <span className="form-label">Survey data</span>{' '}
        <AutoSave resource={@props.workflow}>
          <button type="button" onClick={@resetTask}>Delete all</button>
        </AutoSave>
      </div>

      {for choiceID in @props.task.choicesOrder
        choice = @props.task.choices[choiceID]
        <Details key={choiceID} className="survey-task-editor-choice" summary={
          <strong>{choice.label}</strong>
        }>
          <Markdown content={choice.description} />
          <div>
            {for characteristicID in @props.task.characteristicsOrder when choice.characteristics[characteristicID]?.length isnt 0
              characteristic = @props.task.characteristics[characteristicID]
              <div key={characteristicID}>
                <small>
                  {characteristic.label}:{' '}
                  {valueLabels = for valueID in characteristic.valuesOrder when valueID in choice.characteristics[characteristicID]
                    value = characteristic.values[valueID]
                    value.label
                  valueLabels.join ', '}
                </small>
              </div>}
            {unless choice.confusionsOrder.length is 0
              <div>
                <small>
                  Confused with:{' '}
                  {twinLabels = for twinID in choice.confusionsOrder
                    twin = @props.task.choices[twinID]
                    twin?.label ? '(Unknown choice)'
                  twinLabels.join ', '}
                </small>
              </div>}
          </div>
        </Details>}

      <hr />

      {if @props.task.questionsOrder?.length
        <div>
          <Details summary="Questions">
            {for questionID in @props.task.questionsOrder
              question = @props.task.questions[questionID]
              <p>
                <strong>{question.label}</strong>:{' '}
                {if question.multiple
                  'Any of'
                else
                  'One of'}{' '}
                {(question.answers[answerID].label for answerID in question.answersOrder).join ', '}{' '}
                {if question.required
                  '(Required)'}
                </p>}
          </Details>
          <hr />
        </div>}

      <Details summary={<small>Raw task data</small>}>
        <pre style={fontSize: '10px', whiteSpace: 'pre-wrap'}>{JSON.stringify @props.task, null, 2}</pre>
      </Details>
    </div>

  handleFiles: (forEachRow, afterFileHook, e) ->
    @setState
      importErrors: []
    Array::slice.call(e.target.files).forEach (file) =>
      @readFile file<commit_msg>Add required checkbox to survey task editor<commit_after>React = require 'react'
FileButton = require '../../../components/file-button'
alert = require '../../../lib/alert'
Details = require '../../../components/details'
TriggeredModalForm = require 'modal-form/triggered'
surveyEditorHelp = require './editor-help'
AutoSave = require '../../../components/auto-save'
handleInputChange = require '../../../lib/handle-input-change'
NextTaskSelector = require '../next-task-selector'
MediaArea = require '../../../components/media-area'
PromiseRenderer = require '../../../components/promise-renderer'
{Markdown} = require 'markdownz'
Papa = require 'papaparse'
apiClient = require 'panoptes-client/lib/api-client'
putFile = require '../../../lib/put-file'
Utility = require './utility'

module.exports = React.createClass
  displayName: 'SurveyTaskEditor'

  getInitialState: ->
    importErrors: []
    resettingMedia: false

  getDefaultProps: ->
    workflow: null
    task: null
    taskPrefix: ''

  render: ->
    window.editingSurveyTask = @props.task

    <div className="workflow-task-editor">
      <p><span className="form-label">Import task data</span></p>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" accept=".csv, .tsv" multiple onSelect={@handleFiles.bind this, @addChoice, null}>Add choices CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.choices}
        </TriggeredModalForm>
      </div>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" accept=".csv, .tsv" multiple onSelect={@handleFiles.bind this, @addCharacteristics, null}>Add characteristics CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.characteristics}
        </TriggeredModalForm>
      </div>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" accept=".csv, .tsv" multiple onSelect={@handleFiles.bind this, @addConfusion, null}>Add confused pairs CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.confusions}
        </TriggeredModalForm>
      </div>
      <div className="columns-container" style={marginBottom: '0.2em'}>
        <FileButton className="major-button column" multiple onSelect={@handleFiles.bind this, @addQuestion, @cleanQuestions}>Add questions CSV</FileButton>
        <TriggeredModalForm trigger={
          <span className="secret-button">
            <i className="fa fa-question-circle"></i>
          </span>
        }>
          {surveyEditorHelp.questions}
        </TriggeredModalForm>
      </div>

      <hr />

      {unless @state.importErrors.length is 0
        <div>
          <p className="form-label">Import errors</p>
          {for {error, file, row}, i in @state.importErrors
            <p key={i}>
              <strong>{error.message}</strong>
              <br />
              <span className="form-help">
                {if file?
                  <span>{file?.name} </span>}
                {if row? or error.row?
                  <span>Row {(row ? error.row) + 1} </span>}
              </span>
            </p>}
          <hr />
        </div>}

      <div>
        <span className="form-label">Survey images</span>{' '}
        <AutoSave resource={@props.workflow}>
          <button type="button" disabled={@state.resettingMedia} onClick={@resetMedia}>Delete all</button>
          {if @state.resettingMedia
            <i className="fa fa-spinner fa-spin"></i>}
        </AutoSave>
      </div>

      <MediaArea
        resource={@props.workflow}
        metadata={prefix: @props.taskPrefix}
        style={maxHeight: '90vh'}
        onAdd={@handleImageAdd}
        onDelete={@handleImageDelete}
      />

      <hr />

      <p>
        <AutoSave resource={@props.workflow}>
          <span className="form-label">Next task</span>
          <br />
          <NextTaskSelector workflow={@props.workflow} name="#{@props.taskPrefix}.next" value={@props.task.next ? ''} onChange={handleInputChange.bind @props.workflow} />
        </AutoSave>
      </p>

      <hr />

      <div>
        <span className="form-label">Survey data</span>{' '}
        <AutoSave resource={@props.workflow}>
          <button type="button" onClick={@resetTask}>Delete all</button>
        </AutoSave>
      </div>

      {for choiceID in @props.task.choicesOrder
        choice = @props.task.choices[choiceID]
        <Details key={choiceID} className="survey-task-editor-choice" summary={
          <strong>{choice.label}</strong>
        }>
          <Markdown content={choice.description} />
          <div>
            {for characteristicID in @props.task.characteristicsOrder when choice.characteristics[characteristicID]?.length isnt 0
              characteristic = @props.task.characteristics[characteristicID]
              <div key={characteristicID}>
                <small>
                  {characteristic.label}:{' '}
                  {valueLabels = for valueID in characteristic.valuesOrder when valueID in choice.characteristics[characteristicID]
                    value = characteristic.values[valueID]
                    value.label
                  valueLabels.join ', '}
                </small>
              </div>}
            {unless choice.confusionsOrder.length is 0
              <div>
                <small>
                  Confused with:{' '}
                  {twinLabels = for twinID in choice.confusionsOrder
                    twin = @props.task.choices[twinID]
                    twin?.label ? '(Unknown choice)'
                  twinLabels.join ', '}
                </small>
              </div>}
          </div>
        </Details>}

      <hr />

      {if @props.task.questionsOrder?.length
        <div>
          <Details summary="Questions">
            {for questionID in @props.task.questionsOrder
              question = @props.task.questions[questionID]
              <p>
                <strong>{question.label}</strong>:{' '}
                {if question.multiple
                  'Any of'
                else
                  'One of'}{' '}
                {(question.answers[answerID].label for answerID in question.answersOrder).join ', '}{' '}
                {if question.required
                  '(Required)'}
                </p>}
          </Details>
          <hr />
        </div>}

      <Details summary={<small>Raw task data</small>}>
        <pre style={fontSize: '10px', whiteSpace: 'pre-wrap'}>{JSON.stringify @props.task, null, 2}</pre>
      </Details>

      <hr />

      <label>
        <AutoSave resource={@props.workflow}>
          <input type="checkbox" name="#{@props.taskPrefix}.required" checked={@props.task.required} onChange={handleInputChange.bind @props.workflow} />{' '}
          Require at least one identification
        </AutoSave>
      </label>
    </div>

  handleFiles: (forEachRow, afterFileHook, e) ->
    @setState
      importErrors: []
    Array::slice.call(e.target.files).forEach (file) =>
      @readFile file
{'fraction_non_alphanumeric': 0.14615123770769753, 'fraction_numerical': 0.002305866395388267, 'mean_word_length': 2.1122836639932463, 'pattern_counts': {'":': 0, '<': 255, '<?xml version=': 0, '>': 265, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3091257', 'n_tokens_mistral': 4163, 'n_tokens_neox': 4049, 'n_words': 814}