<commit_before><link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../../bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="../../../bower_components/paper-input/paper-textarea.html">
<link rel="import" href="../../../bower_components/etools-repeatable-field-set/etools-repeatable-field-set.html">
<link rel="import" href="../../../bower_components/etools-searchable-multiselection-menu/etools-searchable-multiselection-menu.html">
<link rel="import" href="../../../bower_components/etools-ajax/etools-ajax.html">

<link rel="import" href="../travel-elements/travel-status.html">

<link rel="import" href="../../styles/shared-styles.html">
<link rel="import" href="../../styles/et2f-styles.html">

<dom-module id="travel-cost-assignment">
  <template>
    <style include="shared-styles et2f-styles iron-flex iron-flex-alignment iron-flex-factors">

      :host {
        display: block;
        width: 100%;
      }

    </style>

    <etools-ajax url="[[costStructureEndpoint]]"
      loading="{{wbsLoading}}"
      on-success="_handleCostStructure"
      ></etools-ajax>

    <form is="iron-form"
      id="cost_assignment_form"
      class="layout vertical flex">

      <div class="layout horizontal">

        <etools-searchable-multiselection-menu label="Business Area"
          class$="flex-4 [[computedPermission.business_area.readOnly]]"
          options="[[structure.business_areas]]"
          empty-value
          value="{{costAssignment.business_area}}"
          disabled="[[disableBusinessArea]]"
          hidden$="[[computedPermission.business_area.hidden]]"
          placeholder="select"
          required$="[[computedPermission.business_area.required]]"
          starred>
        </etools-searchable-multiselection-menu>

        <paper-checkbox class$="custom-margin self-end flex-3 [[computedPermission.delegate.readOnly]]"
          hidden$="[[computedPermission.delegate.hidden]]"
          checked="{{costAssignment.delegate}}"
          disabled="[[computedPermission.delegate.disabled]]"
          >Delegate
        </paper-checkbox>

        <div class="flex-5"></div>
      </div>

      <div class="layout horizontal">

        <etools-searchable-multiselection-menu label="WBS"
          id="wbs"
          class$="flex-4 [[computedPermission.wbs.readOnly]]"
          options="[[wbsOptions]]"
          empty-value
          value="{{costAssignment.wbs}}"
          disabled="[[computedPermission.wbs.disabled]]"
          hidden$="[[computedPermission.wbs.hidden]]"
          placeholder="select"
          required$="[[computedPermission.wbs.required]]"
          starred>
        </etools-searchable-multiselection-menu>

        <etools-searchable-multiselection-menu label="Grant"
          id="grant"
          class$="flex-3 [[computedPermission.grant.readOnly]]"
          options="[[grantOptions]]"
          value="{{costAssignment.grant}}"
          disabled="[[disableGrant]]"
          hidden$="[[computedPermission.grant.hidden]]"
          empty-value
          required$="[[computedPermission.grant.required]]"
          placeholder="select"
          starred>
        </etools-searchable-multiselection-menu>

        <etools-searchable-multiselection-menu label="Fund"
          id="fund"
          class$="flex-3 [[computedPermission.fund.readOnly]]"
          options="[[fundOptions]]"
          value="{{costAssignment.fund}}"
          disabled="[[disableFund]]"
          empty-value
          hidden$="[[computedPermission.fund.hidden]]"
          required$="[[computedPermission.fund.required]]"
          placeholder="select"
          starred>
        </etools-searchable-multiselection-menu>

        <paper-input label="Share (%)"
          class$="flex-2 custom-margin [[computedPermission.share.readOnly]]"
          value="{{costAssignment.share}}"
          disabled="[[disableShare]]"
          hidden$="[[computedPermission.share.hidden]]"
          type="number"
          min="0"
          max="100"
          required$="[[computedPermission.share.required]]"
          step="1"
          pattern="^(100|([1-9]{0,1})?([0-9]{0,1})?)$"
          placeholder="add"
          invalid="[[invalidShares]]"
          starred>
          <span suffix>%</span>
        </paper-input>
      </div>
    </form>
  </template>

  <script>
    Polymer({
      is: 'travel-cost-assignment',
      properties: {
        costAssignment: {
          type: Object,
          notify: true
        },
        costStructureEndpoint: {
          type: String,
        },
        wbsOptions: {
          type: Array,
          value: function() {
            return [];
          },
        },
        wbsLoading: {
          type: Boolean,
          value: false,
          notify: true
        },
        user: {
          type: Object,
        },
        structure: {
          type: Object,
          value: {}
        },
        invalidShares: {
          type: Boolean,
          value: false
        },
        defaultBusinessArea: {
          type: Object,
        },
        disableBusinessArea: {
          type: Boolean,
          value: true,
          computed: '_computeDisableBusinessArea(computedPermission.business_area.disabled, costAssignment.delegate)'
        },
        disableGrant: {
          type: Boolean,
          value: true,
          computed: '_computeDisableGrant(computedPermission.grant.disabled, costAssignment.wbs)'
        },
        disableFund: {
          type: Boolean,
          value: true,
          computed: '_computeDisableFund(computedPermission.fund.disabled, costAssignment.grant)'
        },
        disableShare: {
          type: Boolean,
          value: true,
          computed: '_computeDisableShare(computedPermission.share.disabled, costAssignment.fund)'
        },
        grantOptions: {
          type: Array,
          computed: '_computeGrantOptions(costAssignment.wbs.*, costAssignment.*)',
        },
        fundOptions: {
          type: Array,
          computed: '_computeFundOptions(costAssignment.grant.*, costAssignment.*)',
        },
      },

      behaviors: [et2fBehaviors.PermissionLayer, et2fBehaviors.ApiBehavior],

      observers: [
        '_observeDefaultBusinessArea(defaultBusinessArea, costAssignment.*)',
        '_costAssignmentObserver(costAssignment.*)',
        '_businessAreaChanged(costAssignment.business_area, user)',
      ],

      _isInList: function(list, value) {
        if (!value || !list) {
          return false;
        }
        return list.some(function(item) {
          return item.value === value.value;
        });
      },

      _observeDefaultBusinessArea: function(defaultBusinessArea, costAssignmentChanged) {
        var businessArea = defaultBusinessArea;
        if (costAssignmentChanged && costAssignmentChanged.base) {
          businessArea = costAssignmentChanged.base.business_area;
          businessArea = businessArea ? businessArea : defaultBusinessArea;
        }
        this.set('costAssignment.business_area', businessArea);
      },

      _costAssignmentObserver: function(costAssignmentChanged) {
        if (costAssignmentChanged.base && !costAssignmentChanged.base._validationFunction) {
            costAssignmentChanged.base._validationFunction = this._validateCostAssignment.bind(this);
        }
        this[costAssignmentChanged.path] = costAssignmentChanged.value;
      },

      _computeDisableBusinessArea: function(permission, delegate, businessArea) {
        if (!delegate) {
          this.set('costAssignment.business_area', this.defaultBusinessArea);
        }
        return permission || !delegate;
      },

      _computeDisableGrant: function(permission, wbs) {
        return permission || !(wbs && wbs.grants !== []);
      },

      _computeDisableFund: function(permission, grant) {
        return permission || !(grant && grant.funds !== []);
      },

      _computeDisableShare: function(permission, fund) {
        return permission || !fund;
      },

      _computeGrantOptions: function(wbsCh, costAssignmentCh) {
        if (costAssignmentCh.path === 'costAssignment.fund' || costAssignmentCh.path === 'costAssignment.grant') {
          return this.grantOptions;
        }
        if (wbsCh && wbsCh.base) {
          var wbs = wbsCh.base;
          var grantOptions = wbs.grants;
          var grant = costAssignmentCh.base.grant;
          if (!this._isInList(grantOptions, grant) && !wbs.toProcess) {
            this.set('costAssignment.grant', null);
            this.set('costAssignment.fund', null);
          }
          return grantOptions;
        } else if (!wbsCh.base) {
          // Selected empty
          this.set('costAssignment.grant', null);
          this.set('costAssignment.fund', null);
          return [];
        }
      },

      _computeFundOptions: function(grantCh, costAssignmentCh) {
        if (grantCh && grantCh.base) {
          var grant = grantCh.base;
          var fundOptions = grant.funds;
          var fund = costAssignmentCh.base.fund;
          if (!this._isInList(fundOptions, fund) && !grant.toProcess) {
            this.set('costAssignment.fund', null);
          }
          return fundOptions;
        } else if (!grantCh.base) {
          // Selected empty
          this.set('costAssignment.fund', null);
          return [];
        }
      },

      _validateCostAssignment: function() {
        return this.$.cost_assignment_form.validate();
      },

      // Handling incoming cost_structure, mapping values, if have them
      _handleCostStructure: function(e, data) {
        var self = this;
        var parsed = this.parseCostStructure(data);
        this.set('wbsOptions', parsed.wbs);

        if (this.costAssignment.wbs && this.costAssignment.wbs.toProcess === true) {
          this.set('costAssignment.wbs', parsed.wbs.find(function(newWbs) {
            return newWbs.value === self.costAssignment.wbs.value;
          }));
        }

        if (this.costAssignment.grant && this.costAssignment.grant.toProcess === true) {
          this.set('costAssignment.grant', parsed.grants.find(function(newGrant) {
            return newGrant.value === self.costAssignment.grant.value;
          }));
        }

        if (this.costAssignment.fund && this.costAssignment.fund.toProcess === true) {
          this.set('costAssignment.fund', parsed.funds.find(function(newFund) {
            return newFund.value === self.costAssignment.fund.value;
          }));
        }
      },

      _businessAreaChanged: function(business_area, user) {
        // Reset dropdowns on non-compatible business-area code, or not toProcess
        var differentCountryCode = this.costAssignment &&
                                   !!this.costAssignment.wbs &&
                                   !!this.costAssignment.wbs.business_area &&
                                   (business_area.value !== this.costAssignment.wbs.business_area);
        var toProcess = this.costAssignment && this.costAssignment.wbs && this.costAssignment.wbs.toProcess !== false;

        if (differentCountryCode || !toProcess) {
          this.set('costAssignment.wbs', null);
          this.set('costAssignment.grant', null);
          this.set('costAssignment.fund', null);
        } else {
          Polymer.dom(this.$.wbs).flush();
          Polymer.dom(this.$.grant).flush();
          Polymer.dom(this.$.fund).flush();
        }

        // If its users default area, set dropdown options to it
        if (business_area.value === user.t2f.business_area) {
          this.set('wbsOptions', this.structure.wbs);

        // If not, start downloading options set
        } else {
          this.set('wbsOptions', []);
          this.set('costStructureEndpoint', undefined);
          this.set('costStructureEndpoint', '/api/wbs_grants_funds/?business_area=' + business_area.id);
        }
      }
    });
  </script>
</dom-module>
<commit_msg>Dynamic-align on cost-asignment<commit_after><link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../../bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="../../../bower_components/paper-input/paper-textarea.html">
<link rel="import" href="../../../bower_components/etools-repeatable-field-set/etools-repeatable-field-set.html">
<link rel="import" href="../../../bower_components/etools-searchable-multiselection-menu/etools-searchable-multiselection-menu.html">
<link rel="import" href="../../../bower_components/etools-ajax/etools-ajax.html">

<link rel="import" href="../travel-elements/travel-status.html">

<link rel="import" href="../../styles/shared-styles.html">
<link rel="import" href="../../styles/et2f-styles.html">

<dom-module id="travel-cost-assignment">
  <template>
    <style include="shared-styles et2f-styles iron-flex iron-flex-alignment iron-flex-factors">

      :host {
        display: block;
        width: 100%;
      }

    </style>

    <etools-ajax url="[[costStructureEndpoint]]"
      loading="{{wbsLoading}}"
      on-success="_handleCostStructure"
      ></etools-ajax>

    <form is="iron-form"
      id="cost_assignment_form"
      class="layout vertical flex">

      <div class="layout horizontal">

        <etools-searchable-multiselection-menu label="Business Area"
          class$="flex-4 [[computedPermission.business_area.readOnly]]"
          options="[[structure.business_areas]]"
          empty-value
          dynamic-align
          value="{{costAssignment.business_area}}"
          disabled="[[disableBusinessArea]]"
          hidden$="[[computedPermission.business_area.hidden]]"
          placeholder="select"
          required$="[[computedPermission.business_area.required]]"
          starred>
        </etools-searchable-multiselection-menu>

        <paper-checkbox class$="custom-margin self-end flex-3 [[computedPermission.delegate.readOnly]]"
          hidden$="[[computedPermission.delegate.hidden]]"
          checked="{{costAssignment.delegate}}"
          disabled="[[computedPermission.delegate.disabled]]"
          >Delegate
        </paper-checkbox>

        <div class="flex-5"></div>
      </div>

      <div class="layout horizontal">

        <etools-searchable-multiselection-menu label="WBS"
          id="wbs"
          class$="flex-4 [[computedPermission.wbs.readOnly]]"
          options="[[wbsOptions]]"
          empty-value
          dynamic-align
          value="{{costAssignment.wbs}}"
          disabled="[[computedPermission.wbs.disabled]]"
          hidden$="[[computedPermission.wbs.hidden]]"
          placeholder="select"
          required$="[[computedPermission.wbs.required]]"
          starred>
        </etools-searchable-multiselection-menu>

        <etools-searchable-multiselection-menu label="Grant"
          id="grant"
          class$="flex-3 [[computedPermission.grant.readOnly]]"
          options="[[grantOptions]]"
          value="{{costAssignment.grant}}"
          disabled="[[disableGrant]]"
          hidden$="[[computedPermission.grant.hidden]]"
          empty-value
          dynamic-align
          required$="[[computedPermission.grant.required]]"
          placeholder="select"
          starred>
        </etools-searchable-multiselection-menu>

        <etools-searchable-multiselection-menu label="Fund"
          id="fund"
          class$="flex-3 [[computedPermission.fund.readOnly]]"
          options="[[fundOptions]]"
          value="{{costAssignment.fund}}"
          disabled="[[disableFund]]"
          empty-value
          dynamic-align
          hidden$="[[computedPermission.fund.hidden]]"
          required$="[[computedPermission.fund.required]]"
          placeholder="select"
          starred>
        </etools-searchable-multiselection-menu>

        <paper-input label="Share (%)"
          class$="flex-2 custom-margin [[computedPermission.share.readOnly]]"
          value="{{costAssignment.share}}"
          disabled="[[disableShare]]"
          hidden$="[[computedPermission.share.hidden]]"
          type="number"
          min="0"
          max="100"
          required$="[[computedPermission.share.required]]"
          step="1"
          pattern="^(100|([1-9]{0,1})?([0-9]{0,1})?)$"
          placeholder="add"
          invalid="[[invalidShares]]"
          starred>
          <span suffix>%</span>
        </paper-input>
      </div>
    </form>
  </template>

  <script>
    Polymer({
      is: 'travel-cost-assignment',
      properties: {
        costAssignment: {
          type: Object,
          notify: true
        },
        costStructureEndpoint: {
          type: String,
        },
        wbsOptions: {
          type: Array,
          value: function() {
            return [];
          },
        },
        wbsLoading: {
          type: Boolean,
          value: false,
          notify: true
        },
        user: {
          type: Object,
        },
        structure: {
          type: Object,
          value: {}
        },
        invalidShares: {
          type: Boolean,
          value: false
        },
        defaultBusinessArea: {
          type: Object,
        },
        disableBusinessArea: {
          type: Boolean,
          value: true,
          computed: '_computeDisableBusinessArea(computedPermission.business_area.disabled, costAssignment.delegate)'
        },
        disableGrant: {
          type: Boolean,
          value: true,
          computed: '_computeDisableGrant(computedPermission.grant.disabled, costAssignment.wbs)'
        },
        disableFund: {
          type: Boolean,
          value: true,
          computed: '_computeDisableFund(computedPermission.fund.disabled, costAssignment.grant)'
        },
        disableShare: {
          type: Boolean,
          value: true,
          computed: '_computeDisableShare(computedPermission.share.disabled, costAssignment.fund)'
        },
        grantOptions: {
          type: Array,
          computed: '_computeGrantOptions(costAssignment.wbs.*, costAssignment.*)',
        },
        fundOptions: {
          type: Array,
          computed: '_computeFundOptions(costAssignment.grant.*, costAssignment.*)',
        },
      },

      behaviors: [et2fBehaviors.PermissionLayer, et2fBehaviors.ApiBehavior],

      observers: [
        '_observeDefaultBusinessArea(defaultBusinessArea, costAssignment.*)',
        '_costAssignmentObserver(costAssignment.*)',
        '_businessAreaChanged(costAssignment.business_area, user)',
      ],

      _isInList: function(list, value) {
        if (!value || !list) {
          return false;
        }
        return list.some(function(item) {
          return item.value === value.value;
        });
      },

      _observeDefaultBusinessArea: function(defaultBusinessArea, costAssignmentChanged) {
        var businessArea = defaultBusinessArea;
        if (costAssignmentChanged && costAssignmentChanged.base) {
          businessArea = costAssignmentChanged.base.business_area;
          businessArea = businessArea ? businessArea : defaultBusinessArea;
        }
        this.set('costAssignment.business_area', businessArea);
      },

      _costAssignmentObserver: function(costAssignmentChanged) {
        if (costAssignmentChanged.base && !costAssignmentChanged.base._validationFunction) {
            costAssignmentChanged.base._validationFunction = this._validateCostAssignment.bind(this);
        }
        this[costAssignmentChanged.path] = costAssignmentChanged.value;
      },

      _computeDisableBusinessArea: function(permission, delegate, businessArea) {
        if (!delegate) {
          this.set('costAssignment.business_area', this.defaultBusinessArea);
        }
        return permission || !delegate;
      },

      _computeDisableGrant: function(permission, wbs) {
        return permission || !(wbs && wbs.grants !== []);
      },

      _computeDisableFund: function(permission, grant) {
        return permission || !(grant && grant.funds !== []);
      },

      _computeDisableShare: function(permission, fund) {
        return permission || !fund;
      },

      _computeGrantOptions: function(wbsCh, costAssignmentCh) {
        if (costAssignmentCh.path === 'costAssignment.fund' || costAssignmentCh.path === 'costAssignment.grant') {
          return this.grantOptions;
        }
        if (wbsCh && wbsCh.base) {
          var wbs = wbsCh.base;
          var grantOptions = wbs.grants;
          var grant = costAssignmentCh.base.grant;
          if (!this._isInList(grantOptions, grant) && !wbs.toProcess) {
            this.set('costAssignment.grant', null);
            this.set('costAssignment.fund', null);
          }
          return grantOptions;
        } else if (!wbsCh.base) {
          // Selected empty
          this.set('costAssignment.grant', null);
          this.set('costAssignment.fund', null);
          return [];
        }
      },

      _computeFundOptions: function(grantCh, costAssignmentCh) {
        if (grantCh && grantCh.base) {
          var grant = grantCh.base;
          var fundOptions = grant.funds;
          var fund = costAssignmentCh.base.fund;
          if (!this._isInList(fundOptions, fund) && !grant.toProcess) {
            this.set('costAssignment.fund', null);
          }
          return fundOptions;
        } else if (!grantCh.base) {
          // Selected empty
          this.set('costAssignment.fund', null);
          return [];
        }
      },

      _validateCostAssignment: function() {
        return this.$.cost_assignment_form.validate();
      },

      // Handling incoming cost_structure, mapping values, if have them
      _handleCostStructure: function(e, data) {
        var self = this;
        var parsed = this.parseCostStructure(data);
        this.set('wbsOptions', parsed.wbs);

        if (this.costAssignment.wbs && this.costAssignment.wbs.toProcess === true) {
          this.set('costAssignment.wbs', parsed.wbs.find(function(newWbs) {
            return newWbs.value === self.costAssignment.wbs.value;
          }));
        }

        if (this.costAssignment.grant && this.costAssignment.grant.toProcess === true) {
          this.set('costAssignment.grant', parsed.grants.find(function(newGrant) {
            return newGrant.value === self.costAssignment.grant.value;
          }));
        }

        if (this.costAssignment.fund && this.costAssignment.fund.toProcess === true) {
          this.set('costAssignment.fund', parsed.funds.find(function(newFund) {
            return newFund.value === self.costAssignment.fund.value;
          }));
        }
      },

      _businessAreaChanged: function(business_area, user) {
        // Reset dropdowns on non-compatible business-area code, or not toProcess
        var differentCountryCode = this.costAssignment &&
                                   !!this.costAssignment.wbs &&
                                   !!this.costAssignment.wbs.business_area &&
                                   (business_area.value !== this.costAssignment.wbs.business_area);
        var toProcess = this.costAssignment && this.costAssignment.wbs && this.costAssignment.wbs.toProcess !== false;

        if (differentCountryCode || !toProcess) {
          this.set('costAssignment.wbs', null);
          this.set('costAssignment.grant', null);
          this.set('costAssignment.fund', null);
        } else {
          Polymer.dom(this.$.wbs).flush();
          Polymer.dom(this.$.grant).flush();
          Polymer.dom(this.$.fund).flush();
        }

        // If its users default area, set dropdown options to it
        if (business_area.value === user.t2f.business_area) {
          this.set('wbsOptions', this.structure.wbs);

        // If not, start downloading options set
        } else {
          this.set('wbsOptions', []);
          this.set('costStructureEndpoint', undefined);
          this.set('costStructureEndpoint', '/api/wbs_grants_funds/?business_area=' + business_area.id);
        }
      }
    });
  </script>
</dom-module>

{'fraction_non_alphanumeric': 0.13750205964738837, 'fraction_numerical': 0.002553962761575218, 'mean_word_length': 2.281119070144614, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1462515', 'n_tokens_mistral': 6744, 'n_tokens_neox': 6655, 'n_words': 1024}