@green-code-studio/objects-list 0.1.8 → 1.0.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.
@@ -6,6 +6,7 @@ import {ContextMenu} from "@green-code-studio/context-menu/dist/index.mjs";
6
6
  import {ConcurencyLimiter} from "./utils/concurencyLimiter.js";
7
7
  import {IdsSet} from "./idsSet.js";
8
8
  import {ConfigPopup} from "./ConfigPopup.js";
9
+ import {create} from "fast-creator";
9
10
 
10
11
  export class ObjectsList extends HTMLElement {
11
12
  constructor(datasource) {
@@ -103,8 +104,10 @@ export class ObjectsList extends HTMLElement {
103
104
  }
104
105
 
105
106
  initFoot() {
106
- this.foot = this.addChild('.foot');
107
- let menuButton = this.foot.addChild('button.menuButton span.icon-settings');
107
+ this.foot = create('.foot');
108
+ this.append(this.foot);
109
+ let menuButton = create('button.menuButton span.icon-settings');
110
+ this.foot.append(menuButton)
108
111
  menuButton.onclick = e => this.showConfigPopup();
109
112
  this.pagination = new PaginationButtons();
110
113
  this.pagination.onpageclick = (page) => {
@@ -112,13 +115,15 @@ export class ObjectsList extends HTMLElement {
112
115
  this.refresh();
113
116
  }
114
117
  this.foot.append(this.pagination);
115
- this.searchForm = this.foot.addChild('form', {className: 'search'});
118
+ this.searchForm = create('form', {className: 'search'});
119
+ this.foot.append(this.searchForm);
116
120
  this.searchForm.onsubmit = e => e.preventDefault();
117
- const searchInput = this.searchForm.addChild('input', {
121
+ const searchInput = create('input', {
118
122
  name: 'search',
119
123
  type: 'search',
120
124
  placeholder: t('objectList.search')
121
125
  });
126
+ this.searchForm.append(create(searchInput));
122
127
  searchInput.oninput = e => {
123
128
  this.start = 0;
124
129
  this.refresh();
@@ -1,3 +1,5 @@
1
+ import {create} from "fast-creator";
2
+
1
3
  export class PaginationButtons extends HTMLElement {
2
4
  constructor() {
3
5
  super();
@@ -8,15 +10,18 @@ export class PaginationButtons extends HTMLElement {
8
10
 
9
11
  render() {
10
12
  let pagination = this.getPagination();
11
- this.children.removeAll();
13
+ while(this.firstChild){
14
+ this.removeChild(this.firstChild)
15
+ }
12
16
  for (let pageNumber of pagination) {
13
17
  if (pageNumber == null) {
14
- this.addChild('span', {text: '...'});
18
+ this.append(create('span', {text: '...'}));
15
19
  } else {
16
- let pageButton = this.addChild('button', {
20
+ let pageButton = create('button', {
17
21
  text: pageNumber + 1,
18
22
  className: pageNumber == this.currentPage ? 'active' : ''
19
23
  });
24
+ this.append(pageButton);
20
25
  pageButton.onclick = () => {
21
26
  if (this.onpageclick) {
22
27
  this.onpageclick(pageNumber);
@@ -68,4 +73,4 @@ export class PaginationButtons extends HTMLElement {
68
73
  }
69
74
  }
70
75
 
71
- customElements.define('pagination-buttons', PaginationButtons);
76
+ customElements.define('pagination-buttons', PaginationButtons);
@@ -0,0 +1,214 @@
1
+ @import "@green-code-studio/context-menu/src/contextMenu.scss";
2
+ data-view {
3
+ border: 1px solid var(--second);
4
+ display: flex;
5
+ flex-direction: column;
6
+ height: calc(100vh - 200px);
7
+ user-select: none;
8
+
9
+
10
+ table-view {
11
+ display: block;
12
+ flex-grow: 1;
13
+ overflow: auto;
14
+ --rowHeight: 41px;
15
+
16
+ .bodyContainer {
17
+
18
+ }
19
+
20
+ .head {
21
+ position: sticky;
22
+ top: 0;
23
+ z-index: 1;
24
+ height: 19px;
25
+ background: var(--second);
26
+
27
+ .column {
28
+ background: var(--second);
29
+ color: var(--textSecondColor);
30
+ cursor: default;
31
+ white-space: nowrap;
32
+ overflow: hidden;
33
+ text-overflow: ellipsis;
34
+ font-weight: 700;
35
+ position: absolute;
36
+ padding: 0 10px;
37
+ box-sizing: border-box;
38
+ height: 19px;
39
+
40
+ &.ableToSort {
41
+ //@extend .icon;
42
+ //@extend .icon-down;
43
+
44
+ &::before {
45
+ transform: scaleY(0);
46
+ transition: all 300ms ease-out;
47
+ position: absolute;
48
+ right: 0;
49
+ }
50
+
51
+ &[data-order="asc"] {
52
+ &::before {
53
+ transform: scaleY(1);
54
+ }
55
+ }
56
+
57
+ &[data-order="desc"] {
58
+ &::before {
59
+ transform: scaleY(-1);
60
+ }
61
+ }
62
+
63
+ .tableCopy {
64
+ display: none;
65
+ }
66
+
67
+ cursor: pointer;
68
+ }
69
+
70
+
71
+ }
72
+ }
73
+
74
+ .body {
75
+ position: relative;
76
+
77
+ .tr {
78
+ display: flex;
79
+ position: absolute;
80
+ transition: top 300ms ease, background 100ms;
81
+ table-layout: fixed;
82
+ flex-direction: row;
83
+ animation: data-view-appear 200ms;
84
+
85
+ @keyframes data-view-appear {
86
+ 0% {
87
+ opacity: 0;
88
+ }
89
+ 100% {
90
+ opacity: 1
91
+ }
92
+ }
93
+
94
+
95
+ &.selectedMain, &:focus {
96
+ outline: 2px black dashed;
97
+ outline-offset: -2px;
98
+ }
99
+
100
+ .td {
101
+ padding: 5px 10px;
102
+ margin: 0;
103
+ white-space: nowrap;
104
+ overflow: hidden;
105
+ text-overflow: ellipsis;
106
+ display: block;
107
+ flex: 0 0 auto;
108
+ box-sizing: border-box;
109
+ height: var(--rowHeight);
110
+
111
+ button, .button {
112
+ font-size: 16px;
113
+ margin-left: 2px;
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+
120
+ }
121
+
122
+ list-view {
123
+ display: block;
124
+ flex-grow: 1;
125
+ overflow: auto;
126
+
127
+ .body {
128
+ position: relative;
129
+
130
+ .tr {
131
+ display: grid;
132
+ position: absolute;
133
+ transition: top 300ms ease, background 100ms;
134
+ animation: data-view-appear 200ms;
135
+ grid-template-columns: max-content 1fr max-content;
136
+ width: 100%;
137
+ padding: 10px 0;
138
+
139
+
140
+ &.selectedMain, &:focus {
141
+ outline: 2px black dashed;
142
+ outline-offset: -2px;
143
+ }
144
+
145
+ button, .button {
146
+ font-size: 16px;
147
+ margin-left: 2px;
148
+ }
149
+
150
+ .icon {
151
+ grid-column: 1;
152
+ grid-row: 1/4;
153
+ font-size: 40px;
154
+ line-height: 63px;
155
+ }
156
+
157
+ .keyValue {
158
+ grid-column: 2/4;
159
+ overflow: hidden;
160
+ white-space: nowrap;
161
+ text-overflow: ellipsis;
162
+ line-height: 21px;
163
+
164
+
165
+ &:nth-child(2), &:nth-child(3) {
166
+ grid-column: 2;
167
+ }
168
+ }
169
+
170
+ .actions {
171
+ grid-column: 3;
172
+ grid-row: 1/3;
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ .foot {
179
+ border-top: 1px solid var(--second);
180
+ display: flex;
181
+ justify-content: space-between;
182
+
183
+ @media (max-width: 600px) {
184
+ form {
185
+ input {
186
+ width: 40px;
187
+
188
+ &:focus {
189
+ width: 200px;
190
+ margin-left: -160px;
191
+ }
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ &.infiniteScrollEnabled {
198
+ table-view, list-view {
199
+ .body {
200
+ height: var(--height);
201
+ }
202
+ }
203
+
204
+ pagination-buttons {
205
+ display: none;
206
+ }
207
+ }
208
+ }
209
+
210
+ pagination-buttons {
211
+ button.active {
212
+ background: var(--main);
213
+ }
214
+ }
package/src/tableView.js CHANGED
@@ -28,10 +28,11 @@ export class TableView extends AbstractView {
28
28
  refreshHeader() {
29
29
  while (this.head.firstChild) this.head.firstChild.remove();
30
30
 
31
- this.head.addChild('.column.icon')
31
+ this.head.append(create('.column.icon'))
32
32
  for (let column of this.objectsList.visibleColumns) {
33
- let node = this.head.addChild('.column')
34
- node.addChild('span.name', {text: column.name});
33
+ let node = create('.column')
34
+ this.head.append(node);
35
+ node.append(create('span.name', {text: column.name}));
35
36
  if (column.sortName) {
36
37
  node.classList.add('ableToSort');
37
38
  node.dataset.sortName = column.sortName
@@ -49,7 +50,7 @@ export class TableView extends AbstractView {
49
50
  }
50
51
  }
51
52
  }
52
- this.head.addChild('.column.actions')
53
+ this.head.append(create('.column.actions'))
53
54
  }
54
55
 
55
56
  loadData(data, start, limit, infiniteScrollEnabled) {
@@ -65,7 +66,7 @@ export class TableView extends AbstractView {
65
66
  generateRow(data) {
66
67
  let tr = this.body.querySelector(`.tr[data-row="${data.id}"]`);
67
68
  if (!tr) {
68
- tr = document.create('.tr');
69
+ tr = create('.tr');
69
70
  tr.draggable = true;
70
71
  }
71
72
  tr.classList.toggle('selected', this.objectsList.selected.has(data.id))
@@ -75,23 +76,27 @@ export class TableView extends AbstractView {
75
76
 
76
77
  fillRowContent(tr, data) {
77
78
  tr.lastData = data;
78
- tr.children.removeAll();
79
- tr.addChild('.td.icon', {className: this.objectsList.icon});
79
+ while(tr.firstChild){
80
+ tr.removeChild(tr.firstChild)
81
+ }
82
+ tr.append(create('.td.icon', {className: this.objectsList.icon}));
80
83
  for (let column of this.objectsList.visibleColumns) {
81
- let td = tr.addChild('.td');
84
+ let td = create('.td');
85
+ tr.append(td);
82
86
  if (this.multiEdit && column.dataName) {
83
87
  tr.dataset.id = data.id;
84
- td.addChild('input', {
88
+ td.append(create('input', {
85
89
  data: {name: column.dataName},
86
90
  value: data[column.dataName],
87
91
  onclick: e => e.stopPropagation(),
88
92
  onchange: () => this.multiEditChanged(tr)
89
- });
93
+ }));
90
94
  } else {
91
95
  td.append(column.content?.call(column, data) || data[column.dataName] || '');
92
96
  }
93
97
  }
94
- let actionsTd = tr.addChild('.td.actions');
98
+ let actionsTd = create('.td.actions');
99
+ tr.append(actionsTd);
95
100
  let actions = this.objectsList.generateActions([data], 'row');
96
101
  if (this.multiEdit && data.__isMultirowEdited) {
97
102
  actions = [
@@ -105,9 +110,10 @@ export class TableView extends AbstractView {
105
110
  ]
106
111
  }
107
112
  for (let action of actions) {
108
- let actionButton = actionsTd.addChild(action.href ? 'a.button' : 'button', {
113
+ let actionButton = create(action.href ? 'a.button' : 'button', {
109
114
  title: action.name
110
115
  });
116
+ actionsTd.append(create(actionButton));
111
117
  actionButton.classList.add('action-' + (action.action ?? 'view'));
112
118
 
113
119
  if (action.href) {
@@ -117,7 +123,7 @@ export class TableView extends AbstractView {
117
123
  actionButton.onclick = action.command;
118
124
  }
119
125
  if (action.icon) {
120
- actionButton.addChild('span', {classList: [action.icon]});
126
+ actionButton.append(create('span', {classList: [action.icon]}));
121
127
  } else {
122
128
  actionButton.textContent = action.name;
123
129
  }
@@ -164,10 +170,10 @@ export class TableView extends AbstractView {
164
170
  return x.lastElementChild.getBoundingClientRect().right - x.getBoundingClientRect().left + parseFloat(getComputedStyle(x).paddingRight);
165
171
  else
166
172
  return 0;
167
- }).max());
173
+ }).reduce((a, b) => Math.max(a, b), 0));
168
174
  needed.push({base: actionWidth, grow: 0});
169
- let availableToGrow = this.clientWidth - needed.sum(x => x.base);
170
- let sumGrow = needed.sum(x => x.grow);
175
+ let availableToGrow = this.clientWidth - needed.map(x => x.base).reduce((a, b) => a + b, 0);
176
+ let sumGrow = needed.map(x => x.grow).reduce((a, b) => a + b, 0);
171
177
  if (availableToGrow > 0 && sumGrow > 0) {
172
178
  return needed.map(x => x.base + x.grow / sumGrow * availableToGrow);
173
179
  } else {
@@ -27,7 +27,15 @@ export default {
27
27
  {
28
28
  test: /\.mpts$/,
29
29
  use: ["mpts-loader"]
30
- }
30
+ },{
31
+ test: /\.scss$/,
32
+ use: [
33
+ "style-loader", // creates style nodes from JS strings
34
+ "css-loader", // translates CSS into CommonJS
35
+ "sass-loader" // compiles Sass to CSS, using Node Sass by default
36
+ ]
37
+
38
+ },
31
39
  ]
32
40
  }
33
41
  }
package/webpack.config.js CHANGED
@@ -6,7 +6,8 @@ import {fileURLToPath} from 'url';
6
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
7
  export default {
8
8
  entry: {
9
- index: './src/index.js'
9
+ index: './src/index.js',
10
+ style: './src/style/objectsList.scss',
10
11
  },
11
12
  output: {
12
13
  path: path.resolve(__dirname, './dist'),
@@ -23,6 +24,13 @@ export default {
23
24
  {
24
25
  test: /\.mpts$/,
25
26
  use: ["mpts-loader"]
27
+ },{
28
+ test: /\.scss$/,
29
+ use: [
30
+ "css-loader", // translates CSS into CommonJS
31
+ "sass-loader" // compiles Sass to CSS, using Node Sass by default
32
+ ]
33
+
26
34
  }
27
35
  ]
28
36
  },
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/objects-list.iml" filepath="$PROJECT_DIR$/.idea/objects-list.iml" />
6
- </modules>
7
- </component>
8
- </project>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$" />
5
- <orderEntry type="inheritedJdk" />
6
- <orderEntry type="sourceFolder" forTests="false" />
7
- </component>
8
- </module>
package/.idea/php.xml DELETED
@@ -1,19 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="MessDetectorOptionsConfiguration">
4
- <option name="transferred" value="true" />
5
- </component>
6
- <component name="PHPCSFixerOptionsConfiguration">
7
- <option name="transferred" value="true" />
8
- </component>
9
- <component name="PHPCodeSnifferOptionsConfiguration">
10
- <option name="highlightLevel" value="WARNING" />
11
- <option name="transferred" value="true" />
12
- </component>
13
- <component name="PhpStanOptionsConfiguration">
14
- <option name="transferred" value="true" />
15
- </component>
16
- <component name="PsalmOptionsConfiguration">
17
- <option name="transferred" value="true" />
18
- </component>
19
- </project>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>