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.
- package/CHANGELOG.md +23 -0
- package/esm/BaseEnum.d.ts +2 -13
- package/esm/BaseEnum.js +0 -4
- package/esm/FF_Entity.js +20 -4
- package/esm/SqlDatabase/FF_LogToConsole.d.ts +4 -1
- package/esm/SqlDatabase/FF_LogToConsole.js +15 -8
- package/esm/api/index.d.ts +4 -4
- package/esm/api/index.js +13 -13
- package/esm/auth/Adapter.js +1 -9
- package/esm/auth/AuthController.server.d.ts +1 -2
- package/esm/auth/AuthController.server.js +21 -12
- package/esm/auth/RoleHelpers.d.ts +2 -2
- package/esm/auth/RoleHelpers.js +6 -4
- package/esm/auth/client/Auth.d.ts +11 -4
- package/esm/auth/client/Auth.js +14 -6
- package/esm/auth/{Entities.d.ts → client/Entities.d.ts} +4 -4
- package/esm/auth/{Entities.js → client/Entities.js} +33 -17
- package/esm/auth/client/index.d.ts +5 -0
- package/esm/auth/client/index.js +5 -0
- package/esm/auth/helper.d.ts +6 -1
- package/esm/auth/helper.js +11 -4
- package/esm/auth/index.d.ts +11 -11
- package/esm/auth/index.js +93 -78
- package/esm/auth/providers/github.js +2 -1
- package/esm/auth/providers/index.js +1 -1
- package/esm/auth/providers/strava.js +2 -1
- package/esm/auth/static/assets/{Page-RIbXHuZG.d.ts → Page-BEFYPjis.d.ts} +1 -1
- package/esm/auth/static/assets/{Page-RIbXHuZG.js → Page-BEFYPjis.js} +1 -1
- package/esm/auth/static/assets/Page-Cfysx_UV.d.ts +6 -0
- package/esm/auth/static/assets/Page-Cfysx_UV.js +18 -0
- package/esm/auth/static/assets/{Page-DBWJjlEQ.d.ts → Page-DtgkOCJs.d.ts} +1 -1
- package/esm/auth/static/assets/{Page-DBWJjlEQ.js → Page-DtgkOCJs.js} +1 -1
- package/esm/auth/static/assets/index-QypqCYwC.d.ts +63 -0
- package/esm/auth/static/assets/index-QypqCYwC.js +2 -0
- package/esm/auth/static/index.html +1 -1
- package/esm/auth/types.d.ts +7 -5
- package/esm/bin/cmd.js +28 -14
- package/esm/cellsBuildor.d.ts +5 -4
- package/esm/cellsBuildor.js +42 -17
- package/esm/changeLog/index.d.ts +23 -7
- package/esm/changeLog/index.js +24 -18
- package/esm/feedback/FeedbackController.d.ts +12 -3
- package/esm/feedback/FeedbackController.js +62 -13
- package/esm/feedback/index.d.ts +1 -0
- package/esm/feedback/ui/DialogIssue.svelte +26 -7
- package/esm/feedback/ui/DialogIssues.svelte +7 -2
- package/esm/handle/index.d.ts +1 -1
- package/esm/helper.js +3 -2
- package/esm/index.d.ts +10 -3
- package/esm/index.js +1 -1
- package/esm/mail/index.js +15 -10
- package/esm/storeList.d.ts +3 -1
- package/esm/storeList.js +20 -10
- package/esm/ui/Field.svelte +11 -13
- package/esm/ui/FieldGroup.svelte +4 -2
- package/esm/ui/Grid.svelte +90 -20
- package/esm/ui/Grid.svelte.d.ts +1 -0
- package/esm/ui/GridPaginate.svelte +12 -10
- package/esm/ui/GridPaginate.svelte.d.ts +1 -1
- package/esm/ui/dialog/DialogPrimitive.svelte +1 -5
- package/esm/ui/dialog/dialog.d.ts +10 -8
- package/esm/ui/dialog/dialog.js +9 -10
- package/esm/ui/internals/Input.svelte +10 -1
- package/esm/ui/link/LinkPlus.svelte +41 -29
- package/esm/vite/index.js +4 -1
- package/package.json +8 -8
- package/esm/auth/static/assets/Page-apb_xgZT.d.ts +0 -6
- package/esm/auth/static/assets/Page-apb_xgZT.js +0 -18
- package/esm/auth/static/assets/index-qfq98Nyd.d.ts +0 -63
- 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
|
+
/// <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?:
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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) {
|
package/esm/storeList.d.ts
CHANGED
|
@@ -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
|
-
|
|
47
|
-
|
|
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,
|
|
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
|
-
|
|
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.
|
|
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,
|
|
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
|
-
|
|
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 } : {}) };
|
package/esm/ui/Field.svelte
CHANGED
|
@@ -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
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
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'}
|
package/esm/ui/FieldGroup.svelte
CHANGED
|
@@ -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
|
|
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
|
};
|
package/esm/ui/Grid.svelte
CHANGED
|
@@ -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="
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
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}
|
package/esm/ui/Grid.svelte.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
13
|
+
pageDisplayed = pageDisplayed + 1;
|
|
14
14
|
}
|
|
15
15
|
} else {
|
|
16
|
-
if (
|
|
17
|
-
|
|
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 &&
|
|
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="
|
|
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 {
|
|
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
|
-
>({
|
|
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>
|
|
@@ -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>,
|
|
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;
|
package/esm/ui/dialog/dialog.js
CHANGED
|
@@ -42,10 +42,9 @@ const createDialogManagement = () => {
|
|
|
42
42
|
};
|
|
43
43
|
return show(detail, 'confirmDelete');
|
|
44
44
|
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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:
|
|
65
|
-
classes:
|
|
66
|
-
noThrow:
|
|
67
|
-
wDelete:
|
|
68
|
-
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("");
|