5htp-core 0.4.9-1 → 0.4.9-2
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/package.json +1 -1
- package/src/client/assets/css/components/table.less +1 -0
- package/src/client/components/Table/index.tsx +24 -79
- package/src/client/components/inputv3/base.tsx +2 -2
- package/src/client/components/inputv3/index.tsx +1 -1
- package/src/common/validation/schema.ts +8 -2
- package/src/common/validation/validator.ts +3 -3
- package/src/server/services/router/request/index.ts +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "Convenient TypeScript framework designed for Performance and Productivity.",
|
|
4
|
-
"version": "0.4.9-
|
|
4
|
+
"version": "0.4.9-2",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,7 +29,8 @@ export type Props<TRow> = {
|
|
|
29
29
|
empty?: ComponentChild | false,
|
|
30
30
|
className?: string,
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
selection?: [TRow[], React.SetStateAction<TRow[]>],
|
|
33
|
+
maxSelection?: number,
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export type TColumn = JSX.HTMLAttributes<HTMLElement> & {
|
|
@@ -39,24 +40,26 @@ export type TColumn = JSX.HTMLAttributes<HTMLElement> & {
|
|
|
39
40
|
stick?: boolean,
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
export type TAction<TRow> = Omit<TButtonProps, 'onClick'> & {
|
|
43
|
-
onClick: (row: TRow) => void,
|
|
44
|
-
label: ComponentChild,
|
|
45
|
-
multi?: boolean,
|
|
46
|
-
default?: boolean,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
43
|
/*----------------------------------
|
|
50
44
|
- COMPOSANTS
|
|
51
45
|
----------------------------------*/
|
|
52
46
|
export default function Liste<TRow extends TDonneeInconnue>({
|
|
53
47
|
stickyHeader,
|
|
54
48
|
data: rows, setData, empty,
|
|
55
|
-
|
|
49
|
+
selection: selectionState, maxSelection,
|
|
50
|
+
columns, ...props
|
|
56
51
|
}: Props<TRow>) {
|
|
57
52
|
|
|
58
53
|
const { modal } = useContext();
|
|
59
54
|
|
|
55
|
+
// Selection
|
|
56
|
+
const selection = selectionState ? {
|
|
57
|
+
current: selectionState[0],
|
|
58
|
+
set: selectionState[1],
|
|
59
|
+
isMultiple: maxSelection === undefined || maxSelection > 1
|
|
60
|
+
} : undefined;
|
|
61
|
+
|
|
62
|
+
// Empty data
|
|
60
63
|
if (rows.length === 0)
|
|
61
64
|
return empty === false ? null : (
|
|
62
65
|
<div class={"pd-2 col al-center " + (props.className || '')}>
|
|
@@ -67,32 +70,28 @@ export default function Liste<TRow extends TDonneeInconnue>({
|
|
|
67
70
|
</div>
|
|
68
71
|
);
|
|
69
72
|
|
|
70
|
-
const [selection, setSelection] = React.useState<number[]>([]);
|
|
71
|
-
const selectionMultiple = actions && actions.some((action) => action.multi);
|
|
72
|
-
|
|
73
|
-
const defaultAction = actions && actions.find((action) => action.default);
|
|
74
|
-
|
|
75
73
|
/*----------------------------------
|
|
76
74
|
- RENDU COLONNES / LIGNES
|
|
77
75
|
----------------------------------*/
|
|
78
76
|
let renduColonnes: ComponentChild[] = [];
|
|
79
77
|
|
|
80
78
|
const renduLignes = rows.map((row: TRow, iDonnee: number) => (
|
|
81
|
-
<tr {...
|
|
82
|
-
onClick: () =>
|
|
79
|
+
<tr {...(maxSelection === 1 && selection) ? {
|
|
80
|
+
onClick: () => selection.set([row]),
|
|
83
81
|
class: 'clickable'
|
|
84
82
|
} : {}}>
|
|
85
|
-
|
|
83
|
+
|
|
84
|
+
{selection?.isMultiple && (
|
|
86
85
|
<td>
|
|
87
86
|
<Checkbox
|
|
88
87
|
id={"selectionner" + iDonnee}
|
|
89
|
-
value={selection.
|
|
90
|
-
onChange={(
|
|
91
|
-
|
|
88
|
+
value={selection.current.some(s => s.id === row.id)}
|
|
89
|
+
onChange={(isSelected: boolean) => {
|
|
90
|
+
selection.set(current => isSelected
|
|
92
91
|
// Ajoute
|
|
93
|
-
? [...current, row
|
|
92
|
+
? [...current, row]
|
|
94
93
|
// Retire
|
|
95
|
-
: current.filter((
|
|
94
|
+
: current.filter((currentElem) => currentElem.id !== row.id))
|
|
96
95
|
}}
|
|
97
96
|
/>
|
|
98
97
|
</td>
|
|
@@ -164,27 +163,6 @@ export default function Liste<TRow extends TDonneeInconnue>({
|
|
|
164
163
|
</td>
|
|
165
164
|
)
|
|
166
165
|
})}
|
|
167
|
-
|
|
168
|
-
{actions !== undefined && (
|
|
169
|
-
<td class="stickyColumn">
|
|
170
|
-
<Popover content={(
|
|
171
|
-
<ul class="col menu card bg white">
|
|
172
|
-
{actions.map(({ label, onClick, ...props }: TAction<TRow>) => (
|
|
173
|
-
<li>
|
|
174
|
-
<Button {...props}
|
|
175
|
-
onClick={() => onClick && onClick(row)}
|
|
176
|
-
|
|
177
|
-
>
|
|
178
|
-
{label}
|
|
179
|
-
</Button>
|
|
180
|
-
</li>
|
|
181
|
-
))}
|
|
182
|
-
</ul>
|
|
183
|
-
)}>
|
|
184
|
-
<Button size="s" icon="solid/ellipsis-h" />
|
|
185
|
-
</Popover>
|
|
186
|
-
</td>
|
|
187
|
-
)}
|
|
188
166
|
</tr>
|
|
189
167
|
));
|
|
190
168
|
|
|
@@ -202,57 +180,24 @@ export default function Liste<TRow extends TDonneeInconnue>({
|
|
|
202
180
|
<table>
|
|
203
181
|
<thead className={stickyHeader ? 'stickyHeader' : undefined}>
|
|
204
182
|
<tr>
|
|
205
|
-
{
|
|
183
|
+
{selection?.isMultiple && (
|
|
206
184
|
<th>
|
|
207
185
|
<Checkbox
|
|
208
|
-
value={selection.length >= rows.length}
|
|
186
|
+
value={selection.current.length >= rows.length}
|
|
209
187
|
onChange={(status: boolean) => {
|
|
210
|
-
|
|
188
|
+
selection.set(status ? rows : []);
|
|
211
189
|
}}
|
|
212
190
|
/>
|
|
213
191
|
</th>
|
|
214
192
|
)}
|
|
215
193
|
|
|
216
194
|
{renduColonnes}
|
|
217
|
-
|
|
218
|
-
{actions !== undefined && (
|
|
219
|
-
<th>Actions</th>
|
|
220
|
-
)}
|
|
221
195
|
</tr>
|
|
222
196
|
</thead>
|
|
223
197
|
<tbody>
|
|
224
198
|
{renduLignes}
|
|
225
199
|
</tbody>
|
|
226
200
|
</table>
|
|
227
|
-
|
|
228
|
-
{(selection.length !== 0 && actions) && (
|
|
229
|
-
<footer>
|
|
230
|
-
<div className="card pdv-05 row inline pos_bottom">
|
|
231
|
-
<strong>{selection.length} selected items</strong>
|
|
232
|
-
|
|
233
|
-
{actions.map(({ label, multi, onClick, ...props }: TAction<TRow>) => {
|
|
234
|
-
|
|
235
|
-
if (!multi)
|
|
236
|
-
return;
|
|
237
|
-
|
|
238
|
-
const selectedRows = selection.map((index: number) => rows[index]);
|
|
239
|
-
|
|
240
|
-
return (
|
|
241
|
-
<Button
|
|
242
|
-
{...props}
|
|
243
|
-
onClick={() => onClick && onClick(selectedRows)}
|
|
244
|
-
>
|
|
245
|
-
{label}
|
|
246
|
-
</Button>
|
|
247
|
-
)
|
|
248
|
-
})}
|
|
249
|
-
|
|
250
|
-
<Button onClick={() => setSelection([])}>
|
|
251
|
-
Cancel
|
|
252
|
-
</Button>
|
|
253
|
-
</div>
|
|
254
|
-
</footer>
|
|
255
|
-
)}
|
|
256
201
|
</div>
|
|
257
202
|
</>
|
|
258
203
|
}
|
|
@@ -69,7 +69,7 @@ export function useInput<TValue>(
|
|
|
69
69
|
if (state.changed === false)
|
|
70
70
|
return;
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
console.log(`[input] Commit value:`, state.value, externalValue);
|
|
73
73
|
if (onChange !== undefined)
|
|
74
74
|
onChange(state.value);
|
|
75
75
|
}
|
|
@@ -78,7 +78,7 @@ export function useInput<TValue>(
|
|
|
78
78
|
React.useEffect(() => {
|
|
79
79
|
|
|
80
80
|
if (externalValue !== undefined && externalValue !== state.value) {
|
|
81
|
-
|
|
81
|
+
console.log("External value change", externalValue);
|
|
82
82
|
setState({ value: externalValue, valueSource: 'external', changed: true })
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -64,7 +64,7 @@ export default (props: Props & InputBaseProps<string> & TInputElementProps) => {
|
|
|
64
64
|
- INIT
|
|
65
65
|
----------------------------------*/
|
|
66
66
|
|
|
67
|
-
const [{ value, focus, fieldProps }, setValue, commitValue, setState] = useInput(props, ''
|
|
67
|
+
const [{ value, focus, fieldProps }, setValue, commitValue, setState] = useInput(props, '');
|
|
68
68
|
|
|
69
69
|
// Trigger onchange oly when finished typing
|
|
70
70
|
const refCommit = React.useRef<NodeJS.Timeout | null>(null);
|
|
@@ -14,7 +14,7 @@ import defaultValidators, { SchemaValidators, getFieldValidator } from './valida
|
|
|
14
14
|
----------------------------------*/
|
|
15
15
|
|
|
16
16
|
export type TSchemaFields = {
|
|
17
|
-
[fieldName: string]: TSchemaFields | Schema<{}> | TValidatorDefinition
|
|
17
|
+
[fieldName: string]: TSchemaFields | Schema<{}> | Validator<any> | TValidatorDefinition
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
type TSchemaOptions = {
|
|
@@ -42,9 +42,15 @@ export type TSchemaData<TSchema extends Schema<{}>> =
|
|
|
42
42
|
|
|
43
43
|
export type TValidatedData<TFields extends TSchemaFields> = {
|
|
44
44
|
// For each field, the values returned by validator.validate()
|
|
45
|
-
[name in keyof TFields]:
|
|
45
|
+
[name in keyof TFields]: TFieldReturnType<TFields[name]>
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
type TFieldReturnType<TField> = TField extends TValidatorDefinition
|
|
49
|
+
? TField[2]
|
|
50
|
+
: TField extends Schema<infer T>
|
|
51
|
+
? TValidatedData<T>
|
|
52
|
+
: never
|
|
53
|
+
|
|
48
54
|
/*----------------------------------
|
|
49
55
|
- CONST
|
|
50
56
|
----------------------------------*/
|
|
@@ -18,9 +18,9 @@ import type { InputBaseProps } from '@client/components/inputv3/base';
|
|
|
18
18
|
----------------------------------*/
|
|
19
19
|
|
|
20
20
|
export type TValidatorDefinition<K extends keyof SchemaValidators = keyof SchemaValidators> = [
|
|
21
|
-
type:
|
|
22
|
-
args:
|
|
23
|
-
returnType:
|
|
21
|
+
type: string,
|
|
22
|
+
args: any[],
|
|
23
|
+
returnType: string
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
// TODO: remove
|