mirror of
				https://gitlab.nic.cz/turris/reforis/foris-js.git
				synced 2025-11-03 23:00:31 +01:00 
			
		
		
		
	Merge branch 'docs' into 'dev'
Fix docs, extract CSS to Foris JS. See merge request turris/reforis/foris-js!10
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -43,8 +43,8 @@ coverage.xml
 | 
			
		||||
## Translations
 | 
			
		||||
*.mo
 | 
			
		||||
 | 
			
		||||
/js/styleguide/
 | 
			
		||||
.gitignore
 | 
			
		||||
 | 
			
		||||
dist/
 | 
			
		||||
foris-*.tgz
 | 
			
		||||
styleguide/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
.PHONY: all install-js watch-js build-js publish-beta lint-js test-js create-messages update-messages clean
 | 
			
		||||
.PHONY: all install-js watch-js build-js publish-beta lint-js test-js create-messages update-messages docs clean
 | 
			
		||||
 | 
			
		||||
all:
 | 
			
		||||
	@echo "make install-js"
 | 
			
		||||
@@ -17,6 +17,10 @@ all:
 | 
			
		||||
	@echo "    Create locale messages (.pot)."
 | 
			
		||||
	@echo "make update-messages"
 | 
			
		||||
	@echo "    Update locale messages from .pot file."
 | 
			
		||||
	@echo "make docs"
 | 
			
		||||
	@echo "    Build project documentation."
 | 
			
		||||
	@echo "make docs-watch"
 | 
			
		||||
	@echo "    Start styleguidist server."
 | 
			
		||||
	@echo "make clean"
 | 
			
		||||
	@echo "    Remove python artifacts and virtualenv."
 | 
			
		||||
 | 
			
		||||
@@ -42,5 +46,10 @@ create-messages:
 | 
			
		||||
update-messages:
 | 
			
		||||
	pybabel update -i translations/forisjs.pot -d translations
 | 
			
		||||
 | 
			
		||||
docs:
 | 
			
		||||
	npm run-script docs
 | 
			
		||||
docs-watch:
 | 
			
		||||
	npm run-script docs:watch
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf node_modules dist
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								docs/intro.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/intro.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Foris JS library is set of componets and utils for Foris JS application and plugins.
 | 
			
		||||
@@ -24,4 +24,8 @@ module.exports = {
 | 
			
		||||
    globals: {
 | 
			
		||||
        TZ: "utc",
 | 
			
		||||
    },
 | 
			
		||||
    transform: {
 | 
			
		||||
        "^.+\\.js$": "babel-jest",
 | 
			
		||||
        "^.+\\.css$": "jest-transform-css",
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2011
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2011
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										29
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								package.json
									
									
									
									
									
								
							@@ -16,12 +16,13 @@
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "axios": "^0.19.0",
 | 
			
		||||
    "immutability-helper": "^3.0.0",
 | 
			
		||||
    "jest-transform-css": "^2.0.0",
 | 
			
		||||
    "moment": "^2.24.0",
 | 
			
		||||
    "moment-timezone": "^0.5.25",
 | 
			
		||||
    "prop-types": "^15.7.2",
 | 
			
		||||
    "react-datetime": "^2.16.3",
 | 
			
		||||
    "react-router": "^5.0.1",
 | 
			
		||||
    "react-uid": "^2.2.0",
 | 
			
		||||
    "moment": "^2.24.0",
 | 
			
		||||
    "moment-timezone": "^0.5.25"
 | 
			
		||||
    "react-uid": "^2.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "peerDependencies": {
 | 
			
		||||
    "react": "^16.9.0",
 | 
			
		||||
@@ -31,10 +32,11 @@
 | 
			
		||||
    "@babel/cli": "^7.4.4",
 | 
			
		||||
    "@babel/core": "^7.4.5",
 | 
			
		||||
    "@babel/plugin-proposal-class-properties": "^7.4.4",
 | 
			
		||||
    "@babel/plugin-transform-runtime": "^7.4.4",
 | 
			
		||||
    "@babel/plugin-syntax-export-default-from": "^7.2.0",
 | 
			
		||||
    "@babel/plugin-transform-runtime": "^7.4.4",
 | 
			
		||||
    "@babel/preset-env": "^7.4.5",
 | 
			
		||||
    "@babel/preset-react": "^7.0.0",
 | 
			
		||||
    "@fortawesome/fontawesome-free": "^5.11.2",
 | 
			
		||||
    "@testing-library/react": "^8.0.9",
 | 
			
		||||
    "babel-eslint": "^9.0.0",
 | 
			
		||||
    "babel-jest": "^24.8.0",
 | 
			
		||||
@@ -42,31 +44,38 @@
 | 
			
		||||
    "babel-plugin-module-resolver": "^3.2.0",
 | 
			
		||||
    "babel-plugin-react-transform": "^3.0.0",
 | 
			
		||||
    "babel-polyfill": "^6.26.0",
 | 
			
		||||
    "bootstrap": "^4.3.1",
 | 
			
		||||
    "copy-webpack-plugin": "^5.0.4",
 | 
			
		||||
    "css-loader": "^3.2.0",
 | 
			
		||||
    "eslint": "^6.1.0",
 | 
			
		||||
    "eslint-config-airbnb": "^18.0.1",
 | 
			
		||||
    "eslint-plugin-import": "^2.18.2",
 | 
			
		||||
    "eslint-plugin-jsx-a11y": "^6.2.3",
 | 
			
		||||
    "eslint-plugin-react": "^7.14.3",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^1.7.0",
 | 
			
		||||
    "file-loader": "^4.2.0",
 | 
			
		||||
    "jest": "^24.8.0",
 | 
			
		||||
    "jest-mock-axios": "^3.0.0",
 | 
			
		||||
    "moment": "^2.24.0",
 | 
			
		||||
    "moment-timezone": "^0.5.25",
 | 
			
		||||
    "react": "^16.9.0",
 | 
			
		||||
    "react-dom": "^16.9.0",
 | 
			
		||||
    "react-styleguidist": "^9.1.11",
 | 
			
		||||
    "snapshot-diff": "^0.5.1"
 | 
			
		||||
    "react-styleguidist": "^9.1.16",
 | 
			
		||||
    "snapshot-diff": "^0.5.1",
 | 
			
		||||
    "style-loader": "^1.0.0",
 | 
			
		||||
    "webpack": "^4.41.0"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline",
 | 
			
		||||
    "build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline",
 | 
			
		||||
    "build:watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline",
 | 
			
		||||
    "build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline --copy-files",
 | 
			
		||||
    "build:watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline --copy-files",
 | 
			
		||||
    "prepare": "rm -rf ./dist && npm run build",
 | 
			
		||||
    "lint": "eslint src",
 | 
			
		||||
    "test": "jest",
 | 
			
		||||
    "test:watch": "jest --watch",
 | 
			
		||||
    "test:coverage": "jest --coverage --colors",
 | 
			
		||||
    "test:update-snapshots": "jest -u"
 | 
			
		||||
    "test:update-snapshots": "jest -u",
 | 
			
		||||
    "docs": "npx styleguidist build ",
 | 
			
		||||
    "docs:watch": "styleguidist server"
 | 
			
		||||
  },
 | 
			
		||||
  "files": [
 | 
			
		||||
    "dist/**",
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,6 @@ const [value, setValue] = useState(false);
 | 
			
		||||
    value={value}
 | 
			
		||||
    label="Some label" 
 | 
			
		||||
    helpText="Read the small text!"
 | 
			
		||||
    onChange={value => setValue(value)}
 | 
			
		||||
    onChange={event =>setValue(event.target.value)}
 | 
			
		||||
/>
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import React from "react";
 | 
			
		||||
import PropTypes from "prop-types";
 | 
			
		||||
import Datetime from "react-datetime/DateTime";
 | 
			
		||||
import moment from "moment/moment";
 | 
			
		||||
import "react-datetime/css/react-datetime.css";
 | 
			
		||||
 | 
			
		||||
import { Input } from "./Input";
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ const [email, setEmail] = useState('Wrong email');
 | 
			
		||||
        value={email}
 | 
			
		||||
        label="Some label" 
 | 
			
		||||
        helpText="Read the small text!"
 | 
			
		||||
        onChange={target => setEmail(target.value)}
 | 
			
		||||
        onChange={event =>setEmail(event.target.value)}
 | 
			
		||||
    />
 | 
			
		||||
    <button type="submit">Try to submit</button>
 | 
			
		||||
</form>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,13 @@
 | 
			
		||||
Bootstrap modal component.
 | 
			
		||||
 | 
			
		||||
I have no idea why example doesn't work here but you can investigate HTML code...
 | 
			
		||||
it's required to have an element `<div id={"modal-container"}/>` somewhere on the page since modals are rendered in portals.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
    <div id="modal-container"/>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
I have no idea why example doesn't work here but you can investigate HTML code and Foris project.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import {ModalHeader, ModalBody, ModalFooter} from './Modal';
 | 
			
		||||
 | 
			
		||||
@@ -8,7 +15,7 @@ import {useState} from 'react';
 | 
			
		||||
const [shown, setShown] = useState(false);
 | 
			
		||||
 | 
			
		||||
<>
 | 
			
		||||
    <Modal shown={shown}>
 | 
			
		||||
    <Modal setShown={setShown} shown={shown}>
 | 
			
		||||
        <ModalHeader setShown={setShown} title='Warning!'/>
 | 
			
		||||
        <ModalBody><p>Bla bla bla...</p></ModalBody>
 | 
			
		||||
        <ModalFooter>
 | 
			
		||||
@@ -19,9 +26,8 @@ const [shown, setShown] = useState(false);
 | 
			
		||||
        </ModalFooter>
 | 
			
		||||
    </Modal>
 | 
			
		||||
    
 | 
			
		||||
    <button 
 | 
			
		||||
        className='btn btn-secondary'
 | 
			
		||||
        onClick={()=>setShown(true)}
 | 
			
		||||
    >Show modal</button>
 | 
			
		||||
    <button className='btn btn-secondary' onClick={()=>setShown(true)}>
 | 
			
		||||
        Show modal
 | 
			
		||||
    </button>
 | 
			
		||||
</>
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								src/bootstrap/NumberInput.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/bootstrap/NumberInput.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
input[type="number"] {
 | 
			
		||||
    -webkit-appearance: textfield;
 | 
			
		||||
    -moz-appearance: textfield;
 | 
			
		||||
    appearance: textfield;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
input[type=number]::-webkit-inner-spin-button,
 | 
			
		||||
input[type=number]::-webkit-outer-spin-button {
 | 
			
		||||
    -webkit-appearance: none;
 | 
			
		||||
}
 | 
			
		||||
@@ -9,6 +9,7 @@ import React from "react";
 | 
			
		||||
 | 
			
		||||
import PropTypes from "prop-types";
 | 
			
		||||
import { Input } from "./Input";
 | 
			
		||||
import "./NumberInput.css";
 | 
			
		||||
 | 
			
		||||
NumberInput.propTypes = {
 | 
			
		||||
    /** Field label. */
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,6 @@ const [value, setValue] = useState(42);
 | 
			
		||||
    helpText="Read the small text!"
 | 
			
		||||
    min='33'
 | 
			
		||||
    max='54'
 | 
			
		||||
    onChange={target => setValue(target.value)}
 | 
			
		||||
    onChange={event =>setValue(event.target.value)}
 | 
			
		||||
/>
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,6 @@ const [value, setValue] = useState('secret');
 | 
			
		||||
    value={value}
 | 
			
		||||
    label="Some password" 
 | 
			
		||||
    helpText="Read the small text!"
 | 
			
		||||
    onChange={target => setValue(target.value)}
 | 
			
		||||
    onChange={event =>setValue(event.target.value)}
 | 
			
		||||
/>
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ const [value, setValue] = useState(CHOICES[0].value);
 | 
			
		||||
        value={value}
 | 
			
		||||
        name='some-radio'
 | 
			
		||||
        choices={CHOICES}
 | 
			
		||||
        onChange={event=>setValue(event.target.value)}
 | 
			
		||||
        onChange={event =>setValue(event.target.value)}
 | 
			
		||||
    />
 | 
			
		||||
    <p>Selected value: {value}</p>
 | 
			
		||||
</>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,6 @@ const [value, setValue] = useState('Bla bla');
 | 
			
		||||
    value={value}
 | 
			
		||||
    label="Some text" 
 | 
			
		||||
    helpText="Read the small text!"
 | 
			
		||||
    onChange={event => setValue(event.target.value)}
 | 
			
		||||
    onChange={event =>setValue(event.target.value)}
 | 
			
		||||
/>
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,10 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export const REFORIS_URL_PREFIX = process.env.LIGHTTPD ? "/reforis" : "";
 | 
			
		||||
 | 
			
		||||
export const ForisURLs = {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								src/form/components/ForisForm.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/form/components/ForisForm.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
`<ForisForm/>` is Higher-Order Component which encapsulates entire form logic and provides with children required props.
 | 
			
		||||
This component structure provides comfort API and allows to create typical Foris module forms easily.
 | 
			
		||||
 | 
			
		||||
## Example of usage of `<ForisForm/>`
 | 
			
		||||
You can pass more forms as children.
 | 
			
		||||
```js
 | 
			
		||||
<ForisForm
 | 
			
		||||
    ws={ws}
 | 
			
		||||
    forisConfig={{
 | 
			
		||||
        endpoint: API_URLs.wan,
 | 
			
		||||
        wsModule: "wan",
 | 
			
		||||
    }}
 | 
			
		||||
    prepData={prepData}
 | 
			
		||||
    prepDataToSubmit={prepDataToSubmit}
 | 
			
		||||
    validator={validator}
 | 
			
		||||
>
 | 
			
		||||
    <WANForm />
 | 
			
		||||
    <WAN6Form />
 | 
			
		||||
    <MACForm />
 | 
			
		||||
</ForisForm>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Example of children forms `props` usage
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
export default function MACForm({
 | 
			
		||||
    formData, formErrors, setFormValue, ...props
 | 
			
		||||
}) {
 | 
			
		||||
    const macSettings = formData.mac_settings;
 | 
			
		||||
    const errors = (formErrors || {}).mac_settings || {};
 | 
			
		||||
    return (
 | 
			
		||||
        <>
 | 
			
		||||
            <h3>{_("MAC")}</h3>
 | 
			
		||||
            <CheckBox
 | 
			
		||||
                label={_("Custom MAC address")}
 | 
			
		||||
                checked={macSettings.custom_mac_enabled}
 | 
			
		||||
                helpText={HELP_TEXTS.custom_mac_enabled}
 | 
			
		||||
 | 
			
		||||
                onChange={setFormValue(
 | 
			
		||||
                    (value) => ({ mac_settings: { custom_mac_enabled: { $set: value } } }),
 | 
			
		||||
                )}
 | 
			
		||||
 | 
			
		||||
                {...props}
 | 
			
		||||
            />
 | 
			
		||||
            {macSettings.custom_mac_enabled
 | 
			
		||||
                ? (
 | 
			
		||||
                    <TextInput
 | 
			
		||||
                        label={_("MAC address")}
 | 
			
		||||
                        value={macSettings.custom_mac || ""}
 | 
			
		||||
                        helpText={HELP_TEXTS.custom_mac}
 | 
			
		||||
                        error={errors.custom_mac}
 | 
			
		||||
                        required
 | 
			
		||||
 | 
			
		||||
                        onChange={setFormValue(
 | 
			
		||||
                            (value) => ({ mac_settings: { custom_mac: { $set: value } } }),
 | 
			
		||||
                        )}
 | 
			
		||||
 | 
			
		||||
                        {...props}
 | 
			
		||||
                    />
 | 
			
		||||
                )
 | 
			
		||||
                : null}
 | 
			
		||||
        </>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
The <ForisForm/> passes subsequent `props` to the child components.
 | 
			
		||||
 | 
			
		||||
| Prop           | Type   | Description                                                                |
 | 
			
		||||
|----------------|--------|----------------------------------------------------------------------------|
 | 
			
		||||
| `formData`     | object | Data returned from API.                                                    |
 | 
			
		||||
| `formErrors`   | object | Errors returned after validation via validator.                            |
 | 
			
		||||
| `setFormValue` | func   | Function for data update. It takes update rule as arg (see example above). |
 | 
			
		||||
| `disabled`     | bool   | Flag to disable form elements (during updates or loadings e.t.c.).         |
 | 
			
		||||
@@ -1,3 +1,10 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// API
 | 
			
		||||
export { useAPIGet } from "api/get";
 | 
			
		||||
export { useAPIPost } from "api/post";
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,10 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** Return undefined if object has no keys, otherwise return object. */
 | 
			
		||||
export function undefinedIfEmpty(instance) {
 | 
			
		||||
    if (Object.keys(instance).length > 0) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								styleguide.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								styleguide.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const path = require("path");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    title: "Foris JS docs",
 | 
			
		||||
    sections: [
 | 
			
		||||
        {
 | 
			
		||||
            name: "Foris JS",
 | 
			
		||||
            content: "docs/intro.md",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Foris forms",
 | 
			
		||||
            components: [
 | 
			
		||||
                "src/form/components/ForisForm.js",
 | 
			
		||||
                "src/form/components/alerts.js",
 | 
			
		||||
                "src/form/components/SubmitButton.js",
 | 
			
		||||
            ],
 | 
			
		||||
            exampleMode: "expand",
 | 
			
		||||
            usageMode: "expand",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Bootstrap components",
 | 
			
		||||
            description: "Set of bootstrap components.",
 | 
			
		||||
            components: "src/bootstrap/*.js",
 | 
			
		||||
            exampleMode: "expand",
 | 
			
		||||
            usageMode: "expand",
 | 
			
		||||
            ignore: [
 | 
			
		||||
                "src/bootstrap/constants.js",
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    require: [
 | 
			
		||||
        "babel-polyfill",
 | 
			
		||||
        path.join(__dirname, "node_modules/bootstrap/dist/css/bootstrap.min.css"),
 | 
			
		||||
        path.join(__dirname, "node_modules/@fortawesome/fontawesome-free/css/all.min.css"),
 | 
			
		||||
    ],
 | 
			
		||||
    webpackConfig: {
 | 
			
		||||
        module: {
 | 
			
		||||
            rules: [
 | 
			
		||||
                {
 | 
			
		||||
                    test: /\.js$/,
 | 
			
		||||
                    exclude: /node_modules/,
 | 
			
		||||
                    loader: "babel-loader",
 | 
			
		||||
                }, {
 | 
			
		||||
                    test: /\.css$/,
 | 
			
		||||
                    use: ["style-loader", "css-loader"],
 | 
			
		||||
                }, {
 | 
			
		||||
                    test: /\.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/,
 | 
			
		||||
                    loader: "file-loader",
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user