@green-code-studio/objects-list 1.5.3 → 1.6.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.
package/demo/demo.js CHANGED
@@ -18,8 +18,11 @@ const dataSource={
18
18
  const objectList=new ObjectsList(dataSource)
19
19
  objectList.paramsInUrl=true;
20
20
  objectList.columns=[
21
- {dataName:'id', title:'ID'},
22
- {dataName:'name', title:'Name'},
21
+ {dataName:'id', name:'ID'},
22
+ {dataName:'name', name:'Name'},
23
+ {name:'a', content:()=>{return 'aaa'}},
24
+ {name:'b', content:()=>{return 'bbb'}},
25
+ {name:'c', content:()=>{return 'ccc'}},
23
26
  ]
24
27
  objectList.generateActions=()=>[{title:'zz', href:'https://google.com'}]
25
28
  objectList.style.height='500px';
package/dist/index.mjs CHANGED
@@ -174,7 +174,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
174
174
  \****************************/
175
175
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
176
176
 
177
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ObjectsList: () => (/* binding */ ObjectsList)\n/* harmony export */ });\n/* harmony import */ var _tableView_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tableView.js */ \"./src/tableView.js\");\n/* harmony import */ var _listView_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./listView.js */ \"./src/listView.js\");\n/* harmony import */ var _i18n_xml__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./i18n.xml */ \"./src/i18n.xml\");\n/* harmony import */ var _paginationButtons_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./paginationButtons.js */ \"./src/paginationButtons.js\");\n/* harmony import */ var _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @green-code-studio/context-menu/dist/index.mjs */ \"./node_modules/@green-code-studio/context-menu/dist/index.mjs\");\n/* harmony import */ var _utils_concurencyLimiter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/concurencyLimiter.js */ \"./src/utils/concurencyLimiter.js\");\n/* harmony import */ var _idsSet_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./idsSet.js */ \"./src/idsSet.js\");\n/* harmony import */ var _ConfigPopup_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ConfigPopup.js */ \"./src/ConfigPopup.js\");\n/* harmony import */ var fast_creator__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! fast-creator */ \"./node_modules/fast-creator/dist/entry.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass ObjectsList extends HTMLElement {\r\n constructor(datasource) {\r\n super();\r\n this.columns = [];\r\n this.hiddenColumns = new Set()\r\n this.columnFilters = new Map();\r\n this.generateActions = () => [];\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView;\r\n this.icon = 'icon-document';\r\n this.loadConcurencyLimiter = new _utils_concurencyLimiter_js__WEBPACK_IMPORTED_MODULE_5__.ConcurencyLimiter();\r\n this.datasource = datasource;\r\n this.datasource.onchange = () => this.refresh();\r\n this.start = 0;\r\n this.limit = 10\r\n this.total = 0;\r\n this.selected = new _idsSet_js__WEBPACK_IMPORTED_MODULE_6__.IdsSet();\r\n this.selectedMain = null;\r\n this.dataById = new Map();\r\n this.initFoot();\r\n this.addEventListener('contextmenu', e => this.showGlobalContextMenu(e));\r\n addEventListener('resize', e => this.resize());\r\n this.addEventListener('keydown', e => this.onkeydown(e));\r\n this.infiniteScrollEnabled = false;\r\n }\r\n\r\n get visibleColumns() {\r\n return this.columns.filter(x => !this.hiddenColumns.has(x.dataName))\r\n }\r\n\r\n refreshLimit() {\r\n this.limit = this.insideView.calcMaxVisibleItems(this.clientHeight - this.foot.clientHeight - 2);\r\n if (this.limit < 1) this.limit = 1;\r\n if (this.infiniteScrollEnabled) {\r\n this.limit = Math.ceil(this.limit / 20) * 20 + 40;\r\n } else {\r\n this.start = Math.floor(Math.min(this.total, this.start) / this.limit) * this.limit;\r\n }\r\n }\r\n\r\n async refresh() {\r\n this.classList.toggle('infiniteScrollEnabled', this.infiniteScrollEnabled);\r\n\r\n if (!this.insideView || !(this.insideView instanceof this.insideViewClass))\r\n this.initInsideView();\r\n else if (this.insideView.refreshHeader) {\r\n this.insideView.params=this.insideViewParams\r\n this.insideView.refreshHeader()\r\n }\r\n\r\n this.refreshLimit();\r\n const refreshSymbol = Symbol();\r\n this.lastRefreshSymbol = refreshSymbol;\r\n await this.loadConcurencyLimiter.run(async () => {\r\n if (this.lastRefreshSymbol != refreshSymbol) return;\r\n\r\n let data = await this.datasource.get(this);\r\n if (this.lastRefreshSymbol != refreshSymbol) return;\r\n\r\n this.currentRows = data.rows;\r\n this.fillDataById(data.rows);\r\n this.total = data.total;\r\n this.insideView.loadData(data, this.start, this.limit, this.infiniteScrollEnabled);\r\n this.pagination.currentPage = Math.floor(this.start / this.limit);\r\n this.pagination.totalPages = Math.ceil(this.total / this.limit);\r\n this.pagination.render();\r\n });\r\n while (this.filterShortContainer.firstChild) {\r\n this.filterShortContainer.firstChild.remove()\r\n }\r\n if (this.columnFilters.size) {\r\n this.filterShortContainer.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('span', {text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.filtersCount') + ': ' + this.columnFilters.size}));\r\n const clearButton = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('button', {text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.clearFilters')});\r\n clearButton.onclick = () => {\r\n this.columnFilters.clear();\r\n this.refresh();\r\n }\r\n this.filterShortContainer.append(clearButton);\r\n }\r\n if (this.paramsInUrl) {\r\n this.setUrl();\r\n }\r\n }\r\n\r\n setUrl() {\r\n const query = new URLSearchParams(document.location.search)\r\n console.log('dddddcccc')\r\n console.log(query)\r\n let changed = false;\r\n var visibleColumns = this.visibleColumns.map(x => x.dataName).join();\r\n if (query.get('visibleColumns') || this.hiddenColumns.size) {\r\n if (query.get('visibleColumns') != visibleColumns) {\r\n query.set('visibleColumns', visibleColumns);\r\n changed = true;\r\n }\r\n }\r\n if (query.get('sort') || this.sort?.col) {\r\n if (query.get('sort') != this.sort?.col) {\r\n query.set('sort', this.sort?.col);\r\n changed = true;\r\n }\r\n }\r\n if (query.get('sortDesc') == 'true' || this.sort?.desc) {\r\n if ((query.get('sortDesc') == 'true') != this.sort?.desc) {\r\n query.set('sortDesc', this.sort?.desc ? 'true' : 'false');\r\n changed = true;\r\n }\r\n }\r\n if (query.get('columnFilters') || this.columnFilters) {\r\n if (query.get('columnFilters') != JSON.stringify(Array.from(this.columnFilters.entries()))) {\r\n query.set('columnFilters', JSON.stringify(Array.from(this.columnFilters.entries())));\r\n changed = true;\r\n }\r\n }\r\n\r\n if (query.get('insideView') || this.insideViewName) {\r\n if(query.get('insideView') !=this.insideViewName){\r\n query.set('insideView', this.insideViewName);\r\n changed = true;\r\n }\r\n }\r\n if (changed) {\r\n const url = new URL(document.location);\r\n url.search = new URLSearchParams(query).toString();\r\n history.pushState(null, '', url.toString());\r\n }\r\n }\r\n get insideViewName(){\r\n if(this.insideViewClass == _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView){\r\n if(this.insideViewParams?.wide)\r\n return 'tableWideView';\r\n else\r\n return 'tableView'\r\n }else{\r\n return 'listView'\r\n }\r\n }\r\n set insideViewName(value){\r\n if(this.insideViewName == value)return;\r\n if (value == 'tableView') {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView\r\n this.insideViewParams = {wide: false}\r\n } else if (value == 'tableWideView') {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView\r\n this.insideViewParams = {wide: true}\r\n } else {\r\n this.insideViewClass = _listView_js__WEBPACK_IMPORTED_MODULE_1__.ListView\r\n this.insideViewParams = {}\r\n }\r\n }\r\n\r\n readUrl() {\r\n\r\n const query = new URLSearchParams(document.location.search)\r\n if (query.get('visibleColumns')) {\r\n this.hiddenColumns = new Set(this.columns.map(x => x.dataName));\r\n for (const name of query.get('visibleColumns').split(',')) {\r\n this.hiddenColumns.delete(name);\r\n }\r\n }\r\n if (query.get('sort')) {\r\n this.sort = query.get('sort');\r\n }\r\n if (query.get('columnFilters')) {\r\n this.columnFilters = new Map(JSON.parse(query.get('columnFilters')));\r\n }\r\n if(query.get('insideView')){\r\n this.insideViewName = query.get('insideView');\r\n }\r\n }\r\n\r\n initInsideView() {\r\n if (this.insideView) {\r\n this.insideView.remove();\r\n }\r\n this.insideView = new this.insideViewClass(this, this.insideViewParams);\r\n this.insertBefore(this.insideView, this.foot);\r\n this.insideView.refresh = () => this.refresh();\r\n this.insideView.onPaginationChanged = (start, limit) => {\r\n if (this.start != start) {\r\n this.start = start;\r\n //this.limit=limit;\r\n this.refresh();\r\n }\r\n }\r\n }\r\n\r\n fillDataById(rows) {\r\n for (let row of rows) {\r\n this.dataById.set(parseInt(row.id), row);\r\n }\r\n }\r\n\r\n getSelectedData() {\r\n let data = Array.from(this.dataById).filter(([id, row]) => this.selected.has(id)).map(([id, row]) => row);\r\n if (data.length > 0) return data;\r\n else if (this.dataById[this.selectedMain])\r\n return [this.dataById[this.selectedMain]]\r\n else return [];\r\n }\r\n\r\n initFoot() {\r\n this.foot = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('.foot');\r\n this.append(this.foot);\r\n let menuButton = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('button.menuButton span.icon-settings');\r\n this.foot.append(menuButton)\r\n menuButton.onclick = e => this.showConfigPopup();\r\n this.pagination = new _paginationButtons_js__WEBPACK_IMPORTED_MODULE_3__.PaginationButtons();\r\n this.pagination.onpageclick = (page) => {\r\n this.start = page * this.limit;\r\n this.refresh();\r\n }\r\n this.foot.append(this.pagination);\r\n this.filterShortContainer = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('.filterShortContainer');\r\n this.foot.append(this.filterShortContainer);\r\n this.searchForm = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('form', {className: 'search'});\r\n this.foot.append(this.searchForm);\r\n this.searchForm.onsubmit = e => e.preventDefault();\r\n const searchInput = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('input', {\r\n name: 'search',\r\n type: 'search',\r\n placeholder: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.search')\r\n });\r\n this.searchForm.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)(searchInput));\r\n searchInput.oninput = e => {\r\n this.start = 0;\r\n this.refresh();\r\n }\r\n\r\n }\r\n\r\n get search() {\r\n if (!this.foot) return '';\r\n const searchForm = this.foot.querySelector('.search');\r\n if (!searchForm) return '';\r\n return searchForm.search.value;\r\n }\r\n\r\n showGlobalContextMenu(e) {\r\n let elements = [{\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.paginationMode'),\r\n icon: 'icon-pagination',\r\n onclick: () => {\r\n this.infiniteScrollEnabled = false;\r\n this.refresh();\r\n }\r\n }, {\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.scrollMode'),\r\n icon: 'icon-scroll',\r\n onclick: () => {\r\n this.infiniteScrollEnabled = true;\r\n this.refresh();\r\n }\r\n }, {\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.tableView'),\r\n icon: 'icon-table',\r\n onclick: () => {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView;\r\n this.refresh();\r\n }\r\n }, {\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.listView'),\r\n icon: 'icon-table',\r\n onclick: () => {\r\n this.insideViewClass = _listView_js__WEBPACK_IMPORTED_MODULE_1__.ListView;\r\n this.refresh();\r\n }\r\n }];\r\n if (this.allowTableEdit) {\r\n elements.push({\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.startMultiEdit'),\r\n icon: 'icon-edit',\r\n onclick: () => {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView;\r\n this.refresh();\r\n this.insideView.startMultiEdit();\r\n }\r\n });\r\n }\r\n _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_4__.ContextMenu.openContextMenu(e, elements);\r\n }\r\n\r\n resize() {\r\n let limit = this.limit;\r\n this.refreshLimit();\r\n if (limit != this.limit) {\r\n this.refresh();\r\n }\r\n }\r\n\r\n multiEditChanged(id, data, save = false) {\r\n this.datasource.multiEditChanged(id, data, save);\r\n }\r\n\r\n showConfigPopup() {\r\n if (this.querySelector('config-popup')) {\r\n this.querySelector('config-popup').remove()\r\n } else {\r\n const popup = new _ConfigPopup_js__WEBPACK_IMPORTED_MODULE_7__.ConfigPopup(this)\r\n this.append(popup)\r\n }\r\n }\r\n\r\n gotoUrl(url) {\r\n window.location.href = url;\r\n }\r\n\r\n onkeydown(e) {\r\n if (e.ctrlKey) {\r\n if (e.key == 'ArrowLeft' || e.key == 'ArrowRight') {\r\n let page = Math.floor(this.start / this.limit);\r\n page += (e.key == 'ArrowLeft' ? -1 : 1);\r\n if (page < 0) page = 0;\r\n else if (page>0 && page > Math.ceil(this.total / this.limit)-1) page = Math.ceil(this.total / this.limit)-1;\r\n this.start = page * this.limit;\r\n this.refresh();\r\n }\r\n }\r\n }\r\n}\r\n\r\ncustomElements.define('data-view', ObjectsList);\r\n\n\n//# sourceURL=webpack://@green-code-studio/objects-list/./src/objectsList.js?");
177
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ObjectsList: () => (/* binding */ ObjectsList)\n/* harmony export */ });\n/* harmony import */ var _tableView_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tableView.js */ \"./src/tableView.js\");\n/* harmony import */ var _listView_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./listView.js */ \"./src/listView.js\");\n/* harmony import */ var _i18n_xml__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./i18n.xml */ \"./src/i18n.xml\");\n/* harmony import */ var _paginationButtons_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./paginationButtons.js */ \"./src/paginationButtons.js\");\n/* harmony import */ var _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @green-code-studio/context-menu/dist/index.mjs */ \"./node_modules/@green-code-studio/context-menu/dist/index.mjs\");\n/* harmony import */ var _utils_concurencyLimiter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/concurencyLimiter.js */ \"./src/utils/concurencyLimiter.js\");\n/* harmony import */ var _idsSet_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./idsSet.js */ \"./src/idsSet.js\");\n/* harmony import */ var _ConfigPopup_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ConfigPopup.js */ \"./src/ConfigPopup.js\");\n/* harmony import */ var fast_creator__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! fast-creator */ \"./node_modules/fast-creator/dist/entry.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass ObjectsList extends HTMLElement {\r\n constructor(datasource) {\r\n super();\r\n this.columns = [];\r\n this.hiddenColumns = new Set()\r\n this.columnFilters = new Map();\r\n this.generateActions = () => [];\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView;\r\n this.icon = 'icon-document';\r\n this.loadConcurencyLimiter = new _utils_concurencyLimiter_js__WEBPACK_IMPORTED_MODULE_5__.ConcurencyLimiter();\r\n this.datasource = datasource;\r\n this.datasource.onchange = () => this.refresh();\r\n this.start = 0;\r\n this.limit = 10\r\n this.total = 0;\r\n this.selected = new _idsSet_js__WEBPACK_IMPORTED_MODULE_6__.IdsSet();\r\n this.selectedMain = null;\r\n this.dataById = new Map();\r\n this.initFoot();\r\n this.addEventListener('contextmenu', e => this.showGlobalContextMenu(e));\r\n addEventListener('resize', e => this.resize());\r\n this.addEventListener('keydown', e => this.onkeydown(e));\r\n this.infiniteScrollEnabled = false;\r\n }\r\n\r\n get visibleColumns() {\r\n return this.columns.filter(x => !this.hiddenColumns.has(x.dataName))\r\n }\r\n\r\n refreshLimit() {\r\n this.limit = this.insideView.calcMaxVisibleItems(this.clientHeight - this.foot.clientHeight - 2);\r\n if (this.limit < 1) this.limit = 1;\r\n if (this.infiniteScrollEnabled) {\r\n this.limit = Math.ceil(this.limit / 20) * 20 + 40;\r\n } else {\r\n this.start = Math.floor(Math.min(this.total, this.start) / this.limit) * this.limit;\r\n }\r\n }\r\n\r\n async refresh() {\r\n this.classList.toggle('infiniteScrollEnabled', this.infiniteScrollEnabled);\r\n\r\n if (!this.insideView || !(this.insideView instanceof this.insideViewClass))\r\n this.initInsideView();\r\n else if (this.insideView.refreshHeader) {\r\n this.insideView.params = this.insideViewParams\r\n this.insideView.refreshHeader()\r\n }\r\n\r\n this.refreshLimit();\r\n const refreshSymbol = Symbol();\r\n this.lastRefreshSymbol = refreshSymbol;\r\n await this.loadConcurencyLimiter.run(async () => {\r\n if (this.lastRefreshSymbol != refreshSymbol) return;\r\n\r\n let data = await this.datasource.get(this);\r\n if (this.lastRefreshSymbol != refreshSymbol) return;\r\n\r\n this.currentRows = data.rows;\r\n this.fillDataById(data.rows);\r\n this.total = data.total;\r\n this.insideView.loadData(data, this.start, this.limit, this.infiniteScrollEnabled);\r\n this.pagination.currentPage = Math.floor(this.start / this.limit);\r\n this.pagination.totalPages = Math.ceil(this.total / this.limit);\r\n this.pagination.render();\r\n });\r\n while (this.filterShortContainer.firstChild) {\r\n this.filterShortContainer.firstChild.remove()\r\n }\r\n if (this.columnFilters.size) {\r\n this.filterShortContainer.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('span', {text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.filtersCount') + ': ' + this.columnFilters.size}));\r\n const clearButton = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('button', {text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.clearFilters')});\r\n clearButton.onclick = () => {\r\n this.columnFilters.clear();\r\n this.refresh();\r\n }\r\n this.filterShortContainer.append(clearButton);\r\n }\r\n if (this.paramsInUrl) {\r\n this.setUrl();\r\n }\r\n }\r\n\r\n setUrl() {\r\n const query = new URLSearchParams(document.location.search)\r\n console.log('dddddcccc')\r\n console.log(query)\r\n let changed = false;\r\n var visibleColumns = this.visibleColumns.map(x => x.dataName).join();\r\n if (query.get('visibleColumns') || this.hiddenColumns.size) {\r\n if (query.get('visibleColumns') != visibleColumns) {\r\n query.set('visibleColumns', visibleColumns);\r\n changed = true;\r\n }\r\n }\r\n if (query.get('sort') || this.sort?.col) {\r\n if (query.get('sort') != this.sort?.col) {\r\n query.set('sort', this.sort?.col);\r\n changed = true;\r\n }\r\n }\r\n if (query.get('sortDesc') == 'true' || this.sort?.desc) {\r\n if ((query.get('sortDesc') == 'true') != this.sort?.desc) {\r\n query.set('sortDesc', this.sort?.desc ? 'true' : 'false');\r\n changed = true;\r\n }\r\n }\r\n if (query.get('columnFilters') || this.columnFilters) {\r\n if (query.get('columnFilters') != JSON.stringify(Array.from(this.columnFilters.entries()))) {\r\n query.set('columnFilters', JSON.stringify(Array.from(this.columnFilters.entries())));\r\n changed = true;\r\n }\r\n }\r\n\r\n if (query.get('insideView') || this.insideViewName) {\r\n if (query.get('insideView') != this.insideViewName) {\r\n query.set('insideView', this.insideViewName);\r\n changed = true;\r\n }\r\n }\r\n if (changed) {\r\n const url = new URL(document.location);\r\n url.search = new URLSearchParams(query).toString();\r\n history.pushState(null, '', url.toString());\r\n }\r\n }\r\n\r\n get insideViewName() {\r\n if (this.insideViewClass == _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView) {\r\n if (this.insideViewParams?.wide)\r\n return 'tableWideView';\r\n else\r\n return 'tableView'\r\n } else {\r\n return 'listView'\r\n }\r\n }\r\n\r\n set insideViewName(value) {\r\n if (this.insideViewName == value) return;\r\n if (value == 'tableView') {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView\r\n this.insideViewParams = {wide: false}\r\n } else if (value == 'tableWideView') {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView\r\n this.insideViewParams = {wide: true}\r\n } else {\r\n this.insideViewClass = _listView_js__WEBPACK_IMPORTED_MODULE_1__.ListView\r\n this.insideViewParams = {}\r\n }\r\n }\r\n\r\n readUrl() {\r\n\r\n const query = new URLSearchParams(document.location.search)\r\n if (query.get('visibleColumns')) {\r\n this.hiddenColumns = new Set(this.columns.map(x => x.dataName));\r\n for (const name of query.get('visibleColumns').split(',')) {\r\n this.hiddenColumns.delete(name);\r\n }\r\n }\r\n if (query.get('sort')) {\r\n this.sort = query.get('sort');\r\n }\r\n if (query.get('columnFilters')) {\r\n this.columnFilters = new Map(JSON.parse(query.get('columnFilters')));\r\n }\r\n if (query.get('insideView')) {\r\n this.insideViewName = query.get('insideView');\r\n }\r\n }\r\n\r\n initInsideView() {\r\n if (this.insideView) {\r\n this.insideView.remove();\r\n }\r\n this.insideView = new this.insideViewClass(this, this.insideViewParams);\r\n this.insertBefore(this.insideView, this.foot);\r\n this.insideView.refresh = () => this.refresh();\r\n this.insideView.onPaginationChanged = (start, limit) => {\r\n if (this.start != start) {\r\n this.start = start;\r\n //this.limit=limit;\r\n this.refresh();\r\n }\r\n }\r\n }\r\n\r\n fillDataById(rows) {\r\n for (let row of rows) {\r\n this.dataById.set(parseInt(row.id), row);\r\n }\r\n }\r\n\r\n getSelectedData() {\r\n let data = Array.from(this.dataById).filter(([id, row]) => this.selected.has(id)).map(([id, row]) => row);\r\n if (data.length > 0) return data;\r\n else if (this.dataById[this.selectedMain])\r\n return [this.dataById[this.selectedMain]]\r\n else return [];\r\n }\r\n\r\n initFoot() {\r\n this.foot = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('.foot');\r\n this.append(this.foot);\r\n let menuButton = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('button.menuButton span.icon-settings');\r\n this.foot.append(menuButton)\r\n menuButton.onclick = e => this.showConfigPopup();\r\n this.pagination = new _paginationButtons_js__WEBPACK_IMPORTED_MODULE_3__.PaginationButtons();\r\n this.pagination.onpageclick = (page) => {\r\n this.start = page * this.limit;\r\n this.refresh();\r\n }\r\n this.foot.append(this.pagination);\r\n this.filterShortContainer = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('.filterShortContainer');\r\n this.foot.append(this.filterShortContainer);\r\n this.searchForm = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('form', {className: 'search'});\r\n this.foot.append(this.searchForm);\r\n this.searchForm.onsubmit = e => e.preventDefault();\r\n const searchInput = (0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)('input', {\r\n name: 'search',\r\n type: 'search',\r\n placeholder: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.search')\r\n });\r\n this.searchForm.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_8__.create)(searchInput));\r\n searchInput.oninput = e => {\r\n this.start = 0;\r\n this.refresh();\r\n }\r\n\r\n }\r\n\r\n get search() {\r\n if (!this.foot) return '';\r\n const searchForm = this.foot.querySelector('.search');\r\n if (!searchForm) return '';\r\n return searchForm.search.value;\r\n }\r\n\r\n showGlobalContextMenu(e) {\r\n let elements = [{\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.paginationMode'),\r\n icon: 'icon-pagination',\r\n onclick: () => {\r\n this.infiniteScrollEnabled = false;\r\n this.refresh();\r\n }\r\n }, {\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.scrollMode'),\r\n icon: 'icon-scroll',\r\n onclick: () => {\r\n this.infiniteScrollEnabled = true;\r\n this.refresh();\r\n }\r\n }, {\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.tableView'),\r\n icon: 'icon-table',\r\n onclick: () => {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView;\r\n this.refresh();\r\n }\r\n }, {\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.listView'),\r\n icon: 'icon-table',\r\n onclick: () => {\r\n this.insideViewClass = _listView_js__WEBPACK_IMPORTED_MODULE_1__.ListView;\r\n this.refresh();\r\n }\r\n }];\r\n if (this.allowTableEdit) {\r\n elements.push({\r\n text: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_2__.t)('objectList.startMultiEdit'),\r\n icon: 'icon-edit',\r\n onclick: () => {\r\n this.insideViewClass = _tableView_js__WEBPACK_IMPORTED_MODULE_0__.TableView;\r\n this.refresh();\r\n this.insideView.startMultiEdit();\r\n }\r\n });\r\n }\r\n _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_4__.ContextMenu.openContextMenu(e, elements);\r\n }\r\n\r\n resize() {\r\n let limit = this.limit;\r\n this.refreshLimit();\r\n if (limit != this.limit) {\r\n this.refresh();\r\n }\r\n }\r\n\r\n multiEditChanged(id, data, save = false) {\r\n this.datasource.multiEditChanged(id, data, save);\r\n }\r\n\r\n showConfigPopup() {\r\n if (this.querySelector('config-popup')) {\r\n this.querySelector('config-popup').remove()\r\n } else {\r\n const popup = new _ConfigPopup_js__WEBPACK_IMPORTED_MODULE_7__.ConfigPopup(this)\r\n this.append(popup)\r\n }\r\n }\r\n\r\n gotoUrl(url) {\r\n window.location.href = url;\r\n }\r\n\r\n onkeydown(e) {\r\n if (e.ctrlKey) {\r\n if (e.key == 'ArrowLeft' || e.key == 'ArrowRight') {\r\n let page = Math.floor(this.start / this.limit);\r\n page += (e.key == 'ArrowLeft' ? -1 : 1);\r\n if (page < 0) page = 0;\r\n else if (page > 0 && page > Math.ceil(this.total / this.limit) - 1) page = Math.ceil(this.total / this.limit) - 1;\r\n this.start = page * this.limit;\r\n this.refresh();\r\n }\r\n }\r\n }\r\n\r\n\r\n reorderColumns(column, next) {\r\n console.log('reorderColumns')\r\n this.columns.splice(this.columns.indexOf(column), 1);\r\n if (next)\r\n this.columns.splice(this.columns.indexOf(next), 0, column);\r\n else\r\n this.columns.push(column)\r\n if (this.insideView.setColumnsWidths) {\r\n this.insideView.setColumnsWidths()\r\n }\r\n }\r\n}\r\n\r\ncustomElements.define('data-view', ObjectsList);\r\n\n\n//# sourceURL=webpack://@green-code-studio/objects-list/./src/objectsList.js?");
178
178
 
179
179
  /***/ }),
180
180
 
@@ -194,7 +194,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
194
194
  \**************************/
195
195
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
196
196
 
197
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TableView: () => (/* binding */ TableView)\n/* harmony export */ });\n/* harmony import */ var _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @green-code-studio/context-menu/dist/index.mjs */ \"./node_modules/@green-code-studio/context-menu/dist/index.mjs\");\n/* harmony import */ var fast_creator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fast-creator */ \"./node_modules/fast-creator/dist/entry.js\");\n/* harmony import */ var _abstractView_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./abstractView.js */ \"./src/abstractView.js\");\n/* harmony import */ var _i18n_xml__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./i18n.xml */ \"./src/i18n.xml\");\n\r\n\r\n\r\n\r\n\r\nclass TableView extends _abstractView_js__WEBPACK_IMPORTED_MODULE_2__.AbstractView {\r\n constructor(objectsList, params) {\r\n super();\r\n this.objectsList = objectsList;\r\n this.init();\r\n window.dbgTable = this;\r\n this.params=params??{};\r\n }\r\n\r\n init() {\r\n this.head = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.head');\r\n this.append(this.head);\r\n this.refreshHeader();\r\n const bodyContainer = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.bodyContainer')\r\n this.body = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.body')\r\n bodyContainer.append(this.body)\r\n this.append(bodyContainer);\r\n this.setColumnsWidths();\r\n addEventListener('resize', this.setColumnsWidths.bind(this))\r\n addEventListener('copy', this.onCopy.bind(this));\r\n this.addEventListener('scroll', this.onScroll.bind(this));\r\n }\r\n\r\n refreshHeader() {\r\n while (this.head.firstChild) this.head.firstChild.remove();\r\n\r\n this.head.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.column.icon'))\r\n for (let column of this.objectsList.visibleColumns) {\r\n let node = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.column')\r\n this.head.append(node);\r\n node.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('span.name', {text: column.name}));\r\n if (column.sortName) {\r\n node.classList.add('ableToSort');\r\n node.dataset.sortName = column.sortName\r\n node.onclick = () => {\r\n let sortName = column.sortName || x.dataset.value;\r\n if (this.objectsList.sort && this.objectsList.sort.col === column.sortName) {\r\n this.objectsList.sort.desc = !this.objectsList.sort.desc;\r\n } else {\r\n this.objectsList.sort = {col: column.sortName, desc: false};\r\n }\r\n if (!this.objectsList.infiniteScrollEnabled) {\r\n this.objectsList.start = 0;\r\n }\r\n this.objectsList.refresh();\r\n }\r\n }\r\n }\r\n this.head.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.column.actions'))\r\n }\r\n\r\n loadData(data, start, limit, infiniteScrollEnabled) {\r\n this.refreshSortIndicators();\r\n super.loadData(data, start, limit, infiniteScrollEnabled)\r\n this.setColumnsWidths();\r\n }\r\n\r\n get rowHeight() {\r\n return parseFloat(window.getComputedStyle(this).getPropertyValue('--rowHeight') ?? 31);\r\n }\r\n\r\n generateRow(data) {\r\n let tr = this.body.querySelector(`.tr[data-row=\"${data.id}\"]`);\r\n if (!tr) {\r\n tr = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.tr');\r\n tr.draggable = true;\r\n }\r\n tr.classList.toggle('selected', this.objectsList.selected.has(data.id))\r\n this.fillRowContent(tr, data);\r\n return tr;\r\n }\r\n\r\n fillRowContent(tr, data) {\r\n tr.lastData = data;\r\n while (tr.firstChild) {\r\n tr.removeChild(tr.firstChild)\r\n }\r\n tr.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.td.icon', {className: this.objectsList.icon}));\r\n for (let column of this.objectsList.visibleColumns) {\r\n let td = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.td');\r\n tr.append(td);\r\n if (this.multiEdit && column.dataName) {\r\n tr.dataset.id = data.id;\r\n td.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('input', {\r\n data: {name: column.dataName},\r\n value: data[column.dataName],\r\n onclick: e => e.stopPropagation(),\r\n onchange: () => this.multiEditChanged(tr)\r\n }));\r\n } else {\r\n td.append(column.content?.call(column, data) || data[column.dataName] || '');\r\n }\r\n }\r\n let actionsTd = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.td.actions');\r\n tr.append(actionsTd);\r\n let actions = this.objectsList.generateActions([data], 'row');\r\n if (this.multiEdit && data.__isMultirowEdited) {\r\n actions = [\r\n {\r\n name: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_3__.t)(\"objectList.saveRow\"),\r\n icon: 'icon-save',\r\n command: () => {\r\n this.multiEditChanged(tr, true)\r\n }\r\n }\r\n ]\r\n }\r\n for (let action of actions) {\r\n let actionButton = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)(action.href ? 'a.button' : 'button', {\r\n title: action.name\r\n });\r\n actionsTd.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)(actionButton));\r\n actionButton.classList.add('action-' + (action.action ?? 'view'));\r\n\r\n if (action.href) {\r\n actionButton.href = action.href;\r\n }\r\n if (action.command) {\r\n actionButton.onclick = action.command;\r\n }\r\n if (action.icon) {\r\n actionButton.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('span', {classList: [action.icon]}));\r\n } else {\r\n actionButton.textContent = action.name;\r\n }\r\n }\r\n\r\n\r\n tr.dataset.row = data.id;\r\n tr.oncontextmenu = this.contextMenu.bind(this, tr);\r\n tr.onclick = this.trOnClick.bind(this, data);\r\n tr.ondblclick = this.trOnDblClick.bind(this, data, tr);\r\n tr.onkeydown = this.trOnKeyDown.bind(this, data, tr);\r\n tr.ondragstart = this.trOnDragStart.bind(this, data, tr);\r\n }\r\n\r\n setColumnsWidths() {\r\n const widths = this.calculateColumnsWidths();\r\n for (let tr of this.body.children) {\r\n for (let i = 0; i < widths.length; i++) {\r\n tr.children[i].style.width = widths[i] + 'px';\r\n }\r\n }\r\n let sum = 0;\r\n for (let i = 0; i < widths.length; i++) {\r\n let node = this.head.children[i];\r\n if (node) {\r\n if (i + 1 < widths.length)\r\n node.style.width = widths[i] + 1 + 'px';\r\n else\r\n node.style.width = widths[i] + 'px';\r\n node.style.left = sum + 'px';\r\n }\r\n sum += widths[i];\r\n }\r\n }\r\n\r\n calculateColumnsWidths() {\r\n let needed = [{base: 30, grow: 0}];\r\n\r\n for (let column of this.objectsList.visibleColumns) {\r\n needed.push({base: column.width || 10, grow: typeof (column.widthGrow) == \"number\" ? column.widthGrow : 1});\r\n }\r\n let actionWidth = Math.ceil(Array.from(this.querySelectorAll('.td.actions')).map(x => {\r\n if (x.lastElementChild)\r\n return x.lastElementChild.getBoundingClientRect().right - x.getBoundingClientRect().left + parseFloat(getComputedStyle(x).paddingRight);\r\n else\r\n return 0;\r\n }).reduce((a, b) => Math.max(a, b), 0));\r\n needed.push({base: actionWidth, grow: 0});\r\n let availableToGrow = this.clientWidth - needed.map(x => x.base).reduce((a, b) => a + b, 0);\r\n let sumGrow = needed.map(x => x.grow).reduce((a, b) => a + b, 0);\r\n if (this.params?.wide) {\r\n return needed.map(x => x.base + x.grow * Math.max(100, availableToGrow / sumGrow));\r\n } else {\r\n if (availableToGrow > 0 && sumGrow > 0) {\r\n return needed.map(x => x.base + x.grow / sumGrow * availableToGrow);\r\n } else {\r\n return needed.map(x => x.base);\r\n }\r\n }\r\n }\r\n\r\n refreshSortIndicators() {\r\n this.head.querySelectorAll('[data-order]').forEach(x => delete x.dataset.order);\r\n if (this.objectsList.sort)\r\n this.head.querySelectorAll(`[data-sort-name=\"${this.objectsList.sort.col}\"]`).forEach(x => x.dataset.order = this.objectsList.sort.desc ? 'desc' : 'asc');\r\n }\r\n\r\n contextMenu(tr, event) {\r\n event.stopPropagation();\r\n if (!this.objectsList.selected.has(tr.dataset.row)) {\r\n this.objectsList.selected.clear();\r\n this.objectsList.selected.add(tr.dataset.row)\r\n this.objectsList.selectedMain = tr.dataset.row;\r\n this.refreshSelectedClasses();\r\n }\r\n const rows = this.objectsList.getSelectedData();\r\n let actions = this.objectsList.generateActions(rows, 'contextMenu');\r\n let actions2=[];\r\n for (const action of actions) {\r\n actions2.push(action);\r\n if(action.href){\r\n actions2.push({...action, href:null, command:()=>window.open(action.href), name:(action.name??'')+' ('+(0,_i18n_xml__WEBPACK_IMPORTED_MODULE_3__.t)('objectList.inNewTab')+')'});\r\n }\r\n }\r\n let elements = actions2.map(action => ({\r\n text: action.name,\r\n icon: action.icon,\r\n class: action.action ? 'action-' + action.action : '',\r\n onclick: action.command || (() => this.objectsList.gotoUrl(action.href))\r\n }));\r\n elements.push({\r\n text: 'copy',\r\n icon: 'icon-copy',\r\n onclick: () => {\r\n this.forceCopy(rows);\r\n }\r\n })\r\n _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_0__.ContextMenu.openContextMenu(event, elements);\r\n }\r\n\r\n refreshSelectedClasses() {\r\n for (const tr of this.body.children) {\r\n tr.classList.toggle('selected', this.objectsList.selected.has(tr.dataset.row));\r\n tr.classList.toggle('selectedMain', this.objectsList.selectedMain == tr.dataset.row);\r\n if (this.objectsList.selectedMain == tr.dataset.row) {\r\n tr.tabIndex = 1;\r\n tr.focus();\r\n getSelection().selectAllChildren(tr)\r\n } else {\r\n tr.tabIndex = -1;\r\n }\r\n }\r\n }\r\n\r\n\r\n trOnClick(row, e) {\r\n const rowsIds = this.objectsList.currentRows.map(x => x.id);\r\n console.log('click')\r\n if (!e.ctrlKey) {\r\n this.objectsList.selected.clear();\r\n }\r\n\r\n if (e.shiftKey) {\r\n const mainIndex = rowsIds.indexOf(this.objectsList.selectedMain);\r\n const clickedIndex = rowsIds.indexOf(row.id);\r\n if (clickedIndex >= 0 && mainIndex >= 0)\r\n rowsIds.slice(Math.min(mainIndex, clickedIndex), Math.max(mainIndex, clickedIndex) + 1).forEach(x => this.objectsList.selected.add(x));\r\n } else {\r\n if (this.objectsList.selected.has(row.id))\r\n this.objectsList.selected.delete(row.id);\r\n else\r\n this.objectsList.selected.add(row.id);\r\n\r\n this.objectsList.selectedMain = row.id;\r\n }\r\n\r\n this.refreshSelectedClasses();\r\n }\r\n\r\n trOnDblClick(row, tr, e) {\r\n if (!this.objectsList.selected.has(tr.dataset.row)) {\r\n this.objectsList.selected.clear();\r\n this.objectsList.selected.add(tr.dataset.row)\r\n this.objectsList.selectedMain = tr.dataset.row;\r\n this.refreshSelectedClasses();\r\n }\r\n let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dblClick').find(x => x.main);\r\n if (action) {\r\n if (action.command) {\r\n action.command();\r\n } else if (action.href) {\r\n this.objectsList.gotoUrl(action.href)\r\n }\r\n }\r\n }\r\n\r\n selectRange(start, end) {\r\n const rowsIds = this.objectsList.currentRows.map(x => x.id);\r\n let startIndex = rowsIds.indexOf(start);\r\n let endIndex = rowsIds.indexOf(end);\r\n if (endIndex < startIndex) {\r\n let tmp = startIndex;\r\n startIndex = endIndex;\r\n endIndex = tmp;\r\n }\r\n for (let i = startIndex; i <= endIndex; i++) {\r\n this.objectsList.selected.add(rowsIds[i]);\r\n }\r\n }\r\n\r\n trOnKeyDown(row, tr, e) {\r\n console.log('trOnKeyDown')\r\n if (e.key === 'Enter') {\r\n let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'enter').find(x => x.main);\r\n if (action) {\r\n if (action.command) {\r\n action.command();\r\n } else if (action.href) {\r\n this.objectsList.gotoUrl(action.href)\r\n }\r\n }\r\n } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\r\n const rowsIds = this.objectsList.currentRows.map(x => x.id);\r\n let index = rowsIds.indexOf(this.objectsList.selectedMain);\r\n if (e.key === 'ArrowDown') {\r\n if (index < rowsIds.length) index++;\r\n else index = rowsIds.length - 1;\r\n } else {\r\n if (index > 0) index--;\r\n }\r\n const id = rowsIds[index];\r\n if (!e.ctrlKey) {\r\n this.objectsList.selected.clear();\r\n }\r\n if (e.shiftKey) {\r\n if (!this.objectsList.selectedShiftStart) {\r\n this.objectsList.selectedShiftStart = this.objectsList.selectedMain;\r\n }\r\n this.selectRange(this.objectsList.selectedShiftStart, id)\r\n } else {\r\n this.objectsList.selectedShiftStart = null;\r\n if (!e.ctrlKey) {\r\n this.objectsList.selected.add(id);\r\n }\r\n }\r\n this.objectsList.selectedMain = id;\r\n this.refreshSelectedClasses();\r\n e.preventDefault();\r\n } else if (e.key === ' ') {\r\n if (this.objectsList.selected.has(this.objectsList.selectedMain))\r\n this.objectsList.selected.delete(this.objectsList.selectedMain);\r\n else\r\n this.objectsList.selected.add(this.objectsList.selectedMain);\r\n\r\n this.refreshSelectedClasses();\r\n e.preventDefault();\r\n } else if (e.key === 'a') {\r\n if (e.ctrlKey)\r\n this.objectsList.selected.selectAll();\r\n\r\n this.refreshSelectedClasses();\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n onCopy(e) {\r\n if (this.copyForced) {\r\n this.fillDataTransfer(e.clipboardData, this.copyForced);\r\n e.preventDefault();\r\n } else if (document.querySelector(':focus')?.findParent(x => x === this)) {\r\n this.fillDataTransfer(e.clipboardData, this.objectsList.selected);\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n trOnDragStart(row, oryginalTr, e) {\r\n if (!this.objectsList.selected.has(row.id)) {\r\n this.objectsList.selected.clear()\r\n this.objectsList.selected.add(row.id)\r\n this.refreshSelectedClasses();\r\n }\r\n this.fillDataTransfer(e.dataTransfer, this.objectsList.selected);\r\n }\r\n\r\n fillDataTransfer(dataTransfer, ids) {\r\n const trs = Array.from(this.body.children).filter(tr => ids.has(tr.dataset.row));\r\n let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dataTransfer').find(x => x.main);\r\n if (action && action.href) {\r\n dataTransfer.setData('text/uri-list', new URL(action.href, document.baseURI));\r\n }\r\n if (action && action.hrefArray) {\r\n dataTransfer.setData('text/uri-list', action.hrefArray.map(x => new URL(x, document.baseURI)).map(x => x.toString()).join(\"\\r\\n#\\r\\n\"));\r\n }\r\n dataTransfer.setData('text/html', this.generateTableHtml(trs));\r\n dataTransfer.setData('text/plain', this.generateTableTextPlain(trs));\r\n\r\n }\r\n\r\n generateTableHtml(trs) {\r\n const thead = '<thead><tr>' + Array.from(this.head.querySelectorAll('.column')).map(x => '<th>' + x.innerHTML + '</th>').join('') + '</tr></thead>';\r\n const tbody = '<tbody>' + trs.map(tr => {\r\n return '<tr>' + Array.from(tr.children).slice(1, -1).map(td => {\r\n return '<td>' + td.innerHTML + '</td>';\r\n }).join('') + '</tr>';\r\n }).join('') + '</tbody>'\r\n return '<table>' + thead + tbody + '</table>';\r\n }\r\n\r\n generateTableTextPlain(trs) {\r\n const head = Array.from(this.head.querySelectorAll('.column')).map(x => x.textContent.replace(/\\r\\n/gm, ' ')).join(\"\\t\")\r\n const body = trs.map(tr => Array.from(tr.children).slice(1).map(x => x.textContent.replace(/\\r\\n/gm, ' ')).join(\"\\t\")).join(\"\\r\\n\")\r\n return head + \"\\r\\n\" + body;\r\n }\r\n\r\n calcMaxVisibleItems(height) {\r\n return Math.floor((height - this.head.clientHeight) / this.rowHeight);\r\n }\r\n\r\n forceCopy(rows) {\r\n this.copyForced = new Set(rows.map(x => x.id));\r\n document.execCommand(\"copy\");\r\n setTimeout(() => this.copyForced = null, 100);\r\n }\r\n\r\n startMultiEdit() {\r\n this.multiEdit = true;\r\n }\r\n\r\n multiEditChanged(tr, save = false) {\r\n let data = [...tr.querySelectorAll('[data-name]')].map(x => [x.dataset.name, x.value]);\r\n let dataObj = Object.fromEntries(data);\r\n this.objectsList.multiEditChanged(tr.dataset.id, dataObj, save);\r\n this.fillRowContent(tr, {...tr.lastData, ...dataObj, __isMultirowEdited: true});\r\n this.setColumnsWidths();\r\n }\r\n}\r\n\r\ncustomElements.define('table-view', TableView);\r\n\n\n//# sourceURL=webpack://@green-code-studio/objects-list/./src/tableView.js?");
197
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TableView: () => (/* binding */ TableView)\n/* harmony export */ });\n/* harmony import */ var _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @green-code-studio/context-menu/dist/index.mjs */ \"./node_modules/@green-code-studio/context-menu/dist/index.mjs\");\n/* harmony import */ var fast_creator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fast-creator */ \"./node_modules/fast-creator/dist/entry.js\");\n/* harmony import */ var _abstractView_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./abstractView.js */ \"./src/abstractView.js\");\n/* harmony import */ var _i18n_xml__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./i18n.xml */ \"./src/i18n.xml\");\n\r\n\r\n\r\n\r\n\r\nclass TableView extends _abstractView_js__WEBPACK_IMPORTED_MODULE_2__.AbstractView {\r\n constructor(objectsList, params) {\r\n super();\r\n this.objectsList = objectsList;\r\n this.init();\r\n window.dbgTable = this;\r\n this.params = params ?? {};\r\n }\r\n\r\n init() {\r\n this.head = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.head');\r\n this.append(this.head);\r\n this.refreshHeader();\r\n const bodyContainer = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.bodyContainer')\r\n this.body = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.body')\r\n bodyContainer.append(this.body)\r\n this.append(bodyContainer);\r\n this.setColumnsWidths();\r\n addEventListener('resize', this.setColumnsWidths.bind(this))\r\n addEventListener('copy', this.onCopy.bind(this));\r\n this.addEventListener('scroll', this.onScroll.bind(this));\r\n }\r\n\r\n refreshHeader() {\r\n while (this.head.firstChild) this.head.firstChild.remove();\r\n\r\n console.log('uuu')\r\n this.head.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.column.icon'))\r\n for (let column of this.objectsList.visibleColumns) {\r\n let node = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.column')\r\n node.__column = column\r\n this.head.append(node);\r\n node.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('span.name', {text: column.name}));\r\n if (column.sortName) {\r\n node.classList.add('ableToSort');\r\n node.dataset.sortName = column.sortName\r\n node.onclick = () => {\r\n let sortName = column.sortName || x.dataset.value;\r\n if (this.objectsList.sort && this.objectsList.sort.col === column.sortName) {\r\n this.objectsList.sort.desc = !this.objectsList.sort.desc;\r\n } else {\r\n this.objectsList.sort = {col: column.sortName, desc: false};\r\n }\r\n if (!this.objectsList.infiniteScrollEnabled) {\r\n this.objectsList.start = 0;\r\n }\r\n this.objectsList.refresh();\r\n }\r\n }\r\n this.initColumnMovability(node)\r\n }\r\n this.head.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.column.actions'))\r\n }\r\n\r\n initColumnMovability(node) {\r\n let startX = null;\r\n let onmove = (e) => {\r\n const movement = (e.pageX - startX);\r\n node.style.setProperty('--move-x', movement + 'px');\r\n if (movement < -node.previousElementSibling.clientWidth / 2) {\r\n if (node.previousElementSibling.__column) {\r\n startX -= node.previousElementSibling.clientWidth;\r\n const prev=node.previousElementSibling;\r\n node.parentNode.insertBefore(node, prev);\r\n this.objectsList.reorderColumns(node.__column, prev?.__column)\r\n }\r\n } else if (movement > node.nextElementSibling.clientWidth / 2) {\r\n if (node.nextElementSibling.__column) {\r\n startX += node.nextElementSibling.clientWidth;\r\n const next=node.nextElementSibling.nextElementSibling;\r\n node.parentNode.insertBefore(node, next);\r\n this.objectsList.reorderColumns(node.__column, next?.__column)\r\n }\r\n }\r\n }\r\n const onup = e => {\r\n startX = null;\r\n node.style.setProperty('--move-x', 0 + 'px');\r\n removeEventListener('mousemove', onmove);\r\n removeEventListener('mouseup', onup);\r\n this.objectsList.refresh()\r\n }\r\n node.addEventListener('mousedown', (e) => {\r\n startX = e.pageX;\r\n addEventListener('mousemove', onmove)\r\n addEventListener('mouseup', onup)\r\n })\r\n }\r\n\r\n loadData(data, start, limit, infiniteScrollEnabled) {\r\n this.refreshSortIndicators();\r\n super.loadData(data, start, limit, infiniteScrollEnabled)\r\n this.setColumnsWidths();\r\n }\r\n\r\n get rowHeight() {\r\n return parseFloat(window.getComputedStyle(this).getPropertyValue('--rowHeight') ?? 31);\r\n }\r\n\r\n generateRow(data) {\r\n let tr = this.body.querySelector(`.tr[data-row=\"${data.id}\"]`);\r\n if (!tr) {\r\n tr = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.tr');\r\n tr.draggable = true;\r\n }\r\n tr.classList.toggle('selected', this.objectsList.selected.has(data.id))\r\n this.fillRowContent(tr, data);\r\n return tr;\r\n }\r\n\r\n fillRowContent(tr, data) {\r\n tr.lastData = data;\r\n while (tr.firstChild) {\r\n tr.removeChild(tr.firstChild)\r\n }\r\n tr.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.td.icon', {className: this.objectsList.icon}));\r\n for (let column of this.objectsList.visibleColumns) {\r\n let td = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.td');\r\n tr.append(td);\r\n if (this.multiEdit && column.dataName) {\r\n tr.dataset.id = data.id;\r\n td.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('input', {\r\n data: {name: column.dataName},\r\n value: data[column.dataName],\r\n onclick: e => e.stopPropagation(),\r\n onchange: () => this.multiEditChanged(tr)\r\n }));\r\n } else {\r\n td.append(column.content?.call(column, data) || data[column.dataName] || '');\r\n }\r\n }\r\n let actionsTd = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('.td.actions');\r\n tr.append(actionsTd);\r\n let actions = this.objectsList.generateActions([data], 'row');\r\n if (this.multiEdit && data.__isMultirowEdited) {\r\n actions = [\r\n {\r\n name: (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_3__.t)(\"objectList.saveRow\"),\r\n icon: 'icon-save',\r\n command: () => {\r\n this.multiEditChanged(tr, true)\r\n }\r\n }\r\n ]\r\n }\r\n for (let action of actions) {\r\n let actionButton = (0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)(action.href ? 'a.button' : 'button', {\r\n title: action.name\r\n });\r\n actionsTd.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)(actionButton));\r\n actionButton.classList.add('action-' + (action.action ?? 'view'));\r\n\r\n if (action.href) {\r\n actionButton.href = action.href;\r\n }\r\n if (action.command) {\r\n actionButton.onclick = action.command;\r\n }\r\n if (action.icon) {\r\n actionButton.append((0,fast_creator__WEBPACK_IMPORTED_MODULE_1__.create)('span', {classList: [action.icon]}));\r\n } else {\r\n actionButton.textContent = action.name;\r\n }\r\n }\r\n\r\n\r\n tr.dataset.row = data.id;\r\n tr.oncontextmenu = this.contextMenu.bind(this, tr);\r\n tr.onclick = this.trOnClick.bind(this, data);\r\n tr.ondblclick = this.trOnDblClick.bind(this, data, tr);\r\n tr.onkeydown = this.trOnKeyDown.bind(this, data, tr);\r\n tr.ondragstart = this.trOnDragStart.bind(this, data, tr);\r\n }\r\n\r\n setColumnsWidths() {\r\n const widths = this.calculateColumnsWidths();\r\n for (let tr of this.body.children) {\r\n for (let i = 0; i < widths.length; i++) {\r\n tr.children[i].style.width = widths[i] + 'px';\r\n }\r\n }\r\n let sum = 0;\r\n for (let i = 0; i < widths.length; i++) {\r\n let node = this.head.children[i];\r\n if (node) {\r\n if (i + 1 < widths.length)\r\n node.style.width = widths[i] + 1 + 'px';\r\n else\r\n node.style.width = widths[i] + 'px';\r\n node.style.left = sum + 'px';\r\n }\r\n sum += widths[i];\r\n }\r\n }\r\n\r\n calculateColumnsWidths() {\r\n let needed = [{base: 30, grow: 0}];\r\n\r\n for (let column of this.objectsList.visibleColumns) {\r\n needed.push({base: column.width || 10, grow: typeof (column.widthGrow) == \"number\" ? column.widthGrow : 1});\r\n }\r\n let actionWidth = Math.ceil(Array.from(this.querySelectorAll('.td.actions')).map(x => {\r\n if (x.lastElementChild)\r\n return x.lastElementChild.getBoundingClientRect().right - x.getBoundingClientRect().left + parseFloat(getComputedStyle(x).paddingRight);\r\n else\r\n return 0;\r\n }).reduce((a, b) => Math.max(a, b), 0));\r\n needed.push({base: actionWidth, grow: 0});\r\n let availableToGrow = this.clientWidth - needed.map(x => x.base).reduce((a, b) => a + b, 0);\r\n let sumGrow = needed.map(x => x.grow).reduce((a, b) => a + b, 0);\r\n if (this.params?.wide) {\r\n return needed.map(x => x.base + x.grow * Math.max(100, availableToGrow / sumGrow));\r\n } else {\r\n if (availableToGrow > 0 && sumGrow > 0) {\r\n return needed.map(x => x.base + x.grow / sumGrow * availableToGrow);\r\n } else {\r\n return needed.map(x => x.base);\r\n }\r\n }\r\n }\r\n\r\n refreshSortIndicators() {\r\n this.head.querySelectorAll('[data-order]').forEach(x => delete x.dataset.order);\r\n if (this.objectsList.sort)\r\n this.head.querySelectorAll(`[data-sort-name=\"${this.objectsList.sort.col}\"]`).forEach(x => x.dataset.order = this.objectsList.sort.desc ? 'desc' : 'asc');\r\n }\r\n\r\n contextMenu(tr, event) {\r\n event.stopPropagation();\r\n if (!this.objectsList.selected.has(tr.dataset.row)) {\r\n this.objectsList.selected.clear();\r\n this.objectsList.selected.add(tr.dataset.row)\r\n this.objectsList.selectedMain = tr.dataset.row;\r\n this.refreshSelectedClasses();\r\n }\r\n const rows = this.objectsList.getSelectedData();\r\n let actions = this.objectsList.generateActions(rows, 'contextMenu');\r\n let actions2 = [];\r\n for (const action of actions) {\r\n actions2.push(action);\r\n if (action.href) {\r\n actions2.push({\r\n ...action,\r\n href: null,\r\n command: () => window.open(action.href),\r\n name: (action.name ?? '') + ' (' + (0,_i18n_xml__WEBPACK_IMPORTED_MODULE_3__.t)('objectList.inNewTab') + ')'\r\n });\r\n }\r\n }\r\n let elements = actions2.map(action => ({\r\n text: action.name,\r\n icon: action.icon,\r\n class: action.action ? 'action-' + action.action : '',\r\n onclick: action.command || (() => this.objectsList.gotoUrl(action.href))\r\n }));\r\n elements.push({\r\n text: 'copy',\r\n icon: 'icon-copy',\r\n onclick: () => {\r\n this.forceCopy(rows);\r\n }\r\n })\r\n _green_code_studio_context_menu_dist_index_mjs__WEBPACK_IMPORTED_MODULE_0__.ContextMenu.openContextMenu(event, elements);\r\n }\r\n\r\n refreshSelectedClasses() {\r\n for (const tr of this.body.children) {\r\n tr.classList.toggle('selected', this.objectsList.selected.has(tr.dataset.row));\r\n tr.classList.toggle('selectedMain', this.objectsList.selectedMain == tr.dataset.row);\r\n if (this.objectsList.selectedMain == tr.dataset.row) {\r\n tr.tabIndex = 1;\r\n tr.focus();\r\n getSelection().selectAllChildren(tr)\r\n } else {\r\n tr.tabIndex = -1;\r\n }\r\n }\r\n }\r\n\r\n\r\n trOnClick(row, e) {\r\n const rowsIds = this.objectsList.currentRows.map(x => x.id);\r\n console.log('click')\r\n if (!e.ctrlKey) {\r\n this.objectsList.selected.clear();\r\n }\r\n\r\n if (e.shiftKey) {\r\n const mainIndex = rowsIds.indexOf(this.objectsList.selectedMain);\r\n const clickedIndex = rowsIds.indexOf(row.id);\r\n if (clickedIndex >= 0 && mainIndex >= 0)\r\n rowsIds.slice(Math.min(mainIndex, clickedIndex), Math.max(mainIndex, clickedIndex) + 1).forEach(x => this.objectsList.selected.add(x));\r\n } else {\r\n if (this.objectsList.selected.has(row.id))\r\n this.objectsList.selected.delete(row.id);\r\n else\r\n this.objectsList.selected.add(row.id);\r\n\r\n this.objectsList.selectedMain = row.id;\r\n }\r\n\r\n this.refreshSelectedClasses();\r\n }\r\n\r\n trOnDblClick(row, tr, e) {\r\n if (!this.objectsList.selected.has(tr.dataset.row)) {\r\n this.objectsList.selected.clear();\r\n this.objectsList.selected.add(tr.dataset.row)\r\n this.objectsList.selectedMain = tr.dataset.row;\r\n this.refreshSelectedClasses();\r\n }\r\n let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dblClick').find(x => x.main);\r\n if (action) {\r\n if (action.command) {\r\n action.command();\r\n } else if (action.href) {\r\n this.objectsList.gotoUrl(action.href)\r\n }\r\n }\r\n }\r\n\r\n selectRange(start, end) {\r\n const rowsIds = this.objectsList.currentRows.map(x => x.id);\r\n let startIndex = rowsIds.indexOf(start);\r\n let endIndex = rowsIds.indexOf(end);\r\n if (endIndex < startIndex) {\r\n let tmp = startIndex;\r\n startIndex = endIndex;\r\n endIndex = tmp;\r\n }\r\n for (let i = startIndex; i <= endIndex; i++) {\r\n this.objectsList.selected.add(rowsIds[i]);\r\n }\r\n }\r\n\r\n trOnKeyDown(row, tr, e) {\r\n console.log('trOnKeyDown')\r\n if (e.key === 'Enter') {\r\n let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'enter').find(x => x.main);\r\n if (action) {\r\n if (action.command) {\r\n action.command();\r\n } else if (action.href) {\r\n this.objectsList.gotoUrl(action.href)\r\n }\r\n }\r\n } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\r\n const rowsIds = this.objectsList.currentRows.map(x => x.id);\r\n let index = rowsIds.indexOf(this.objectsList.selectedMain);\r\n if (e.key === 'ArrowDown') {\r\n if (index < rowsIds.length) index++;\r\n else index = rowsIds.length - 1;\r\n } else {\r\n if (index > 0) index--;\r\n }\r\n const id = rowsIds[index];\r\n if (!e.ctrlKey) {\r\n this.objectsList.selected.clear();\r\n }\r\n if (e.shiftKey) {\r\n if (!this.objectsList.selectedShiftStart) {\r\n this.objectsList.selectedShiftStart = this.objectsList.selectedMain;\r\n }\r\n this.selectRange(this.objectsList.selectedShiftStart, id)\r\n } else {\r\n this.objectsList.selectedShiftStart = null;\r\n if (!e.ctrlKey) {\r\n this.objectsList.selected.add(id);\r\n }\r\n }\r\n this.objectsList.selectedMain = id;\r\n this.refreshSelectedClasses();\r\n e.preventDefault();\r\n } else if (e.key === ' ') {\r\n if (this.objectsList.selected.has(this.objectsList.selectedMain))\r\n this.objectsList.selected.delete(this.objectsList.selectedMain);\r\n else\r\n this.objectsList.selected.add(this.objectsList.selectedMain);\r\n\r\n this.refreshSelectedClasses();\r\n e.preventDefault();\r\n } else if (e.key === 'a') {\r\n if (e.ctrlKey)\r\n this.objectsList.selected.selectAll();\r\n\r\n this.refreshSelectedClasses();\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n onCopy(e) {\r\n if (this.copyForced) {\r\n this.fillDataTransfer(e.clipboardData, this.copyForced);\r\n e.preventDefault();\r\n } else if (document.querySelector(':focus')?.findParent(x => x === this)) {\r\n this.fillDataTransfer(e.clipboardData, this.objectsList.selected);\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n trOnDragStart(row, oryginalTr, e) {\r\n if (!this.objectsList.selected.has(row.id)) {\r\n this.objectsList.selected.clear()\r\n this.objectsList.selected.add(row.id)\r\n this.refreshSelectedClasses();\r\n }\r\n this.fillDataTransfer(e.dataTransfer, this.objectsList.selected);\r\n }\r\n\r\n fillDataTransfer(dataTransfer, ids) {\r\n const trs = Array.from(this.body.children).filter(tr => ids.has(tr.dataset.row));\r\n let action = this.objectsList.generateActions(this.objectsList.getSelectedData(), 'dataTransfer').find(x => x.main);\r\n if (action && action.href) {\r\n dataTransfer.setData('text/uri-list', new URL(action.href, document.baseURI));\r\n }\r\n if (action && action.hrefArray) {\r\n dataTransfer.setData('text/uri-list', action.hrefArray.map(x => new URL(x, document.baseURI)).map(x => x.toString()).join(\"\\r\\n#\\r\\n\"));\r\n }\r\n dataTransfer.setData('text/html', this.generateTableHtml(trs));\r\n dataTransfer.setData('text/plain', this.generateTableTextPlain(trs));\r\n\r\n }\r\n\r\n generateTableHtml(trs) {\r\n const thead = '<thead><tr>' + Array.from(this.head.querySelectorAll('.column')).map(x => '<th>' + x.innerHTML + '</th>').join('') + '</tr></thead>';\r\n const tbody = '<tbody>' + trs.map(tr => {\r\n return '<tr>' + Array.from(tr.children).slice(1, -1).map(td => {\r\n return '<td>' + td.innerHTML + '</td>';\r\n }).join('') + '</tr>';\r\n }).join('') + '</tbody>'\r\n return '<table>' + thead + tbody + '</table>';\r\n }\r\n\r\n generateTableTextPlain(trs) {\r\n const head = Array.from(this.head.querySelectorAll('.column')).map(x => x.textContent.replace(/\\r\\n/gm, ' ')).join(\"\\t\")\r\n const body = trs.map(tr => Array.from(tr.children).slice(1).map(x => x.textContent.replace(/\\r\\n/gm, ' ')).join(\"\\t\")).join(\"\\r\\n\")\r\n return head + \"\\r\\n\" + body;\r\n }\r\n\r\n calcMaxVisibleItems(height) {\r\n return Math.floor((height - this.head.clientHeight) / this.rowHeight);\r\n }\r\n\r\n forceCopy(rows) {\r\n this.copyForced = new Set(rows.map(x => x.id));\r\n document.execCommand(\"copy\");\r\n setTimeout(() => this.copyForced = null, 100);\r\n }\r\n\r\n startMultiEdit() {\r\n this.multiEdit = true;\r\n }\r\n\r\n multiEditChanged(tr, save = false) {\r\n let data = [...tr.querySelectorAll('[data-name]')].map(x => [x.dataset.name, x.value]);\r\n let dataObj = Object.fromEntries(data);\r\n this.objectsList.multiEditChanged(tr.dataset.id, dataObj, save);\r\n this.fillRowContent(tr, {...tr.lastData, ...dataObj, __isMultirowEdited: true});\r\n this.setColumnsWidths();\r\n }\r\n}\r\n\r\ncustomElements.define('table-view', TableView);\r\n\n\n//# sourceURL=webpack://@green-code-studio/objects-list/./src/tableView.js?");
198
198
 
199
199
  /***/ }),
200
200
 
package/dist/style.mjs CHANGED
@@ -14,7 +14,7 @@
14
14
  \************************************/
15
15
  /***/ ((module, __webpack_exports__, __webpack_require__) => {
16
16
 
17
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.contextMenu {\n position: fixed;\n z-index: 1000;\n margin: 0;\n padding: 0;\n max-width: 100vh;\n min-width: 200px;\n user-select: none;\n background: var(--background);\n}\n.contextMenu li, .contextMenu a {\n display: flex;\n cursor: pointer;\n margin: 0;\n white-space: nowrap;\n align-items: center;\n}\n.contextMenu li .icon, .contextMenu a .icon {\n display: inline-block;\n flex: 0 0 50px;\n text-align: center;\n font-size: 1.2em;\n line-height: 1em;\n vertical-align: middle;\n}\n.contextMenu li .iconPlaceholder, .contextMenu a .iconPlaceholder {\n display: inline-block;\n width: 50px;\n}\n.contextMenu li .content, .contextMenu a .content {\n flex: 1 1 auto;\n display: inline-block;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 15px 10px;\n line-height: 1em;\n vertical-align: middle;\n}\n\ndata-view {\n border: 1px solid var(--second);\n display: flex;\n flex-direction: column;\n height: calc(100vh - 200px);\n user-select: none;\n}\ndata-view table-view {\n display: block;\n flex-grow: 1;\n overflow: auto;\n --rowHeight: 41px;\n}\ndata-view table-view .head {\n position: sticky;\n top: 0;\n z-index: 1;\n height: 19px;\n background: var(--second);\n}\ndata-view table-view .head .column {\n background: var(--second);\n color: var(--textSecondColor);\n cursor: default;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 700;\n position: absolute;\n padding: 0 10px;\n box-sizing: border-box;\n height: 19px;\n}\ndata-view table-view .head .column.ableToSort {\n cursor: pointer;\n}\ndata-view table-view .head .column.ableToSort::before {\n transform: scaleY(0);\n transition: all 300ms ease-out;\n position: absolute;\n right: 0;\n}\ndata-view table-view .head .column.ableToSort[data-order=asc]::before {\n transform: scaleY(1);\n}\ndata-view table-view .head .column.ableToSort[data-order=desc]::before {\n transform: scaleY(-1);\n}\ndata-view table-view .head .column.ableToSort .tableCopy {\n display: none;\n}\ndata-view table-view .body {\n position: relative;\n}\ndata-view table-view .body .tr {\n display: flex;\n position: absolute;\n transition: top 300ms ease, background 100ms;\n table-layout: fixed;\n flex-direction: row;\n animation: data-view-appear 200ms;\n}\n@keyframes data-view-appear {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\ndata-view table-view .body .tr.selectedMain, data-view table-view .body .tr:focus {\n outline: 2px black dashed;\n outline-offset: -2px;\n}\ndata-view table-view .body .tr .td {\n padding: 5px 10px;\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n flex: 0 0 auto;\n box-sizing: border-box;\n height: var(--rowHeight);\n}\ndata-view table-view .body .tr .td button, data-view table-view .body .tr .td .button {\n font-size: 16px;\n margin-left: 2px;\n}\ndata-view table-view .body .tr .td.actions {\n display: flex;\n}\ndata-view list-view {\n display: block;\n flex-grow: 1;\n overflow: auto;\n}\ndata-view list-view .body {\n position: relative;\n}\ndata-view list-view .body .tr {\n display: grid;\n position: absolute;\n transition: top 300ms ease, background 100ms;\n animation: data-view-appear 200ms;\n grid-template-columns: max-content 1fr max-content;\n width: 100%;\n padding: 10px 0;\n}\ndata-view list-view .body .tr.selectedMain, data-view list-view .body .tr:focus {\n outline: 2px black dashed;\n outline-offset: -2px;\n}\ndata-view list-view .body .tr button, data-view list-view .body .tr .button {\n font-size: 16px;\n margin-left: 2px;\n}\ndata-view list-view .body .tr .icon {\n grid-column: 1;\n grid-row: 1/4;\n font-size: 40px;\n line-height: 63px;\n}\ndata-view list-view .body .tr .keyValue {\n grid-column: 2/4;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n line-height: 21px;\n}\ndata-view list-view .body .tr .keyValue:nth-child(2), data-view list-view .body .tr .keyValue:nth-child(3) {\n grid-column: 2;\n}\ndata-view list-view .body .tr .actions {\n grid-column: 3;\n grid-row: 1/3;\n}\ndata-view .foot {\n border-top: 1px solid var(--second);\n display: flex;\n justify-content: space-between;\n}\n@media (max-width: 600px) {\n data-view .foot form input {\n width: 40px;\n }\n data-view .foot form input:focus {\n width: 200px;\n margin-left: -160px;\n }\n}\ndata-view pagination-buttons {\n flex: 1 1;\n display: flex;\n justify-content: center;\n}\ndata-view.infiniteScrollEnabled table-view .body, data-view.infiniteScrollEnabled list-view .body {\n height: var(--height);\n}\ndata-view.infiniteScrollEnabled pagination-buttons {\n display: none;\n}\n\npagination-buttons button.active {\n background: var(--main);\n}`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://@green-code-studio/objects-list/./src/style/objectsList.scss?");
17
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.contextMenu {\n position: fixed;\n z-index: 1000;\n margin: 0;\n padding: 0;\n max-width: 100vh;\n min-width: 200px;\n user-select: none;\n background: var(--background);\n}\n.contextMenu li, .contextMenu a {\n display: flex;\n cursor: pointer;\n margin: 0;\n white-space: nowrap;\n align-items: center;\n}\n.contextMenu li .icon, .contextMenu a .icon {\n display: inline-block;\n flex: 0 0 50px;\n text-align: center;\n font-size: 1.2em;\n line-height: 1em;\n vertical-align: middle;\n}\n.contextMenu li .iconPlaceholder, .contextMenu a .iconPlaceholder {\n display: inline-block;\n width: 50px;\n}\n.contextMenu li .content, .contextMenu a .content {\n flex: 1 1 auto;\n display: inline-block;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 15px 10px;\n line-height: 1em;\n vertical-align: middle;\n}\n\ndata-view {\n border: 1px solid var(--second);\n display: flex;\n flex-direction: column;\n height: calc(100vh - 200px);\n user-select: none;\n}\ndata-view table-view {\n display: block;\n flex-grow: 1;\n overflow: auto;\n --rowHeight: 41px;\n}\ndata-view table-view .head {\n position: sticky;\n top: 0;\n z-index: 1;\n height: 19px;\n background: var(--second);\n}\ndata-view table-view .head .column {\n background: var(--second);\n color: var(--textSecondColor);\n cursor: default;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-weight: 700;\n position: absolute;\n padding: 0 10px;\n box-sizing: border-box;\n height: 19px;\n transform: translateX(var(--move-x));\n}\ndata-view table-view .head .column.ableToSort {\n cursor: pointer;\n}\ndata-view table-view .head .column.ableToSort::before {\n transform: scaleY(0);\n transition: all 300ms ease-out;\n position: absolute;\n right: 0;\n}\ndata-view table-view .head .column.ableToSort[data-order=asc]::before {\n transform: scaleY(1);\n}\ndata-view table-view .head .column.ableToSort[data-order=desc]::before {\n transform: scaleY(-1);\n}\ndata-view table-view .head .column.ableToSort .tableCopy {\n display: none;\n}\ndata-view table-view .body {\n position: relative;\n}\ndata-view table-view .body .tr {\n display: flex;\n position: absolute;\n transition: top 300ms ease, background 100ms;\n table-layout: fixed;\n flex-direction: row;\n animation: data-view-appear 200ms;\n}\n@keyframes data-view-appear {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\ndata-view table-view .body .tr.selectedMain, data-view table-view .body .tr:focus {\n outline: 2px black dashed;\n outline-offset: -2px;\n}\ndata-view table-view .body .tr .td {\n padding: 5px 10px;\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n flex: 0 0 auto;\n box-sizing: border-box;\n height: var(--rowHeight);\n}\ndata-view table-view .body .tr .td button, data-view table-view .body .tr .td .button {\n font-size: 16px;\n margin-left: 2px;\n}\ndata-view table-view .body .tr .td.actions {\n display: flex;\n}\ndata-view list-view {\n display: block;\n flex-grow: 1;\n overflow: auto;\n}\ndata-view list-view .body {\n position: relative;\n}\ndata-view list-view .body .tr {\n display: grid;\n position: absolute;\n transition: top 300ms ease, background 100ms;\n animation: data-view-appear 200ms;\n grid-template-columns: max-content 1fr max-content;\n width: 100%;\n padding: 10px 0;\n}\ndata-view list-view .body .tr.selectedMain, data-view list-view .body .tr:focus {\n outline: 2px black dashed;\n outline-offset: -2px;\n}\ndata-view list-view .body .tr button, data-view list-view .body .tr .button {\n font-size: 16px;\n margin-left: 2px;\n}\ndata-view list-view .body .tr .icon {\n grid-column: 1;\n grid-row: 1/4;\n font-size: 40px;\n line-height: 63px;\n}\ndata-view list-view .body .tr .keyValue {\n grid-column: 2/4;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n line-height: 21px;\n}\ndata-view list-view .body .tr .keyValue:nth-child(2), data-view list-view .body .tr .keyValue:nth-child(3) {\n grid-column: 2;\n}\ndata-view list-view .body .tr .actions {\n grid-column: 3;\n grid-row: 1/3;\n}\ndata-view .foot {\n border-top: 1px solid var(--second);\n display: flex;\n justify-content: space-between;\n}\n@media (max-width: 600px) {\n data-view .foot form input {\n width: 40px;\n }\n data-view .foot form input:focus {\n width: 200px;\n margin-left: -160px;\n }\n}\ndata-view pagination-buttons {\n flex: 1 1;\n display: flex;\n justify-content: center;\n}\ndata-view.infiniteScrollEnabled table-view .body, data-view.infiniteScrollEnabled list-view .body {\n height: var(--height);\n}\ndata-view.infiniteScrollEnabled pagination-buttons {\n display: none;\n}\n\npagination-buttons button.active {\n background: var(--main);\n}`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://@green-code-studio/objects-list/./src/style/objectsList.scss?");
18
18
 
19
19
  /***/ }),
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@green-code-studio/objects-list",
3
- "version": "1.5.3",
3
+ "version": "1.6.0",
4
4
  "main": "src/index.js",
5
5
  "author": "Mateusz Krawczyk",
6
6
  "license": "MIT",
@@ -53,7 +53,7 @@ export class ObjectsList extends HTMLElement {
53
53
  if (!this.insideView || !(this.insideView instanceof this.insideViewClass))
54
54
  this.initInsideView();
55
55
  else if (this.insideView.refreshHeader) {
56
- this.insideView.params=this.insideViewParams
56
+ this.insideView.params = this.insideViewParams
57
57
  this.insideView.refreshHeader()
58
58
  }
59
59
 
@@ -123,7 +123,7 @@ export class ObjectsList extends HTMLElement {
123
123
  }
124
124
 
125
125
  if (query.get('insideView') || this.insideViewName) {
126
- if(query.get('insideView') !=this.insideViewName){
126
+ if (query.get('insideView') != this.insideViewName) {
127
127
  query.set('insideView', this.insideViewName);
128
128
  changed = true;
129
129
  }
@@ -134,18 +134,20 @@ export class ObjectsList extends HTMLElement {
134
134
  history.pushState(null, '', url.toString());
135
135
  }
136
136
  }
137
- get insideViewName(){
138
- if(this.insideViewClass == TableView){
139
- if(this.insideViewParams?.wide)
137
+
138
+ get insideViewName() {
139
+ if (this.insideViewClass == TableView) {
140
+ if (this.insideViewParams?.wide)
140
141
  return 'tableWideView';
141
142
  else
142
143
  return 'tableView'
143
- }else{
144
+ } else {
144
145
  return 'listView'
145
146
  }
146
147
  }
147
- set insideViewName(value){
148
- if(this.insideViewName == value)return;
148
+
149
+ set insideViewName(value) {
150
+ if (this.insideViewName == value) return;
149
151
  if (value == 'tableView') {
150
152
  this.insideViewClass = TableView
151
153
  this.insideViewParams = {wide: false}
@@ -173,7 +175,7 @@ export class ObjectsList extends HTMLElement {
173
175
  if (query.get('columnFilters')) {
174
176
  this.columnFilters = new Map(JSON.parse(query.get('columnFilters')));
175
177
  }
176
- if(query.get('insideView')){
178
+ if (query.get('insideView')) {
177
179
  this.insideViewName = query.get('insideView');
178
180
  }
179
181
  }
@@ -320,12 +322,25 @@ export class ObjectsList extends HTMLElement {
320
322
  let page = Math.floor(this.start / this.limit);
321
323
  page += (e.key == 'ArrowLeft' ? -1 : 1);
322
324
  if (page < 0) page = 0;
323
- else if (page>0 && page > Math.ceil(this.total / this.limit)-1) page = Math.ceil(this.total / this.limit)-1;
325
+ else if (page > 0 && page > Math.ceil(this.total / this.limit) - 1) page = Math.ceil(this.total / this.limit) - 1;
324
326
  this.start = page * this.limit;
325
327
  this.refresh();
326
328
  }
327
329
  }
328
330
  }
331
+
332
+
333
+ reorderColumns(column, next) {
334
+ console.log('reorderColumns')
335
+ this.columns.splice(this.columns.indexOf(column), 1);
336
+ if (next)
337
+ this.columns.splice(this.columns.indexOf(next), 0, column);
338
+ else
339
+ this.columns.push(column)
340
+ if (this.insideView.setColumnsWidths) {
341
+ this.insideView.setColumnsWidths()
342
+ }
343
+ }
329
344
  }
330
345
 
331
346
  customElements.define('data-view', ObjectsList);
@@ -37,6 +37,7 @@ data-view {
37
37
  padding: 0 10px;
38
38
  box-sizing: border-box;
39
39
  height: 19px;
40
+ transform: translateX(var(--move-x));
40
41
 
41
42
  &.ableToSort {
42
43
  //@extend .icon;
package/src/tableView.js CHANGED
@@ -9,7 +9,7 @@ export class TableView extends AbstractView {
9
9
  this.objectsList = objectsList;
10
10
  this.init();
11
11
  window.dbgTable = this;
12
- this.params=params??{};
12
+ this.params = params ?? {};
13
13
  }
14
14
 
15
15
  init() {
@@ -29,9 +29,11 @@ export class TableView extends AbstractView {
29
29
  refreshHeader() {
30
30
  while (this.head.firstChild) this.head.firstChild.remove();
31
31
 
32
+ console.log('uuu')
32
33
  this.head.append(create('.column.icon'))
33
34
  for (let column of this.objectsList.visibleColumns) {
34
35
  let node = create('.column')
36
+ node.__column = column
35
37
  this.head.append(node);
36
38
  node.append(create('span.name', {text: column.name}));
37
39
  if (column.sortName) {
@@ -50,10 +52,46 @@ export class TableView extends AbstractView {
50
52
  this.objectsList.refresh();
51
53
  }
52
54
  }
55
+ this.initColumnMovability(node)
53
56
  }
54
57
  this.head.append(create('.column.actions'))
55
58
  }
56
59
 
60
+ initColumnMovability(node) {
61
+ let startX = null;
62
+ let onmove = (e) => {
63
+ const movement = (e.pageX - startX);
64
+ node.style.setProperty('--move-x', movement + 'px');
65
+ if (movement < -node.previousElementSibling.clientWidth / 2) {
66
+ if (node.previousElementSibling.__column) {
67
+ startX -= node.previousElementSibling.clientWidth;
68
+ const prev=node.previousElementSibling;
69
+ node.parentNode.insertBefore(node, prev);
70
+ this.objectsList.reorderColumns(node.__column, prev?.__column)
71
+ }
72
+ } else if (movement > node.nextElementSibling.clientWidth / 2) {
73
+ if (node.nextElementSibling.__column) {
74
+ startX += node.nextElementSibling.clientWidth;
75
+ const next=node.nextElementSibling.nextElementSibling;
76
+ node.parentNode.insertBefore(node, next);
77
+ this.objectsList.reorderColumns(node.__column, next?.__column)
78
+ }
79
+ }
80
+ }
81
+ const onup = e => {
82
+ startX = null;
83
+ node.style.setProperty('--move-x', 0 + 'px');
84
+ removeEventListener('mousemove', onmove);
85
+ removeEventListener('mouseup', onup);
86
+ this.objectsList.refresh()
87
+ }
88
+ node.addEventListener('mousedown', (e) => {
89
+ startX = e.pageX;
90
+ addEventListener('mousemove', onmove)
91
+ addEventListener('mouseup', onup)
92
+ })
93
+ }
94
+
57
95
  loadData(data, start, limit, infiniteScrollEnabled) {
58
96
  this.refreshSortIndicators();
59
97
  super.loadData(data, start, limit, infiniteScrollEnabled)
@@ -202,11 +240,16 @@ export class TableView extends AbstractView {
202
240
  }
203
241
  const rows = this.objectsList.getSelectedData();
204
242
  let actions = this.objectsList.generateActions(rows, 'contextMenu');
205
- let actions2=[];
243
+ let actions2 = [];
206
244
  for (const action of actions) {
207
245
  actions2.push(action);
208
- if(action.href){
209
- actions2.push({...action, href:null, command:()=>window.open(action.href), name:(action.name??'')+' ('+t('objectList.inNewTab')+')'});
246
+ if (action.href) {
247
+ actions2.push({
248
+ ...action,
249
+ href: null,
250
+ command: () => window.open(action.href),
251
+ name: (action.name ?? '') + ' (' + t('objectList.inNewTab') + ')'
252
+ });
210
253
  }
211
254
  }
212
255
  let elements = actions2.map(action => ({