backend-plus 2.0.0-beta.1 → 2.0.0-beta.10

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.
@@ -67,7 +67,7 @@ myOwn.wScreens.table = function(addrParams){
67
67
  myOwn.wScreens.procAux = {
68
68
  showParams:function(formDef, main_layout, addrParams, mainAction){
69
69
  var autoproced = addrParams.autoproced || false
70
- addrParams.up=addrParams.up||{};
70
+ addrParams.up=addrParams.up||addrParams.ff||{};
71
71
  var params=addrParams.up;
72
72
  // var button = html.button(formDef.proceedLabel||my.messages.proceed).create();
73
73
  var label = formDef.proceedLabel||my.messages.proceed;
@@ -284,6 +284,8 @@ myOwn.getStructuresToRegisterInLdb = function getStructuresToRegisterInLdb(paren
284
284
  return promiseChain;
285
285
  }
286
286
 
287
+ myOwn.skipInFixedFields = Symbol("skipInFixedFields");
288
+
287
289
  myOwn.TableConnector = function(context, opts){
288
290
  var connector = this;
289
291
  for(var attr in context){
@@ -293,7 +295,7 @@ myOwn.TableConnector = function(context, opts){
293
295
  connector.fixedFields = connector.opts.fixedFields || [];
294
296
  connector.fixedField = {};
295
297
  connector.fixedFields.forEach(function(pair){
296
- if(!pair.range){
298
+ if(!pair.range && pair.value != myOwn.skipInFixedFields){
297
299
  connector.fixedField[pair.fieldName] = pair.value;
298
300
  }
299
301
  });
@@ -442,7 +444,7 @@ myOwn.TableConnectorLocal = function(context, opts){
442
444
  connector.fixedFields = connector.opts.fixedFields || [];
443
445
  connector.fixedField = {};
444
446
  connector.fixedFields.forEach(function(pair){
445
- if(!pair.range){
447
+ if(!pair.range && pair.value != myOwn.skipInFixedFields){
446
448
  connector.fixedField[pair.fieldName] = pair.value;
447
449
  }
448
450
  });
@@ -573,7 +575,6 @@ myOwn.setTimeStamp = function setTimeStamp(row){
573
575
 
574
576
  myOwn.skipTimeStamp = function skipTimeStamp(row, timeStamp){
575
577
  var skip = (row[TIME_STAMP_PROP] || 0) > timeStamp;
576
- console.log(skip ? 'SKIP' : 'PASS', timeStamp, row[TIME_STAMP_PROP], JSON4all.toUrl(row))
577
578
  if (!skip) row[TIME_STAMP_PROP] = timeStamp;
578
579
  return skip;
579
580
  }
@@ -601,9 +602,9 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
601
602
  }
602
603
  })
603
604
  }
604
- grid.refreshAllRows = function(){
605
+ grid.refreshAllRows = async function(force){
605
606
  var timeStamp = new Date().getTime();
606
- grid.connector.my.ajax.table_data({
607
+ await grid.connector.my.ajax.table_data({
607
608
  table:grid.connector.tableName,
608
609
  fixedFields:grid.connector.fixedFields,
609
610
  paramfun:grid.connector.parameterFunctions||{}
@@ -624,7 +625,34 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
624
625
  return sameValue(JSON.stringify(primaryKeyValuesForRow),JSON.stringify(primaryKeyValuesForDepotRow))
625
626
  });
626
627
  //chequeo que exista depot por las dudas
627
- if (depot) {
628
+ if ((!depot || !depot.tr || !depot.tr.parentNode) && !thereIsANewRecord && !grid.vertical) {
629
+ if (!depot) {
630
+ var depot = grid.createDepotFromRow(row);
631
+ grid.depots.push(depot);
632
+ grid.sortDepotsToDisplay(grid.depots);
633
+ } else if (depot.tr && !depot.tr.parentNode) {
634
+ depot.tr = null
635
+ }
636
+ var iRow = -1;
637
+ var i = 0;
638
+ while (i < grid.depots.length){
639
+ var aDepot = grid.depots[i];
640
+ if (depot == aDepot) break;
641
+ if (aDepot && aDepot.tr && aDepot.tr.parentNode && aDepot.tr.rowIndex != null) {
642
+ iRow = aDepot.tr.sectionRowIndex
643
+ }
644
+ i++;
645
+ }
646
+ grid.createRowElements(iRow + 1, depot);
647
+ grid.updateRowData(depot);
648
+ depot.tick = tick
649
+ if (!force) {
650
+ changeIoStatus(depot,'background-change', depot.row);
651
+ setTimeout(function(){
652
+ changeIoStatus(depot,'ok', depot.row);
653
+ },3000);
654
+ }
655
+ } else if (depot) {
628
656
  if (!sameValue(JSON.stringify(row),JSON.stringify(depot.row))) {
629
657
  //grid.retrieveRowAndRefresh(depot);
630
658
  if(depot.tr){
@@ -632,31 +660,20 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
632
660
  }
633
661
  }
634
662
  depot.tick = tick
635
- } else if (!depot && !thereIsANewRecord && !grid.vertical) {
636
- var depot = grid.createDepotFromRow(row);
637
- grid.depots.push(depot);
638
- grid.sortDepotsToDisplay(grid.depots);
639
- grid.createRowElements(grid.depots.findIndex((myDepot)=>myDepot===depot), depot);
640
- grid.updateRowData(depot);
641
- depot.tick = tick
642
- changeIoStatus(depot,'background-change', depot.row);
643
- setTimeout(function(){
644
- changeIoStatus(depot,'ok', depot.row);
645
- },3000);
646
663
  }
647
664
  })
648
665
  if(!thereIsANewRecord){
649
666
  var i = 0;
650
667
  var depotsToDelete = grid.depots.filter(depot => depot.tick != tick);
651
668
  var depot;
652
- if (myOwn.config.config['grid-row-retain-moved-or-deleted']) {
669
+ if (myOwn.config.config['grid-row-retain-moved-or-deleted'] && !force) {
653
670
  var depotsToRetain = grid.depots.filter(depot => depot.tick == tick);
654
671
  for (depot of depotsToRetain) {
655
- if (depot.tr.getAttribute('not-here')) depot.tr.removeAttribute('not-here')
672
+ if (depot.tr && depot.tr.getAttribute('not-here')) depot.tr.removeAttribute('not-here')
656
673
  }
657
674
  }
658
675
  while (depot = depotsToDelete.pop()) {
659
- depot.manager.displayAsDeleted(depot, 'unknown');
676
+ depot.manager.displayAsDeleted(depot, force ? 'change-ff' : 'unknown');
660
677
  }
661
678
  }
662
679
  })
@@ -1140,9 +1157,13 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
1140
1157
  alt:'DETAIL',
1141
1158
  title:detailTableDef.label||my.messages.details
1142
1159
  }).create();
1143
- var menuRef={w:'table', table:detailTableDef.table};
1160
+ var menuRef = detailTableDef.table ? {table:detailTableDef.table} : {w:detailTableDef.wScreen, autoproced:true};
1144
1161
  var calculateFixedFields = function(){
1145
- return detailTableDef.fields.map(function(pair){
1162
+ return detailTableDef.fields
1163
+ .filter(function(pair){
1164
+ return !pair.nullMeansAll || depot.row[pair.source] != null;
1165
+ })
1166
+ .map(function(pair){
1146
1167
  var fieldCondition={fieldName: pair.target, value:'value' in pair ? pair.value : depot.row[pair.source]}
1147
1168
  if(pair.range){
1148
1169
  fieldCondition.range=pair.range;
@@ -1225,9 +1246,17 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
1225
1246
  g.dom.main.addEventListener('deletedRowOk', refresh);
1226
1247
  g.dom.main.addEventListener('savedRowOk', refresh);
1227
1248
  }
1228
- detailControl.refreshAllRowsInGrid=function(){
1229
- if(detailTableDef.refreshFromParent){
1230
- g.refreshAllRows();
1249
+ detailControl.refreshAllRowsInGrid=function(force){
1250
+ if(detailTableDef.refreshFromParent || force){
1251
+ if (force) {
1252
+ g.dom.main.style.opacity=0.5;
1253
+ fixedFields = calculateFixedFields()
1254
+ g.connector.fixedFields = fixedFields
1255
+ }
1256
+ setTimeout(async ()=>{
1257
+ await g.refreshAllRows(force);
1258
+ g.dom.main.style.opacity=1;
1259
+ },1)
1231
1260
  }
1232
1261
  }
1233
1262
  return g;
@@ -2195,7 +2224,7 @@ myOwn.TableGrid.prototype.createRowInsertElements = function createRowInsertElem
2195
2224
  }
2196
2225
  var depotForInsert = grid.createDepotFromRow({$allow:{delete:true, update:true}}, 'new');
2197
2226
  grid.connector.fixedFields.forEach(function(pair){
2198
- if(!pair.range){
2227
+ if(!pair.range && grid.def.field[pair.fieldName].inTable !== false){
2199
2228
  depotForInsert.row[pair.fieldName] = pair.value;
2200
2229
  depotForInsert.rowPendingForUpdate[pair.fieldName] = pair.value;
2201
2230
  }
@@ -2701,10 +2730,11 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
2701
2730
 
2702
2731
  myOwn.TableGrid.prototype.displayAsDeleted = function displayAsDeleted(depot, mode){
2703
2732
  var grid = this;
2733
+ var fast = mode == 'change-ff'
2704
2734
  if (mode == 'unknown' && myOwn.config.config['grid-row-retain-moved-or-deleted']) {
2705
2735
  depot.tr.setAttribute('not-here', 'yes');
2706
2736
  } else {
2707
- var position = Math.min(grid.depots.length,Math.max(0,depot.tr.sectionRowIndex));
2737
+ var position = depot.tr ? Math.min(grid.depots.length,Math.max(0,depot.tr.sectionRowIndex)) : 0;
2708
2738
  if(grid.depots[position] !== depot){
2709
2739
  position = grid.depots.indexOf(depot);
2710
2740
  }
@@ -2729,12 +2759,14 @@ myOwn.TableGrid.prototype.displayAsDeleted = function displayAsDeleted(depot, mo
2729
2759
  depots[j-1].colNumber = j;
2730
2760
  }
2731
2761
  }else{
2732
- depot.my.fade(depot.tr);
2733
- for(var detailControl in depot.detailControls){
2734
- if(depot.detailControls[detailControl].tr){
2735
- depot.my.fade(depot.detailControls[detailControl].tr);
2736
- }
2737
- };
2762
+ if(depot.tr){
2763
+ depot.my.fade(depot.tr, {fast});
2764
+ for(var detailControl in depot.detailControls){
2765
+ if(depot.detailControls[detailControl].tr){
2766
+ depot.my.fade(depot.detailControls[detailControl].tr, {fast});
2767
+ }
2768
+ };
2769
+ }
2738
2770
  }
2739
2771
  }
2740
2772
  grid.updateTotals(grid.depots.length?1:0, grid.depots.length);
@@ -252,11 +252,12 @@ myOwn.log = function log(severity, message){
252
252
  };
253
253
 
254
254
  myOwn.fade = function fade(element, options){
255
- if(element.tagName.toUpperCase()==='TR' && element.parentNode.replaceChild){
255
+ options=options||{};
256
+ if (!element.parentNode) return
257
+ if(element.tagName.toUpperCase()==='TR' && element.parentNode.replaceChild && !options.fast){
256
258
  var parent=element.parentNode;
257
259
  var dummyTr=document.createElement(element.tagName);
258
260
  dummyTr.className=element.className;
259
- options=options||{};
260
261
  options.smooth=options.smooth||{};
261
262
  var spans=options.smooth.spans;
262
263
  var sourceRow;
@@ -230,7 +230,7 @@ export type EditableDbDefinition = {
230
230
  }
231
231
  }
232
232
  export type FieldsForConnect = (string | {source:string, target:string})[]
233
- export type FieldsForConnectDetailTable = (string | {source:string, target:string} | {value:any, target:string})[]
233
+ export type FieldsForConnectDetailTable = (string | {source:string, target:string, nullMeansAll?:boolean} | {value:any, target:string})[]
234
234
 
235
235
  export type FkActions = 'no action'|'restrict'|'cascade'|'set null'|'set default';
236
236
  export type ForeignKey = {
@@ -418,6 +418,7 @@ export class AppBackend{
418
418
  i18n:{
419
419
  messages:Record<LangId,Record<string, string>>
420
420
  }
421
+ shootDownBackend():Promise<void>
421
422
  }
422
423
 
423
424
  }
@@ -616,6 +616,7 @@ AppBackend.prototype.start = function start(opts){
616
616
  console.log('*','express server');
617
617
  be.server.close(/** @param {Error} err */function(err){
618
618
  if(err){
619
+ console.log('*', err)
619
620
  reject(err);
620
621
  }else{
621
622
  resolve();
@@ -989,21 +990,20 @@ AppBackend.prototype.start = function start(opts){
989
990
  done(null,false,{message:be.messages.unlogged.login.userOrPassFail});
990
991
  }
991
992
  }).then(async function(userInfo){
993
+ if (!userInfo) return;
992
994
  if (!be.config.login.skipBitacora) {
993
995
  var context = be.getContext(req);
994
- var sessionInfo = client.query(be.generateInsertSQL(be.config.server.bitacoraSchema, be.config.server.bitacoraTableName,{
996
+ var sessionInfo = await client.query(be.generateInsertSQL(be.config.server.bitacoraSchema, be.config.server.bitacoraTableName,{
995
997
  procedure_name: '@login',
996
- parameters: {
997
- user:username,
998
- machine_id: context.machineId,
999
- navigator: context.navigator,
1000
- init_date: bestGlobals.datetime.now(),
1001
- }
998
+ username,
999
+ machine_id: context.machineId,
1000
+ navigator: context.navigator,
1001
+ init_date: bestGlobals.datetime.now(),
1002
+ parameters: {}
1002
1003
  })).fetchUniqueValue();
1003
1004
  userInfo.bitacoraId = sessionInfo.value;
1004
1005
  }
1005
1006
  done(null, userInfo);
1006
- return userInfo;
1007
1007
  }).then(function(){
1008
1008
  client.done();
1009
1009
  }).catch(function(err){
@@ -1233,6 +1233,7 @@ AppBackend.prototype.checkDatabaseStructure = async function checkDatabaseStruct
1233
1233
  alter table his.bitacora alter column id type bigint;
1234
1234
  grant usage on schema his to ${be.config.db.user};
1235
1235
  grant select, insert, update on his.bitacora to ${be.config.db.user};
1236
+ alter table his.bitacora alter column parameters_definition drop not null;
1236
1237
  `;
1237
1238
  throw new Error(message);
1238
1239
  }
@@ -1376,6 +1377,7 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
1376
1377
  var params={};
1377
1378
  procedureDef.parameters.forEach(function(paramDef){
1378
1379
  var undecodedValue = req[source][paramDef.name];
1380
+ undecodedValue = paramDef.encoding == 'plain' || undecodedValue === undefined ? undecodedValue : undecodedValue + '';
1379
1381
  var value = undecodedValue===undefined?undecodedValue:myOwn.encoders[paramDef.encoding].parse(undecodedValue);
1380
1382
  if(undecodedValue===undefined){
1381
1383
  if(paramDef.defaultSpecial === 'currentYear'){
@@ -2596,8 +2598,13 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
2596
2598
  var schema=db.quoteIdent(be.config.db.schema);
2597
2599
  linesCreate.push("set role to "+owner+";");
2598
2600
  linesCreate.push("drop schema if exists "+schema+' cascade;');
2601
+ if (be.config.install.dump["drop-his"]) {
2602
+ linesCreate.push("drop schema if exists his cascade;");
2603
+ }
2599
2604
  linesCreate.push("create schema "+schema+';');
2600
2605
  linesCreate.push("grant usage on schema "+schema+' to '+user+';');
2606
+ linesCreate.push("create schema if not exists his;");
2607
+ linesCreate.push("grant usage on schema his to "+user+';');
2601
2608
  if(be.config.install.dump["admin-can-create-tables"]){
2602
2609
  linesCreate.push("grant create on schema "+schema+' to '+user+';');
2603
2610
  }
@@ -189,6 +189,9 @@ ProcedureTables = [
189
189
  var updateTarget = {}
190
190
  for(var name in parameters.newRow){
191
191
  var defField=mainDefTable.field[name];
192
+ if (!defField) {
193
+ throw new Error("field "+name+" does not exist in "+mainDefTable.name);
194
+ }
192
195
  if(!defField.allow[action] && (!opts || !opts.forImport) && (
193
196
  !defField.isPk ||
194
197
  parameters.primaryKeyValues[defField.isPk-1]!=parameters.newRow[name]
@@ -317,7 +317,7 @@ function tableDefAdapt(tableDef, context){
317
317
  resultFieldDef.referencesFields=fkDef.fields;
318
318
  resultFieldDef.skipReferenceLookup=fkDef.skipReferenceLookup || fkTableDef.skipReferenceLookup;
319
319
  }catch(err){
320
- console.log('ERROR',fkDef.fields,'in',resultTableDef.field);
320
+ console.log('ERROR',fkDef.fields,'in',resultTableDef.field.name);
321
321
  err.context=(err.context||'')+'referencing '+fkDef.fields[lastPos].source+' in '+resultTableDef.name+' to '+fkDef.references+' \n ';
322
322
  throw err;
323
323
  }
@@ -2,15 +2,16 @@
2
2
 
3
3
  module.exports = function(context){
4
4
  const BITACORA_TABLENAME = context.be.config.server.bitacoraTableName;
5
+ const BITACORA_SCHEMA = context.be.config.server.bitacoraSchema;
5
6
  return context.be.tableDefAdapt({
6
7
  name:'bitacora',
7
8
  title:'Bitacora',
8
9
  tableName: BITACORA_TABLENAME,
10
+ schema: BITACORA_SCHEMA,
9
11
  editable:context.forDump,
10
12
  fields:[
11
13
  {name:'id' , typeName:'bigint' , nullable:false, sequence:{name: 'secuencia_bitacora', firstValue: 1}},
12
14
  {name:'procedure_name' , typeName:'text' , nullable:false },
13
- {name:'parameters_definition' , typeName:'text' , nullable:false },
14
15
  {name:'parameters' , typeName:'text' , nullable:false },
15
16
  {name:'username' , typeName:'text' , nullable:false },
16
17
  {name:'machine_id' , typeName:'text' , nullable:false },
@@ -21,6 +22,7 @@ module.exports = function(context){
21
22
  {name:'end_status' , typeName:'text' },
22
23
  ],
23
24
  primaryKey:['id'],
25
+ sql:{skipEnance:true},
24
26
  sortColumns:[{column:'id', order:-1}]
25
27
  }, context);
26
28
  }
@@ -3,6 +3,7 @@
3
3
  module.exports = function(context){
4
4
  return context.be.tableDefAdapt({
5
5
  name:'locks',
6
+ schema:'his',
6
7
  allow:{
7
8
  insert:true,
8
9
  delete:false,
@@ -4,6 +4,7 @@ module.exports = function(context){
4
4
  var $1_is_num=`$1 ~ '^\\s*(\\d+(\\.\\d*)?|\\.\\d+)\\s*$'`
5
5
  return context.be.tableDefAdapt({
6
6
  name:'summary',
7
+ schema:'his',
7
8
  editable:context.forDump,
8
9
  fields:[
9
10
  {name:'table_name' , typeName:'text' , visible:false},
@@ -32,6 +33,7 @@ module.exports = function(context){
32
33
  ],
33
34
  primaryKey:['table_name', 'name'],
34
35
  // hiddenColunns:['typeName', 'nullable', 'label', 'title', 'description'],
36
+ sql:{skipEnance:true},
35
37
  sortColumns:[{column:'ordinal_position', order:1}]
36
38
  }, context);
37
39
  }
@@ -5,6 +5,7 @@ module.exports = function(context){
5
5
  return context.be.tableDefAdapt({
6
6
  name:'tokens',
7
7
  elementName:'token',
8
+ schema:'his',
8
9
  editable:admin,
9
10
  fields:[
10
11
  {name:'token' , typeName:'text' , nullable:false },
@@ -21,7 +22,8 @@ module.exports = function(context){
21
22
  ],
22
23
  sql:{
23
24
  isTable: true,
24
- from: `(select * from tokens order by date desc)`
25
+ from: `(select * from tokens order by date desc)`,
26
+ skipEnance:true,
25
27
  },
26
28
  }, context);
27
29
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "backend-plus",
3
3
  "description": "Backend for the anti Pareto rule",
4
- "version": "2.0.0-beta.1",
4
+ "version": "2.0.0-beta.10",
5
5
  "author": "Codenautas <codenautas@googlegroups.com>",
6
6
  "license": "MIT",
7
7
  "repository": "codenautas/backend-plus",
@@ -54,7 +54,7 @@
54
54
  "mini-tools": "^1.12.1",
55
55
  "moment": "^2.29.4",
56
56
  "multiparty": "^4.2.3",
57
- "nodemailer": "^6.9.3",
57
+ "nodemailer": "^6.9.4",
58
58
  "numeral": "^2.0.6",
59
59
  "pg-promise-strict": "^1.3.3",
60
60
  "pikaday": "^1.8.2",
@@ -73,7 +73,7 @@
73
73
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz"
74
74
  },
75
75
  "devDependencies": {
76
- "@types/big.js": "^6.1.6",
76
+ "@types/big.js": "^6.2.0",
77
77
  "@types/expect.js": "~0.3.29",
78
78
  "@types/express": "^4.17.17",
79
79
  "@types/express-useragent": "^1.0.2",
@@ -81,8 +81,8 @@
81
81
  "@types/js-yaml": "^4.0.5",
82
82
  "@types/mocha": "^10.0.1",
83
83
  "@types/multiparty": "~0.0.33",
84
- "@types/node": "^20.3.3",
85
- "@types/nodemailer": "^6.4.8",
84
+ "@types/node": "^20.5.1",
85
+ "@types/nodemailer": "^6.4.9",
86
86
  "@types/numeral": "~2.0.2",
87
87
  "@types/session-file-store": "^1.2.2",
88
88
  "@types/stack-trace": "~0.0.30",
@@ -98,10 +98,10 @@
98
98
  "kill-9": "~0.4.3",
99
99
  "mocha": "^10.2.0",
100
100
  "nyc": "^15.1.0",
101
- "puppeteer": "^20.7.4",
101
+ "puppeteer": "^21.1.0",
102
102
  "sinon": "^15.2.0",
103
103
  "supertest": "^6.3.3",
104
- "types.d.ts": "~0.6.15",
104
+ "types.d.ts": "~0.6.18",
105
105
  "typescript": "^5.1.6",
106
106
  "why-is-node-running": "^2.2.2"
107
107
  },