<commit_before>import {pageCommonStyles} from '../../../../../../styles/page-common-styles';
import {gridLayoutStyles} from '../../../../../../styles/grid-layout-styles';
import {SharedStyles} from '../../../../../../styles/shared-styles';
import '@unicef-polymer/etools-data-table/etools-data-table.js';
import '@unicef-polymer/etools-content-panel';
import '@unicef-polymer/etools-loading';
import '@polymer/paper-icon-button';
import '@polymer/paper-button';
import '@polymer/iron-icons/editor-icons';
import {html, PolymerElement} from '@polymer/polymer/polymer-element';
import {getUniqueId} from '../../../../../../utils/utils';
import {property} from '@polymer/decorators/lib/decorators';
import {sendRequest} from '@unicef-polymer/etools-ajax/etools-ajax-request';
import EndpointsMixin from '../../../../../../endpoints/endpoints-mixin';
import clone from 'lodash-es/clone';
import {monitoringActivitiesStyles} from './monitoring-activities.styles';
import {parseRequestErrorsAndShowAsToastMsgs} from '@unicef-polymer/etools-ajax/ajax-error-parser';
import {Partner} from '../../../../../../../models/partners.models';

type ActivitiesGroup = {
  activities: MonitoringActivity[];
  id: string;
};

enum DragAndDropClasses {
  originGroup = 'origin-group',
  originRow = 'original-row',
  row = 'row',
  cloned = 'cloned-row',
  activities = 'activities',
  hovered = 'hovered',
  removeBtn = 'remove',
  grouped = 'grouped'
}

export class MonitoringActivities extends EndpointsMixin(PolymerElement) {
  static get template() {
    return html`
      ${pageCommonStyles} ${gridLayoutStyles} ${SharedStyles} ${monitoringActivitiesStyles}
      <etools-content-panel
        id="monitoring-activities-panel"
        class="content-section"
        panel-title="Monitoring Activities"
      >
        <template is="dom-if" if="[[showEditBtn(activities, isReadonly)]]">
          <div slot="panel-btns">
            <paper-icon-button icon="create" title="Edit" on-click="startEdit"> </paper-icon-button>
          </div>
        </template>

        <etools-loading active="[[loading]]"></etools-loading>

        <template is="dom-if" if="[[!activities.length]]">
          <div class="no-activities">There are no activities</div>
        </template>

        <template is="dom-if" if="[[activities.length]]">
          <div class="row panel-row-tall layout-horizontal">
            <etools-data-table-column class="flex-2 cell">Reference #</etools-data-table-column>
            <etools-data-table-column class="flex-1 cell">Start Date</etools-data-table-column>
            <etools-data-table-column class="flex-1 cell">End Date</etools-data-table-column>
            <etools-data-table-column class="flex-2 cell">Location (Site)</etools-data-table-column>
          </div>
        </template>

        <template is="dom-repeat" items="[[mappedGroups]]">
          <div class$="activities [[groupedClass(item.activities.length)]]" data-group-id$="[[item.id]]">
            <div class="braces">
              <div class="description">Count as one</div>
            </div>
            <div class="remove" data-is-remove>
              <div class="remove-button">
                <div class="description">Remove from group</div>
              </div>
            </div>
            <template is="dom-repeat" items="[[item.activities]]" as="activity">
              <div class="row layout-horizontal" data-group-id$="[[item.id]]" data-activity-id$="[[activity.id]]">
                <div class="flex-2 cell">
                  <iron-icon
                    hidden$="[[!editMode]]"
                    class="flex-none"
                    icon="editor:drag-handle"
                    on-mousedown="startDrag"
                  ></iron-icon>
                  <template is="dom-if" if="[[!editMode]]">
                    <a target="_blank" title="[[activity.id]]" href$="/fm/activities/[[activity.id]]/details">
                      [[activity.reference_number]]
                    </a>
                  </template>
                  <template is="dom-if" if="[[editMode]]">[[activity.reference_number]]</template>
                </div>
                <div class="flex-1 cell">[[activity.start_date]]</div>
                <div class="flex-1 cell">[[activity.end_date]]</div>
                <div class="flex-2 cell">[[locationAndSite(activity.location.name, activity.location_site.name)]]</div>
              </div>
            </template>
          </div>
        </template>
        <div class="actions" hidden$="[[!editMode]]">
          <paper-button on-tap="cancelEdit">Cancel</paper-button>
          <paper-button raised class="save" on-tap="saveGroups">Save</paper-button>
        </div>
      </etools-content-panel>
    `;
  }

  @property({type: Array})
  set activityGroups(groups: number[][]) {
    if (groups) {
      this.groups = clone(groups);
      this.originalGroups = groups;
      this.mapActivitiesToGroups();
    }
  }

  @property({type: Boolean})
  isReadonly = true;

  @property({type: Boolean})
  loading = true;

  @property({type: Boolean})
  editMode = false;

  @property({type: Number})
  set partnerId(id: number) {
    if (this._partnerId !== id) {
      this._partnerId = id;
      this.loadActivities();
    }
  }

  @property({type: Array})
  activities: MonitoringActivity[] | null = null;
  groups: number[][] | null = null;
  originalGroups: number[][] | null = null;

  @property({type: Object})
  mappedGroups: ActivitiesGroup[] = [];

  private offset: any = {
    x: 0,
    y: 0
  };
  private clonedRow: HTMLElement | null = null;
  private groupsBoundingMap: Map<HTMLElement, ClientRect> = new Map();
  private currentlyHoveredElement: HTMLElement | null = null;
  private _partnerId!: number;

  connectedCallback(): void {
    super.connectedCallback();
    this.onMouseMove = this.onMouseMove.bind(this);
    this.onMouseUp = this.onMouseUp.bind(this);
  }

  loadActivities() {
    this.mappedGroups = [];
    this.loading = true;
    sendRequest({
      endpoint: this.getEndpoint('partnerActivities', {id: this._partnerId})
    }).then((response: any) => {
      this.activities = response.results;
      this.mapActivitiesToGroups();
      this.loading = false;
    });
  }

  showEditBtn(activities: MonitoringActivity[], isReadonly: boolean): boolean {
    return Boolean(activities?.length) && !isReadonly;
  }

  startEdit() {
    this.editMode = true;
  }

  cancelEdit() {
    this.groups = clone(this.originalGroups);
    this.editMode = false;<commit_msg>[ch26818] Prevent loading activities if partnerId is not defined (#1722) (#1732)<commit_after>import {pageCommonStyles} from '../../../../../../styles/page-common-styles';
import {gridLayoutStyles} from '../../../../../../styles/grid-layout-styles';
import {SharedStyles} from '../../../../../../styles/shared-styles';
import '@unicef-polymer/etools-data-table/etools-data-table.js';
import '@unicef-polymer/etools-content-panel';
import '@unicef-polymer/etools-loading';
import '@polymer/paper-icon-button';
import '@polymer/paper-button';
import '@polymer/iron-icons/editor-icons';
import {html, PolymerElement} from '@polymer/polymer/polymer-element';
import {getUniqueId} from '../../../../../../utils/utils';
import {property} from '@polymer/decorators/lib/decorators';
import {sendRequest} from '@unicef-polymer/etools-ajax/etools-ajax-request';
import EndpointsMixin from '../../../../../../endpoints/endpoints-mixin';
import clone from 'lodash-es/clone';
import {monitoringActivitiesStyles} from './monitoring-activities.styles';
import {parseRequestErrorsAndShowAsToastMsgs} from '@unicef-polymer/etools-ajax/ajax-error-parser';
import {Partner} from '../../../../../../../models/partners.models';

type ActivitiesGroup = {
  activities: MonitoringActivity[];
  id: string;
};

enum DragAndDropClasses {
  originGroup = 'origin-group',
  originRow = 'original-row',
  row = 'row',
  cloned = 'cloned-row',
  activities = 'activities',
  hovered = 'hovered',
  removeBtn = 'remove',
  grouped = 'grouped'
}

export class MonitoringActivities extends EndpointsMixin(PolymerElement) {
  static get template() {
    return html`
      ${pageCommonStyles} ${gridLayoutStyles} ${SharedStyles} ${monitoringActivitiesStyles}
      <etools-content-panel
        id="monitoring-activities-panel"
        class="content-section"
        panel-title="Monitoring Activities"
      >
        <template is="dom-if" if="[[showEditBtn(activities, isReadonly)]]">
          <div slot="panel-btns">
            <paper-icon-button icon="create" title="Edit" on-click="startEdit"> </paper-icon-button>
          </div>
        </template>

        <etools-loading active="[[loading]]"></etools-loading>

        <template is="dom-if" if="[[!activities.length]]">
          <div class="no-activities">There are no activities</div>
        </template>

        <template is="dom-if" if="[[activities.length]]">
          <div class="row panel-row-tall layout-horizontal">
            <etools-data-table-column class="flex-2 cell">Reference #</etools-data-table-column>
            <etools-data-table-column class="flex-1 cell">Start Date</etools-data-table-column>
            <etools-data-table-column class="flex-1 cell">End Date</etools-data-table-column>
            <etools-data-table-column class="flex-2 cell">Location (Site)</etools-data-table-column>
          </div>
        </template>

        <template is="dom-repeat" items="[[mappedGroups]]">
          <div class$="activities [[groupedClass(item.activities.length)]]" data-group-id$="[[item.id]]">
            <div class="braces">
              <div class="description">Count as one</div>
            </div>
            <div class="remove" data-is-remove>
              <div class="remove-button">
                <div class="description">Remove from group</div>
              </div>
            </div>
            <template is="dom-repeat" items="[[item.activities]]" as="activity">
              <div class="row layout-horizontal" data-group-id$="[[item.id]]" data-activity-id$="[[activity.id]]">
                <div class="flex-2 cell">
                  <iron-icon
                    hidden$="[[!editMode]]"
                    class="flex-none"
                    icon="editor:drag-handle"
                    on-mousedown="startDrag"
                  ></iron-icon>
                  <template is="dom-if" if="[[!editMode]]">
                    <a target="_blank" title="[[activity.id]]" href$="/fm/activities/[[activity.id]]/details">
                      [[activity.reference_number]]
                    </a>
                  </template>
                  <template is="dom-if" if="[[editMode]]">[[activity.reference_number]]</template>
                </div>
                <div class="flex-1 cell">[[activity.start_date]]</div>
                <div class="flex-1 cell">[[activity.end_date]]</div>
                <div class="flex-2 cell">[[locationAndSite(activity.location.name, activity.location_site.name)]]</div>
              </div>
            </template>
          </div>
        </template>
        <div class="actions" hidden$="[[!editMode]]">
          <paper-button on-tap="cancelEdit">Cancel</paper-button>
          <paper-button raised class="save" on-tap="saveGroups">Save</paper-button>
        </div>
      </etools-content-panel>
    `;
  }

  @property({type: Array})
  set activityGroups(groups: number[][]) {
    if (groups) {
      this.groups = clone(groups);
      this.originalGroups = groups;
      this.mapActivitiesToGroups();
    }
  }

  @property({type: Boolean})
  isReadonly = true;

  @property({type: Boolean})
  loading = true;

  @property({type: Boolean})
  editMode = false;

  @property({type: Number})
  set partnerId(id: number) {
    if (this._partnerId !== id) {
      this._partnerId = id;
      this.loadActivities();
    }
  }

  @property({type: Array})
  activities: MonitoringActivity[] | null = null;
  groups: number[][] | null = null;
  originalGroups: number[][] | null = null;

  @property({type: Object})
  mappedGroups: ActivitiesGroup[] = [];

  private offset: any = {
    x: 0,
    y: 0
  };
  private clonedRow: HTMLElement | null = null;
  private groupsBoundingMap: Map<HTMLElement, ClientRect> = new Map();
  private currentlyHoveredElement: HTMLElement | null = null;
  private _partnerId!: number;

  connectedCallback(): void {
    super.connectedCallback();
    this.onMouseMove = this.onMouseMove.bind(this);
    this.onMouseUp = this.onMouseUp.bind(this);
  }

  loadActivities() {
    this.mappedGroups = [];
    if (!this._partnerId) {
      return;
    }
    this.loading = true;
    sendRequest({
      endpoint: this.getEndpoint('partnerActivities', {id: this._partnerId})
    }).then((response: any) => {
      this.activities = response.results;
      this.mapActivitiesToGroups();
      this.loading = false;
    });
  }

  showEditBtn(activities: MonitoringActivity[], isReadonly: boolean): boolean {
    return Boolean(activities?.length) && !isReadonly;
  }

  startEdit() {
    this.editMode = true;
  }

  cancelEdit() {
    this.groups = clone(this.originalGroups);
    this.editMode = false;
{'fraction_non_alphanumeric': 0.17189041511724976, 'fraction_numerical': 0.0025043636639599303, 'mean_word_length': 2.708978328173375, 'pattern_counts': {'":': 0, '<': 137, '<?xml version=': 0, '>': 139, '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': '4829984', 'n_tokens_mistral': 4010, 'n_tokens_neox': 3912, 'n_words': 718}