Skip to content
Snippets Groups Projects
Commit 2aa5a112 authored by Steinwender, Tamara's avatar Steinwender, Tamara
Browse files

Add tabulator table webcomponent

parent 12c28c2f
No related branches found
No related tags found
1 merge request!314Master
Showing
with 1212 additions and 0 deletions
/vendor/**
/dist/**
*.conf.js
*.config.js
\ No newline at end of file
{
"root": true,
"extends": "./../../eslint.common.json"
}
dist
node_modules
.idea
npm-debug.log
package-lock.json
index.html
node_modules
.idea
npm-debug.log
package-lock.json
index.html
node_modules/
/dist
/vendor
{
"bracketSpacing": false,
"singleQuote": true,
"tabWidth": 4,
"printWidth": 100,
"bracketSameLine": true,
"htmlWhitespaceSensitivity": "ignore",
"overrides": [
{
"files": "*.js",
"options": {
"semi": true
}
}
]
}
This diff is collapsed.
# Tabulator table web component
This web component allows to create a table with tabulator-tables.
## Installation
You can install these components via npm:
```bash
npm i @dbp-toolkit/tabulator-table
```
After you have installed the theme-switcher component via npm you can use this example to get a button
that opens a dialogue with multiple themes. After you have selected a theme the class of the theme is
applied to the body of your html document. To add a style to the specific class you have to
```html
<script type="module" src="node_modules/@dbp-toolkit/tabulator-table/dist/dbp-tabulator-table.js"></script>
```
Or you can include the JS files directly via CDN:
```html
<script type="module" src="https://unpkg.com/@dbp-toolkit/tabulator-table@0.0.1/dist/tabulator-table.js"></script>
```
## Usage
```html
<dbp-tabulator-table></dbp-tabulator-table>
```
## Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
- example `<dbp-tabulator-table lang="de"></dbp-tabulator-table>`
## Note
## Local development
```bash
# get the source
git clone git@gitlab.tugraz.at:dbp/web-components/toolkit.git
cd toolkit/packages/tabulator-table
# install dependencies
yarn install
# constantly build dist/bundle.js and run a local web-server on port 8002
yarn run watch-local
# build local packages in dist directory
yarn run build
```
Jump to <http://localhost:8002> and you should get a demo page.
packages/tabulator-table/assets/favicon.ico

1.12 KiB

module.exports = {
createOldCatalogs: false,
indentation: 4,
keepRemoved: false,
locales: ['en', 'de'],
output: 'src/i18n/$LOCALE/$NAMESPACE.json',
input: ['src/**/*.js'],
sort: true,
i18nextOptions: {compatibilityJSON: 'v3'},
};
module.exports = require('../../karma.common.conf.js');
{
"name": "@dbp-toolkit/tabulator-table",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/tabulator-table",
"version": "0.0.1",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
"type": "git",
"url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
"directory": "packages/tabulator-table"
},
"publishConfig": {
"registry": "https://registry.npmjs.org",
"access": "public"
},
"devDependencies": {
"@esm-bundle/chai": "^4.2.0",
"@rollup/plugin-commonjs": "^23.0.0",
"@rollup/plugin-json": "^5.0.0",
"@rollup/plugin-node-resolve": "^15.0.0",
"@rollup/plugin-terser": "^0.1.0",
"eslint": "^8.0.0",
"eslint-plugin-jsdoc": "^39.0.0",
"i18next-parser": "^7.0.0",
"karma": "^6.0.0",
"karma-chrome-launcher": "^3.0.0",
"karma-firefox-launcher": "^2.1.0",
"karma-mocha": "^2.0.0",
"mocha": "^10.0.0",
"playwright-core": "^1.20.2",
"prettier": "^2.5.1",
"rollup": "^3.2.5",
"rollup-plugin-copy": "^3.1.0",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-serve": "^2.0.0"
},
"dependencies": {
"@dbp-toolkit/common": "^0.3.3",
"@open-wc/scoped-elements": "^2.1.0",
"i18next": "^22.0.0",
"jszip": "^3.5.0",
"lit": "^2.0.0",
"material-design-icons-svg": "^3.0.0",
"tabulator-tables": "^5.4.3"
},
"scripts": {
"clean": "rm dist/*",
"format": "yarn run format:eslint && yarn run format:prettier",
"format:eslint": "eslint \"**/*.{js,ts}\" --fix",
"format:prettier": "prettier \"**/*.{js,json,ts}\" --write",
"build": "yarn run build-local",
"build-local": "rollup --bundleConfigAsCjs -c",
"build-dev": "rollup --bundleConfigAsCjs -c --environment BUILD:development",
"build-prod": "rollup --bundleConfigAsCjs -c --environment BUILD:production",
"build-demo": "rollup --bundleConfigAsCjs -c --environment BUILD:demo",
"build-test": "rollup --bundleConfigAsCjs -c --environment BUILD:test",
"i18next": "i18next",
"watch": "yarn run watch-local",
"watch-local": "rollup --bundleConfigAsCjs -c --watch",
"watch-dev": "rollup --bundleConfigAsCjs -c --watch --environment BUILD:development",
"test": "yarn run build-test && karma start --singleRun",
"lint": "eslint ."
}
}
import glob from 'glob';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
import terser from '@rollup/plugin-terser';
import json from '@rollup/plugin-json';
import serve from 'rollup-plugin-serve';
import del from 'rollup-plugin-delete';
import {getPackagePath, getDistPath} from '../../rollup.utils.js';
import path from 'path';
const pkg = require('./package.json');
const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local';
console.log('build: ' + build);
export default (async () => {
return {
input:
build !== 'test'
? ['src/demo.js', 'src/dbp-tabulator-table.js']
: glob.sync('test/**/*.js'),
output: {
dir: 'dist',
entryFileNames: '[name].js',
chunkFileNames: 'shared/[name].[hash].[format].js',
format: 'esm',
sourcemap: true,
},
plugins: [
del({
targets: 'dist/*',
}),
resolve({browser: true}),
commonjs(),
json(),
build !== 'local' && build !== 'test' ? terser() : false,
copy({
targets: [
{src: 'assets/index.html', dest: 'dist'},
{src: 'assets/favicon.ico', dest: 'dist'},
{
src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'),
dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')),
},
{
src: await getPackagePath('tabulator-tables', 'dist/css'),
dest: 'dist/' + (await getDistPath(pkg.name, 'tabulator-tables')),
},
],
}),
process.env.ROLLUP_WATCH === 'true'
? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002})
: false,
],
};
})();
import * as commonUtils from '@dbp-toolkit/common/utils';
import {TabulatorTable} from './tabulator-table';
commonUtils.defineCustomElement('dbp-tabulator-table', TabulatorTable);
import {createInstance, setOverridesByGlobalCache} from './i18n';
import {html, LitElement} from 'lit';
import {ScopedElementsMixin} from '@open-wc/scoped-elements';
import {TabulatorTable} from './tabulator-table';
import * as commonUtils from '@dbp-toolkit/common/utils';
export class TabulatorTableDemo extends ScopedElementsMixin(LitElement) {
constructor() {
super();
this._i18n = createInstance();
this.lang = this._i18n.language;
this.url = '';
this.selectedFiles = [];
this.selectedFilesCount = 0;
this.langDir = '';
}
static get scopedElements() {
return {
'dbp-tabulator-table': TabulatorTable,
};
}
static get properties() {
return {
lang: {type: String},
langDir: {type: String, attribute: "lang-dir"},
};
}
connectedCallback() {
super.connectedCallback();
if (this.langDir) {
setOverridesByGlobalCache(this._i18n, this);
}
}
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
if (propName === 'lang') {
this._i18n.changeLanguage(this.lang);
}
});
super.update(changedProperties);
}
render() {
const i18n = this._i18n;
let data = [
{id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
{id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
];
let options = {
layout:"fitColumns",
columns:[
{title:"Name", field:"name", width:150},
{title:"Age", field:"age", hozAlign:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
],
columnDefaults: {
vertAlign: 'middle',
hozAlign: 'left',
resizable: false,
},
};
return html`
<section class="section">
<div class="content">
<h1 class="title">${i18n.t('demo-title')}</h1>
<p></p>
</div>
<div class="content">
<dbp-tabulator-table lang="de" select-all-enabled pagination-enabled="true" data=${JSON.stringify(data)} options=${JSON.stringify(options)}></dbp-tabulator-table>
</div>
</section>
`;
}
}
commonUtils.defineCustomElement('dbp-tabulator-table-demo', TabulatorTableDemo);
import {createInstance as _createInstance, setOverridesByGlobalCache} from '@dbp-toolkit/common/i18next.js';
import de from './i18n/de/translation.json';
import en from './i18n/en/translation.json';
export function createInstance() {
return _createInstance({en: en, de: de}, 'de', 'en');
}
export{setOverridesByGlobalCache};
{
"demo-title": "Tabulator Table Demo"
}
{
"demo-title": "Tabulator Table Demo"
}
export {TabulatorTable} from './tabulator-table';
import {createInstance} from './i18n.js';
import {html, css, unsafeCSS} from 'lit';
import {ScopedElementsMixin} from '@open-wc/scoped-elements';
import * as commonStyles from '@dbp-toolkit/common/styles';
import {TabulatorFull as Tabulator} from 'tabulator-tables';
import * as commonUtils from "@dbp-toolkit/common/utils";
import {name as pkgName} from "@dbp-toolkit/tabulator-table/package.json";
import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element";
export class TabulatorTable extends ScopedElementsMixin(DBPLitElement) {
constructor() {
super();
this._i18n = createInstance();
this.lang = this._i18n.language;
this.tabulatorTable = null;
this.identifier = 'table';
this.options = {
layout:"fitColumns",
autoColumns: true,
};
this.data = [];
this.paginationEnabled = false;
this.paginationSize = 10;
this.selectAllEnabled = false;
}
static get properties() {
return {
...super.properties,
lang: {type: String},
identifier: {type: String, attribute: 'identifier'},
options: {type: Object},
data: {type: Array, attribute: 'data'},
paginationEnabled: {type: Boolean, attribute: 'pagination-enabled'},
paginationSize: {type: Number, attribute: 'pagination-size'},
selectAllEnabled: {type: Boolean, attribute: 'select-all-enabled'},
};
}
static get scopedElements() {
return {
};
}
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
if (propName === 'lang') {
this._i18n.changeLanguage(this.lang);
if (this.tabulatorTable) {
this.tabulatorTable.setLocale(this.lang);
}
}
});
super.update(changedProperties);
}
connectedCallback() {
super.connectedCallback();
this.updateComplete.then(() => {
if (this.paginationEnabled) {
let paginationElement = this._('.tabulator-paginator');
this.options['pagination'] = 'local';
this.options['paginationSize'] = this.paginationSize;
this.options['paginationSizeSelector'] = true;
this.options['paginationElement'] = paginationElement;
this.options['langs'] = {
'en': {
'pagination': {
'page_size': 'Page size',
'page_size_title': 'Page size',
'first': '<span class="mobile-hidden">First</span>',
'first_title': 'First Page',
'last': '<span class="mobile-hidden">Last</span>',
'last_title': 'Last Page',
'prev': '<span class="mobile-hidden">Prev</span>',
'prev_title': 'Prev Page',
'next': '<span class="mobile-hidden">Next</span>',
'next_title': 'Next Page'
}
},
'de': {
'pagination': {
'page_size': 'Einträge pro Seite',
'page_size_title': 'Einträge pro Seite',
'first': '<span class="mobile-hidden">Erste</span>',
'first_title': 'Erste Seite',
'last': '<span class="mobile-hidden">Letzte</span>',
'last_title': 'Letzte Seite',
'prev': '<span class="mobile-hidden">Vorherige</span>',
'prev_title': 'Vorherige Seite',
'next': '<span class="mobile-hidden">Nächste</span>',
'next_title': 'Nächste Seite'
}
}
};
}
this.tabulatorTable = new Tabulator(this._("#" + this.identifier), this.options);
this.tabulatorTable.on("tableBuilt", this.tableBuildFunctions.bind(this));
this.tabulatorTable.on("rowClick", this.rowClickFunction.bind(this));
});
}
disconnectedCallback() {
this.tabulatorTable.off("tableBuilt");
this.tabulatorTable.off("rowClick");
super.disconnectedCallback();
}
tableBuildFunctions() {
this.tabulatorTable.setLocale(this.lang);
this.tabulatorTable.setData(this.data);
if (this.selectAllEnabled) {
console.log("add select all");
this.tabulatorTable.addColumn({
title:
'<label id="select_all_wrapper" class="button-container select-all-icon">' +
'<input type="checkbox" id="select_all" name="select_all" value="select_all">' +
'<span class="checkmark" id="select_all_checkmark"></span>' +
'</label>',
field: 'empty',
hozAlign: 'center',
width: 40,
headerSort: false,
responsive: 0,
widthGrow: 1,
headerClick: (e) => {
let allSelected = this.checkAllSelected();
if (allSelected) {
this.tabulatorTable.deselectRow();
this._('#select_all').checked = false;
} else {
this.tabulatorTable.selectRow("visible");
this._('#select_all').checked = true;
}
e.preventDefault();
},
}, true);
}
}
rowClickFunction(e, row) {
if (
this.tabulatorTable !== null &&
this.tabulatorTable.getSelectedRows().length ===
this.tabulatorTable.getRows("visible").length) {
this._('#select_all').checked = true;
} else {
this._('#select_all').checked = false;
}
}
/**
* Select or deselect all files from tabulator table
*
*/
selectAllFiles() {
let allSelected = this.checkAllSelected();
if (allSelected) {
this.tabulatorTable.getSelectedRows().forEach((row) => row.deselect());
} else {
this.tabulatorTable.getRows().forEach((row) => row.select());
}
}
checkAllSelected() {
if (this.tabulatorTable) {
let maxSelected = this.tabulatorTable.getRows("visible").length;
let selected = this.tabulatorTable.getSelectedRows().length;
if (selected === maxSelected) {
return true;
}
}
return false;
}
static get styles() {
const iconPath = commonUtils.getAssetURL(
'@dbp-toolkit/common',
'icons/'
);
// language=css
return css`
${commonStyles.getThemeCSS()}
${commonStyles.getGeneralCSS()}
${commonStyles.getTabulatorStyles()}
${commonStyles.getRadioAndCheckboxCss()}
.select-all-icon {
height: 40px;
position: absolute;
top: -2px;
}
.checkmark {
height: 20px;
width: 20px;
left: 10px;
top: 8px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-top: 4px;
padding-bottom: 4px;
font-weight: normal;
font-size: 1rem;
}
.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers {
min-height: 37px;
display: flex;
align-items: center;
}
.tabulator .tabulator-footer .tabulator-paginator .tabulator-page[disabled] {
opacity: 0.4;
}
.tabulator .tabulator-footer {
background-color: var(--dbp-background);
color: var(--dbp-content);
}
.tabulator .tabulator-footer .tabulator-footer-contents {
flex-direction: column;
}
.tabulator .tabulator-footer .tabulator-paginator {
flex-direction: row;
display: flex;
align-items: center;
}
.tabulator .tabulator-footer .tabulator-paginator label {
color: var(--dbp-content);
font-weight: 400;
}
.tabulator .tabulator-footer .tabulator-paginator .tabulator-page-size {
box-sizing: border-box;
border: var(--dbp-border);
border-radius: var(--dbp-border-radius);
padding: calc(0.5em - 1px) 1.7em calc(0.5em - 1px) 0.75em;
cursor: pointer;
background-position-x: calc(100% - 0.4rem);
background-size: auto 45%;
min-height: 40px;
}
.tabulator .tabulator-footer .tabulator-paginator .tabulator-page {
opacity: unset;
border-radius: var(--dbp-border-radius);
cursor: pointer;
padding: calc(0.375em - 1px) 0.75em;
text-align: center;
white-space: nowrap;
font-size: inherit;
font-weight: bolder;
font-family: inherit;
transition: all 0.15s ease 0s, color 0.15s ease 0s;
background: var(--dbp-secondary-surface);
color: var(--dbp-on-secondary-surface);
border-color: var(--dbp-secondary-surface-border-color);
box-sizing: border-box;
min-height: 40px;
}
@media only screen and (orientation: portrait) and (max-width: 768px) {
.mobile-hidden {
display: none;
}
#custom-pagination, .tabulator-footer {
position: sticky;
bottom: 0;
z-index: 10;
}
.tabulator {
overflow: visible;
}
.tabulator .tabulator-footer .tabulator-paginator .tabulator-page {
border: none;
}
.tabulator .tabulator-footer .tabulator-footer-contents .tabulator-paginator .tabulator-pages {
display: none;
}
.tabulator .tabulator-footer .tabulator-paginator {
text-align: center;
}
.tabulator .tabulator-footer .tabulator-paginator label {
display: none;
}
.tabulator .tabulator-footer .tabulator-paginator .tabulator-page {
border: none;
}
.tabulator .tabulator-footer .tabulator-paginator .tabulator-page-size {
padding-right: 1.5em;
background-size: auto 40%;
}
button[data-page="prev"]::after, button[data-page="next"]::after, button[data-page="first"]::after, button[data-page="last"]::after {
content: " ";
background-color: var(--dbp-content);
mask-repeat: no-repeat;
mask-position: center center;
padding: 0 0 0.25%;
mask-size: 1.4rem !important;
}
button[data-page="first"]::after {
content: " ";
mask-image: url("${unsafeCSS(iconPath)}angle-double-left.svg");
}
button[data-page="prev"]::after {
mask-image: url("${unsafeCSS(iconPath)}chevron-left.svg");
}
button[data-page="next"]::after {
mask-image: url("${unsafeCSS(iconPath)}chevron-right.svg");
}
button[data-page="last"]::after {
content: " ";
mask-image: url("${unsafeCSS(iconPath)}angle-double-right.svg");
}
}
`;
}
render() {
const tabulatorCss = commonUtils.getAssetURL(
pkgName,
'tabulator-tables/css/tabulator.min.css'
);
return html`
<div class="wrapper">
<link rel="stylesheet" href="${tabulatorCss}"/>
<div class="table-wrapper">
<div id=${this.identifier}></div>
<div class='tabulator' id='custom-pagination'>
<div class='tabulator-footer'>
<div class='tabulator-footer-contents'>
<span class='tabulator-paginator'></span>
</div>
</div>
</div>
</div>
</div>
`;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment