firstly 0.0.12 → 0.0.14

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 (120) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/esm/ROUTES.d.ts +2 -0
  3. package/esm/ROUTES.js +1 -0
  4. package/esm/api/index.d.ts +9 -0
  5. package/esm/api/index.js +3 -1
  6. package/esm/auth/AuthController.d.ts +12 -23
  7. package/esm/auth/AuthController.js +12 -31
  8. package/esm/auth/server/AuthController.server.d.ts +11 -11
  9. package/esm/auth/server/AuthController.server.js +99 -34
  10. package/esm/auth/server/handleGuard.d.ts +16 -0
  11. package/esm/auth/server/handleGuard.js +67 -0
  12. package/esm/auth/server/helperFirstly.d.ts +1 -1
  13. package/esm/auth/server/helperFirstly.js +1 -0
  14. package/esm/auth/server/index.d.ts +3 -1
  15. package/esm/auth/server/index.js +3 -1
  16. package/esm/auth/server/module.d.ts +105 -89
  17. package/esm/auth/server/module.js +55 -42
  18. package/esm/auth/server/providers/github.d.ts +4 -2
  19. package/esm/auth/server/providers/github.js +2 -2
  20. package/esm/auth/static/assets/Page-B0XXxe0N.d.ts +6 -0
  21. package/esm/auth/static/assets/Page-B0XXxe0N.js +1 -0
  22. package/esm/auth/static/assets/Page-DdKMiUZn.d.ts +6 -0
  23. package/esm/auth/static/assets/Page-DdKMiUZn.js +20 -0
  24. package/esm/auth/static/assets/Page-UV_hqY7I.d.ts +6 -0
  25. package/esm/auth/static/assets/Page-UV_hqY7I.js +1 -0
  26. package/esm/auth/static/assets/Page-mK42zGEw.css +1 -0
  27. package/esm/auth/static/assets/index-C9jzxOBu.d.ts +151 -0
  28. package/esm/auth/static/assets/index-C9jzxOBu.js +42 -0
  29. package/esm/auth/static/assets/index-DKWpA6v7.css +4 -0
  30. package/esm/auth/static/index.html +11 -11
  31. package/esm/auth/types.d.ts +26 -3
  32. package/esm/bin/cmd.js +423 -152
  33. package/esm/cellsBuildor.js +1 -1
  34. package/esm/common.d.ts +5 -0
  35. package/esm/common.js +8 -0
  36. package/esm/cron/server/index.js +1 -1
  37. package/esm/feedback/FeedbackController.js +58 -53
  38. package/esm/feedback/server/index.d.ts +6 -15
  39. package/esm/feedback/server/index.js +4 -5
  40. package/esm/feedback/types.d.ts +14 -0
  41. package/esm/feedback/types.js +4 -0
  42. package/esm/feedback/ui/DialogIssue.svelte +131 -119
  43. package/esm/feedback/ui/DialogIssue.svelte.d.ts +20 -18
  44. package/esm/feedback/ui/DialogIssues.svelte +108 -99
  45. package/esm/feedback/ui/DialogIssues.svelte.d.ts +20 -18
  46. package/esm/feedback/ui/DialogMilestones.svelte +40 -34
  47. package/esm/feedback/ui/DialogMilestones.svelte.d.ts +18 -16
  48. package/esm/feedback/ui/Feedback.svelte +11 -9
  49. package/esm/feedback/ui/Feedback.svelte.d.ts +16 -14
  50. package/esm/index.d.ts +2 -5
  51. package/esm/index.js +2 -8
  52. package/esm/mail/server/index.d.ts +9 -2
  53. package/esm/mail/server/index.js +3 -1
  54. package/esm/mail/templates/DefaultMail.svelte +81 -61
  55. package/esm/mail/templates/DefaultMail.svelte.d.ts +28 -26
  56. package/esm/server/index.d.ts +0 -0
  57. package/esm/server/index.js +1 -0
  58. package/esm/storeItem.d.ts +1 -4
  59. package/esm/storeItem.js +1 -1
  60. package/esm/storeList.d.ts +1 -4
  61. package/esm/sveltekit/server/index.d.ts +3 -9
  62. package/esm/sveltekit/server/index.js +3 -0
  63. package/esm/ui/Button.svelte +112 -89
  64. package/esm/ui/Button.svelte.d.ts +34 -24
  65. package/esm/ui/Clipboardable.svelte +24 -17
  66. package/esm/ui/Clipboardable.svelte.d.ts +34 -23
  67. package/esm/ui/Field.svelte +328 -285
  68. package/esm/ui/Field.svelte.d.ts +15 -8
  69. package/esm/ui/FieldGroup.svelte +112 -91
  70. package/esm/ui/FieldGroup.svelte.d.ts +17 -6
  71. package/esm/ui/Grid.svelte +322 -308
  72. package/esm/ui/Grid.svelte.d.ts +17 -6
  73. package/esm/ui/GridLoading.svelte +28 -27
  74. package/esm/ui/GridLoading.svelte.d.ts +19 -17
  75. package/esm/ui/GridPaginate.svelte +68 -61
  76. package/esm/ui/GridPaginate.svelte.d.ts +21 -19
  77. package/esm/ui/Icon.svelte +116 -80
  78. package/esm/ui/Icon.svelte.d.ts +52 -43
  79. package/esm/ui/Loading.svelte +10 -8
  80. package/esm/ui/Loading.svelte.d.ts +29 -18
  81. package/esm/ui/Tooltip.svelte +38 -35
  82. package/esm/ui/Tooltip.svelte.d.ts +30 -20
  83. package/esm/ui/dialog/DialogForm.svelte +70 -63
  84. package/esm/ui/dialog/DialogForm.svelte.d.ts +18 -16
  85. package/esm/ui/dialog/DialogManagement.svelte +74 -74
  86. package/esm/ui/dialog/DialogManagement.svelte.d.ts +22 -21
  87. package/esm/ui/dialog/DialogPrimitive.svelte +82 -76
  88. package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +35 -25
  89. package/esm/ui/dialog/FormEditAction.svelte +58 -50
  90. package/esm/ui/dialog/FormEditAction.svelte.d.ts +13 -6
  91. package/esm/ui/dialog/dialog.d.ts +1 -4
  92. package/esm/ui/internals/FieldContainer.svelte +24 -17
  93. package/esm/ui/internals/FieldContainer.svelte.d.ts +37 -28
  94. package/esm/ui/internals/Input.svelte +136 -102
  95. package/esm/ui/internals/Input.svelte.d.ts +34 -32
  96. package/esm/ui/internals/Textarea.svelte +60 -52
  97. package/esm/ui/internals/Textarea.svelte.d.ts +31 -28
  98. package/esm/ui/internals/select/MultiSelectMelt.svelte +243 -199
  99. package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +29 -27
  100. package/esm/ui/internals/select/SelectMelt.svelte +254 -219
  101. package/esm/ui/internals/select/SelectMelt.svelte.d.ts +34 -32
  102. package/esm/ui/internals/select/SelectRadio.svelte +39 -33
  103. package/esm/ui/internals/select/SelectRadio.svelte.d.ts +24 -22
  104. package/esm/ui/link/Link.svelte +25 -20
  105. package/esm/ui/link/Link.svelte.d.ts +31 -23
  106. package/esm/ui/link/LinkPlus.svelte +52 -51
  107. package/esm/ui/link/LinkPlus.svelte.d.ts +20 -18
  108. package/esm/vite/index.d.ts +2 -3
  109. package/esm/vite/index.js +33 -26
  110. package/package.json +16 -20
  111. package/esm/auth/static/assets/Page-Bb8bFlrP.d.ts +0 -4
  112. package/esm/auth/static/assets/Page-Bb8bFlrP.js +0 -1
  113. package/esm/auth/static/assets/Page-BxomFlZ8.d.ts +0 -4
  114. package/esm/auth/static/assets/Page-BxomFlZ8.js +0 -1
  115. package/esm/auth/static/assets/Page-CaIYu0-y.d.ts +0 -6
  116. package/esm/auth/static/assets/Page-CaIYu0-y.js +0 -19
  117. package/esm/auth/static/assets/Page-MkYglNtu.css +0 -1
  118. package/esm/auth/static/assets/index-Bl0Bk5u0.d.ts +0 -64
  119. package/esm/auth/static/assets/index-Bl0Bk5u0.js +0 -2
  120. package/esm/auth/static/assets/index-R27C_TlP.css +0 -4
@@ -1,290 +1,333 @@
1
- <script generics="T extends Record<any, any>">import { createEventDispatcher } from "svelte";
2
- import {} from "remult";
3
- import {} from "../";
4
- import { suffixWithS } from "../formats/strings";
5
- import {
6
- displayWithDefaultAndSuffix,
7
- getEntityDisplayValue,
8
- getFieldMetaType,
9
- getFirstInterestingField
10
- } from "../helper.js";
11
- import { tw } from "../utils/tailwind";
12
- import Clipboardable from "./Clipboardable.svelte";
13
- import Icon from "./Icon.svelte";
14
- import FieldContainer from "./internals/FieldContainer.svelte";
15
- import Input from "./internals/Input.svelte";
16
- import MultiSelectMelt from "./internals/select/MultiSelectMelt.svelte";
17
- import SelectMelt from "./internals/select/SelectMelt.svelte";
18
- import SelectRadio from "./internals/select/SelectRadio.svelte";
19
- import Textarea from "./internals/Textarea.svelte";
20
- import LinkPlus from "./link/LinkPlus.svelte";
21
- export let cell;
22
- export let value = void 0;
23
- export let cellsValues = {};
24
- export let withDedounce = false;
25
- export let error = "";
26
- export let mode = "edit";
27
- export let focus = false;
28
- export let clearable = void 0;
29
- export let disabled = false;
30
- const dispatch = createEventDispatcher();
31
- function dispatchSelected(_data) {
32
- value = _data;
33
- dispatch("selected", _data);
34
- }
35
- $: metaType = getFieldMetaType(cell.field);
36
- const isViewMode = (_mode, _field) => {
37
- return _mode === "view" || _field?.dbReadOnly || _field?.options.allowApiUpdate === false;
38
- };
39
- const common = (_field, isLight = false) => {
40
- let toRet = {
41
- id: _field?.key ?? "SOMETHING_AT_LEAST",
42
- disabled: _field?.dbReadOnly || _field?.options.allowApiUpdate === false || disabled,
43
- placeholder: _field?.options?.placeholder ?? void 0
44
- };
45
- if (isLight) {
46
- return toRet;
47
- }
48
- return {
49
- ...toRet,
50
- step: _field?.options?.step ?? void 0,
51
- name: _field?.key
52
- // required: _field?.allowNull === false,
53
- };
54
- };
55
- const toInput = (_metadata, _value) => {
56
- try {
57
- return _metadata?.valueConverter.toInput(_value, metaType.subKind);
58
- } catch (error2) {
59
- console.error(`error toInput w field '${_metadata?.key}'`, error2);
60
- }
61
- };
62
- const fromInput = (_metadata, _value) => {
63
- try {
64
- if (_metadata.allowNull && _value === null) {
65
- return null;
66
- }
67
- return _metadata?.valueConverter.fromInput(_value, metaType.subKind);
68
- } catch (error2) {
69
- console.error(`error fromInput w field '${_metadata.key}'`, error2);
70
- }
71
- };
72
- const getId = () => {
73
- return value?.id || value;
74
- };
75
- const getLoadOptions = async (cellsValues2, str) => {
76
- if (metaType.kind !== "relation") {
77
- return { items: [], totalCount: 0 };
78
- }
79
- const metaTypeObj = { ...metaType };
80
- let findToUse = {};
81
- if (metaTypeObj.repoTarget.metadata.options.searchableFind) {
82
- findToUse = metaTypeObj.repoTarget.metadata.options.searchableFind(str);
83
- } else {
84
- if (str) {
85
- const field = getFirstInterestingField(metaTypeObj.repoTarget);
86
- findToUse = { where: { [field.key]: { $contains: str } } };
87
- }
88
- }
89
- const foEdit = cell.field?.options.findOptionsForEdit;
90
- const narrowFindEditWhere = typeof foEdit === "function" ? foEdit(cellsValues2).where ?? {} : typeof foEdit === "object" ? foEdit.where ?? {} : {};
91
- const foCrud = cell.field?.options.findOptions;
92
- const narrowFindCrudWhere = typeof foCrud === "function" ? foCrud().where ?? {} : typeof foCrud === "object" ? foCrud.where ?? {} : {};
93
- findToUse = {
94
- include: { ...findToUse.include ?? {} },
95
- where: { $and: [findToUse.where, narrowFindEditWhere, narrowFindCrudWhere] }
96
- };
97
- let limit = cell.field?.options.findOptionsLimit ?? 24;
98
- const arr = [];
99
- arr.push(
100
- ...await metaTypeObj.repoTarget.find({
101
- ...findToUse,
102
- limit
103
- })
104
- );
105
- let totalCount = arr.length;
106
- if (totalCount === limit) {
107
- const agg = await metaTypeObj.repoTarget.aggregate({ where: findToUse.where });
108
- totalCount = agg.$count;
109
- }
110
- if (!cell.field?.options.multiSelect) {
111
- if (str === "" && getId() && !arr.find((r) => String(r.id) === String(getId()))) {
112
- arr.unshift(await metaTypeObj.repoTarget.findId(getId()));
113
- }
114
- }
115
- return { items: arr.map((r) => getEntityDisplayValue(metaTypeObj.repoTarget, r)), totalCount };
116
- };
117
- const getMultiValues = (value2) => {
118
- return (value2 ?? []).map((c) => c.id) || value2;
119
- };
120
- const calcSuffix = (value2) => {
121
- if (cell.field?.options.suffixEdit) {
122
- if (cell.field?.options.suffixEditWithS) {
123
- return suffixWithS(value2, cell.field?.options.suffixEdit);
124
- } else {
125
- return cell.field?.options.suffixEdit;
126
- }
127
- }
128
- if (cell.field?.options.suffix) {
129
- if (cell.field?.options.suffixWithS) {
130
- return suffixWithS(value2, cell.field?.options.suffix);
131
- } else {
132
- return cell.field?.options.suffix;
133
- }
134
- }
135
- return "";
136
- };
1
+ <script lang="ts" generics="T extends Record<any, any>">
2
+ import { createEventDispatcher } from 'svelte'
3
+ import type { HTMLInputAttributes } from 'svelte/elements'
4
+
5
+ import { type FieldMetadata, type FindOptions } from 'remult'
6
+
7
+ import { type BaseItem, type Cell } from '../'
8
+ import { suffixWithS } from '../formats/strings'
9
+ import {
10
+ displayWithDefaultAndSuffix,
11
+ getEntityDisplayValue,
12
+ getFieldMetaType,
13
+ getFirstInterestingField,
14
+ type MetaTypeRelation,
15
+ } from '../helper.js'
16
+ import { tw } from '../utils/tailwind'
17
+ import Clipboardable from './Clipboardable.svelte'
18
+ import Icon from './Icon.svelte'
19
+ import FieldContainer from './internals/FieldContainer.svelte'
20
+ import Input from './internals/Input.svelte'
21
+ import MultiSelectMelt from './internals/select/MultiSelectMelt.svelte'
22
+ import SelectMelt from './internals/select/SelectMelt.svelte'
23
+ import SelectRadio from './internals/select/SelectRadio.svelte'
24
+ import Textarea from './internals/Textarea.svelte'
25
+ import LinkPlus from './link/LinkPlus.svelte'
26
+
27
+ export let cell: Cell<T>
28
+ export let value: HTMLInputAttributes['value'] = undefined
29
+
30
+ // values of other fields in same context e.g. in form
31
+ export let cellsValues: any = {}
32
+
33
+ export let withDedounce: boolean = false
34
+
35
+ export let error = ''
36
+
37
+ export let mode: 'edit' | 'view' | 'filtre' = 'edit'
38
+
39
+ export let focus: boolean = false
40
+
41
+ export let clearable: boolean | undefined = undefined
42
+ export let disabled = false
43
+
44
+ const dispatch = createEventDispatcher()
45
+
46
+ function dispatchSelected(_data: BaseItem | BaseItem[] | undefined) {
47
+ value = _data
48
+ dispatch('selected', _data)
49
+ }
50
+ $: metaType = getFieldMetaType(cell.field!)
51
+
52
+ const isViewMode = (_mode: 'edit' | 'view' | 'filtre', _field?: FieldMetadata<any, any>) => {
53
+ return _mode === 'view' || _field?.dbReadOnly || _field?.options.allowApiUpdate === false
54
+ }
55
+
56
+ const common = (_field?: FieldMetadata<any, any>, isLight = false) => {
57
+ let toRet = {
58
+ id: _field?.key ?? 'SOMETHING_AT_LEAST',
59
+ disabled: _field?.dbReadOnly || _field?.options.allowApiUpdate === false || disabled,
60
+ placeholder: _field?.options?.placeholder ?? undefined,
61
+ }
62
+ if (isLight) {
63
+ return toRet
64
+ }
65
+ return {
66
+ ...toRet,
67
+ step: _field?.options?.step ?? undefined,
68
+ name: _field?.key,
69
+ // required: _field?.allowNull === false,
70
+ }
71
+ }
72
+
73
+ const toInput = (_metadata?: FieldMetadata<any, any>, _value?: HTMLInputAttributes['value']) => {
74
+ try {
75
+ return _metadata?.valueConverter.toInput(_value, metaType.subKind)
76
+ } catch (error) {
77
+ console.error(`error toInput w field '${_metadata?.key}'`, error)
78
+ }
79
+ }
80
+
81
+ const fromInput = (_metadata: FieldMetadata<any, any>, _value: HTMLInputAttributes['value']) => {
82
+ try {
83
+ // REMULT default for numbers ?
84
+ if (_metadata.allowNull && _value === null) {
85
+ return null
86
+ }
87
+ return _metadata?.valueConverter.fromInput(_value, metaType.subKind)
88
+ } catch (error) {
89
+ console.error(`error fromInput w field '${_metadata.key}'`, error)
90
+ }
91
+ }
92
+
93
+ // let items: any[] = []
94
+
95
+ const getId = () => {
96
+ return value?.id || value
97
+ }
98
+
99
+ const getLoadOptions = async (cellsValues: any, str: string) => {
100
+ if (metaType.kind !== 'relation') {
101
+ return { items: [], totalCount: 0 }
102
+ }
103
+ // To make TS happy
104
+ const metaTypeObj = { ...metaType } as MetaTypeRelation
105
+
106
+ let findToUse: FindOptions<any> = {}
107
+ if (metaTypeObj.repoTarget.metadata.options.searchableFind) {
108
+ // narrowFind at the end because searchableFind should not change the narrowed part!
109
+ findToUse = metaTypeObj.repoTarget.metadata.options.searchableFind(str)
110
+ } else {
111
+ if (str) {
112
+ const field = getFirstInterestingField(metaTypeObj.repoTarget)
113
+ findToUse = { where: { [field.key]: { $contains: str } } }
114
+ }
115
+ }
116
+
117
+ const foEdit = cell.field?.options.findOptionsForEdit
118
+ const narrowFindEditWhere =
119
+ typeof foEdit === 'function'
120
+ ? (foEdit(cellsValues).where ?? {})
121
+ : typeof foEdit === 'object'
122
+ ? (foEdit.where ?? {})
123
+ : {}
124
+
125
+ // @ts-ignore
126
+ const foCrud = cell.field?.options.findOptions
127
+ const narrowFindCrudWhere =
128
+ typeof foCrud === 'function'
129
+ ? (foCrud().where ?? {})
130
+ : typeof foCrud === 'object'
131
+ ? (foCrud.where ?? {})
132
+ : {}
133
+
134
+ findToUse = {
135
+ include: { ...(findToUse.include ?? {}) },
136
+ where: { $and: [findToUse.where, narrowFindEditWhere, narrowFindCrudWhere] },
137
+ }
138
+
139
+ // 24 here is a "magic number"!
140
+ let limit = cell.field?.options.findOptionsLimit ?? 24
141
+
142
+ const arr = []
143
+ arr.push(
144
+ ...(await metaTypeObj.repoTarget.find({
145
+ ...findToUse,
146
+ limit,
147
+ })),
148
+ )
149
+
150
+ let totalCount = arr.length
151
+ // If we are at the limit... there is probably more! How many?
152
+ if (totalCount === limit) {
153
+ const agg = await metaTypeObj.repoTarget.aggregate({ where: findToUse.where })
154
+ totalCount = agg.$count
155
+ }
156
+
157
+ if (!cell.field?.options.multiSelect) {
158
+ // let's get the current item if it's not in the default list (only when there is no searchFilter going on)
159
+ if (str === '' && getId() && !arr.find((r) => String(r.id) === String(getId()))) {
160
+ arr.unshift(await metaTypeObj.repoTarget.findId(getId()))
161
+ }
162
+ }
163
+
164
+ return { items: arr.map((r) => getEntityDisplayValue(metaTypeObj.repoTarget, r)), totalCount }
165
+ }
166
+
167
+ const getMultiValues = (value: any) => {
168
+ return (value ?? []).map((c: any) => c.id) || value
169
+ }
170
+
171
+ const calcSuffix = (value: any) => {
172
+ if (cell.field?.options.suffixEdit) {
173
+ if (cell.field?.options.suffixEditWithS) {
174
+ return suffixWithS(value, cell.field?.options.suffixEdit)
175
+ } else {
176
+ return cell.field?.options.suffixEdit
177
+ }
178
+ }
179
+
180
+ if (cell.field?.options.suffix) {
181
+ if (cell.field?.options.suffixWithS) {
182
+ return suffixWithS(value, cell.field?.options.suffix)
183
+ } else {
184
+ return cell.field?.options.suffix
185
+ }
186
+ }
187
+
188
+ return ''
189
+ }
137
190
  </script>
138
191
 
139
192
  <FieldContainer
140
- forId={cell.field?.key ?? ''}
141
- label={cell?.header ?? cell.field?.caption ?? cell.field?.key}
142
- required={!cell.field?.allowNull && mode === 'edit' && metaType.subKind !== 'checkbox'}
143
- {error}
144
- classes={{ slot: metaType.subKind === 'textarea' ? 'h-24 items-start' : '' }}
193
+ forId={cell.field?.key ?? ''}
194
+ label={cell?.header ?? cell.field?.caption ?? cell.field?.key}
195
+ required={!cell.field?.allowNull && mode === 'edit' && metaType.subKind !== 'checkbox'}
196
+ {error}
197
+ classes={{ slot: metaType.subKind === 'textarea' ? 'h-24 items-start' : '' }}
145
198
  >
146
- {@const clearableComputed =
147
- cell.clearable || clearable || (mode === 'filtre' && clearable === undefined)}
148
- {#if isViewMode(mode, cell.field)}
149
- <span class="input-bordered flex items-center pl-2 pr-4">
150
- {#if cell.field?.inputType === 'checkbox'}
151
- <input
152
- type="checkbox"
153
- {...common(cell.field)}
154
- class="checkbox ml-2"
155
- disabled
156
- checked={value}
157
- />
158
- {:else if metaType.kind === 'relation'}
159
- {@const item = getEntityDisplayValue(metaType.repoTarget, value)}
160
- <div class={tw('flex items-center gap-4', 'h-12', 'pl-2')}>
161
- <LinkPlus {item}></LinkPlus>
162
- </div>
163
- {:else if metaType.kind === 'enum'}
164
- {@const v = displayWithDefaultAndSuffix(cell.field, value)}
165
- <div class="ml-2 flex h-12 items-center gap-4">
166
- {#if value?.icon}
167
- <Icon {...value.icon} />
168
- {/if}
169
- <Clipboardable value={v}>{v}</Clipboardable>
170
- </div>
171
- {:else}
172
- {@const v = displayWithDefaultAndSuffix(cell.field, value)}
173
- <div
174
- class="ml-2 flex h-12 w-full items-center {metaType.subKind === 'number'
175
- ? 'justify-end'
176
- : ''}"
177
- >
178
- <Clipboardable value={v}>{v}</Clipboardable>
179
- </div>
180
- {/if}
181
- </span>
182
- {:else if metaType.kind === 'relation'}
183
- {#if metaType.field.options.multiSelect}
184
- <MultiSelectMelt
185
- {...common(cell.field, true)}
186
- clearable={clearableComputed}
187
- loadOptions={async (str) => await getLoadOptions(cellsValues, str)}
188
- values={value}
189
- on:selected={(e) => dispatchSelected(e.detail)}
190
- />
191
- {:else}
192
- <!-- {items} -->
193
- <SelectMelt
194
- {focus}
195
- {...common(cell.field, true)}
196
- clearable={clearableComputed}
197
- loadOptions={async (str) => await getLoadOptions(cellsValues, str)}
198
- value={value?.id || value}
199
- on:selected={(e) => dispatchSelected(e.detail)}
200
- on:issue={(e) => {
201
- error = e.detail
202
- }}
203
- createOptionWhenNoResult={!!cell.field?.options.createOptionWhenNoResult}
204
- on:createRequest
205
- />
206
- {/if}
207
- {:else if metaType.kind === 'enum'}
208
- {#if metaType.field.options.multiSelect || metaType.subKind === 'multi'}
209
- <MultiSelectMelt
210
- {...common(cell.field, true)}
211
- clearable={clearableComputed}
212
- items={metaType.values}
213
- values={getMultiValues(value)}
214
- on:selected={(e) => {
215
- dispatchSelected(e.detail)
216
- }}
217
- />
218
- {:else if metaType.values.length <= (cell.field?.options.styleRadioUntil ?? 3) && !clearableComputed}
219
- <SelectRadio
220
- {...common(cell.field, true)}
221
- items={metaType.values}
222
- value={value?.id || value}
223
- on:selected={(e) => dispatchSelected(e.detail)}
224
- />
225
- {:else}
226
- <SelectMelt
227
- {focus}
228
- {...common(cell.field, true)}
229
- clearable={clearableComputed}
230
- items={metaType.values}
231
- value={value?.id || value}
232
- on:selected={(e) => dispatchSelected(e.detail)}
233
- on:issue={(e) => {
234
- error = e.detail
235
- }}
236
- />
237
- {/if}
238
- {:else if metaType.subKind === 'checkbox'}
239
- <div class="grid content-center items-center pl-4">
240
- <input
241
- type="checkbox"
242
- {...{ ...common(cell.field), required: undefined }}
243
- class="checkbox"
244
- checked={value}
245
- on:input={(e) => {
246
- // @ts-ignore
247
- value = e.target.checked
248
- dispatchSelected(value)
249
- }}
250
- />
251
- </div>
252
- {:else if metaType.subKind === 'text' || metaType.subKind === 'email' || metaType.subKind === 'password' || metaType.subKind === 'dateOnly' || metaType.subKind === 'number'}
253
- <div class="input input-bordered inline-flex w-full items-center pl-2">
254
- <Input
255
- {focus}
256
- {...common(cell.field)}
257
- autocomplete="off"
258
- class={tw(
259
- `join-item placeholder:text-base-content/30 w-full bg-transparent`,
260
- metaType.subKind === 'number' && 'text-end',
261
- )}
262
- type={metaType.subKind.replaceAll('dateOnly', 'date')}
263
- value={toInput(cell.field, value)}
264
- {withDedounce}
265
- on:input={(e) => {
266
- // @ts-ignore
267
- value = fromInput(cell.field, e.detail.value)
268
- dispatchSelected(value)
269
- }}
270
- {...$$restProps}
271
- />
272
- {calcSuffix(value)}
273
- </div>
274
- {:else if metaType.subKind === 'textarea'}
275
- <Textarea
276
- {focus}
277
- {...common(cell.field)}
278
- value={toInput(cell.field, value)}
279
- on:input={(e) => {
280
- // @ts-ignore
281
- value = fromInput(cell.field, e.detail.value)
282
- }}
283
- />
284
- {:else}
285
- <!-- This shoud NEVER be displayed -->
286
- <span class="text-error flex items-center pl-2"
287
- >Type "{cell.field?.inputType}" not managed!</span
288
- >
289
- {/if}
199
+ {@const clearableComputed =
200
+ cell.clearable || clearable || (mode === 'filtre' && clearable === undefined)}
201
+ {#if isViewMode(mode, cell.field)}
202
+ <span class="input-bordered flex items-center pl-2 pr-4">
203
+ {#if cell.field?.inputType === 'checkbox'}
204
+ <input type="checkbox" {...common(cell.field)} class="checkbox ml-2" disabled checked={value} />
205
+ {:else if metaType.kind === 'relation'}
206
+ {@const item = getEntityDisplayValue(metaType.repoTarget, value)}
207
+ <div class={tw('flex items-center gap-4', 'h-12', 'pl-2')}>
208
+ <LinkPlus {item}></LinkPlus>
209
+ </div>
210
+ {:else if metaType.kind === 'enum'}
211
+ {@const v = displayWithDefaultAndSuffix(cell.field, value)}
212
+ <div class="ml-2 flex h-12 items-center gap-4">
213
+ {#if value?.icon}
214
+ <Icon {...value.icon} />
215
+ {/if}
216
+ <Clipboardable value={v}>{v}</Clipboardable>
217
+ </div>
218
+ {:else}
219
+ {@const v = displayWithDefaultAndSuffix(cell.field, value)}
220
+ <div
221
+ class="ml-2 flex h-12 w-full items-center {metaType.subKind === 'number' ? 'justify-end' : ''}"
222
+ >
223
+ <Clipboardable value={v}>{v}</Clipboardable>
224
+ </div>
225
+ {/if}
226
+ </span>
227
+ {:else if metaType.kind === 'relation'}
228
+ {#if metaType.field.options.multiSelect}
229
+ <MultiSelectMelt
230
+ {...common(cell.field, true)}
231
+ clearable={clearableComputed}
232
+ loadOptions={async (str) => await getLoadOptions(cellsValues, str)}
233
+ values={value}
234
+ on:selected={(e) => dispatchSelected(e.detail)}
235
+ />
236
+ {:else}
237
+ <!-- {items} -->
238
+ <SelectMelt
239
+ {focus}
240
+ {...common(cell.field, true)}
241
+ clearable={clearableComputed}
242
+ loadOptions={async (str) => await getLoadOptions(cellsValues, str)}
243
+ value={value?.id || value}
244
+ on:selected={(e) => dispatchSelected(e.detail)}
245
+ on:issue={(e) => {
246
+ error = e.detail
247
+ }}
248
+ createOptionWhenNoResult={!!cell.field?.options.createOptionWhenNoResult}
249
+ on:createRequest
250
+ />
251
+ {/if}
252
+ {:else if metaType.kind === 'enum'}
253
+ {#if metaType.field.options.multiSelect || metaType.subKind === 'multi'}
254
+ <MultiSelectMelt
255
+ {...common(cell.field, true)}
256
+ clearable={clearableComputed}
257
+ items={metaType.values}
258
+ values={getMultiValues(value)}
259
+ on:selected={(e) => {
260
+ dispatchSelected(e.detail)
261
+ }}
262
+ />
263
+ {:else if metaType.values.length <= (cell.field?.options.styleRadioUntil ?? 3) && !clearableComputed}
264
+ <SelectRadio
265
+ {...common(cell.field, true)}
266
+ items={metaType.values}
267
+ value={value?.id || value}
268
+ on:selected={(e) => dispatchSelected(e.detail)}
269
+ />
270
+ {:else}
271
+ <SelectMelt
272
+ {focus}
273
+ {...common(cell.field, true)}
274
+ clearable={clearableComputed}
275
+ items={metaType.values}
276
+ value={value?.id || value}
277
+ on:selected={(e) => dispatchSelected(e.detail)}
278
+ on:issue={(e) => {
279
+ error = e.detail
280
+ }}
281
+ />
282
+ {/if}
283
+ {:else if metaType.subKind === 'checkbox'}
284
+ <div class="grid content-center items-center pl-4">
285
+ <input
286
+ type="checkbox"
287
+ {...{ ...common(cell.field), required: undefined }}
288
+ class="checkbox"
289
+ checked={value}
290
+ on:input={(e) => {
291
+ // @ts-ignore
292
+ value = e.target.checked
293
+ dispatchSelected(value)
294
+ }}
295
+ />
296
+ </div>
297
+ {:else if metaType.subKind === 'text' || metaType.subKind === 'email' || metaType.subKind === 'password' || metaType.subKind === 'dateOnly' || metaType.subKind === 'number'}
298
+ <div class="input input-bordered inline-flex w-full items-center pl-2">
299
+ <Input
300
+ {focus}
301
+ {...common(cell.field)}
302
+ autocomplete="off"
303
+ class={tw(
304
+ `join-item placeholder:text-base-content/30 w-full bg-transparent`,
305
+ metaType.subKind === 'number' && 'text-end',
306
+ )}
307
+ type={metaType.subKind.replaceAll('dateOnly', 'date')}
308
+ value={toInput(cell.field, value)}
309
+ {withDedounce}
310
+ on:input={(e) => {
311
+ // @ts-ignore
312
+ value = fromInput(cell.field, e.detail.value)
313
+ dispatchSelected(value)
314
+ }}
315
+ {...$$restProps}
316
+ />
317
+ {calcSuffix(value)}
318
+ </div>
319
+ {:else if metaType.subKind === 'textarea'}
320
+ <Textarea
321
+ {focus}
322
+ {...common(cell.field)}
323
+ value={toInput(cell.field, value)}
324
+ on:input={(e) => {
325
+ // @ts-ignore
326
+ value = fromInput(cell.field, e.detail.value)
327
+ }}
328
+ />
329
+ {:else}
330
+ <!-- This shoud NEVER be displayed -->
331
+ <span class="text-error flex items-center pl-2">Type "{cell.field?.inputType}" not managed!</span>
332
+ {/if}
290
333
  </FieldContainer>