mirror of
				https://gitlab.nic.cz/turris/reforis/foris-js.git
				synced 2025-10-30 22:20:31 +01:00 
			
		
		
		
	Client configuration
This commit is contained in:
		
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "foris", | ||||
|   "version": "1.0.0", | ||||
|   "version": "1.1.0", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "foris", | ||||
|   "version": "1.0.0", | ||||
|   "version": "1.1.0", | ||||
|   "description": "Set of components and utils for Foris and its plugins.", | ||||
|   "author": "CZ.NIC, z.s.p.o.", | ||||
|   "repository": { | ||||
|   | ||||
| @@ -12,7 +12,7 @@ import { | ||||
|     API_ACTIONS, TIMEOUT, HEADERS, APIReducer, getErrorMessage, | ||||
| } from "./utils"; | ||||
|  | ||||
| export function useAPIPost(url) { | ||||
| export function useAPIPost(url, contentType) { | ||||
|     const [state, dispatch] = useReducer(APIReducer, { | ||||
|         isSending: false, | ||||
|         isError: false, | ||||
| @@ -20,12 +20,17 @@ export function useAPIPost(url) { | ||||
|         data: null, | ||||
|     }); | ||||
|  | ||||
|     const headers = { ...HEADERS }; | ||||
|     if (contentType) { | ||||
|         headers["Content-Type"] = contentType; | ||||
|     } | ||||
|  | ||||
|     const post = async (data) => { | ||||
|         dispatch({ type: API_ACTIONS.INIT }); | ||||
|         try { | ||||
|             const result = await axios.post(url, data, { | ||||
|                 timeout: TIMEOUT, | ||||
|                 headers: HEADERS, | ||||
|                 headers, | ||||
|             }); | ||||
|             dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); | ||||
|         } catch (error) { | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  | ||||
| import React from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { useUID } from "react-uid/dist/es5/index"; | ||||
| import { useUID } from "react-uid"; | ||||
|  | ||||
| import { formFieldsSize } from "./constants"; | ||||
|  | ||||
|   | ||||
							
								
								
									
										34
									
								
								src/bootstrap/FileInput.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/bootstrap/FileInput.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/) | ||||
|  * | ||||
|  * This is free software, licensed under the GNU General Public License v3. | ||||
|  * See /LICENSE for more information. | ||||
|  */ | ||||
|  | ||||
| import React from "react"; | ||||
|  | ||||
| import PropTypes from "prop-types"; | ||||
| import { Input } from "./Input"; | ||||
|  | ||||
| FileInput.propTypes = { | ||||
|     /** Field label. */ | ||||
|     label: PropTypes.string.isRequired, | ||||
|     /** Error message. */ | ||||
|     error: PropTypes.string, | ||||
|     /** Help text message. */ | ||||
|     helpText: PropTypes.string, | ||||
|     /** Email value. */ | ||||
|     value: PropTypes.string, | ||||
| }; | ||||
|  | ||||
| export function FileInput({ ...props }) { | ||||
|     return ( | ||||
|         <Input | ||||
|             type="file" | ||||
|             className="custom-file-input" | ||||
|             labelClassName="custom-file-label" | ||||
|             groupClassName="custom-file" | ||||
|             {...props} | ||||
|         /> | ||||
|     ); | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/bootstrap/FileInput.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/bootstrap/FileInput.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| Bootstrap component for file input. Includes label and has predefined sizes and structure for using in foris forms.  | ||||
|  | ||||
| All additional `props` are passed to the `<input type="file">` HTML component. | ||||
|  | ||||
| ```js | ||||
| import {useState} from 'react'; | ||||
| const [files, setFiles] = useState([]); | ||||
|  | ||||
| <FileInput | ||||
|     files={files} | ||||
|     label="Some file" | ||||
|     helpText="Will be uploaded" | ||||
|     onChange={event =>setFiles(event.target.files)} | ||||
| /> | ||||
| ``` | ||||
| @@ -6,7 +6,7 @@ | ||||
|  */ | ||||
|  | ||||
| import React from "react"; | ||||
| import { useUID } from "react-uid/dist/es5/index"; | ||||
| import { useUID } from "react-uid"; | ||||
| import PropTypes from "prop-types"; | ||||
|  | ||||
| import { formFieldsSize } from "./constants"; | ||||
| @@ -21,31 +21,31 @@ Input.propTypes = { | ||||
|         PropTypes.arrayOf(PropTypes.node), | ||||
|         PropTypes.node, | ||||
|     ]), | ||||
|     labelClassName: PropTypes.string, | ||||
|     groupClassName: PropTypes.string, | ||||
| }; | ||||
|  | ||||
| /** Base bootstrap input component. */ | ||||
| export function Input({ | ||||
|     type, label, helpText, error, className, children, ...props | ||||
|     type, label, helpText, error, className, children, labelClassName, groupClassName, ...props | ||||
| }) { | ||||
|     const uid = useUID(); | ||||
|     const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim(); | ||||
|     return ( | ||||
|         <div className={formFieldsSize}> | ||||
|             <div className="form-group"> | ||||
|                 <label htmlFor={uid}>{label}</label> | ||||
|                 <div className="input-group"> | ||||
|                     <input | ||||
|                         className={inputClassName} | ||||
|                         type={type} | ||||
|                         id={uid} | ||||
|         <div className={`form-group ${formFieldsSize}`}> | ||||
|             <label className={labelClassName} htmlFor={uid}>{label}</label> | ||||
|             <div className={`input-group ${groupClassName || ""}`.trim()}> | ||||
|                 <input | ||||
|                     className={inputClassName} | ||||
|                     type={type} | ||||
|                     id={uid} | ||||
|  | ||||
|                         {...props} | ||||
|                     /> | ||||
|                     {children} | ||||
|                 </div> | ||||
|                 {error ? <div className="invalid-feedback">{error}</div> : null} | ||||
|                 {helpText ? <small className="form-text text-muted">{helpText}</small> : null} | ||||
|                     {...props} | ||||
|                 /> | ||||
|                 {children} | ||||
|             </div> | ||||
|             {error ? <div className="invalid-feedback">{error}</div> : null} | ||||
|             {helpText ? <small className="form-text text-muted">{helpText}</small> : null} | ||||
|         </div> | ||||
|     ); | ||||
| } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  | ||||
| import React from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { useUID } from "react-uid/dist/es5/index"; | ||||
| import { useUID } from "react-uid"; | ||||
|  | ||||
| import { formFieldsSize } from "./constants"; | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  | ||||
| import React from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { useUID } from "react-uid/dist/es5/index"; | ||||
| import { useUID } from "react-uid"; | ||||
|  | ||||
|  | ||||
| Select.propTypes = { | ||||
|   | ||||
| @@ -2,53 +2,49 @@ | ||||
|  | ||||
| exports[`<NumberInput/> Render number input 1`] = ` | ||||
| <div | ||||
|   class="col-sm-12 offset-lg-1 col-lg-10" | ||||
|   class="form-group col-sm-12 offset-lg-1 col-lg-10" | ||||
| > | ||||
|   <div | ||||
|     class="form-group" | ||||
|   <label | ||||
|     for="1" | ||||
|   > | ||||
|     <label | ||||
|       for="1" | ||||
|     > | ||||
|       Test label | ||||
|     </label> | ||||
|     Test label | ||||
|   </label> | ||||
|   <div | ||||
|     class="input-group" | ||||
|   > | ||||
|     <input | ||||
|       class="form-control" | ||||
|       id="1" | ||||
|       type="number" | ||||
|       value="1" | ||||
|     /> | ||||
|     <div | ||||
|       class="input-group" | ||||
|       class="input-group-append" | ||||
|     > | ||||
|       <input | ||||
|         class="form-control" | ||||
|         id="1" | ||||
|         type="number" | ||||
|         value="1" | ||||
|       /> | ||||
|       <div | ||||
|         class="input-group-append" | ||||
|       <button | ||||
|         aria-label="Increase" | ||||
|         class="btn btn-outline-secondary" | ||||
|         type="button" | ||||
|       > | ||||
|         <button | ||||
|           aria-label="Increase" | ||||
|           class="btn btn-outline-secondary" | ||||
|           type="button" | ||||
|         > | ||||
|           <i | ||||
|             class="fas fa-plus" | ||||
|           /> | ||||
|         </button> | ||||
|         <button | ||||
|           aria-label="Decrease" | ||||
|           class="btn btn-outline-secondary" | ||||
|           type="button" | ||||
|         > | ||||
|           <i | ||||
|             class="fas fa-minus" | ||||
|           /> | ||||
|         </button> | ||||
|       </div> | ||||
|         <i | ||||
|           class="fas fa-plus" | ||||
|         /> | ||||
|       </button> | ||||
|       <button | ||||
|         aria-label="Decrease" | ||||
|         class="btn btn-outline-secondary" | ||||
|         type="button" | ||||
|       > | ||||
|         <i | ||||
|           class="fas fa-minus" | ||||
|         /> | ||||
|       </button> | ||||
|     </div> | ||||
|     <small | ||||
|       class="form-text text-muted" | ||||
|     > | ||||
|       Some help text | ||||
|     </small> | ||||
|   </div> | ||||
|   <small | ||||
|     class="form-text text-muted" | ||||
|   > | ||||
|     Some help text | ||||
|   </small> | ||||
| </div> | ||||
| `; | ||||
|   | ||||
| @@ -2,32 +2,28 @@ | ||||
|  | ||||
| exports[`<PasswordInput/> Render password input 1`] = ` | ||||
| <div | ||||
|   class="col-sm-12 offset-lg-1 col-lg-10" | ||||
|   class="form-group col-sm-12 offset-lg-1 col-lg-10" | ||||
| > | ||||
|   <div | ||||
|     class="form-group" | ||||
|   <label | ||||
|     for="1" | ||||
|   > | ||||
|     <label | ||||
|       for="1" | ||||
|     > | ||||
|       Test label | ||||
|     </label> | ||||
|     <div | ||||
|       class="input-group" | ||||
|     > | ||||
|       <input | ||||
|         autocomplete="new-password" | ||||
|         class="form-control" | ||||
|         id="1" | ||||
|         type="password" | ||||
|         value="Some password" | ||||
|       /> | ||||
|     </div> | ||||
|     <small | ||||
|       class="form-text text-muted" | ||||
|     > | ||||
|       Some help text | ||||
|     </small> | ||||
|     Test label | ||||
|   </label> | ||||
|   <div | ||||
|     class="input-group" | ||||
|   > | ||||
|     <input | ||||
|       autocomplete="new-password" | ||||
|       class="form-control" | ||||
|       id="1" | ||||
|       type="password" | ||||
|       value="Some password" | ||||
|     /> | ||||
|   </div> | ||||
|   <small | ||||
|     class="form-text text-muted" | ||||
|   > | ||||
|     Some help text | ||||
|   </small> | ||||
| </div> | ||||
| `; | ||||
|   | ||||
| @@ -2,31 +2,27 @@ | ||||
|  | ||||
| exports[`<TextInput/> Render text input 1`] = ` | ||||
| <div | ||||
|   class="col-sm-12 offset-lg-1 col-lg-10" | ||||
|   class="form-group col-sm-12 offset-lg-1 col-lg-10" | ||||
| > | ||||
|   <div | ||||
|     class="form-group" | ||||
|   <label | ||||
|     for="1" | ||||
|   > | ||||
|     <label | ||||
|       for="1" | ||||
|     > | ||||
|       Test label | ||||
|     </label> | ||||
|     <div | ||||
|       class="input-group" | ||||
|     > | ||||
|       <input | ||||
|         class="form-control" | ||||
|         id="1" | ||||
|         type="text" | ||||
|         value="Some text" | ||||
|       /> | ||||
|     </div> | ||||
|     <small | ||||
|       class="form-text text-muted" | ||||
|     > | ||||
|       Some help text | ||||
|     </small> | ||||
|     Test label | ||||
|   </label> | ||||
|   <div | ||||
|     class="input-group" | ||||
|   > | ||||
|     <input | ||||
|       class="form-control" | ||||
|       id="1" | ||||
|       type="text" | ||||
|       value="Some text" | ||||
|     /> | ||||
|   </div> | ||||
|   <small | ||||
|     class="form-text text-muted" | ||||
|   > | ||||
|     Some help text | ||||
|   </small> | ||||
| </div> | ||||
| `; | ||||
|   | ||||
| @@ -17,7 +17,7 @@ const FORM_ACTIONS = { | ||||
|     resetData: 2, | ||||
| }; | ||||
|  | ||||
| export function useForm(validator, prepData) { | ||||
| export function useForm(validator, dataPreprocessor) { | ||||
|     const [state, dispatch] = useReducer(formReducer, { | ||||
|         data: null, | ||||
|         initialData: null, | ||||
| @@ -28,10 +28,10 @@ export function useForm(validator, prepData) { | ||||
|         dispatch({ | ||||
|             type: FORM_ACTIONS.resetData, | ||||
|             data, | ||||
|             prepData, | ||||
|             dataPreprocessor, | ||||
|             validator, | ||||
|         }); | ||||
|     }, [prepData, validator]); | ||||
|     }, [dataPreprocessor, validator]); | ||||
|  | ||||
|     const onFormChangeHandler = useCallback((updateRule) => (event) => { | ||||
|         dispatch({ | ||||
| @@ -41,6 +41,7 @@ export function useForm(validator, prepData) { | ||||
|             validator, | ||||
|         }); | ||||
|     }, [validator]); | ||||
|  | ||||
|     return [ | ||||
|         state, | ||||
|         onFormChangeHandler, | ||||
| @@ -61,12 +62,15 @@ function formReducer(state, action) { | ||||
|         }; | ||||
|     } | ||||
|     case FORM_ACTIONS.resetData: { | ||||
|         if (!action.data) return { ...state, initialData: state.data }; | ||||
|         const prepData = action.prepData ? action.prepData(action.data) : action.data; | ||||
|         if (!action.data) { | ||||
|             return { ...state, initialData: state.data }; | ||||
|         } | ||||
|  | ||||
|         const data = action.dataPreprocessor ? action.dataPreprocessor(action.data) : action.data; | ||||
|         return { | ||||
|             data: prepData, | ||||
|             initialData: prepData, | ||||
|             errors: action.data ? action.validator(prepData) : undefined, | ||||
|             data, | ||||
|             initialData: data, | ||||
|             errors: action.data ? action.validator(data) : undefined, | ||||
|         }; | ||||
|     } | ||||
|     default: { | ||||
| @@ -82,6 +86,9 @@ function getChangedValue(target) { | ||||
|     } else if (target.type === "number") { | ||||
|         const parsedValue = parseInt(value); | ||||
|         value = Number.isNaN(parsedValue) ? value : parsedValue; | ||||
|     } else if (target.type === "file") { | ||||
|         // Return first file (we don't need multiple yet) | ||||
|         [value] = target.files; | ||||
|     } | ||||
|     return value; | ||||
| } | ||||
|   | ||||
| @@ -15,15 +15,16 @@ export { useAPIPatch } from "api/patch"; | ||||
| export { Alert } from "bootstrap/Alert"; | ||||
| export { Button } from "bootstrap/Button"; | ||||
| export { CheckBox } from "bootstrap/CheckBox"; | ||||
| export { formFieldsSize } from "bootstrap/constants"; | ||||
| export { DataTimeInput } from "bootstrap/DataTimeInput"; | ||||
| export { EmailInput } from "bootstrap/EmailInput"; | ||||
| export { FileInput } from "bootstrap/FileInput"; | ||||
| export { Input } from "bootstrap/Input"; | ||||
| export { NumberInput } from "bootstrap/NumberInput"; | ||||
| export { PasswordInput } from "bootstrap/PasswordInput"; | ||||
| export { RadioSet } from "bootstrap/RadioSet"; | ||||
| export { Select } from "bootstrap/Select"; | ||||
| export { TextInput } from "bootstrap/TextInput"; | ||||
| export { formFieldsSize } from "bootstrap/constants"; | ||||
|  | ||||
| export { | ||||
|     Spinner, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user