@addsign/moje-agenda-shared-lib 1.0.60 → 2.0.0
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/Dialog-DZMfjbGC.js +421 -0
- package/dist/Dialog-DZMfjbGC.js.map +1 -0
- package/dist/assets/style.css +4369 -0
- package/dist/assets/tailwind.css +1365 -1193
- package/dist/check-B7dJm08z.js +12 -0
- package/dist/check-B7dJm08z.js.map +1 -0
- package/dist/components/Button.js +1 -1
- package/dist/components/datatable/DataTable.js +6 -2
- package/dist/components/datatable/DataTable.js.map +1 -1
- package/dist/components/datatable/DataTableServer.js +6 -2
- package/dist/components/datatable/DataTableServer.js.map +1 -1
- package/dist/components/form/AutocompleteSearchBar.js +6 -2
- package/dist/components/form/AutocompleteSearchBar.js.map +1 -1
- package/dist/components/form/AutocompleteSearchBarServer.js +6 -2
- package/dist/components/form/AutocompleteSearchBarServer.js.map +1 -1
- package/dist/components/form/FileInput.js +7 -3
- package/dist/components/form/FileInput.js.map +1 -1
- package/dist/components/form/FileInputMultiple.js +7 -3
- package/dist/components/form/FileInputMultiple.js.map +1 -1
- package/dist/components/form/FormField.js +6 -2
- package/dist/components/form/FormField.js.map +1 -1
- package/dist/components/form/PositionsSelectorSingle.js +6 -2
- package/dist/components/form/PositionsSelectorSingle.js.map +1 -1
- package/dist/components/form/SelectField.js +6 -2
- package/dist/components/form/SelectField.js.map +1 -1
- package/dist/components/profiles/ProfileOverview.js +6 -2
- package/dist/components/profiles/ProfileOverview.js.map +1 -1
- package/dist/components/ui/Combobox.d.ts +1 -0
- package/dist/components/ui/Combobox.js +138 -0
- package/dist/components/ui/Combobox.js.map +1 -0
- package/dist/components/ui/DateTimePicker.js +19 -5
- package/dist/components/ui/DateTimePicker.js.map +1 -1
- package/dist/components/ui/Dialog.js +15 -413
- package/dist/components/ui/Dialog.js.map +1 -1
- package/dist/components/ui/ScrollArea.js +2 -1
- package/dist/components/ui/ScrollArea.js.map +1 -1
- package/dist/components/ui/command.d.ts +80 -0
- package/dist/components/ui/command.js +643 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/datepicker.js +14 -1
- package/dist/components/ui/datepicker.js.map +1 -1
- package/dist/components/ui/popover.js +3 -2
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/radioGroup.d.ts +5 -0
- package/dist/components/ui/radioGroup.js +586 -0
- package/dist/components/ui/radioGroup.js.map +1 -0
- package/dist/components/ui/select.js +9 -144
- package/dist/components/ui/select.js.map +1 -1
- package/dist/index-BXrwe-_7.js +1395 -0
- package/dist/index-BXrwe-_7.js.map +1 -0
- package/dist/index-Bk8dRTPE.js +11 -0
- package/dist/index-Bk8dRTPE.js.map +1 -0
- package/dist/index-BlzC-wss.js +140 -0
- package/dist/index-BlzC-wss.js.map +1 -0
- package/dist/index-Bp9GiUkg.js +2266 -0
- package/dist/index-Bp9GiUkg.js.map +1 -0
- package/dist/index-BzVVosDl.js +57 -0
- package/dist/index-BzVVosDl.js.map +1 -0
- package/dist/index-CbAQSs_C.js +40 -0
- package/dist/index-CbAQSs_C.js.map +1 -0
- package/dist/index-Dz_fWpFA.js +2203 -0
- package/dist/index-Dz_fWpFA.js.map +1 -0
- package/dist/index-IXOTxK3N.js +7 -0
- package/dist/index-IXOTxK3N.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.js +29 -12
- package/dist/main.js.map +1 -1
- package/dist/parse-D2yb8751.js +1727 -0
- package/dist/parse-D2yb8751.js.map +1 -0
- package/dist/tailwind-l0sNRNKZ.js +2 -0
- package/dist/tailwind-l0sNRNKZ.js.map +1 -0
- package/lib/components/Button.tsx +57 -0
- package/lib/components/Calendar.tsx +242 -0
- package/lib/components/ConfirmationModalDialog.tsx +115 -0
- package/lib/components/Modal.tsx +73 -0
- package/lib/components/ModalDialog.tsx +63 -0
- package/lib/components/Spinner.tsx +25 -0
- package/lib/components/SpinnerIcon.tsx +12 -0
- package/lib/components/datatable/DataTable.tsx +442 -0
- package/lib/components/datatable/DataTableServer.tsx +939 -0
- package/lib/components/datatable/DatatableSettings.tsx +48 -0
- package/lib/components/datatable/Resizable.tsx +99 -0
- package/lib/components/datatable/types.ts +33 -0
- package/lib/components/form/AutocompleteSearchBar.tsx +424 -0
- package/lib/components/form/AutocompleteSearchBarServer.tsx +257 -0
- package/lib/components/form/DateField.tsx +124 -0
- package/lib/components/form/DateRangeField.tsx +116 -0
- package/lib/components/form/FileInput.tsx +188 -0
- package/lib/components/form/FileInputMultiple.tsx +186 -0
- package/lib/components/form/FormField.tsx +371 -0
- package/lib/components/form/InputField.tsx +230 -0
- package/lib/components/form/PositionsSelectorSingle.tsx +266 -0
- package/lib/components/form/RadioGroup.tsx +64 -0
- package/lib/components/form/SelectField.tsx +267 -0
- package/lib/components/layout/IconInCircle.tsx +29 -0
- package/lib/components/layout/PageTitle.tsx +19 -0
- package/lib/components/layout/SectionTitle.tsx +22 -0
- package/lib/components/profiles/ProfileOverview.tsx +212 -0
- package/lib/components/ui/Calendar.tsx +68 -0
- package/lib/components/ui/Combobox.tsx +122 -0
- package/lib/components/ui/DatePicker.tsx +124 -0
- package/lib/components/ui/DateTimePicker.tsx +187 -0
- package/lib/components/ui/Dialog.tsx +118 -0
- package/lib/components/ui/ScrollArea.tsx +45 -0
- package/lib/components/ui/button.tsx +56 -0
- package/lib/components/ui/command.tsx +153 -0
- package/lib/components/ui/form.tsx +177 -0
- package/lib/components/ui/input.tsx +22 -0
- package/lib/components/ui/label.tsx +24 -0
- package/lib/components/ui/popover.tsx +31 -0
- package/lib/components/ui/radioGroup.tsx +44 -0
- package/lib/components/ui/select.tsx +158 -0
- package/lib/contexts/FederationContext.tsx +28 -0
- package/lib/contexts/useFederationContext.ts +4 -0
- package/lib/css/tailwind.css +10 -0
- package/lib/fonts/arial.ts +3 -0
- package/lib/fonts/arialBold.ts +4 -0
- package/lib/main.ts +64 -0
- package/lib/types.ts +492 -0
- package/lib/utils/PdfManager.ts +224 -0
- package/lib/utils/getFullName.tsx +83 -0
- package/lib/utils/getIntersectingDays.ts +28 -0
- package/lib/utils/handleErrors.ts +28 -0
- package/lib/utils/hasRightInModule.ts +17 -0
- package/lib/utils/hasRole.ts +12 -0
- package/lib/utils/utils.ts +6 -0
- package/lib/vite-env.d.ts +1 -0
- package/package.json +5 -2
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { IFormFieldGlobalProps } from "../../types";
|
|
3
|
+
import { MdClose } from "react-icons/md";
|
|
4
|
+
import { useClickAway } from "react-use";
|
|
5
|
+
import { FaSpinner } from "react-icons/fa";
|
|
6
|
+
import SpinnerIcon from "../SpinnerIcon";
|
|
7
|
+
|
|
8
|
+
export interface IInputFieldProps extends IFormFieldGlobalProps {
|
|
9
|
+
maxLength?: number;
|
|
10
|
+
debounceTimeout?: number;
|
|
11
|
+
manualRef?: React.RefObject<HTMLInputElement>;
|
|
12
|
+
disableAutocomplete?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function InputField({
|
|
16
|
+
label,
|
|
17
|
+
name,
|
|
18
|
+
value,
|
|
19
|
+
description,
|
|
20
|
+
onInputChange,
|
|
21
|
+
placeholder,
|
|
22
|
+
className,
|
|
23
|
+
register,
|
|
24
|
+
type,
|
|
25
|
+
disabled,
|
|
26
|
+
maxLength,
|
|
27
|
+
errors = {},
|
|
28
|
+
rounded = true,
|
|
29
|
+
debounceTimeout,
|
|
30
|
+
required,
|
|
31
|
+
onFocus = () => {},
|
|
32
|
+
onBlur = () => {},
|
|
33
|
+
children,
|
|
34
|
+
disableAutocomplete,
|
|
35
|
+
}: IInputFieldProps) {
|
|
36
|
+
const wrapperRef = React.useRef(null);
|
|
37
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
38
|
+
const [inputValue, setInputValue] = React.useState(value || ""); // Local state for input value
|
|
39
|
+
const debounceTimeoutRef = React.useRef<NodeJS.Timeout | null>(null); // Ref to hold the debounce timeout
|
|
40
|
+
const [inputIsChanging, setInputIsChanging] = React.useState(false);
|
|
41
|
+
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
setInputValue(value || "");
|
|
44
|
+
}, [value]);
|
|
45
|
+
const handleClear = (e: any) => {
|
|
46
|
+
setInputValue(""); // Clear local state
|
|
47
|
+
onInputChange({
|
|
48
|
+
...e,
|
|
49
|
+
target: {
|
|
50
|
+
value: "",
|
|
51
|
+
name: name,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
const fallbackRef = React.useRef(null);
|
|
56
|
+
const {
|
|
57
|
+
ref: registeredRef = fallbackRef,
|
|
58
|
+
onBlur: formOnBlur = () => {} /* default function */,
|
|
59
|
+
...rest
|
|
60
|
+
} = register ? register(name) : {};
|
|
61
|
+
|
|
62
|
+
const ref = registeredRef || fallbackRef;
|
|
63
|
+
const handleSetFocus = () => {
|
|
64
|
+
setIsFocused(true);
|
|
65
|
+
ref?.current?.focus();
|
|
66
|
+
};
|
|
67
|
+
useClickAway(wrapperRef, () => {
|
|
68
|
+
if (isFocused) {
|
|
69
|
+
setIsFocused(false);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const handleDebouncedChange = React.useCallback(
|
|
74
|
+
(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
75
|
+
const { value } = e.target;
|
|
76
|
+
setInputValue(value); // Update local state
|
|
77
|
+
setInputIsChanging(true);
|
|
78
|
+
|
|
79
|
+
if (debounceTimeout) {
|
|
80
|
+
// Clear any previous debounce timeout
|
|
81
|
+
if (debounceTimeoutRef.current)
|
|
82
|
+
clearTimeout(debounceTimeoutRef.current);
|
|
83
|
+
|
|
84
|
+
// Set a new debounce timeout
|
|
85
|
+
debounceTimeoutRef.current = setTimeout(() => {
|
|
86
|
+
onInputChange(e);
|
|
87
|
+
setInputIsChanging(false);
|
|
88
|
+
}, debounceTimeout);
|
|
89
|
+
} else {
|
|
90
|
+
onInputChange(e);
|
|
91
|
+
setInputIsChanging(false);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
[debounceTimeout, debounceTimeoutRef, onInputChange, setInputValue]
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const handleBlur = (
|
|
98
|
+
e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>
|
|
99
|
+
) => {
|
|
100
|
+
formOnBlur(e); // Call React Hook Form's onBlur
|
|
101
|
+
setIsFocused(false); // Then call your custom onBlur logic
|
|
102
|
+
|
|
103
|
+
if (debounceTimeoutRef.current && inputIsChanging) {
|
|
104
|
+
clearTimeout(debounceTimeoutRef.current);
|
|
105
|
+
onInputChange(e);
|
|
106
|
+
setInputIsChanging(false);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const renderInput = () => {
|
|
111
|
+
switch (type) {
|
|
112
|
+
case "textarea":
|
|
113
|
+
return (
|
|
114
|
+
<textarea
|
|
115
|
+
id={name}
|
|
116
|
+
name={name}
|
|
117
|
+
className="grow shrink basis-0 text-gray-900 text-sm font-normal leading-tight focus:border-none
|
|
118
|
+
bg-white "
|
|
119
|
+
disabled={disabled}
|
|
120
|
+
value={inputValue}
|
|
121
|
+
rows={3}
|
|
122
|
+
{...rest} // Spread the rest of register's return value
|
|
123
|
+
// ref={ref}
|
|
124
|
+
onChange={(e) => handleDebouncedChange(e)}
|
|
125
|
+
onFocus={() => {
|
|
126
|
+
setIsFocused(true);
|
|
127
|
+
onFocus();
|
|
128
|
+
}}
|
|
129
|
+
onBlur={(e) => {
|
|
130
|
+
handleBlur(e);
|
|
131
|
+
onBlur();
|
|
132
|
+
}}
|
|
133
|
+
maxLength={maxLength || 4000}
|
|
134
|
+
/>
|
|
135
|
+
);
|
|
136
|
+
default:
|
|
137
|
+
return (
|
|
138
|
+
<>
|
|
139
|
+
<input
|
|
140
|
+
className={`text-gray-900 text-sm font-normal leading-normal
|
|
141
|
+
text-ellipsis overflow-hidden w-full disabled:cursor-not-allowed bg-white`}
|
|
142
|
+
id={name}
|
|
143
|
+
name={name}
|
|
144
|
+
disabled={disabled}
|
|
145
|
+
type={type}
|
|
146
|
+
{...rest}
|
|
147
|
+
// ref={ref}
|
|
148
|
+
value={inputValue} // Controlled value
|
|
149
|
+
placeholder={placeholder}
|
|
150
|
+
onChange={(e) => handleDebouncedChange(e)}
|
|
151
|
+
onFocus={() => {
|
|
152
|
+
setIsFocused(true);
|
|
153
|
+
onFocus();
|
|
154
|
+
}}
|
|
155
|
+
onBlur={(e) => {
|
|
156
|
+
handleBlur(e);
|
|
157
|
+
onBlur();
|
|
158
|
+
}}
|
|
159
|
+
autoComplete={disableAutocomplete ? "off" : "on"}
|
|
160
|
+
/>
|
|
161
|
+
</>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<>
|
|
168
|
+
<div
|
|
169
|
+
className={
|
|
170
|
+
"min-h-30 flex-col justify-start items-start gap-1.5 w-full relative " +
|
|
171
|
+
className
|
|
172
|
+
}
|
|
173
|
+
ref={wrapperRef}
|
|
174
|
+
id="component"
|
|
175
|
+
>
|
|
176
|
+
<div className="self-stretch flex-col justify-start items-start gap-1.5 flex">
|
|
177
|
+
{label && (
|
|
178
|
+
<div className="text-slate-700 text-sm font-medium leading-tight">
|
|
179
|
+
{label} {required ? "*" : ""}
|
|
180
|
+
</div>
|
|
181
|
+
)}
|
|
182
|
+
<div
|
|
183
|
+
className={`self-stretch w-full pl-3 pr-2 py-1 border justify-between items-center gap-0 inline-flex outline-none bg-white
|
|
184
|
+
${isFocused ? "outline-4 outline-indigo-200 outline-offset-0 border-indigo-300 " : ""}
|
|
185
|
+
${rounded ? " rounded-lg " : " rounded-none "}
|
|
186
|
+
${disabled ? " !opacity-80 cursor-not-allowed " : ""}`}
|
|
187
|
+
onClick={handleSetFocus}
|
|
188
|
+
>
|
|
189
|
+
<div className="flex-grow basis-0 min-h-[32px] justify-start items-center gap-0 flex whitespace-nowrap w-[calc(100%-40px)] ">
|
|
190
|
+
{renderInput()}
|
|
191
|
+
</div>
|
|
192
|
+
<div className="items-center content-center flex-shrink flex">
|
|
193
|
+
{inputIsChanging === true && (
|
|
194
|
+
<div className="w-6 h-6 relative flex items-center justify-center align-middle">
|
|
195
|
+
<SpinnerIcon icon={<FaSpinner />} />
|
|
196
|
+
</div>
|
|
197
|
+
)}
|
|
198
|
+
{value && !disabled && (
|
|
199
|
+
<div
|
|
200
|
+
className="w-6 h-6 relative flex cursor-pointer items-center justify-center align-middle hover:bg-gray-100 rounded-full text-lg"
|
|
201
|
+
onClick={handleClear}
|
|
202
|
+
id={name + ":clear"}
|
|
203
|
+
>
|
|
204
|
+
<MdClose />
|
|
205
|
+
</div>
|
|
206
|
+
)}
|
|
207
|
+
{children}
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
{description && !isFocused && (
|
|
212
|
+
<div
|
|
213
|
+
className="self-stretch text-slate-600 text-sm font-normal leading-tight"
|
|
214
|
+
id={name + ":description"}
|
|
215
|
+
>
|
|
216
|
+
{description}
|
|
217
|
+
</div>
|
|
218
|
+
)}{" "}
|
|
219
|
+
{errors[name] && (
|
|
220
|
+
<div
|
|
221
|
+
className="HintText self-stretch text-red-600 text-sm font-normal leading-tight mt-1"
|
|
222
|
+
id={name + ":error"}
|
|
223
|
+
>
|
|
224
|
+
{errors[name]?.message}
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
227
|
+
</div>
|
|
228
|
+
</>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
AutocompleteSearchBar,
|
|
4
|
+
Button,
|
|
5
|
+
FormField,
|
|
6
|
+
IPositionEmployee,
|
|
7
|
+
SectionTitle,
|
|
8
|
+
getFullName,
|
|
9
|
+
} from "../../main";
|
|
10
|
+
import { AxiosResponse } from "axios";
|
|
11
|
+
import { CiEdit } from "react-icons/ci";
|
|
12
|
+
|
|
13
|
+
import { useFederationContext } from "../../main";
|
|
14
|
+
import { MdCheck } from "react-icons/md";
|
|
15
|
+
|
|
16
|
+
interface IPositionsSelectorSingleProps {
|
|
17
|
+
label: string;
|
|
18
|
+
name: string;
|
|
19
|
+
onInputChange: (e: any) => void;
|
|
20
|
+
initPositionEmployee?: IPositionEmployee;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
initDepartmentId?: string;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
}
|
|
25
|
+
function PositionsSelectorSingle({
|
|
26
|
+
label,
|
|
27
|
+
name,
|
|
28
|
+
onInputChange,
|
|
29
|
+
initPositionEmployee,
|
|
30
|
+
disabled,
|
|
31
|
+
initDepartmentId,
|
|
32
|
+
placeholder,
|
|
33
|
+
}: IPositionsSelectorSingleProps) {
|
|
34
|
+
const [isModalOpen, setModalOpen] = useState(false);
|
|
35
|
+
const [department, setDepartment] = useState("");
|
|
36
|
+
const [positions, setPositions] = useState<IPositionEmployee[]>([]); // State to hold the original data
|
|
37
|
+
const [selectedPositionEmployee, setSelectedPositionEmployee] =
|
|
38
|
+
useState<IPositionEmployee>(); // State to hold the original data
|
|
39
|
+
const [storedPositionEmployee, setStoredPositionEmployee] =
|
|
40
|
+
useState<IPositionEmployee>(); // State to hold the original data
|
|
41
|
+
|
|
42
|
+
const apiClient = useFederationContext()?.apiClient;
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
46
|
+
if (event.key === "Escape") {
|
|
47
|
+
setModalOpen(false);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
51
|
+
return () => {
|
|
52
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
53
|
+
};
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
setSelectedPositionEmployee(initPositionEmployee);
|
|
58
|
+
setStoredPositionEmployee(initPositionEmployee);
|
|
59
|
+
setDepartment(department);
|
|
60
|
+
}, [initPositionEmployee, department]);
|
|
61
|
+
|
|
62
|
+
//If I will get init department ID and not init position employee, I will use the init department ID as a default departmen
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (initDepartmentId && !initPositionEmployee) {
|
|
65
|
+
setDepartment(initDepartmentId);
|
|
66
|
+
}
|
|
67
|
+
}, [initDepartmentId, initPositionEmployee]);
|
|
68
|
+
|
|
69
|
+
const handleSave = (
|
|
70
|
+
selectedPositionEmployee: IPositionEmployee | undefined
|
|
71
|
+
) => {
|
|
72
|
+
onInputChange({
|
|
73
|
+
target: { name: name, value: selectedPositionEmployee || null },
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
setStoredPositionEmployee(selectedPositionEmployee);
|
|
77
|
+
setModalOpen(false);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const handleSelectedPositionEmployee = (position: IPositionEmployee) => {
|
|
81
|
+
console.log(
|
|
82
|
+
"%csrcsharedPositionsSelectorSingle.tsx:54 position",
|
|
83
|
+
"color: #007acc;",
|
|
84
|
+
position,
|
|
85
|
+
selectedPositionEmployee,
|
|
86
|
+
position.id == selectedPositionEmployee?.id
|
|
87
|
+
);
|
|
88
|
+
if (
|
|
89
|
+
!selectedPositionEmployee ||
|
|
90
|
+
position.id !== selectedPositionEmployee?.id
|
|
91
|
+
) {
|
|
92
|
+
setSelectedPositionEmployee(position);
|
|
93
|
+
} else {
|
|
94
|
+
setSelectedPositionEmployee(undefined);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const handleDepartmentChange = (e: any) => {
|
|
98
|
+
console.log("%csrcsharedTransferListModal.tsx:109 e", "color: #007acc;", e);
|
|
99
|
+
setDepartment(e);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (department && isModalOpen) {
|
|
104
|
+
apiClient
|
|
105
|
+
.get(
|
|
106
|
+
"os/positions/employees?maxResults=1000&departmentId=" + department
|
|
107
|
+
)
|
|
108
|
+
.then((response: AxiosResponse) => {
|
|
109
|
+
setPositions(response.data?.content);
|
|
110
|
+
})
|
|
111
|
+
.catch((error: any) => {
|
|
112
|
+
console.error(
|
|
113
|
+
"There was an error fetching positions/employees",
|
|
114
|
+
error
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}, [apiClient, department, isModalOpen]);
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<>
|
|
122
|
+
<div className="">
|
|
123
|
+
<p className="text-slate-700 text-sm leading-tight font-medium mb-2">
|
|
124
|
+
{label}:
|
|
125
|
+
</p>
|
|
126
|
+
<div className="w-full flex gap-5 ">
|
|
127
|
+
<FormField
|
|
128
|
+
placeholder={placeholder || "Zatím není určen"}
|
|
129
|
+
name={name}
|
|
130
|
+
onInputChange={() => {}}
|
|
131
|
+
type="text"
|
|
132
|
+
disabled
|
|
133
|
+
value={
|
|
134
|
+
storedPositionEmployee?.employee
|
|
135
|
+
? getFullName(storedPositionEmployee?.employee, true, false)
|
|
136
|
+
: ""
|
|
137
|
+
}
|
|
138
|
+
></FormField>
|
|
139
|
+
<Button
|
|
140
|
+
className={"text-xl " + (disabled ? "hidden" : "")}
|
|
141
|
+
variant="primary"
|
|
142
|
+
onClick={() => setModalOpen(true)}
|
|
143
|
+
disabled={disabled}
|
|
144
|
+
>
|
|
145
|
+
<CiEdit></CiEdit>
|
|
146
|
+
</Button>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
{isModalOpen && (
|
|
150
|
+
<div
|
|
151
|
+
className="fixed inset-0 bg-black bg-opacity-25 flex items-center justify-center p-5"
|
|
152
|
+
style={{ zIndex: 50 }}
|
|
153
|
+
>
|
|
154
|
+
<div
|
|
155
|
+
className="bg-white rounded-lg shadow-xl m-4 overflow-auto max-h-full pointer-events-auto "
|
|
156
|
+
style={{ width: "50vw" }}
|
|
157
|
+
>
|
|
158
|
+
<div className="flex flex-col gap-4 p-5">
|
|
159
|
+
<div className="">
|
|
160
|
+
<SectionTitle>{label} - Výběr pozice</SectionTitle>{" "}
|
|
161
|
+
</div>
|
|
162
|
+
<div className="">
|
|
163
|
+
<AutocompleteSearchBar
|
|
164
|
+
name="departmentId"
|
|
165
|
+
placeholder="Vyhledejte útvar"
|
|
166
|
+
fetchUrl="os/departments?pageSize=5000"
|
|
167
|
+
valueKey="departmentId"
|
|
168
|
+
labelKey="nameLong"
|
|
169
|
+
label="Útvar"
|
|
170
|
+
onChange={handleDepartmentChange}
|
|
171
|
+
onBlur={() => {}}
|
|
172
|
+
onFocus={() => {}}
|
|
173
|
+
value={department}
|
|
174
|
+
showId={true}
|
|
175
|
+
></AutocompleteSearchBar>
|
|
176
|
+
</div>
|
|
177
|
+
<div className=" max-h-[400px] overflow-auto">
|
|
178
|
+
<div className="pt-4 w-full grid grid-cols-2 gap-x-4">
|
|
179
|
+
<div className="text-slate-700 text-sm leading-tight font-medium my-4 col-span-2">
|
|
180
|
+
Nalezené pozice:
|
|
181
|
+
</div>
|
|
182
|
+
{positions.map((position) => (
|
|
183
|
+
<div
|
|
184
|
+
key={position.id}
|
|
185
|
+
className={`group flex justify-between items-center py-2 cursor-pointer ${
|
|
186
|
+
position.id == selectedPositionEmployee?.id
|
|
187
|
+
? " bg-gray-100 hover:bg-gray-200 "
|
|
188
|
+
: "hover:bg-gray-50"
|
|
189
|
+
} `}
|
|
190
|
+
onClick={() => handleSelectedPositionEmployee(position)}
|
|
191
|
+
>
|
|
192
|
+
<div className=" ">
|
|
193
|
+
{getFullName(position.employee, true)}
|
|
194
|
+
</div>
|
|
195
|
+
<div
|
|
196
|
+
className={` group-hover:text-gray-300 px-3 ${
|
|
197
|
+
position.id == selectedPositionEmployee?.id
|
|
198
|
+
? " text-blue-500 group-hover:text-black "
|
|
199
|
+
: "text-transparent"
|
|
200
|
+
}`}
|
|
201
|
+
>
|
|
202
|
+
<MdCheck size={25} />
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
))}
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
<div className="flex justify-between gap-4">
|
|
209
|
+
<div className=" w-1/2 group flex ">
|
|
210
|
+
<FormField
|
|
211
|
+
placeholder="Zatím není určen"
|
|
212
|
+
name={name}
|
|
213
|
+
label="Zvolená pozice "
|
|
214
|
+
onInputChange={() => {}}
|
|
215
|
+
type="text"
|
|
216
|
+
disabled
|
|
217
|
+
value={
|
|
218
|
+
selectedPositionEmployee
|
|
219
|
+
? getFullName(
|
|
220
|
+
selectedPositionEmployee?.employee,
|
|
221
|
+
true,
|
|
222
|
+
false
|
|
223
|
+
)
|
|
224
|
+
: ""
|
|
225
|
+
}
|
|
226
|
+
></FormField>
|
|
227
|
+
{selectedPositionEmployee && (
|
|
228
|
+
<div className="flex justify-end space-x-5 mt-auto ml-5">
|
|
229
|
+
{" "}
|
|
230
|
+
<Button
|
|
231
|
+
variant="secondary"
|
|
232
|
+
onClick={() =>
|
|
233
|
+
handleSelectedPositionEmployee(
|
|
234
|
+
selectedPositionEmployee
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
>
|
|
238
|
+
Odebrat přiřazení
|
|
239
|
+
</Button>
|
|
240
|
+
</div>
|
|
241
|
+
)}
|
|
242
|
+
</div>
|
|
243
|
+
<div className="flex justify-end space-x-5 mt-auto ">
|
|
244
|
+
<Button
|
|
245
|
+
variant="secondary"
|
|
246
|
+
onClick={() => setModalOpen(false)}
|
|
247
|
+
>
|
|
248
|
+
Zrušit
|
|
249
|
+
</Button>
|
|
250
|
+
<Button
|
|
251
|
+
variant="primary"
|
|
252
|
+
onClick={() => handleSave(selectedPositionEmployee)}
|
|
253
|
+
>
|
|
254
|
+
Uložit
|
|
255
|
+
</Button>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
)}
|
|
262
|
+
</>
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export default PositionsSelectorSingle;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { IFormFieldGlobalProps, IOptionItem } from "../../types";
|
|
2
|
+
|
|
3
|
+
export interface IRadioGroupProps extends IFormFieldGlobalProps {
|
|
4
|
+
options?: IOptionItem[];
|
|
5
|
+
valueKey?: string;
|
|
6
|
+
labelKey?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function RadioGroup({
|
|
10
|
+
label,
|
|
11
|
+
name,
|
|
12
|
+
value,
|
|
13
|
+
description,
|
|
14
|
+
onInputChange,
|
|
15
|
+
options,
|
|
16
|
+
errors = {},
|
|
17
|
+
required,
|
|
18
|
+
disabled,
|
|
19
|
+
register = () => {},
|
|
20
|
+
}: IRadioGroupProps) {
|
|
21
|
+
return (
|
|
22
|
+
<div className="w-full min-h-30 flex-col justify-start items-start gap-1.5 sharedLibrary">
|
|
23
|
+
<div className="self-stretch flex-col justify-start items-start gap-1.5 flex mb-2">
|
|
24
|
+
{label && (
|
|
25
|
+
<label
|
|
26
|
+
className="text-slate-700 text-sm leading-tight font-medium"
|
|
27
|
+
htmlFor={name}
|
|
28
|
+
>
|
|
29
|
+
{label} {required ? "*" : ""}
|
|
30
|
+
</label>
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
<div className="flex flex-col gap-1">
|
|
34
|
+
{options?.map((option, index) => (
|
|
35
|
+
<label key={index} className="inline-flex items-center space-x-2">
|
|
36
|
+
<input
|
|
37
|
+
type="radio"
|
|
38
|
+
name={name}
|
|
39
|
+
value={option.value}
|
|
40
|
+
checked={value === option.value}
|
|
41
|
+
disabled={disabled}
|
|
42
|
+
{...register(name)} // Spread the rest of register's return value
|
|
43
|
+
onChange={onInputChange}
|
|
44
|
+
className="text-indigo-600 border-gray-300 focus:ring-indigo-500 mr-2"
|
|
45
|
+
/>
|
|
46
|
+
<span className="text-gray-900 text-sm font-normal leading-tight">
|
|
47
|
+
{option.label}
|
|
48
|
+
</span>
|
|
49
|
+
</label>
|
|
50
|
+
))}
|
|
51
|
+
</div>
|
|
52
|
+
{description && (
|
|
53
|
+
<div className="HintText self-stretch text-slate-600 text-sm font-normal leading-tight">
|
|
54
|
+
{description}
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
{errors[name] && (
|
|
58
|
+
<div className="HintText self-stretch text-red-600 text-sm font-normal leading-tight">
|
|
59
|
+
{errors[name]?.message}
|
|
60
|
+
</div>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|