tycho-components 0.25.2 → 0.25.5
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/common/AppForm/AppForm.js +4 -0
- package/dist/common/AppForm/FormColorField.d.ts +11 -0
- package/dist/common/AppForm/FormColorField.js +21 -0
- package/dist/common/AppForm/style.scss +18 -0
- package/dist/features/Participants/ParticipantService.d.ts +1 -2
- package/dist/features/Participants/ParticipantService.js +3 -2
- package/dist/features/Participants/Participants.js +85 -14
- package/dist/features/Participants/style.scss +10 -2
- package/dist/features/Participants/types/Participant.d.ts +7 -4
- package/dist/features/Participants/types/Participant.js +0 -22
- package/dist/features/index.d.ts +1 -1
- package/dist/features/index.js +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { AsyncSelectField, CheckboxField, DatePickerField, SelectField, SelectMultipleField, SwitchField, TextField, } from 'tycho-storybook';
|
|
3
|
+
import FormColorField from './FormColorField';
|
|
3
4
|
import './style.scss';
|
|
4
5
|
const convertList = (values, labelAttr, valueAttr) => {
|
|
5
6
|
if (!values)
|
|
@@ -58,6 +59,9 @@ export default function AppForm({ fields, form, prefix, onChangeFunctions = {},
|
|
|
58
59
|
if (field.type === 'textarea') {
|
|
59
60
|
return (_jsx(TextField, { attr: name, label: field.name, createdForm: form, disabled: field.disabled, required: field.required, onChange: (value) => handleChange?.(value), multiline: true, rows: field.rows, height: "100%" }, name));
|
|
60
61
|
}
|
|
62
|
+
if (field.type === 'color') {
|
|
63
|
+
return (_jsx(FormColorField, { attr: name, label: field.name, form: form, disabled: field.disabled, tooltipText: field.tooltipText }, name));
|
|
64
|
+
}
|
|
61
65
|
const handleBlur = getOnBlurFn(field.attr);
|
|
62
66
|
return (_jsx(TextField, { attr: name, label: field.size === 'small' ? undefined : field.name, placeholder: field.size === 'small' ? field.name : undefined, createdForm: form, mask: field.mask, blurMask: field.blurMask, disabled: field.disabled, required: field.required, onChange: (value) => handleChange?.(value), height: field.size === 'small' ? '32px' : undefined, onBlur: handleBlur }, name));
|
|
63
67
|
}) }));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UseFormReturn } from 'react-hook-form';
|
|
2
|
+
import '../AppColorpicker/style.scss';
|
|
3
|
+
type Props = {
|
|
4
|
+
attr: string;
|
|
5
|
+
label: string;
|
|
6
|
+
form: UseFormReturn<any, any, any>;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
tooltipText?: string;
|
|
9
|
+
};
|
|
10
|
+
export default function FormColorField({ attr, label, form, disabled, tooltipText, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { HexColorPicker } from 'react-colorful';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { Button, Icon, Tooltip } from 'tycho-storybook';
|
|
6
|
+
import '../AppColorpicker/style.scss';
|
|
7
|
+
const defaultColor = '#FFFFFF';
|
|
8
|
+
export default function FormColorField({ attr, label, form, disabled, tooltipText, }) {
|
|
9
|
+
const { t } = useTranslation('common');
|
|
10
|
+
const formValue = form.watch(attr);
|
|
11
|
+
const [openColor, setOpenColor] = useState(false);
|
|
12
|
+
const [color, setColor] = useState(defaultColor);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
setColor(formValue || defaultColor);
|
|
15
|
+
}, [formValue]);
|
|
16
|
+
const handleConfirm = () => {
|
|
17
|
+
form.setValue(attr, color, { shouldDirty: true });
|
|
18
|
+
setOpenColor(false);
|
|
19
|
+
};
|
|
20
|
+
return (_jsxs("div", { className: "form-color-field", children: [_jsxs("div", { className: "form-color-field-label", children: [_jsx("span", { children: label }), tooltipText && (_jsx(Tooltip, { title: tooltipText, children: _jsx("span", { children: _jsx(Icon, { name: "help", className: "info", size: "x-small" }) }) }))] }), _jsxs("div", { className: "color-picker-container", children: [_jsx("div", { className: "swatch", style: { backgroundColor: color }, onClick: () => !disabled && setOpenColor(!openColor), onKeyDown: () => !disabled && setOpenColor(!openColor), role: "link", "aria-label": "open color picker", tabIndex: disabled ? -1 : 0 }), openColor && !disabled && (_jsxs(_Fragment, { children: [_jsx(HexColorPicker, { color: color, onChange: setColor }), _jsxs("div", { className: "buttons", children: [_jsx(Button, { text: t('button.confirm'), onClick: handleConfirm, size: "x-small" }), _jsx(Button, { text: t('button.cancel'), onClick: () => setOpenColor(false), color: "danger", size: "x-small" })] })] }))] })] }));
|
|
21
|
+
}
|
|
@@ -40,3 +40,21 @@
|
|
|
40
40
|
gap: 16px;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
|
|
44
|
+
.form-color-field {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: var(--spacing-100);
|
|
48
|
+
|
|
49
|
+
.form-color-field-label {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
gap: var(--spacing-50);
|
|
53
|
+
@include label-medium-2;
|
|
54
|
+
color: var(--text-primary);
|
|
55
|
+
|
|
56
|
+
.info {
|
|
57
|
+
color: var(--icon-primary);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { AppEditableField } from '../../common/AppEditable/AppEditableField';
|
|
2
1
|
import Participant, { ParticipantCreateRequest } from './types/Participant';
|
|
3
2
|
declare function add(uid: string, request: ParticipantCreateRequest): Promise<import("axios").AxiosResponse<Participant, any, {}>>;
|
|
4
|
-
declare function update(
|
|
3
|
+
declare function update(uid: string, code: string, participant: Participant): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
5
4
|
declare function remove(document: string, code: string, transfer?: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
6
5
|
declare const ParticipantService: {
|
|
7
6
|
add: typeof add;
|
|
@@ -2,8 +2,9 @@ import api, { platformApi } from '../../configs/api';
|
|
|
2
2
|
function add(uid, request) {
|
|
3
3
|
return api.post(`${platformApi.catalog}/participant/${uid}`, request);
|
|
4
4
|
}
|
|
5
|
-
function update(
|
|
6
|
-
|
|
5
|
+
function update(uid, code, participant) {
|
|
6
|
+
const request = { uid, code, participant };
|
|
7
|
+
return api.patch(`${platformApi.catalog}/participant/update`, request);
|
|
7
8
|
}
|
|
8
9
|
function remove(document, code, transfer) {
|
|
9
10
|
const request = {
|
|
@@ -1,34 +1,99 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { MenuItem, Select } from '@mui/material';
|
|
3
|
-
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
4
5
|
import { useTranslation } from 'react-i18next';
|
|
5
6
|
import { Button } from 'tycho-storybook';
|
|
6
|
-
import
|
|
7
|
+
import AppForm from '../../common/AppForm/AppForm';
|
|
7
8
|
import { useMessageUtils } from '../../configs/useMessageUtils';
|
|
8
9
|
import ParticipantCreate from './ParticipantCreate';
|
|
9
10
|
import ParticipantRemove from './ParticipantRemove';
|
|
10
11
|
import './style.scss';
|
|
11
|
-
import { CHAT_FIELDS, PARTICIPANT_FIELDS, } from './types/Participant';
|
|
12
12
|
import ParticipantService from './ParticipantService';
|
|
13
|
+
const PARTICIPANT_FIELD_DEFS = [
|
|
14
|
+
{ attr: 'order', type: 'text', required: true },
|
|
15
|
+
{ attr: 'code', type: 'text', required: true },
|
|
16
|
+
{ attr: 'name', type: 'text', required: false },
|
|
17
|
+
{ attr: 'separator', type: 'text', required: false },
|
|
18
|
+
{ attr: 'color', type: 'color', required: false, tooltip: true },
|
|
19
|
+
];
|
|
20
|
+
const CHAT_FIELD_DEFS = [
|
|
21
|
+
{ attr: 'language', type: 'text', required: false },
|
|
22
|
+
{ attr: 'age', type: 'text', required: false },
|
|
23
|
+
{ attr: 'sex', type: 'text', required: false },
|
|
24
|
+
{ attr: 'group', type: 'text', required: false },
|
|
25
|
+
{ attr: 'ses', type: 'text', required: false },
|
|
26
|
+
{ attr: 'role', type: 'text', required: false },
|
|
27
|
+
{ attr: 'education', type: 'text', required: false },
|
|
28
|
+
{ attr: 'custom', type: 'text', required: false },
|
|
29
|
+
];
|
|
30
|
+
const toCoreFormValues = (participant) => ({
|
|
31
|
+
order: participant.order ?? '',
|
|
32
|
+
code: participant.code ?? '',
|
|
33
|
+
name: participant.name ?? '',
|
|
34
|
+
separator: participant.separator ?? '',
|
|
35
|
+
color: participant.color ?? '',
|
|
36
|
+
});
|
|
37
|
+
const toChatFormValues = (participant) => ({
|
|
38
|
+
language: participant.language ?? '',
|
|
39
|
+
age: participant.age ?? '',
|
|
40
|
+
sex: participant.sex ?? '',
|
|
41
|
+
group: participant.group ?? '',
|
|
42
|
+
ses: participant.ses ?? '',
|
|
43
|
+
role: participant.role ?? '',
|
|
44
|
+
education: participant.education ?? '',
|
|
45
|
+
custom: participant.custom ?? '',
|
|
46
|
+
});
|
|
13
47
|
export default function Participants({ document, participants, onChange, useChat, }) {
|
|
14
48
|
const { t } = useTranslation('participants');
|
|
15
49
|
const { dispatchMessage } = useMessageUtils();
|
|
16
50
|
const [participant, setParticipant] = useState();
|
|
17
51
|
const [openRemove, setOpenRemove] = useState(false);
|
|
18
52
|
const [openCreate, setOpenCreate] = useState(false);
|
|
19
|
-
const
|
|
20
|
-
|
|
53
|
+
const participantForm = useForm({
|
|
54
|
+
defaultValues: toCoreFormValues({ order: 1, code: '', name: '' }),
|
|
55
|
+
});
|
|
56
|
+
const chatForm = useForm({
|
|
57
|
+
defaultValues: toChatFormValues({ order: 1, code: '', name: '' }),
|
|
58
|
+
});
|
|
59
|
+
const participantFields = useMemo(() => PARTICIPANT_FIELD_DEFS.map((field) => ({
|
|
60
|
+
...field,
|
|
61
|
+
name: t(`participant.field.${field.attr}`),
|
|
62
|
+
...(field.tooltip
|
|
63
|
+
? { tooltipText: t(`participant.field.${field.attr}.tooltip`) }
|
|
64
|
+
: {}),
|
|
65
|
+
})), [t]);
|
|
66
|
+
const chatFields = useMemo(() => CHAT_FIELD_DEFS.map((field) => ({
|
|
67
|
+
...field,
|
|
68
|
+
name: t(`participant.field.${field.attr}`),
|
|
69
|
+
})), [t]);
|
|
70
|
+
const buildParticipantPayload = () => {
|
|
71
|
+
const coreValues = participantForm.getValues();
|
|
72
|
+
const chatValues = chatForm.getValues();
|
|
73
|
+
const order = typeof coreValues.order === 'string'
|
|
74
|
+
? Number(coreValues.order) || participant?.order || 1
|
|
75
|
+
: coreValues.order;
|
|
76
|
+
return {
|
|
77
|
+
...participant,
|
|
78
|
+
...chatValues,
|
|
79
|
+
...coreValues,
|
|
80
|
+
order,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
const handleSave = () => {
|
|
84
|
+
if (!participant)
|
|
21
85
|
return;
|
|
22
|
-
|
|
86
|
+
const lookupCode = participant.code;
|
|
87
|
+
const payload = buildParticipantPayload();
|
|
88
|
+
ParticipantService.update(document, lookupCode, payload)
|
|
23
89
|
.then(() => {
|
|
24
90
|
dispatchMessage({ key: 'update.success', t });
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
setParticipant(thisParticipant);
|
|
91
|
+
const thisParticipants = [...participants];
|
|
92
|
+
const idx = thisParticipants.findIndex((p) => p.code === lookupCode);
|
|
93
|
+
if (idx >= 0) {
|
|
94
|
+
thisParticipants[idx] = payload;
|
|
95
|
+
}
|
|
96
|
+
setParticipant(payload);
|
|
32
97
|
onChange(thisParticipants);
|
|
33
98
|
})
|
|
34
99
|
.catch((err) => {
|
|
@@ -39,9 +104,15 @@ export default function Participants({ document, participants, onChange, useChat
|
|
|
39
104
|
if (participants.length > 0)
|
|
40
105
|
setParticipant(participants[0]);
|
|
41
106
|
}, []);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (!participant)
|
|
109
|
+
return;
|
|
110
|
+
participantForm.reset(toCoreFormValues(participant));
|
|
111
|
+
chatForm.reset(toChatFormValues(participant));
|
|
112
|
+
}, [participant, participantForm, chatForm]);
|
|
42
113
|
return (_jsxs("div", { className: "participants-container", children: [_jsxs("div", { className: "header", children: [_jsx("div", { className: "title", children: t('label.title') }), _jsx("div", { className: "actions", children: _jsx(Button, { icon: "add", text: t('button.label.add'), onClick: () => setOpenCreate(true), size: "small", mode: "outlined" }) })] }), _jsx("div", { className: "body", children: participant && (_jsxs(_Fragment, { children: [_jsx(Select, { onChange: (e) => setParticipant(participants[Number(e.target.value)]), value: participant
|
|
43
114
|
? participants.findIndex((p) => p.code === participant.code)
|
|
44
|
-
: 0, fullWidth: true, className: "select-participant", children: participants.map((el, idx) => (_jsx(MenuItem, { value: idx, children: `${el.code} - ${el.name}` }, idx))) }),
|
|
115
|
+
: 0, fullWidth: true, className: "select-participant", children: participants.map((el, idx) => (_jsx(MenuItem, { value: idx, children: `${el.code} - ${el.name}` }, idx))) }), _jsxs("div", { className: "fields", children: [_jsx(AppForm, { fields: participantFields, form: participantForm }), _jsx(Button, { text: t('common:button.confirm'), onClick: handleSave, size: "small", className: "save-button" })] }), useChat && (_jsxs("div", { className: "fields", children: [_jsx(AppForm, { fields: chatFields, form: chatForm }), _jsx(Button, { text: t('common:button.confirm'), onClick: handleSave, size: "small", className: "save-button" })] })), _jsx("div", { className: "footer", children: _jsx(Button, { icon: "delete", text: t('common:button.remove'), size: "small", className: "danger", onClick: () => {
|
|
45
116
|
setParticipant(participant);
|
|
46
117
|
setOpenRemove(true);
|
|
47
118
|
} }) })] })) }), participant && openRemove && (_jsx(ParticipantRemove, { document: document, onChange: (list) => {
|
|
@@ -14,10 +14,18 @@
|
|
|
14
14
|
.body {
|
|
15
15
|
height: 90vh;
|
|
16
16
|
overflow-y: auto;
|
|
17
|
-
padding:
|
|
17
|
+
padding: var(--spacing-200);
|
|
18
18
|
|
|
19
19
|
> .select-participant {
|
|
20
|
-
margin-bottom:
|
|
20
|
+
margin-bottom: var(--spacing-200);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.fields {
|
|
24
|
+
margin-bottom: var(--spacing-200);
|
|
25
|
+
|
|
26
|
+
.save-button {
|
|
27
|
+
margin-top: var(--spacing-200);
|
|
28
|
+
}
|
|
21
29
|
}
|
|
22
30
|
}
|
|
23
31
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { FormField } from '../../../common/AppEditable/FormField';
|
|
2
1
|
type Participant = {
|
|
3
2
|
order: number;
|
|
4
3
|
code: string;
|
|
5
4
|
name: string;
|
|
6
5
|
color?: string;
|
|
6
|
+
separator?: string;
|
|
7
7
|
role?: string;
|
|
8
8
|
ses?: string;
|
|
9
9
|
education?: string;
|
|
10
|
-
|
|
10
|
+
sex?: string;
|
|
11
11
|
custom?: string;
|
|
12
12
|
corpus?: string;
|
|
13
13
|
language?: string;
|
|
@@ -18,11 +18,14 @@ export type ParticipantCreateRequest = {
|
|
|
18
18
|
code: string;
|
|
19
19
|
name: string;
|
|
20
20
|
};
|
|
21
|
+
export type ParticipantUpdateRequest = {
|
|
22
|
+
uid: string;
|
|
23
|
+
code: string;
|
|
24
|
+
participant: Participant;
|
|
25
|
+
};
|
|
21
26
|
export declare const EMPTY_PARTICIPANT: {
|
|
22
27
|
order: number;
|
|
23
28
|
code: string;
|
|
24
29
|
name: string;
|
|
25
30
|
};
|
|
26
|
-
export declare const PARTICIPANT_FIELDS: FormField[];
|
|
27
|
-
export declare const CHAT_FIELDS: FormField[];
|
|
28
31
|
export default Participant;
|
|
@@ -3,25 +3,3 @@ export const EMPTY_PARTICIPANT = {
|
|
|
3
3
|
code: '',
|
|
4
4
|
name: '',
|
|
5
5
|
};
|
|
6
|
-
export const PARTICIPANT_FIELDS = [
|
|
7
|
-
{ name: 'order', type: 'text', required: true },
|
|
8
|
-
{ name: 'code', type: 'text', required: true },
|
|
9
|
-
{ name: 'name', type: 'text', required: false },
|
|
10
|
-
{ name: 'separator', type: 'text', required: false },
|
|
11
|
-
{
|
|
12
|
-
name: 'color',
|
|
13
|
-
type: 'color',
|
|
14
|
-
required: false,
|
|
15
|
-
tooltip: true,
|
|
16
|
-
},
|
|
17
|
-
];
|
|
18
|
-
export const CHAT_FIELDS = [
|
|
19
|
-
{ name: 'language', type: 'text', required: false },
|
|
20
|
-
{ name: 'age', type: 'text', required: false },
|
|
21
|
-
{ name: 'sex', type: 'text', required: false },
|
|
22
|
-
{ name: 'group', type: 'text', required: false },
|
|
23
|
-
{ name: 'ses', type: 'text', required: false },
|
|
24
|
-
{ name: 'role', type: 'text', required: false },
|
|
25
|
-
{ name: 'education', type: 'text', required: false },
|
|
26
|
-
{ name: 'custom', type: 'text', required: false },
|
|
27
|
-
];
|
package/dist/features/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { default as CommentService } from './Comments/CommentService';
|
|
|
5
5
|
export { default as Parameters } from './Parameters';
|
|
6
6
|
export { default as Participants } from './Participants';
|
|
7
7
|
export type { default as Participant, ParticipantCreateRequest, } from './Participants/types/Participant';
|
|
8
|
-
export { EMPTY_PARTICIPANT,
|
|
8
|
+
export { EMPTY_PARTICIPANT, } from './Participants/types/Participant';
|
|
9
9
|
export { default as SentenceView } from './SentenceView';
|
|
10
10
|
export { default as TreeView } from './TreeView';
|
|
11
11
|
export { default as CytoscapeTreeConverter } from './TreeView/cytoscape/CytoscapeTreeConverter';
|
package/dist/features/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { default as HeaderNotifications } from './Comments/HeaderNotifications';
|
|
|
3
3
|
export { default as CommentService } from './Comments/CommentService';
|
|
4
4
|
export { default as Parameters } from './Parameters';
|
|
5
5
|
export { default as Participants } from './Participants';
|
|
6
|
-
export { EMPTY_PARTICIPANT,
|
|
6
|
+
export { EMPTY_PARTICIPANT, } from './Participants/types/Participant';
|
|
7
7
|
export { default as SentenceView } from './SentenceView';
|
|
8
8
|
export { default as TreeView } from './TreeView';
|
|
9
9
|
export { default as CytoscapeTreeConverter } from './TreeView/cytoscape/CytoscapeTreeConverter';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tycho-components",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.25.
|
|
4
|
+
"version": "0.25.5",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"react-i18next": "^13.0.2",
|
|
83
83
|
"react-router-dom": "^6.14.2",
|
|
84
84
|
"react-toastify": "^9.1.3",
|
|
85
|
-
"tycho-storybook": "0.9.
|
|
85
|
+
"tycho-storybook": "0.9.4",
|
|
86
86
|
"wavesurfer-react": "^2.2.2",
|
|
87
87
|
"wavesurfer.js": "^6.6.3"
|
|
88
88
|
},
|