mirror of
https://github.com/devcode-it/openstamanager.git
synced 2025-06-05 22:09:38 +02:00
feat: ✨ Aggiunto ordinamento nella tabella
This commit is contained in:
4
.idea/inspectionProfiles/Project_Default.xml
generated
4
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -99,7 +99,7 @@
|
|||||||
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="myValues">
|
<option name="myValues">
|
||||||
<value>
|
<value>
|
||||||
<list size="22">
|
<list size="24">
|
||||||
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
||||||
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
||||||
<item index="2" class="java.lang.String" itemvalue="comment" />
|
<item index="2" class="java.lang.String" itemvalue="comment" />
|
||||||
@@ -122,6 +122,8 @@
|
|||||||
<item index="19" class="java.lang.String" itemvalue="text-area" />
|
<item index="19" class="java.lang.String" itemvalue="text-area" />
|
||||||
<item index="20" class="java.lang.String" itemvalue="mwc-select" />
|
<item index="20" class="java.lang.String" itemvalue="mwc-select" />
|
||||||
<item index="21" class="java.lang.String" itemvalue="mwc-checkbox" />
|
<item index="21" class="java.lang.String" itemvalue="mwc-checkbox" />
|
||||||
|
<item index="22" class="java.lang.String" itemvalue="mwc-linear-progress" />
|
||||||
|
<item index="23" class="java.lang.String" itemvalue="mwc-icon-button-toggle" />
|
||||||
</list>
|
</list>
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
"@material/mwc-fab": "^0.25.3",
|
"@material/mwc-fab": "^0.25.3",
|
||||||
"@material/mwc-formfield": "^0.25.3",
|
"@material/mwc-formfield": "^0.25.3",
|
||||||
"@material/mwc-icon-button": "^0.25.3",
|
"@material/mwc-icon-button": "^0.25.3",
|
||||||
|
"@material/mwc-icon-button-toggle": "^0.25.3",
|
||||||
"@material/mwc-linear-progress": "^0.25.3",
|
"@material/mwc-linear-progress": "^0.25.3",
|
||||||
"@material/mwc-list": "^0.25.3",
|
"@material/mwc-list": "^0.25.3",
|
||||||
"@material/mwc-menu": "^0.25.3",
|
"@material/mwc-menu": "^0.25.3",
|
||||||
|
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -29,6 +29,7 @@ specifiers:
|
|||||||
'@material/mwc-fab': ^0.25.3
|
'@material/mwc-fab': ^0.25.3
|
||||||
'@material/mwc-formfield': ^0.25.3
|
'@material/mwc-formfield': ^0.25.3
|
||||||
'@material/mwc-icon-button': ^0.25.3
|
'@material/mwc-icon-button': ^0.25.3
|
||||||
|
'@material/mwc-icon-button-toggle': ^0.25.3
|
||||||
'@material/mwc-linear-progress': ^0.25.3
|
'@material/mwc-linear-progress': ^0.25.3
|
||||||
'@material/mwc-list': ^0.25.3
|
'@material/mwc-list': ^0.25.3
|
||||||
'@material/mwc-menu': ^0.25.3
|
'@material/mwc-menu': ^0.25.3
|
||||||
@@ -109,6 +110,7 @@ dependencies:
|
|||||||
'@material/mwc-fab': 0.25.3
|
'@material/mwc-fab': 0.25.3
|
||||||
'@material/mwc-formfield': 0.25.3
|
'@material/mwc-formfield': 0.25.3
|
||||||
'@material/mwc-icon-button': 0.25.3
|
'@material/mwc-icon-button': 0.25.3
|
||||||
|
'@material/mwc-icon-button-toggle': 0.25.3
|
||||||
'@material/mwc-linear-progress': 0.25.3
|
'@material/mwc-linear-progress': 0.25.3
|
||||||
'@material/mwc-list': 0.25.3
|
'@material/mwc-list': 0.25.3
|
||||||
'@material/mwc-menu': 0.25.3
|
'@material/mwc-menu': 0.25.3
|
||||||
@@ -2122,6 +2124,16 @@ packages:
|
|||||||
tslib: 2.3.1
|
tslib: 2.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@material/mwc-icon-button-toggle/0.25.3:
|
||||||
|
resolution: {integrity: sha512-H3eMHHZWyqO2Dd3FXiDOArmegUBpXB3vatZLPDHVFKABdZlt0M4qusgvV7IIo53urLqqcVo6u8FMjtv9VGnXpQ==}
|
||||||
|
dependencies:
|
||||||
|
'@material/mwc-base': 0.25.3
|
||||||
|
'@material/mwc-icon-button': 0.25.3
|
||||||
|
'@material/mwc-ripple': 0.25.3
|
||||||
|
lit: 2.0.2
|
||||||
|
tslib: 2.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@material/mwc-icon-button/0.25.3:
|
/@material/mwc-icon-button/0.25.3:
|
||||||
resolution: {integrity: sha512-FexkMpK3ZSHh7NF+PIqvVhvAbBOgFDYPck/lqnxIDC3VGJ0rjD/1MqevDy2fY6IcHGlc8Ai7VuYbdQ6Cvw8WcQ==}
|
resolution: {integrity: sha512-FexkMpK3ZSHh7NF+PIqvVhvAbBOgFDYPck/lqnxIDC3VGJ0rjD/1MqevDy2fY6IcHGlc8Ai7VuYbdQ6Cvw8WcQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@@ -2,6 +2,7 @@ import '@material/mwc-linear-progress';
|
|||||||
import '@material/mwc-list/mwc-list-item';
|
import '@material/mwc-list/mwc-list-item';
|
||||||
import '@material/mwc-select';
|
import '@material/mwc-select';
|
||||||
|
|
||||||
|
import {type Cash} from 'cash-dom/dist/cash';
|
||||||
import {
|
import {
|
||||||
type Children,
|
type Children,
|
||||||
type Vnode
|
type Vnode
|
||||||
@@ -114,4 +115,74 @@ export default class DataTable extends Component {
|
|||||||
|
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oncreate(vnode) {
|
||||||
|
super.oncreate(vnode);
|
||||||
|
|
||||||
|
$(this.element).find('thead th[sortable], thead th[sortable] mwc-icon-button-toggle').on('click', this.onColumnClicked.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
showProgress() {
|
||||||
|
$(this.element).find('.mdc-data-table__progress-indicator mwc-linear-progress').get(0).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
hideProgress() {
|
||||||
|
$(this.element).find('.mdc-data-table__progress-indicator mwc-linear-progress').get(0).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
onColumnClicked(event: Event) {
|
||||||
|
this.showProgress();
|
||||||
|
|
||||||
|
const column: Cash = $(event.target).closest('th');
|
||||||
|
const ascendingClass = 'mdc-data-table__header-cell--sorted';
|
||||||
|
const descendingClass = 'mdc-data-table__header-cell--sorted-descending';
|
||||||
|
|
||||||
|
// If it's already sorted change direction
|
||||||
|
if (column.hasClass(ascendingClass)) {
|
||||||
|
column.toggleClass(descendingClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean previously sorted info and arrows
|
||||||
|
const columns = $(this.element).find('thead th');
|
||||||
|
columns.removeClass(ascendingClass);
|
||||||
|
columns.find('mwc-icon-button-toggle').hide();
|
||||||
|
|
||||||
|
// Add ony one header to sort
|
||||||
|
column.addClass(ascendingClass);
|
||||||
|
|
||||||
|
// Check if need descending sorting
|
||||||
|
const isDescending = column.hasClass(descendingClass);
|
||||||
|
|
||||||
|
// Do sorting
|
||||||
|
this.sortTable(column.index() + 1, isDescending, column.attr('type') === 'numeric');
|
||||||
|
}
|
||||||
|
|
||||||
|
sortTable(columnIndex: number, isDescending: boolean, isNumeric: boolean) {
|
||||||
|
const sorted = [...$(this.element).find(`tr td:nth-child(${columnIndex})`)].sort((a: HTMLElement, b: HTMLElement) => {
|
||||||
|
let aValue = a.textContent;
|
||||||
|
let bValue = b.textContent;
|
||||||
|
|
||||||
|
if (isNumeric) {
|
||||||
|
aValue = Number.parseFloat(aValue);
|
||||||
|
bValue = Number.parseFloat(bValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDescending) {
|
||||||
|
const temporary = aValue;
|
||||||
|
aValue = bValue;
|
||||||
|
bValue = temporary;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof aValue === 'string') {
|
||||||
|
return aValue.localeCompare(bValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return aValue < bValue ? -1 : (aValue > bValue ? 1 : 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const cell of sorted) {
|
||||||
|
const row = $(cell).parent();
|
||||||
|
row.appendTo(row.parent());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,9 @@
|
|||||||
|
import '@material/mwc-icon-button-toggle';
|
||||||
|
|
||||||
|
import {type Cash} from 'cash-dom/dist/cash';
|
||||||
|
|
||||||
import Component from '../Component.jsx';
|
import Component from '../Component.jsx';
|
||||||
|
import Mdi from '../Mdi.jsx';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attributes:
|
* Attributes:
|
||||||
@@ -10,6 +15,24 @@ export default class TableColumn extends Component {
|
|||||||
[`mdc-data-table__header-cell--${this.attrs.get('type')}`]: this.attrs.has('type')
|
[`mdc-data-table__header-cell--${this.attrs.get('type')}`]: this.attrs.has('type')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.attrs.has('sortable')) {
|
||||||
|
this.attrs.addClassNames('mdc-data-table__header-cell--with-sort');
|
||||||
|
this.attrs.put('aria-sort', 'none').put('data-column-id', this.attrs.get('id'));
|
||||||
|
|
||||||
|
vnode.children = (
|
||||||
|
<div className="mdc-data-table__header-cell-wrapper">
|
||||||
|
<mwc-icon-button-toggle style="--mdc-icon-button-size: 28px; display: none;">
|
||||||
|
<Mdi icon="arrow-down-thin" slot="onIcon"/>
|
||||||
|
<Mdi icon="arrow-up-thin" slot="offIcon" />
|
||||||
|
</mwc-icon-button-toggle>
|
||||||
|
|
||||||
|
<div className="mdc-data-table__header-cell-label">
|
||||||
|
{vnode.children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ((!vnode.children || vnode.children.length === 0) && this.attrs.get('type') === 'checkbox') {
|
if ((!vnode.children || vnode.children.length === 0) && this.attrs.get('type') === 'checkbox') {
|
||||||
vnode.children = <mwc-checkbox/>;
|
vnode.children = <mwc-checkbox/>;
|
||||||
}
|
}
|
||||||
@@ -32,5 +55,28 @@ export default class TableColumn extends Component {
|
|||||||
.prop('checked', checkbox.prop('checked'));
|
.prop('checked', checkbox.prop('checked'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle click on column (add arrows)
|
||||||
|
const observer = new MutationObserver((mutations) => {
|
||||||
|
for (const mutation of mutations) {
|
||||||
|
const {classList} = mutation.target;
|
||||||
|
const ascendingClass = 'mdc-data-table__header-cell--sorted';
|
||||||
|
const descendingClass = 'mdc-data-table__header-cell--sorted-descending';
|
||||||
|
|
||||||
|
const onValue = classList.contains(descendingClass);
|
||||||
|
|
||||||
|
const button: Cash = $(this.element).find('mwc-icon-button-toggle');
|
||||||
|
button.prop('on', onValue);
|
||||||
|
|
||||||
|
if (classList.contains(ascendingClass) || classList.contains(descendingClass)) {
|
||||||
|
$(this.element).css('cursor', 'auto').off('click');
|
||||||
|
button.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(this.element, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['class']
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -124,7 +124,7 @@ export default class RecordsPage extends Page {
|
|||||||
return collect(this.columns)
|
return collect(this.columns)
|
||||||
.map(
|
.map(
|
||||||
(column: ColumnT | string, id: string) => (
|
(column: ColumnT | string, id: string) => (
|
||||||
<TableColumn id={id} key={id} {...((typeof column === 'object') ? column : {})}>
|
<TableColumn id={id} key={id} {...((typeof column === 'object') ? column : {})} sortable>
|
||||||
{typeof column === 'string' ? column : column.title}
|
{typeof column === 'string' ? column : column.title}
|
||||||
</TableColumn>
|
</TableColumn>
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user