@green-code-studio/objects-list 1.9.6 → 1.10.0

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,3 +1,6 @@
1
+
2
+ import {t} from "./i18n.xml";
3
+ import {ContextMenu} from "@green-code-studio/context-menu/dist/index.mjs";
1
4
  export class AbstractView extends HTMLElement {
2
5
  loadData(data, start, limit, infiniteScrollEnabled) {
3
6
  this.style.setProperty('--height', (data.total * this.rowHeight) + 'px');
@@ -36,4 +39,198 @@ export class AbstractView extends HTMLElement {
36
39
  this.onPaginationChanged(passedStart);
37
40
  }
38
41
  }
42
+
43
+ trOnClick(row, e) {
44
+ const rowsIds = this.objectsList.currentRows.map(x => x.id);
45
+ console.log('click')
46
+ if (!e.ctrlKey) {
47
+ this.objectsList.selected.clear();
48
+ }
49
+
50
+ if (e.shiftKey) {
51
+ const mainIndex = rowsIds.indexOf(this.objectsList.selectedMain);
52
+ const clickedIndex = rowsIds.indexOf(row.id);
53
+ if (clickedIndex >= 0 && mainIndex >= 0)
54
+ rowsIds.slice(Math.min(mainIndex, clickedIndex), Math.max(mainIndex, clickedIndex) + 1).forEach(x => this.objectsList.selected.add(x));
55
+ } else {
56
+ if (this.objectsList.selected.has(row.id))
57
+ this.objectsList.selected.delete(row.id);
58
+ else
59
+ this.objectsList.selected.add(row.id);
60
+
61
+ this.objectsList.selectedMain = row.id;
62
+ }
63
+
64
+ this.refreshSelectedClasses();
65
+ }
66
+
67
+ trOnDblClick(row, tr, e) {
68
+ if (!this.objectsList.selected.has(tr.dataset.row)) {
69
+ this.objectsList.selected.clear();
70
+ this.objectsList.selected.add(tr.dataset.row)
71
+ this.objectsList.selectedMain = tr.dataset.row;
72
+ this.refreshSelectedClasses();
73
+ }
74
+ let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dblClick').find(x => x.main);
75
+ if (action) {
76
+ if (action.command) {
77
+ action.command();
78
+ } else if (action.href) {
79
+ this.objectsList.gotoUrl(action.href)
80
+ }
81
+ }
82
+ }
83
+ contextMenu(tr, event) {
84
+ event.stopPropagation();
85
+ if (!this.objectsList.selected.has(tr.dataset.row)) {
86
+ this.objectsList.selected.clear();
87
+ this.objectsList.selected.add(tr.dataset.row)
88
+ this.objectsList.selectedMain = tr.dataset.row;
89
+ this.refreshSelectedClasses();
90
+ }
91
+ const rows = this.objectsList.getSelectedData();
92
+ let actions = this.objectsList.generateActions(rows, 'contextMenu');
93
+ let actions2 = [];
94
+ for (const action of actions) {
95
+ actions2.push(action);
96
+ if (action.href) {
97
+ actions2.push({
98
+ ...action,
99
+ href: null,
100
+ command: () => window.open(action.href),
101
+ name: (action.name ?? '') + ' (' + t('objectList.inNewTab') + ')'
102
+ });
103
+ }
104
+ }
105
+ let elements = actions2.map(action => ({
106
+ text: action.name,
107
+ icon: action.icon,
108
+ class: action.action ? 'action-' + action.action : '',
109
+ onclick: action.command || (() => this.objectsList.gotoUrl(action.href))
110
+ }));
111
+ elements.push({
112
+ text: 'copy',
113
+ icon: 'icon-copy',
114
+ onclick: () => {
115
+ this.forceCopy(rows);
116
+ }
117
+ })
118
+ ContextMenu.openContextMenu(event, elements);
119
+ }
120
+ trOnKeyDown(row, tr, e) {
121
+ console.log('trOnKeyDown')
122
+ if (e.key === 'Enter') {
123
+ let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'enter').find(x => x.main);
124
+ if (action) {
125
+ if (action.command) {
126
+ action.command();
127
+ } else if (action.href) {
128
+ this.objectsList.gotoUrl(action.href)
129
+ }
130
+ }
131
+ } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
132
+ const rowsIds = this.objectsList.currentRows.map(x => x.id);
133
+ let index = rowsIds.indexOf(this.objectsList.selectedMain);
134
+ if (e.key === 'ArrowDown') {
135
+ if (index < rowsIds.length) index++;
136
+ else index = rowsIds.length - 1;
137
+ } else {
138
+ if (index > 0) index--;
139
+ }
140
+ const id = rowsIds[index];
141
+ if (!e.ctrlKey) {
142
+ this.objectsList.selected.clear();
143
+ }
144
+ if (e.shiftKey) {
145
+ if (!this.objectsList.selectedShiftStart) {
146
+ this.objectsList.selectedShiftStart = this.objectsList.selectedMain;
147
+ }
148
+ this.selectRange(this.objectsList.selectedShiftStart, id)
149
+ } else {
150
+ this.objectsList.selectedShiftStart = null;
151
+ if (!e.ctrlKey) {
152
+ this.objectsList.selected.add(id);
153
+ }
154
+ }
155
+ this.objectsList.selectedMain = id;
156
+ this.refreshSelectedClasses();
157
+ e.preventDefault();
158
+ } else if (e.key === ' ') {
159
+ if (this.objectsList.selected.has(this.objectsList.selectedMain))
160
+ this.objectsList.selected.delete(this.objectsList.selectedMain);
161
+ else
162
+ this.objectsList.selected.add(this.objectsList.selectedMain);
163
+
164
+ this.refreshSelectedClasses();
165
+ e.preventDefault();
166
+ } else if (e.key === 'a') {
167
+ if (e.ctrlKey)
168
+ this.objectsList.selected.selectAll();
169
+
170
+ this.refreshSelectedClasses();
171
+ e.preventDefault();
172
+ }
173
+ }
174
+
175
+ trOnDragStart(row, oryginalTr, e) {
176
+ if (!this.objectsList.selected.has(row.id)) {
177
+ this.objectsList.selected.clear()
178
+ this.objectsList.selected.add(row.id)
179
+ this.refreshSelectedClasses();
180
+ }
181
+ this.fillDataTransfer(e.dataTransfer, this.objectsList.selected);
182
+ }
183
+
184
+ fillDataTransfer(dataTransfer, ids) {
185
+ const trs = Array.from(this.body.children).filter(tr => ids.has(tr.dataset.row));
186
+ let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dataTransfer').find(x => x.main);
187
+ if (action && action.href) {
188
+ dataTransfer.setData('text/uri-list', new URL(action.href, document.baseURI));
189
+ }
190
+ if (action && action.hrefArray) {
191
+ dataTransfer.setData('text/uri-list', action.hrefArray.map(x => new URL(x, document.baseURI)).map(x => x.toString()).join("\r\n#\r\n"));
192
+ }
193
+ dataTransfer.setData('text/html', this.generateTableHtml(trs));
194
+ dataTransfer.setData('text/plain', this.generateTableTextPlain(trs));
195
+
196
+ }
197
+
198
+ refreshSelectedClasses() {
199
+ for (const tr of this.body.children) {
200
+ tr.classList.toggle('selected', this.objectsList.selected.has(tr.dataset.row));
201
+ tr.classList.toggle('selectedMain', this.objectsList.selectedMain == tr.dataset.row);
202
+ if (this.objectsList.selectedMain == tr.dataset.row) {
203
+ tr.tabIndex = 1;
204
+ tr.focus();
205
+ getSelection().selectAllChildren(tr)
206
+ } else {
207
+ tr.tabIndex = -1;
208
+ }
209
+ }
210
+ }
211
+
212
+ selectRange(start, end) {
213
+ const rowsIds = this.objectsList.currentRows.map(x => x.id);
214
+ let startIndex = rowsIds.indexOf(start);
215
+ let endIndex = rowsIds.indexOf(end);
216
+ if (endIndex < startIndex) {
217
+ let tmp = startIndex;
218
+ startIndex = endIndex;
219
+ endIndex = tmp;
220
+ }
221
+ for (let i = startIndex; i <= endIndex; i++) {
222
+ this.objectsList.selected.add(rowsIds[i]);
223
+ }
224
+ }
225
+
226
+
227
+ onCopy(e) {
228
+ if (this.copyForced) {
229
+ this.fillDataTransfer(e.clipboardData, this.copyForced);
230
+ e.preventDefault();
231
+ } else if (document.querySelector(':focus')?.findParent(x => x === this)) {
232
+ this.fillDataTransfer(e.clipboardData, this.objectsList.selected);
233
+ e.preventDefault();
234
+ }
235
+ }
39
236
  }
@@ -0,0 +1,58 @@
1
+ import {AbstractView} from "./abstractView.js";
2
+ import {create} from "fast-creator";
3
+ import {ListView} from "./listView.js";
4
+
5
+ export class CalendarView extends AbstractView {
6
+ constructor(objectsList) {
7
+ super();
8
+ this.objectsList = objectsList;
9
+ this.init();
10
+ window.dbgList = this;
11
+ }
12
+
13
+ init() {
14
+ this.body = create('.body.monthCalendarBody')
15
+ const bodyContainer = create('.bodyContainer')
16
+ bodyContainer.append(this.body)
17
+ this.append(bodyContainer)
18
+ this.addEventListener('scroll', this.onScroll.bind(this));
19
+ }
20
+
21
+ calcMaxVisibleItems(height) {
22
+ return Number.POSITIVE_INFINITY
23
+ }
24
+
25
+ loadData(data) {
26
+ while(this.body.firstChild){
27
+ this.body.removeChild(this.body.firstChild);
28
+ }
29
+ console.log('data', data)
30
+ let startDay = new Date()
31
+ if(this.objectsList.date){
32
+ startDay = new Date(this.objectsList.date)
33
+ }
34
+ startDay.setDate(1);
35
+
36
+ startDay.setDate(startDay.getDate() - startDay.getDay() + 1);
37
+ for (let i = 0; i < 7 * 6; i++) {
38
+ const day = new Date(startDay);
39
+ day.setDate(startDay.getDate() + i);
40
+ const dayElement = create('.day', {
41
+ data: {date: day.toISOString().substring(0, 10)},
42
+ text: day.toISOString().substring(0, 10)
43
+ })
44
+ this.body.append(dayElement)
45
+ for (let item of data.rows.filter(r => this.objectsList.dateRowCallback(r).toISOString().substring(0, 10) == day.toISOString().substring(0, 10))) {
46
+ const itemElement = create('.item', {text: item})
47
+ dayElement.append(itemElement)
48
+ itemElement.oncontextmenu = this.contextMenu.bind(this, itemElement);
49
+ itemElement.onclick = this.trOnClick.bind(this, item);
50
+ itemElement.ondblclick = this.trOnDblClick.bind(this, item, itemElement);
51
+ itemElement.onkeydown = this.trOnKeyDown.bind(this, item, itemElement);
52
+ itemElement.ondragstart = this.trOnDragStart.bind(this, item, itemElement);
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ customElements.define('calendar-view', CalendarView);
package/src/i18n.xml CHANGED
@@ -25,6 +25,14 @@
25
25
  <value lang="pl">Widok listy</value>
26
26
  <value lang="en">List view</value>
27
27
  </node>
28
+ <node name="calendarView">
29
+ <value lang="pl">Widok kalendarza</value>
30
+ <value lang="en">Calendar view</value>
31
+ </node>
32
+ <node name="timelineView">
33
+ <value lang="pl">Widok osi czasu</value>
34
+ <value lang="en">Timeline view</value>
35
+ </node>
28
36
  <node name="startMultiEdit">
29
37
  <value lang="pl">Rozpocznij edycję wielu</value>
30
38
  <value lang="en">Start multi-edit</value>
package/src/listView.js CHANGED
@@ -74,11 +74,11 @@ export class ListView extends AbstractView {
74
74
 
75
75
 
76
76
  tr.dataset.row = data.id;
77
- // tr.oncontextmenu = this.contextMenu.bind(this, tr);
78
- // tr.onclick = this.trOnClick.bind(this, data);
79
- // tr.ondblclick = this.trOnDblClick.bind(this, data, tr);
80
- // tr.onkeydown = this.trOnKeyDown.bind(this, data, tr);
81
- // tr.ondragstart = this.trOnDragStart.bind(this, data, tr);
77
+ tr.oncontextmenu = this.contextMenu.bind(this, tr);
78
+ tr.onclick = this.trOnClick.bind(this, data);
79
+ tr.ondblclick = this.trOnDblClick.bind(this, data, tr);
80
+ tr.onkeydown = this.trOnKeyDown.bind(this, data, tr);
81
+ tr.ondragstart = this.trOnDragStart.bind(this, data, tr);
82
82
  }
83
83
  }
84
84
 
@@ -7,6 +7,7 @@ import {ConcurencyLimiter} from "./utils/concurencyLimiter.js";
7
7
  import {IdsSet} from "./idsSet.js";
8
8
  import {ConfigPopup} from "./ConfigPopup.js";
9
9
  import {create} from "fast-creator";
10
+ import {CalendarView} from "./calendarView.js";
10
11
 
11
12
  export class ObjectsList extends HTMLElement {
12
13
  constructor(datasource) {
@@ -90,6 +91,8 @@ export class ObjectsList extends HTMLElement {
90
91
  const refreshSymbol = Symbol();
91
92
  this.lastRefreshSymbol = refreshSymbol;
92
93
  this.lastRefreshSymbolTotal = refreshSymbol;
94
+ this.pagination.style.display=this.insideView instanceof CalendarView ? 'none' : '';
95
+ this.dateInput.style.display=this.insideView instanceof CalendarView ? '' : 'none';
93
96
  if (this.asyncTotal) {
94
97
  const promise1 = this.loadConcurencyLimiter.run(async () => {
95
98
  if (this.lastRefreshSymbol != refreshSymbol) return;
@@ -224,9 +227,15 @@ export class ObjectsList extends HTMLElement {
224
227
  } else if (value == 'tableWideView') {
225
228
  this.insideViewClass = TableView
226
229
  this.insideViewParams = {wide: true}
227
- } else {
230
+ } else if (value == 'listView') {
228
231
  this.insideViewClass = ListView
229
232
  this.insideViewParams = {}
233
+ }else if (value == 'calendarView') {
234
+ this.insideViewClass = CalendarView
235
+ this.insideViewParams = {}
236
+ }else if (value == 'timelineView') {
237
+ this.insideViewClass = TimelineView
238
+ this.insideViewParams = {}
230
239
  }
231
240
  }
232
241
 
@@ -313,6 +322,13 @@ export class ObjectsList extends HTMLElement {
313
322
  this.refresh();
314
323
  }
315
324
  this.foot.append(this.pagination);
325
+ this.dateInput = create('input', {type: 'month', value:new Date().toISOString().substring(0, 7)});
326
+ this.dateInput.onchange = date => {
327
+ this.start = 0;
328
+ this.date=this.dateInput.value;
329
+ this.refresh();
330
+ }
331
+ this.foot.append(this.dateInput);
316
332
  this.filterShortContainer = create('.filterShortContainer');
317
333
  this.foot.append(this.filterShortContainer);
318
334
  this.searchForm = create('form', {className: 'search'});
@@ -179,6 +179,12 @@ data-view {
179
179
  }
180
180
  }
181
181
  }
182
+ calendar-view{
183
+ .body{
184
+ display: grid;
185
+ grid-template-columns: repeat(7, 1fr);
186
+ }
187
+ }
182
188
 
183
189
  .foot {
184
190
  border-top: 1px solid var(--second);
package/src/tableView.js CHANGED
@@ -245,202 +245,6 @@ export class TableView extends AbstractView {
245
245
  this.head.querySelectorAll(`[data-sort-name="${this.objectsList.sort.col}"]`).forEach(x => x.dataset.order = this.objectsList.sort.desc ? 'desc' : 'asc');
246
246
  }
247
247
 
248
- contextMenu(tr, event) {
249
- event.stopPropagation();
250
- if (!this.objectsList.selected.has(tr.dataset.row)) {
251
- this.objectsList.selected.clear();
252
- this.objectsList.selected.add(tr.dataset.row)
253
- this.objectsList.selectedMain = tr.dataset.row;
254
- this.refreshSelectedClasses();
255
- }
256
- const rows = this.objectsList.getSelectedData();
257
- let actions = this.objectsList.generateActions(rows, 'contextMenu');
258
- let actions2 = [];
259
- for (const action of actions) {
260
- actions2.push(action);
261
- if (action.href) {
262
- actions2.push({
263
- ...action,
264
- href: null,
265
- command: () => window.open(action.href),
266
- name: (action.name ?? '') + ' (' + t('objectList.inNewTab') + ')'
267
- });
268
- }
269
- }
270
- let elements = actions2.map(action => ({
271
- text: action.name,
272
- icon: action.icon,
273
- class: action.action ? 'action-' + action.action : '',
274
- onclick: action.command || (() => this.objectsList.gotoUrl(action.href))
275
- }));
276
- elements.push({
277
- text: 'copy',
278
- icon: 'icon-copy',
279
- onclick: () => {
280
- this.forceCopy(rows);
281
- }
282
- })
283
- ContextMenu.openContextMenu(event, elements);
284
- }
285
-
286
- refreshSelectedClasses() {
287
- for (const tr of this.body.children) {
288
- tr.classList.toggle('selected', this.objectsList.selected.has(tr.dataset.row));
289
- tr.classList.toggle('selectedMain', this.objectsList.selectedMain == tr.dataset.row);
290
- if (this.objectsList.selectedMain == tr.dataset.row) {
291
- tr.tabIndex = 1;
292
- tr.focus();
293
- getSelection().selectAllChildren(tr)
294
- } else {
295
- tr.tabIndex = -1;
296
- }
297
- }
298
- }
299
-
300
-
301
- trOnClick(row, e) {
302
- const rowsIds = this.objectsList.currentRows.map(x => x.id);
303
- console.log('click')
304
- if (!e.ctrlKey) {
305
- this.objectsList.selected.clear();
306
- }
307
-
308
- if (e.shiftKey) {
309
- const mainIndex = rowsIds.indexOf(this.objectsList.selectedMain);
310
- const clickedIndex = rowsIds.indexOf(row.id);
311
- if (clickedIndex >= 0 && mainIndex >= 0)
312
- rowsIds.slice(Math.min(mainIndex, clickedIndex), Math.max(mainIndex, clickedIndex) + 1).forEach(x => this.objectsList.selected.add(x));
313
- } else {
314
- if (this.objectsList.selected.has(row.id))
315
- this.objectsList.selected.delete(row.id);
316
- else
317
- this.objectsList.selected.add(row.id);
318
-
319
- this.objectsList.selectedMain = row.id;
320
- }
321
-
322
- this.refreshSelectedClasses();
323
- }
324
-
325
- trOnDblClick(row, tr, e) {
326
- if (!this.objectsList.selected.has(tr.dataset.row)) {
327
- this.objectsList.selected.clear();
328
- this.objectsList.selected.add(tr.dataset.row)
329
- this.objectsList.selectedMain = tr.dataset.row;
330
- this.refreshSelectedClasses();
331
- }
332
- let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dblClick').find(x => x.main);
333
- if (action) {
334
- if (action.command) {
335
- action.command();
336
- } else if (action.href) {
337
- this.objectsList.gotoUrl(action.href)
338
- }
339
- }
340
- }
341
-
342
- selectRange(start, end) {
343
- const rowsIds = this.objectsList.currentRows.map(x => x.id);
344
- let startIndex = rowsIds.indexOf(start);
345
- let endIndex = rowsIds.indexOf(end);
346
- if (endIndex < startIndex) {
347
- let tmp = startIndex;
348
- startIndex = endIndex;
349
- endIndex = tmp;
350
- }
351
- for (let i = startIndex; i <= endIndex; i++) {
352
- this.objectsList.selected.add(rowsIds[i]);
353
- }
354
- }
355
-
356
- trOnKeyDown(row, tr, e) {
357
- console.log('trOnKeyDown')
358
- if (e.key === 'Enter') {
359
- let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'enter').find(x => x.main);
360
- if (action) {
361
- if (action.command) {
362
- action.command();
363
- } else if (action.href) {
364
- this.objectsList.gotoUrl(action.href)
365
- }
366
- }
367
- } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
368
- const rowsIds = this.objectsList.currentRows.map(x => x.id);
369
- let index = rowsIds.indexOf(this.objectsList.selectedMain);
370
- if (e.key === 'ArrowDown') {
371
- if (index < rowsIds.length) index++;
372
- else index = rowsIds.length - 1;
373
- } else {
374
- if (index > 0) index--;
375
- }
376
- const id = rowsIds[index];
377
- if (!e.ctrlKey) {
378
- this.objectsList.selected.clear();
379
- }
380
- if (e.shiftKey) {
381
- if (!this.objectsList.selectedShiftStart) {
382
- this.objectsList.selectedShiftStart = this.objectsList.selectedMain;
383
- }
384
- this.selectRange(this.objectsList.selectedShiftStart, id)
385
- } else {
386
- this.objectsList.selectedShiftStart = null;
387
- if (!e.ctrlKey) {
388
- this.objectsList.selected.add(id);
389
- }
390
- }
391
- this.objectsList.selectedMain = id;
392
- this.refreshSelectedClasses();
393
- e.preventDefault();
394
- } else if (e.key === ' ') {
395
- if (this.objectsList.selected.has(this.objectsList.selectedMain))
396
- this.objectsList.selected.delete(this.objectsList.selectedMain);
397
- else
398
- this.objectsList.selected.add(this.objectsList.selectedMain);
399
-
400
- this.refreshSelectedClasses();
401
- e.preventDefault();
402
- } else if (e.key === 'a') {
403
- if (e.ctrlKey)
404
- this.objectsList.selected.selectAll();
405
-
406
- this.refreshSelectedClasses();
407
- e.preventDefault();
408
- }
409
- }
410
-
411
- onCopy(e) {
412
- if (this.copyForced) {
413
- this.fillDataTransfer(e.clipboardData, this.copyForced);
414
- e.preventDefault();
415
- } else if (document.querySelector(':focus')?.findParent(x => x === this)) {
416
- this.fillDataTransfer(e.clipboardData, this.objectsList.selected);
417
- e.preventDefault();
418
- }
419
- }
420
-
421
- trOnDragStart(row, oryginalTr, e) {
422
- if (!this.objectsList.selected.has(row.id)) {
423
- this.objectsList.selected.clear()
424
- this.objectsList.selected.add(row.id)
425
- this.refreshSelectedClasses();
426
- }
427
- this.fillDataTransfer(e.dataTransfer, this.objectsList.selected);
428
- }
429
-
430
- fillDataTransfer(dataTransfer, ids) {
431
- const trs = Array.from(this.body.children).filter(tr => ids.has(tr.dataset.row));
432
- let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dataTransfer').find(x => x.main);
433
- if (action && action.href) {
434
- dataTransfer.setData('text/uri-list', new URL(action.href, document.baseURI));
435
- }
436
- if (action && action.hrefArray) {
437
- dataTransfer.setData('text/uri-list', action.hrefArray.map(x => new URL(x, document.baseURI)).map(x => x.toString()).join("\r\n#\r\n"));
438
- }
439
- dataTransfer.setData('text/html', this.generateTableHtml(trs));
440
- dataTransfer.setData('text/plain', this.generateTableTextPlain(trs));
441
-
442
- }
443
-
444
248
  generateTableHtml(trs) {
445
249
  const thead = '<thead><tr>' + Array.from(this.head.querySelectorAll('.column')).map(x => '<th>' + x.innerHTML + '</th>').join('') + '</tr></thead>';
446
250
  const tbody = '<tbody>' + trs.map(tr => {