@green-code-studio/objects-list 1.9.7 → 1.10.1
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.
- package/demo/demo.js +14 -7
- package/demoDist/demo.js +5 -5
- package/dist/index.mjs +17 -7
- package/dist/style.mjs +1 -1
- package/package.json +1 -1
- package/src/ConfigPopup.js +4 -0
- package/src/ConfigPopup.mpts +4 -0
- package/src/abstractView.js +197 -0
- package/src/calendarView.js +58 -0
- package/src/i18n.xml +8 -0
- package/src/listView.js +5 -5
- package/src/objectsList.js +26 -7
- package/src/style/objectsList.scss +17 -2
- package/src/tableView.js +0 -196
package/src/abstractView.js
CHANGED
|
@@ -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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
package/src/objectsList.js
CHANGED
|
@@ -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) {
|
|
@@ -62,13 +63,16 @@ export class ObjectsList extends HTMLElement {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
get visibleColumns() {
|
|
65
|
-
return this.columnsReordered.filter(x => !this.hiddenColumns.has(x.dataName??x.sortName))
|
|
66
|
+
return this.columnsReordered.filter(x => !this.hiddenColumns.has(x.dataName ?? x.sortName))
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
refreshLimit() {
|
|
69
70
|
this.limit = this.insideView.calcMaxVisibleItems(this.clientHeight - this.foot.clientHeight - 2);
|
|
70
71
|
if (this.limit < 1) this.limit = 1;
|
|
71
|
-
if (this.
|
|
72
|
+
if (this.insideView instanceof CalendarView) {
|
|
73
|
+
this.start = 0;
|
|
74
|
+
this.limit = 1000000;
|
|
75
|
+
} else if (this.infiniteScrollEnabled) {
|
|
72
76
|
this.limit = Math.ceil(this.limit / 20) * 20 + 40;
|
|
73
77
|
} else {
|
|
74
78
|
this.start = Math.floor(Math.min(this.total, this.start) / this.limit) * this.limit;
|
|
@@ -90,6 +94,8 @@ export class ObjectsList extends HTMLElement {
|
|
|
90
94
|
const refreshSymbol = Symbol();
|
|
91
95
|
this.lastRefreshSymbol = refreshSymbol;
|
|
92
96
|
this.lastRefreshSymbolTotal = refreshSymbol;
|
|
97
|
+
this.pagination.style.display = this.insideView instanceof CalendarView ? 'none' : '';
|
|
98
|
+
this.dateInput.style.display = this.insideView instanceof CalendarView ? '' : 'none';
|
|
93
99
|
if (this.asyncTotal) {
|
|
94
100
|
const promise1 = this.loadConcurencyLimiter.run(async () => {
|
|
95
101
|
if (this.lastRefreshSymbol != refreshSymbol) return;
|
|
@@ -179,7 +185,7 @@ export class ObjectsList extends HTMLElement {
|
|
|
179
185
|
old = old || {};
|
|
180
186
|
let ret = {};
|
|
181
187
|
let changed = false;
|
|
182
|
-
var visibleColumns = this.visibleColumns.map(x => x.dataName??x.sortName).join();
|
|
188
|
+
var visibleColumns = this.visibleColumns.map(x => x.dataName ?? x.sortName).join();
|
|
183
189
|
if (old.visibleColumns || this.hiddenColumns.size || this.columnsReorderedChanged) {
|
|
184
190
|
ret.visibleColumns = visibleColumns;
|
|
185
191
|
changed = true;
|
|
@@ -224,9 +230,15 @@ export class ObjectsList extends HTMLElement {
|
|
|
224
230
|
} else if (value == 'tableWideView') {
|
|
225
231
|
this.insideViewClass = TableView
|
|
226
232
|
this.insideViewParams = {wide: true}
|
|
227
|
-
} else {
|
|
233
|
+
} else if (value == 'listView') {
|
|
228
234
|
this.insideViewClass = ListView
|
|
229
235
|
this.insideViewParams = {}
|
|
236
|
+
} else if (value == 'calendarView') {
|
|
237
|
+
this.insideViewClass = CalendarView
|
|
238
|
+
this.insideViewParams = {}
|
|
239
|
+
} else if (value == 'timelineView') {
|
|
240
|
+
this.insideViewClass = TimelineView
|
|
241
|
+
this.insideViewParams = {}
|
|
230
242
|
}
|
|
231
243
|
}
|
|
232
244
|
|
|
@@ -240,13 +252,13 @@ export class ObjectsList extends HTMLElement {
|
|
|
240
252
|
applyParams(params) {
|
|
241
253
|
if (params?.visibleColumns) {
|
|
242
254
|
const splitted = params.visibleColumns.split(',');
|
|
243
|
-
this.hiddenColumns = new Set(this.columns.map(x => x.dataName??x.sortName));
|
|
255
|
+
this.hiddenColumns = new Set(this.columns.map(x => x.dataName ?? x.sortName));
|
|
244
256
|
for (const name of splitted) {
|
|
245
257
|
this.hiddenColumns.delete(name);
|
|
246
258
|
}
|
|
247
259
|
for (let i = splitted.length - 1; i > 0; i--) {
|
|
248
|
-
const column = this.columnsReordered.find(x => (x.dataName??x.sortName) == splitted[i - 1]);
|
|
249
|
-
const next = this.columnsReordered.find(x => (x.dataName??x.sortName) == splitted[i]);
|
|
260
|
+
const column = this.columnsReordered.find(x => (x.dataName ?? x.sortName) == splitted[i - 1]);
|
|
261
|
+
const next = this.columnsReordered.find(x => (x.dataName ?? x.sortName) == splitted[i]);
|
|
250
262
|
if (column) {
|
|
251
263
|
this.columnsReordered.splice(this.columnsReordered.indexOf(column), 1);
|
|
252
264
|
if (next)
|
|
@@ -313,6 +325,13 @@ export class ObjectsList extends HTMLElement {
|
|
|
313
325
|
this.refresh();
|
|
314
326
|
}
|
|
315
327
|
this.foot.append(this.pagination);
|
|
328
|
+
this.dateInput = create('input', {type: 'month', value: new Date().toISOString().substring(0, 7)});
|
|
329
|
+
this.dateInput.onchange = date => {
|
|
330
|
+
this.start = 0;
|
|
331
|
+
this.date = this.dateInput.value;
|
|
332
|
+
this.refresh();
|
|
333
|
+
}
|
|
334
|
+
this.foot.append(this.dateInput);
|
|
316
335
|
this.filterShortContainer = create('.filterShortContainer');
|
|
317
336
|
this.foot.append(this.filterShortContainer);
|
|
318
337
|
this.searchForm = create('form', {className: 'search'});
|
|
@@ -180,6 +180,20 @@ data-view {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
calendar-view {
|
|
184
|
+
flex-grow: 1;
|
|
185
|
+
|
|
186
|
+
.bodyContainer {
|
|
187
|
+
overflow: scroll;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.body {
|
|
191
|
+
display: grid;
|
|
192
|
+
grid-template-columns: repeat(7, 1fr);
|
|
193
|
+
min-height: 100%;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
183
197
|
.foot {
|
|
184
198
|
border-top: 1px solid var(--second);
|
|
185
199
|
display: flex;
|
|
@@ -223,8 +237,9 @@ pagination-buttons {
|
|
|
223
237
|
background: var(--main);
|
|
224
238
|
}
|
|
225
239
|
}
|
|
226
|
-
|
|
227
|
-
|
|
240
|
+
|
|
241
|
+
.categoryTableContainer {
|
|
242
|
+
&:not(:has(.filter)) .filterHeader {
|
|
228
243
|
display: none;
|
|
229
244
|
}
|
|
230
245
|
}
|
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 => {
|