From 04f69702af2e3103d13a3310d12d1a75e8e8286f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ola=20W=C3=B3jcikowska?= Date: Wed, 26 May 2021 17:49:21 +0200 Subject: [PATCH 1/4] Initial version of the wizard --- package.json | 1 + src/containers/Wizard.js | 173 +++++++++++++++++++++++++++++++++++++++ src/index.js | 1 + 3 files changed, 175 insertions(+) create mode 100644 src/containers/Wizard.js diff --git a/package.json b/package.json index 2046fd478..8d723bbc3 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "react-dom": "^16.13.1", "react-helmet": "^6.1.0", "react-json-view": "^1.20.0", + "react-markdown": "^6.0.2", "react-redux": "^7.2.0", "react-router-dom": "^5.1.2", "reactstrap": "^8.4.1", diff --git a/src/containers/Wizard.js b/src/containers/Wizard.js new file mode 100644 index 000000000..fdecc97c1 --- /dev/null +++ b/src/containers/Wizard.js @@ -0,0 +1,173 @@ +import React, { useState, useEffect } from "react"; +import ReactMarkdown from 'react-markdown' +import { Row, Col, Card, CardHeader, CardBody, CardFooter, FormGroup, Input, Label, Pagination, PaginationItem, PaginationLink } from "reactstrap"; + +export function Wizard({ + name, wizardPages +}) { + + const [rows, setRows] = useState(); + const [page, setPage] = useState(1); + const [totalCount, setTotalCount] = useState(2); //TODO: calculate + // const [limit, setLimit] = useState(1); // TODO: remove + + useEffect(() => { + setTotalCount(wizardPages.length); + }, []); + + useEffect(() => { + getRows(); + console.warn("pageIdx in useeffect", page) + }, [page]); + + useEffect(() => { + console.warn("totalCount in useeffect", totalCount) + }, [totalCount]); + + const getRows = () => { + var view = [] + if (wizardPages != undefined) { + console.log("wizardPages", wizardPages) + console.log("pageIdx", page) + console.log("wizardPages[pageIdx]", wizardPages[page]) + var pageView = wizardPages[page-1] + if (pageView.rows != undefined) { + pageView.rows.forEach(row => { + if (row.type == "markdown") { + view.push( + + {row.contents} + + ) + } else if (row.type == "input") { + view.push( + + + + + ); + } else { + // TODO: maybe it's not even needed + }; + }); + }; + setRows(view) + }; + }; + + + return ( + + + + + {/* {pages[pageIdx].title} */} + + + + {rows} + + + + {/* Here should be some progress indicator */} + + + + + ); +} + + + + +function ListPagination(props) { + + const slots = Math.min(5, props.max); + + var start = props.page - Math.floor(slots / 2); + var end = props.page + Math.floor(slots / 2); + + if (start < 1) { + start = 1; + end = Math.min(slots, props.max); + } + + else if (end > props.max) { + start = Math.max(props.max - slots + 1, 1); + end = props.max; + } + + let pages = []; + var i; + for (i = start; i <= end; i++) { + pages.push(i); + } + + return ( + + + props.onPageChange(1)} + > + + + + + + props.onPageChange(Math.max(1, props.page - 1))} + > + + + + + {pages.map((i, x) => + + {props.onPageChange(i); + console.error("clicked!!!") + console.error("clicked!!!", props.page) + }} + > + {i} + + + )} + + + = props.max} + onClick={(e) => {props.onPageChange(props.page + 1) + console.error("clicked!!! props.page + 1", props.page) + }} + > + + + + + { props.max != undefined ? + + props.onPageChange(props.max)} + > + + + + : null} + + + ); +} diff --git a/src/index.js b/src/index.js index 1c2201e13..f5f574356 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ export { Humanize } from './containers/Humanize'; export { DataTable } from './containers/DataTable'; export { ButtonWithAuthz } from './modules/auth/ButtonWithAuthz'; export { Spinner } from './containers/Spinner'; +export { Wizard } from './containers/Wizard'; export { default as SplashScreen } from './containers/SplashScreen'; import "./style.scss"; From ee1c1f66a3f888c9af56dc4c6868d6d93de74896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ola=20W=C3=B3jcikowska?= Date: Mon, 31 May 2021 14:32:02 +0200 Subject: [PATCH 2/4] Adjust styling --- src/containers/Wizard.js | 90 +++++++++++++--------------------------- src/style.scss | 4 ++ 2 files changed, 33 insertions(+), 61 deletions(-) diff --git a/src/containers/Wizard.js b/src/containers/Wizard.js index fdecc97c1..68e927069 100644 --- a/src/containers/Wizard.js +++ b/src/containers/Wizard.js @@ -1,6 +1,6 @@ import React, { useState, useEffect } from "react"; import ReactMarkdown from 'react-markdown' -import { Row, Col, Card, CardHeader, CardBody, CardFooter, FormGroup, Input, Label, Pagination, PaginationItem, PaginationLink } from "reactstrap"; +import { Row, Col, Card, CardHeader, CardBody, CardFooter, FormGroup, Input, Label, Pagination, PaginationItem, PaginationLink, Progress } from "reactstrap"; export function Wizard({ name, wizardPages @@ -8,8 +8,9 @@ export function Wizard({ const [rows, setRows] = useState(); const [page, setPage] = useState(1); - const [totalCount, setTotalCount] = useState(2); //TODO: calculate - // const [limit, setLimit] = useState(1); // TODO: remove + const [totalCount, setTotalCount] = useState(0); //TODO: calculate + const [progressStep, setProgressStep] = useState(20); + const [pageTitle, setPageTitle] = useState(""); useEffect(() => { setTotalCount(wizardPages.length); @@ -17,20 +18,13 @@ export function Wizard({ useEffect(() => { getRows(); - console.warn("pageIdx in useeffect", page) + setPageTitle(wizardPages[page - 1].title ? wizardPages[page - 1].title : page - 1); // pagination counts index from 1, not 0 }, [page]); - useEffect(() => { - console.warn("totalCount in useeffect", totalCount) - }, [totalCount]); - const getRows = () => { var view = [] if (wizardPages != undefined) { - console.log("wizardPages", wizardPages) - console.log("pageIdx", page) - console.log("wizardPages[pageIdx]", wizardPages[page]) - var pageView = wizardPages[page-1] + var pageView = wizardPages[page - 1] if (pageView.rows != undefined) { pageView.rows.forEach(row => { if (row.type == "markdown") { @@ -61,27 +55,25 @@ export function Wizard({ return ( - - - - - {/* {pages[pageIdx].title} */} - - - - {rows} - - - - {/* Here should be some progress indicator */} - - - - + + + {pageTitle} + + + + {rows} + + + + {/* Here should be some progress indicator */} + + ); } @@ -113,31 +105,20 @@ function ListPagination(props) { return ( - - props.onPageChange(1)} - > - - - - props.onPageChange(Math.max(1, props.page - 1))} > - {pages.map((i, x) => {props.onPageChange(i); - console.error("clicked!!!") - console.error("clicked!!!", props.page) + onClick={(e) => { + props.onPageChange(i); }} > {i} @@ -149,25 +130,12 @@ function ListPagination(props) { = props.max} - onClick={(e) => {props.onPageChange(props.page + 1) - console.error("clicked!!! props.page + 1", props.page) + onClick={(e) => { + props.onPageChange(props.page + 1) }} > - - - { props.max != undefined ? - - props.onPageChange(props.max)} - > - - - - : null} - ); } diff --git a/src/style.scss b/src/style.scss index 0a2bdbca9..f1a53eb92 100644 --- a/src/style.scss +++ b/src/style.scss @@ -26,3 +26,7 @@ main > .container-fluid, main > .container { .breadcrumb { margin: 0 !important; } + +.height-100 { + height: 100% !important; +} From 705386173a8d8e0118d46cfade00dc71b562a931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ola=20W=C3=B3jcikowska?= Date: Tue, 8 Jun 2021 14:56:08 +0200 Subject: [PATCH 3/4] Displaying input fields --- src/containers/Wizard.js | 53 +++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/src/containers/Wizard.js b/src/containers/Wizard.js index 68e927069..0edc8ecb7 100644 --- a/src/containers/Wizard.js +++ b/src/containers/Wizard.js @@ -1,6 +1,8 @@ import React, { useState, useEffect } from "react"; +import { useForm } from "react-hook-form"; import ReactMarkdown from 'react-markdown' -import { Row, Col, Card, CardHeader, CardBody, CardFooter, FormGroup, Input, Label, Pagination, PaginationItem, PaginationLink, Progress } from "reactstrap"; +import { Card, CardHeader, CardBody, CardFooter, FormGroup, FormText, Input, Label, Pagination, PaginationItem, PaginationLink } from "reactstrap"; + export function Wizard({ name, wizardPages @@ -11,6 +13,7 @@ export function Wizard({ const [totalCount, setTotalCount] = useState(0); //TODO: calculate const [progressStep, setProgressStep] = useState(20); const [pageTitle, setPageTitle] = useState(""); + const { register, handleSubmit, setValue, getValues, errors, reset } = useForm(); useEffect(() => { setTotalCount(wizardPages.length); @@ -33,19 +36,19 @@ export function Wizard({ {row.contents} ) - } else if (row.type == "input") { - view.push( - - - - - ); - } else { - // TODO: maybe it's not even needed + } else if (row.type == "object") { + var line = row.properties + Object.keys(line).map((key, idx) => { + view.push() + }) }; }); }; @@ -139,3 +142,25 @@ function ListPagination(props) { ); } + + +// TODO: Different types of Item to cover formats such as "number", "boolean", checkbox, radiobox +export function InputStringItem(props) { + return ( + + + + + {props.description} + + + ); +} From 545ea9f5ed80035720c82bc2b5db774eda980f47 Mon Sep 17 00:00:00 2001 From: titkov49 Date: Tue, 22 Jun 2021 14:22:03 +0200 Subject: [PATCH 4/4] make new module for wizard --- src/abc/Module.js | 4 + src/index.js | 1 - src/{containers => modules/wizard}/Wizard.js | 0 src/modules/wizard/WizardContainer.js | 23 ++++ src/modules/wizard/index.js | 23 ++++ src/modules/wizard/mock-data.json | 119 +++++++++++++++++++ 6 files changed, 169 insertions(+), 1 deletion(-) rename src/{containers => modules/wizard}/Wizard.js (100%) create mode 100644 src/modules/wizard/WizardContainer.js create mode 100644 src/modules/wizard/index.js create mode 100644 src/modules/wizard/mock-data.json diff --git a/src/abc/Module.js b/src/abc/Module.js index b0519eaec..06370107d 100644 --- a/src/abc/Module.js +++ b/src/abc/Module.js @@ -1,6 +1,10 @@ export default class Module { constructor(app, name) { this.App = app; + this.Name = name; + this.Config = app?.config; + this.Navigation = app?.Navigation; + this.Router = app?.Router; } initialize() { diff --git a/src/index.js b/src/index.js index f5f574356..1c2201e13 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,6 @@ export { Humanize } from './containers/Humanize'; export { DataTable } from './containers/DataTable'; export { ButtonWithAuthz } from './modules/auth/ButtonWithAuthz'; export { Spinner } from './containers/Spinner'; -export { Wizard } from './containers/Wizard'; export { default as SplashScreen } from './containers/SplashScreen'; import "./style.scss"; diff --git a/src/containers/Wizard.js b/src/modules/wizard/Wizard.js similarity index 100% rename from src/containers/Wizard.js rename to src/modules/wizard/Wizard.js diff --git a/src/modules/wizard/WizardContainer.js b/src/modules/wizard/WizardContainer.js new file mode 100644 index 000000000..9cc81d391 --- /dev/null +++ b/src/modules/wizard/WizardContainer.js @@ -0,0 +1,23 @@ +import React from 'react'; + +import { Wizard } from './Wizard'; +import { Container } from 'reactstrap'; + +import json from './mock-data.json'; + +const WizardContainer = (props) => { + console.log(json) + + return ( + + + + ) +} + +export default WizardContainer; + diff --git a/src/modules/wizard/index.js b/src/modules/wizard/index.js new file mode 100644 index 000000000..6c16ab8ac --- /dev/null +++ b/src/modules/wizard/index.js @@ -0,0 +1,23 @@ +import Module from 'asab-webui/abc/Module'; +import WizardContainer from './WizardContainer'; + +export default class WizardModule extends Module { + constructor (app) { + super(app, "WizardModule"); + + console.log("WizardModule: ", this); + + this.Router.addRoute({ + path: "/wizard/", + exact: true, + name: "Wizard", + component: WizardContainer + }) + + this.Navigation.addItem({ + name: "Wizard", + icon: "cil-gem", + url: "/wizard/" + }) + } +} \ No newline at end of file diff --git a/src/modules/wizard/mock-data.json b/src/modules/wizard/mock-data.json new file mode 100644 index 000000000..806efd026 --- /dev/null +++ b/src/modules/wizard/mock-data.json @@ -0,0 +1,119 @@ +{ + "name": "Wizard Name", + "wizardPages": [ + { + "title": "a 1", + "rows": + [ + { + "type": "markdown", + "contents": "# headline \n ## second line \n normal text \n\n second line of normal text" + }, + { + "$id": "some_id", + "type": "object", + "description": "description", + "examples": [ + { + "servers": "lm1:12181,lm2:22181,lm3:32181", + "path": "/lmio" + } + ], + "required": [ + "servers", + "path" + ], + "properties": { + "servers": { + "$id": "#/properties/asab%3Azookeeper/properties/servers", + "type": "text", + "title": "The servers schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "lm1:12181,lm2:22181,lm3:32181" + ] + }, + "path": { + "$id": "#/properties/asab%3Azookeeper/properties/path", + "type": "text", + "title": "The path schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "/lmio" + ] + } + } + }, + { + "type": "markdown", + "contents": "## headline 2" + } + ] + }, + { + "title": "b 2", + "rows": + [ + { + "type": "markdown", + "contents": "# headline \n ## second line \n normal text \n\n second line of normal text" + }, + { + "type": "markdown", + "contents": "## headline 2" + }, + { + "type": "markdown", + "contents": "### headline 3" + }, + { + "type": "markdown", + "contents": "#### headline 4" + }, + { + "$id": "some_id2", + "type": "object", + "description": "description", + "examples": [ + { + "servers": "lm1:12181,lm2:22181,lm3:32181", + "path": "/lmio" + } + ], + "required": [ + "servers", + "path" + ], + "properties": { + "servers2": { + "$id": "#/properties/asab%3Azookeeper/properties/servers2", + "type": "string", + "title": "The servers schema2", + "description": "An explanation about the purpose of servers2.", + "default": "", + "examples": [ + "lm1:12181,lm2:22181,lm3:32181" + ] + }, + "path2": { + "$id": "#/properties/asab%3Azookeeper/properties/path2", + "type": "string", + "title": "The path schema2", + "description": "An explanation about the purpose of path2.", + "default": "some default value", + "examples": [ + "/lmio" + ] + } + } + }, + { + "type": "markdown", + "contents": "last markdown under input" + } + ] + } + ] +} \ No newline at end of file