From 615a0b6d7cd9bfcda2f02de65850759787a443d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Delattre?= Date: Tue, 9 Jul 2019 22:06:34 +0200 Subject: [PATCH] Add multiple polochon handling in the frontend --- frontend/js/actions/polochon.js | 35 +++++++++ frontend/js/components/forms/input.js | 22 ++++++ frontend/js/components/forms/modal.js | 49 ++++++++++++ frontend/js/components/polochons/add.js | 31 ++++++++ frontend/js/components/polochons/edit.js | 59 ++++++++++++++ frontend/js/components/polochons/list.js | 56 +++++++++++++ frontend/js/components/polochons/polochon.js | 83 ++++++++++++++++++++ frontend/js/components/polochons/user.js | 14 ++++ frontend/js/components/users/profile.js | 3 + frontend/js/reducers/index.js | 2 + frontend/js/reducers/polochon.js | 28 +++++++ frontend/js/reducers/users.js | 4 + 12 files changed, 386 insertions(+) create mode 100644 frontend/js/actions/polochon.js create mode 100644 frontend/js/components/forms/input.js create mode 100644 frontend/js/components/forms/modal.js create mode 100644 frontend/js/components/polochons/add.js create mode 100644 frontend/js/components/polochons/edit.js create mode 100644 frontend/js/components/polochons/list.js create mode 100644 frontend/js/components/polochons/polochon.js create mode 100644 frontend/js/components/polochons/user.js create mode 100644 frontend/js/reducers/polochon.js diff --git a/frontend/js/actions/polochon.js b/frontend/js/actions/polochon.js new file mode 100644 index 0000000..acac051 --- /dev/null +++ b/frontend/js/actions/polochon.js @@ -0,0 +1,35 @@ +import { configureAxios, request } from "../requests" + +export const getPolochons = () => request( + "PUBLIC_POLOCHON_LIST_FETCH", + configureAxios().get("/polochons"), +) + +export const getManagedPolochons = () => request( + "MANAGED_POLOCHON_LIST_FETCH", + configureAxios().get("/users/polochons"), +) + +export const addPolochon = (params) => request( + "ADD_POLOCHON", + configureAxios().post("/polochons", params), + [ + () => getManagedPolochons(), + ], +) + +export const updatePolochon = ({ id, ...params }) => request( + "UPDATE_POLOCHON", + configureAxios().post(`/polochons/${id}`, params), + [ + () => getManagedPolochons(), + ], +) + +export const deletePolochon = (id) => request( + "UPDATE_POLOCHON", + configureAxios().delete(`/polochons/${id}`), + [ + () => getManagedPolochons(), + ], +) diff --git a/frontend/js/components/forms/input.js b/frontend/js/components/forms/input.js new file mode 100644 index 0000000..8da4c85 --- /dev/null +++ b/frontend/js/components/forms/input.js @@ -0,0 +1,22 @@ +import React from "react" +import PropTypes from "prop-types" + +export const FormInput = ({ label, value, updateValue }) => { + return ( +
+ + updateValue(e.target.value)} + /> +
+ ) +} +FormInput.propTypes = { + label: PropTypes.string, + value: PropTypes.string, + updateValue: PropTypes.func, +}; diff --git a/frontend/js/components/forms/modal.js b/frontend/js/components/forms/modal.js new file mode 100644 index 0000000..26b3475 --- /dev/null +++ b/frontend/js/components/forms/modal.js @@ -0,0 +1,49 @@ +import React from "react" +import PropTypes from "prop-types" + +import { Modal } from "react-bootstrap" + +export const FormModal = ({ + show, + setShow, + title, + icon, + handleSubmit, + children, +}) => { + const submit = function(e) { + if (e) { e.preventDefault(); } + handleSubmit(); + }; + + return ( + setShow(false)}> + + + + {title} + + + +
submit(ev)}> + {children} +
+
+ +
Apply
+
setShow(false)}>Close
+
+
+ ) +} +FormModal.propTypes = { + show: PropTypes.bool, + setShow: PropTypes.func, + icon: PropTypes.string, + title: PropTypes.string, + handleSubmit: PropTypes.func, + children: PropTypes.oneOf( + PropTypes.object, + PropTypes.array, + ), +}; diff --git a/frontend/js/components/polochons/add.js b/frontend/js/components/polochons/add.js new file mode 100644 index 0000000..e8d41d8 --- /dev/null +++ b/frontend/js/components/polochons/add.js @@ -0,0 +1,31 @@ +import React, { useState } from "react" +import PropTypes from "prop-types" +import { connect } from "react-redux" + +import { addPolochon } from "../../actions/polochon" + +import { PolochonEdit } from "./edit" + +export const PolochonAddConnected = ({ addPolochon }) => { + const [modal, setModal] = useState(false); + + return ( + +
setModal(true)}> + + Add new polochon +
+ + +
+ ) +} +PolochonAddConnected.propTypes = { + addPolochon: PropTypes.func, +}; + +export const PolochonAdd = connect(null, {addPolochon})(PolochonAddConnected); diff --git a/frontend/js/components/polochons/edit.js b/frontend/js/components/polochons/edit.js new file mode 100644 index 0000000..d740c7b --- /dev/null +++ b/frontend/js/components/polochons/edit.js @@ -0,0 +1,59 @@ +import React, { useState, useEffect } from "react" +import PropTypes from "prop-types" + +import { FormModal } from "../forms/modal" +import { FormInput } from "../forms/input" + +export const PolochonEdit = ({ + show, + setShow, + id, + initialName, + initialUrl, + initialToken, + update, +}) => { + const [name, setName] = useState(initialName); + const [url, setUrl] = useState(initialUrl); + const [token, setToken] = useState(initialToken); + + useEffect(() => { + setName(initialName); + setUrl(initialUrl); + setToken(initialToken); + }, [id, initialName, initialUrl, initialToken]) + + const handleSubmit = () => { + update({ id, name, url, token }); + setShow(false); + }; + + return ( + + + + + + ) +} +PolochonEdit.propTypes = { + show: PropTypes.bool, + setShow: PropTypes.func, + update: PropTypes.func, + id: PropTypes.string, + initialName: PropTypes.string, + initialUrl: PropTypes.string, + initialToken: PropTypes.string, +}; +PolochonEdit.defaultProps = { + id: "", + initialName: "", + initialUrl: "", + initialToken: "", +}; diff --git a/frontend/js/components/polochons/list.js b/frontend/js/components/polochons/list.js new file mode 100644 index 0000000..22474fe --- /dev/null +++ b/frontend/js/components/polochons/list.js @@ -0,0 +1,56 @@ +import React, { useEffect } from "react" +import PropTypes from "prop-types" +import { connect } from "react-redux" +import { List } from "immutable" + +import { getManagedPolochons } from "../../actions/polochon" + +import { Polochon } from "./polochon" +import { PolochonAdd } from "./add" + +const mapStateToProps = (state) => ({ + managedList: state.polochon.get("managed"), +}); + +const mapDispatchToProps = { + getManagedPolochons, +} + +const PolochonListConnected = ({ + getManagedPolochons, + managedList, +}) => { + + useEffect(() => { + getManagedPolochons(); + }, [getManagedPolochons]) + + return ( +
+
+

My polochons

+
+ + {managedList.map((el, index) => ( + + ))} + + +
+
+ ) +} +PolochonListConnected.propTypes = { + getManagedPolochons: PropTypes.func, + managedList: PropTypes.instanceOf(List), +}; + +export const PolochonList = connect(mapStateToProps, mapDispatchToProps)(PolochonListConnected); diff --git a/frontend/js/components/polochons/polochon.js b/frontend/js/components/polochons/polochon.js new file mode 100644 index 0000000..6e86c00 --- /dev/null +++ b/frontend/js/components/polochons/polochon.js @@ -0,0 +1,83 @@ +import React, { useState } from "react" +import PropTypes from "prop-types" +import { List } from "immutable" +import { connect } from "react-redux" + +import { PolochonUser } from "./user" +import { PolochonEdit } from "./edit" + +import { updatePolochon, deletePolochon } from "../../actions/polochon" + +export const PolochonConnected = ({ + id, + name, + token, + url, + authToken, + users, + updatePolochon, + deletePolochon, +}) => { + const [edit, setEdit] = useState(false); + + return ( + +
+
+ {name !== "" ? name : "-"} + + ({url !== "" ? url : "-"}) + + + setEdit(true)} + /> + deletePolochon(id)} + /> + +
+
+

ID: {id}

+

Egress token: {token}

+

Ingress token: {authToken}

+

+ Users: + {users.map((user, index) => ( + + ))} +

+
+
+ + +
+ ) +} +PolochonConnected.propTypes = { + id: PropTypes.string, + name: PropTypes.string, + token: PropTypes.string, + url: PropTypes.string, + authToken: PropTypes.string, + users: PropTypes.instanceOf(List), + updatePolochon: PropTypes.func, + deletePolochon: PropTypes.func, +}; + +export const Polochon = connect(null, { updatePolochon, deletePolochon })(PolochonConnected); diff --git a/frontend/js/components/polochons/user.js b/frontend/js/components/polochons/user.js new file mode 100644 index 0000000..4ed207b --- /dev/null +++ b/frontend/js/components/polochons/user.js @@ -0,0 +1,14 @@ +import React from "react" +import PropTypes from "prop-types" + +export const PolochonUser = ({ id, name }) => { + return ( + + {name} ({id}) + + ) +} +PolochonUser.propTypes = { + id: PropTypes.string, + name: PropTypes.string, +}; diff --git a/frontend/js/components/users/profile.js b/frontend/js/components/users/profile.js index 8905590..207780c 100644 --- a/frontend/js/components/users/profile.js +++ b/frontend/js/components/users/profile.js @@ -4,6 +4,8 @@ import { connect } from "react-redux" import Loader from "../loader/loader" import { Map } from "immutable" +import { PolochonList } from "../polochons/list" + import { updateUser, getUserInfos, getUserTokens, getUserModules @@ -37,6 +39,7 @@ const UserProfile = (props) => { url={props.url} updateUser={props.updateUser} /> + state.set("loadingPublic", true), + "PUBLIC_POLOCHON_LIST_FETCH_FULFILLED": (state, action) => { + return state.merge({ + loadingPublic: false, + public: List(fromJS(action.payload.response.data)), + }); + }, + "MANAGED_POLOCHON_LIST_FETCH_PENDING": state => state.set("loadingManaged", true), + "MANAGED_POLOCHON_LIST_FETCH_FULFILLED": (state, action) => { + return state.merge({ + loadingManaged: false, + managed: List(fromJS(action.payload.response.data)), + }); + }, +} + +export default (state = defaultState, action) => + handlers[action.type] ? handlers[action.type](state, action) : state; diff --git a/frontend/js/reducers/users.js b/frontend/js/reducers/users.js index 0b7cad6..557f27c 100644 --- a/frontend/js/reducers/users.js +++ b/frontend/js/reducers/users.js @@ -13,6 +13,8 @@ const defaultState = Map({ isLogged: false, polochonToken: "", polochonUrl: "", + polochonName: "", + polochonActivated: false, tokens: List(), modules: Map(), modulesLoading: false, @@ -45,6 +47,8 @@ const handlers = { "GET_USER_FULFILLED": (state, action) => state.merge(Map({ polochonToken: action.payload.response.data.token, polochonUrl: action.payload.response.data.url, + polochonName: action.payload.response.data.name, + polochonActivated: action.payload.response.data.activated, loading: false, })), "GET_USER_TOKENS_PENDING": state => state.set("loading", true),