{% extends "admin/base_site_grid.html" %}
{% load i18n %}
{% load static %}

{% block extrastyle %}{{block.super}}
<style>
#attributes-supplyinformation thead tr td,
#attributes-networkstatus thead tr td,
#attributes-downstreamoperationplans thead tr td,
#attributes-upstreamoperationplans thead tr td,
#attributes-operationproblems thead tr td,
#attributes-operationresources thead tr td,
#attributes-operationflowplans thead tr td,
#attributes-operationdemandpegging thead tr td,
#attributes-inventorydata thead tr td {
  border-bottom-width: 1px;
  border-bottom-style: solid;
  border-bottom-color: #bbb;
}

rect.opplan {
  vector-effect: non-scaling-stroke;
  stroke-width: 1px;
  stroke: rgb(0,0,0);
}

/* Button group icons */
.btn-primary.active:disabled {
  background-color: var(--bs-btn-active-bg);
}
</style>
{% endblock %}

{% block extrahead %}
<script>
  function getVisibleSelectedIds() {
    pageIDs = (jQuery("#grid").jqGrid && jQuery("#grid").jqGrid('getDataIDs')) || [];
    const vueSelectedOperationPlans = (upload.selectedRows || []).map((op) => op.reference || op);

    // filter out selected IDs that do not belong to this page
    upload.selectedRows = pageIDs.filter((id) => vueSelectedOperationPlans.includes(id));

    return upload.selectedRows;
  }

  // Expose to global scope for use in jqGrid callbacks
  window.getVisibleSelectedIds = getVisibleSelectedIds;
</script>
{{block.super}}
<script src="{{STATIC_URL}}js/d3.min.js"></script>

{% if debug_js %}
<script type="module" src="http://localhost:5173/static/src/main.js"></script>
<script type="module" src="http://localhost:5173/static/@vite/client"></script>
{% else %}
<script src="{{STATIC_URL}}input/main.js"></script>
{% endif %}
<script>

  // Pre-load kanban card template
  window.kanban_card_template_promise = fetch('{% url "operationplandetail" %}../input/kanbancard.html')
    .then(response => response.text())
    .then(html => {
      // Strip {% verbatim %} and {% endverbatim %} if they exist
      var cleanHtml = html.replace(/\{%\s*verbatim\s*%\}/g, '').replace(/\{%\s*endverbatim\s*%\}/g, '');
      window.kanban_card_template = cleanHtml;
      return cleanHtml;
    });

  var urlParams = new URLSearchParams(window.location.search);
  var mode = preferences && preferences.mode || "table";
  var calendarmode = preferences && preferences.calendarmode || "{{reportclass.calendarmode}}";
  var grouping = preferences && preferences.grouping || null;
  var groupingdir = preferences && preferences.groupingdir || "asc";
  var editable = {% if reportclass.editable and haschangeperm %}true{% else %}false{% endif %};
  var service_url = {% if proxied %}'/svc/{{request.database}}/'{% else %}document.location.protocol + "//{{port}}/"{% endif %};
  var service_token = '{{token}}';
  var isDataSaved = false;
  // the following variables are set in Vue components
  var operationplanChanges = {};
  var pageIDs = [];

  function setActiveButton(buttonId) {
    [
      jQuery('#gridmode'),
      jQuery('#kanbanmode'),
      jQuery('#calendarmode'),
      jQuery('#ganttmode')
    ].forEach(div => div.removeClass('active'));
    jQuery(`#${buttonId}`).addClass('active');
  }

  function setVisibleByMode(mode) {
    [
      jQuery('#tablemode'),
      jQuery('#kanban'),
      jQuery('#calendar'),
      jQuery('#gantt')
    ].forEach(div => div.hasClass('d-none') ? div.removeClass('d-none').addClass('d-none') : div.addClass('d-none'));

    switch (mode) {
      case 'table': {
        preferences.mode = mode;
        jQuery('#tablemode').removeClass('d-none');
        jQuery("#grid").jqGrid('setGridParam', {datatype: 'json'}).trigger('reloadGrid');
        break;
      }
      case 'kanban': {
        preferences.mode = mode;
        jQuery('#kanban').removeClass('d-none');
        break;
      }
      case 'calendar': {
        preferences.mode = mode;
        jQuery('#calendar').removeClass('d-none');
        break;
      }
      case 'gantt': {
        preferences.mode = mode;
        jQuery('#gantt').removeClass('d-none');
        break;
      }
      case 'default': {
        break
      }
    }
  }

  function saveData(rows, ok_callback) {
      $.ajax({
        url: service_url + 'operationplan/',
        data: JSON.stringify(rows),
        type: "POST",
        headers: { "Authorization": "Bearer " + service_token },
        contentType: "application/json",
        success: function () {
          const event = new CustomEvent('triggerUndo', {
            detail: {
              execute: 'undo',
              reference: null,
              status: null,
              selectedRows: null
            }
          });
          document.getElementById('app').dispatchEvent(event);
          upload.undo();
          jQuery("#save i").addClass('hidden');
          jQuery(".ng-dirty").removeClass('ng-dirty');
          if (typeof ok_callback !== 'undefined') ok_callback();
          isDataSaved = true;
        },
        error: ajaxerror
    });
    operationplanChanges = {};
  }

  function extraPreference() {
    var tmp = {
      "height": Math.floor(jQuery("#content-main").height()),
      "width": Math.floor(jQuery("#fields").width()),
      "mode": mode,
      "calendarmode": calendarmode,
      "columns": window.appInstance?.kanbancolumns || window.preferences.columns || undefined,
      "grouping": grouping,
      "groupingdir": groupingdir,
      "detailwidth": Math.floor(jQuery("#detailspanel").width() || 0),
      "widgets": jQuery(".widget").length > 1 ? widget.getConfig() : preferences.widgets
    };
    return tmp;
  }

  function extraSearchUpdate(filter) {
    thefilter = filter;
    initialfilter = filter;
  	if (preferences && preferences.mode == "kanban") {
  	  return true;
  	}
  	else if (preferences && preferences.mode == "gantt") {
  	  return true;
  	}
    else if (preferences && preferences.mode && preferences.mode.startsWith("calendar")) {
      return true;
    }
    return false;
  }

  function setHeights(e, $el, opt) {
      // If called from the resizable plugin, $el is #content-main
      // If called manually, we use the current height of the element
      var h = ($el && $el.height) ? $el.height() : jQuery('#content-main').height();

      jQuery('#grid').setGridWidth(jQuery('#content-main').width());
      jQuery('#grid').setGridHeight(h - 60);

      jQuery('.column-body').removeClass('d-none').css('height', h - 60);
  }

  function setWidths() {
    var w = jQuery("#workarea").width() - jQuery('#detailspanel').width() - jQuery("#resize-handle").parent().width();
    jQuery('#grid').setGridWidth(w);
    jQuery("#grid").setGridHeight(jQuery('#content-main').height() - 52);
    jQuery("#kanban").css("width", w - 25);
    jQuery("#scrolldayview").css("width", w - 25);
    jQuery("#scrollweekview").css("width", w - 60);
    jQuery("#scrollmonthview").css("width", w - 45);
  }

  function getDirtyData() {
  	if (preferences && preferences.mode && (preferences.mode == "kanban" || preferences.mode == "gantt" || preferences.mode.startsWith("calendar"))) {
      initialfilter = thefilter;
    }
  	else {
      var dirty = jQuery("#grid").getChangedCells('dirty');
      for (var c of dirty) {
        var ref = jQuery("#grid").jqGrid('getCell', c.id, "operationplan__reference");
        if (ref) c.operationplan__reference = ref;
      }
      savedData = false;
      return dirty;
    }
  }

  var language = "{{LANGUAGE_CODE}}";
  var version = '{% version_short %}';
  var lastid = '';
  var preferences = {{ preferences | json }};
  var default_operationplan_type = "{{ default_operationplan_type }}";
  var groupBy = "{{ groupBy }}";
  var thefilter = initialfilter;
  var groupingcfg = {{ groupingcfg | json }};
  var currentdate = new Date("{{ currentdate|date:'Y-m-d' }}");

  var horizonstart = new Date({{request.report_startdate|date:"Y"}},{{request.report_startdate|date:"n"}}-1,{{request.report_startdate|date:"j"}});
  var horizonend = new Date({{request.report_enddate|date:"Y"}},{{request.report_enddate|date:"n"}}-1,{{request.report_enddate|date:"j"}});
  var viewstart = new Date(horizonstart.getTime());
  var viewend = new Date(horizonend.getTime());


  jQuery(function() {
    jQuery("#workarea").css('overflow-x','visible');
    jQuery("#content-main").resizable({
      handleSelector: "#resize-handle",
      resizeWidth: false,
      resizeHeight: true,
      onDrag: setHeights,
      onDragEnd: function (e, $el, opt) {
        if (typeof preferences !== 'undefined') {
          preferences.height = Math.floor(jQuery("#content-main").height());
        }
        grid.saveColumnConfiguration();
      }
    });
    jQuery("#save").on('click', function() {
      jQuery(window).off('beforeunload', upload.warnUnsavedChanges);

      if (mode === 'kanban') {
        // Dispatch event to Vue component for kanban mode
        const event = new CustomEvent('triggerSave', {
          detail: {
            execute: 'triggerSave',
            reference: null,
            status: null,
            selectedRows: null
          }
        });
        document.getElementById('app').dispatchEvent(event);
      } else {
        // Use existing jqGrid save for table mode
        upload.save();
      }
    });
    jQuery("#undo").on('click', function() {
      jQuery(window).off('beforeunload', upload.warnUnsavedChanges);


        // Dispatch event to Vue component for kanban mode
        const event = new CustomEvent('triggerUndo', {
          detail: {
            execute: 'undo',
            reference: null,
            status: null,
            selectedRows: null
          }
        });
        document.getElementById('app').dispatchEvent(event);

        // Use existing jqGrid undo for table mode
        upload.undo();

    });
    jQuery("#actionsul li a, button#actions1").off('click').on('click', function(event) {
      let action = jQuery(this).attr('name') || jQuery(this).prop('name');
      if (!action) {
        // Dropdown menu items
        action = jQuery(this).parent().attr('name') || jQuery(this).parent().prop('name');
      }
      if (!action && jQuery("#actions").length) {
        action = jQuery("#actions").val();
      }

      if ((mode === 'kanban' || mode.startsWith('calendar')) && action === 'erp_incr_export') {
        const customEvent = new CustomEvent("triggerERPExport", {
          detail: { mode: mode }
        });
        document.getElementById('app').dispatchEvent(customEvent);
      } else if (action) {
        const customEvent = new CustomEvent("refreshStatus", {
          detail: {
            execute: 'refreshStatus',
            reference: null,
            status: action,
            selectedRows: null,
          }
        });
        document.getElementById('app').dispatchEvent(customEvent);

        if (mode === 'table' || mode === 'gantt') {
          // Traditional table mode or Gantt mode
          $("#actions1 span").text($(this).text());
          $("#actions").val(action);
          grid.runAction(action);
        }
      }
      event.stopImmediatePropagation();
      event.preventDefault();
    });
    jQuery("#gridmode").on('click', function() {
      attemptModeChange('table', function() {
        mode = "table";
        const event = new CustomEvent("setMode", {
          detail: { mode: "table" }
        });
        document.getElementById('app').dispatchEvent(event);
        setVisibleByMode(mode);
        setActiveButton('gridmode');
        grid.saveColumnConfiguration();
      });
    });
    jQuery("#kanbanmode").on('click', function() {
      attemptModeChange('kanban', function() {
        preferences.height = Math.floor(jQuery("#content-main").height());
        mode = "kanban";
        const event = new CustomEvent("setMode", {
          detail: { mode: "kanban" }
        });
        document.getElementById('app').dispatchEvent(event);
        setVisibleByMode(mode);
        setActiveButton('kanbanmode');
        grid.saveColumnConfiguration();
      });
    });
    jQuery("#calendarmonth").on('click', function() {
      attemptModeChange('calendarmonth', function () {
        preferences.height = Math.floor(jQuery("#content-main").height());
        mode = "calendarmonth";
        const event = new CustomEvent("setMode", {
            detail: {mode: "calendarmonth"}
        });
        document.getElementById('app').dispatchEvent(event);
        setVisibleByMode(mode.startsWith('calendar') ? 'calendar' : mode);

        grid.saveColumnConfiguration(function () {
          location.reload();
        });
      });
    });
    jQuery("#calendarweek").on('click', function() {
      attemptModeChange('calendarweek', function () {
        preferences.height = Math.floor(jQuery("#content-main").height());
        mode = "calendarweek";
        const event = new CustomEvent("setMode", {
          detail: {mode: "calendarweek"}
        });
        document.getElementById('app').dispatchEvent(event);
        setVisibleByMode(mode.startsWith('calendar') ? 'calendar' : mode);

        grid.saveColumnConfiguration(function () {
          location.reload();
        });
      });
    });
    jQuery("#calendarday").on('click', function() {
    attemptModeChange('calendarday', function () {
      preferences.height = Math.floor(jQuery("#content-main").height());
        mode = "calendarday";
        const event = new CustomEvent("setMode", {
          detail: {mode: "calendarday"}
        });
        document.getElementById('app').dispatchEvent(event);
        setVisibleByMode(mode.startsWith('calendar') ? 'calendar' : mode);

        grid.saveColumnConfiguration(function () {
          location.reload();
        });
      });
    });
    jQuery('#zoomin').on("click", function() { zoom(0.5); });
    jQuery('#zoomout').on("click", function() { zoom(2); });
    {% if showGantt %}
    jQuery("#ganttmode").on('click', function() {
      attemptModeChange('gantt', function() {
        mode = "gantt";
        const event = new CustomEvent("setMode", {
          detail: { mode: "gantt" }
        });
        document.getElementById('app').dispatchEvent(event);
        setVisibleByMode(mode);

        grid.saveColumnConfiguration(function() {
          location.reload();
        });
      });
    });
    jQuery("#zoomin, #zoomout").removeClass("d-none");
    {% endif %}

    setActiveButton(mode.startsWith('calendar') ? 'calendarmode' : (mode == "table") ? 'gridmode' : (mode + 'mode'));
    setVisibleByMode(mode.startsWith('calendar') ? 'calendar' : mode);
  });

  // Controller will call this function to pass values to the grid
  function displayongrid(reference, id, columnid, value) {
    if (!columnid) return;
    var grid = jQuery("#grid");
    // Resolve row id from reference when id is not provided
    if (!id) {
      var rowids = grid.jqGrid('getDataIDs');
      if (rowids.indexOf(String(reference)) === -1) {
        for (var i = 0; i < rowids.length; i++) {
          var ref = grid.jqGrid('getCell', rowids[i], 'operationplan__reference');
          if (String(ref) === String(reference)) {
            id = rowids[i];
            break;
          }
        }
      } else {
        id = reference;
      }
    }

    if (!id) return;

    jQuery("#"+id).removeClass("edited").addClass("edited");


    if ( ["startdate", "enddate", "quantity", "quantity_completed", "remark", "status"].includes(columnid) ||
      (columnid === "status" && ['proposed', 'approved', 'confirmed', 'completed', 'closed'].indexOf(value) > -1)
    ) {
      if (["freppledb.input.views.capacity.ResourceDetail", "freppledb.input.views.inventory.InventoryDetail"].includes(window.reportkey)) {
        columnid = 'operationplan__' + columnid;
      }
      jQuery("#grid").jqGrid("setCell", id, columnid, value, "dirty-cell");
      jQuery("#save, #undo").removeClass("btn-primary btn-danger").addClass("btn-danger").prop("disabled", false);
      jQuery(window).off('beforeunload', upload.warnUnsavedChanges);
      jQuery(window).on('beforeunload', upload.warnUnsavedChanges);
    }
  }

  window.displayongrid = displayongrid;
  window.setHeights = setHeights;

  jQuery("#workarea").css('overflow-x', 'visible');
  jQuery("#resize-handle").css({ 'display': 'inline-block' });

  // Set jqGrid single select behavior
  jQuery("#grid").jqGrid("setGridParam", { singleSelectClickMode: "selectonly" });

  // Hide message button
  jQuery("#hidemessage").on("click", function () {
    hidemessage = true;
    jQuery("#hidemessage").parent().parent().hide();
    if (typeof grid !== 'undefined' && typeof grid.saveColumnConfiguration === 'function') {
      grid.saveColumnConfiguration();
    }
  });

  // Dispatch event when grid refreshes
  document.addEventListener('DOMContentLoaded', function () {
    window.addEventListener('gridRefresh', function (event) {
      if (typeof refreshGrid === 'function') {
        refreshGrid();
      }
    });
  });

  // Apply saved content height if present
  if (window.preferences && window.preferences.height) {
    const h = Math.max(150, Math.floor(window.preferences.height));
    jQuery('#content-main').css('height', h + 'px');
    // Adjust inner widgets to the applied height
    jQuery("#grid").setGridHeight(h - 52);
  }
</script>
{% endblock %}

{% block extracontainer %}{% endblock %}

{% block tools %}{% if args %}{% include "common/snippet_follow.html" %}{% endif %}{% endblock %}

{% block tabs %}{% if args %}{% tabs model %}{% endif %}{% endblock %}

{% block actions %}
  <div class="btn-group" role="group">
    <button data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans "display table"|capfirst|force_escape %}"
      class="btn btn-sm btn-primary{% if preferences.mode != 'kanban' and preferences.mode != 'gantt' and preferences.mode != 'calendarday' and preferences.mode != 'calendarweek' and preferences.mode != 'calendarmonth' or not preferences.mode %} active{% endif %}"
      type="button" id="gridmode" name="mode">
      <span class="fa fa-table fa-lg" style="margin: 2px 0 3px 0;"></span>
    </button>
    <button data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans "display kanban cards"|capfirst|force_escape %}" class="btn btn-sm btn-primary{% if preferences.mode == 'kanban' %} active{% endif %}" type="button" id="kanbanmode" name="mode">
      <span class="fa fa-columns fa-lg fa-lg" style="margin: 2px 0 3px 0;"></span>
    </button>
    <div class="btn-group dropdown" data-bs-toggle="tooltip" data-bs-toggle="tooltip"
      data-bs-placement="top" title="{% trans "display calendar"|capfirst|force_escape %}">
      <button type="button" id="calendarmode" name="mode"
        class="btn btn-sm btn-primary dropdown-toggle{% if preferences.mode == 'calendarday' or preferences.mode == 'calendarweek' or preferences.mode == 'calendarmonth' %} active{% endif %}"
        data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        <span class="fa fa-calendar-o"></span>
        <span class="caret"></span>
      </button>
      <ul class="dropdown-menu">
        <li class="dropdown-item" id="calendarmonth"><a href="#">{% trans "month"|capfirst %}</a></li>
        <li class="dropdown-item" id="calendarweek"><a href="#">{% trans "week"|capfirst %}</a></li>
        <li class="dropdown-item" id="calendarday"><a href="#">{% trans "day"|capfirst %}</a></li>
      </ul>
    </div>
    {% if showGantt %}
    <button data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans "display Gantt chart"|capfirst|force_escape %}" class="btn btn-sm btn-primary{% if preferences.mode == 'gantt' %} active{% endif %}" type="button" id="ganttmode" name="mode">
      <span class="fa fa-align-left fa-lg fa-lg" style="margin: 2px 0 3px 0;"></span>
    </button>
    {% endif %}
  </div>
{% if hasaddperm %}<button class="btn btn-sm btn-primary" onclick="location.href='{{request.prefix}}/data/{{model|app_label}}/{{model|object_name|lower}}/add/{% if is_popup %}?_popup=1{% endif %}'" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans "Create new object"|escape %}" ><span class="fa fa-plus"></span></button>
{% endif %}{% if hasaddperm and not is_popup and reportclass.canDuplicate %}<button class="btn btn-sm btn-primary"  disabled id="copy_selected" onclick="if (mode === 'kanban') { document.getElementById('app').dispatchEvent(new CustomEvent('triggerCopy')); } else { grid.showCopy(); }" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'Copy selected objects'|capfirst|escape %}" ><span class="fa fa-copy"></span></button>
{% endif %}
<!--{% if haschangeperm and not is_popup %}<button class="btn btn-sm btn-primary" id="edit_selected" disabled onclick="grid.update('{{request.prefix}}/data/{{model|app_label}}/{{model|object_name|lower}}/')" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans "Update objects"|escape %}" ><span class="fa fa-edit"></span></button>
{% endif %}-->
{% if hasdeleteperm and not is_popup %}<button class="btn btn-sm btn-primary" id="delete_selected" disabled data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'Delete selected objects'|capfirst|escape %}" onclick="if (mode === 'kanban') { document.getElementById('app').dispatchEvent(new CustomEvent('triggerDelete', { detail: { url: '{{request.prefix}}/data/{{model|app_label}}/{{model|object_name|lower}}/' } })); } else { grid.showDelete('{{request.prefix}}/data/{{model|app_label}}/{{model|object_name|lower}}/'); }" ><span class="fa fa-minus"></span></button>
{% endif %}{% if reportclass.hasTimeBuckets %}<button class="btn btn-sm btn-primary" onclick="grid.showBucket()" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'set time horizon'|capfirst|force_escape %}" id="bucketconfig"><span class="fa fa-clock-o"></span></button>
{% endif %}<button class="btn d-none btn-sm btn-primary" id="zoomin" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'Zoom in'|capfirst|force_escape %}"><span class="fa fa-search-plus"></span></button>
<button class="btn d-none btn-sm btn-primary" id="zoomout" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'Zoom out'|capfirst|force_escape %}"><span class="fa fa-search-minus"></span></button>
{% if hasaddperm %}<button class="btn btn-sm d-none d-md-inline-block btn-primary" id="csvimport" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'Import CSV or Excel file'|capfirst|force_escape %}" onclick="import_show('', undefined, true)"><span class="fa fa-arrow-up"></span></button>
{% endif %}<button class="btn btn-sm btn-primary" onclick="grid.showExport(true,{{ scenario_permissions }})" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'export as CSV or Excel file'|capfirst|force_escape %}"><span class="fa fa-arrow-down"></span></button>
<button id="customize" class="btn btn-sm btn-primary" onclick="grid.showCustomize(false);" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="{% trans 'customize'|capfirst|force_escape %}"><span class="fa fa-wrench"></span></button>
{% endblock %}

{% block afterPageLoad %}
displayGrid({% if preferences.mode != "kanban" and preferences.mode != "gantt" and preferences.mode != "calendarday" and preferences.mode != "calendarweek" and preferences.mode != "calendarmonth" %}true{% else %}false{% endif %});
{% endblock %}

{% block extra_grid %}

onSelectRow: function(rowid, status) {
  const rowData = jQuery("#grid").getRowData(rowid);
  const reference = rowData.operationplan__reference ? rowData.operationplan__reference : rowid;

  const references = jQuery("#grid").jqGrid('getGridParam', 'selarrrow').filter(x => x.id !== 'cb').map(x => x.operationplan__reference ? x.operationplan__reference : x);
  const event = new CustomEvent("singleSelect", {
    detail: {
      execute: 'displayInfo',
      reference: reference,
      status: status,
      selectedRows: references,
    }
  });
  document.getElementById('app').dispatchEvent(event);

  var sel = jQuery("#grid").jqGrid('getGridParam', 'selarrrow') || [];
  upload.selectedRows = sel.filter(x => x.id !== 'cb');

  var visibleIds = (jQuery("#grid").jqGrid && jQuery("#grid").jqGrid('getDataIDs')) || [];
  var selectedIds = sel.map(function(x){ return (x && typeof x === 'object') ? (x.id || x.operationplan__reference || String(x)) : String(x); });
  var hasVisible = selectedIds.filter(function(id){ return id !== 'cb' && visibleIds.indexOf(id) !== -1; }).length > 0;
  ['#actions1','#actions2','#segments1','#copy_selected','#delete_selected'].forEach(function(s){ var el=jQuery(s); if (el.length) el.prop('disabled', !hasVisible); });
},
onSelectAll: function(aRowids, status){
  const event = new CustomEvent('allSelect', {
    detail: {
      execute: 'displayInfo',
      status: status,
      selectedRows: aRowids,
    }
  });
  document.getElementById('app').dispatchEvent(event);
  if (jQuery("#actions").length) jQuery("#actions1").prop('disabled', !status);
  var sel = jQuery("#grid").jqGrid('getGridParam', 'selarrrow') || [];
  upload.selectedRows = sel.filter(x => x.id !== 'cb');
  if (sel.length !== 0 && status)  {
    var visibleIds = (jQuery("#grid").jqGrid && jQuery("#grid").jqGrid('getDataIDs')) || [];
    var selectedIds = sel.map(function(x){ return (x && typeof x === 'object') ? (x.id || x.operationplan__reference || String(x)) : String(x); });
    var hasVisible = selectedIds.filter(function(id){ return id !== 'cb' && visibleIds.indexOf(id) !== -1; }).length > 0;
    ['#actions1','#actions2','#segments1','#copy_selected','#delete_selected'].forEach(function(s){ var el=jQuery(s); if (el.length) el.prop('disabled', !hasVisible); });
  }
},

afterSaveCell: function(rowid, cellname, value, iRow, iCol) {
  const rowData = jQuery("#grid").getRowData(rowid);
  const reference = rowData.operationplan__reference ? rowData.operationplan__reference : rowid;

  const event = new CustomEvent('displayonpanel', {
    detail: {
      rowid: rowid,
      reference: reference,
      field: cellname,
      value: value
    }
  });
  document.getElementById('app').dispatchEvent(event);
  isDataSaved = false;
},

multiboxonly: false,
loadComplete: function(data) {
  const pageSelectedIDs = getVisibleSelectedIds();
  const changedOperationplanReferences = Object.keys(window.operationplanChanges);
  if (changedOperationplanReferences.length > 0) {
    changedOperationplanReferences.forEach((reference) => {
      if (pageSelectedIDs.includes(reference)) {
        const changedCellsKeys = Object.keys(window.operationplanChanges[reference]);
        changedCellsKeys.forEach((field) => {
          try {
            displayongrid(reference, null, field, window.operationplanChanges[reference][field]);
          } catch (e) {
            // ignore
          }
        });
      }
    });
  }
  const IDs = Object.keys(window.operationplanChanges);

  jQuery('#curerror').html("");
  getVisibleSelectedIds().forEach(function(op) {
    jQuery("#grid").jqGrid('setSelection', op, false);
  })

  const references = jQuery("#grid").jqGrid('getGridParam', 'selarrrow').filter(x => x.id !== 'cb').map(x => x.operationplan__reference ? x.operationplan__reference : x);

  if (getVisibleSelectedIds().length === 1) {
    let event = new CustomEvent('displayonpanel', jQuery("#grid").getRowData(getVisibleSelectedIds()[0]));
    document.getElementById('app').dispatchEvent(event);

    event = new CustomEvent("singleSelect", {
      detail: {
        execute: 'displayInfo',
        reference: getVisibleSelectedIds()[0],
        status: status,
        selectedRows: references,
      }
    });
    document.getElementById('app').dispatchEvent(event);
  } else if (getVisibleSelectedIds().length > 1) {
    var selectiondata = [];
    for (var x of getVisibleSelectedIds())
      selectiondata.push(jQuery("#grid").getRowData(x));

    event = new CustomEvent('processAggregatedInfo', {
      detail: {
        selectiondata: selectiondata,
        colModel: jQuery("#grid").jqGrid ('getGridParam', 'colModel')
      }
    });
    document.getElementById('app').dispatchEvent(event);
  } else {
    const event = new CustomEvent('allSelect', {
      detail: {
        execute: 'displayInfo',
        status: false,
        selectedRows: [],
      }
    });
    document.getElementById('app').dispatchEvent(event);
  }
  // Initialize actions buttons state based on visible-page selection after load
  var sel = jQuery("#grid").jqGrid('getGridParam', 'selarrrow') || [];
  var visibleIds = (jQuery("#grid").jqGrid && jQuery("#grid").jqGrid('getDataIDs')) || [];
  var selectedIds = sel.map(function(x){ return (x && typeof x === 'object') ? (x.id || x.operationplan__reference || String(x)) : String(x); });
  var hasVisible = selectedIds.filter(function(id){ return id !== 'cb' && visibleIds.indexOf(id) !== -1; }).length > 0;
  ['#actions1','#actions2','#segments1','#copy_selected','#delete_selected'].forEach(function(s){ var el=jQuery(s); if (el.length) el.prop('disabled', !hasVisible); });

  if (window.preferences && window.preferences.height) {
    setHeights();
  }
},
{% endblock %}

{% block table %}
<div>

<div class="row text-center">
<div id="content-main" class="col-md-12" style="min-height: 150px; margin-top: 0.7em">
  <div id="tablemode">
    <table id="grid" class="table table-striped" style="background-color: white"></table>
    <div id="gridpager"></div>
  </div>
  <div id="calendar" class="col-md-12">
  </div>
  <div id="kanban" class="row"></div>
  <div id="gantt" class="row"></div>
</div>
<span id="resize-handle" class="fa fa-bars handle" style="display: inline-block"></span>
</div>

<svg width="0" height="0"><defs id="gradients"></defs></svg>
{% endblock %}

{% block after_table %}
<div id="app"></div>
<div id="popup" class="modal fade in" role="dialog" style="z-index: 10000"></div>

<script>
  // Send event to show dialog if there are unsaved changes
  function attemptModeChange(targetMode, modeChangeFunction) {
    const event = new CustomEvent("attemptModeChange", {
      detail: {
        mode: targetMode,
        modeChangeFunction: modeChangeFunction
      }
    });
    document.getElementById('app').dispatchEvent(event);
  }

  if (window.preferences && window.preferences.height) {
      const h = Math.max(150, Math.floor(window.preferences.height));
      jQuery('#content-main').css('height', h + 'px');
      // Now setHeights() will pick up the height we just set on #content-main
      setTimeout(setHeights, 100);
  }
</script>
{% endblock %}
