@bexis2/bexis2-core-ui 0.1.5 → 0.1.7

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,139 +1,153 @@
1
- # bexis-core-ui
2
-
3
- ## v0.1.5
4
- ### update
5
- - MultiSelect
6
- - isTargetComplex -> complexTarget
7
- - isComplex -> complexSource
8
- - DropdownKVP
9
- - targetIsComplex -> complexTarget
10
-
11
- ## v0.1.4
12
- > test for deploy
13
-
14
-
15
- ## v0.1.3
16
- > test table
17
-
18
- ## v0.1.2
19
- ### update
20
- - MultiSelect
21
- - return complex type is available now
22
-
23
- ## v0.1.1
24
- ### update
25
- - Page
26
- - add menu (beta)
27
-
28
-
29
- ## v.0.1.0
30
- ### add
31
- #### types
32
- - ListItem
33
- - KvP
34
-
35
- #### enum
36
- - Position
37
-
38
- ### update
39
- #### components
40
- - DropdownKVP
41
- - return of the target to complex or id only
42
- - TextInput, TextArea, Number
43
- - add placeholder
44
-
45
- ## v0.0.31
46
- ### add
47
- #### components
48
- - Alert
49
-
50
- ### updates
51
- #### components
52
- - Spinner
53
- - label
54
- - color
55
- - position
56
-
57
- - Table
58
- - Date filters
59
- - Configuration for complex types
60
- - Custom event dispatcher
61
- - Updated docs.
62
- - Disabling of filters
63
- - Disabling of sorting
64
-
65
- ### fixes:
66
- #### table
67
- - Arrow in pageSize dropdown.
68
- - Bug with number filter not working on zero values.
69
- - Table of Contents on the right sidebar.
70
-
71
- ## v0.0.29
72
-
73
- ### add
74
- #### types
75
- - Link
76
-
77
- ## v0.0.28
78
-
79
- ### add
80
- #### components
81
- - Page
82
-
83
-
84
-
85
- ## v0.0.27
86
-
87
- ### add
88
- #### components
89
- - Table
90
- - TableFilter
91
- - cloumnFilter
92
- - searchFilter
93
-
94
- #### types
95
- - TableConfig
96
- - Columns
97
- - Column
98
- - Input
99
-
100
- <hr/>
101
-
102
- ## v0.0.26
103
-
104
- ### updates
105
-
106
- - fix bugs in checkbox list
107
- - fix bugs in multi select
108
-
109
- <hr/>
110
-
111
- ## v0.0.25
112
-
113
- ### adds
114
- #### components
115
- - Spinner
116
- - FileUploader
117
- - FileInfo
118
- - FileIcon
119
- -
120
- #### types
121
- - FileUploaderModel
122
-
123
- <hr/>
124
-
125
- ## v0.0.23
126
-
127
- ### updates
128
- - update bexis 2 theme
129
-
130
- ### adds
131
- - Checkbox
132
- - CheckboxKVPList
133
- - CheckboxList
134
- - DateInput
135
- - DropdownKVP
136
- - MultiSelect
137
- - NumberInput
138
- - TextArea
139
- - TextInput
1
+ # bexis-core-ui
2
+ ## v0.1.7
3
+ ### update
4
+ - MultiSelect
5
+ - remove skeleton css classes from svelte select input
6
+
7
+ ## v0.1.6
8
+
9
+ - remove massive console.logs
10
+
11
+ ### update
12
+ - Table
13
+ - change submit to apply filter
14
+ - show emtpy table if not data is in the store
15
+ - add option of including custom rendering component
16
+
17
+ ## v0.1.5
18
+ ### update
19
+ - MultiSelect
20
+ - isTargetComplex -> complexTarget
21
+ - isComplex -> complexSource
22
+ - DropdownKVP
23
+ - targetIsComplex -> complexTarget
24
+
25
+ ## v0.1.4
26
+ > test for deploy
27
+
28
+
29
+ ## v0.1.3
30
+ > test table
31
+
32
+ ## v0.1.2
33
+ ### update
34
+ - MultiSelect
35
+ - return complex type is available now
36
+
37
+ ## v0.1.1
38
+ ### update
39
+ - Page
40
+ - add menu (beta)
41
+
42
+
43
+ ## v.0.1.0
44
+ ### add
45
+ #### types
46
+ - ListItem
47
+ - KvP
48
+
49
+ #### enum
50
+ - Position
51
+
52
+ ### update
53
+ #### components
54
+ - DropdownKVP
55
+ - return of the target to complex or id only
56
+ - TextInput, TextArea, Number
57
+ - add placeholder
58
+
59
+ ## v0.0.31
60
+ ### add
61
+ #### components
62
+ - Alert
63
+
64
+ ### updates
65
+ #### components
66
+ - Spinner
67
+ - label
68
+ - color
69
+ - position
70
+
71
+ - Table
72
+ - Date filters
73
+ - Configuration for complex types
74
+ - Custom event dispatcher
75
+ - Updated docs.
76
+ - Disabling of filters
77
+ - Disabling of sorting
78
+
79
+ ### fixes:
80
+ #### table
81
+ - Arrow in pageSize dropdown.
82
+ - Bug with number filter not working on zero values.
83
+ - Table of Contents on the right sidebar.
84
+
85
+ ## v0.0.29
86
+
87
+ ### add
88
+ #### types
89
+ - Link
90
+
91
+ ## v0.0.28
92
+
93
+ ### add
94
+ #### components
95
+ - Page
96
+
97
+
98
+
99
+ ## v0.0.27
100
+
101
+ ### add
102
+ #### components
103
+ - Table
104
+ - TableFilter
105
+ - cloumnFilter
106
+ - searchFilter
107
+
108
+ #### types
109
+ - TableConfig
110
+ - Columns
111
+ - Column
112
+ - Input
113
+
114
+ <hr/>
115
+
116
+ ## v0.0.26
117
+
118
+ ### updates
119
+
120
+ - fix bugs in checkbox list
121
+ - fix bugs in multi select
122
+
123
+ <hr/>
124
+
125
+ ## v0.0.25
126
+
127
+ ### adds
128
+ #### components
129
+ - Spinner
130
+ - FileUploader
131
+ - FileInfo
132
+ - FileIcon
133
+ -
134
+ #### types
135
+ - FileUploaderModel
136
+
137
+ <hr/>
138
+
139
+ ## v0.0.23
140
+
141
+ ### updates
142
+ - update bexis 2 theme
143
+
144
+ ### adds
145
+ - Checkbox
146
+ - CheckboxKVPList
147
+ - CheckboxList
148
+ - DateInput
149
+ - DropdownKVP
150
+ - MultiSelect
151
+ - NumberInput
152
+ - TextArea
153
+ - TextInput
@@ -52,12 +52,12 @@ const tableColumns = [
52
52
  disableFiltering = false,
53
53
  disableSorting = false
54
54
  } = columns[key];
55
- const { toSortableValueFn, toFilterableValueFn, toStringFn } = instructions ?? {};
55
+ const { toSortableValueFn, toFilterableValueFn, toStringFn, renderComponent } = instructions ?? {};
56
56
  return table.column({
57
57
  header: header ?? key,
58
58
  accessor,
59
- cell: ({ value }) => {
60
- return toStringFn ? toStringFn(value) : value;
59
+ cell: ({ value, row }) => {
60
+ return renderComponent ? createRender(renderComponent, { value, row }) : toStringFn ? toStringFn(value) : value;
61
61
  },
62
62
  plugins: {
63
63
  sort: {
@@ -132,12 +132,14 @@ const { filterValue } = pluginStates.tableFilter;
132
132
 
133
133
  <div class="grid gap-2">
134
134
  <div class="table-container">
135
- <input
136
- class="input p-2 mb-2 border border-primary-500"
137
- type="text"
138
- bind:value={$filterValue}
139
- placeholder="Search rows..."
140
- />
135
+ {#if $data.length > 0}
136
+ <input
137
+ class="input p-2 mb-2 border border-primary-500"
138
+ type="text"
139
+ bind:value={$filterValue}
140
+ placeholder="Search rows..."
141
+ />
142
+ {/if}
141
143
  <table {...$tableAttrs} class="table table-compact bg-tertiary-200">
142
144
  <thead>
143
145
  {#each $headerRows as headerRow (headerRow.id)}
@@ -183,6 +185,8 @@ const { filterValue } = pluginStates.tableFilter;
183
185
  {/each}
184
186
  </tr>
185
187
  </Subscribe>
188
+ {:else}
189
+ <p class="items-center justify-center flex w-full p-10 italic">Nothing to show here.</p>
186
190
  {/each}
187
191
  </thead>
188
192
 
@@ -205,6 +209,7 @@ const { filterValue } = pluginStates.tableFilter;
205
209
  </tbody>
206
210
  </table>
207
211
  </div>
208
-
209
- <TablePagination pageConfig={pluginStates.page} {pageSizes} />
212
+ {#if $data.length > 0}
213
+ <TablePagination pageConfig={pluginStates.page} {pageSizes} />
214
+ {/if}
210
215
  </div>
@@ -24,7 +24,6 @@ let files = { accepted: [], rejected: [] };
24
24
  $:
25
25
  files;
26
26
  onMount(async () => {
27
- console.log("fileupload - OnMount", data);
28
27
  if (!data) {
29
28
  load();
30
29
  } else {
@@ -42,22 +41,18 @@ async function load() {
42
41
  console.log("fileupload", model);
43
42
  }
44
43
  function handleFilesSelect(e) {
45
- console.log("handleFilesSelect", e);
46
44
  console.log("files", files);
47
45
  const { acceptedFiles, fileRejections } = e.detail;
48
46
  files.accepted = [...files.accepted, ...acceptedFiles];
49
47
  files.rejected = [...files.rejected, ...fileRejections];
50
- console.log("acceptedFiles", acceptedFiles);
51
48
  console.log("files.accepted", files.accepted);
52
49
  if (fileRejections.length > 0) {
53
- console.log("the dropped file is not supported.");
54
50
  console.log(files.rejected);
55
51
  let messages = [""];
56
52
  for (let index = 0; index < fileRejections.length; index++) {
57
53
  const element = fileRejections[index];
58
54
  messages.push(getErrorMessage(element));
59
55
  }
60
- console.log(messages);
61
56
  dispatch("error", { messages });
62
57
  files.rejected = [];
63
58
  }
@@ -76,12 +71,9 @@ function getErrorMessage(rejected) {
76
71
  return message;
77
72
  }
78
73
  async function handleSubmit() {
79
- console.log("SUBMIT");
80
74
  dispatch("submit");
81
75
  let url = submit + "?id=" + id;
82
- console.log("SUBMIT");
83
76
  if (files.accepted.length > 0) {
84
- console.log(files);
85
77
  const formData = new FormData();
86
78
  formData.append("files", "123");
87
79
  for (var i = 0; i < files.accepted.length; i++) {
@@ -96,37 +88,37 @@ async function handleSubmit() {
96
88
  }
97
89
  }
98
90
  }
99
- </script>
100
-
101
- <form on:submit|preventDefault={handleSubmit}>
102
- {#if model}
103
- <!--if model exist -->
104
- <div>
105
- <DropZone
106
- on:drop={handleFilesSelect}
107
- accept={model.accept}
108
- multiple={model.multiple}
109
- {maxSize}
110
- >
111
- <b style="font-size:xx-large"><Fa icon={faFileUpload} /></b>
112
- <span
113
- ><b>Drag 'n' drop some files here, or click to select files</b>
114
- <b>max file : {model.maxSize} mb</b></span
115
- >
116
- <p>
117
- {#if model.accept}
118
- {#each model.accept as ext}
119
- {ext} ,
120
- {/each}
121
- {/if}
122
- </p>
123
- </DropZone>
124
- </div>
125
-
126
- <button id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
127
- {:else}
128
- <!-- while data is not loaded show a loading information -->
129
-
130
- <Spinner />
131
- {/if}
132
- </form>
91
+ </script>
92
+
93
+ <form on:submit|preventDefault={handleSubmit}>
94
+ {#if model}
95
+ <!--if model exist -->
96
+ <div>
97
+ <DropZone
98
+ on:drop={handleFilesSelect}
99
+ accept={model.accept}
100
+ multiple={model.multiple}
101
+ {maxSize}
102
+ >
103
+ <b style="font-size:xx-large"><Fa icon={faFileUpload} /></b>
104
+ <span
105
+ ><b>Drag 'n' drop some files here, or click to select files</b>
106
+ <b>max file : {model.maxSize} mb</b></span
107
+ >
108
+ <p>
109
+ {#if model.accept}
110
+ {#each model.accept as ext}
111
+ {ext} ,
112
+ {/each}
113
+ {/if}
114
+ </p>
115
+ </DropZone>
116
+ </div>
117
+
118
+ <button id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
119
+ {:else}
120
+ <!-- while data is not loaded show a loading information -->
121
+
122
+ <Spinner />
123
+ {/if}
124
+ </form>
@@ -20,16 +20,18 @@
20
20
  $: value = null;
21
21
  $: updateTarget(value);
22
22
 
23
+ let container;
24
+
23
25
  function updateTarget(selection) {
24
26
  //diffrent cases
25
- console.log('------');
26
- console.log('isComplex',complexSource);
27
- console.log('complexTarget',complexTarget);
28
- console.log('selection',selection);
27
+ //console.log('------');
28
+ //console.log('isComplex',complexSource);
29
+ //console.log('complexTarget',complexTarget);
30
+ //console.log('selection',selection);
29
31
 
30
32
  //a) source is complex model is simple
31
33
  if (complexSource && !complexTarget && isLoaded) {
32
- console.log('a) source is complex model is simple');
34
+ //console.log('a) source is complex model is simple');
33
35
 
34
36
  target = [];
35
37
  for (let i in selection) {
@@ -47,18 +49,18 @@
47
49
 
48
50
  if (complexSource && complexTarget && isLoaded)
49
51
  {
50
- console.log("both complex",selection);
52
+ //console.log("both complex",selection);
51
53
  target = selection;
52
54
 
53
55
  }
54
56
 
55
- // console.log('selection ' + title, selection);
56
- // console.log('target ' + title, target);
57
+ // //console.log('selection ' + title, selection);
58
+ // //console.log('target ' + title, target);
57
59
  }
58
60
 
59
61
  onMount(async () => {
60
- //console.log("on mount multiselect");
61
- //console.log(source);
62
+ ////console.log("on mount multiselect");
63
+ ////console.log(source);
62
64
 
63
65
  //a) source is complex model is simple
64
66
  if (complexSource && !complexTarget) {
@@ -73,7 +75,7 @@
73
75
  if (items.length > 0) {
74
76
  value = items;
75
77
  }
76
- //console.log(value);
78
+ ////console.log(value);
77
79
  }
78
80
 
79
81
  if (complexSource && complexTarget)
@@ -84,8 +86,8 @@
84
86
 
85
87
  //b) simple liust and simple model
86
88
  if (!complexSource && !complexTarget) {
87
- //console.log("source", source);
88
- //console.log("target",target);
89
+ ////console.log("source", source);
90
+ ////console.log("target",target);
89
91
  isLoaded = true;
90
92
  //set target only if its nit empty
91
93
  if (target != null && target !== undefined && target != '') {
@@ -95,9 +97,10 @@
95
97
  });
96
98
  </script>
97
99
 
100
+
98
101
  <InputContainer label={title} {feedback} {required}>
99
102
  <Select
100
- class="select variant-form-material"
103
+ id={title}
101
104
  items={source}
102
105
  {itemId}
103
106
  label = {itemLabel}
@@ -106,3 +109,9 @@
106
109
  placeholder="-- Please select --"
107
110
  />
108
111
  </InputContainer>
112
+
113
+ <span class="svelte-select-list"/>
114
+
115
+ <style>
116
+ .svelte-select-list{color:green}
117
+ </style>
@@ -7,4 +7,8 @@ h1{
7
7
 
8
8
  :root {
9
9
  --background:rgb(var(--color-surface-200))
10
- }
10
+ }
11
+
12
+ [type='text']:focus{
13
+ --tw-ring-color:#00000;
14
+ }
@@ -49,6 +49,7 @@ export interface ColumnInstructions {
49
49
  toStringFn?: (value: any) => string;
50
50
  toSortableValueFn?: (value: any) => string | number;
51
51
  toFilterableValueFn?: (value: any) => string | number | Date;
52
+ renderComponent?: typeof SvelteComponent;
52
53
  }
53
54
  export interface Column {
54
55
  header?: string;
@@ -15,9 +15,9 @@ passwordStore.subscribe((value) => {
15
15
  password = value;
16
16
  });
17
17
  export function setApiConfig(_host, _user, _pw) {
18
- console.log('overwrite settings');
18
+ console.log('overwrite api settings');
19
19
  hostStore.update((h) => (h = _host));
20
20
  usernameStore.update((u) => (u = _user));
21
21
  passwordStore.update((p) => (p = _pw));
22
- console.log('overwrite host', _host);
22
+ //console.log('overwrite host',_host);
23
23
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@bexis2/bexis2-core-ui",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite dev",
7
- "package": "svelte-package --watch",
7
+ "package": "svelte-package",
8
8
  "build": "vite build",
9
9
  "build package": "svelte-kit sync && svelte-package --watch",
10
10
  "preview": "vite preview",
@@ -28,7 +28,7 @@
28
28
  pageSizes = [5, 10, 15, 20]
29
29
  } = config;
30
30
 
31
- type AccessorType = keyof (typeof $data)[0];
31
+ type AccessorType = keyof (typeof $data)[number];
32
32
 
33
33
  const dispatch = createEventDispatcher();
34
34
  const actionDispatcher = (obj) => dispatch('action', obj);
@@ -67,13 +67,18 @@
67
67
  disableSorting = false
68
68
  } = columns[key];
69
69
 
70
- const { toSortableValueFn, toFilterableValueFn, toStringFn } = instructions ?? {};
70
+ const { toSortableValueFn, toFilterableValueFn, toStringFn, renderComponent } =
71
+ instructions ?? {};
71
72
 
72
73
  return table.column({
73
74
  header: header ?? key,
74
75
  accessor: accessor,
75
- cell: ({ value }) => {
76
- return toStringFn ? toStringFn(value) : value;
76
+ cell: ({ value, row }) => {
77
+ return renderComponent
78
+ ? createRender(renderComponent, { value, row })
79
+ : toStringFn
80
+ ? toStringFn(value)
81
+ : value;
77
82
  },
78
83
  plugins: {
79
84
  sort: {
@@ -158,12 +163,14 @@
158
163
 
159
164
  <div class="grid gap-2">
160
165
  <div class="table-container">
161
- <input
162
- class="input p-2 mb-2 border border-primary-500"
163
- type="text"
164
- bind:value={$filterValue}
165
- placeholder="Search rows..."
166
- />
166
+ {#if $data.length > 0}
167
+ <input
168
+ class="input p-2 mb-2 border border-primary-500"
169
+ type="text"
170
+ bind:value={$filterValue}
171
+ placeholder="Search rows..."
172
+ />
173
+ {/if}
167
174
  <table {...$tableAttrs} class="table table-compact bg-tertiary-200">
168
175
  <thead>
169
176
  {#each $headerRows as headerRow (headerRow.id)}
@@ -209,6 +216,8 @@
209
216
  {/each}
210
217
  </tr>
211
218
  </Subscribe>
219
+ {:else}
220
+ <p class="items-center justify-center flex w-full p-10 italic">Nothing to show here.</p>
212
221
  {/each}
213
222
  </thead>
214
223
 
@@ -231,6 +240,7 @@
231
240
  </tbody>
232
241
  </table>
233
242
  </div>
234
-
235
- <TablePagination pageConfig={pluginStates.page} {pageSizes} />
243
+ {#if $data.length > 0}
244
+ <TablePagination pageConfig={pluginStates.page} {pageSizes} />
245
+ {/if}
236
246
  </div>
@@ -1,184 +1,184 @@
1
- <script lang="ts">
2
- import type { FileUploaderModel, FileInfo, Files } from '../../models/Models.js';
3
-
4
- import DropZone from 'svelte-file-dropzone/Dropzone.svelte';
5
- import Fa from 'svelte-fa/src/fa.svelte';
6
-
7
- import Spinner from '../page/Spinner.svelte';
8
- import { createEventDispatcher } from 'svelte';
9
- import { faTrash } from '@fortawesome/free-solid-svg-icons';
10
- import { faSave } from '@fortawesome/free-regular-svg-icons';
11
- import { faFileUpload } from '@fortawesome/free-solid-svg-icons';
12
-
13
- import { Api } from '../../services/Api.js';
14
-
15
- export let id = 0;
16
- export let version = 1;
17
-
18
- import { onMount } from 'svelte';
19
-
20
- // export let description="";
21
- // export let status=0;
22
-
23
- //action to load fileupload model
24
- export let start = '';
25
- //action to save selected file
26
- export let submit = '';
27
-
28
- export let context = '';
29
-
30
- export let data: FileUploaderModel | undefined;
31
-
32
- $: model = data;
33
- $: submitBt = 'submit';
34
-
35
- let maxSize = 0;
36
-
37
- const dispatch = createEventDispatcher();
38
-
39
- let fx: FileInfo[];
40
-
41
- let files: Files = { accepted: [], rejected: [] };
42
- $: files;
43
-
44
- onMount(async () => {
45
- console.log('fileupload - OnMount', data);
46
-
47
- if (!data) {
48
- load();
49
- } else {
50
- model = data;
51
- }
52
-
53
- if (model) {
54
- submitBt += context;
55
- maxSize = model.maxSize * 1024 * 1024;
56
- }
57
- });
58
-
59
- // load modal from server
60
- async function load() {
61
- let url = start + '?id=' + id + '&version=' + version;
62
-
63
- // load menu froms server
64
- const res = await Api.get(url);
65
- model = await res.data();
66
-
67
- console.log('fileupload', model);
68
- }
69
-
70
- function handleFilesSelect(e: any) {
71
- console.log('handleFilesSelect', e);
72
- console.log('files', files);
73
-
74
- const { acceptedFiles, fileRejections } = e.detail;
75
-
76
- files.accepted = [...files.accepted, ...acceptedFiles];
77
- files.rejected = [...files.rejected, ...fileRejections];
78
-
79
- console.log('acceptedFiles', acceptedFiles);
80
- console.log('files.accepted', files.accepted);
81
-
82
- if (fileRejections.length > 0) {
83
- //alert("the dropped file is not supported");
84
- console.log('the dropped file is not supported.');
85
- console.log(files.rejected);
86
-
87
- let messages = [''];
88
-
89
- for (let index = 0; index < fileRejections.length; index++) {
90
- const element = fileRejections[index];
91
- messages.push(getErrorMessage(element));
92
- }
93
-
94
- console.log(messages);
95
-
96
- dispatch('error', { messages });
97
- //list up the errors somewhere
98
- files.rejected = [];
99
- }
100
-
101
- if (acceptedFiles.length > 0) {
102
- document.getElementById(submitBt)?.click();
103
- }
104
- }
105
-
106
- function getErrorMessage(rejected) {
107
- let message = '';
108
- message = rejected.file.path + ' : ';
109
- let errors = rejected.errors;
110
- for (let index = 0; index < errors.length; index++) {
111
- const error = errors[index];
112
- message += error.message;
113
- }
114
-
115
- return message;
116
- }
117
-
118
- async function handleSubmit() {
119
- console.log('SUBMIT');
120
-
121
- dispatch('submit');
122
-
123
- let url = submit + '?id=' + id;
124
-
125
- // console.log(model);
126
- // console.log(url);
127
- console.log('SUBMIT');
128
-
129
- if (files.accepted.length > 0) {
130
- console.log(files);
131
-
132
- const formData = new FormData();
133
- formData.append('files', '123');
134
- // Looping over all files and add it to FormData object
135
- for (var i = 0; i < files.accepted.length; i++) {
136
- formData.append(files.accepted[i].name, files.accepted[i]);
137
- }
138
-
139
- const response = await Api.post(url, formData);
140
-
141
- if (response.status == 200) {
142
- dispatch('submited');
143
-
144
- let message = files.accepted.length + ' is/are uploaded';
145
- dispatch('success', { text: message });
146
-
147
- files.accepted = [];
148
- }
149
- }
150
- }
151
- </script>
152
-
153
- <form on:submit|preventDefault={handleSubmit}>
154
- {#if model}
155
- <!--if model exist -->
156
- <div>
157
- <DropZone
158
- on:drop={handleFilesSelect}
159
- accept={model.accept}
160
- multiple={model.multiple}
161
- {maxSize}
162
- >
163
- <b style="font-size:xx-large"><Fa icon={faFileUpload} /></b>
164
- <span
165
- ><b>Drag 'n' drop some files here, or click to select files</b>
166
- <b>max file : {model.maxSize} mb</b></span
167
- >
168
- <p>
169
- {#if model.accept}
170
- {#each model.accept as ext}
171
- {ext} ,
172
- {/each}
173
- {/if}
174
- </p>
175
- </DropZone>
176
- </div>
177
-
178
- <button id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
179
- {:else}
180
- <!-- while data is not loaded show a loading information -->
181
-
182
- <Spinner />
183
- {/if}
184
- </form>
1
+ <script lang="ts">
2
+ import type { FileUploaderModel, FileInfo, Files } from '../../models/Models.js';
3
+
4
+ import DropZone from 'svelte-file-dropzone/Dropzone.svelte';
5
+ import Fa from 'svelte-fa/src/fa.svelte';
6
+
7
+ import Spinner from '../page/Spinner.svelte';
8
+ import { createEventDispatcher } from 'svelte';
9
+ import { faTrash } from '@fortawesome/free-solid-svg-icons';
10
+ import { faSave } from '@fortawesome/free-regular-svg-icons';
11
+ import { faFileUpload } from '@fortawesome/free-solid-svg-icons';
12
+
13
+ import { Api } from '../../services/Api.js';
14
+
15
+ export let id = 0;
16
+ export let version = 1;
17
+
18
+ import { onMount } from 'svelte';
19
+
20
+ // export let description="";
21
+ // export let status=0;
22
+
23
+ //action to load fileupload model
24
+ export let start = '';
25
+ //action to save selected file
26
+ export let submit = '';
27
+
28
+ export let context = '';
29
+
30
+ export let data: FileUploaderModel | undefined;
31
+
32
+ $: model = data;
33
+ $: submitBt = 'submit';
34
+
35
+ let maxSize = 0;
36
+
37
+ const dispatch = createEventDispatcher();
38
+
39
+ let fx: FileInfo[];
40
+
41
+ let files: Files = { accepted: [], rejected: [] };
42
+ $: files;
43
+
44
+ onMount(async () => {
45
+ //console.log('fileupload - OnMount', data);
46
+
47
+ if (!data) {
48
+ load();
49
+ } else {
50
+ model = data;
51
+ }
52
+
53
+ if (model) {
54
+ submitBt += context;
55
+ maxSize = model.maxSize * 1024 * 1024;
56
+ }
57
+ });
58
+
59
+ // load modal from server
60
+ async function load() {
61
+ let url = start + '?id=' + id + '&version=' + version;
62
+
63
+ // load menu froms server
64
+ const res = await Api.get(url);
65
+ model = await res.data();
66
+
67
+ console.log('fileupload', model);
68
+ }
69
+
70
+ function handleFilesSelect(e: any) {
71
+ //console.log('handleFilesSelect', e);
72
+ console.log('files', files);
73
+
74
+ const { acceptedFiles, fileRejections } = e.detail;
75
+
76
+ files.accepted = [...files.accepted, ...acceptedFiles];
77
+ files.rejected = [...files.rejected, ...fileRejections];
78
+
79
+ //console.log('acceptedFiles', acceptedFiles);
80
+ console.log('files.accepted', files.accepted);
81
+
82
+ if (fileRejections.length > 0) {
83
+ //alert("the dropped file is not supported");
84
+ //console.log('the dropped file is not supported.');
85
+ console.log(files.rejected);
86
+
87
+ let messages = [''];
88
+
89
+ for (let index = 0; index < fileRejections.length; index++) {
90
+ const element = fileRejections[index];
91
+ messages.push(getErrorMessage(element));
92
+ }
93
+
94
+ //console.log(messages);
95
+
96
+ dispatch('error', { messages });
97
+ //list up the errors somewhere
98
+ files.rejected = [];
99
+ }
100
+
101
+ if (acceptedFiles.length > 0) {
102
+ document.getElementById(submitBt)?.click();
103
+ }
104
+ }
105
+
106
+ function getErrorMessage(rejected) {
107
+ let message = '';
108
+ message = rejected.file.path + ' : ';
109
+ let errors = rejected.errors;
110
+ for (let index = 0; index < errors.length; index++) {
111
+ const error = errors[index];
112
+ message += error.message;
113
+ }
114
+
115
+ return message;
116
+ }
117
+
118
+ async function handleSubmit() {
119
+ //console.log('SUBMIT');
120
+
121
+ dispatch('submit');
122
+
123
+ let url = submit + '?id=' + id;
124
+
125
+ // //console.log(model);
126
+ // //console.log(url);
127
+ //console.log('SUBMIT');
128
+
129
+ if (files.accepted.length > 0) {
130
+ //console.log(files);
131
+
132
+ const formData = new FormData();
133
+ formData.append('files', '123');
134
+ // Looping over all files and add it to FormData object
135
+ for (var i = 0; i < files.accepted.length; i++) {
136
+ formData.append(files.accepted[i].name, files.accepted[i]);
137
+ }
138
+
139
+ const response = await Api.post(url, formData);
140
+
141
+ if (response.status == 200) {
142
+ dispatch('submited');
143
+
144
+ let message = files.accepted.length + ' is/are uploaded';
145
+ dispatch('success', { text: message });
146
+
147
+ files.accepted = [];
148
+ }
149
+ }
150
+ }
151
+ </script>
152
+
153
+ <form on:submit|preventDefault={handleSubmit}>
154
+ {#if model}
155
+ <!--if model exist -->
156
+ <div>
157
+ <DropZone
158
+ on:drop={handleFilesSelect}
159
+ accept={model.accept}
160
+ multiple={model.multiple}
161
+ {maxSize}
162
+ >
163
+ <b style="font-size:xx-large"><Fa icon={faFileUpload} /></b>
164
+ <span
165
+ ><b>Drag 'n' drop some files here, or click to select files</b>
166
+ <b>max file : {model.maxSize} mb</b></span
167
+ >
168
+ <p>
169
+ {#if model.accept}
170
+ {#each model.accept as ext}
171
+ {ext} ,
172
+ {/each}
173
+ {/if}
174
+ </p>
175
+ </DropZone>
176
+ </div>
177
+
178
+ <button id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
179
+ {:else}
180
+ <!-- while data is not loaded show a loading information -->
181
+
182
+ <Spinner />
183
+ {/if}
184
+ </form>
@@ -20,16 +20,18 @@
20
20
  $: value = null;
21
21
  $: updateTarget(value);
22
22
 
23
+ let container;
24
+
23
25
  function updateTarget(selection) {
24
26
  //diffrent cases
25
- console.log('------');
26
- console.log('isComplex',complexSource);
27
- console.log('complexTarget',complexTarget);
28
- console.log('selection',selection);
27
+ //console.log('------');
28
+ //console.log('isComplex',complexSource);
29
+ //console.log('complexTarget',complexTarget);
30
+ //console.log('selection',selection);
29
31
 
30
32
  //a) source is complex model is simple
31
33
  if (complexSource && !complexTarget && isLoaded) {
32
- console.log('a) source is complex model is simple');
34
+ //console.log('a) source is complex model is simple');
33
35
 
34
36
  target = [];
35
37
  for (let i in selection) {
@@ -47,18 +49,18 @@
47
49
 
48
50
  if (complexSource && complexTarget && isLoaded)
49
51
  {
50
- console.log("both complex",selection);
52
+ //console.log("both complex",selection);
51
53
  target = selection;
52
54
 
53
55
  }
54
56
 
55
- // console.log('selection ' + title, selection);
56
- // console.log('target ' + title, target);
57
+ // //console.log('selection ' + title, selection);
58
+ // //console.log('target ' + title, target);
57
59
  }
58
60
 
59
61
  onMount(async () => {
60
- //console.log("on mount multiselect");
61
- //console.log(source);
62
+ ////console.log("on mount multiselect");
63
+ ////console.log(source);
62
64
 
63
65
  //a) source is complex model is simple
64
66
  if (complexSource && !complexTarget) {
@@ -73,7 +75,7 @@
73
75
  if (items.length > 0) {
74
76
  value = items;
75
77
  }
76
- //console.log(value);
78
+ ////console.log(value);
77
79
  }
78
80
 
79
81
  if (complexSource && complexTarget)
@@ -84,8 +86,8 @@
84
86
 
85
87
  //b) simple liust and simple model
86
88
  if (!complexSource && !complexTarget) {
87
- //console.log("source", source);
88
- //console.log("target",target);
89
+ ////console.log("source", source);
90
+ ////console.log("target",target);
89
91
  isLoaded = true;
90
92
  //set target only if its nit empty
91
93
  if (target != null && target !== undefined && target != '') {
@@ -95,9 +97,10 @@
95
97
  });
96
98
  </script>
97
99
 
100
+
98
101
  <InputContainer label={title} {feedback} {required}>
99
102
  <Select
100
- class="select variant-form-material"
103
+ id={title}
101
104
  items={source}
102
105
  {itemId}
103
106
  label = {itemLabel}
@@ -106,3 +109,9 @@
106
109
  placeholder="-- Please select --"
107
110
  />
108
111
  </InputContainer>
112
+
113
+ <span class="svelte-select-list"/>
114
+
115
+ <style>
116
+ .svelte-select-list{color:green}
117
+ </style>
@@ -7,4 +7,8 @@ h1{
7
7
 
8
8
  :root {
9
9
  --background:rgb(var(--color-surface-200))
10
- }
10
+ }
11
+
12
+ [type='text']:focus{
13
+ --tw-ring-color:#00000;
14
+ }
@@ -3,13 +3,11 @@ import type { ColumnFilterFn } from 'svelte-headless-table/lib/plugins';
3
3
  import type { Writable } from 'svelte/store';
4
4
 
5
5
  // page
6
- export interface Link
7
- {
8
- label:string,
9
- url:string
6
+ export interface Link {
7
+ label: string;
8
+ url: string;
10
9
  }
11
10
 
12
-
13
11
  // Form
14
12
  export interface Input {
15
13
  id: string;
@@ -18,7 +16,7 @@ export interface Input {
18
16
  invalid: boolean;
19
17
  valid: boolean;
20
18
  required: boolean;
21
- placeholder:string;
19
+ placeholder: string;
22
20
  }
23
21
 
24
22
  export interface FileInfo {
@@ -61,6 +59,7 @@ export interface ColumnInstructions {
61
59
  toStringFn?: (value: any) => string;
62
60
  toSortableValueFn?: (value: any) => string | number;
63
61
  toFilterableValueFn?: (value: any) => string | number | Date;
62
+ renderComponent?: typeof SvelteComponent;
64
63
  }
65
64
 
66
65
  // Table column type
@@ -88,15 +87,14 @@ export interface TableConfig<T> {
88
87
  optionsComponent?: typeof SvelteComponent;
89
88
  }
90
89
 
91
-
92
90
  // lists
93
91
  export interface KvP {
94
- id: number;
95
- text: string;
92
+ id: number;
93
+ text: string;
96
94
  }
97
95
 
98
96
  export interface ListItem {
99
- id: number;
100
- text: string;
101
- group: string;
102
- }
97
+ id: number;
98
+ text: string;
99
+ group: string;
100
+ }
@@ -1,31 +1,32 @@
1
- import { writable } from 'svelte/store';
2
-
3
- export let host = 'window.location.origin';
4
- export let username = '';
5
- export let password = '';
6
-
7
- const hostStore = writable(''); //writable(window.location.origin);
8
- const usernameStore = writable('');
9
- const passwordStore = writable('');
10
-
11
- hostStore.subscribe((value) => {
12
- host = value;
13
- });
14
-
15
- usernameStore.subscribe((value) => {
16
- username = value;
17
- });
18
-
19
- passwordStore.subscribe((value) => {
20
- password = value;
21
- });
22
-
23
- export function setApiConfig(_host: string, _user: string, _pw: string) {
24
- console.log('overwrite settings');
25
-
26
- hostStore.update((h) => (h = _host));
27
- usernameStore.update((u) => (u = _user));
28
- passwordStore.update((p) => (p = _pw));
29
-
30
- console.log('overwrite host',_host);
31
- }
1
+ import { writable } from 'svelte/store';
2
+
3
+ export let host = 'window.location.origin';
4
+ export let username = '';
5
+ export let password = '';
6
+
7
+ const hostStore = writable(''); //writable(window.location.origin);
8
+ const usernameStore = writable('');
9
+ const passwordStore = writable('');
10
+
11
+ hostStore.subscribe((value) => {
12
+ host = value;
13
+ });
14
+
15
+ usernameStore.subscribe((value) => {
16
+ username = value;
17
+ });
18
+
19
+ passwordStore.subscribe((value) => {
20
+ password = value;
21
+ });
22
+
23
+ export function setApiConfig(_host: string, _user: string, _pw: string) {
24
+
25
+ console.log('overwrite api settings');
26
+
27
+ hostStore.update((h) => (h = _host));
28
+ usernameStore.update((u) => (u = _user));
29
+ passwordStore.update((p) => (p = _pw));
30
+
31
+ //console.log('overwrite host',_host);
32
+ }