backend-plus 2.7.0-beta.0 → 2.7.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- /*global myOwn, my, XLSX, Pikaday */
3
+ /*global myOwn, my, xlsxNowBrowser, Pikaday */
4
4
  /*global miniMenuPromise, dialogPromise, alertPromise, confirmPromise, promptPromise, simpleFormPromise */
5
5
  /*global Blob, document, CustomEvent, URL */
6
6
 
@@ -248,7 +248,7 @@ myOwn.getStructuresToRegisterInLdb = function getStructuresToRegisterInLdb(paren
248
248
  var dummyElement = html.div().create();
249
249
  var Connector = my.TableConnector;
250
250
  var connector = new Connector({
251
- my:my,
251
+ my:my,
252
252
  tableName: tableName,
253
253
  getElementToDisplayCount:function(){ return dummyElement }
254
254
  });
@@ -264,7 +264,7 @@ myOwn.getStructuresToRegisterInLdb = function getStructuresToRegisterInLdb(paren
264
264
  var dummyElement = html.div().create();
265
265
  var Connector = my.TableConnector;
266
266
  var connector = new Connector({
267
- my:my,
267
+ my:my,
268
268
  tableName: foreignKey.references,
269
269
  getElementToDisplayCount:function(){ return dummyElement }
270
270
  });
@@ -305,8 +305,8 @@ myOwn.TableConnector = function(context, opts){
305
305
 
306
306
  myOwn.TableConnector.prototype.getStructure = function getStructure(opts){
307
307
  var opts = changing({
308
- registerInLocalDB: false,
309
- waitForFreshStructure: false
308
+ registerInLocalDB: false,
309
+ waitForFreshStructure: false
310
310
  }, opts || {});
311
311
  var connector = this;
312
312
  var my = connector.my;
@@ -337,7 +337,7 @@ myOwn.TableConnector.prototype.getStructure = function getStructure(opts){
337
337
  connector.whenStructureReady = canContinue.then(function(){
338
338
  return my.getStructureFromLocalDb(connector.tableName);
339
339
  }).then(function(tableDef){
340
- if(!tableDef){
340
+ if(!tableDef){
341
341
  return structureFromBackend;
342
342
  }
343
343
  connector.localDef = connector.def = changing(tableDef, connector.opts.tableDef||{});
@@ -384,7 +384,7 @@ myOwn.TableConnector.prototype.deleteRecord = function deleteRecord(depot, opts)
384
384
  return (depot.primaryKeyValues===false?
385
385
  Promise.resolve():
386
386
  depot.my.ajax.table_record_delete({
387
- table:depot.def.name,
387
+ table:depot.def.name,
388
388
  primaryKeyValues:depot.primaryKeyValues,
389
389
  launcher:opts.launcher
390
390
  }).then(function(){
@@ -419,7 +419,7 @@ myOwn.TableConnector.prototype.recordEnter = function recordEnter(depot){
419
419
  return (!this.my.config.cursor || depot.primaryKeyValues===false?
420
420
  Promise.resolve():
421
421
  depot.my.ajax.table_record_enter({
422
- table:depot.def.name,
422
+ table:depot.def.name,
423
423
  primaryKeyValues:depot.primaryKeyValues
424
424
  })
425
425
  );
@@ -428,7 +428,7 @@ myOwn.TableConnector.prototype.recordLeave = function recordLeave(depot){
428
428
  return (!this.my.config.cursor || depot.primaryKeyValues===false?
429
429
  Promise.resolve():
430
430
  depot.my.ajax.table_record_leave({
431
- table:depot.def.name,
431
+ table:depot.def.name,
432
432
  primaryKeyValues:depot.primaryKeyValues
433
433
  })
434
434
  );
@@ -445,7 +445,7 @@ myOwn.TableConnectorLocal = function(context, opts){
445
445
  connector.opts = opts||{};
446
446
  connector.fixedFields = connector.opts.fixedFields || [];
447
447
  connector.fixedField = {};
448
- connector.pick = connector.opts.pick;
448
+ connector.pick = connector.opts.pick;
449
449
  connector.hideBecauseRelated = {};
450
450
  connector.fixedFields.forEach(function(pair){
451
451
  if(!pair.range && !pair.until && pair.value != myOwn.skipInFixedFields){
@@ -461,7 +461,7 @@ myOwn.TableConnectorLocal = function(context, opts){
461
461
  myOwn.TableConnectorLocal.prototype.getStructure = function getStructure(){
462
462
  var connector = this;
463
463
  connector.whenStructureReady = my.getStructureFromLocalDb(connector.tableName).then(function(tableDef){
464
- if(!tableDef){
464
+ if(!tableDef){
465
465
  var err = new Error();
466
466
  err.code='NO-STRUCTURE';
467
467
  throw err;
@@ -587,8 +587,8 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
587
587
  grid.detailingPath=opts.detailingPath;
588
588
  var Connector = my.offline.mode?my.TableConnectorLocal:my.TableConnector;
589
589
  grid.connector = new Connector({
590
- my:this,
591
- tableName: tableName,
590
+ my:this,
591
+ tableName: tableName,
592
592
  getElementToDisplayCount:function(){ return (grid.dom.footInfo||{}).displayTo||html.div().create(); }
593
593
  }, opts);
594
594
  var preparing = grid.prepareAndDisplayGrid().then(function(){
@@ -661,9 +661,9 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
661
661
  changeIoStatus(depot,'ok', depot.row);
662
662
  },3000);
663
663
  }
664
- } else if (depot) {
664
+ } else if (depot) {
665
665
  if (!sameValue(JSON.stringify(row),JSON.stringify(depot.row))) {
666
- //grid.retrieveRowAndRefresh(depot);
666
+ //grid.retrieveRowAndRefresh(depot);
667
667
  if(depot.tr){
668
668
  grid.depotRefresh(depot,{updatedRow:row, sendedForUpdate:{}},{noDispatchEvents:true});
669
669
  }
@@ -676,7 +676,7 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
676
676
  var depotsToDisplay = grid.filterDepots(grid.depots);
677
677
  var depotsToDelete = depotsToDisplay.filter(depot => depot.tick != tick);
678
678
  var depot;
679
- if (myOwn.config.config['grid-row-retain-moved-or-deleted'] && !force) {
679
+ if (myOwn.config.config['grid-row-retain-moved-or-deleted'] && !force) {
680
680
  var depotsToRetain = grid.depots.filter(depot => depot.tick == tick);
681
681
  for (depot of depotsToRetain) {
682
682
  depot['$refreshed'] = false
@@ -684,8 +684,8 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
684
684
  }
685
685
  }
686
686
  while (depot = depotsToDelete.pop()) {
687
- depot.manager.displayAsDeleted(depot, force ? 'change-ff' : 'unknown');
688
- if (myOwn.config.config['grid-row-retain-moved-or-deleted']) {
687
+ depot.manager.displayAsDeleted(depot, force ? 'change-ff' : 'unknown');
688
+ if (myOwn.config.config['grid-row-retain-moved-or-deleted']) {
689
689
  if(!depot['$refreshed']){
690
690
  grid.retrieveRowAndRefresh(depot,{retrieveIgnoringWhere:true})
691
691
  depot['$refreshed'] = true
@@ -744,7 +744,7 @@ myOwn.TableGrid.prototype.createDepotFromRow = function createDepotFromRow(row,
744
744
  var depot = {
745
745
  my: grid.my,
746
746
  def: grid.def,
747
- connector: grid.connector,
747
+ connector: grid.connector,
748
748
  manager: grid,
749
749
  rowControls:{},
750
750
  row: row,
@@ -956,7 +956,7 @@ myOwn.DataColumnGrid.prototype.cellAttributes = function cellAttributes(specific
956
956
  }
957
957
  return attr;
958
958
  }
959
-
959
+
960
960
  myOwn.DataColumnGrid.prototype.th = function th(){
961
961
  var fieldDef = this.fieldDef;
962
962
  var grid = this.grid;
@@ -1098,11 +1098,11 @@ myOwn.DataColumnGrid.prototype.td = function td(depot, iColumn, tr, saveRow){
1098
1098
  if (fieldDef.references) {
1099
1099
  promiseChain = promiseChain.then(
1100
1100
  grid.setInheritedFields(depot, function(fkDef){
1101
- return fkDef.references == fieldDef.references &&
1101
+ return fkDef.references == fieldDef.references &&
1102
1102
  fkDef.fields.find(function(field){
1103
1103
  return field.source == fieldDef.name
1104
1104
  }) &&
1105
- fkDef.displayFields.length >= 0
1105
+ fkDef.displayFields.length >= 0
1106
1106
  }
1107
1107
  ));
1108
1108
  }
@@ -1205,7 +1205,7 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
1205
1205
  if(!event.ctrlKey && event.button!=1){
1206
1206
  event.preventDefault();
1207
1207
  }
1208
- detailControl.displayDetailGrid({fixedFields:fixedFields, detailing:{}},event);
1208
+ detailControl.displayDetailGrid({fixedFields:fixedFields, detailing:{}},event);
1209
1209
  }
1210
1210
  detailControl.forceDisplayDetailGrid = function(opts){
1211
1211
  if(detailControl.show){
@@ -1217,7 +1217,7 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
1217
1217
  detailControl.refreshDetailGrid = function(opts){
1218
1218
  var detailControl=this;
1219
1219
  if(detailControl.show){
1220
-
1220
+
1221
1221
  }
1222
1222
  }
1223
1223
  detailControl.displayDetailGrid = function(opts,event){
@@ -1253,8 +1253,8 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
1253
1253
  wScreen.mainAction(params,divGrid);
1254
1254
  }else{
1255
1255
  result = grid.my.tableGrid(detailTableDef.table, divGrid, {
1256
- fixedFields: fixedFields,
1257
- detailing:opts.detailing,
1256
+ fixedFields: fixedFields,
1257
+ detailing:opts.detailing,
1258
1258
  detailingForUrl:grid.detailingForUrl,
1259
1259
  detailingPath:(grid.detailingPath||[]).concat(depot.lastsPrimaryKeyValues),
1260
1260
  parentDepot: depot
@@ -1415,7 +1415,7 @@ myOwn.TableGrid.prototype.prepareMenu = function prepareMenu(button){
1415
1415
  grid.hideColumnsViaCss();
1416
1416
  });
1417
1417
  selectColumnsToShowElement.addEventListener('change',function(){
1418
- var listOptionsToShow=Array.prototype.slice.call(selectColumnsToShowElement.selectedOptions);
1418
+ var listOptionsToShow=Array.prototype.slice.call(selectColumnsToShowElement.selectedOptions);
1419
1419
  listOptionsToShow.forEach(function(option) {
1420
1420
  grid.view.hiddenColumns.splice(grid.view.hiddenColumns.indexOf(option.value),1);
1421
1421
  selectColumnsToShowElement.removeChild(option);
@@ -1450,9 +1450,9 @@ myOwn.TableGrid.prototype.prepareMenu = function prepareMenu(button){
1450
1450
  var messages = {};
1451
1451
  menuOptions.push(
1452
1452
  myOwn.dialogUpload(
1453
- 'table_upload',
1453
+ 'table_upload',
1454
1454
  {
1455
- table:grid.def.name,
1455
+ table:grid.def.name,
1456
1456
  prefilledFields:grid.connector.fixedFields,
1457
1457
  skipUnknownFieldsAtImport:null
1458
1458
  },
@@ -1533,8 +1533,8 @@ myOwn.TableGrid.prototype.prepareMenu = function prepareMenu(button){
1533
1533
  })
1534
1534
  );
1535
1535
  menuOptions.push({
1536
- img:my.path.img+'filtered-complete-table.png',
1537
- label:my.messages.filteredCompleteTable,
1536
+ img:my.path.img+'filtered-complete-table.png',
1537
+ label:my.messages.filteredCompleteTable,
1538
1538
  href:urlFilteredCompleteTable,
1539
1539
  showPage:my.showPage,
1540
1540
  });
@@ -1577,14 +1577,14 @@ myOwn.dialogDownload = function dialogDownload(grid){
1577
1577
  html.div({class:'state-preparing'}, [
1578
1578
  html.div(my.messages.preparingForExport),
1579
1579
  html.img({
1580
- class:'img-preparing',
1581
- src:'img/preparing.png',
1582
- alt:my.messages.preparingForExport,
1583
- title:my.messages.preparingForExport,
1580
+ class:'img-preparing',
1581
+ src:'img/preparing.png',
1582
+ alt:my.messages.preparingForExport,
1583
+ title:my.messages.preparingForExport,
1584
1584
  }),
1585
1585
  ]),
1586
1586
  html.div({class:'state-ready'}, [downloadElement]),
1587
- html.div('.'),
1587
+ html.div('.'),
1588
1588
  ]).create();
1589
1589
  dialogWindow.appendChild(mainDiv);
1590
1590
  var fieldsDef2Export=[];
@@ -1596,9 +1596,9 @@ myOwn.dialogDownload = function dialogDownload(grid){
1596
1596
  var prepare=function(){
1597
1597
  mainDiv.setAttribute("current-state", "preparing");
1598
1598
  setTimeout(function(){
1599
- fieldsDef2Export=grid.def.fields.filter(function(fieldDef){
1600
- return (fieldDef.inTable!==false || input.fromOtherTables.checked)
1601
- && fieldDef.visible
1599
+ fieldsDef2Export=grid.def.fields.filter(function(fieldDef){
1600
+ return (fieldDef.inTable!==false || input.fromOtherTables.checked)
1601
+ && fieldDef.visible
1602
1602
  && (fieldDef.allow.update || input.readOnly.checked || fieldDef.isPk)
1603
1603
  && (!grid.view.hiddenColumns.includes(fieldDef.name) || input.hiddens.checked);
1604
1604
  });
@@ -1607,7 +1607,7 @@ myOwn.dialogDownload = function dialogDownload(grid){
1607
1607
  }else{
1608
1608
  if(input.csv.checked){
1609
1609
  separator=',';
1610
- replacer=function(txt){
1610
+ replacer=function(txt){
1611
1611
  return /[\n,"]/.test(txt)?'"'+txt.replace(/"/g,'""')+'"':txt
1612
1612
  }
1613
1613
  dotExtension='.csv';
@@ -1619,7 +1619,7 @@ myOwn.dialogDownload = function dialogDownload(grid){
1619
1619
  '\r':'\\r',
1620
1620
  '\n':'\\n',
1621
1621
  }
1622
- replacer=function(txt){
1622
+ replacer=function(txt){
1623
1623
  return txt.replace(/[|\\\r\n]/g,function(char){
1624
1624
  return trans[char];
1625
1625
  })
@@ -1651,37 +1651,75 @@ myOwn.dialogDownload = function dialogDownload(grid){
1651
1651
  }));
1652
1652
  });
1653
1653
  var blob = new Blob([data.map(function(line){return line.map(replacer).join(separator)}).join('\r\n')], {type: 'text/plain'});
1654
- var url = URL.createObjectURL(blob);
1654
+ var url = URL.createObjectURL(blob);
1655
1655
  downloadElement.href=url;
1656
1656
  downloadElement.setAttribute("download", grid.def.name+dotExtension);
1657
1657
  mainDiv.setAttribute("current-state", "ready");
1658
1658
  }
1659
- var STYLE_HEADER={ font: {bold:true, underline:true}/*, alignment:{horizontal:'center'}*/};
1660
- var STYLE_EXTRA_HEADER={ font: {bold:true, underline:true, color:{rgb: "800040"}}/*, alignment:{horizontal:'center'}*/};
1661
- var STYLE_PK={font:{bold:true}};
1662
- var STYLE_LOOKUP={font:{color:{ rgb: "5588DD" }}};
1663
- var populateTableXLS = function populateTableXLS(ws, depots, fieldDefs, topRow, leftColumn){
1664
- topRow=topRow||0;
1659
+ var XLSX_STYLES={
1660
+ header : {bold:true},
1661
+ extraHeader : {bold:true, color:"404040"},
1662
+ pk : {bold:true},
1663
+ lookup : {color:"404040"},
1664
+ interval : {numFmt:'[h]:mm:ss'},
1665
+ intervalPk : {base:'pk' , numFmt:'[h]:mm:ss'},
1666
+ intervalLookup:{base:'lookup', numFmt:'[h]:mm:ss'},
1667
+ };
1668
+ // Las columnas que salen de exportJsonFieldAsColumns aparecen recién al
1669
+ // recorrer las filas, pero el encabezado se escribe antes que ellas: con
1670
+ // escritura secuencial hay que conocerlas de entrada, y esta pasada las junta.
1671
+ var collectExtraColumns = function collectExtraColumns(depots, fieldDefs, firstColumn){
1672
+ var lastColumn=firstColumn-1;
1673
+ if(grid.def.exportJsonFieldAsColumns){
1674
+ depots.forEach(function(depot){
1675
+ fieldDefs.forEach(function(fieldDef){
1676
+ if(grid.def.exportJsonFieldAsColumns == fieldDef.name){
1677
+ var value=depot.row[fieldDef.name];
1678
+ var fields = typeof value == "string" ? JSON.parse(value) : value;
1679
+ for(var name in fields){
1680
+ if(extraColumns[name]==null){
1681
+ extraColumns[name] = ++lastColumn;
1682
+ }
1683
+ }
1684
+ }
1685
+ });
1686
+ });
1687
+ }
1688
+ return lastColumn;
1689
+ }
1690
+ var styleForField = function styleForField(fieldDef, depot){
1691
+ var isInterval = fieldDef.typeName == 'interval';
1692
+ if(fieldDef.isPk){
1693
+ return isInterval?'intervalPk':'pk';
1694
+ }
1695
+ if(!fieldDef.allow || !fieldDef.allow.update || depot.allow.update === false){
1696
+ return isInterval?'intervalLookup':'lookup';
1697
+ }
1698
+ return isInterval?'interval':undefined;
1699
+ }
1700
+ // Las filas de una tabla, como las toma xlsx-now: la primera es el
1701
+ // encabezado y cada una de las demás es un array donde la posición es la
1702
+ // columna. `leftColumn` corre la tabla entera hacia la derecha.
1703
+ var tableRowsXLS = function tableRowsXLS(depots, fieldDefs, leftColumn){
1665
1704
  leftColumn=leftColumn||0;
1666
- fieldDefs.forEach(function(field,iColumn){
1667
- ws[XLSX.utils.encode_cell({c:iColumn+leftColumn,r:topRow})]={t:'s',v:field.name, s:STYLE_HEADER};
1668
- lastColumnExported = Math.max(lastColumnExported, iColumn);
1705
+ var lastColumn=collectExtraColumns(depots, fieldDefs, fieldDefs.length);
1706
+ lastColumnExported = Math.max(lastColumnExported, lastColumn);
1707
+ var pad=new Array(leftColumn);
1708
+ var headerRow=pad.concat(fieldDefs.map(function(field){
1709
+ return {v:field.name, s:'header'};
1710
+ }));
1711
+ likeAr(extraColumns).forEach(function(pos, name){
1712
+ headerRow[pos+leftColumn]={v:name, s:'extraHeader'};
1669
1713
  });
1670
- depots.forEach(function(depot, iRow){
1714
+ var rows=[headerRow];
1715
+ depots.forEach(function(depot){
1716
+ var row=pad.concat([]);
1671
1717
  var addCell = function addCell(value, fieldDef, iColumn){
1672
1718
  if(value!=null){
1673
- var excelValue=typeStore.typerFrom(fieldDef).toExcelValue(value);
1674
- var valueType=typeStore.typerFrom(fieldDef).toExcelType(value);
1675
- var cell={t:valueType,v:excelValue};
1676
- if(fieldDef.typeName == 'interval'){
1677
- cell.z='[h]:mm:ss';
1678
- }
1679
- if(fieldDef.isPk){
1680
- cell.s=STYLE_PK;
1681
- }else if(!fieldDef.allow || !fieldDef.allow.update || depot.allow.update === false){
1682
- cell.s=STYLE_LOOKUP;
1683
- }
1684
- ws[XLSX.utils.encode_cell({c:iColumn+leftColumn,r:iRow+1+topRow})]=cell;
1719
+ row[iColumn+leftColumn]={
1720
+ v:typeStore.typerFrom(fieldDef).toExcelValue(value),
1721
+ s:styleForField(fieldDef, depot),
1722
+ };
1685
1723
  }
1686
1724
  }
1687
1725
  fieldDefs.forEach(function(fieldDef, iColumn){
@@ -1689,33 +1727,33 @@ myOwn.dialogDownload = function dialogDownload(grid){
1689
1727
  if(grid.def.exportJsonFieldAsColumns == fieldDef.name){
1690
1728
  var fields = typeof value == "string" ? JSON.parse(value) : value;
1691
1729
  for(var name in fields){
1692
- var pos = extraColumns[name];
1693
- if(pos==null){
1694
- lastColumnExported++;
1695
- extraColumns[name] = lastColumnExported;
1696
- ws[XLSX.utils.encode_cell({c:lastColumnExported+leftColumn,r:topRow})]={t:'s',v:name, s:STYLE_EXTRA_HEADER};
1697
- pos = lastColumnExported;
1698
- }
1699
- addCell(fields[name], {typeName:typeof fields[name] == 'number'? 'decimal':'text'}, pos)
1730
+ addCell(fields[name], {typeName:typeof fields[name] == 'number'? 'decimal':'text'}, extraColumns[name])
1700
1731
  }
1701
1732
  }else{
1702
1733
  addCell(value, fieldDef, iColumn);
1703
1734
  }
1704
1735
  });
1736
+ rows.push(row);
1705
1737
  });
1706
- ws["!ref"]="A1:"+XLSX.utils.encode_cell({c:lastColumnExported+leftColumn,r:grid.depotsToDisplay.length+topRow});
1738
+ return rows;
1707
1739
  }
1708
1740
  var excelExport = function(){
1709
- var wb = XLSX.utils.book_new();
1710
- var ws = {};
1711
- var exportFileInformationWs={};
1712
- var i=0;
1713
- exportFileInformationWs[XLSX.utils.encode_cell({c:0,r:++i})]={t:'s',v:'table',s:STYLE_HEADER};
1714
- exportFileInformationWs[XLSX.utils.encode_cell({c:1,r: i})]={t:'s',v:grid.def.name};
1715
- exportFileInformationWs[XLSX.utils.encode_cell({c:0,r:++i})]={t:'s',v:'date',s:STYLE_HEADER};
1716
- exportFileInformationWs[XLSX.utils.encode_cell({c:1,r: i})]={t:'s',v:new Date().toISOString()};
1717
- exportFileInformationWs[XLSX.utils.encode_cell({c:0,r:++i})]={t:'s',v:'user',s:STYLE_HEADER};
1718
- exportFileInformationWs[XLSX.utils.encode_cell({c:1,r: i})]={t:'s',v:my.config.username};
1741
+ var sheet1name=grid.def.name.length>27?grid.def.name.slice(0,27)+'...':grid.def.name;
1742
+ var sheet2name=grid.def.name!=="metadata"?"metadata":"meta-data";
1743
+ var rows=[{
1744
+ '#worksheet':sheet1name+'b',
1745
+ freezeRows: 1,
1746
+ freezeColumns: grid.def.primaryKey?.length ?? 0,
1747
+ autoWidthMax: 40,
1748
+ }];
1749
+ rows=rows.concat(tableRowsXLS(grid.depotsToDisplay, fieldsDef2Export));
1750
+ rows.push({'#worksheet':sheet2name, autoWidthMax: 40});
1751
+ // La primera fila de metadata queda en blanco, como cuando las
1752
+ // celdas se escribían por dirección arrancando en la fila 2.
1753
+ rows.push([]);
1754
+ rows.push([{v:'table',s:'header'}, grid.def.name]);
1755
+ rows.push([{v:'date' ,s:'header'}, new Date().toISOString()]);
1756
+ rows.push([{v:'user' ,s:'header'}, my.config.username]);
1719
1757
  // grid.def.allow.forEach(function(action,iAction){
1720
1758
  // exportFileInformationWs[XLSX.utils.encode_cell({c:iAction,r:2})]={t:'s',v:action};
1721
1759
  // })
@@ -1729,22 +1767,22 @@ myOwn.dialogDownload = function dialogDownload(grid){
1729
1767
  }).map(function(fieldDef){
1730
1768
  return {row:fieldDef};
1731
1769
  });
1732
- populateTableXLS(exportFileInformationWs, fieldPropertiesDepot,fieldPropertiesDefs,i+1,1);
1770
+ extraColumns={};
1771
+ rows=rows.concat(tableRowsXLS(fieldPropertiesDepot,fieldPropertiesDefs,1));
1733
1772
  }
1734
1773
  }
1735
- populateTableXLS(ws, grid.depotsToDisplay, fieldsDef2Export);
1736
- var sheet1name=grid.def.name.length>27?grid.def.name.slice(0,27)+'...':grid.def.name;
1737
- var sheet2name=grid.def.name!=="metadata"?"metadata":"meta-data";
1738
- wb.SheetNames=[sheet1name,sheet2name];
1739
- wb.Sheets[sheet1name]=ws;
1740
- exportFileInformationWs["!ref"]="A1:F100";
1741
- wb.Sheets[sheet2name]=exportFileInformationWs;
1742
- var wbFile = XLSX.write(wb, {bookType:'xlsx', bookSST:false, type: 'binary', cellDates:true});
1743
- var blob = new Blob([s2ab(wbFile)],{type:"application/octet-stream"});
1744
- mainDiv.setAttribute("current-state", "ready");
1745
- var url = URL.createObjectURL(blob);
1746
- downloadElement.href=url;
1747
- downloadElement.setAttribute("download", grid.def.name+".xlsx");
1774
+ xlsxNowBrowser.createXlsxBlob({
1775
+ rows,
1776
+ styles:XLSX_STYLES
1777
+ }).then(function(blob){
1778
+ mainDiv.setAttribute("current-state", "ready");
1779
+ var url = URL.createObjectURL(blob);
1780
+ downloadElement.href=url;
1781
+ downloadElement.setAttribute("download", grid.def.name+".xlsx");
1782
+ }).catch(function(err){
1783
+ mainDiv.setAttribute("current-state", "chossing");
1784
+ alertPromise(err.message);
1785
+ });
1748
1786
  };
1749
1787
  });
1750
1788
  };
@@ -1824,7 +1862,7 @@ myOwn.dialogUpload = function dialogUpload(ajaxPath, ajaxParams, ajaxPrepareResu
1824
1862
  });
1825
1863
  simpleFormPromise({elementsList:[
1826
1864
  messages.importDataFromFile,
1827
- buttonFile,
1865
+ buttonFile,
1828
1866
  ...(optsNames.map(name => html.label([html.br(), buttons[name], messages[name]]).create())),
1829
1867
  html.br().create(),
1830
1868
  buttonConfirmImport,
@@ -2052,7 +2090,7 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
2052
2090
  ]).create();
2053
2091
  grid.prepareMenu(buttonMenu);
2054
2092
  grid.columns=[new my.ActionColumnGrid({
2055
- grid:grid,
2093
+ grid:grid,
2056
2094
  actions:[
2057
2095
  /*buttonInsert,*//*buttonSaveMode,*/buttonCreateFilter,buttonCreateFilterAdd,buttonDestroyFilter,
2058
2096
  buttonOrientation,
@@ -2069,8 +2107,8 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
2069
2107
  // [new my.SpecialColumnGrid({class:"empty-right-column"})]
2070
2108
  );
2071
2109
  if(grid.modes.withColumnDetails==null){
2072
- grid.modes.withColumnDetails=grid.def.fields.some(function(fieldDef){
2073
- return fieldDef.label!=fieldDef.title;
2110
+ grid.modes.withColumnDetails=grid.def.fields.some(function(fieldDef){
2111
+ return fieldDef.label!=fieldDef.title;
2074
2112
  });
2075
2113
  }
2076
2114
  if(grid.vertical){
@@ -2087,7 +2125,7 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
2087
2125
  elementInfo[info.name] = html.span(info.value).create();
2088
2126
  elementInfo.appendChild(elementInfo[info.name]);
2089
2127
  });
2090
- elementInfo.displayTo.textContent = my.messages.loading;
2128
+ elementInfo.displayTo.textContent = my.messages.loading;
2091
2129
  }
2092
2130
  grid.dom.headInfo = html.th({class: 'head-info', colspan:grid.columns.length-1, "is-processing":"1"}).create();
2093
2131
  createInfoColumnStructure(grid.dom.headInfo);
@@ -2116,11 +2154,11 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
2116
2154
  grid.dom.table = html.table({"class":"my-grid", "my-table": grid.actualName},[
2117
2155
  grid.dom.caption,
2118
2156
  html.tbody(
2119
- grid.columns.map(function(column){
2157
+ grid.columns.map(function(column){
2120
2158
  return html.tr([
2121
2159
  column.th(),
2122
2160
  grid.modes.withColumnDetails?html.tr(grid.columns.map(function(column){ return column.thDetail(); })):null
2123
- ]);
2161
+ ]);
2124
2162
  })
2125
2163
  ),
2126
2164
  html.tfoot([
@@ -2159,7 +2197,7 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
2159
2197
  var dummyElement = html.div().create();
2160
2198
  var Connector = my.offline.mode?my.TableConnectorLocal:my.TableConnector;
2161
2199
  var myConnector = new Connector({
2162
- my:my,
2200
+ my:my,
2163
2201
  tableName: fkDef.references,
2164
2202
  getElementToDisplayCount:function(){ return dummyElement }
2165
2203
  }, {fixedFields: fixedFields});
@@ -2187,7 +2225,7 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
2187
2225
 
2188
2226
  myOwn.specialDefaultValue={
2189
2227
  current_date:function(){ return myOwn.config.currentDate||bestGlobals.date.today(); },
2190
- next_number:function(fieldName, aboveDepot, belowDepot){
2228
+ next_number:function(fieldName, aboveDepot, belowDepot){
2191
2229
  var manager = aboveDepot.manager ?? belowDepot.manager
2192
2230
  if(!manager){
2193
2231
  return 1;
@@ -2202,7 +2240,7 @@ myOwn.specialDefaultValue={
2202
2240
  }
2203
2241
  return belowDepot.row[fieldName]?belowDepot.row[fieldName]+1:(
2204
2242
  aboveDepot.row[fieldName]?aboveDepot.row[fieldName]-1:1
2205
- );
2243
+ );
2206
2244
  },
2207
2245
  current_user: function specialDefaultValueCurrentUser(){
2208
2246
  return my.config.username;
@@ -2239,7 +2277,7 @@ myOwn.TableGrid.prototype.createRowInsertElements = function createRowInsertElem
2239
2277
  }
2240
2278
  /*
2241
2279
  while(
2242
- position<grid.dom.table.tBodies[0].rows.length &&
2280
+ position<grid.dom.table.tBodies[0].rows.length &&
2243
2281
  grid.dom.table.tBodies[0].rows[position].isDetail
2244
2282
  ){
2245
2283
  position++;
@@ -2266,7 +2304,9 @@ myOwn.TableGrid.prototype.createRowInsertElements = function createRowInsertElem
2266
2304
  }
2267
2305
  if(value!==null){
2268
2306
  depotForInsert.row[fieldDef.name] = value;
2269
- depotForInsert.rowPendingForUpdate[fieldDef.name] = value;
2307
+ if (fieldDef.inTable) {
2308
+ depotForInsert.rowPendingForUpdate[fieldDef.name] = value;
2309
+ }
2270
2310
  }
2271
2311
  });
2272
2312
  //TODO: mejorar la posición dentro del splice o concluir que no sirve el splice
@@ -2294,10 +2334,10 @@ var changeIoStatus = function changeIoStatus(depot,newStatus, objectWithFieldsOr
2294
2334
  var fieldNames=typeof objectWithFieldsOrListOfFieldNames === "string"?[objectWithFieldsOrListOfFieldNames]:(
2295
2335
  objectWithFieldsOrListOfFieldNames instanceof Array?objectWithFieldsOrListOfFieldNames:Object.keys(objectWithFieldsOrListOfFieldNames)
2296
2336
  );
2297
- fieldNames.forEach(function(name){
2337
+ fieldNames.forEach(function(name){
2298
2338
  if(depot.rowControls[name]){
2299
2339
  var td=depot.rowControls[name];
2300
- td.setAttribute('io-status', newStatus);
2340
+ td.setAttribute('io-status', newStatus);
2301
2341
  if(title){
2302
2342
  td.title=title;
2303
2343
  }else{
@@ -2363,8 +2403,8 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2363
2403
  if(depot.status==='new'){
2364
2404
  var specialMandatories=grid.def.specialValidator?myOwn.validators[grid.def.specialValidator].getMandatoryMap(depot.row):{};
2365
2405
  var mandatoryOmitted=function(fieldDef){
2366
- return (specialMandatories[fieldDef.name] || fieldDef.nullable!==true && fieldDef.isPk || fieldDef.nullable===false)
2367
- && depot.row[fieldDef.name]==null
2406
+ return (specialMandatories[fieldDef.name] || fieldDef.nullable!==true && fieldDef.isPk || fieldDef.nullable===false)
2407
+ && depot.row[fieldDef.name]==null
2368
2408
  && (grid.connector.fixedFields.find(function(pair){
2369
2409
  return !pair.range && !pair.until && pair.fieldName===fieldDef.name
2370
2410
  })||{}).value == null
@@ -2391,7 +2431,7 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2391
2431
  // var sendedForUpdate = depot.my.cloneRow(depot.rowPendingForUpdate);
2392
2432
  return my.ajax.table_data({
2393
2433
  table:depot.def.name,
2394
- fixedFields:grid.def.primaryKey.map(function(fieldName, i){
2434
+ fixedFields:grid.def.primaryKey.map(function(fieldName, i){
2395
2435
  return {fieldName:fieldName, value:depot.primaryKeyValues[i]};
2396
2436
  }),
2397
2437
  pick:grid.def.pick,
@@ -2403,8 +2443,8 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2403
2443
  grid.setRowStyle = function setRowStyle(depot, row, skipUpdateStatus){
2404
2444
  if(!skipUpdateStatus){
2405
2445
  depot.status = 'loaded';
2406
- depot.primaryKeyValues = grid.def.primaryKey.map(function(fieldName){
2407
- return depot.row[fieldName];
2446
+ depot.primaryKeyValues = grid.def.primaryKey.map(function(fieldName){
2447
+ return depot.row[fieldName];
2408
2448
  });
2409
2449
  /*
2410
2450
  depot.lastsPrimaryKeyValues = depot.primaryKeyValues.slice(0);
@@ -2421,7 +2461,7 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2421
2461
  depot.lastsPrimaryKeyValues=JSON.stringify(depot.lastsPrimaryKeyValues);
2422
2462
  }
2423
2463
  depot.tr.setAttribute('pk-values',JSON.stringify(depot.primaryKeyValues));
2424
- grid.def.layout.styleColumns.forEach(function(fieldName){
2464
+ grid.def.layout.styleColumns.forEach(function(fieldName){
2425
2465
  depot.tr.setAttribute('column-'+fieldName,JSON.stringify(depot.row[fieldName]));
2426
2466
  });
2427
2467
  }
@@ -2462,15 +2502,15 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2462
2502
  },3000,fieldName);
2463
2503
  /*jshint loopfunc: false */
2464
2504
  }else if(sameValue(retrievedRow[fieldName], source[fieldName])){
2465
- // ok, si bien lo que viene no coincide con lo pendiente que sigue pendiente,
2466
- // sí coincide con lo que estaba antes de mandar a grabar,
2505
+ // ok, si bien lo que viene no coincide con lo pendiente que sigue pendiente,
2506
+ // sí coincide con lo que estaba antes de mandar a grabar,
2467
2507
  // entonces no hay conflicto el usuario sabe sobre qué está modificando
2468
2508
  //REVISAR SI SE QUIERE REVERTIR
2469
2509
  }else{
2470
- // no coincide con lo pendiente ni con lo anterior,
2510
+ // no coincide con lo pendiente ni con lo anterior,
2471
2511
  // hay un conflicto con el conocimiento del usuario que modificó algo que estaba en otro estado
2472
- changeIoStatus(depot,'write-read-conflict',
2473
- fieldName,
2512
+ changeIoStatus(depot,'write-read-conflict',
2513
+ fieldName,
2474
2514
  myOwn.messages.anotherUserChangedTheRow+'. \n'+
2475
2515
  myOwn.messages.oldValue+': '+source[fieldName]+(
2476
2516
  whenMergeOverride?'':'\n'+myOwn.messages.actualValueInDB+': '+retrievedRow[fieldName]
@@ -2511,7 +2551,7 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2511
2551
  }
2512
2552
  grid.refreshAggregates();
2513
2553
  for(var detailControl in depot.detailControls){
2514
- if(depot.detailControls[detailControl].tr){
2554
+ if(depot.detailControls[detailControl].tr){
2515
2555
  depot.detailControls[detailControl].refreshAllRowsInGrid()
2516
2556
  }
2517
2557
  };
@@ -2530,7 +2570,7 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2530
2570
  tr=grid.dom.table.rows[0];
2531
2571
  depot.colNumber = grid.dom.table.rows[0].childNodes.length;
2532
2572
  }else{
2533
- tr = grid.my.insertRow({section:tbody, iRow:iRow, smooth:depot.status==='new'?{
2573
+ tr = grid.my.insertRow({section:tbody, iRow:iRow, smooth:depot.status==='new'?{
2534
2574
  colCount:grid.def.detailTables.length + grid.def.fields.length
2535
2575
  }:false});
2536
2576
  }
@@ -2540,11 +2580,11 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2540
2580
  return column.fieldDef?column.fieldDef.visible:true
2541
2581
  }).forEach(function(column, iColumn){
2542
2582
  tr.appendChild(column.td(depot, iColumn, tr, saveRow));
2543
- if(grid.vertical){
2583
+ if(grid.vertical){
2544
2584
  tr = tr.nextSibling;
2545
2585
  }
2546
2586
  });
2547
- if(!grid.vertical){
2587
+ if(!grid.vertical){
2548
2588
  tr.addEventListener('focusout', function(event){
2549
2589
  tr.removeAttribute('current_line');
2550
2590
  if(event.target.parentNode != (event.relatedTarget||{}).parentNode ){
@@ -2609,7 +2649,7 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2609
2649
  special: 'filter',
2610
2650
  my: grid.my,
2611
2651
  def: grid.def,
2612
- connector: grid.connector,
2652
+ connector: grid.connector,
2613
2653
  manager: grid,
2614
2654
  rowControls:{},
2615
2655
  row: {},
@@ -2677,7 +2717,7 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2677
2717
  var depotsToDisplay = grid.filterDepots(grid.depots);
2678
2718
  grid.sortDepotsToDisplay = function sortDepotsToDisplay(depotsToDisplay){
2679
2719
  if(grid.view.sortColumns.length>0){
2680
- return depotsToDisplay.sort(function(depot1, depot2){
2720
+ return depotsToDisplay.sort(function(depot1, depot2){
2681
2721
  grid.view.sortColumns.forEach(function(orderColumn){
2682
2722
  if(!grid.def.field[orderColumn.column]){
2683
2723
  my.log(orderColumn.column+' order no está en '+grid.def.name);
@@ -2772,7 +2812,7 @@ myOwn.TableGrid.prototype.displayAsDeleted = function displayAsDeleted(depot, mo
2772
2812
  var grid = this;
2773
2813
  var fast = mode == 'change-ff'
2774
2814
  if (mode == 'unknown' && myOwn.config.config['grid-row-retain-moved-or-deleted']) {
2775
- depot.tr.setAttribute('not-here', 'yes');
2815
+ depot.tr.setAttribute('not-here', 'yes');
2776
2816
  } else {
2777
2817
  var position = depot.tr ? Math.min(grid.depots.length,Math.max(0,depot.tr.sectionRowIndex)) : 0;
2778
2818
  if(grid.depots[position] !== depot){
@@ -2814,7 +2854,7 @@ myOwn.TableGrid.prototype.displayAsDeleted = function displayAsDeleted(depot, mo
2814
2854
 
2815
2855
  myOwn.confirmDelete=function confirmDelete(depot, opts){
2816
2856
  return depot.my.showQuestion(
2817
- depot.my.messages.Delete+' '+(depot.primaryKeyValues === false ? depot.my.messages.newUnsavedRow : JSON.stringify(depot.primaryKeyValues))+' ?',
2857
+ depot.my.messages.Delete+' '+(depot.primaryKeyValues === false ? depot.my.messages.newUnsavedRow : JSON.stringify(depot.primaryKeyValues))+' ?',
2818
2858
  {askForNoRepeat:depot.my.messages.Delete+', '+depot.def.name}
2819
2859
  );
2820
2860
  }
@@ -2980,10 +3020,10 @@ myOwn.getReference = function getReference(referenceName, opts){
2980
3020
  var reference={};
2981
3021
  if(!my.references[referenceName] || opts.fixedFields.length){
2982
3022
  var dummyElement = html.div().create();
2983
- var Connector = my.offline.mode?my.TableConnectorLocal:my.TableConnector;
3023
+ var Connector = my.offline.mode?my.TableConnectorLocal:my.TableConnector;
2984
3024
  var connector=new Connector({
2985
- my:my,
2986
- tableName: referenceName,
3025
+ my:my,
3026
+ tableName: referenceName,
2987
3027
  getElementToDisplayCount:function(){ return dummyElement; },
2988
3028
  activeOnly: true
2989
3029
  }, {fixedFields:opts.fixedFields});
@@ -3022,7 +3062,7 @@ myOwn.autoSetupFunctions.push(function autoSetupMyTables(){
3022
3062
  myOwn.ExpanderJsonReadOnly={
3023
3063
  autoExpand:true,
3024
3064
  whenReadOnly:true,
3025
- whenType: function(typedControl){
3065
+ whenType: function(typedControl){
3026
3066
  var typeInfo = typedControl.controledType.typeInfo;
3027
3067
  return typeInfo.typeName === 'jsonb';
3028
3068
  },
@@ -3053,7 +3093,7 @@ myOwn.ExpanderJsonReadOnly={
3053
3093
  }
3054
3094
  myOwn.ExpanderReferences={
3055
3095
  autoExpand:true,
3056
- whenType: function(typedControl){
3096
+ whenType: function(typedControl){
3057
3097
  var typeInfo = typedControl.controledType.typeInfo;
3058
3098
  return typeInfo.references && !typeInfo.skipReferenceLookup;
3059
3099
  },
@@ -3138,7 +3178,7 @@ myOwn.ExpanderReferences={
3138
3178
  attributes: {'allow-write': true}
3139
3179
  }
3140
3180
  }).then(function(text){
3141
- typedControl.setTypedValue(text||null, true);
3181
+ typedControl.setTypedValue(text||null, true);
3142
3182
  }).catch(function(err){
3143
3183
  if(!DialogPromise){
3144
3184
  return alertPromise(err.message);
@@ -3177,4 +3217,4 @@ myOwn.validators={}
3177
3217
  myOwn.sortMethods={
3178
3218
  'charbychar':bestGlobals.forOrder.Native,
3179
3219
  'default':bestGlobals.forOrder,
3180
- }
3220
+ }