import Thorium , { Components , Controller , UserInterface , useState } from "thoriumjs"; import style from '../../../styles/table.module.css'; import Style from '../../../styles/table.module.css'; // import chevron from './chevron-down.svg'; import { Icon } from "../../elements/icon/icon"; const { ElementUI , NodeUI } = UserInterface; export type DataLineOptionsInit = any[]; const [table,setTable] = useState(null); const [heading,setHeading] = useState(null); class Cell extends Components.Div{ constructor(element?:any){ super({ prop : {name : 'cell'}, childrens : (element ? [new element()] : []) }) } } interface TableLineController extends Controller{ data:()=>string[]; } class TableLine extends Components.TableRow{ constructor(options:DataLineOptionsInit){ super({ prop : { name : 'tableline', // ':type' : data.constructor.name, ':selected' : false, class : 'context', }, childrens : Array.from(options , (element) => { return new Components.TableD({ childrens : [new Cell(element)] }) }), proto : { data(){ return Array.from(this.querySelectorAll('[name=cell]') , (cell:Controller) => { return cell.innerText; }) } } }) } } interface TableHeadController extends Controller{ headers:()=>string[]; } class TableHead extends Components.TableHead{ constructor(options:TableOptionsInit){ super({ prop : { name : 'tablehead', class : 'context' }, childrens : [ new Components.TableRow({ prop : { name : 'cell' }, childrens : Array.from(options.headers , (header) => { return new Components.TableH({ childrens : [ new Components.Label({prop : {text : header} }), ( header && options.sortable ? new Icon({ type : 'mask' , // path : chevron , prop : { type : 'sorter' , ':option' : 'desc'}, proto : { onMutation(mutation){ let value = this.getAttribute(mutation.attributeName); if(mutation.attributeName == 'option'){ let cellId = Array.from( this.context('tablehead').children , (cell:Controller,iterator:number) => { if(cell == this.parentNode)return iterator; } ).filter((x) => x)[0]; if(value == 'asc')table.value.sortColumn(cellId,'asc'); else if(value == 'desc')table.value.sortColumn(cellId,'desc'); } }, onMouseDown(){ let option = this.getAttribute('option'); if(option == 'desc')this.setAttribute('option','asc'); else if(option == 'asc') this.setAttribute('option','desc'); } } }) : null) ] }) }) }) ], proto : { AfterInitialise(){setHeading(this);}, headers(){return options.headers;} } }) } } export interface TableOptionsInit{ sortable?:boolean, headers : string[], data? : DataLineOptionsInit[], } export interface TableController extends Controller{ addColumn:(x:any)=>void; deleteColumn:(x:any)=>void; duplicateLine:(x:any)=>void; moveLineToTop:(x:any)=>void; moveLineUp:(x:any)=>void; moveLineDown:(x:any)=>void; moveLineToBottom:(x:any)=>void; sortColumn:(columnId:number,order:'asc'|'desc')=>void; values:()=>void; dump:()=>void; dumpLine:(lineId:number)=>void; dumpLines:()=>void; _setTable:(options:TableOptionsInit)=>void; } export class SimpleTable extends Components.Table{ constructor(options:TableOptionsInit){ console.log('iciiii',options); super({ prop : { name : 'table', class : `${style.Table}`, ':column-nb':options.headers.length, // style : `--column-nb:${options.headers.length};--table-template-columns:${Array.from({length : options.headers.length} , (x,i) => {return (i == 0 ? 'minmax(50px,100px)' : 'minmax(150px,1fr)')}).join(' ')};` }, childrens : [ new TableHead(options), new Components.TableBody({ childrens : Array.from(options.data , (data) => { return new TableLine(data); }) }) // ...Array.from(options.data , (data) => { // return new TableLine(data); // }) ], proto : { AfterInitialise(){ setTable(this); }, onMutation(mutation){ const value = this.getAttribute(mutation.attributeName); if(mutation.attributeName == 'column-nb'){ this.style = `--column-nb:${value};--table-template-columns:${Array.from({length : Number(value)} , (x,i) => {return (i == 0 ? 'minmax(0,20px)' : 'minmax(150px,1fr)')}).join(' ')};` } }, addColumn(columnName:string){ const columnNumbers = Number(this.getAttribute('column-nb')); this.setAttribute('column-nb',columnNumbers+1); new NodeUI([new Components.Label({prop : {text : columnName}})]).BuildIn(this.children['tablehead']).then((node) => node.Initialise()); for(const line of this.querySelectorAll('[name=tableline]')){ new NodeUI([new Cell()]).BuildIn(line).then((node) => node.Initialise()); } }, deleteColumn(columnName:string){ }, duplicateLine(lineId:any){ }, moveLineToTop(lineId:any){ let lines = this.querySelectorAll('div[name=tableline]'); this.insertBefore( lines[lineId], lines[0]); }, moveLineUp(lineId:any){ let lines = this.querySelectorAll('div[name=tableline]'); this.insertBefore( lines[lineId], lines[lineId - 1]); }, moveLineDown(lineId:any){ let lines = this.querySelectorAll('div[name=tableline]'); this.insertBefore( lines[lineId], lines[lineId + 2]); }, moveLineToBottom(lineId:any){ let lines = this.querySelectorAll('div[name=tableline]'); this.appendChild(lines[lineId]); }, sortColumn(columnId:number,order:'asc'|'desc'){ const comparator = (a:TableLineController, b:TableLineController) => { if(order == 'asc'){ if (a.data()[columnId] > b.data()[columnId]) return -1; if (a.data()[columnId] < b.data()[columnId]) return 1; } if(order == 'desc'){ if (a.data()[columnId] < b.data()[columnId]) return -1; if (a.data()[columnId] > b.data()[columnId]) return 1; } return 0; } // Function to sort Data const subjects = this.querySelectorAll("div[name=tableline]"); const subjectsArray = Array.from(subjects); let sorted = subjectsArray.sort(comparator); sorted.forEach((e) => {this.appendChild(e)}); }, values(){ let headers = heading.value.headers(); return Array.from( this.querySelectorAll('div[name=tableline]') , (line:TableLineController) => { return Object.fromEntries(new Map(Array.from( line.data() , (data:string,i:number) => { return [headers[i] , data]; }))) }) }, dump(){ return Array.from(this.querySelectorAll('*') , (element:Element) => { return element.remove(); }) }, dumpLine(lineId){ this.querySelectorAll('[name=tableline]')[lineId].remove(); }, dumpLines(){ return Array.from(this.querySelectorAll('[name=tableline]') , (line:Element) => { return line.remove(); }) }, _setTable(options:TableOptionsInit){ this.dump(); console.log(options); this.setAttribute('column-nb',options.headers.length); new NodeUI([ new TableHead(options), ...(options.data ? Array.from(options.data , (data) => { return new TableLine(data); }) : []) ]).BuildIn(this) .then((node) => {node.Initialise()}); } } }) } } export class Table extends Components.Table{ constructor(options:TableOptionsInit){ super({ prop : { name : 'table', class : `${Style.Table}`, // ':column-nb':options.headers.length, // style : `--column-nb:${options.headers.length};--table-template-columns:${Array.from({length : options.headers.length} , (x,i) => {return (i == 0 ? 'minmax(50px,100px)' : 'minmax(150px,1fr)')}).join(' ')};` }, childrens : [ ...(options.headers ? [ new Components.TableHead({ childrens : [ new Components.TableRow({ childrens : Array.from( options.headers , (header) => { return new Components.TableH({ childrens :[ new Components.Div({ prop : {name : 'content'}, childrens : [ ...( header && options.sortable ? [new Icon({ type : 'mask' , // path : chevron , prop : { type : 'sorter' , ':option' : 'desc'}, proto : { onMutation(mutation){ let value = this.getAttribute(mutation.attributeName); if(mutation.attributeName == 'option'){ let cellId = Array.from( this.context('tablehead').children , (cell:Controller,iterator:number) => { if(cell == this.parentNode)return iterator; } ).filter((x) => x)[0]; if(value == 'asc')table.value.sortColumn(cellId,'asc'); else if(value == 'desc')table.value.sortColumn(cellId,'desc'); } }, onMouseDown(){ let option = this.getAttribute('option'); if(option == 'desc')this.setAttribute('option','asc'); else if(option == 'asc') this.setAttribute('option','desc'); } } })] : []), new Components.Label({ prop : {text : header} }) ] }) ] }) } ) }) ] }) ] : [] ), ...(options.data ? [ new Components.TableBody({ childrens : Array.from( options.data , (dataset) => { return new Components.TableRow({ childrens : Array.from( dataset , (value) => { return new Components.TableD({ childrens : [new value()] }) }) }) } ) }) ] : []) ] }) } }