argous 1.2.225 → 1.2.227
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/dist/actions/index.d.ts +4 -0
- package/dist/actions/index.js +5 -1
- package/dist/components/Programa/Programa.js +18 -29
- package/dist/reducers/argous.d.ts +8 -0
- package/dist/reducers/argous.js +4 -1
- package/dist/types.d.ts +8 -2
- package/lib/actions/index.ts +4 -0
- package/lib/components/Programa/Programa.js +18 -23
- package/lib/reducers/argous.ts +7 -1
- package/lib/types.d.ts +8 -2
- package/package.json +1 -1
- package/dist/components/Programa/Annotations/Annotation.d.ts +0 -19
- package/dist/components/Programa/Annotations/Annotation.js +0 -317
- package/dist/components/Programa/Annotations/AnnotationsList.d.ts +0 -3
- package/dist/components/Programa/Annotations/AnnotationsList.js +0 -50
- package/dist/components/Programa/Annotations/Input/FileInput.d.ts +0 -6
- package/dist/components/Programa/Annotations/Input/FileInput.js +0 -147
- package/dist/components/Programa/Annotations/Input/Input.d.ts +0 -3
- package/dist/components/Programa/Annotations/Input/Input.js +0 -218
- package/dist/components/Programa/Annotations/Input/PrivacySelection.d.ts +0 -7
- package/dist/components/Programa/Annotations/Input/PrivacySelection.js +0 -65
- package/dist/components/Programa/Annotations/Input/ReplyInformation.d.ts +0 -5
- package/dist/components/Programa/Annotations/Input/ReplyInformation.js +0 -78
- package/dist/components/Programa/Annotations/Input/UsersAutocomplete.d.ts +0 -7
- package/dist/components/Programa/Annotations/Input/UsersAutocomplete.js +0 -139
- package/dist/components/Programa/Annotations/index.d.ts +0 -23
- package/dist/components/Programa/Annotations/index.js +0 -195
- package/dist/components/Programa/Annotations/utils.d.ts +0 -18
- package/dist/components/Programa/Annotations/utils.js +0 -46
- package/lib/components/Programa/Annotations/Annotation.js +0 -275
- package/lib/components/Programa/Annotations/AnnotationsList.js +0 -30
- package/lib/components/Programa/Annotations/Input/FileInput.js +0 -96
- package/lib/components/Programa/Annotations/Input/Input.js +0 -190
- package/lib/components/Programa/Annotations/Input/PrivacySelection.js +0 -72
- package/lib/components/Programa/Annotations/Input/ReplyInformation.js +0 -86
- package/lib/components/Programa/Annotations/Input/UsersAutocomplete.js +0 -122
- package/lib/components/Programa/Annotations/index.js +0 -136
- package/lib/components/Programa/Annotations/utils.js +0 -30
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import FileInput from './FileInput';
|
|
2
|
-
import PrivacySelection from './PrivacySelection';
|
|
3
|
-
import ReplyInformation from './ReplyInformation';
|
|
4
|
-
import UsersAutocomplete from './UsersAutocomplete';
|
|
5
|
-
import { AnnotationsContext } from '..';
|
|
6
|
-
import { prepareFile, saveProgramAnnotation } from '../../../../api';
|
|
7
|
-
import { ANNOTATION_ANSWERS_INDEX, ANNOTATION_DATE_INDEX, ANNOTATION_ID_INDEX, ANNOTATION_PARAMETERS_INDEX, ANNOTATION_PROGRAM_CODE_INDEX, ANNOTATION_TEXT_INDEX, ANNOTATION_USER_INDEX } from '../Annotation';
|
|
8
|
-
import { EXTRA_SMALL_SIZE, SMALL_SIZE, LARGE_SIZE, LIGHT_GREY_COLOR } from '../utils';
|
|
9
|
-
import { Button, CircularProgress, Input as MaterialInput, makeStyles } from '@material-ui/core';
|
|
10
|
-
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const useStyles = makeStyles(theme => ({
|
|
14
|
-
inputContainer: {
|
|
15
|
-
display: 'flex',
|
|
16
|
-
flexDirection: 'column',
|
|
17
|
-
gap: SMALL_SIZE
|
|
18
|
-
},
|
|
19
|
-
materialInput: {
|
|
20
|
-
padding: EXTRA_SMALL_SIZE,
|
|
21
|
-
backgroundColor: theme.palette.background.default,
|
|
22
|
-
border: `1px solid ${LIGHT_GREY_COLOR(theme.palette.type)}`,
|
|
23
|
-
'&>textarea': {
|
|
24
|
-
minHeight: (LARGE_SIZE + SMALL_SIZE)
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
buttonsDiv: {
|
|
28
|
-
display: 'flex',
|
|
29
|
-
justifyContent: 'flex-end',
|
|
30
|
-
gap: SMALL_SIZE,
|
|
31
|
-
'&>button': {
|
|
32
|
-
minHeight: 30,
|
|
33
|
-
lineHeight: 1
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}));
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const initialStatePrivacyType = '0';
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const Input = () => {
|
|
43
|
-
|
|
44
|
-
const classes = useStyles();
|
|
45
|
-
const materialInputRef = useRef(null);
|
|
46
|
-
const { list, annotationParameters, selectedAnnotation, code, loading, dispatch } = useContext(AnnotationsContext);
|
|
47
|
-
const replying = !!selectedAnnotation.length;
|
|
48
|
-
|
|
49
|
-
const [text, setText] = useState('');
|
|
50
|
-
const [file, setFile] = useState('');
|
|
51
|
-
const [markedUsers, setMarkedUsers] = useState([]);
|
|
52
|
-
const [privacyType, setPrivacyType] = useState(initialStatePrivacyType);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
function resetStates() {
|
|
56
|
-
setText('');
|
|
57
|
-
setFile('');
|
|
58
|
-
setMarkedUsers([]);
|
|
59
|
-
setPrivacyType(initialStatePrivacyType);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const cancelReply = () => {
|
|
63
|
-
dispatch({ field: 'selectedAnnotation', value: [] });
|
|
64
|
-
resetStates();
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const addAnnotation = ({ answer, newAnnotation = [] }) => {
|
|
68
|
-
if (!newAnnotation.length) return;
|
|
69
|
-
|
|
70
|
-
let newList = [...list.annotations];
|
|
71
|
-
|
|
72
|
-
if (answer) {
|
|
73
|
-
const parentIndex = newList.findIndex((annotation) => (annotation[ANNOTATION_ID_INDEX] === answer));
|
|
74
|
-
if (parentIndex === -1) return;
|
|
75
|
-
|
|
76
|
-
let newParentAnnotation = [...newList[parentIndex]];
|
|
77
|
-
let newAnswers = [...newParentAnnotation[ANNOTATION_ANSWERS_INDEX]];
|
|
78
|
-
const newAnswer = {
|
|
79
|
-
dsAnotacao: newAnnotation[ANNOTATION_TEXT_INDEX],
|
|
80
|
-
dtAnotacao: newAnnotation[ANNOTATION_DATE_INDEX],
|
|
81
|
-
idAnotacao: newAnnotation[ANNOTATION_ID_INDEX],
|
|
82
|
-
idAnotacaoPai: answer,
|
|
83
|
-
parametros: newAnnotation[ANNOTATION_PARAMETERS_INDEX],
|
|
84
|
-
pgCode: newAnnotation[ANNOTATION_PROGRAM_CODE_INDEX],
|
|
85
|
-
usuario: newAnnotation[ANNOTATION_USER_INDEX]
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
newAnswers.push(newAnswer);
|
|
89
|
-
newParentAnnotation.splice(ANNOTATION_ANSWERS_INDEX, 1, newAnswers);
|
|
90
|
-
newList.splice(parentIndex, 1, newParentAnnotation);
|
|
91
|
-
} else {
|
|
92
|
-
newList.unshift(newAnnotation);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
dispatch({ type: 'list', field: 'annotations', value: newList });
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const saveAnnotation = async (event) => {
|
|
99
|
-
dispatch({ type: 'loading', field: 'save', value: true });
|
|
100
|
-
|
|
101
|
-
let methodParameters = {
|
|
102
|
-
pgCode: code,
|
|
103
|
-
dsAnotacao: text,
|
|
104
|
-
idAnotacaoPai: (selectedAnnotation.length) ? selectedAnnotation[ANNOTATION_ID_INDEX] : undefined,
|
|
105
|
-
parametros: annotationParameters,
|
|
106
|
-
tpPrivacidade: privacyType,
|
|
107
|
-
idRecebimento: undefined,
|
|
108
|
-
usuarioRelacionado: markedUsers.map(([id]) => id)
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
if (file) {
|
|
112
|
-
const { idRecebimento } = await prepareFile(file);
|
|
113
|
-
methodParameters.idRecebimento = idRecebimento;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const response = await saveProgramAnnotation(methodParameters);
|
|
117
|
-
if (response?.status) {
|
|
118
|
-
cancelReply();
|
|
119
|
-
addAnnotation({ answer: selectedAnnotation[ANNOTATION_ID_INDEX], newAnnotation: response?.anotacao });
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
dispatch({ type: 'loading', field: 'save', value: false });
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const setUpReply = () => {
|
|
126
|
-
(materialInputRef.current) && materialInputRef.current.focus();
|
|
127
|
-
setFile('');
|
|
128
|
-
setMarkedUsers([]);
|
|
129
|
-
setPrivacyType(initialStatePrivacyType);
|
|
130
|
-
};
|
|
131
|
-
useEffect(() => (replying) && setUpReply(), [replying]);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return <div className={classes.inputContainer}>
|
|
135
|
-
{(replying) && <ReplyInformation {...{ selectedAnnotation }} />}
|
|
136
|
-
<div>
|
|
137
|
-
<MaterialInput
|
|
138
|
-
fullWidth
|
|
139
|
-
multiline
|
|
140
|
-
inputRef={materialInputRef}
|
|
141
|
-
placeholder='Escreva a sua anotação'
|
|
142
|
-
disabled={loading.save}
|
|
143
|
-
value={text}
|
|
144
|
-
onChange={(event) => setText(event.target.value)}
|
|
145
|
-
className={classes.materialInput}
|
|
146
|
-
/>
|
|
147
|
-
</div>
|
|
148
|
-
{(!replying) && (
|
|
149
|
-
<>
|
|
150
|
-
<div className={classes.buttonsDiv}>
|
|
151
|
-
<FileInput {...{ file }} onChange={(_, value) => setFile(value)} />
|
|
152
|
-
</div>
|
|
153
|
-
<div className={classes.buttonsDiv}>
|
|
154
|
-
<UsersAutocomplete
|
|
155
|
-
disabled={loading.save}
|
|
156
|
-
value={markedUsers}
|
|
157
|
-
onChange={(event, value, reason, details) => setMarkedUsers(value)}
|
|
158
|
-
/>
|
|
159
|
-
</div>
|
|
160
|
-
<div className={classes.buttonsDiv}>
|
|
161
|
-
<PrivacySelection
|
|
162
|
-
disabled={loading.save}
|
|
163
|
-
value={privacyType}
|
|
164
|
-
onChange={event => setPrivacyType(event.target.value)}
|
|
165
|
-
/>
|
|
166
|
-
</div>
|
|
167
|
-
</>
|
|
168
|
-
)}
|
|
169
|
-
<div className={classes.buttonsDiv}>
|
|
170
|
-
{(replying) && (
|
|
171
|
-
<Button color='default' variant='contained' size='small' onClick={cancelReply}>
|
|
172
|
-
Cancelar
|
|
173
|
-
</Button>
|
|
174
|
-
)}
|
|
175
|
-
<Button
|
|
176
|
-
color='primary'
|
|
177
|
-
variant='contained'
|
|
178
|
-
size='small'
|
|
179
|
-
disabled={!text.length || loading.save}
|
|
180
|
-
onClick={saveAnnotation}
|
|
181
|
-
style={{ width: (replying) ? 97.13 : 72.45 }}
|
|
182
|
-
>
|
|
183
|
-
{(loading.save) ? <CircularProgress color='primary' size={22} /> : (replying) ? 'Responder' : 'Anotar'}
|
|
184
|
-
</Button>
|
|
185
|
-
</div>
|
|
186
|
-
</div>;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
export default Input;
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { EXTRA_SMALL_SIZE, MEDIUM_SIZE, privacyTypeOptions } from '../utils';
|
|
2
|
-
import { MenuItem, TextField, Typography, makeStyles } from '@material-ui/core';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const useStyles = makeStyles({
|
|
7
|
-
selectTextField: {
|
|
8
|
-
'&>div>svg': {
|
|
9
|
-
right: EXTRA_SMALL_SIZE
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
menuItem: {
|
|
13
|
-
display: 'flex',
|
|
14
|
-
gap: EXTRA_SMALL_SIZE,
|
|
15
|
-
padding: EXTRA_SMALL_SIZE
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const PrivacySelection = ({ value = '', onChange = () => '', disabled = false }) => {
|
|
21
|
-
|
|
22
|
-
const classes = useStyles();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<TextField
|
|
27
|
-
{...{ value, onChange, disabled }}
|
|
28
|
-
select
|
|
29
|
-
variant='filled'
|
|
30
|
-
InputProps={{
|
|
31
|
-
disableUnderline: true,
|
|
32
|
-
style: {
|
|
33
|
-
borderRadius: 4,
|
|
34
|
-
height: '100%'
|
|
35
|
-
}
|
|
36
|
-
}}
|
|
37
|
-
SelectProps={{
|
|
38
|
-
SelectDisplayProps: {
|
|
39
|
-
style: {
|
|
40
|
-
display: 'flex',
|
|
41
|
-
alignItems: 'center',
|
|
42
|
-
gap: EXTRA_SMALL_SIZE,
|
|
43
|
-
padding: `${EXTRA_SMALL_SIZE}px ${(EXTRA_SMALL_SIZE * 2) + 24}px ${EXTRA_SMALL_SIZE}px ${EXTRA_SMALL_SIZE}px`
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
MenuProps: {
|
|
47
|
-
variant: 'menu',
|
|
48
|
-
MenuListProps: {
|
|
49
|
-
style: { padding: `${EXTRA_SMALL_SIZE}px 0` }
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}}
|
|
53
|
-
className={classes.selectTextField}
|
|
54
|
-
>
|
|
55
|
-
{privacyTypeOptions.map((privacyType) => {
|
|
56
|
-
|
|
57
|
-
const value = privacyType[0];
|
|
58
|
-
const label = privacyType[1];
|
|
59
|
-
const ICON = privacyType[2];
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return <MenuItem key={`${value}-menu-item`} {...{ value }} className={classes.menuItem}>
|
|
63
|
-
{(ICON) && <ICON size={MEDIUM_SIZE} />}
|
|
64
|
-
<Typography variant='body2'>{label}</Typography>
|
|
65
|
-
</MenuItem>;
|
|
66
|
-
})}
|
|
67
|
-
</TextField>
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
export default PrivacySelection;
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { ArgousAvatar } from '../../../../components';
|
|
2
|
-
import { ANNOTATION_DATE_INDEX, ANNOTATION_TEXT_INDEX, ANNOTATION_USER_INDEX } from '../Annotation';
|
|
3
|
-
import { AVATAR_SIZE, AnswerIcon, EXTRA_SMALL_SIZE, MEDIUM_GREY_COLOR, SMALL_SIZE, UNIMED_GREEN_COLOR } from '../utils';
|
|
4
|
-
import { Typography, makeStyles } from '@material-ui/core';
|
|
5
|
-
import moment from 'moment';
|
|
6
|
-
import React from 'react';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const useStyles = makeStyles(theme => ({
|
|
10
|
-
replyInformation: {
|
|
11
|
-
display: 'flex',
|
|
12
|
-
flexDirection: 'column',
|
|
13
|
-
alignItems: 'flex-end',
|
|
14
|
-
gap: SMALL_SIZE,
|
|
15
|
-
'&>div:nth-child(1)': {
|
|
16
|
-
display: 'flex',
|
|
17
|
-
gap: SMALL_SIZE,
|
|
18
|
-
'&>h6': {
|
|
19
|
-
fontWeight: 500,
|
|
20
|
-
lineHeight: 1
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
'&>div:nth-child(2)': {
|
|
24
|
-
display: 'flex',
|
|
25
|
-
flexDirection: 'column',
|
|
26
|
-
gap: SMALL_SIZE,
|
|
27
|
-
'&>div:nth-child(1)': {
|
|
28
|
-
display: 'flex',
|
|
29
|
-
justifyContent: 'flex-end',
|
|
30
|
-
gap: SMALL_SIZE,
|
|
31
|
-
'&>div:nth-child(1)': {
|
|
32
|
-
display: 'flex',
|
|
33
|
-
alignItems: 'flex-end',
|
|
34
|
-
justifyContent: 'center',
|
|
35
|
-
flexDirection: 'column',
|
|
36
|
-
gap: EXTRA_SMALL_SIZE,
|
|
37
|
-
'&>h6': {
|
|
38
|
-
lineHeight: 1
|
|
39
|
-
},
|
|
40
|
-
'&>p': {
|
|
41
|
-
lineHeight: 1,
|
|
42
|
-
fontSize: '.75rem',
|
|
43
|
-
fontWeight: 500,
|
|
44
|
-
color: MEDIUM_GREY_COLOR(theme.palette.type)
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
'&>div:nth-child(2)': {
|
|
48
|
-
width: AVATAR_SIZE,
|
|
49
|
-
height: AVATAR_SIZE
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}));
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const ReplyInformation = ({ selectedAnnotation }) => {
|
|
58
|
-
|
|
59
|
-
const classes = useStyles();
|
|
60
|
-
const text = selectedAnnotation[ANNOTATION_TEXT_INDEX];
|
|
61
|
-
const user = { id: (selectedAnnotation[ANNOTATION_USER_INDEX]?.[0] || -1), name: (selectedAnnotation[ANNOTATION_USER_INDEX]?.[1] || '') };
|
|
62
|
-
const date = (selectedAnnotation[ANNOTATION_DATE_INDEX]) ? moment(selectedAnnotation[ANNOTATION_DATE_INDEX]).format('DD/MM/YYYY HH:mm:ss') : '';
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return <div className={classes.replyInformation}>
|
|
66
|
-
<div>
|
|
67
|
-
<AnswerIcon color={UNIMED_GREEN_COLOR} size={16} />
|
|
68
|
-
<Typography variant='subtitle1'>Respondendo</Typography>
|
|
69
|
-
</div>
|
|
70
|
-
<div>
|
|
71
|
-
<div>
|
|
72
|
-
<div>
|
|
73
|
-
<Typography variant='subtitle2'>{user.name}</Typography>
|
|
74
|
-
<Typography variant='body2'>{date}</Typography>
|
|
75
|
-
</div>
|
|
76
|
-
<ArgousAvatar alt={`${user.name}-avatar`} idUsuario={user.id} nome={user.name} />
|
|
77
|
-
</div>
|
|
78
|
-
<div>
|
|
79
|
-
<Typography variant='body2' align='right'>{text}</Typography>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
</div>;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
export default ReplyInformation;
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { searchUsers } from '../../../../api';
|
|
2
|
-
import { ArgousAvatar } from '../../../../components';
|
|
3
|
-
import { formataNome } from '../../../../utils';
|
|
4
|
-
import { setError } from '../../../../utils/api';
|
|
5
|
-
import { EXTRA_SMALL_SIZE, LARGE_SIZE, SMALL_SIZE } from '../utils';
|
|
6
|
-
import { Chip, TextField, makeStyles } from '@material-ui/core';
|
|
7
|
-
import { Autocomplete } from '@material-ui/lab';
|
|
8
|
-
import React, { useEffect, useState } from 'react';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const useStyles = makeStyles({
|
|
12
|
-
userAutocomplete: {
|
|
13
|
-
maxWidth: '100%'
|
|
14
|
-
},
|
|
15
|
-
usersAutocompleteInput: {
|
|
16
|
-
'&>div>input': {
|
|
17
|
-
minWidth: '137px !important',
|
|
18
|
-
padding: `${EXTRA_SMALL_SIZE}px !important`
|
|
19
|
-
},
|
|
20
|
-
'& .MuiAutocomplete-inputRoot[class*="MuiFilledInput-root"] .MuiAutocomplete-endAdornment': {
|
|
21
|
-
right: EXTRA_SMALL_SIZE
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
usersAutocompleteChip: {
|
|
25
|
-
height: LARGE_SIZE,
|
|
26
|
-
borderRadius: 0,
|
|
27
|
-
margin: EXTRA_SMALL_SIZE,
|
|
28
|
-
'&>span': {
|
|
29
|
-
padding: `0 ${SMALL_SIZE}px`
|
|
30
|
-
},
|
|
31
|
-
'&>svg': {
|
|
32
|
-
margin: `0 ${EXTRA_SMALL_SIZE}px 0 0`
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const UsersAutocomplete = ({ value = [], onChange = () => '', disabled = false }) => {
|
|
39
|
-
|
|
40
|
-
const classes = useStyles();
|
|
41
|
-
const [search, setSearch] = useState('');
|
|
42
|
-
const [users, setUsers] = useState([]);
|
|
43
|
-
|
|
44
|
-
async function getUsers(dsFiltroNome) {
|
|
45
|
-
const res = await searchUsers({ dsFiltroNome });
|
|
46
|
-
if (res.users?.length) setUsers(res.users || []);
|
|
47
|
-
else setError(res.dsErro);
|
|
48
|
-
}
|
|
49
|
-
useEffect(() => getUsers(search), [search]);
|
|
50
|
-
|
|
51
|
-
function handleOnChange (event, value, reason, details) {
|
|
52
|
-
(onChange) && onChange(event, value, reason, details);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
<Autocomplete
|
|
58
|
-
{...{ value, disabled }}
|
|
59
|
-
multiple
|
|
60
|
-
onChange={handleOnChange}
|
|
61
|
-
options={users.filter(user => value.indexOf(user) < 0)}
|
|
62
|
-
getOptionLabel={option => formataNome(option[1])}
|
|
63
|
-
getOptionSelected={(option, value) => (option?.[0] === value?.[0])}
|
|
64
|
-
noOptionsText='Não encontrado'
|
|
65
|
-
openText='Abrir'
|
|
66
|
-
closeText='Fechar'
|
|
67
|
-
clearText='Limpar'
|
|
68
|
-
renderTags={(value, getTagProps) => (
|
|
69
|
-
value.map((option, index) => {
|
|
70
|
-
|
|
71
|
-
const id = option?.[0];
|
|
72
|
-
const name = option?.[1];
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<Chip
|
|
77
|
-
icon={(
|
|
78
|
-
<ArgousAvatar
|
|
79
|
-
alt={`${name} avatar`}
|
|
80
|
-
idUsuario={id}
|
|
81
|
-
nome={name}
|
|
82
|
-
style={{ height: 30, width: 30, margin: `0 0 0 ${EXTRA_SMALL_SIZE}px` }}
|
|
83
|
-
/>
|
|
84
|
-
)}
|
|
85
|
-
label={option[1] || option}
|
|
86
|
-
{...getTagProps({ index })}
|
|
87
|
-
className={classes.usersAutocompleteChip}
|
|
88
|
-
/>
|
|
89
|
-
);
|
|
90
|
-
})
|
|
91
|
-
)}
|
|
92
|
-
renderInput={params => (
|
|
93
|
-
<TextField
|
|
94
|
-
id={params.id}
|
|
95
|
-
variant='filled'
|
|
96
|
-
placeholder='Selecione usuários'
|
|
97
|
-
fullWidth={params.fullWidth}
|
|
98
|
-
size={params.size}
|
|
99
|
-
disabled={params.disabled}
|
|
100
|
-
InputLabelProps={params.InputLabelProps}
|
|
101
|
-
InputProps={{
|
|
102
|
-
...params.InputProps,
|
|
103
|
-
disableUnderline: true,
|
|
104
|
-
style: {
|
|
105
|
-
height: '100%',
|
|
106
|
-
borderRadius: 4,
|
|
107
|
-
padding: `${EXTRA_SMALL_SIZE}px 62px ${EXTRA_SMALL_SIZE}px ${EXTRA_SMALL_SIZE}px`
|
|
108
|
-
}
|
|
109
|
-
}}
|
|
110
|
-
inputProps={params.inputProps}
|
|
111
|
-
value={search}
|
|
112
|
-
onChange={e => setSearch(e.target.value)}
|
|
113
|
-
className={classes.usersAutocompleteInput}
|
|
114
|
-
/>
|
|
115
|
-
)}
|
|
116
|
-
className={classes.userAutocomplete}
|
|
117
|
-
/>
|
|
118
|
-
);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
export default UsersAutocomplete;
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import AnnotationsList from './AnnotationsList';
|
|
2
|
-
import Input from './Input/Input';
|
|
3
|
-
import { CloseIcon, EXTRA_SMALL_SIZE, MEDIUM_SIZE } from './utils';
|
|
4
|
-
import { getProgramAnnotations } from '../../../api';
|
|
5
|
-
import { useStore } from '../../../utils';
|
|
6
|
-
import { CircularProgress, Dialog, IconButton, Typography, makeStyles } from '@material-ui/core';
|
|
7
|
-
import React, { createContext, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
8
|
-
import { useImmerReducer } from 'use-immer';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const useStyles = makeStyles(() => ({
|
|
12
|
-
dialogContainer: {
|
|
13
|
-
display: 'flex',
|
|
14
|
-
flexDirection: 'column',
|
|
15
|
-
gap: MEDIUM_SIZE,
|
|
16
|
-
padding: MEDIUM_SIZE,
|
|
17
|
-
overflowY: 'auto'
|
|
18
|
-
},
|
|
19
|
-
dialogHeader: {
|
|
20
|
-
display: 'flex',
|
|
21
|
-
alignItems: 'flex-start',
|
|
22
|
-
justifyContent: 'space-between',
|
|
23
|
-
gap: MEDIUM_SIZE,
|
|
24
|
-
'&>h6': {
|
|
25
|
-
lineHeight: 1
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
dialogHeaderActions: {
|
|
29
|
-
position: 'relative',
|
|
30
|
-
'&>button': {
|
|
31
|
-
zIndex: 1,
|
|
32
|
-
padding: EXTRA_SMALL_SIZE
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
dialogHeaderLoading: {
|
|
36
|
-
position: 'absolute',
|
|
37
|
-
inset: 0,
|
|
38
|
-
zIndex: 0
|
|
39
|
-
}
|
|
40
|
-
}));
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const initialStateLoading = {
|
|
44
|
-
main: false,
|
|
45
|
-
save: false,
|
|
46
|
-
file: false
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const initialStateList = {
|
|
50
|
-
annotations: []
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const initialState = {
|
|
54
|
-
selectedAnnotation: [],
|
|
55
|
-
list: initialStateList,
|
|
56
|
-
loading: initialStateLoading,
|
|
57
|
-
printScreen: {}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const reducer = (state = initialState, { type, property, field, value }) => {
|
|
61
|
-
switch (type) {
|
|
62
|
-
default:
|
|
63
|
-
if (type && property && field) state[type][property][field] = value;
|
|
64
|
-
else if (type && field) state[type][field] = value;
|
|
65
|
-
else if (field) state[field] = value;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export const AnnotationsContext = createContext(initialState);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const Annotations = ({ open, proceed, onClose, code, pgTitle, annotationParameters, openAnnotationParameters }) => {
|
|
74
|
-
|
|
75
|
-
const classes = useStyles();
|
|
76
|
-
const { usuarioLogado: loggedUser } = useStore();
|
|
77
|
-
const dialogRef = useRef(null);
|
|
78
|
-
const [state, dispatch] = useImmerReducer(reducer, initialState);
|
|
79
|
-
const { loading, list } = state;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const handleDialogClose = useCallback((event) => {
|
|
83
|
-
(proceed) && proceed();
|
|
84
|
-
(onClose) && onClose(event);
|
|
85
|
-
}, [proceed, onClose]);
|
|
86
|
-
|
|
87
|
-
const getAnnotations = useCallback(async (code) => {
|
|
88
|
-
dispatch({ type: 'loading', field: 'main', value: true });
|
|
89
|
-
|
|
90
|
-
const response = await getProgramAnnotations({ pgCode: code, ctrlPgn: {} });
|
|
91
|
-
(response?.status) && dispatch({ type: 'list', field: 'annotations', value: (response?.list || []) });
|
|
92
|
-
|
|
93
|
-
dispatch({ type: 'loading', field: 'main', value: false });
|
|
94
|
-
}, [dispatch]);
|
|
95
|
-
useEffect(() => getAnnotations(code), [code, getAnnotations]);
|
|
96
|
-
|
|
97
|
-
const scrollDialogToBottom = (event) => {
|
|
98
|
-
if (!dialogRef.current) return;
|
|
99
|
-
dialogRef.current.children[2].children[0].scroll({ top: dialogRef.current.offsetHeight, behavior: 'smooth' });
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const contextValues = useMemo(() => ({
|
|
103
|
-
...state,
|
|
104
|
-
code,
|
|
105
|
-
pgTitle,
|
|
106
|
-
loggedUser,
|
|
107
|
-
dialogRef,
|
|
108
|
-
annotationParameters,
|
|
109
|
-
openAnnotationParameters,
|
|
110
|
-
scrollDialogToBottom,
|
|
111
|
-
handleDialogClose,
|
|
112
|
-
dispatch
|
|
113
|
-
}), [code, pgTitle, annotationParameters, openAnnotationParameters, loggedUser, state, handleDialogClose, dispatch]);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return <AnnotationsContext.Provider value={contextValues}>
|
|
117
|
-
<Dialog {...{ open }} maxWidth='lg' disableRestoreFocus disableEnforceFocus ref={dialogRef} onClose={handleDialogClose}>
|
|
118
|
-
<div className={classes.dialogContainer}>
|
|
119
|
-
<div className={classes.dialogHeader}>
|
|
120
|
-
<Typography variant='h6'>Anotações {pgTitle}</Typography>
|
|
121
|
-
<div className={classes.dialogHeaderActions}>
|
|
122
|
-
<IconButton onClick={handleDialogClose}>
|
|
123
|
-
<CloseIcon />
|
|
124
|
-
</IconButton>
|
|
125
|
-
{(loading.main) && <CircularProgress color='secondary' size={34} className={classes.dialogHeaderLoading} />}
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
{(!!list.annotations.length) && <AnnotationsList />}
|
|
129
|
-
<Input />
|
|
130
|
-
</div>
|
|
131
|
-
</Dialog>
|
|
132
|
-
</AnnotationsContext.Provider>;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
export default Annotations;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { BsCheck2All } from 'react-icons/bs';
|
|
3
|
-
import { IoMdGlobe } from 'react-icons/io';
|
|
4
|
-
import { IoArrowUndoSharp, IoClose, IoLockClosed } from 'react-icons/io5';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const EXTRA_SMALL_SIZE = 5;
|
|
8
|
-
export const SMALL_SIZE = (EXTRA_SMALL_SIZE * 2);
|
|
9
|
-
export const MEDIUM_SIZE = (SMALL_SIZE * 2);
|
|
10
|
-
export const LARGE_SIZE = (MEDIUM_SIZE * 2);
|
|
11
|
-
export const AVATAR_SIZE = 33;
|
|
12
|
-
|
|
13
|
-
export const UNIMED_GREEN_COLOR = '#00995D';
|
|
14
|
-
export const LIGHT_GREY_COLOR = type => `rgba(${(type === 'light') ? '0, 0, 0' : '255, 255, 255'}, .12)`;
|
|
15
|
-
export const MEDIUM_GREY_COLOR = type => `rgba(${(type === 'light') ? '0, 0, 0' : '255, 255, 255'}, .6)`;
|
|
16
|
-
|
|
17
|
-
export const ViewedIcon = props => <BsCheck2All {...props} />;
|
|
18
|
-
export const AnswerIcon = props => <IoArrowUndoSharp {...props} />;
|
|
19
|
-
export const CloseIcon = props => <IoClose {...props} />;
|
|
20
|
-
|
|
21
|
-
export const privacyTypeOptions = [
|
|
22
|
-
['0', 'Público', IoMdGlobe],
|
|
23
|
-
['1', 'Privado', IoLockClosed]
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
export const ELLIPSIS_TEXT_STYLE = {
|
|
27
|
-
overflow: 'hidden',
|
|
28
|
-
whiteSpace: 'nowrap',
|
|
29
|
-
textOverflow: 'ellipsis'
|
|
30
|
-
};
|