firstly 0.0.7 → 0.0.9

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/esm/BaseEnum.d.ts +2 -13
  3. package/esm/BaseEnum.js +0 -4
  4. package/esm/FF_Entity.js +20 -4
  5. package/esm/SqlDatabase/FF_LogToConsole.d.ts +4 -1
  6. package/esm/SqlDatabase/FF_LogToConsole.js +15 -8
  7. package/esm/api/index.d.ts +4 -4
  8. package/esm/api/index.js +13 -13
  9. package/esm/auth/Adapter.js +1 -9
  10. package/esm/auth/AuthController.server.d.ts +1 -2
  11. package/esm/auth/AuthController.server.js +21 -12
  12. package/esm/auth/RoleHelpers.d.ts +2 -2
  13. package/esm/auth/RoleHelpers.js +6 -4
  14. package/esm/auth/client/Auth.d.ts +11 -4
  15. package/esm/auth/client/Auth.js +14 -6
  16. package/esm/auth/{Entities.d.ts → client/Entities.d.ts} +4 -4
  17. package/esm/auth/{Entities.js → client/Entities.js} +33 -17
  18. package/esm/auth/client/index.d.ts +5 -0
  19. package/esm/auth/client/index.js +5 -0
  20. package/esm/auth/helper.d.ts +6 -1
  21. package/esm/auth/helper.js +11 -4
  22. package/esm/auth/index.d.ts +11 -11
  23. package/esm/auth/index.js +93 -78
  24. package/esm/auth/providers/github.js +2 -1
  25. package/esm/auth/providers/index.js +1 -1
  26. package/esm/auth/providers/strava.js +2 -1
  27. package/esm/auth/static/assets/{Page-RIbXHuZG.d.ts → Page-BEFYPjis.d.ts} +1 -1
  28. package/esm/auth/static/assets/{Page-RIbXHuZG.js → Page-BEFYPjis.js} +1 -1
  29. package/esm/auth/static/assets/Page-Cfysx_UV.d.ts +6 -0
  30. package/esm/auth/static/assets/Page-Cfysx_UV.js +18 -0
  31. package/esm/auth/static/assets/{Page-DBWJjlEQ.d.ts → Page-DtgkOCJs.d.ts} +1 -1
  32. package/esm/auth/static/assets/{Page-DBWJjlEQ.js → Page-DtgkOCJs.js} +1 -1
  33. package/esm/auth/static/assets/index-QypqCYwC.d.ts +63 -0
  34. package/esm/auth/static/assets/index-QypqCYwC.js +2 -0
  35. package/esm/auth/static/index.html +1 -1
  36. package/esm/auth/types.d.ts +7 -5
  37. package/esm/bin/cmd.js +28 -14
  38. package/esm/cellsBuildor.d.ts +5 -4
  39. package/esm/cellsBuildor.js +42 -17
  40. package/esm/changeLog/index.d.ts +23 -7
  41. package/esm/changeLog/index.js +24 -18
  42. package/esm/feedback/FeedbackController.d.ts +12 -3
  43. package/esm/feedback/FeedbackController.js +62 -13
  44. package/esm/feedback/index.d.ts +1 -0
  45. package/esm/feedback/ui/DialogIssue.svelte +26 -7
  46. package/esm/feedback/ui/DialogIssues.svelte +7 -2
  47. package/esm/handle/index.d.ts +1 -1
  48. package/esm/helper.js +3 -2
  49. package/esm/index.d.ts +10 -3
  50. package/esm/index.js +1 -1
  51. package/esm/mail/index.js +15 -10
  52. package/esm/storeList.d.ts +3 -1
  53. package/esm/storeList.js +20 -10
  54. package/esm/ui/Field.svelte +11 -13
  55. package/esm/ui/FieldGroup.svelte +4 -2
  56. package/esm/ui/Grid.svelte +90 -20
  57. package/esm/ui/Grid.svelte.d.ts +1 -0
  58. package/esm/ui/GridPaginate.svelte +12 -10
  59. package/esm/ui/GridPaginate.svelte.d.ts +1 -1
  60. package/esm/ui/dialog/DialogPrimitive.svelte +1 -5
  61. package/esm/ui/dialog/dialog.d.ts +10 -8
  62. package/esm/ui/dialog/dialog.js +9 -10
  63. package/esm/ui/internals/Input.svelte +10 -1
  64. package/esm/ui/link/LinkPlus.svelte +41 -29
  65. package/esm/vite/index.js +4 -1
  66. package/package.json +8 -8
  67. package/esm/auth/static/assets/Page-apb_xgZT.d.ts +0 -6
  68. package/esm/auth/static/assets/Page-apb_xgZT.js +0 -18
  69. package/esm/auth/static/assets/index-qfq98Nyd.d.ts +0 -63
  70. package/esm/auth/static/assets/index-qfq98Nyd.js +0 -2
package/esm/index.d.ts CHANGED
@@ -1,14 +1,16 @@
1
- /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.1_svelte@4.2.18_vite@5.4.1_@types+node@_vtylvkjv5lewhfcl4vq2py4rce/node_modules/@sveltejs/kit" />
1
+ /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.2_svelte@4.2.18_vite@5.4.1_@types+node@_lnml5jetshdinsnlj53joqxhde/node_modules/@sveltejs/kit" />
2
2
  import type { RequestEvent } from '@sveltejs/kit';
3
3
  import type { FindOptionsBase } from 'remult';
4
4
  import { Log } from '@kitql/helpers';
5
5
  import type { BaseEnum, BaseItem, FF_Icon } from './BaseEnum.js';
6
6
  import type { CellsInput as CellsInput_ForExport } from './cellsBuildor.js';
7
+ import type { ColumnDeciderArgs } from './changeLog/index.js';
7
8
  import { default as DefaultMail } from './mail/templates/DefaultMail.svelte';
8
9
  import { storeItem } from './storeItem.js';
9
10
  import { storeList } from './storeList.js';
10
11
  import { default as Button } from './ui/Button.svelte';
11
12
  import { default as Clipboardable } from './ui/Clipboardable.svelte';
13
+ import type { dialog } from './ui/dialog/dialog.js';
12
14
  import { default as DialogManagement } from './ui/dialog/DialogManagement.svelte';
13
15
  import { default as FormEditAction } from './ui/dialog/FormEditAction.svelte';
14
16
  import { default as Field } from './ui/Field.svelte';
@@ -43,7 +45,7 @@ export { FF_LogToConsole } from './SqlDatabase/FF_LogToConsole.js';
43
45
  export { BaseEnum } from './BaseEnum.js';
44
46
  export { dialog } from './ui/dialog/dialog.js';
45
47
  export { getEntityDisplayValue, isError, getFieldLinkDisplayValue, getEnum, getEnums, } from './helper.js';
46
- export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, } from './cellsBuildor.js';
48
+ export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, containsWords, } from './cellsBuildor.js';
47
49
  export { storeItem };
48
50
  export { storeList };
49
51
  export { displayPhone, arrToStr } from './formats/strings.js';
@@ -71,7 +73,11 @@ declare module 'remult' {
71
73
  href?: (item: entityType) => string;
72
74
  findOptionsForEdit?: ((entity: entityType) => FindOptionsBase<valueType>) | FindOptionsBase<valueType>;
73
75
  findOptionsLimit?: number;
74
- createOptionWhenNoResult?: boolean;
76
+ createOptionWhenNoResult?: {
77
+ onCreateRequest: (item: entityType, strCreateNew: string) => Parameters<typeof dialog.form>;
78
+ onSuccess: (entity: entityType, newItem: any) => Promise<void>;
79
+ onError?: () => void;
80
+ };
75
81
  multiSelect?: boolean;
76
82
  skipForDefaultField?: boolean;
77
83
  }
@@ -83,6 +89,7 @@ declare module 'remult' {
83
89
  permissionApiInsert?: BaseEnum[] | BaseEnum;
84
90
  permissionApiRead?: BaseEnum[] | BaseEnum;
85
91
  permissionApiUpdate?: BaseEnum[] | BaseEnum;
92
+ changeLog?: false | ColumnDeciderArgs<entityType>;
86
93
  }
87
94
  interface UserInfo {
88
95
  session: {
package/esm/index.js CHANGED
@@ -37,7 +37,7 @@ export { FF_LogToConsole } from './SqlDatabase/FF_LogToConsole.js';
37
37
  export { BaseEnum } from './BaseEnum.js';
38
38
  export { dialog } from './ui/dialog/dialog.js';
39
39
  export { getEntityDisplayValue, isError, getFieldLinkDisplayValue, getEnum, getEnums, } from './helper.js';
40
- export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, } from './cellsBuildor.js';
40
+ export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, containsWords, } from './cellsBuildor.js';
41
41
  export { storeItem };
42
42
  export { storeList };
43
43
  export { displayPhone, arrToStr } from './formats/strings.js';
package/esm/mail/index.js CHANGED
@@ -14,16 +14,21 @@ export const mailInit = async (nodemailer, o) => {
14
14
  else {
15
15
  try {
16
16
  nodemailer.createTestAccount(globalOptions?.apiUrl ?? '', (err, account) => {
17
- globalOptions = { ...globalOptions, from: account.user };
18
- transporter = nodemailer.createTransport({
19
- host: account.smtp.host,
20
- port: account.smtp.port,
21
- secure: account.smtp.secure,
22
- auth: {
23
- user: account.user,
24
- pass: account.pass,
25
- },
26
- });
17
+ if (account) {
18
+ globalOptions = { ...globalOptions, from: account.user };
19
+ transporter = nodemailer.createTransport({
20
+ host: account.smtp.host,
21
+ port: account.smtp.port,
22
+ secure: account.smtp.secure,
23
+ auth: {
24
+ user: account.user,
25
+ pass: account.pass,
26
+ },
27
+ });
28
+ }
29
+ else {
30
+ log.error("Error nodemailer.createTestAccount() can't be done.");
31
+ }
27
32
  });
28
33
  }
29
34
  catch (error) {
@@ -1,13 +1,15 @@
1
1
  /// <reference types="svelte" />
2
- import type { FindOptions, Repository } from 'remult';
2
+ import type { FindOptions, GroupByOptions, MembersOnly, Repository } from 'remult';
3
3
  type TheStoreList<T> = {
4
4
  items: T[];
5
5
  loading: boolean;
6
6
  totalCount: number | undefined;
7
+ agg: any | undefined;
7
8
  };
8
9
  export type FF_FindOptions<T> = FindOptions<T> & {
9
10
  withCount?: boolean;
10
11
  withItems?: boolean;
12
+ aggregate?: GroupByOptions<T, (keyof MembersOnly<T>)[], any, any, any, any, any>;
11
13
  };
12
14
  /**
13
15
  * @param repo remult repository to listen to
package/esm/storeList.js CHANGED
@@ -15,7 +15,7 @@ import { writable } from 'svelte/store';
15
15
  * $: browser && tasks.listen(data.options)
16
16
  * ```
17
17
  */
18
- export const storeList = (repo, initValues = { items: [], loading: true, totalCount: undefined }) => {
18
+ export const storeList = (repo, initValues = { items: [], loading: true, totalCount: undefined, agg: undefined }) => {
19
19
  const { subscribe, set, update } = writable(initValues);
20
20
  let unSub = null;
21
21
  onDestroy(async () => {
@@ -43,27 +43,36 @@ export const storeList = (repo, initValues = { items: [], loading: true, totalCo
43
43
  throw new Error(`xxx.fetch() withItems and withCount can't be both false!`);
44
44
  }
45
45
  else if (!withItems && withCount) {
46
- const totalCount = await repo.count(options?.where);
47
- set({ loading: false, items: [], totalCount });
46
+ let optionsToUse = { where: options?.where };
47
+ if (options?.aggregate) {
48
+ optionsToUse = { ...options.aggregate, where: options?.where };
49
+ }
50
+ // const agg = await repo.aggregate({ ...options?.aggregate, where: options?.where })
51
+ const agg = await repo.aggregate(optionsToUse);
52
+ set({ loading: false, items: [], totalCount: agg.$count, agg });
48
53
  if (onNewData) {
49
- onNewData(undefined, totalCount);
54
+ onNewData(undefined, agg.$count);
50
55
  }
51
56
  }
52
57
  else if (withItems && !withCount) {
53
58
  const items = await repo.find(options);
54
- set({ loading: false, items, totalCount: undefined });
59
+ set({ loading: false, items, totalCount: undefined, agg: undefined });
55
60
  if (onNewData) {
56
61
  onNewData(items, undefined);
57
62
  }
58
63
  }
59
64
  else {
60
- const [items, totalCount] = await Promise.all([
65
+ let optionsToUse = { where: options?.where };
66
+ if (options?.aggregate) {
67
+ optionsToUse = { ...options.aggregate, where: options?.where };
68
+ }
69
+ const [items, agg] = await Promise.all([
61
70
  repo.find({ ...options }),
62
- repo.count(options?.where),
71
+ repo.aggregate(optionsToUse),
63
72
  ]);
64
- set({ loading: false, items, totalCount });
73
+ set({ loading: false, items, totalCount: agg.$count, agg });
65
74
  if (onNewData) {
66
- onNewData(items, totalCount);
75
+ onNewData(items, agg.$count);
67
76
  }
68
77
  }
69
78
  }
@@ -75,7 +84,8 @@ export const storeList = (repo, initValues = { items: [], loading: true, totalCo
75
84
  const withCount = options?.withCount ?? false;
76
85
  let totalCount = undefined;
77
86
  if (withCount) {
78
- totalCount = await repo.count(options?.where);
87
+ const agg = await repo.aggregate({ where: options?.where });
88
+ totalCount = agg.$count;
79
89
  }
80
90
  update((c) => {
81
91
  return { ...c, items: info.items, loading: false, ...(withCount ? { totalCount } : {}) };
@@ -17,6 +17,7 @@ import MultiSelectMelt from "./internals/select/MultiSelectMelt.svelte";
17
17
  import SelectMelt from "./internals/select/SelectMelt.svelte";
18
18
  import SelectRadio from "./internals/select/SelectRadio.svelte";
19
19
  import Textarea from "./internals/Textarea.svelte";
20
+ import LinkPlus from "./link/LinkPlus.svelte";
20
21
  export let cell;
21
22
  export let value = void 0;
22
23
  export let cellsValues = {};
@@ -100,7 +101,8 @@ const getLoadOptions = async (cellsValues2, str) => {
100
101
  );
101
102
  let totalCount = arr.length;
102
103
  if (totalCount === limit) {
103
- totalCount = await metaTypeObj.repoTarget.count(findToUse.where);
104
+ const agg = await metaTypeObj.repoTarget.aggregate({ where: findToUse.where });
105
+ totalCount = agg.$count;
104
106
  }
105
107
  if (!cell.field?.options.multiSelect) {
106
108
  if (str === "" && getId() && !arr.find((r) => String(r.id) === String(getId()))) {
@@ -153,16 +155,7 @@ const calcSuffix = (value2) => {
153
155
  {:else if metaType.kind === 'relation'}
154
156
  {@const item = getEntityDisplayValue(metaType.repoTarget, value)}
155
157
  <div class={tw('flex items-center gap-4', 'h-12', 'pl-2')}>
156
- {#if item && item?.icon}
157
- <Icon {...item.icon} />
158
- {/if}
159
- <div class="grid grid-cols-1">
160
- <span>{cell?.header ?? item?.caption ?? '-'}</span>
161
- <!-- && captionSubStyle === 'inline' -->
162
- {#if item?.captionSub}
163
- <span class="text-base-content/70 text-xs italic">{item.captionSub}</span>
164
- {/if}
165
- </div>
158
+ <LinkPlus {item}></LinkPlus>
166
159
  </div>
167
160
  {:else if metaType.kind === 'enum'}
168
161
  {@const v = displayWithDefaultAndSuffix(cell.field, value)}
@@ -204,7 +197,7 @@ const calcSuffix = (value2) => {
204
197
  on:issue={(e) => {
205
198
  error = e.detail
206
199
  }}
207
- createOptionWhenNoResult={cell.field?.options.createOptionWhenNoResult}
200
+ createOptionWhenNoResult={!!cell.field?.options.createOptionWhenNoResult}
208
201
  on:createRequest
209
202
  />
210
203
  {/if}
@@ -245,7 +238,12 @@ const calcSuffix = (value2) => {
245
238
  type="checkbox"
246
239
  {...{ ...common(cell.field), required: undefined }}
247
240
  class="checkbox"
248
- bind:checked={value}
241
+ checked={value}
242
+ on:input={(e) => {
243
+ // @ts-ignore
244
+ value = e.target.checked
245
+ dispatchSelected(value)
246
+ }}
249
247
  />
250
248
  </div>
251
249
  {:else if metaType.subKind === 'text' || metaType.subKind === 'email' || metaType.subKind === 'password' || metaType.subKind === 'dateOnly' || metaType.subKind === 'number'}
@@ -10,9 +10,11 @@ export let store;
10
10
  export let focusKey = null;
11
11
  const getError = (errors, field) => {
12
12
  const fo = getRelationFieldInfo(field);
13
- const keyToUse = fo?.options?.field ?? field.key;
14
- if (errors && errors[keyToUse]) {
13
+ const keyToUse = fo?.options?.field;
14
+ if (errors && keyToUse && errors[keyToUse]) {
15
15
  return errors[keyToUse];
16
+ } else if (errors && errors[field.key]) {
17
+ return errors[field.key];
16
18
  }
17
19
  return void 0;
18
20
  };
@@ -31,6 +31,7 @@ export let classes = {
31
31
  };
32
32
  export let orderBy = void 0;
33
33
  export let orderByCols = void 0;
34
+ export let settingsLeft = false;
34
35
  export let dicoNoResult = "Aucun r\xE9sultat !";
35
36
  const dispatch = createEventDispatcher();
36
37
  const sorting = (toSort, b) => {
@@ -62,19 +63,55 @@ const sortingIcon = (toSort, b, _orderBy) => {
62
63
  const cellsToTake = (cells2) => {
63
64
  return cells2.filter((c) => c.modeView !== "hide");
64
65
  };
66
+ const classForRounding = (i) => {
67
+ if (settingsLeft && (withEdit || withDelete || withAdd)) {
68
+ if (i === 0) {
69
+ return "";
70
+ } else if (i === cells.length - 1) {
71
+ return "rounded-tr-lg";
72
+ }
73
+ }
74
+ if (!settingsLeft && (withEdit || withDelete || withAdd)) {
75
+ if (i === 0) {
76
+ return "rounded-tl-lg";
77
+ } else if (i === cells.length - 1) {
78
+ return "";
79
+ }
80
+ }
81
+ if (i === 0) {
82
+ return "rounded-tl-lg";
83
+ } else if (i === cells.length - 1) {
84
+ return "rounded-tr-lg";
85
+ }
86
+ };
65
87
  </script>
66
88
 
67
89
  <div class="overflow-x-auto">
68
90
  <table class="table {classes.table}">
69
91
  <thead>
70
92
  <tr>
93
+ {#if settingsLeft && (withEdit || withDelete || withAdd)}
94
+ <th class="rounded-tl-lg">
95
+ <div class="flex justify-start">
96
+ {#if !withAdd}
97
+ <Icon data={LibIcon_Settings}></Icon>
98
+ {:else}
99
+ <Button
100
+ permission={store.getRepo().metadata.options.permissionApiInsert}
101
+ disabled={!store.getRepo().metadata.apiInsertAllowed()}
102
+ class="btn btn-square btn-ghost btn-xs"
103
+ on:click={() => dispatch('add', {})}
104
+ >
105
+ <Icon data={LibIcon_Add} />
106
+ </Button>
107
+ {/if}
108
+ </div>
109
+ </th>
110
+ {/if}
111
+
71
112
  {#each cellsToTake(cells) as b, i}
72
113
  {@const al = align(b.field, b.kind === 'slot')}
73
- <th
74
- class="{al}
75
- {i === 0 ? 'rounded-tl-lg' : ''}
76
- {i === cells.length - 1 && !withEdit && !withDelete ? 'rounded-tr-lg' : ''}"
77
- >
114
+ <th class="{al} {classForRounding(i)}">
78
115
  {#if b.headerSlot}
79
116
  <slot name="header" field={b.field} />
80
117
  {:else}
@@ -98,20 +135,22 @@ const cellsToTake = (cells2) => {
98
135
  </th>
99
136
  {/each}
100
137
 
101
- {#if withEdit || withDelete || withAdd}
102
- <th class="flex justify-end rounded-tr-lg">
103
- {#if withAdd}
104
- <Button
105
- permission={store.getRepo().metadata.options.permissionApiInsert}
106
- disabled={!store.getRepo().metadata.apiInsertAllowed()}
107
- class="btn btn-square btn-ghost btn-xs"
108
- on:click={() => dispatch('add', {})}
109
- >
110
- <Icon data={LibIcon_Add} />
111
- </Button>
112
- {:else}
113
- <Icon data={LibIcon_Settings}></Icon>
114
- {/if}
138
+ {#if !settingsLeft && (withEdit || withDelete || withAdd)}
139
+ <th class="rounded-tr-lg">
140
+ <div class="flex justify-end">
141
+ {#if withAdd}
142
+ <Button
143
+ permission={store.getRepo().metadata.options.permissionApiInsert}
144
+ disabled={!store.getRepo().metadata.apiInsertAllowed()}
145
+ class="btn btn-square btn-ghost btn-xs"
146
+ on:click={() => dispatch('add', {})}
147
+ >
148
+ <Icon data={LibIcon_Add} />
149
+ </Button>
150
+ {:else}
151
+ <Icon data={LibIcon_Settings}></Icon>
152
+ {/if}
153
+ </div>
115
154
  </th>
116
155
  {/if}
117
156
  </tr>
@@ -123,6 +162,34 @@ const cellsToTake = (cells2) => {
123
162
  {:else}
124
163
  {#each $store.items as row}
125
164
  <tr on:click={() => dispatch('rowclick', row)} class="hover:bg-base-content/20">
165
+ <!-- BECARFULL THIS CODE IS DUPLICATED -->
166
+ {#if settingsLeft && (withEdit || withDelete)}
167
+ <td class="text-left">
168
+ <div class="flex justify-start gap-2">
169
+ {#if withEdit}
170
+ <Button
171
+ permission={store.getRepo().metadata.options.permissionApiUpdate}
172
+ disabled={!store.getRepo().metadata.apiUpdateAllowed()}
173
+ class="btn btn-square btn-ghost btn-xs"
174
+ on:click={() => dispatch('edit', row)}
175
+ >
176
+ <Icon data={LibIcon_Edit} />
177
+ </Button>
178
+ {/if}
179
+ {#if withDelete}
180
+ <Button
181
+ permission={store.getRepo().metadata.options.permissionApiDelete}
182
+ disabled={!store.getRepo().metadata.apiDeleteAllowed()}
183
+ class="btn btn-square btn-ghost btn-xs"
184
+ on:click={() => dispatch('delete', row)}
185
+ >
186
+ <Icon data={LibIcon_Delete} />
187
+ </Button>
188
+ {/if}
189
+ </div>
190
+ </td>
191
+ {/if}
192
+
126
193
  {#each cellsToTake(cells) as b}
127
194
  {@const metaType = getFieldMetaType(b.field)}
128
195
  <td class={align(b.field, b.kind === 'slot')}>
@@ -153,6 +220,8 @@ const cellsToTake = (cells2) => {
153
220
  href: b.field?.options?.href ? b.field?.options.href(row) : item?.href,
154
221
  }}
155
222
  />
223
+ {:else if b.kind === 'baseItem'}
224
+ <LinkPlus item={row[metaType.field.key]} />
156
225
  {:else if b.kind === 'field_link'}
157
226
  {@const item = getFieldLinkDisplayValue(metaType.field, row)}
158
227
  <LinkPlus {item} />
@@ -191,7 +260,8 @@ const cellsToTake = (cells2) => {
191
260
  {/if}
192
261
  </td>
193
262
  {/each}
194
- {#if withEdit || withDelete}
263
+
264
+ {#if !settingsLeft && (withEdit || withDelete)}
195
265
  <td class="text-right">
196
266
  <div class="flex justify-end gap-2">
197
267
  {#if withEdit}
@@ -15,6 +15,7 @@ declare class __sveltets_Render<T extends Record<any, any>> {
15
15
  } | undefined;
16
16
  orderBy?: EntityOrderBy<T> | undefined;
17
17
  orderByCols?: true | (keyof T)[] | undefined;
18
+ settingsLeft?: boolean | undefined;
18
19
  dicoNoResult?: string | undefined;
19
20
  };
20
21
  events(): {
@@ -4,29 +4,31 @@ import "./LibIcon";
4
4
  import { LibIcon_ChevronLeft, LibIcon_ChevronRight } from "./LibIcon";
5
5
  import Loading from "./Loading.svelte";
6
6
  export let label = "Pagination";
7
- export let page;
7
+ export let pageDisplayed;
8
8
  export let totalCount = void 0;
9
9
  export let pageSize = 25;
10
10
  const update = (op) => {
11
11
  if (op === "+") {
12
12
  if (canGoNext) {
13
- page = page + 1;
13
+ pageDisplayed = pageDisplayed + 1;
14
14
  }
15
15
  } else {
16
- if (page > 1) {
17
- page = page - 1;
16
+ if (pageDisplayed > 1) {
17
+ pageDisplayed = pageDisplayed - 1;
18
18
  }
19
19
  }
20
20
  };
21
21
  $: isValidValue = totalCount !== void 0 && totalCount !== null;
22
22
  $: needPaginate = isValidValue && (totalCount ?? 0) > pageSize;
23
- $: canGoNext = isValidValue && needPaginate && page < Math.ceil((totalCount ?? 0) / pageSize);
23
+ $: canGoNext = isValidValue && needPaginate && pageDisplayed < Math.ceil((totalCount ?? 0) / pageSize);
24
24
  </script>
25
25
 
26
26
  <FieldContainer {label} forId="paginate" classes={{ label: 'justify-end' }}>
27
- <div class="flex items-center justify-end">
27
+ <div class="flex w-36 items-center justify-end">
28
28
  {#if totalCount === undefined}
29
- <Loading class="mx-2 h-8 w-1/2"></Loading>
29
+ <Loading class="ml-6 mr-2 h-3 w-1/6"></Loading>
30
+ <Loading class="mx-2 h-4 w-1/2"></Loading>
31
+ <Loading class="mx-2 h-3 w-1/6"></Loading>
30
32
  {:else if !needPaginate}
31
33
  <span class="text-primary justify-end px-2 font-bold">
32
34
  {totalCount}
@@ -36,7 +38,7 @@ $: canGoNext = isValidValue && needPaginate && page < Math.ceil((totalCount ?? 0
36
38
  <button
37
39
  aria-label="left"
38
40
  on:click={() => update('-')}
39
- class="btn join-item {page === 1 ? 'btn-disabled' : ''}"
41
+ class="btn join-item p-1 {pageDisplayed === 1 ? 'btn-disabled' : ''}"
40
42
  >
41
43
  <Icon data={LibIcon_ChevronLeft} />
42
44
  </button>
@@ -44,7 +46,7 @@ $: canGoNext = isValidValue && needPaginate && page < Math.ceil((totalCount ?? 0
44
46
  <button aria-label="current" class="btn join-item px-0">
45
47
  <span class="text-primary font-bold">{totalCount}</span>
46
48
  <span class="text-[0.55rem] italic"
47
- >({page} / {Math.ceil((totalCount ?? 0) / pageSize)})</span
49
+ >({pageDisplayed} / {Math.ceil((totalCount ?? 0) / pageSize)})</span
48
50
  >
49
51
  </button>
50
52
  {:else}
@@ -53,7 +55,7 @@ $: canGoNext = isValidValue && needPaginate && page < Math.ceil((totalCount ?? 0
53
55
  <button
54
56
  aria-label="right"
55
57
  on:click={() => update('+')}
56
- class="btn join-item {!canGoNext ? 'btn-disabled' : ''}"
58
+ class="btn join-item p-1 {!canGoNext ? 'btn-disabled' : ''}"
57
59
  >
58
60
  <Icon data={LibIcon_ChevronRight} />
59
61
  </button>
@@ -3,7 +3,7 @@ import './LibIcon';
3
3
  declare const __propDef: {
4
4
  props: {
5
5
  label?: string | undefined;
6
- page: number;
6
+ pageDisplayed: number;
7
7
  totalCount?: number | undefined | null;
8
8
  pageSize?: number | undefined;
9
9
  };
@@ -40,11 +40,7 @@ function dispatchChange(_data) {
40
40
  />
41
41
  <div
42
42
  class={tw(
43
- `border-base-content/60
44
- bg-base-100
45
- relative z-40 max-h-[90vh] overflow-visible rounded-xl
46
- border p-6
47
- shadow-lg`,
43
+ `border-base-content/60 bg-base-100 relative z-40 max-h-[90vh] overflow-visible rounded-xl border p-6 shadow-lg`,
48
44
  classes.root,
49
45
  )}
50
46
  transition:flyAndScale={{
@@ -29,6 +29,15 @@ type ResultClose<entityType = any> = {
29
29
  item?: entityType;
30
30
  };
31
31
  export type DialogType = 'custom' | 'confirm' | 'confirmDelete' | 'insert' | 'update' | 'view';
32
+ export type DialogFormType<entityType> = {
33
+ cells?: CellsInput<entityType>;
34
+ defaults?: Partial<entityType>;
35
+ classes?: DialogClasses;
36
+ noThrow?: boolean;
37
+ wDelete?: boolean;
38
+ topicPrefixText?: string;
39
+ focusKey?: string;
40
+ };
32
41
  export type DialogMetaDataInternal<entityType = any> = DialogMetaData<entityType> & {
33
42
  id: number;
34
43
  type: DialogType;
@@ -37,14 +46,7 @@ export type DialogMetaDataInternal<entityType = any> = DialogMetaData<entityType
37
46
  export declare const dialog: {
38
47
  confirm: (topic: string, text: string, icon?: string) => Promise<ResultClose<any>>;
39
48
  confirmDelete: (topic: string) => Promise<ResultClose<any>>;
40
- form: <entityType>(type: 'insert' | 'update' | 'view', topic: string, repo: Repository<entityType>, cells: CellsInput<entityType>, options?: {
41
- defaults?: Partial<entityType>;
42
- classes?: DialogClasses;
43
- noThrow?: boolean;
44
- wDelete?: boolean;
45
- topicPrefixText?: string;
46
- focusKey?: string;
47
- }) => Promise<ResultClose<any>>;
49
+ form: <entityType>(type: 'insert' | 'update' | 'view', topic: string, repo: Repository<entityType>, settings: DialogFormType<entityType>) => Promise<ResultClose<any>>;
48
50
  show: (dialog: DialogMetaData) => Promise<ResultClose<any>>;
49
51
  close: (id: number, result: ResultClose) => void;
50
52
  closeAll: () => void;
@@ -42,10 +42,9 @@ const createDialogManagement = () => {
42
42
  };
43
43
  return show(detail, 'confirmDelete');
44
44
  },
45
- // FIXME JYC: refactor this (no need repo? options?)
46
- form: (type, topic, repo, cells, options) => {
47
- const topicPrefixText = options?.topicPrefixText
48
- ? options?.topicPrefixText + ' '
45
+ form: (type, topic, repo, settings) => {
46
+ const topicPrefixText = settings?.topicPrefixText
47
+ ? settings?.topicPrefixText + ' '
49
48
  : type === 'insert'
50
49
  ? `Créer `
51
50
  : type === 'update'
@@ -60,12 +59,12 @@ const createDialogManagement = () => {
60
59
  },
61
60
  repo,
62
61
  // store,
63
- cells,
64
- defaults: options?.defaults,
65
- classes: options?.classes,
66
- noThrow: options?.noThrow,
67
- wDelete: options?.wDelete,
68
- focusKey: options?.focusKey,
62
+ cells: settings.cells ?? [],
63
+ defaults: settings?.defaults,
64
+ classes: settings?.classes,
65
+ noThrow: settings?.noThrow,
66
+ wDelete: settings?.wDelete,
67
+ focusKey: settings?.focusKey,
69
68
  topicPrefixText,
70
69
  };
71
70
  return show(detail, type);
@@ -20,7 +20,7 @@ const debounce = (fn) => {
20
20
  };
21
21
  function dispatchInput(value2) {
22
22
  if ($$restProps.type === "date") {
23
- if (value2) {
23
+ if (value2 || value2 === null) {
24
24
  dispatch("input", { value: transformDate(value2) });
25
25
  }
26
26
  } else {
@@ -37,6 +37,12 @@ const handleInput = (e) => {
37
37
  } else {
38
38
  value = target.value.toString().replaceAll(",", ".");
39
39
  }
40
+ } else if ($$restProps.type === "date") {
41
+ if (target.value === "") {
42
+ value = null;
43
+ } else {
44
+ value = target.value;
45
+ }
40
46
  } else {
41
47
  value = target.value;
42
48
  }
@@ -49,6 +55,9 @@ const handleInput = (e) => {
49
55
  }
50
56
  };
51
57
  const transformDate = (input) => {
58
+ if (input === null) {
59
+ return null;
60
+ }
52
61
  const rawDateSplited = input.split("-");
53
62
  if (rawDateSplited.length === 3) {
54
63
  const yearSplited = rawDateSplited[0].split("");