<commit_before>// This file is part of Indico.
// Copyright (C) 2002 - 2022 CERN
//
// Indico is free software; you can redistribute it and/or
// modify it under the terms of the MIT License; see the
// LICENSE file for more details.

import createDecorator from 'final-form-calculate';
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import {Field} from 'react-final-form';
import {useSelector} from 'react-redux';
import {Form, Label, Dropdown} from 'semantic-ui-react';

import {FinalCheckbox, FinalDropdown, FinalField, parsers as p} from 'indico/react/forms';
import {Translate} from 'indico/react/i18n';

import {getCurrency} from '../../form/selectors';
import {getFieldValue, getManagement, getPaid} from '../../form_submission/selectors';

import ChoiceLabel from './ChoiceLabel';
import {Choices, choiceShape} from './ChoicesSetup';
import {PlacesLeft} from './PlacesLeftLabel';

import '../../../styles/regform.module.scss';
import './table.module.scss';

function SingleChoiceDropdown({
  existingValue,
  value,
  onChange,
  disabled,
  isRequired,
  isPurged,
  choices,
  withExtraSlots,
  placesUsed,
}) {
  const paid = useSelector(getPaid);
  const management = useSelector(getManagement);
  const currency = useSelector(getCurrency);
  const selectedChoice = choices.find(c => c.id in value) || {};

  const isPaidChoice = choice => choice.price > 0 && paid;
  const isPaidChoiceLocked = choice => !management && isPaidChoice(choice);

  let extraSlotsDropdown = null;
  if (withExtraSlots && selectedChoice && selectedChoice.maxExtraSlots > 0) {
    const options = _.range(1, selectedChoice.maxExtraSlots + 2).map(i => ({
      key: i,
      value: i,
      text: i,
      disabled:
        selectedChoice.placesLimit > 0 &&
        (placesUsed[selectedChoice.id] || 0) - (existingValue[selectedChoice.id] || 0) + i >
          selectedChoice.placesLimit,
    }));
    extraSlotsDropdown = (
      <Form.Select
        options={options}
        disabled={
          disabled ||
          isPaidChoiceLocked(selectedChoice) ||
          (selectedChoice.placesLimit > 0 &&
            (placesUsed[selectedChoice.id] || 0) - (existingValue[selectedChoice.id] || 0) >=
              selectedChoice.placesLimit)
        }
        value={value[selectedChoice.id]}
        onChange={(_evt, data) => onChange({[selectedChoice.id]: data.value})}
        fluid
      />
    );
  }

  const options = choices.map(c => ({
    key: c.id,
    value: c.id,
    disabled:
      !c.isEnabled ||
      isPaidChoiceLocked(c) ||
      (c.placesLimit > 0 && (placesUsed[c.id] || 0) >= c.placesLimit && !existingValue[c.id]),
    text: (
      <div styleName="dropdown-text">
        <div styleName="caption">
          <ChoiceLabel choice={c} management={management} paid={isPaidChoice(c)} />
        </div>
        <div styleName="labels">
          {!!c.price && (
            <Label>
              {c.price} {currency}
            </Label>
          )}
          {c.placesLimit === 0 ? null : (
            <PlacesLeft
              placesLimit={c.placesLimit}
              placesUsed={placesUsed[c.id] || 0}
              isEnabled={c.isEnabled}
            />
          )}
        </div>
      </div>
    ),
  }));

  return (
    <Form.Group styleName="single-choice-dropdown">
      <Form.Field>
        <Dropdown
          selection
          style={{width: 500, opacity: 1}}
          placeholder={Translate.string('Choose an option')}
          options={options}
          disabled={disabled}
          value={(!isPurged && selectedChoice.id) || ''}
          onChange={(e, data) => onChange(data.value ? {[data.value]: 1} : {})}
          clearable={!isRequired}
          search
        />
      </Form.Field>
      {extraSlotsDropdown}
      {extraSlotsDropdown && !!selectedChoice.price && (
        <Label pointing="left">
          {Translate.string('Total: {total} {currency}', {
            total: (
              (selectedChoice.extraSlotsPay ? value[selectedChoice.id] : 1) * selectedChoice.price
            ).toFixed(2),
            currency,
          })}
        </Label>
      )}
    </Form.Group>
  );
}

SingleChoiceDropdown.propTypes = {
  value: PropTypes.object.isRequired,
  onChange: PropTypes.func.isRequired,
  disabled: PropTypes.bool.isRequired,
  isRequired: PropTypes.bool.isRequired,
  isPurged: PropTypes.bool.isRequired,
  choices: PropTypes.arrayOf(PropTypes.shape(choiceShape)).isRequired,
  withExtraSlots: PropTypes.bool.isRequired,<commit_msg>Disable annoying options on regform dropdowns<commit_after>// This file is part of Indico.
// Copyright (C) 2002 - 2022 CERN
//
// Indico is free software; you can redistribute it and/or
// modify it under the terms of the MIT License; see the
// LICENSE file for more details.

import createDecorator from 'final-form-calculate';
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import {Field} from 'react-final-form';
import {useSelector} from 'react-redux';
import {Form, Label, Dropdown} from 'semantic-ui-react';

import {FinalCheckbox, FinalDropdown, FinalField, parsers as p} from 'indico/react/forms';
import {Translate} from 'indico/react/i18n';

import {getCurrency} from '../../form/selectors';
import {getFieldValue, getManagement, getPaid} from '../../form_submission/selectors';

import ChoiceLabel from './ChoiceLabel';
import {Choices, choiceShape} from './ChoicesSetup';
import {PlacesLeft} from './PlacesLeftLabel';

import '../../../styles/regform.module.scss';
import './table.module.scss';

function SingleChoiceDropdown({
  existingValue,
  value,
  onChange,
  disabled,
  isRequired,
  isPurged,
  choices,
  withExtraSlots,
  placesUsed,
}) {
  const paid = useSelector(getPaid);
  const management = useSelector(getManagement);
  const currency = useSelector(getCurrency);
  const selectedChoice = choices.find(c => c.id in value) || {};

  const isPaidChoice = choice => choice.price > 0 && paid;
  const isPaidChoiceLocked = choice => !management && isPaidChoice(choice);

  let extraSlotsDropdown = null;
  if (withExtraSlots && selectedChoice && selectedChoice.maxExtraSlots > 0) {
    const options = _.range(1, selectedChoice.maxExtraSlots + 2).map(i => ({
      key: i,
      value: i,
      text: i,
      disabled:
        selectedChoice.placesLimit > 0 &&
        (placesUsed[selectedChoice.id] || 0) - (existingValue[selectedChoice.id] || 0) + i >
          selectedChoice.placesLimit,
    }));
    extraSlotsDropdown = (
      <Form.Select
        options={options}
        disabled={
          disabled ||
          isPaidChoiceLocked(selectedChoice) ||
          (selectedChoice.placesLimit > 0 &&
            (placesUsed[selectedChoice.id] || 0) - (existingValue[selectedChoice.id] || 0) >=
              selectedChoice.placesLimit)
        }
        value={value[selectedChoice.id]}
        onChange={(_evt, data) => onChange({[selectedChoice.id]: data.value})}
        fluid
      />
    );
  }

  const options = choices.map(c => ({
    key: c.id,
    value: c.id,
    disabled:
      !c.isEnabled ||
      isPaidChoiceLocked(c) ||
      (c.placesLimit > 0 && (placesUsed[c.id] || 0) >= c.placesLimit && !existingValue[c.id]),
    text: (
      <div styleName="dropdown-text">
        <div styleName="caption">
          <ChoiceLabel choice={c} management={management} paid={isPaidChoice(c)} />
        </div>
        <div styleName="labels">
          {!!c.price && (
            <Label>
              {c.price} {currency}
            </Label>
          )}
          {c.placesLimit === 0 ? null : (
            <PlacesLeft
              placesLimit={c.placesLimit}
              placesUsed={placesUsed[c.id] || 0}
              isEnabled={c.isEnabled}
            />
          )}
        </div>
      </div>
    ),
  }));

  return (
    <Form.Group styleName="single-choice-dropdown">
      <Form.Field>
        <Dropdown
          selection
          style={{width: 500, opacity: 1}}
          placeholder={Translate.string('Choose an option')}
          options={options}
          disabled={disabled}
          value={(!isPurged && selectedChoice.id) || ''}
          onChange={(e, data) => onChange(data.value ? {[data.value]: 1} : {})}
          clearable={!isRequired}
          search
          selectOnNavigation={false}
          selectOnBlur={false}
        />
      </Form.Field>
      {extraSlotsDropdown}
      {extraSlotsDropdown && !!selectedChoice.price && (
        <Label pointing="left">
          {Translate.string('Total: {total} {currency}', {
            total: (
              (selectedChoice.extraSlotsPay ? value[selectedChoice.id] : 1) * selectedChoice.price
            ).toFixed(2),
            currency,
          })}
        </Label>
      )}
    </Form.Group>
  );
}

SingleChoiceDropdown.propTypes = {
  value: PropTypes.object.isRequired,
  onChange: PropTypes.func.isRequired,
  disabled: PropTypes.bool.isRequired,
  isRequired: PropTypes.bool.isRequired,
  isPurged: PropTypes.bool.isRequired,
  choices: PropTypes.arrayOf(PropTypes.shape(choiceShape)).isRequired,
  withExtraSlots: PropTypes.bool.isRequired,
{'fraction_non_alphanumeric': 0.1408296943231441, 'fraction_numerical': 0.006768558951965066, 'mean_word_length': 2.6209486166007907, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 69, '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': '4630131', 'n_tokens_mistral': 2796, 'n_tokens_neox': 2744, 'n_words': 586}