@beeblock/svelar-datatable 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -23,10 +23,15 @@ Full-featured DataTable plugin for [Svelar](https://svelar.dev) / SvelteKit 2 wi
23
23
  - **Footer aggregation** — per-column footer with custom functions
24
24
  - **Responsive** — horizontal scroll for small screens
25
25
 
26
- ## Install
26
+ ## Installation
27
27
 
28
28
  ```bash
29
+ # Install and publish route stubs
30
+ npx svelar plugin:install @beeblock/svelar-datatable
31
+
32
+ # Or manual install
29
33
  npm install @beeblock/svelar-datatable
34
+ npx svelar plugin:publish @beeblock/svelar-datatable
30
35
  ```
31
36
 
32
37
  Peer dependencies: `@beeblock/svelar >= 0.4.0`, `svelte ^5.0.0`
@@ -9,5 +9,12 @@ export declare class SvelarDatatablePlugin {
9
9
  get name(): string;
10
10
  get config(): DatatablePluginConfig;
11
11
  static defaults(): Partial<DataTableConfig>;
12
+ publishables(): Promise<{
13
+ routes: {
14
+ source: string;
15
+ dest: string;
16
+ type: "asset";
17
+ }[];
18
+ }>;
12
19
  }
13
20
  export {};
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export { SvelarDatatablePlugin } from './SvelarDatatablePlugin.js';
2
1
  export { DataTableStore } from './state/DataTableStore.js';
3
2
  export { ServerDataTableStore } from './state/ServerDataTableStore.js';
4
3
  export { ExportManager } from './export/ExportManager.js';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- var y={prefix:"/api",defaults:{perPage:15,perPageOptions:[10,15,25,50,100],searchDebounceMs:300,sortable:!0,searchable:!0,paginate:!0,selectable:"none",striped:!0,hover:!0,bordered:!1,compact:!1,responsive:!0,virtualScroll:!1,virtualRowHeight:48}},S=class{_config;constructor(t={}){this._config={...y,...t,defaults:{...y.defaults,...t.defaults}}}get name(){return"svelar-datatable"}get config(){return this._config}static defaults(){return{...y.defaults}}};var m=class{_state;_listeners=new Set;_columns=[];_rowIdFn;_stateSaveKey=null;_lastSelectedId=null;_paginate=!0;constructor(t){this._columns=t.columns,this._stateSaveKey=t.stateSaveKey??null,this._paginate=t.paginate!==!1,this._rowIdFn=typeof t.rowId=="function"?t.rowId:s=>s[t.rowId??"id"];let e=this._loadState();this._state={allRows:t.data??[],filteredRows:[],sortedRows:[],paginatedRows:[],sort:e?.sort??[],filters:e?.filters??[],globalSearch:e?.globalSearch??"",pagination:{page:e?.page??1,perPage:t.perPage??15,total:0,lastPage:1},selectedIds:new Set,columnVisibility:e?.columnVisibility??Object.fromEntries(t.columns.map(s=>[s.key,s.visible!==!1])),columnOrder:e?.columnOrder??t.columns.map(s=>s.key),loading:!1,error:null,editingRowId:null,editingColumn:null,editorMode:null,formData:{},validationErrors:{},draw:0,excelFocusedCell:null,excelEditingCell:null,excelEditValue:""},this._recompute()}subscribe(t){return this._listeners.add(t),()=>this._listeners.delete(t)}getState(){return this._state}_notify(){for(let t of this._listeners)t()}_saveState(){if(this._stateSaveKey)try{let t={sort:this._state.sort,filters:this._state.filters,globalSearch:this._state.globalSearch,page:this._state.pagination.page,columnVisibility:this._state.columnVisibility,columnOrder:this._state.columnOrder};localStorage.setItem(this._stateSaveKey,JSON.stringify(t))}catch{}}_loadState(){if(!this._stateSaveKey)return null;try{let t=localStorage.getItem(this._stateSaveKey);return t?JSON.parse(t):null}catch{return null}}setData(t){this._state={...this._state,allRows:t},this._recompute()}setSort(t){this._state={...this._state,sort:t,pagination:{...this._state.pagination,page:1}},this._recompute(),this._saveState()}toggleSort(t,e=!1){let s=this._state.sort.find(i=>i.column===t),a;s?s.direction==="asc"?a=e?this._state.sort.map(i=>i.column===t?{...i,direction:"desc"}:i):[{column:t,direction:"desc"}]:a=e?this._state.sort.filter(i=>i.column!==t):[]:a=e?[...this._state.sort,{column:t,direction:"asc"}]:[{column:t,direction:"asc"}],this.setSort(a)}setGlobalSearch(t){this._state={...this._state,globalSearch:t,pagination:{...this._state.pagination,page:1}},this._recompute(),this._saveState()}setFilters(t){this._state={...this._state,filters:t,pagination:{...this._state.pagination,page:1}},this._recompute(),this._saveState()}setColumnFilter(t,e,s="like"){let a=this._state.filters.filter(i=>i.column!==t);e!==""&&e!==null&&e!==void 0&&a.push({column:t,value:e,operator:s}),this.setFilters(a)}setPage(t){let e=this._state.pagination.lastPage,s=Math.max(1,Math.min(t,e));this._state={...this._state,pagination:{...this._state.pagination,page:s}},this._recompute(),this._saveState()}setPerPage(t){this._state={...this._state,pagination:{...this._state.pagination,perPage:t,page:1}},this._recompute(),this._saveState()}toggleColumnVisibility(t){let e={...this._state.columnVisibility};e[t]=!e[t],this._state={...this._state,columnVisibility:e},this._notify(),this._saveState()}setColumnVisibility(t){this._state={...this._state,columnVisibility:t},this._notify(),this._saveState()}reorderColumns(t){this._state={...this._state,columnOrder:t},this._notify(),this._saveState()}getRowId(t){return this._rowIdFn(t)}toggleSelect(t){let e=new Set(this._state.selectedIds);e.has(t)?e.delete(t):e.add(t),this._lastSelectedId=t,this._state={...this._state,selectedIds:e},this._notify()}getLastSelectedId(){return this._lastSelectedId}selectSingle(t){this._state={...this._state,selectedIds:new Set([t])},this._notify()}selectAll(){let t=this._state.filteredRows.map(e=>this.getRowId(e));this._state={...this._state,selectedIds:new Set(t)},this._notify()}deselectAll(){this._state={...this._state,selectedIds:new Set},this._notify()}selectRange(t,e){let s=this._state.sortedRows,a=s.findIndex(n=>this.getRowId(n)===t),i=s.findIndex(n=>this.getRowId(n)===e);if(a===-1||i===-1)return;let o=Math.min(a,i),u=Math.max(a,i),r=new Set(this._state.selectedIds);for(let n=o;n<=u;n++)r.add(this.getRowId(s[n]));this._state={...this._state,selectedIds:r},this._notify()}getSelectedRows(){return this._state.allRows.filter(t=>this._state.selectedIds.has(this.getRowId(t)))}openEditor(t,e,s){let a=t!==null?this._state.allRows.find(o=>this.getRowId(o)===t):null,i=a?{...a}:{};this._state={...this._state,editingRowId:t,editingColumn:e,editorMode:s,formData:i,validationErrors:{}},this._notify()}closeEditor(){this._state={...this._state,editingRowId:null,editingColumn:null,editorMode:null,formData:{},validationErrors:{}},this._notify()}setFormField(t,e){this._state={...this._state,formData:{...this._state.formData,[t]:e}},this._notify()}setValidationErrors(t){this._state={...this._state,validationErrors:t},this._notify()}setLoading(t){this._state={...this._state,loading:t},this._notify()}setError(t){this._state={...this._state,error:t},this._notify()}setServerResponse(t){this._state={...this._state,allRows:t.data,filteredRows:t.data,sortedRows:t.data,paginatedRows:t.data,loading:!1,draw:t.draw,pagination:{...this._state.pagination,total:t.recordsFiltered,lastPage:Math.ceil(t.recordsFiltered/this._state.pagination.perPage)||1}},this._notify()}resetState(){if(this._state={...this._state,sort:[],filters:[],globalSearch:"",pagination:{...this._state.pagination,page:1},selectedIds:new Set},this._recompute(),this._stateSaveKey)try{localStorage.removeItem(this._stateSaveKey)}catch{}}focusCell(t,e){this._state={...this._state,excelFocusedCell:{rowIndex:t,columnKey:e}},this._notify()}startCellEdit(){let t=this._state.excelFocusedCell;if(!t)return;let e=this._state.paginatedRows[t.rowIndex];if(!e)return;let s=this._columns.find(a=>a.key===t.columnKey);!s||s.editable===!1||(this._state={...this._state,excelEditingCell:{...t},excelEditValue:e[t.columnKey]!=null?String(e[t.columnKey]):""},this._notify())}setExcelEditValue(t){this._state={...this._state,excelEditValue:t}}commitCellEdit(){let t=this._state.excelEditingCell;if(!t)return null;let e=this._state.paginatedRows[t.rowIndex];if(!e)return this.cancelCellEdit(),null;let s=this._columns.find(o=>o.key===t.columnKey),a=e[t.columnKey],i=this._state.excelEditValue;return s?.type==="number"?i=i===""?null:Number(i):s?.type==="boolean"?i=i==="true"||i==="1":i===""&&(i=null),this._state={...this._state,excelEditingCell:null,excelEditValue:""},i===a||i===null&&a==null?(this._notify(),null):(e[t.columnKey]=i,this._notify(),{row:e,columnKey:t.columnKey,oldValue:a,newValue:i})}cancelCellEdit(){this._state={...this._state,excelEditingCell:null,excelEditValue:""},this._notify()}clearExcelFocus(){this._state={...this._state,excelFocusedCell:null,excelEditingCell:null,excelEditValue:""},this._notify()}getVisibleColumns(){return this._state.columnOrder.filter(t=>this._state.columnVisibility[t]!==!1).map(t=>this._columns.find(e=>e.key===t)).filter(Boolean)}navigateCell(t){let e=this._state.excelFocusedCell,s=this._state.paginatedRows,a=this.getVisibleColumns();if(a.length===0)return null;if(!e){let r=a.find(n=>n.editable!==!1);return r&&s.length>0&&this.focusCell(0,r.key),null}let{rowIndex:i,columnKey:o}=e,u=a.findIndex(r=>r.key===o);if(u===-1)return null;switch(t){case"left":{for(let r=u-1;r>=0;r--)if(a[r].editable!==!1)return this.focusCell(i,a[r].key),null;for(let r=a.length-1;r>=0;r--)if(a[r].editable!==!1)return i>0?(this.focusCell(i-1,a[r].key),null):"page-prev";return null}case"right":{for(let r=u+1;r<a.length;r++)if(a[r].editable!==!1)return this.focusCell(i,a[r].key),null;for(let r=0;r<a.length;r++)if(a[r].editable!==!1)return i<s.length-1?(this.focusCell(i+1,a[r].key),null):"page-next";return null}case"up":return i>0?(this.focusCell(i-1,o),null):"page-prev";case"down":return i<s.length-1?(this.focusCell(i+1,o),null):"page-next"}}_recompute(){let t=[...this._state.allRows];if(this._state.globalSearch){let n=this._state.globalSearch.toLowerCase(),d=this._columns.filter(l=>l.searchable!==!1);t=t.filter(l=>d.some(p=>{let h=l[p.key];return h!=null&&String(h).toLowerCase().includes(n)}))}for(let n of this._state.filters)t=t.filter(d=>{let l=d[n.column];switch(n.operator){case"=":return l==n.value;case"!=":return l!=n.value;case">":return l>n.value;case"<":return l<n.value;case">=":return l>=n.value;case"<=":return l<=n.value;case"like":return l!=null&&String(l).toLowerCase().includes(String(n.value).toLowerCase());case"not_like":return l==null||!String(l).toLowerCase().includes(String(n.value).toLowerCase());case"in":return Array.isArray(n.value)&&n.value.includes(l);case"between":return Array.isArray(n.value)&&l>=n.value[0]&&l<=n.value[1];case"null":return l==null;case"not_null":return l!=null;default:return!0}});let e=t;this._state.sort.length>0&&(t=[...t].sort((n,d)=>{for(let l of this._state.sort){let p=this._columns.find(k=>k.key===l.column),h=n[l.column],g=d[l.column],f=0;if(h==null?f=-1:g==null?f=1:p?.type==="number"?f=Number(h)-Number(g):p?.type==="date"?f=new Date(h).getTime()-new Date(g).getTime():p?.type==="boolean"?f=(h?1:0)-(g?1:0):f=String(h).localeCompare(String(g)),f!==0)return l.direction==="desc"?-f:f}return 0}));let s=t,a=e.length,i=this._state.pagination.perPage,o,u,r;if(this._paginate){r=Math.ceil(a/i)||1,u=Math.min(this._state.pagination.page,r);let n=(u-1)*i;o=s.slice(n,n+i)}else o=s,u=1,r=1;this._state={...this._state,filteredRows:e,sortedRows:s,paginatedRows:o,pagination:{page:u,perPage:i,total:a,lastPage:r}},this._notify()}};function I(c="XSRF-TOKEN"){if(typeof document>"u")return null;let t=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),e=document.cookie.match(new RegExp(`(?:^|;\\s*)${t}=([^;]*)`));return e?decodeURIComponent(e[1]):null}var v=class extends m{_serverUrl;_serverMethod;_drawCounter=0;_abortController=null;_fetchDebounceTimer=null;_serverColumns;_csrfCookieName;_csrfHeaderName;constructor(t){super(t),this._serverUrl=t.serverUrl,this._serverMethod=t.serverMethod??"GET",this._csrfCookieName=t.csrfCookieName??"XSRF-TOKEN",this._csrfHeaderName=t.csrfHeaderName??"X-CSRF-Token",this._serverColumns=t.columns.map(e=>({data:e.key,name:e.key,searchable:e.searchable!==!1,orderable:e.sortable!==!1}))}_buildHeaders(t={}){let e={...t},s=I(this._csrfCookieName);return s&&(e[this._csrfHeaderName]=s),e}setSort(t){let e=this.getState();this._state={...e,sort:t,pagination:{...e.pagination,page:1}},this._debouncedFetch()}setGlobalSearch(t){let e=this.getState();this._state={...e,globalSearch:t,pagination:{...e.pagination,page:1}},this._debouncedFetch()}setFilters(t){let e=this.getState();this._state={...e,filters:t,pagination:{...e.pagination,page:1}},this._debouncedFetch()}setPage(t){let e=this.getState();this._state={...e,pagination:{...e.pagination,page:t}},this._fetchFromServer()}setPerPage(t){let e=this.getState();this._state={...e,pagination:{...e.pagination,perPage:t,page:1}},this._fetchFromServer()}_debouncedFetch(){this._fetchDebounceTimer&&clearTimeout(this._fetchDebounceTimer),this._fetchDebounceTimer=setTimeout(()=>this._fetchFromServer(),300)}async _fetchFromServer(){this._abortController&&this._abortController.abort(),this._abortController=new AbortController;let t=this.getState();this.setLoading(!0),this.setError(null);let e=++this._drawCounter,s={draw:e,start:(t.pagination.page-1)*t.pagination.perPage,length:t.pagination.perPage,search:{value:t.globalSearch,regex:!1},order:t.sort.map(a=>({column:this._serverColumns.findIndex(i=>i.data===a.column),dir:a.direction})),columns:this._serverColumns.map(a=>({...a,search:{value:t.filters.find(i=>i.column===a.data)?.value??"",regex:!1}}))};try{let a;if(this._serverMethod==="POST")a=await fetch(this._serverUrl,{method:"POST",headers:this._buildHeaders({"Content-Type":"application/json"}),body:JSON.stringify(s),signal:this._abortController.signal});else{let o=new URLSearchParams;o.set("draw",String(s.draw)),o.set("start",String(s.start)),o.set("length",String(s.length)),o.set("search[value]",s.search.value),o.set("search[regex]",String(s.search.regex)),s.order.forEach((r,n)=>{o.set(`order[${n}][column]`,String(r.column)),o.set(`order[${n}][dir]`,r.dir)}),s.columns.forEach((r,n)=>{o.set(`columns[${n}][data]`,r.data),o.set(`columns[${n}][name]`,r.name),o.set(`columns[${n}][searchable]`,String(r.searchable)),o.set(`columns[${n}][orderable]`,String(r.orderable)),o.set(`columns[${n}][search][value]`,r.search.value),o.set(`columns[${n}][search][regex]`,String(r.search.regex))});let u=`${this._serverUrl}?${o.toString()}`;a=await fetch(u,{signal:this._abortController.signal})}if(!a.ok)throw new Error(`Server responded with ${a.status}`);let i=await a.json();i.draw===e&&this.setServerResponse(i)}catch(a){if(a.name==="AbortError")return;this.setLoading(!1),this.setError(a.message??"Failed to fetch data")}}async initialFetch(){await this._fetchFromServer()}destroy(){this._abortController&&this._abortController.abort(),this._fetchDebounceTimer&&clearTimeout(this._fetchDebounceTimer)}};function x(c){if(c==null)return"";let t=String(c);return t.includes(",")||t.includes('"')||t.includes(`
2
- `)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function T(c,t){let e=t.filter(i=>i.visible!==!1),s=e.map(i=>x(i.header)).join(","),a=c.map(i=>e.map(o=>x(i[o.key])).join(","));return"\uFEFF"+[s,...a].join(`\r
3
- `)}function D(c,t="export.csv"){let e=new Blob([c],{type:"text/csv;charset=utf-8;"});w(e,t)}function w(c,t){let e=URL.createObjectURL(c),s=document.createElement("a");s.href=e,s.download=t,document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(e)}async function R(c,t){let e=t.filter(o=>o.visible!==!1),s=e.map(o=>o.header).join(" "),a=c.map(o=>e.map(u=>{let r=o[u.key];return r==null?"":String(r)}).join(" ")),i=[s,...a].join(`
4
- `);await navigator.clipboard.writeText(i)}function b(c,t,e){let s=t.filter(r=>r.visible!==!1),a=s.map(r=>`<th style="border:1px solid #ddd;padding:8px 12px;text-align:left;background:#f5f5f5;font-weight:600;">${_(r.header)}</th>`).join(""),i=c.map(r=>`<tr>${s.map(d=>{let l=r[d.key];return`<td style="border:1px solid #ddd;padding:8px 12px;">${_(l==null?"":String(l))}</td>`}).join("")}</tr>`).join(""),o=`<!DOCTYPE html>
1
+ var m=class{_state;_listeners=new Set;_columns=[];_rowIdFn;_stateSaveKey=null;_lastSelectedId=null;_paginate=!0;constructor(t){this._columns=t.columns,this._stateSaveKey=t.stateSaveKey??null,this._paginate=t.paginate!==!1,this._rowIdFn=typeof t.rowId=="function"?t.rowId:s=>s[t.rowId??"id"];let e=this._loadState();this._state={allRows:t.data??[],filteredRows:[],sortedRows:[],paginatedRows:[],sort:e?.sort??[],filters:e?.filters??[],globalSearch:e?.globalSearch??"",pagination:{page:e?.page??1,perPage:t.perPage??15,total:0,lastPage:1},selectedIds:new Set,columnVisibility:e?.columnVisibility??Object.fromEntries(t.columns.map(s=>[s.key,s.visible!==!1])),columnOrder:e?.columnOrder??t.columns.map(s=>s.key),loading:!1,error:null,editingRowId:null,editingColumn:null,editorMode:null,formData:{},validationErrors:{},draw:0,excelFocusedCell:null,excelEditingCell:null,excelEditValue:""},this._recompute()}subscribe(t){return this._listeners.add(t),()=>this._listeners.delete(t)}getState(){return this._state}_notify(){for(let t of this._listeners)t()}_saveState(){if(this._stateSaveKey)try{let t={sort:this._state.sort,filters:this._state.filters,globalSearch:this._state.globalSearch,page:this._state.pagination.page,columnVisibility:this._state.columnVisibility,columnOrder:this._state.columnOrder};localStorage.setItem(this._stateSaveKey,JSON.stringify(t))}catch{}}_loadState(){if(!this._stateSaveKey)return null;try{let t=localStorage.getItem(this._stateSaveKey);return t?JSON.parse(t):null}catch{return null}}setData(t){this._state={...this._state,allRows:t},this._recompute()}setSort(t){this._state={...this._state,sort:t,pagination:{...this._state.pagination,page:1}},this._recompute(),this._saveState()}toggleSort(t,e=!1){let s=this._state.sort.find(i=>i.column===t),a;s?s.direction==="asc"?a=e?this._state.sort.map(i=>i.column===t?{...i,direction:"desc"}:i):[{column:t,direction:"desc"}]:a=e?this._state.sort.filter(i=>i.column!==t):[]:a=e?[...this._state.sort,{column:t,direction:"asc"}]:[{column:t,direction:"asc"}],this.setSort(a)}setGlobalSearch(t){this._state={...this._state,globalSearch:t,pagination:{...this._state.pagination,page:1}},this._recompute(),this._saveState()}setFilters(t){this._state={...this._state,filters:t,pagination:{...this._state.pagination,page:1}},this._recompute(),this._saveState()}setColumnFilter(t,e,s="like"){let a=this._state.filters.filter(i=>i.column!==t);e!==""&&e!==null&&e!==void 0&&a.push({column:t,value:e,operator:s}),this.setFilters(a)}setPage(t){let e=this._state.pagination.lastPage,s=Math.max(1,Math.min(t,e));this._state={...this._state,pagination:{...this._state.pagination,page:s}},this._recompute(),this._saveState()}setPerPage(t){this._state={...this._state,pagination:{...this._state.pagination,perPage:t,page:1}},this._recompute(),this._saveState()}toggleColumnVisibility(t){let e={...this._state.columnVisibility};e[t]=!e[t],this._state={...this._state,columnVisibility:e},this._notify(),this._saveState()}setColumnVisibility(t){this._state={...this._state,columnVisibility:t},this._notify(),this._saveState()}reorderColumns(t){this._state={...this._state,columnOrder:t},this._notify(),this._saveState()}getRowId(t){return this._rowIdFn(t)}toggleSelect(t){let e=new Set(this._state.selectedIds);e.has(t)?e.delete(t):e.add(t),this._lastSelectedId=t,this._state={...this._state,selectedIds:e},this._notify()}getLastSelectedId(){return this._lastSelectedId}selectSingle(t){this._state={...this._state,selectedIds:new Set([t])},this._notify()}selectAll(){let t=this._state.filteredRows.map(e=>this.getRowId(e));this._state={...this._state,selectedIds:new Set(t)},this._notify()}deselectAll(){this._state={...this._state,selectedIds:new Set},this._notify()}selectRange(t,e){let s=this._state.sortedRows,a=s.findIndex(n=>this.getRowId(n)===t),i=s.findIndex(n=>this.getRowId(n)===e);if(a===-1||i===-1)return;let o=Math.min(a,i),d=Math.max(a,i),r=new Set(this._state.selectedIds);for(let n=o;n<=d;n++)r.add(this.getRowId(s[n]));this._state={...this._state,selectedIds:r},this._notify()}getSelectedRows(){return this._state.allRows.filter(t=>this._state.selectedIds.has(this.getRowId(t)))}openEditor(t,e,s){let a=t!==null?this._state.allRows.find(o=>this.getRowId(o)===t):null,i=a?{...a}:{};this._state={...this._state,editingRowId:t,editingColumn:e,editorMode:s,formData:i,validationErrors:{}},this._notify()}closeEditor(){this._state={...this._state,editingRowId:null,editingColumn:null,editorMode:null,formData:{},validationErrors:{}},this._notify()}setFormField(t,e){this._state={...this._state,formData:{...this._state.formData,[t]:e}},this._notify()}setValidationErrors(t){this._state={...this._state,validationErrors:t},this._notify()}setLoading(t){this._state={...this._state,loading:t},this._notify()}setError(t){this._state={...this._state,error:t},this._notify()}setServerResponse(t){this._state={...this._state,allRows:t.data,filteredRows:t.data,sortedRows:t.data,paginatedRows:t.data,loading:!1,draw:t.draw,pagination:{...this._state.pagination,total:t.recordsFiltered,lastPage:Math.ceil(t.recordsFiltered/this._state.pagination.perPage)||1}},this._notify()}resetState(){if(this._state={...this._state,sort:[],filters:[],globalSearch:"",pagination:{...this._state.pagination,page:1},selectedIds:new Set},this._recompute(),this._stateSaveKey)try{localStorage.removeItem(this._stateSaveKey)}catch{}}focusCell(t,e){this._state={...this._state,excelFocusedCell:{rowIndex:t,columnKey:e}},this._notify()}startCellEdit(){let t=this._state.excelFocusedCell;if(!t)return;let e=this._state.paginatedRows[t.rowIndex];if(!e)return;let s=this._columns.find(a=>a.key===t.columnKey);!s||s.editable===!1||(this._state={...this._state,excelEditingCell:{...t},excelEditValue:e[t.columnKey]!=null?String(e[t.columnKey]):""},this._notify())}setExcelEditValue(t){this._state={...this._state,excelEditValue:t}}commitCellEdit(){let t=this._state.excelEditingCell;if(!t)return null;let e=this._state.paginatedRows[t.rowIndex];if(!e)return this.cancelCellEdit(),null;let s=this._columns.find(o=>o.key===t.columnKey),a=e[t.columnKey],i=this._state.excelEditValue;return s?.type==="number"?i=i===""?null:Number(i):s?.type==="boolean"?i=i==="true"||i==="1":i===""&&(i=null),this._state={...this._state,excelEditingCell:null,excelEditValue:""},i===a||i===null&&a==null?(this._notify(),null):(e[t.columnKey]=i,this._notify(),{row:e,columnKey:t.columnKey,oldValue:a,newValue:i})}cancelCellEdit(){this._state={...this._state,excelEditingCell:null,excelEditValue:""},this._notify()}clearExcelFocus(){this._state={...this._state,excelFocusedCell:null,excelEditingCell:null,excelEditValue:""},this._notify()}getVisibleColumns(){return this._state.columnOrder.filter(t=>this._state.columnVisibility[t]!==!1).map(t=>this._columns.find(e=>e.key===t)).filter(Boolean)}navigateCell(t){let e=this._state.excelFocusedCell,s=this._state.paginatedRows,a=this.getVisibleColumns();if(a.length===0)return null;if(!e){let r=a.find(n=>n.editable!==!1);return r&&s.length>0&&this.focusCell(0,r.key),null}let{rowIndex:i,columnKey:o}=e,d=a.findIndex(r=>r.key===o);if(d===-1)return null;switch(t){case"left":{for(let r=d-1;r>=0;r--)if(a[r].editable!==!1)return this.focusCell(i,a[r].key),null;for(let r=a.length-1;r>=0;r--)if(a[r].editable!==!1)return i>0?(this.focusCell(i-1,a[r].key),null):"page-prev";return null}case"right":{for(let r=d+1;r<a.length;r++)if(a[r].editable!==!1)return this.focusCell(i,a[r].key),null;for(let r=0;r<a.length;r++)if(a[r].editable!==!1)return i<s.length-1?(this.focusCell(i+1,a[r].key),null):"page-next";return null}case"up":return i>0?(this.focusCell(i-1,o),null):"page-prev";case"down":return i<s.length-1?(this.focusCell(i+1,o),null):"page-next"}}_recompute(){let t=[...this._state.allRows];if(this._state.globalSearch){let n=this._state.globalSearch.toLowerCase(),u=this._columns.filter(l=>l.searchable!==!1);t=t.filter(l=>u.some(p=>{let h=l[p.key];return h!=null&&String(h).toLowerCase().includes(n)}))}for(let n of this._state.filters)t=t.filter(u=>{let l=u[n.column];switch(n.operator){case"=":return l==n.value;case"!=":return l!=n.value;case">":return l>n.value;case"<":return l<n.value;case">=":return l>=n.value;case"<=":return l<=n.value;case"like":return l!=null&&String(l).toLowerCase().includes(String(n.value).toLowerCase());case"not_like":return l==null||!String(l).toLowerCase().includes(String(n.value).toLowerCase());case"in":return Array.isArray(n.value)&&n.value.includes(l);case"between":return Array.isArray(n.value)&&l>=n.value[0]&&l<=n.value[1];case"null":return l==null;case"not_null":return l!=null;default:return!0}});let e=t;this._state.sort.length>0&&(t=[...t].sort((n,u)=>{for(let l of this._state.sort){let p=this._columns.find(E=>E.key===l.column),h=n[l.column],g=u[l.column],f=0;if(h==null?f=-1:g==null?f=1:p?.type==="number"?f=Number(h)-Number(g):p?.type==="date"?f=new Date(h).getTime()-new Date(g).getTime():p?.type==="boolean"?f=(h?1:0)-(g?1:0):f=String(h).localeCompare(String(g)),f!==0)return l.direction==="desc"?-f:f}return 0}));let s=t,a=e.length,i=this._state.pagination.perPage,o,d,r;if(this._paginate){r=Math.ceil(a/i)||1,d=Math.min(this._state.pagination.page,r);let n=(d-1)*i;o=s.slice(n,n+i)}else o=s,d=1,r=1;this._state={...this._state,filteredRows:e,sortedRows:s,paginatedRows:o,pagination:{page:d,perPage:i,total:a,lastPage:r}},this._notify()}};function F(c="XSRF-TOKEN"){if(typeof document>"u")return null;let t=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),e=document.cookie.match(new RegExp(`(?:^|;\\s*)${t}=([^;]*)`));return e?decodeURIComponent(e[1]):null}var y=class extends m{_serverUrl;_serverMethod;_drawCounter=0;_abortController=null;_fetchDebounceTimer=null;_serverColumns;_csrfCookieName;_csrfHeaderName;constructor(t){super(t),this._serverUrl=t.serverUrl,this._serverMethod=t.serverMethod??"GET",this._csrfCookieName=t.csrfCookieName??"XSRF-TOKEN",this._csrfHeaderName=t.csrfHeaderName??"X-CSRF-Token",this._serverColumns=t.columns.map(e=>({data:e.key,name:e.key,searchable:e.searchable!==!1,orderable:e.sortable!==!1}))}_buildHeaders(t={}){let e={...t},s=F(this._csrfCookieName);return s&&(e[this._csrfHeaderName]=s),e}setSort(t){let e=this.getState();this._state={...e,sort:t,pagination:{...e.pagination,page:1}},this._debouncedFetch()}setGlobalSearch(t){let e=this.getState();this._state={...e,globalSearch:t,pagination:{...e.pagination,page:1}},this._debouncedFetch()}setFilters(t){let e=this.getState();this._state={...e,filters:t,pagination:{...e.pagination,page:1}},this._debouncedFetch()}setPage(t){let e=this.getState();this._state={...e,pagination:{...e.pagination,page:t}},this._fetchFromServer()}setPerPage(t){let e=this.getState();this._state={...e,pagination:{...e.pagination,perPage:t,page:1}},this._fetchFromServer()}_debouncedFetch(){this._fetchDebounceTimer&&clearTimeout(this._fetchDebounceTimer),this._fetchDebounceTimer=setTimeout(()=>this._fetchFromServer(),300)}async _fetchFromServer(){this._abortController&&this._abortController.abort(),this._abortController=new AbortController;let t=this.getState();this.setLoading(!0),this.setError(null);let e=++this._drawCounter,s={draw:e,start:(t.pagination.page-1)*t.pagination.perPage,length:t.pagination.perPage,search:{value:t.globalSearch,regex:!1},order:t.sort.map(a=>({column:this._serverColumns.findIndex(i=>i.data===a.column),dir:a.direction})),columns:this._serverColumns.map(a=>({...a,search:{value:t.filters.find(i=>i.column===a.data)?.value??"",regex:!1}}))};try{let a;if(this._serverMethod==="POST")a=await fetch(this._serverUrl,{method:"POST",headers:this._buildHeaders({"Content-Type":"application/json"}),body:JSON.stringify(s),signal:this._abortController.signal});else{let o=new URLSearchParams;o.set("draw",String(s.draw)),o.set("start",String(s.start)),o.set("length",String(s.length)),o.set("search[value]",s.search.value),o.set("search[regex]",String(s.search.regex)),s.order.forEach((r,n)=>{o.set(`order[${n}][column]`,String(r.column)),o.set(`order[${n}][dir]`,r.dir)}),s.columns.forEach((r,n)=>{o.set(`columns[${n}][data]`,r.data),o.set(`columns[${n}][name]`,r.name),o.set(`columns[${n}][searchable]`,String(r.searchable)),o.set(`columns[${n}][orderable]`,String(r.orderable)),o.set(`columns[${n}][search][value]`,r.search.value),o.set(`columns[${n}][search][regex]`,String(r.search.regex))});let d=`${this._serverUrl}?${o.toString()}`;a=await fetch(d,{signal:this._abortController.signal})}if(!a.ok)throw new Error(`Server responded with ${a.status}`);let i=await a.json();i.draw===e&&this.setServerResponse(i)}catch(a){if(a.name==="AbortError")return;this.setLoading(!1),this.setError(a.message??"Failed to fetch data")}}async initialFetch(){await this._fetchFromServer()}destroy(){this._abortController&&this._abortController.abort(),this._fetchDebounceTimer&&clearTimeout(this._fetchDebounceTimer)}};function v(c){if(c==null)return"";let t=String(c);return t.includes(",")||t.includes('"')||t.includes(`
2
+ `)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function C(c,t){let e=t.filter(i=>i.visible!==!1),s=e.map(i=>v(i.header)).join(","),a=c.map(i=>e.map(o=>v(i[o.key])).join(","));return"\uFEFF"+[s,...a].join(`\r
3
+ `)}function x(c,t="export.csv"){let e=new Blob([c],{type:"text/csv;charset=utf-8;"});S(e,t)}function S(c,t){let e=URL.createObjectURL(c),s=document.createElement("a");s.href=e,s.download=t,document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(e)}async function T(c,t){let e=t.filter(o=>o.visible!==!1),s=e.map(o=>o.header).join(" "),a=c.map(o=>e.map(d=>{let r=o[d.key];return r==null?"":String(r)}).join(" ")),i=[s,...a].join(`
4
+ `);await navigator.clipboard.writeText(i)}function b(c,t,e){let s=t.filter(r=>r.visible!==!1),a=s.map(r=>`<th style="border:1px solid #ddd;padding:8px 12px;text-align:left;background:#f5f5f5;font-weight:600;">${_(r.header)}</th>`).join(""),i=c.map(r=>`<tr>${s.map(u=>{let l=r[u.key];return`<td style="border:1px solid #ddd;padding:8px 12px;">${_(l==null?"":String(l))}</td>`}).join("")}</tr>`).join(""),o=`<!DOCTYPE html>
5
5
  <html><head>
6
6
  <title>${_(e??"Data Export")}</title>
7
7
  <style>
@@ -16,4 +16,4 @@ ${e?`<h1>${_(e)}</h1>`:""}
16
16
  <thead><tr>${a}</tr></thead>
17
17
  <tbody>${i}</tbody>
18
18
  </table>
19
- </body></html>`,u=window.open("","_blank");u&&(u.document.write(o),u.document.close(),u.focus(),setTimeout(()=>u.print(),250))}function _(c){return c.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function E(c,t,e="export.xlsx"){let s;try{s=await import("exceljs")}catch{throw new Error("exceljs is required for Excel export. Install it: npm install exceljs")}let a=new s.Workbook,i=a.addWorksheet("Data"),o=t.filter(d=>d.visible!==!1);i.columns=o.map(d=>({header:d.header,key:d.key,width:20}));let u=i.getRow(1);u.font={bold:!0},u.fill={type:"pattern",pattern:"solid",fgColor:{argb:"FFF0F0F0"}};for(let d of c){let l={};for(let p of o)l[p.key]=d[p.key]??"";i.addRow(l)}let r=await a.xlsx.writeBuffer(),n=new Blob([r],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});w(n,e)}function F(c,t,e="export.pdf"){b(c,t,e.replace(".pdf",""))}var C=class{async export(t,e,s,a){switch(t){case"csv":{let i=T(e,s);D(i,a??"export.csv");break}case"excel":await E(e,s,a??"export.xlsx");break;case"pdf":F(e,s,a??"export.pdf");break;case"clipboard":await R(e,s);break;case"print":b(e,s);break}}};export{m as DataTableStore,C as ExportManager,v as ServerDataTableStore,S as SvelarDatatablePlugin};
19
+ </body></html>`,d=window.open("","_blank");d&&(d.document.write(o),d.document.close(),d.focus(),setTimeout(()=>d.print(),250))}function _(c){return c.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function R(c,t,e="export.xlsx"){let s;try{s=await import("exceljs")}catch{throw new Error("exceljs is required for Excel export. Install it: npm install exceljs")}let a=new s.Workbook,i=a.addWorksheet("Data"),o=t.filter(u=>u.visible!==!1);i.columns=o.map(u=>({header:u.header,key:u.key,width:20}));let d=i.getRow(1);d.font={bold:!0},d.fill={type:"pattern",pattern:"solid",fgColor:{argb:"FFF0F0F0"}};for(let u of c){let l={};for(let p of o)l[p.key]=u[p.key]??"";i.addRow(l)}let r=await a.xlsx.writeBuffer(),n=new Blob([r],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});S(n,e)}function D(c,t,e="export.pdf"){b(c,t,e.replace(".pdf",""))}var w=class{async export(t,e,s,a){switch(t){case"csv":{let i=C(e,s);x(i,a??"export.csv");break}case"excel":await R(e,s,a??"export.xlsx");break;case"pdf":D(e,s,a??"export.pdf");break;case"clipboard":await T(e,s);break;case"print":b(e,s);break}}};export{m as DataTableStore,w as ExportManager,y as ServerDataTableStore};
@@ -1,3 +1,4 @@
1
+ export { SvelarDatatablePlugin } from '../SvelarDatatablePlugin.js';
1
2
  export { DataTableService, type DataTableServiceOptions } from './DataTableService.js';
2
3
  export { DataTableController } from './DataTableController.js';
3
4
  export { parseDataTableRequest, parseDataTableRequestFromBody } from './DataTableRequest.js';
@@ -1 +1 @@
1
- var h=class{_model;_searchable=[];_orderable=[];_baseQueryFn=null;_scopes={};_computedColumns={};_activeScopes=[];constructor(e,t){this._model=e,t?.searchable&&(this._searchable=t.searchable),t?.orderable&&(this._orderable=t.orderable),t?.baseQuery&&(this._baseQueryFn=t.baseQuery),t?.scopes&&(this._scopes=t.scopes),t?.computedColumns&&(this._computedColumns=t.computedColumns)}searchable(e){return this._searchable=e,this}orderable(e){return this._orderable=e,this}setBaseQuery(e){return this._baseQueryFn=e,this}addScope(e,t){return this._scopes[e]=t,this}applyScope(e){return this._activeScopes.push(e),this}addComputedColumn(e,t){return this._computedColumns[e]=t,this}async process(e){try{let t=this._model.query();this._baseQueryFn&&this._baseQueryFn(t);let u=await t.count(),a=this._model.query();this._baseQueryFn&&this._baseQueryFn(a);for(let r of this._activeScopes){let o=this._scopes[r];o&&o(a)}for(let[r,o]of Object.entries(this._computedColumns))a=a.selectRaw(`(${o}) as ${r}`);if(e.search.value){let r=e.search.value,o=this._searchable.length>0?this._searchable:e.columns.filter(i=>i.searchable).map(i=>i.data);o.length>0&&(a=a.whereNested(i=>{for(let l=0;l<o.length;l++){let m=o[l];l===0?i.where(m,"LIKE",`%${r}%`):i.orWhere(m,"LIKE",`%${r}%`)}}))}for(let r of e.columns)r.search.value&&r.searchable&&(a=a.where(r.data,"LIKE",`%${r.search.value}%`));let c=await a.clone().count();for(let r of e.order){let o=e.columns[r.column];o&&(this._orderable.length>0?this._orderable:e.columns.filter(l=>l.orderable).map(l=>l.data)).includes(o.data)&&(a=a.orderBy(o.data,r.dir))}a=a.offset(e.start).limit(e.length);let d=await a.get();return{draw:e.draw,recordsTotal:u,recordsFiltered:c,data:d}}catch(t){return{draw:e.draw,recordsTotal:0,recordsFiltered:0,data:[],error:t.message??"Server error"}}}};function p(s){let e=parseInt(s.get("draw")??"1",10),t=parseInt(s.get("start")??"0",10),u=parseInt(s.get("length")??"15",10),a={value:s.get("search[value]")??"",regex:s.get("search[regex]")==="true"},n=[],c=0;for(;s.has(`order[${c}][column]`);)n.push({column:parseInt(s.get(`order[${c}][column]`)??"0",10),dir:s.get(`order[${c}][dir]`)??"asc"}),c++;let d=[],r=0;for(;s.has(`columns[${r}][data]`);)d.push({data:s.get(`columns[${r}][data]`)??"",name:s.get(`columns[${r}][name]`)??"",searchable:s.get(`columns[${r}][searchable]`)!=="false",orderable:s.get(`columns[${r}][orderable]`)!=="false",search:{value:s.get(`columns[${r}][search][value]`)??"",regex:s.get(`columns[${r}][search][regex]`)==="true"}}),r++;return{draw:e,start:t,length:u,search:a,order:n,columns:d}}async function y(s){return await s.json()}var b=class{static async handle(e,t,u){try{let a=new h(t,u),n;e.request.method==="POST"?n=await y(e.request):n=p(e.url.searchParams);let c=await a.process(n);return new Response(JSON.stringify(c),{status:200,headers:{"Content-Type":"application/json"}})}catch(a){let n={draw:0,recordsTotal:0,recordsFiltered:0,data:[],error:a.message??"Internal server error"};return new Response(JSON.stringify(n),{status:500,headers:{"Content-Type":"application/json"}})}}};export{b as DataTableController,h as DataTableService,p as parseDataTableRequest,y as parseDataTableRequestFromBody};
1
+ var p={prefix:"/api",defaults:{perPage:15,perPageOptions:[10,15,25,50,100],searchDebounceMs:300,sortable:!0,searchable:!0,paginate:!0,selectable:"none",striped:!0,hover:!0,bordered:!1,compact:!1,responsive:!0,virtualScroll:!1,virtualRowHeight:48}},b=class{_config;constructor(e={}){this._config={...p,...e,defaults:{...p.defaults,...e.defaults}}}get name(){return"svelar-datatable"}get config(){return this._config}static defaults(){return{...p.defaults}}async publishables(){let{fileURLToPath:e}=await import("url"),{dirname:t,join:c}=await import("path"),r=t(e(import.meta.url));return{routes:[{source:c(r,"publishable/routes/datatable.ts"),dest:"src/routes/api/datatable/+server.ts",type:"asset"}]}}};var d=class{_model;_searchable=[];_orderable=[];_baseQueryFn=null;_scopes={};_computedColumns={};_activeScopes=[];constructor(e,t){this._model=e,t?.searchable&&(this._searchable=t.searchable),t?.orderable&&(this._orderable=t.orderable),t?.baseQuery&&(this._baseQueryFn=t.baseQuery),t?.scopes&&(this._scopes=t.scopes),t?.computedColumns&&(this._computedColumns=t.computedColumns)}searchable(e){return this._searchable=e,this}orderable(e){return this._orderable=e,this}setBaseQuery(e){return this._baseQueryFn=e,this}addScope(e,t){return this._scopes[e]=t,this}applyScope(e){return this._activeScopes.push(e),this}addComputedColumn(e,t){return this._computedColumns[e]=t,this}async process(e){try{let t=this._model.query();this._baseQueryFn&&this._baseQueryFn(t);let c=await t.count(),r=this._model.query();this._baseQueryFn&&this._baseQueryFn(r);for(let a of this._activeScopes){let o=this._scopes[a];o&&o(r)}for(let[a,o]of Object.entries(this._computedColumns))r=r.selectRaw(`(${o}) as ${a}`);if(e.search.value){let a=e.search.value,o=this._searchable.length>0?this._searchable:e.columns.filter(u=>u.searchable).map(u=>u.data);o.length>0&&(r=r.whereNested(u=>{for(let i=0;i<o.length;i++){let m=o[i];i===0?u.where(m,"LIKE",`%${a}%`):u.orWhere(m,"LIKE",`%${a}%`)}}))}for(let a of e.columns)a.search.value&&a.searchable&&(r=r.where(a.data,"LIKE",`%${a.search.value}%`));let l=await r.clone().count();for(let a of e.order){let o=e.columns[a.column];o&&(this._orderable.length>0?this._orderable:e.columns.filter(i=>i.orderable).map(i=>i.data)).includes(o.data)&&(r=r.orderBy(o.data,a.dir))}r=r.offset(e.start).limit(e.length);let h=await r.get();return{draw:e.draw,recordsTotal:c,recordsFiltered:l,data:h}}catch(t){return{draw:e.draw,recordsTotal:0,recordsFiltered:0,data:[],error:t.message??"Server error"}}}};function f(s){let e=parseInt(s.get("draw")??"1",10),t=parseInt(s.get("start")??"0",10),c=parseInt(s.get("length")??"15",10),r={value:s.get("search[value]")??"",regex:s.get("search[regex]")==="true"},n=[],l=0;for(;s.has(`order[${l}][column]`);)n.push({column:parseInt(s.get(`order[${l}][column]`)??"0",10),dir:s.get(`order[${l}][dir]`)??"asc"}),l++;let h=[],a=0;for(;s.has(`columns[${a}][data]`);)h.push({data:s.get(`columns[${a}][data]`)??"",name:s.get(`columns[${a}][name]`)??"",searchable:s.get(`columns[${a}][searchable]`)!=="false",orderable:s.get(`columns[${a}][orderable]`)!=="false",search:{value:s.get(`columns[${a}][search][value]`)??"",regex:s.get(`columns[${a}][search][regex]`)==="true"}}),a++;return{draw:e,start:t,length:c,search:r,order:n,columns:h}}async function y(s){return await s.json()}var g=class{static async handle(e,t,c){try{let r=new d(t,c),n;e.request.method==="POST"?n=await y(e.request):n=f(e.url.searchParams);let l=await r.process(n);return new Response(JSON.stringify(l),{status:200,headers:{"Content-Type":"application/json"}})}catch(r){let n={draw:0,recordsTotal:0,recordsFiltered:0,data:[],error:r.message??"Internal server error"};return new Response(JSON.stringify(n),{status:500,headers:{"Content-Type":"application/json"}})}}};export{g as DataTableController,d as DataTableService,b as SvelarDatatablePlugin,f as parseDataTableRequest,y as parseDataTableRequestFromBody};
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "@beeblock/svelar-datatable",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Full-featured DataTable plugin for Svelar — sorting, searching, pagination, inline editing, export, and server-side processing",
5
5
  "type": "module",
6
- "keywords": ["svelar-plugin", "datatable", "svelte", "sveltekit", "data-grid"],
6
+ "keywords": [
7
+ "svelar-plugin",
8
+ "datatable",
9
+ "svelte",
10
+ "sveltekit",
11
+ "data-grid"
12
+ ],
7
13
  "license": "MIT",
8
14
  "main": "dist/index.js",
9
15
  "types": "dist/index.d.ts",
@@ -24,7 +30,12 @@
24
30
  "./ui": "./src/ui/index.ts",
25
31
  "./ui/*": "./src/ui/*"
26
32
  },
27
- "files": ["dist", "src/ui", "LICENSE"],
33
+ "files": [
34
+ "dist",
35
+ "src/ui",
36
+ "src/publishable",
37
+ "LICENSE"
38
+ ],
28
39
  "scripts": {
29
40
  "build": "tsup && (tsc --emitDeclarationOnly || echo 'Warning: tsc declaration emit had errors')",
30
41
  "dev": "tsup --watch"
@@ -34,8 +45,12 @@
34
45
  "svelte": "^5.0.0"
35
46
  },
36
47
  "peerDependenciesMeta": {
37
- "exceljs": { "optional": true },
38
- "@beeblock/svelar": { "optional": false }
48
+ "exceljs": {
49
+ "optional": true
50
+ },
51
+ "@beeblock/svelar": {
52
+ "optional": false
53
+ }
39
54
  },
40
55
  "devDependencies": {
41
56
  "tsup": "^8.5.0",
@@ -0,0 +1,30 @@
1
+ // API routes for @beeblock/svelar-datatable
2
+ // Copy to: src/routes/api/datatable/+server.ts
3
+
4
+ import { DataTableController } from '@beeblock/svelar-datatable/server';
5
+ import type { RequestHandler } from './$types';
6
+
7
+ // Replace `YourModel` with your actual Eloquent-style model import.
8
+ // Options let you customise searchable columns, sorting, etc.
9
+ //
10
+ // import { User } from '$lib/models/User';
11
+ //
12
+ // export const GET: RequestHandler = (event) =>
13
+ // DataTableController.handle(event, User, {
14
+ // searchable: ['name', 'email'],
15
+ // sortable: ['name', 'email', 'created_at'],
16
+ // });
17
+ //
18
+ // POST is also supported for complex filter payloads:
19
+ // export const POST: RequestHandler = (event) =>
20
+ // DataTableController.handle(event, User);
21
+
22
+ export const GET: RequestHandler = (event) => {
23
+ // TODO: replace with your model and options
24
+ throw new Error('Configure your model in this route before using DataTableController.handle()');
25
+ };
26
+
27
+ export const POST: RequestHandler = (event) => {
28
+ // TODO: replace with your model and options
29
+ throw new Error('Configure your model in this route before using DataTableController.handle()');
30
+ };