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", |   "name": "foris", | ||||||
|   "version": "1.0.0", |   "version": "1.1.0", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "foris", |   "name": "foris", | ||||||
|   "version": "1.0.0", |   "version": "1.1.0", | ||||||
|   "description": "Set of components and utils for Foris and its plugins.", |   "description": "Set of components and utils for Foris and its plugins.", | ||||||
|   "author": "CZ.NIC, z.s.p.o.", |   "author": "CZ.NIC, z.s.p.o.", | ||||||
|   "repository": { |   "repository": { | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import { | |||||||
|     API_ACTIONS, TIMEOUT, HEADERS, APIReducer, getErrorMessage, |     API_ACTIONS, TIMEOUT, HEADERS, APIReducer, getErrorMessage, | ||||||
| } from "./utils"; | } from "./utils"; | ||||||
|  |  | ||||||
| export function useAPIPost(url) { | export function useAPIPost(url, contentType) { | ||||||
|     const [state, dispatch] = useReducer(APIReducer, { |     const [state, dispatch] = useReducer(APIReducer, { | ||||||
|         isSending: false, |         isSending: false, | ||||||
|         isError: false, |         isError: false, | ||||||
| @@ -20,12 +20,17 @@ export function useAPIPost(url) { | |||||||
|         data: null, |         data: null, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     const headers = { ...HEADERS }; | ||||||
|  |     if (contentType) { | ||||||
|  |         headers["Content-Type"] = contentType; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const post = async (data) => { |     const post = async (data) => { | ||||||
|         dispatch({ type: API_ACTIONS.INIT }); |         dispatch({ type: API_ACTIONS.INIT }); | ||||||
|         try { |         try { | ||||||
|             const result = await axios.post(url, data, { |             const result = await axios.post(url, data, { | ||||||
|                 timeout: TIMEOUT, |                 timeout: TIMEOUT, | ||||||
|                 headers: HEADERS, |                 headers, | ||||||
|             }); |             }); | ||||||
|             dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); |             dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  |  | ||||||
| import React from "react"; | import React from "react"; | ||||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||||
| import { useUID } from "react-uid/dist/es5/index"; | import { useUID } from "react-uid"; | ||||||
|  |  | ||||||
| import { formFieldsSize } from "./constants"; | 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 React from "react"; | ||||||
| import { useUID } from "react-uid/dist/es5/index"; | import { useUID } from "react-uid"; | ||||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||||
|  |  | ||||||
| import { formFieldsSize } from "./constants"; | import { formFieldsSize } from "./constants"; | ||||||
| @@ -21,31 +21,31 @@ Input.propTypes = { | |||||||
|         PropTypes.arrayOf(PropTypes.node), |         PropTypes.arrayOf(PropTypes.node), | ||||||
|         PropTypes.node, |         PropTypes.node, | ||||||
|     ]), |     ]), | ||||||
|  |     labelClassName: PropTypes.string, | ||||||
|  |     groupClassName: PropTypes.string, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** Base bootstrap input component. */ | /** Base bootstrap input component. */ | ||||||
| export function Input({ | export function Input({ | ||||||
|     type, label, helpText, error, className, children, ...props |     type, label, helpText, error, className, children, labelClassName, groupClassName, ...props | ||||||
| }) { | }) { | ||||||
|     const uid = useUID(); |     const uid = useUID(); | ||||||
|     const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim(); |     const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim(); | ||||||
|     return ( |     return ( | ||||||
|         <div className={formFieldsSize}> |         <div className={`form-group ${formFieldsSize}`}> | ||||||
|             <div className="form-group"> |             <label className={labelClassName} htmlFor={uid}>{label}</label> | ||||||
|                 <label htmlFor={uid}>{label}</label> |             <div className={`input-group ${groupClassName || ""}`.trim()}> | ||||||
|                 <div className="input-group"> |                 <input | ||||||
|                     <input |                     className={inputClassName} | ||||||
|                         className={inputClassName} |                     type={type} | ||||||
|                         type={type} |                     id={uid} | ||||||
|                         id={uid} |  | ||||||
|  |  | ||||||
|                         {...props} |                     {...props} | ||||||
|                     /> |                 /> | ||||||
|                     {children} |                 {children} | ||||||
|                 </div> |  | ||||||
|                 {error ? <div className="invalid-feedback">{error}</div> : null} |  | ||||||
|                 {helpText ? <small className="form-text text-muted">{helpText}</small> : null} |  | ||||||
|             </div> |             </div> | ||||||
|  |             {error ? <div className="invalid-feedback">{error}</div> : null} | ||||||
|  |             {helpText ? <small className="form-text text-muted">{helpText}</small> : null} | ||||||
|         </div> |         </div> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  |  | ||||||
| import React from "react"; | import React from "react"; | ||||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||||
| import { useUID } from "react-uid/dist/es5/index"; | import { useUID } from "react-uid"; | ||||||
|  |  | ||||||
| import { formFieldsSize } from "./constants"; | import { formFieldsSize } from "./constants"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  |  | ||||||
| import React from "react"; | import React from "react"; | ||||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||||
| import { useUID } from "react-uid/dist/es5/index"; | import { useUID } from "react-uid"; | ||||||
|  |  | ||||||
|  |  | ||||||
| Select.propTypes = { | Select.propTypes = { | ||||||
|   | |||||||
| @@ -2,53 +2,49 @@ | |||||||
|  |  | ||||||
| exports[`<NumberInput/> Render number input 1`] = ` | exports[`<NumberInput/> Render number input 1`] = ` | ||||||
| <div | <div | ||||||
|   class="col-sm-12 offset-lg-1 col-lg-10" |   class="form-group col-sm-12 offset-lg-1 col-lg-10" | ||||||
| > | > | ||||||
|   <div |   <label | ||||||
|     class="form-group" |     for="1" | ||||||
|   > |   > | ||||||
|     <label |     Test label | ||||||
|       for="1" |   </label> | ||||||
|     > |   <div | ||||||
|       Test label |     class="input-group" | ||||||
|     </label> |   > | ||||||
|  |     <input | ||||||
|  |       class="form-control" | ||||||
|  |       id="1" | ||||||
|  |       type="number" | ||||||
|  |       value="1" | ||||||
|  |     /> | ||||||
|     <div |     <div | ||||||
|       class="input-group" |       class="input-group-append" | ||||||
|     > |     > | ||||||
|       <input |       <button | ||||||
|         class="form-control" |         aria-label="Increase" | ||||||
|         id="1" |         class="btn btn-outline-secondary" | ||||||
|         type="number" |         type="button" | ||||||
|         value="1" |  | ||||||
|       /> |  | ||||||
|       <div |  | ||||||
|         class="input-group-append" |  | ||||||
|       > |       > | ||||||
|         <button |         <i | ||||||
|           aria-label="Increase" |           class="fas fa-plus" | ||||||
|           class="btn btn-outline-secondary" |         /> | ||||||
|           type="button" |       </button> | ||||||
|         > |       <button | ||||||
|           <i |         aria-label="Decrease" | ||||||
|             class="fas fa-plus" |         class="btn btn-outline-secondary" | ||||||
|           /> |         type="button" | ||||||
|         </button> |       > | ||||||
|         <button |         <i | ||||||
|           aria-label="Decrease" |           class="fas fa-minus" | ||||||
|           class="btn btn-outline-secondary" |         /> | ||||||
|           type="button" |       </button> | ||||||
|         > |  | ||||||
|           <i |  | ||||||
|             class="fas fa-minus" |  | ||||||
|           /> |  | ||||||
|         </button> |  | ||||||
|       </div> |  | ||||||
|     </div> |     </div> | ||||||
|     <small |  | ||||||
|       class="form-text text-muted" |  | ||||||
|     > |  | ||||||
|       Some help text |  | ||||||
|     </small> |  | ||||||
|   </div> |   </div> | ||||||
|  |   <small | ||||||
|  |     class="form-text text-muted" | ||||||
|  |   > | ||||||
|  |     Some help text | ||||||
|  |   </small> | ||||||
| </div> | </div> | ||||||
| `; | `; | ||||||
|   | |||||||
| @@ -2,32 +2,28 @@ | |||||||
|  |  | ||||||
| exports[`<PasswordInput/> Render password input 1`] = ` | exports[`<PasswordInput/> Render password input 1`] = ` | ||||||
| <div | <div | ||||||
|   class="col-sm-12 offset-lg-1 col-lg-10" |   class="form-group col-sm-12 offset-lg-1 col-lg-10" | ||||||
| > | > | ||||||
|   <div |   <label | ||||||
|     class="form-group" |     for="1" | ||||||
|   > |   > | ||||||
|     <label |     Test label | ||||||
|       for="1" |   </label> | ||||||
|     > |   <div | ||||||
|       Test label |     class="input-group" | ||||||
|     </label> |   > | ||||||
|     <div |     <input | ||||||
|       class="input-group" |       autocomplete="new-password" | ||||||
|     > |       class="form-control" | ||||||
|       <input |       id="1" | ||||||
|         autocomplete="new-password" |       type="password" | ||||||
|         class="form-control" |       value="Some password" | ||||||
|         id="1" |     /> | ||||||
|         type="password" |  | ||||||
|         value="Some password" |  | ||||||
|       /> |  | ||||||
|     </div> |  | ||||||
|     <small |  | ||||||
|       class="form-text text-muted" |  | ||||||
|     > |  | ||||||
|       Some help text |  | ||||||
|     </small> |  | ||||||
|   </div> |   </div> | ||||||
|  |   <small | ||||||
|  |     class="form-text text-muted" | ||||||
|  |   > | ||||||
|  |     Some help text | ||||||
|  |   </small> | ||||||
| </div> | </div> | ||||||
| `; | `; | ||||||
|   | |||||||
| @@ -2,31 +2,27 @@ | |||||||
|  |  | ||||||
| exports[`<TextInput/> Render text input 1`] = ` | exports[`<TextInput/> Render text input 1`] = ` | ||||||
| <div | <div | ||||||
|   class="col-sm-12 offset-lg-1 col-lg-10" |   class="form-group col-sm-12 offset-lg-1 col-lg-10" | ||||||
| > | > | ||||||
|   <div |   <label | ||||||
|     class="form-group" |     for="1" | ||||||
|   > |   > | ||||||
|     <label |     Test label | ||||||
|       for="1" |   </label> | ||||||
|     > |   <div | ||||||
|       Test label |     class="input-group" | ||||||
|     </label> |   > | ||||||
|     <div |     <input | ||||||
|       class="input-group" |       class="form-control" | ||||||
|     > |       id="1" | ||||||
|       <input |       type="text" | ||||||
|         class="form-control" |       value="Some text" | ||||||
|         id="1" |     /> | ||||||
|         type="text" |  | ||||||
|         value="Some text" |  | ||||||
|       /> |  | ||||||
|     </div> |  | ||||||
|     <small |  | ||||||
|       class="form-text text-muted" |  | ||||||
|     > |  | ||||||
|       Some help text |  | ||||||
|     </small> |  | ||||||
|   </div> |   </div> | ||||||
|  |   <small | ||||||
|  |     class="form-text text-muted" | ||||||
|  |   > | ||||||
|  |     Some help text | ||||||
|  |   </small> | ||||||
| </div> | </div> | ||||||
| `; | `; | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ const FORM_ACTIONS = { | |||||||
|     resetData: 2, |     resetData: 2, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export function useForm(validator, prepData) { | export function useForm(validator, dataPreprocessor) { | ||||||
|     const [state, dispatch] = useReducer(formReducer, { |     const [state, dispatch] = useReducer(formReducer, { | ||||||
|         data: null, |         data: null, | ||||||
|         initialData: null, |         initialData: null, | ||||||
| @@ -28,10 +28,10 @@ export function useForm(validator, prepData) { | |||||||
|         dispatch({ |         dispatch({ | ||||||
|             type: FORM_ACTIONS.resetData, |             type: FORM_ACTIONS.resetData, | ||||||
|             data, |             data, | ||||||
|             prepData, |             dataPreprocessor, | ||||||
|             validator, |             validator, | ||||||
|         }); |         }); | ||||||
|     }, [prepData, validator]); |     }, [dataPreprocessor, validator]); | ||||||
|  |  | ||||||
|     const onFormChangeHandler = useCallback((updateRule) => (event) => { |     const onFormChangeHandler = useCallback((updateRule) => (event) => { | ||||||
|         dispatch({ |         dispatch({ | ||||||
| @@ -41,6 +41,7 @@ export function useForm(validator, prepData) { | |||||||
|             validator, |             validator, | ||||||
|         }); |         }); | ||||||
|     }, [validator]); |     }, [validator]); | ||||||
|  |  | ||||||
|     return [ |     return [ | ||||||
|         state, |         state, | ||||||
|         onFormChangeHandler, |         onFormChangeHandler, | ||||||
| @@ -61,12 +62,15 @@ function formReducer(state, action) { | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|     case FORM_ACTIONS.resetData: { |     case FORM_ACTIONS.resetData: { | ||||||
|         if (!action.data) return { ...state, initialData: state.data }; |         if (!action.data) { | ||||||
|         const prepData = action.prepData ? action.prepData(action.data) : action.data; |             return { ...state, initialData: state.data }; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const data = action.dataPreprocessor ? action.dataPreprocessor(action.data) : action.data; | ||||||
|         return { |         return { | ||||||
|             data: prepData, |             data, | ||||||
|             initialData: prepData, |             initialData: data, | ||||||
|             errors: action.data ? action.validator(prepData) : undefined, |             errors: action.data ? action.validator(data) : undefined, | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|     default: { |     default: { | ||||||
| @@ -82,6 +86,9 @@ function getChangedValue(target) { | |||||||
|     } else if (target.type === "number") { |     } else if (target.type === "number") { | ||||||
|         const parsedValue = parseInt(value); |         const parsedValue = parseInt(value); | ||||||
|         value = Number.isNaN(parsedValue) ? value : parsedValue; |         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; |     return value; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,15 +15,16 @@ export { useAPIPatch } from "api/patch"; | |||||||
| export { Alert } from "bootstrap/Alert"; | export { Alert } from "bootstrap/Alert"; | ||||||
| export { Button } from "bootstrap/Button"; | export { Button } from "bootstrap/Button"; | ||||||
| export { CheckBox } from "bootstrap/CheckBox"; | export { CheckBox } from "bootstrap/CheckBox"; | ||||||
| export { formFieldsSize } from "bootstrap/constants"; |  | ||||||
| export { DataTimeInput } from "bootstrap/DataTimeInput"; | export { DataTimeInput } from "bootstrap/DataTimeInput"; | ||||||
| export { EmailInput } from "bootstrap/EmailInput"; | export { EmailInput } from "bootstrap/EmailInput"; | ||||||
|  | export { FileInput } from "bootstrap/FileInput"; | ||||||
| export { Input } from "bootstrap/Input"; | export { Input } from "bootstrap/Input"; | ||||||
| export { NumberInput } from "bootstrap/NumberInput"; | export { NumberInput } from "bootstrap/NumberInput"; | ||||||
| export { PasswordInput } from "bootstrap/PasswordInput"; | export { PasswordInput } from "bootstrap/PasswordInput"; | ||||||
| export { RadioSet } from "bootstrap/RadioSet"; | export { RadioSet } from "bootstrap/RadioSet"; | ||||||
| export { Select } from "bootstrap/Select"; | export { Select } from "bootstrap/Select"; | ||||||
| export { TextInput } from "bootstrap/TextInput"; | export { TextInput } from "bootstrap/TextInput"; | ||||||
|  | export { formFieldsSize } from "bootstrap/constants"; | ||||||
|  |  | ||||||
| export { | export { | ||||||
|     Spinner, |     Spinner, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user