/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, property} from 'lit/decorators';
import {lll} from 'TYPO3/CMS/Core/lit-helper';
import 'TYPO3/CMS/Backend/Element/IconElement';
/**
* Module: TYPO3/CMS/Backend/Element/TableWizardElement
*
* @example
*
*
*
* This is based on W3C custom elements ("web components") specification, see
* https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
*/
@customElement('typo3-backend-table-wizard')
export class TableWizardElement extends LitElement {
@property({type: String}) type: string = 'textarea';
@property({type: Array}) table: string[][] = [];
@property({type: Number, attribute: 'append-rows'}) appendRows: number = 1;
@property({type: Object}) l10n: any = {};
private get firstRow(): string[] {
return this.table[0] || [];
}
public createRenderRoot(): HTMLElement | ShadowRoot {
// @todo Switch to Shadow DOM once Bootstrap CSS style can be applied correctly
// const renderRoot = this.attachShadow({mode: 'open'});
return this;
}
public render(): TemplateResult {
return this.renderTemplate();
}
private provideMinimalTable(): void {
if (this.table.length === 0 || this.firstRow.length === 0) {
// create a table with one row and one column
this.table = [
['']
];
}
}
private modifyTable(evt: Event, rowIndex: number, colIndex: number): void {
const target = evt.target as HTMLInputElement | HTMLTextAreaElement;
this.table[rowIndex][colIndex] = target.value;
this.requestUpdate();
}
private toggleType(evt: Event): void {
this.type = this.type === 'input' ? 'textarea' : 'input';
}
private moveColumn(evt: Event, col: number, target: number): void {
this.table = this.table.map((row: string[]): string[] => {
const temp = row.splice(col, 1);
row.splice(target, 0, ...temp);
return row;
});
this.requestUpdate();
}
private appendColumn(evt: Event, col: number): void {
this.table = this.table.map((row: string[]): string[] => {
row.splice(col + 1, 0, '');
return row;
});
this.requestUpdate();
}
private removeColumn(evt: Event, col: number): void {
this.table = this.table.map((row: string[]): string[] => {
row.splice(col, 1);
return row;
});
this.requestUpdate();
}
private moveRow(evt: Event, row: number, target: number): void {
const temp = this.table.splice(row, 1);
this.table.splice(target, 0, ...temp);
this.requestUpdate();
}
private appendRow(evt: Event, row: number): void {
let columns = this.firstRow.concat().fill('');
let rows = (new Array(this.appendRows)).fill(columns);
this.table.splice(row + 1, 0, ...rows);
this.requestUpdate();
}
private removeRow(evt: Event, row: number): void {
this.table.splice(row, 1);
this.requestUpdate();
}
private renderTemplate(): TemplateResult {
const colIndexes = Object.keys(this.firstRow).map((item: string) => parseInt(item, 10));
const lastColIndex = colIndexes[colIndexes.length - 1];
const lastRowIndex = this.table.length - 1;
return html`
${this.renderTypeButton()} |
${colIndexes.map((colIndex: number) => html`
${this.renderColButtons(colIndex, lastColIndex)} |
`)}
${this.table.map((row: string[], rowIndex: number) => html`
${this.renderRowButtons(rowIndex, lastRowIndex)} |
${row.map((value: string, colIndex: number) => html`
${this.renderDataElement(value, rowIndex, colIndex)} |
`)}
`)}
`;
}
private renderDataElement(value: string, rowIndex: number, colIndex: number): TemplateResult {
const modifyTable = (evt: Event) => this.modifyTable(evt, rowIndex, colIndex);
switch (this.type) {
case 'input':
return html`
`;
case 'textarea':
default:
return html`
`;
}
}
private renderTypeButton(): TemplateResult {
return html`
`;
}
private renderColButtons(col: number, last: number): TemplateResult {
const leftButton = {
title: col === 0 ? lll('table_end') : lll('table_left'),
class: col === 0 ? 'double-right' : 'left',
target: col === 0 ? last : col - 1,
};
const rightButton = {
title: col === last ? lll('table_start') : lll('table_right'),
class: col === last ? 'double-left' : 'right',
target: col === last ? 0 : col + 1,
};
return html`
`;
}
private renderRowButtons(row: number, last: number): TemplateResult {
const topButton = {
title: row === 0 ? lll('table_bottom') : lll('table_up'),
class: row === 0 ? 'double-down' : 'up',
target: row === 0 ? last : row - 1,
};
const bottomButton = {
title: row === last ? lll('table_top') : lll('table_down'),
class: row === last ? 'double-up' : 'down',
target: row === last ? 0 : row + 1,
};
return html`
`;
}
}