@bexis2/bexis2-core-ui 0.3.4 → 0.3.6

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
@@ -1,5 +1,18 @@
1
1
  # bexis-core-ui
2
2
 
3
+ ## 0.3.6
4
+
5
+ - FileUpload
6
+ - add progressbar during upload
7
+ - Table
8
+ - fix update issue with first row entry
9
+
10
+ ## 0.3.5
11
+
12
+ - listeItemType
13
+ - add description
14
+
15
+
3
16
  ## 0.3.4
4
17
 
5
18
  - Page
@@ -9,10 +9,12 @@ import { Api } from "../../services/Api.js";
9
9
  export let id = 0;
10
10
  export let version = 1;
11
11
  import { onMount } from "svelte";
12
+ import { ProgressBar } from "@skeletonlabs/skeleton";
12
13
  export let start = "";
13
14
  export let submit = "";
14
15
  export let context = "";
15
16
  export let data;
17
+ let isUploading = false;
16
18
  $:
17
19
  model = data;
18
20
  $:
@@ -72,6 +74,7 @@ function getErrorMessage(rejected) {
72
74
  }
73
75
  async function handleSubmit() {
74
76
  dispatch("submit");
77
+ isUploading = true;
75
78
  let url = submit + "?id=" + id;
76
79
  if (files.accepted.length > 0) {
77
80
  const formData = new FormData();
@@ -89,6 +92,7 @@ async function handleSubmit() {
89
92
  files.accepted = [];
90
93
  }
91
94
  }
95
+ isUploading = false;
92
96
  }
93
97
  </script>
94
98
 
@@ -115,6 +119,9 @@ async function handleSubmit() {
115
119
  {/if}
116
120
  </p>
117
121
  </DropZone>
122
+ {#if isUploading}
123
+ <ProgressBar value={undefined}/>
124
+ {/if}
118
125
  </div>
119
126
 
120
127
  <button id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
@@ -1,382 +1,8 @@
1
- <script>import { createEventDispatcher } from "svelte";
2
- import { createTable, Subscribe, Render, createRender } from "svelte-headless-table";
3
- import {
4
- addSortBy,
5
- addPagination,
6
- addExpandedRows,
7
- addColumnFilters,
8
- addTableFilter,
9
- addDataExport
10
- } from "svelte-headless-table/plugins";
11
- import { computePosition, autoUpdate, offset, shift, flip, arrow } from "@floating-ui/dom";
12
- import { SlideToggle, storePopup } from "@skeletonlabs/skeleton";
13
- storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow });
14
- import TableFilter from "./TableFilter.svelte";
15
- import TablePagination from "./TablePagination.svelte";
16
- import { columnFilter, searchFilter } from "./filter";
1
+ <script>import Table from "./TableContent.svelte";
17
2
  export let config;
18
- let {
19
- id: tableId,
20
- // Unique table ID
21
- data,
22
- // Data store
23
- columns,
24
- // Column configuration
25
- resizable = "none",
26
- // Resizability config
27
- height = null,
28
- // Table height
29
- rowHeight = null,
30
- // Row height
31
- optionsComponent,
32
- // Custom component to render in the last column
33
- defaultPageSize = 10,
34
- // Default page size - number of rows to display per page
35
- toggle = false,
36
- // Whether to display the fitToScreen toggle
37
- pageSizes = [5, 10, 15, 20],
38
- // Page sizes to display in the pagination component
39
- fitToScreen = true,
40
- // Whether to fit the table to the screen,
41
- exportable = false
42
- // Whether to display the export button and enable export functionality
43
- } = config;
44
- const dispatch = createEventDispatcher();
45
- const actionDispatcher = (obj) => dispatch("action", obj);
46
- const table = createTable(data, {
47
- colFilter: addColumnFilters(),
48
- tableFilter: addTableFilter({
49
- fn: searchFilter
50
- }),
51
- sort: addSortBy({ disableMultiSort: true }),
52
- page: addPagination({ initialPageSize: defaultPageSize }),
53
- expand: addExpandedRows(),
54
- export: addDataExport({ format: "csv" })
55
- });
56
- const allCols = {};
57
- $data.forEach((item) => {
58
- Object.keys(item).forEach((key) => {
59
- if (!allCols[key]) {
60
- allCols[key] = {};
61
- }
62
- });
63
- });
64
- const accessors = Object.keys(allCols);
65
- const tableColumns = [
66
- ...accessors.filter((accessor) => {
67
- const key = accessor;
68
- if (columns !== void 0 && key in columns && columns[key].exclude === true) {
69
- return false;
70
- }
71
- return true;
72
- }).map((accessor) => {
73
- const key = accessor;
74
- if (columns !== void 0 && key in columns) {
75
- const {
76
- header,
77
- // Custom header to display
78
- colFilterFn,
79
- // Custom column filter function
80
- colFilterComponent,
81
- // Custom column filter component
82
- instructions,
83
- // Custom instructions for the column cells (sorting, filtering, searching, rendering)
84
- disableFiltering = false,
85
- // Whether to disable filtering for the column
86
- disableSorting = false
87
- // Whether to disable sorting for the column
88
- } = columns[key];
89
- const { toSortableValueFn, toFilterableValueFn, toStringFn, renderComponent } = instructions ?? {};
90
- return table.column({
91
- // If header is not provided, use the key as the header
92
- header: header ?? key,
93
- accessor,
94
- // Render the cell with the provided component, or use the toStringFn if provided, or just use the value
95
- cell: ({ value, row }) => {
96
- return renderComponent ? createRender(renderComponent, { value, row }) : toStringFn ? toStringFn(value) : value;
97
- },
98
- plugins: {
99
- // Sorting config
100
- sort: {
101
- disable: disableSorting,
102
- invert: true,
103
- getSortValue: (row) => {
104
- return toSortableValueFn ? toSortableValueFn(row) : row;
105
- }
106
- },
107
- colFilter: !disableFiltering ? {
108
- fn: ({ filterValue: filterValue2, value }) => {
109
- const val = toFilterableValueFn ? toFilterableValueFn(value) : value;
110
- return colFilterFn ? colFilterFn({ filterValue: filterValue2, value: val }) : columnFilter({ filterValue: filterValue2, value: val });
111
- },
112
- render: ({ filterValue: filterValue2, values, id }) => {
113
- return createRender(colFilterComponent ?? TableFilter, {
114
- filterValue: filterValue2,
115
- id,
116
- tableId,
117
- values,
118
- toFilterableValueFn
119
- });
120
- }
121
- } : void 0,
122
- tableFilter: {
123
- // Search filter config
124
- getFilterValue: (row) => {
125
- return toStringFn ? toStringFn(row) : row;
126
- }
127
- }
128
- }
129
- });
130
- } else {
131
- return table.column({
132
- header: key,
133
- accessor,
134
- cell: ({ value }) => {
135
- return value ? value : "";
136
- },
137
- plugins: {
138
- // Sorting enabled by default
139
- sort: {
140
- invert: true
141
- },
142
- // Filtering enabled by default
143
- colFilter: {
144
- fn: columnFilter,
145
- render: ({ filterValue: filterValue2, values, id }) => createRender(TableFilter, {
146
- filterValue: filterValue2,
147
- id,
148
- tableId,
149
- values
150
- })
151
- }
152
- }
153
- });
154
- }
155
- })
156
- ];
157
- if (optionsComponent !== void 0) {
158
- tableColumns.push(
159
- table.display({
160
- id: "optionsColumn",
161
- header: "",
162
- plugins: {
163
- export: {
164
- exclude: true
165
- }
166
- },
167
- cell: ({ row }, _) => {
168
- return createRender(optionsComponent, {
169
- row: row.isData() ? row.original : null,
170
- dispatchFn: actionDispatcher
171
- });
172
- }
173
- })
174
- );
175
- }
176
- const createdTableColumns = table.createColumns(tableColumns);
177
- const { headerRows, pageRows, tableAttrs, tableBodyAttrs, pluginStates } = table.createViewModel(createdTableColumns);
178
- const { filterValue } = pluginStates.tableFilter;
179
- const { exportedData } = pluginStates.export;
180
- const minWidth = (id) => {
181
- if (columns && id in columns) {
182
- return columns[id].minWidth ?? 0;
183
- }
184
- return 0;
185
- };
186
- const fixedWidth = (id) => {
187
- if (columns && id in columns) {
188
- return columns[id].fixedWidth ?? 0;
189
- }
190
- return 0;
191
- };
192
- const cellStyle = (id) => {
193
- const minW = minWidth(id);
194
- const fixedW = fixedWidth(id);
195
- const styles = [];
196
- minW && styles.push(`min-width: ${minW}px`);
197
- fixedW && styles.push(`width: ${fixedW}px`);
198
- return styles.join(";");
199
- };
200
- const resetResize = () => {
201
- if (resizable === "columns" || resizable === "both") {
202
- $headerRows.forEach((row) => {
203
- row.cells.forEach((cell) => {
204
- const minW = minWidth(cell.id);
205
- const fixedW = fixedWidth(cell.id);
206
- fixedW && document.getElementById(`th-${tableId}-${cell.id}`)?.style.setProperty("width", `${fixedW}px`);
207
- minW && document.getElementById(`th-${tableId}-${cell.id}`)?.style.setProperty("min-width", `${minW}px`);
208
- !minW && !fixedW && document.getElementById(`th-${tableId}-${cell.id}`)?.style.setProperty("width", "auto");
209
- });
210
- });
211
- }
212
- if (resizable === "rows" || resizable === "both") {
213
- $pageRows.forEach((row) => {
214
- row.cells.forEach((cell) => {
215
- document.getElementById(`${tableId}-${cell.id}-${row.id}`)?.style.setProperty("height", "auto");
216
- });
217
- });
218
- }
219
- };
220
- const exportAsCsv = () => {
221
- const anchor = document.createElement("a");
222
- anchor.style.display = "none";
223
- anchor.href = `data:text/csv;charset=utf-8,${encodeURIComponent($exportedData)}`;
224
- anchor.download = `${tableId}.csv`;
225
- document.body.appendChild(anchor);
226
- anchor.click();
227
- document.body.removeChild(anchor);
228
- };
3
+ const data = config.data;
229
4
  </script>
230
5
 
231
- <div class="grid gap-2 overflow-auto" class:w-fit={!fitToScreen} class:w-full={fitToScreen}>
232
- <div class="table-container">
233
- <!-- Enable the search filter if table is not empty -->
234
- {#if $data.length > 0}
235
- <input
236
- class="input p-2 border border-primary-500"
237
- type="text"
238
- bind:value={$filterValue}
239
- placeholder="Search rows..."
240
- id="{tableId}-search"
241
- />
242
- <div class="flex justify-between items-center py-2 w-full">
243
- <div>
244
- <!-- Enable the fitToScreen toggle if toggle === true -->
245
- {#if toggle}
246
- <SlideToggle
247
- name="slider-label"
248
- active="bg-primary-500"
249
- size="sm"
250
- checked={fitToScreen}
251
- id="{tableId}-toggle"
252
- on:change={() => (fitToScreen = !fitToScreen)}>Fit to screen</SlideToggle
253
- >
254
- {/if}
255
- </div>
256
- <div class="flex gap-2">
257
- <!-- Enable the resetResize button if resizable !== 'none' -->
258
- {#if resizable !== 'none'}
259
- <button
260
- type="button"
261
- class="btn btn-sm variant-filled-primary rounded-full order-last"
262
- on:click|preventDefault={resetResize}>Reset sizing</button
263
- >
264
- {/if}
265
- {#if exportable}
266
- <button
267
- type="button"
268
- class="btn btn-sm variant-filled-primary rounded-full order-last"
269
- on:click|preventDefault={exportAsCsv}>Export as CSV</button
270
- >
271
- {/if}
272
- </div>
273
- </div>
274
- {/if}
275
-
276
- <div class="overflow-auto" style="height: {height}px">
277
- <table
278
- {...$tableAttrs}
279
- class="table table-auto table-compact bg-tertiary-500/30 dark:bg-tertiary-900/10 overflow-clip"
280
- id="{tableId}-table"
281
- >
282
- <!-- If table height is provided, making the top row sticky -->
283
- <thead class=" {height != null ? `sticky top-0` : ''}">
284
- {#if $data.length > 0}
285
- {#each $headerRows as headerRow (headerRow.id)}
286
- <Subscribe
287
- rowAttrs={headerRow.attrs()}
288
- let:rowAttrs
289
- rowProps={headerRow.props()}
290
- let:rowProps
291
- >
292
- <tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-500 items-stretch">
293
- {#each headerRow.cells as cell (cell.id)}
294
- <Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
295
- <th
296
- scope="col"
297
- class="!p-2 overflow-auto"
298
- class:resize-x={(resizable === 'columns' || resizable === 'both') &&
299
- !fixedWidth(cell.id)}
300
- {...attrs}
301
- id="th-{tableId}-{cell.id}"
302
- style={cellStyle(cell.id)}
303
- >
304
- <div class="flex justify-between items-center">
305
- <div class="flex gap-1 whitespace-pre-wrap">
306
- <!-- Adding sorting config and styling -->
307
- <span
308
- class:underline={props.sort.order}
309
- class:normal-case={cell.id !== cell.label}
310
- class:cursor-pointer={!props.sort.disabled}
311
- on:click={props.sort.toggle}
312
- on:keydown={props.sort.toggle}
313
- >
314
- {cell.render()}
315
- </span>
316
- <div class="w-2">
317
- {#if props.sort.order === 'asc'}
318
-
319
- {:else if props.sort.order === 'desc'}
320
-
321
- {/if}
322
- </div>
323
- </div>
324
- <!-- Adding column filter config -->
325
- {#if cell.isData()}
326
- {#if props.colFilter?.render}
327
- <div class="">
328
- <Render of={props.colFilter.render} />
329
- </div>
330
- {/if}
331
- {/if}
332
- </div>
333
- </th>
334
- </Subscribe>
335
- {/each}
336
- </tr>
337
- </Subscribe>
338
- {/each}
339
- {:else}
340
- <!-- Table is empty -->
341
- <p class="items-center justify-center flex w-full p-10 italic">Nothing to show here.</p>
342
- {/if}
343
- </thead>
344
-
345
- <tbody class="overflow-auto" {...$tableBodyAttrs}>
346
- {#if $data.length > 0}
347
- {#each $pageRows as row (row.id)}
348
- <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
349
- <tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
350
- {#each row.cells as cell, index (cell?.id)}
351
- <Subscribe attrs={cell.attrs()} let:attrs>
352
- <td
353
- {...attrs}
354
- class="!p-2 overflow-auto {index === 0 &&
355
- (resizable === 'rows' || resizable === 'both')
356
- ? 'resize-y'
357
- : ''}"
358
- id="{tableId}-{cell.id}-{row.id}"
359
- >
360
- <!-- Adding config for initial rowHeight, if provided -->
361
- <div
362
- class="flex items-center"
363
- style="height: {rowHeight ? `${rowHeight}px` : 'auto'};"
364
- >
365
- <div class="grow h-full"><Render of={cell.render()} /></div>
366
- </div>
367
- </td>
368
- </Subscribe>
369
- {/each}
370
- </tr>
371
- </Subscribe>
372
- {/each}
373
- {/if}
374
- </tbody>
375
- </table>
376
- </div>
377
- </div>
378
- {#if $data.length > 0}
379
- <!-- Adding pagination, if table is not empty -->
380
- <TablePagination pageConfig={pluginStates.page} {pageSizes} id={tableId} />
381
- {/if}
382
- </div>
6
+ {#key $data.length && true}
7
+ <Table {config} on:action />
8
+ {/key}
@@ -1,16 +1,5 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import type { TableConfig } from '../../models/Models';
3
- declare const __propDef: {
4
- props: {
5
- config: TableConfig<any>;
6
- };
7
- events: {
8
- action: CustomEvent<any>;
9
- } & {
10
- [evt: string]: CustomEvent<any>;
11
- };
12
- slots: {};
13
- };
2
+ declare const __propDef: any;
14
3
  export type TableProps = typeof __propDef.props;
15
4
  export type TableEvents = typeof __propDef.events;
16
5
  export type TableSlots = typeof __propDef.slots;