tycho-components 0.0.4 → 0.0.5-SNAPSHOT-1

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 (139) hide show
  1. package/dist/AppColorpicker/AppColorpicker.d.ts +10 -0
  2. package/dist/AppColorpicker/AppColorpicker.js +21 -0
  3. package/{src/AppColorpicker/index.tsx → dist/AppColorpicker/index.d.ts} +0 -1
  4. package/dist/AppColorpicker/index.js +2 -0
  5. package/dist/AppEditable/AppEditable.d.ts +14 -0
  6. package/dist/AppEditable/AppEditable.js +80 -0
  7. package/dist/AppEditable/AppEditableField.d.ts +7 -0
  8. package/dist/AppEditable/AppEditableField.js +1 -0
  9. package/dist/AppEditable/FormField.d.ts +14 -0
  10. package/dist/AppEditable/FormField.js +8 -0
  11. package/dist/AppEditable/FormFieldOption.d.ts +7 -0
  12. package/dist/AppEditable/FormFieldOption.js +20 -0
  13. package/{src/AppEditable/index.tsx → dist/AppEditable/index.d.ts} +0 -1
  14. package/dist/AppEditable/index.js +2 -0
  15. package/dist/AppModal/AppModal.d.ts +20 -0
  16. package/dist/AppModal/AppModal.js +22 -0
  17. package/dist/AppModal/AppModalConfirm.d.ts +11 -0
  18. package/dist/AppModal/AppModalConfirm.js +20 -0
  19. package/dist/AppModal/AppModalRemove.d.ts +9 -0
  20. package/dist/AppModal/AppModalRemove.js +20 -0
  21. package/{src/AppModal/index.tsx → dist/AppModal/index.d.ts} +0 -1
  22. package/dist/AppModal/index.js +2 -0
  23. package/dist/AppToast/AppToast.d.ts +2 -0
  24. package/dist/AppToast/AppToast.js +78 -0
  25. package/dist/AppToast/ToastMessage.d.ts +8 -0
  26. package/dist/AppToast/ToastMessage.js +4 -0
  27. package/{src/AppToast/index.tsx → dist/AppToast/index.d.ts} +0 -1
  28. package/dist/AppToast/index.js +2 -0
  29. package/dist/Dummy/Dummy.d.ts +9 -0
  30. package/dist/Dummy/Dummy.js +8 -0
  31. package/{src/Dummy/index.tsx → dist/Dummy/index.d.ts} +0 -1
  32. package/dist/Dummy/index.js +2 -0
  33. package/dist/Participants/ParticipantCreate/ParticipantCreate.d.ts +9 -0
  34. package/dist/Participants/ParticipantCreate/ParticipantCreate.js +41 -0
  35. package/{src/Participants/ParticipantCreate/index.tsx → dist/Participants/ParticipantCreate/index.d.ts} +0 -1
  36. package/dist/Participants/ParticipantCreate/index.js +2 -0
  37. package/dist/Participants/ParticipantRemove/ParticipantRemove.d.ts +11 -0
  38. package/dist/Participants/ParticipantRemove/ParticipantRemove.js +26 -0
  39. package/{src/Participants/ParticipantRemove/index.tsx → dist/Participants/ParticipantRemove/index.d.ts} +0 -1
  40. package/dist/Participants/ParticipantRemove/index.js +2 -0
  41. package/dist/Participants/Participants.d.ts +9 -0
  42. package/dist/Participants/Participants.js +57 -0
  43. package/{src/Participants/index.tsx → dist/Participants/index.d.ts} +0 -1
  44. package/dist/Participants/index.js +2 -0
  45. package/dist/Participants/types/Participant.d.ts +27 -0
  46. package/dist/Participants/types/Participant.js +17 -0
  47. package/dist/Participants/types/ParticipantService.d.ts +11 -0
  48. package/dist/Participants/types/ParticipantService.js +12 -0
  49. package/dist/configs/CommonContext.d.ts +10 -0
  50. package/dist/configs/CommonContext.js +10 -0
  51. package/dist/configs/CookieStorage.d.ts +10 -0
  52. package/dist/configs/CookieStorage.js +28 -0
  53. package/dist/configs/Localization.d.ts +64 -0
  54. package/dist/configs/Localization.js +28 -0
  55. package/dist/configs/MessageUtils.d.ts +20 -0
  56. package/dist/configs/MessageUtils.js +30 -0
  57. package/dist/configs/Storage.d.ts +9 -0
  58. package/dist/configs/Storage.js +16 -0
  59. package/dist/configs/api.d.ts +2 -0
  60. package/dist/configs/api.js +38 -0
  61. package/dist/configs/localization/CommonTexts.d.ts +27 -0
  62. package/dist/configs/localization/CommonTexts.js +27 -0
  63. package/dist/configs/localization/ParticipantsTexts.d.ts +34 -0
  64. package/dist/configs/localization/ParticipantsTexts.js +34 -0
  65. package/dist/configs/store/actions.d.ts +4 -0
  66. package/dist/configs/store/actions.js +9 -0
  67. package/dist/configs/store/reducer.d.ts +3 -0
  68. package/dist/configs/store/reducer.js +19 -0
  69. package/dist/configs/store/store.d.ts +3 -0
  70. package/dist/configs/store/store.js +6 -0
  71. package/dist/configs/store/types.d.ts +13 -0
  72. package/dist/configs/store/types.js +4 -0
  73. package/dist/index.js +9 -0
  74. package/package.json +33 -24
  75. package/.eslintignore +0 -2
  76. package/.eslintrc.cjs +0 -28
  77. package/.eslintrc.json +0 -31
  78. package/.gitlab-ci.yml +0 -14
  79. package/.storybook/main.ts +0 -32
  80. package/.storybook/preview-head.html +0 -4
  81. package/.storybook/preview.css +0 -6
  82. package/.storybook/preview.tsx +0 -29
  83. package/src/AppColorpicker/AppColorpicker.tsx +0 -69
  84. package/src/AppEditable/AppEditable.tsx +0 -280
  85. package/src/AppEditable/AppEditableField.ts +0 -7
  86. package/src/AppEditable/FormField.ts +0 -26
  87. package/src/AppEditable/FormFieldOption.ts +0 -38
  88. package/src/AppModal/AppModal.tsx +0 -93
  89. package/src/AppModal/AppModalConfirm.tsx +0 -62
  90. package/src/AppModal/AppModalRemove.tsx +0 -51
  91. package/src/AppToast/AppToast.tsx +0 -94
  92. package/src/AppToast/ToastMessage.ts +0 -9
  93. package/src/Dummy/Dummy.stories.tsx +0 -21
  94. package/src/Dummy/Dummy.tsx +0 -16
  95. package/src/Participants/ParticipantCreate/ParticipantCreate.tsx +0 -83
  96. package/src/Participants/ParticipantRemove/ParticipantRemove.tsx +0 -51
  97. package/src/Participants/Participants.stories.tsx +0 -45
  98. package/src/Participants/Participants.tsx +0 -145
  99. package/src/Participants/types/Participant.ts +0 -43
  100. package/src/Participants/types/ParticipantService.ts +0 -18
  101. package/src/configs/CommonContext.tsx +0 -23
  102. package/src/configs/CookieStorage.ts +0 -36
  103. package/src/configs/Localization.ts +0 -30
  104. package/src/configs/MessageUtils.ts +0 -60
  105. package/src/configs/Storage.ts +0 -21
  106. package/src/configs/api.ts +0 -49
  107. package/src/configs/localization/CommonTexts.ts +0 -27
  108. package/src/configs/localization/ParticipantsTexts.ts +0 -40
  109. package/src/configs/store/actions.ts +0 -12
  110. package/src/configs/store/reducer.ts +0 -22
  111. package/src/configs/store/store.ts +0 -9
  112. package/src/configs/store/types.ts +0 -16
  113. package/src/new-styles/base/_borders.scss +0 -30
  114. package/src/new-styles/base/_colors.scss +0 -100
  115. package/src/new-styles/base/_displays.scss +0 -207
  116. package/src/new-styles/base/_margins.css +0 -174
  117. package/src/new-styles/base/_spacing.scss +0 -26
  118. package/src/new-styles/base/_tokens.scss +0 -329
  119. package/src/new-styles/base/_typographs.scss +0 -348
  120. package/src/new-styles/main.scss +0 -27
  121. package/src/react-app-env.d.ts +0 -5
  122. package/src/vite-env.d.ts +0 -13
  123. package/stories/Configure.mdx +0 -171
  124. package/stories/StorybookUtils.tsx +0 -40
  125. package/tsconfig.json +0 -31
  126. package/tsconfig.node.json +0 -10
  127. package/vite.config.ts +0 -26
  128. /package/{src → dist}/AppColorpicker/style.scss +0 -0
  129. /package/{src → dist}/AppEditable/style.scss +0 -0
  130. /package/{src → dist}/AppModal/style.scss +0 -0
  131. /package/{src → dist}/AppToast/style.scss +0 -0
  132. /package/{src → dist}/Dummy/styles.scss +0 -0
  133. /package/{src → dist}/Participants/ParticipantCreate/style.scss +0 -0
  134. /package/{src → dist}/Participants/ParticipantRemove/style.scss +0 -0
  135. /package/{src → dist}/Participants/style.scss +0 -0
  136. /package/{src/index.ts → dist/index.d.ts} +0 -0
  137. /package/{src → dist}/styles/_variables.scss +0 -0
  138. /package/{src → dist}/styles/bootstrap.min.css +0 -0
  139. /package/{src → dist}/styles/main.scss +0 -0
@@ -1,93 +0,0 @@
1
- import { Box, Fade, Modal } from '@mui/material';
2
- import cx from 'classnames';
3
- import React from 'react';
4
- import { useTranslation } from 'react-i18next';
5
- import { Button, Icon } from 'tycho-storybook';
6
- import './style.scss';
7
-
8
- type Props = {
9
- children: React.ReactNode;
10
- title: string;
11
- close: () => void;
12
- confirm?: () => void;
13
- cancel?: () => void;
14
- subtitle?: string;
15
- className?: string;
16
- disableConfirm?: boolean;
17
- hideFooter?: boolean;
18
- disableCancel?: boolean;
19
- disableClose?: boolean;
20
- confirmLabel?: string;
21
- closeLabel?: string;
22
- onEntered?: () => void;
23
- };
24
-
25
- export default function AppModal({
26
- children,
27
- title,
28
- subtitle,
29
- className,
30
- close,
31
- confirm,
32
- disableConfirm,
33
- hideFooter,
34
- disableClose,
35
- disableCancel,
36
- confirmLabel,
37
- closeLabel,
38
- cancel,
39
- onEntered,
40
- }: Props) {
41
- const { t } = useTranslation('common');
42
-
43
- const getClassNames = cx('modal-container', className);
44
-
45
- return (
46
- <Modal open>
47
- <Fade in onEntered={() => onEntered && onEntered()}>
48
- <Box className={getClassNames} sx={style}>
49
- <div className="header">
50
- <div className="titles">
51
- <span className="title">{title}</span>
52
- {subtitle && <span className="subtitle">{subtitle}</span>}
53
- </div>
54
- {!disableClose && (
55
- <Icon name="close" onClick={close} className="pointer" />
56
- )}
57
- </div>
58
- <div className="body">{children}</div>
59
- {!hideFooter ? (
60
- <div className="footer">
61
- {!disableCancel && (
62
- <Button
63
- onClick={cancel || close}
64
- text={closeLabel || t('button.cancel')}
65
- color="danger"
66
- />
67
- )}
68
- {confirm && (
69
- <Button
70
- onClick={confirm}
71
- disabled={disableConfirm}
72
- text={confirmLabel || t('button.confirm')}
73
- />
74
- )}
75
- </div>
76
- ) : null}
77
- </Box>
78
- </Fade>
79
- </Modal>
80
- );
81
- }
82
-
83
- const style = {
84
- position: 'absolute',
85
- top: '40%',
86
- left: '50%',
87
- transform: 'translate(-50%, -50%)',
88
- width: '50%',
89
- maxWidth: '1080px',
90
- borderRadius: 'var(--radius-200)',
91
- boxShadow: 24,
92
- bgcolor: 'var(--background-default)',
93
- };
@@ -1,62 +0,0 @@
1
- import { Box, Modal } from '@mui/material';
2
- import { useTranslation } from 'react-i18next';
3
- import { Button, Icon } from 'tycho-storybook';
4
- import './style.scss';
5
-
6
- type Props = {
7
- title: string;
8
- subtitle: string;
9
- onClose: () => void;
10
- onConfirm: () => void;
11
- closeLabel?: string;
12
- confirmLabel?: string;
13
- };
14
-
15
- export default function AppModalConfirm({
16
- title,
17
- subtitle,
18
- onClose,
19
- onConfirm,
20
- closeLabel,
21
- confirmLabel,
22
- }: Props) {
23
- const { t } = useTranslation('header');
24
-
25
- return (
26
- <Modal open>
27
- <Box className="modal-container modal-remove" sx={style}>
28
- <div className="body">
29
- <Icon name="warning" size="large" filled />
30
- <div className="texts">
31
- <span className="title">{title}</span>
32
- <span className="subtitle">{subtitle}</span>
33
- </div>
34
- </div>
35
-
36
- <div className="footer">
37
- <Button
38
- onClick={onClose}
39
- text={closeLabel || t('modal.button.cancel')}
40
- mode="tonal"
41
- />
42
- <Button
43
- onClick={onConfirm}
44
- text={confirmLabel || t('modal.button.confirm')}
45
- />
46
- </div>
47
- </Box>
48
- </Modal>
49
- );
50
- }
51
-
52
- const style = {
53
- position: 'absolute',
54
- top: '40%',
55
- left: '50%',
56
- transform: 'translate(-50%, -50%)',
57
- width: '30%',
58
- maxWidth: '580px',
59
- borderRadius: 'var(--radius-200)',
60
- boxShadow: 24,
61
- bgcolor: 'var(--background-default)',
62
- };
@@ -1,51 +0,0 @@
1
- import { Box, Modal } from '@mui/material';
2
- import { useTranslation } from 'react-i18next';
3
- import { Button, Icon } from 'tycho-storybook';
4
- import './style.scss';
5
-
6
- type Props = {
7
- title: string;
8
- subtitle: string;
9
- onClose: () => void;
10
- onConfirm: () => void;
11
- };
12
-
13
- export default function AppModalRemove({
14
- title,
15
- subtitle,
16
- onClose,
17
- onConfirm,
18
- }: Props) {
19
- const { t } = useTranslation('common');
20
-
21
- return (
22
- <Modal open>
23
- <Box className="modal-container modal-remove" sx={style}>
24
- <div className="body">
25
- <Icon name="warning" size="large" filled />
26
- <div className="texts">
27
- <span className="title">{title}</span>
28
- <span className="subtitle">{subtitle}</span>
29
- </div>
30
- </div>
31
-
32
- <div className="footer">
33
- <Button onClick={onClose} text={t('button.cancel')} mode="tonal" />
34
- <Button onClick={onConfirm} text={t('button.confirm')} />
35
- </div>
36
- </Box>
37
- </Modal>
38
- );
39
- }
40
-
41
- const style = {
42
- position: 'absolute',
43
- top: '40%',
44
- left: '50%',
45
- transform: 'translate(-50%, -50%)',
46
- width: '30%',
47
- maxWidth: '580px',
48
- borderRadius: 'var(--radius-200)',
49
- boxShadow: 24,
50
- bgcolor: 'var(--background-default)',
51
- };
@@ -1,94 +0,0 @@
1
- import CommonContext from '../configs/CommonContext';
2
- import { message } from '../configs/store/actions';
3
- import { useContext, useEffect } from 'react';
4
- import ReactLoading from 'react-loading';
5
- import { ToastContainer, toast } from 'react-toastify';
6
- import 'react-toastify/dist/ReactToastify.css';
7
- import { EMPTY_TOAST } from './ToastMessage';
8
-
9
- export default function AppToast() {
10
- const { dispatch, state } = useContext(CommonContext);
11
-
12
- const handleClose = () => {
13
- toast.dismiss();
14
- dispatch(message(EMPTY_TOAST));
15
- };
16
-
17
- const handleClipboard = () => {
18
- navigator.clipboard.writeText(state.message.value);
19
- };
20
-
21
- const getLoading = () => (
22
- <div className="d-flex">
23
- <ReactLoading
24
- type="spinningBubbles"
25
- color="blue"
26
- height={24}
27
- width={24}
28
- />
29
- <span className="ms-3">Loading...</span>
30
- </div>
31
- );
32
-
33
- const attachCloseToEscape = () => {
34
- const closeOnEscape = (e: any) => {
35
- if (e.keyCode === 27) handleClose();
36
- };
37
-
38
- window.addEventListener('keydown', closeOnEscape);
39
- return () => window.removeEventListener('keydown', closeOnEscape);
40
- };
41
-
42
- useEffect(() => {
43
- attachCloseToEscape();
44
- }, []);
45
-
46
- useEffect(() => {
47
- if (state.toastLoading) {
48
- toast(getLoading(), {
49
- position: 'top-right',
50
- autoClose: false,
51
- hideProgressBar: false,
52
- closeOnClick: false,
53
- pauseOnHover: true,
54
- draggable: false,
55
- progress: undefined,
56
- theme: 'light',
57
- });
58
- } else {
59
- toast.dismiss();
60
- }
61
- }, [state.toastLoading]);
62
-
63
- useEffect(() => {
64
- if (state.message && state.message.value !== '') {
65
- switch (state.message.type) {
66
- case 'error':
67
- toast.error(state.message.value, {
68
- onClose: () => handleClose(),
69
- onClick: () => handleClipboard(),
70
- });
71
- break;
72
- case 'warning':
73
- toast.warning(state.message.value, {
74
- onClose: () => handleClose(),
75
- });
76
- break;
77
- case 'success':
78
- toast.success(state.message.value, {
79
- onClose: () => handleClose(),
80
- });
81
- break;
82
- default:
83
- toast(state.message.value, {
84
- onClose: () => handleClose(),
85
- });
86
- break;
87
- }
88
- } else {
89
- dispatch(message(EMPTY_TOAST));
90
- }
91
- }, [state.message]);
92
-
93
- return <ToastContainer closeOnClick />;
94
- }
@@ -1,9 +0,0 @@
1
- export default interface ToastMessage {
2
- value: string;
3
- type: string;
4
- }
5
-
6
- export const EMPTY_TOAST = {
7
- value: '',
8
- type: '',
9
- };
@@ -1,21 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import Dummy, { DummyModes } from './Dummy';
3
-
4
- const meta = {
5
- title: 'Components/Dummy',
6
- component: Dummy,
7
- parameters: {
8
- layout: 'centered',
9
- },
10
- tags: ['autodocs'],
11
- argTypes: {
12
- mode: { control: 'select', options: DummyModes },
13
- },
14
- } satisfies Meta<typeof Dummy>;
15
-
16
- export default meta;
17
- type Story = StoryObj<typeof meta>;
18
-
19
- export const Primary: Story = {
20
- args: {},
21
- };
@@ -1,16 +0,0 @@
1
- import cx from 'classnames';
2
- import './styles.scss';
3
-
4
- export const DummyModes = ['white', 'blue'] as const;
5
- type DummyModes = (typeof DummyModes)[number];
6
-
7
- export type Props = {
8
- className?: string;
9
- mode?: DummyModes;
10
- };
11
-
12
- export default function Dummy({ className, mode = 'blue' }: Props) {
13
- const getClassNames = cx('ds-dummy', className, mode);
14
-
15
- return <div className={getClassNames}>aaaa</div>;
16
- }
@@ -1,83 +0,0 @@
1
- import { yupResolver } from '@hookform/resolvers/yup';
2
- import { TFunction } from 'i18next';
3
- import { useContext } from 'react';
4
- import { useForm } from 'react-hook-form';
5
- import { useTranslation } from 'react-i18next';
6
- import * as yup from 'yup';
7
- import AppModal from '../../AppModal';
8
- import CommonContext from '../../configs/CommonContext';
9
- import { toastLoading } from '../../configs/store/actions';
10
- import Participant, { ParticipantCreateRequest } from '../types/Participant';
11
- import ParticipantService from '../types/ParticipantService';
12
- import './style.scss';
13
- import { TextField } from 'tycho-storybook';
14
-
15
- type Props = {
16
- document: string;
17
- order: number;
18
- onClose: () => void;
19
- onCreate: (p: Participant) => void;
20
- };
21
-
22
- export default function ParticipantCreate({
23
- document,
24
- order,
25
- onClose,
26
- onCreate,
27
- }: Props) {
28
- const { t } = useTranslation('participants');
29
- const { dispatch, state } = useContext(CommonContext);
30
-
31
- const createdForm = useForm<ParticipantCreateRequest>({
32
- resolver: yupResolver(getFormSchema(t)),
33
- mode: 'onChange',
34
- });
35
-
36
- const handleAdd = () => {
37
- if (state.toastLoading) return;
38
- dispatch(toastLoading(true));
39
- ParticipantService.add(document, createdForm.getValues())
40
- .then((r) => {
41
- onCreate(r.data);
42
- })
43
- .finally(() => {
44
- dispatch(toastLoading(false));
45
- });
46
- };
47
-
48
- return (
49
- <AppModal
50
- title={t('modal.add.title')}
51
- className="modal-participant"
52
- close={onClose}
53
- confirm={handleAdd}
54
- disableConfirm={!createdForm.formState.isValid}
55
- >
56
- <div className="participant-container">
57
- <TextField
58
- label={t('modal.input.code')}
59
- attr="code"
60
- createdForm={createdForm}
61
- showEndAdornment={false}
62
- placeholder={t('common:generic.placeholder')}
63
- required
64
- />
65
- <TextField
66
- label={t('modal.input.name')}
67
- attr="name"
68
- createdForm={createdForm}
69
- showEndAdornment={false}
70
- placeholder={t('common:generic.placeholder')}
71
- />
72
- </div>
73
- </AppModal>
74
- );
75
- }
76
-
77
- const getFormSchema = (
78
- t: TFunction
79
- ): yup.ObjectSchema<ParticipantCreateRequest> =>
80
- yup.object().shape({
81
- code: yup.string().required(t('common:validation.required')),
82
- name: yup.string().required(t('common:validation.required')),
83
- });
@@ -1,51 +0,0 @@
1
- import { useContext } from 'react';
2
- import { useTranslation } from 'react-i18next';
3
- import AppModalRemove from '../../AppModal/AppModalRemove';
4
- import CommonContext from '../../configs/CommonContext';
5
- import { toastLoading } from '../../configs/store/actions';
6
- import Participant from '../types/Participant';
7
- import ParticipantService from '../types/ParticipantService';
8
- import './style.scss';
9
-
10
- type Props = {
11
- participant: Participant;
12
- participants: Participant[];
13
- document: string;
14
- onClose: () => void;
15
- onChange: (p: Participant[]) => void;
16
- };
17
-
18
- export default function ParticipantRemove({
19
- participant,
20
- participants,
21
- document,
22
- onClose,
23
- onChange,
24
- }: Props) {
25
- const { t } = useTranslation('participants');
26
- const { dispatch, state } = useContext(CommonContext);
27
-
28
- const handleRemove = () => {
29
- if (state.toastLoading || !participant) return;
30
- dispatch(toastLoading(true));
31
- ParticipantService.remove(document, participant.code)
32
- .then(() => {
33
- const list =
34
- participants?.filter((p) => p.code !== participant.code) || [];
35
-
36
- onChange(list);
37
- })
38
- .finally(() => {
39
- dispatch(toastLoading(false));
40
- });
41
- };
42
-
43
- return (
44
- <AppModalRemove
45
- title={t('modal.remove.title')}
46
- subtitle={t('modal.remove.description')}
47
- onClose={onClose}
48
- onConfirm={handleRemove}
49
- />
50
- );
51
- }
@@ -1,45 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import Participants from './Participants';
3
- import type Participant from './types/Participant';
4
- import { action } from '@storybook/addon-actions';
5
-
6
- const meta: Meta<typeof Participants> = {
7
- title: 'Components/Participants',
8
- component: Participants,
9
- tags: ['autodocs'],
10
- argTypes: {
11
- document: { control: 'text' },
12
- },
13
- };
14
-
15
- export default meta;
16
-
17
- type Story = StoryObj<typeof Participants>;
18
-
19
- // Mock data for stories
20
- const mockParticipants: Participant[] = [
21
- {
22
- code: 'P001',
23
- name: 'Alice Johnson',
24
- age: '29',
25
- gender: 'F',
26
- role: 'Interviewer',
27
- order: 1,
28
- },
29
- {
30
- code: 'P002',
31
- name: 'Bob Smith',
32
- age: '35',
33
- gender: 'M',
34
- role: 'Interviewee',
35
- order: 2,
36
- },
37
- ];
38
-
39
- export const Primary: Story = {
40
- args: {
41
- document: 'doc-001',
42
- participants: mockParticipants,
43
- onChange: action('Participants list changed'),
44
- },
45
- };
@@ -1,145 +0,0 @@
1
- import { faPlus, faTrash } from '@fortawesome/free-solid-svg-icons';
2
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
- import { useContext, useEffect, useState } from 'react';
4
- import { Button, Form } from 'react-bootstrap';
5
- import { useTranslation } from 'react-i18next';
6
- import AppEditable from '../AppEditable';
7
- import AppEditableField from '../AppEditable/AppEditableField';
8
- import CommonContext from '../configs/CommonContext';
9
- import { dispatchMessage } from '../configs/MessageUtils';
10
- import ParticipantCreate from './ParticipantCreate';
11
- import ParticipantRemove from './ParticipantRemove';
12
- import './style.scss';
13
- import Participant, { PARTICIPANT_FIELDS } from './types/Participant';
14
- import ParticipantService from './types/ParticipantService';
15
-
16
- type Props = {
17
- document: string;
18
- onChange: (p: Participant[]) => void;
19
- participants: Participant[];
20
- };
21
-
22
- export default function Participants({
23
- document,
24
- participants,
25
- onChange,
26
- }: Props) {
27
- const { t } = useTranslation('participants');
28
- const { dispatch } = useContext(CommonContext);
29
-
30
- const [participant, setParticipant] = useState<Participant>();
31
- const [openRemove, setOpenRemove] = useState(false);
32
- const [openCreate, setOpenCreate] = useState(false);
33
-
34
- const handleSave = (field: AppEditableField) => {
35
- if (!field.ref) return;
36
-
37
- ParticipantService.update(field)
38
- .then(() => {
39
- dispatchMessage({ key: 'update.success', dispatch, t });
40
- const { name, value } = field;
41
-
42
- const thisParticipants = participants;
43
- const idx = participants.findIndex((p) => p.code === field.ref);
44
-
45
- // updates the participant
46
- const thisParticipant = { ...thisParticipants[idx], [name]: value };
47
- thisParticipants[idx] = { ...thisParticipant };
48
- setParticipant(thisParticipant);
49
-
50
- onChange(thisParticipants);
51
- })
52
- .catch((err) => {
53
- console.log(err);
54
- });
55
- };
56
-
57
- useEffect(() => {
58
- if (participants.length > 0) setParticipant(participants[0]);
59
- }, []);
60
-
61
- return (
62
- <div className="participants-container">
63
- <div className="header">
64
- <h3>{t('label.title')}</h3>
65
- <div className="actions">
66
- <button
67
- type="button"
68
- className="action"
69
- onClick={() => setOpenCreate(true)}
70
- >
71
- <FontAwesomeIcon icon={faPlus} title={t('button.label.add')} />
72
- <span className="ms-2">{t('button.label.add')}</span>
73
- </button>
74
- </div>
75
- </div>
76
- <div className="body">
77
- {participant && (
78
- <>
79
- <Form.Select
80
- onChange={(e) =>
81
- setParticipant(participants[Number(e.target.value)])
82
- }
83
- >
84
- {participants.map((el, idx) => (
85
- <option value={idx} key={idx}>
86
- {`${el.code} - ${el.name}`}
87
- </option>
88
- ))}
89
- </Form.Select>
90
- <AppEditable
91
- translation="participants"
92
- group="participant"
93
- save={handleSave}
94
- item={{ ...participant, uid: document }}
95
- fields={PARTICIPANT_FIELDS}
96
- className="fields"
97
- reference="code"
98
- />
99
- <div className="footer">
100
- <Button
101
- variant="danger"
102
- onClick={() => {
103
- setParticipant(participant);
104
- setOpenRemove(true);
105
- }}
106
- >
107
- <FontAwesomeIcon icon={faTrash} />
108
- <span className="ms-1">{t('common:button.remove')}</span>
109
- </Button>
110
- </div>
111
- </>
112
- )}
113
- </div>
114
- {participant && openRemove && (
115
- <ParticipantRemove
116
- document={document}
117
- onChange={(list) => {
118
- onChange(list);
119
- setParticipant(
120
- participants.length > 0 ? participants[0] : undefined
121
- );
122
- setOpenRemove(false);
123
- }}
124
- participant={participant}
125
- participants={participants}
126
- onClose={() => setOpenRemove(false)}
127
- />
128
- )}
129
-
130
- {openCreate && (
131
- <ParticipantCreate
132
- document={document}
133
- order={participants.length || 1}
134
- onCreate={(p) => {
135
- const thisParticipants = participants ? [...participants, p] : [p];
136
- onChange(thisParticipants);
137
- setParticipant(p);
138
- setOpenCreate(false);
139
- }}
140
- onClose={() => setOpenCreate(false)}
141
- />
142
- )}
143
- </div>
144
- );
145
- }