@bexis2/bexis2-core-ui 0.0.30 → 0.0.31

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.
@@ -0,0 +1,6 @@
1
+ export var Position;
2
+ (function (Position) {
3
+ Position["start"] = "start";
4
+ Position["end"] = "end";
5
+ Position["center"] = "center";
6
+ })(Position || (Position = {}));
@@ -44,9 +44,17 @@ export interface FileObj {
44
44
  type: string;
45
45
  webkitRelativePath: string;
46
46
  }
47
+ export interface ColumnInstructions {
48
+ toStringFn?: (value: any) => string;
49
+ toSortableValueFn?: (value: any) => string | number;
50
+ toFilterableValueFn?: (value: any) => string | number | Date;
51
+ }
47
52
  export interface Column {
48
53
  header?: string;
49
54
  exclude?: boolean;
55
+ instructions?: ColumnInstructions;
56
+ disableFiltering?: boolean;
57
+ disableSorting?: boolean;
50
58
  colFilterFn?: ColumnFilterFn;
51
59
  colFilterComponent?: typeof SvelteComponent;
52
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bexis2/bexis2-core-ui",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -1,184 +1,230 @@
1
- <script lang="ts">
2
- import { createTable, Subscribe, Render, createRender } from 'svelte-headless-table';
3
- import {
4
- addSortBy,
5
- addPagination,
6
- addExpandedRows,
7
- addColumnFilters,
8
- addTableFilter
9
- } from 'svelte-headless-table/plugins';
10
-
11
- import TableFilter from './TableFilter.svelte';
12
- import TablePagination from './TablePagination.svelte';
13
- import { columnFilter, searchFilter } from './filter';
14
- import type { TableConfig } from '$lib/models/Models';
15
-
16
- export let config: TableConfig<any>;
17
- let {
18
- id: tableId,
19
- data,
20
- columns,
21
- optionsComponent,
22
- defaultPageSize = 10,
23
- pageSizes = [5, 10, 15, 20]
24
- } = config;
25
-
26
- type AccessorType = keyof (typeof $data)[0];
27
-
28
- const table = createTable(data, {
29
- colFilter: addColumnFilters(),
30
- tableFilter: addTableFilter({
31
- fn: searchFilter
32
- }),
33
- sort: addSortBy({ disableMultiSort: true }),
34
- page: addPagination({ initialPageSize: defaultPageSize }),
35
- expand: addExpandedRows()
36
- });
37
-
38
- const accessors: AccessorType[] = Object.keys($data[0]) as AccessorType[];
39
-
40
- const tableColumns = [
41
- ...accessors
42
- .filter((accessor) => {
43
- const key = accessor as string;
44
- if (columns !== undefined && key in columns && columns[key].exclude === true) {
45
- return false;
46
- }
47
- return true;
48
- })
49
- .map((accessor) => {
50
- const key = accessor as string;
51
- if (columns !== undefined && key in columns) {
52
- const { header, colFilterFn, colFilterComponent } = columns[key];
53
- return table.column({
54
- header: header ?? key,
55
- accessor: accessor,
56
- plugins: {
57
- sort: { invert: true },
58
- colFilter: {
59
- fn: colFilterFn ?? columnFilter,
60
- render: ({ filterValue, values, id }) =>
61
- createRender(colFilterComponent ?? TableFilter, {
62
- filterValue,
63
- values,
64
- id,
65
- tableId
66
- })
67
- }
68
- }
69
- });
70
- } else {
71
- return table.column({
72
- header: key,
73
- accessor: accessor,
74
- plugins: {
75
- sort: { invert: true },
76
- colFilter: {
77
- fn: columnFilter,
78
- render: ({ filterValue, values, id }) =>
79
- createRender(TableFilter, { filterValue, values, id, tableId })
80
- }
81
- }
82
- });
83
- }
84
- })
85
- ];
86
-
87
- if (optionsComponent !== undefined) {
88
- tableColumns.push(
89
- table.display({
90
- id: 'options',
91
- header: '',
92
- cell: ({ row }, _) => {
93
- return createRender(optionsComponent!, {
94
- row: row.isData() ? row.original : null
95
- });
96
- }
97
- }) as any
98
- );
99
- }
100
-
101
- const createdTableColumns = table.createColumns(tableColumns);
102
-
103
- const { headerRows, pageRows, tableAttrs, tableBodyAttrs, pluginStates } =
104
- table.createViewModel(createdTableColumns);
105
- const { filterValue } = pluginStates.tableFilter;
106
- </script>
107
-
108
- <div class="grid gap-2">
109
- <div class="table-container">
110
- <input
111
- class="input p-2 mb-2 border border-primary-500"
112
- type="text"
113
- bind:value={$filterValue}
114
- placeholder="Search rows..."
115
- />
116
- <table {...$tableAttrs} class="table table-compact bg-tertiary-200">
117
- <thead>
118
- {#each $headerRows as headerRow (headerRow.id)}
119
- <Subscribe
120
- rowAttrs={headerRow.attrs()}
121
- let:rowAttrs
122
- rowProps={headerRow.props()}
123
- let:rowProps
124
- >
125
- <tr {...rowAttrs} class="bg-primary-300">
126
- {#each headerRow.cells as cell (cell.id)}
127
- <Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
128
- <th scope="col" class="!p-2" {...attrs}>
129
- <div class="flex w-full justify-between items-center">
130
- <div class="flex gap-1">
131
- <span
132
- class:underline={props.sort.order}
133
- class:normal-case={cell.id !== cell.label}
134
- on:click={props.sort.toggle}
135
- on:keydown={props.sort.toggle}
136
- >
137
- {cell.render()}
138
- </span>
139
- <div class="w-2">
140
- {#if props.sort.order === 'asc'}
141
-
142
- {:else if props.sort.order === 'desc'}
143
-
144
- {/if}
145
- </div>
146
- </div>
147
- {#if cell.isData()}
148
- {#if props.colFilter?.render}
149
- <div>
150
- <Render of={props.colFilter.render} />
151
- </div>
152
- {/if}
153
- {/if}
154
- </div>
155
- </th>
156
- </Subscribe>
157
- {/each}
158
- </tr>
159
- </Subscribe>
160
- {/each}
161
- </thead>
162
-
163
- <tbody class="" {...$tableBodyAttrs}>
164
- {#each $pageRows as row (row.id)}
165
- <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
166
- <tr {...rowAttrs}>
167
- {#each row.cells as cell (cell?.id)}
168
- <Subscribe attrs={cell.attrs()} let:attrs>
169
- <td {...attrs} class="!p-2">
170
- <div class="flex items-center w-full h-full table-cell-fit">
171
- <Render of={cell.render()} />
172
- </div>
173
- </td>
174
- </Subscribe>
175
- {/each}
176
- </tr>
177
- </Subscribe>
178
- {/each}
179
- </tbody>
180
- </table>
181
- </div>
182
-
183
- <TablePagination pageConfig={pluginStates.page} {pageSizes} />
184
- </div>
1
+ <script lang="ts">
2
+ import { createEventDispatcher } from 'svelte';
3
+ import { createTable, Subscribe, Render, createRender } from 'svelte-headless-table';
4
+ import {
5
+ addSortBy,
6
+ addPagination,
7
+ addExpandedRows,
8
+ addColumnFilters,
9
+ addTableFilter
10
+ } from 'svelte-headless-table/plugins';
11
+
12
+ import TableFilter from './TableFilter.svelte';
13
+ import TablePagination from './TablePagination.svelte';
14
+ import { columnFilter, searchFilter } from './filter';
15
+ import type { TableConfig } from '$lib/models/Models';
16
+
17
+ export let config: TableConfig<any>;
18
+ let {
19
+ id: tableId,
20
+ data,
21
+ columns,
22
+ optionsComponent,
23
+ defaultPageSize = 10,
24
+ pageSizes = [5, 10, 15, 20]
25
+ } = config;
26
+
27
+ type AccessorType = keyof (typeof $data)[0];
28
+
29
+ const dispatch = createEventDispatcher();
30
+ const actionDispatcher = (obj) => dispatch('action', obj);
31
+
32
+ const table = createTable(data, {
33
+ colFilter: addColumnFilters(),
34
+ tableFilter: addTableFilter({
35
+ fn: searchFilter
36
+ }),
37
+ sort: addSortBy({ disableMultiSort: true }),
38
+ page: addPagination({ initialPageSize: defaultPageSize }),
39
+ expand: addExpandedRows()
40
+ });
41
+
42
+ const accessors: AccessorType[] =
43
+ $data.length > 0 ? (Object.keys($data[0]) as AccessorType[]) : [];
44
+
45
+ const tableColumns = [
46
+ ...accessors
47
+ .filter((accessor) => {
48
+ const key = accessor as string;
49
+ if (columns !== undefined && key in columns && columns[key].exclude === true) {
50
+ return false;
51
+ }
52
+ return true;
53
+ })
54
+ .map((accessor) => {
55
+ const key = accessor as string;
56
+ if (columns !== undefined && key in columns) {
57
+ const {
58
+ header,
59
+ colFilterFn,
60
+ colFilterComponent,
61
+ instructions,
62
+ disableFiltering = false,
63
+ disableSorting = false
64
+ } = columns[key];
65
+
66
+ const { toSortableValueFn, toFilterableValueFn, toStringFn } = instructions ?? {};
67
+
68
+ return table.column({
69
+ header: header ?? key,
70
+ accessor: accessor,
71
+ cell: ({ value }) => {
72
+ return toStringFn ? toStringFn(value) : value;
73
+ },
74
+ plugins: {
75
+ sort: {
76
+ disable: disableSorting,
77
+ invert: true,
78
+ getSortValue: (row) => {
79
+ return toSortableValueFn ? toSortableValueFn(row) : row;
80
+ }
81
+ },
82
+ colFilter: !disableFiltering
83
+ ? {
84
+ fn: ({ filterValue, value }) => {
85
+ const val = toFilterableValueFn ? toFilterableValueFn(value) : value;
86
+
87
+ return colFilterFn
88
+ ? colFilterFn({ filterValue, value: val })
89
+ : columnFilter({ filterValue, value: val });
90
+ },
91
+ render: ({ filterValue, values, id }) => {
92
+ return createRender(colFilterComponent ?? TableFilter, {
93
+ filterValue,
94
+ id,
95
+ tableId,
96
+ values
97
+ });
98
+ }
99
+ }
100
+ : undefined,
101
+ tableFilter: {
102
+ getFilterValue: (row) => {
103
+ return toStringFn ? toStringFn(row) : row;
104
+ }
105
+ }
106
+ }
107
+ });
108
+ } else {
109
+ return table.column({
110
+ header: key,
111
+ accessor: accessor,
112
+ plugins: {
113
+ sort: {
114
+ invert: true
115
+ },
116
+ colFilter: {
117
+ fn: columnFilter,
118
+ render: ({ filterValue, values, id }) =>
119
+ createRender(TableFilter, {
120
+ filterValue,
121
+ id,
122
+ tableId,
123
+ values
124
+ })
125
+ }
126
+ }
127
+ });
128
+ }
129
+ })
130
+ ];
131
+
132
+ if (optionsComponent !== undefined) {
133
+ tableColumns.push(
134
+ table.display({
135
+ id: 'options',
136
+ header: '',
137
+ cell: ({ row }, _) => {
138
+ return createRender(optionsComponent!, {
139
+ row: row.isData() ? row.original : null,
140
+ dispatchFn: actionDispatcher
141
+ });
142
+ }
143
+ }) as any
144
+ );
145
+ }
146
+
147
+ const createdTableColumns = table.createColumns(tableColumns);
148
+
149
+ const { headerRows, pageRows, tableAttrs, tableBodyAttrs, pluginStates } =
150
+ table.createViewModel(createdTableColumns);
151
+ const { filterValue } = pluginStates.tableFilter;
152
+ </script>
153
+
154
+ <div class="grid gap-2">
155
+ <div class="table-container">
156
+ <input
157
+ class="input p-2 mb-2 border border-primary-500"
158
+ type="text"
159
+ bind:value={$filterValue}
160
+ placeholder="Search rows..."
161
+ />
162
+ <table {...$tableAttrs} class="table table-compact bg-tertiary-200">
163
+ <thead>
164
+ {#each $headerRows as headerRow (headerRow.id)}
165
+ <Subscribe
166
+ rowAttrs={headerRow.attrs()}
167
+ let:rowAttrs
168
+ rowProps={headerRow.props()}
169
+ let:rowProps
170
+ >
171
+ <tr {...rowAttrs} class="bg-primary-300">
172
+ {#each headerRow.cells as cell (cell.id)}
173
+ <Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
174
+ <th scope="col" class="!p-2" {...attrs}>
175
+ <div class="flex w-full justify-between items-center">
176
+ <div class="flex gap-1">
177
+ <span
178
+ class:underline={props.sort.order}
179
+ class:normal-case={cell.id !== cell.label}
180
+ on:click={props.sort.toggle}
181
+ on:keydown={props.sort.toggle}
182
+ >
183
+ {cell.render()}
184
+ </span>
185
+ <div class="w-2">
186
+ {#if props.sort.order === 'asc'}
187
+
188
+ {:else if props.sort.order === 'desc'}
189
+
190
+ {/if}
191
+ </div>
192
+ </div>
193
+ {#if cell.isData()}
194
+ {#if props.colFilter?.render}
195
+ <div>
196
+ <Render of={props.colFilter.render} />
197
+ </div>
198
+ {/if}
199
+ {/if}
200
+ </div>
201
+ </th>
202
+ </Subscribe>
203
+ {/each}
204
+ </tr>
205
+ </Subscribe>
206
+ {/each}
207
+ </thead>
208
+
209
+ <tbody class="" {...$tableBodyAttrs}>
210
+ {#each $pageRows as row (row.id)}
211
+ <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
212
+ <tr {...rowAttrs}>
213
+ {#each row.cells as cell (cell?.id)}
214
+ <Subscribe attrs={cell.attrs()} let:attrs>
215
+ <td {...attrs} class="!p-2">
216
+ <div class="flex items-center w-full h-full table-cell-fit">
217
+ <Render of={cell.render()} />
218
+ </div>
219
+ </td>
220
+ </Subscribe>
221
+ {/each}
222
+ </tr>
223
+ </Subscribe>
224
+ {/each}
225
+ </tbody>
226
+ </table>
227
+ </div>
228
+
229
+ <TablePagination pageConfig={pluginStates.page} {pageSizes} />
230
+ </div>
@@ -67,6 +67,32 @@
67
67
  value: 'ends',
68
68
  label: 'Ends with'
69
69
  }
70
+ ],
71
+ date: [
72
+ {
73
+ value: 'ison',
74
+ label: 'Is on'
75
+ },
76
+ {
77
+ value: 'isstartingfrom',
78
+ label: 'Is starting from'
79
+ },
80
+ {
81
+ value: 'isafter',
82
+ label: 'Is after'
83
+ },
84
+ {
85
+ value: 'isuntil',
86
+ label: 'Is until'
87
+ },
88
+ {
89
+ value: 'isbefore',
90
+ label: 'Is before'
91
+ },
92
+ {
93
+ value: 'isnoton',
94
+ label: 'Is not on'
95
+ }
70
96
  ]
71
97
  };
72
98
 
@@ -78,7 +104,12 @@
78
104
  placement: 'bottom-start'
79
105
  };
80
106
 
81
- const type = typeof $values[0];
107
+ let type: string = typeof $values[0];
108
+ if (type === 'object') {
109
+ if ($values[0] instanceof Date) {
110
+ type = 'date';
111
+ }
112
+ }
82
113
  </script>
83
114
 
84
115
  <form class="">
@@ -95,7 +126,7 @@
95
126
  <div class="card p-3 absolute grid gap-2 shadow-lg z-10 w-min">
96
127
  <button
97
128
  class="btn variant-filled-primary btn-sm"
98
- type="submit"
129
+ type="button"
99
130
  on:click|preventDefault={() => {
100
131
  firstOption = 'isequal';
101
132
  firstValue = undefined;
@@ -126,13 +157,20 @@
126
157
  bind:value={firstValue}
127
158
  on:click|stopPropagation
128
159
  />
129
- {:else}
160
+ {:else if type === 'string'}
130
161
  <input
131
162
  type="text"
132
163
  class="input p-1 border border-primary-500"
133
164
  bind:value={firstValue}
134
165
  on:click|stopPropagation
135
166
  />
167
+ {:else}
168
+ <input
169
+ type="date"
170
+ class="input p-1 border border-primary-500"
171
+ bind:value={firstValue}
172
+ on:click|stopPropagation
173
+ />
136
174
  {/if}
137
175
  </div>
138
176
  <label for="" class="label normal-case">And</label>
@@ -154,18 +192,25 @@
154
192
  bind:value={secondValue}
155
193
  on:click|stopPropagation
156
194
  />
157
- {:else}
195
+ {:else if type === 'string'}
158
196
  <input
159
197
  type="text"
160
198
  class="input p-1 border border-primary-500"
161
199
  bind:value={secondValue}
162
200
  on:click|stopPropagation
163
201
  />
202
+ {:else}
203
+ <input
204
+ type="date"
205
+ class="input p-1 border border-primary-500"
206
+ bind:value={secondValue}
207
+ on:click|stopPropagation
208
+ />
164
209
  {/if}
165
210
  </div>
166
211
  <button
167
212
  class="btn variant-filled-primary btn-sm"
168
- type="submit"
213
+ type="button"
169
214
  on:click|preventDefault={() => {
170
215
  active = firstValue?.toString().length > 0 || secondValue?.toString().length > 0;
171
216
  $filterValue = [firstOption, firstValue, secondOption, secondValue];
@@ -40,7 +40,7 @@
40
40
  <select
41
41
  name="pageSize"
42
42
  id="pageSize"
43
- class="select btn btn-sm variant-filled-primary w-min font-bold"
43
+ class="select variant-filled-primary w-min font-bold"
44
44
  bind:value={$pageSize}
45
45
  >
46
46
  {#each pageSizes as size}