-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathuseParserDefaultValue.tsx
More file actions
75 lines (71 loc) · 2.26 KB
/
useParserDefaultValue.tsx
File metadata and controls
75 lines (71 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import React from 'react';
import type { AnySchema } from '../components/DataModel/helperTypes';
import type { SpecifyResource } from '../components/DataModel/legacyTypes';
import type {
LiteralField,
Relationship,
} from '../components/DataModel/specifyField';
import { getDateInputValue } from '../utils/dayJs';
import type { Parser } from '../utils/parser/definitions';
import { parseAnyDate } from '../utils/relativeDate';
/**
* Handles setting the default value of a field if needed on a resource
* according to some parser.
*
* If you don't have a parser, you can use `resolveParser` or `useParser` to
* generate one given the field and resource
*
* Example:
* ```
* const parser = useParser(field, resource);
* useParserDefaultValue(resource, field, parser);
* ```
*
*/
export function useParserDefaultValue(
resource: SpecifyResource<AnySchema> | undefined,
field: LiteralField | Relationship | undefined,
parser: Parser
) {
React.useLayoutEffect(() => {
if (field === undefined || resource === undefined) return;
/*
* Don't auto set numeric to "0", unless it is the default value
* in the form definition
*/
const hasDefault =
parser.value !== undefined &&
(parser.type !== 'number' || parser.value !== 0);
const fieldValue = resource.get(field.name) as
| boolean
| number
| string
| null
| undefined;
if (
hasDefault &&
/*
* Even if resource is new, some values may be prepopulated (i.e, by
* PrepDialog). This is a crude check to see if form's default value
* should overwrite that of the resource
*/
resource.isNew() &&
(parser.type !== 'number' ||
typeof fieldValue !== 'number' ||
fieldValue === 0) &&
((parser.type !== 'text' && parser.type !== 'date') ||
typeof fieldValue !== 'string' ||
fieldValue === '') &&
(parser.type !== 'checkbox' || typeof fieldValue !== 'boolean')
)
resource.set(
field.name,
(parser.type === 'date'
? (getDateInputValue(
parseAnyDate(parser.value?.toString() ?? '') ?? new Date()
) ?? new Date())
: parser.value) as never,
{ silent: true }
);
}, [parser, resource, field]);
}