Skip to content

Commit

Permalink
merge release/0.4 to staging (TouK#1969)
Browse files Browse the repository at this point in the history
* Demo test scripts fix: added change dir to make relative paths works correctly

* CI for PR for release/* (TouK#1954)

* Ui config loading fix: config entries inside defaultUiConfig.conf wasn't able to use in base application conf passed via nussknacker.config.locations

* Configuration guide (TouK#1932)

* Initial configuration/installation guide

* Initial configuration/installation guide

* Update docs/installation_configuration_guide/DesignerConfiguration.md

Co-authored-by: Damian Święcki <dswiecki9@gmail.com>

* Update docs/installation_configuration_guide/DesignerConfiguration.md

Co-authored-by: Damian Święcki <dswiecki9@gmail.com>

* Update docs/installation_configuration_guide/ModelConfiguration.md

Co-authored-by: Damian Święcki <dswiecki9@gmail.com>

* review

* Main configuration guide

Co-authored-by: Damian Święcki <dswiecki9@gmail.com>

* Renaming process to scenario on FE - fixes (TouK#1945)

* Rename process->scenario - fixes

* Error messages

* Custom scenarios

* HttpService

* Fixes

* Review

* Minor fixes in documentation and app run script for Intellij Idea

* Minor fixes in documentation and app run script for Intellij Idea - fixes after review

* fix(visual regresion): notification font size (TouK#1941)

(cherry picked from commit 99d151f)

* fix(visual regresion): notification font size - cypress tests fix

Co-authored-by: Arek Burdach <arek.burdach@gmail.com>
Co-authored-by: Damian Święcki <dswiecki9@gmail.com>
Co-authored-by: JulianWielga <j@touk.pl>
  • Loading branch information
4 people authored and apanczyk committed Jul 30, 2021
1 parent 87d8774 commit 98bce16
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 107 deletions.
3 changes: 2 additions & 1 deletion .run/NussknackerApp.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
<env name="DEVELOPMENT_MODE" value="true" />
<env name="GRAFANA_URL" value="http://localhost:8081/grafana" />
<env name="FLINK_REST_URL" value="http://localhost:3031" />
<env name="FLINK_QUERYABLE_STATE_PROXY" value="localhost:3063" />
<env name="FLINK_QUERYABLE_STATE_PROXY_URL" value="localhost:3063" />
<env name="FLINK_ROCKSDB_CHECKPOINT_DATA_URI" value="file:///opt/flink/data/rocksdb-checkpoints" />
<env name="SCHEMA_REGISTRY_URL" value="http://localhost:3082" />
</envs>
<option name="INCLUDE_PROVIDED_SCOPE" value="true" />
<option name="MAIN_CLASS_NAME" value="pl.touk.nussknacker.ui.NussknackerApp" />
Expand Down
16 changes: 11 additions & 5 deletions ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,26 @@ You can do all steps at once with ```buildServer.sh``` script

## Running from IntelliJ:
1. Find class `pl.touk.nussknacker.ui.NussknackerApp`
2. Edit run [configuration](https://www.jetbrains.com/help/idea/run-debug-configurations.html)
2. Edit run [configuration](https://www.jetbrains.com/help/idea/run-debug-configurations.html) or use existing stored automatically loaded from `./run/NussknackerApp.run.xml`

* Main class: pl.touk.nussknacker.ui.NussknackerApp
* VM options: -Dnussknacker.config.locations=../../../nussknacker-dist/src/universal/conf/dev-application.conf -Dlogback.configurationFile=../logback-dev.xml
* Working directory: should be set to ui/server/work
* Environment variables:
```AUTHENTICATION_USERS_FILE=../../../nussknacker-dist/src/universal/conf/users.conf;MANAGEMENT_MODEL_DIR=../../../engine/flink/management/sample/target/scala-2.12;GENERIC_MODEL_DIR=../../../engine/flink/generic/target/scala-2.12;STANDALONE_MODEL_DIR=../../../engine/standalone/engine/sample/target/scala-2.12```
If you want to connect to infrastructure in docker you need to set on end of line also:
```;FLINK_REST_URL=http://localhost:3031;FLINK_QUERYABLE_STATE_PROXY_URL=localhost:3063;SCHEMA_REGISTRY_URL=http://localhost:3082;KAFKA_ADDRESS=localhost:3032```
```;FLINK_REST_URL=http://localhost:3031;FLINK_QUERYABLE_STATE_PROXY_URL=localhost:3063;FLINK_ROCKSDB_CHECKPOINT_DATA_URI=file:///opt/flink/data/rocksdb-checkpoints;SCHEMA_REGISTRY_URL=http://localhost:3082;KAFKA_ADDRESS=localhost:3032```
* Module classpath: nussknacker-ui (this is ```ui/server``` folder)
* "Included dependencies with "Provided" scope" should be checked, so that Flink DeploymentManager is included in the classpath

## Running backend for frontend development
If you want run backend only for front-end development, please run `./runServer.sh`

If you want to build ui and have access to it from served application, you can execute:
```
sbt buildUi
```
It will produce static assets in `./ui/server/target/scala-XXX/classes/web/static/` that make them accessible via http://localhost:8080/

## Running backend for frontend development from cmd
If you want to run backend only for front-end development, please run `./runServer.sh`

## Running full env (for integration tests)
* Go to docker/demo and run `docker-compose -f docker-compose-env.yml up -d` - runs full env with kafka / flink / etc..
Expand Down
17 changes: 10 additions & 7 deletions ui/client/components/QueriedStateTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ActionsUtils from "../actions/ActionsUtils"
import {DATE_FORMAT} from "../config"
import HttpService from "../http/HttpService"
import {ButtonWithFocus, InputWithFocus, SelectWithFocus} from "./withFocus"
import { withTranslation } from 'react-i18next';

class QueriedStateTable extends React.Component {

Expand All @@ -24,17 +25,19 @@ class QueriedStateTable extends React.Component {
}

render() {
const t = this.props.t

const queryFormRender = () => {
let queryButtonTooltip
if (_.isEmpty(this.selectedQueryName())) {
queryButtonTooltip = "Query name is not selected"
queryButtonTooltip = t("queriedState.notSelected.tooltip.query", "Query name is not selected")
} else if (_.isEmpty(this.selectedProcessId())) {
queryButtonTooltip = "Process id is not selected"
queryButtonTooltip = t("queriedState.notSelected.tooltip.scenario", "Scenario is not selected")
}
return (
<div>
<div className="esp-form-row">
<p>Query name</p>
<p>{t("queriedState.title.queryName", "Query name")}</p>
<SelectWithFocus
value={this.selectedQueryName()}
onChange={(e) => this.setState({queryName: e.target.value, processId: this.processesForQueryName(e.target.value)[0]})}
Expand All @@ -44,22 +47,22 @@ class QueriedStateTable extends React.Component {
</SelectWithFocus>
</div>
<div className="esp-form-row">
<p>Process id</p>
<p>{t("queriedState.title.scenarioName", "Scenario name")}</p>
<SelectWithFocus value={this.selectedProcessId()} onChange={(e) => this.setState({processId: e.target.value})}>
{this.processesForQueryName(this.selectedQueryName()).map((processId, index) => (
<option key={index} value={processId}>{processId}</option>))}
</SelectWithFocus>
</div>
<div className="esp-form-row">
<p>Key (optional)</p>
<p>{t("queriedState.title.key", "Key (optional)")}</p>
<InputWithFocus value={this.state.key} onChange={(e) => this.setState({key: e.target.value})}/>
<ButtonWithFocus
type="button"
className="modalButton"
disabled={_.isEmpty(this.selectedQueryName()) || _.isEmpty(this.selectedProcessId())}
title={queryButtonTooltip}
onClick={this.queryState.bind(this, this.selectedProcessId(), this.selectedQueryName(), this.state.key)}
>Query</ButtonWithFocus>
>{t("queriedState.query.button", "Query")}</ButtonWithFocus>
</div>
</div>
)
Expand Down Expand Up @@ -147,4 +150,4 @@ function mapState(state) {
}
}

export default connect(mapState, ActionsUtils.mapDispatchWithEspActions)(QueriedStateTable)
export default connect(mapState, ActionsUtils.mapDispatchWithEspActions)(withTranslation()(QueriedStateTable))
2 changes: 1 addition & 1 deletion ui/client/components/graph/node-modal/NodeDetailsModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class NodeDetailsModal extends React.Component {
this.setState({...this.state, subprocessContent: response.data.json})
})
} else {
console.warn("Displaying subprocesses is available only in Chromium based browser.")
console.warn("Displaying fragments is available only in Chromium based browser.")
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions ui/client/components/tips/Errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {v4 as uuid4} from "uuid"
import InlinedSvgs from "../../assets/icons/InlinedSvgs"
import HeaderIcon from "./HeaderIcon"
import NodeErrorsLinkSection from "./NodeErrorsLinkSection"
import i18next from "i18next"

export default class Errors extends React.Component {

Expand Down Expand Up @@ -55,8 +56,10 @@ export default class Errors extends React.Component {
nodeErrorsTips = (propertiesErrors, nodeErrors) => {
const {showDetails, currentProcess} = this.props
const nodeIds = Object.keys(nodeErrors)

//TODO: this is dependent on messages from BE. Should be unified to proper resource bundle :/
const looseNodeIds = nodeIds.filter(nodeId => nodeErrors[nodeId].some(error => error.message === "Loose node"))
const invalidEndNodeIds = nodeIds.filter(nodeId => nodeErrors[nodeId].some(error => error.message === "Invalid end of process"))
const invalidEndNodeIds = nodeIds.filter(nodeId => nodeErrors[nodeId].some(error => error.message === "Invalid end of scenario"))
const otherNodeErrorIds = _.difference(nodeIds, _.concat(looseNodeIds, invalidEndNodeIds))
const errorsOnTop = this.errorsOnTopPresent(otherNodeErrorIds, propertiesErrors)

Expand All @@ -65,20 +68,20 @@ export default class Errors extends React.Component {
<div className={"node-error-links"}>
<NodeErrorsLinkSection
nodeIds={_.concat(otherNodeErrorIds, _.isEmpty(propertiesErrors) ? [] : "properties")}
message={"Errors in: "}
message={i18next.t("errors.errorsIn", "Errors in: ")}
showDetails={showDetails}
currentProcess={currentProcess}
/>
<NodeErrorsLinkSection
nodeIds={looseNodeIds}
message={"Loose nodes: "}
message={i18next.t("errors.looseNodes", "Loose nodes: ")}
showDetails={showDetails}
currentProcess={currentProcess}
className={errorsOnTop ? "error-secondary-container" : null}
/>
<NodeErrorsLinkSection
nodeIds={invalidEndNodeIds}
message={"Invalid end of process: "}
message={i18next.t("errors.invalidScenarioEnd", "Invalid end of scenario: ")}
showDetails={showDetails}
currentProcess={currentProcess}
className={errorsOnTop ? "error-secondary-container" : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function defaultToolbarsConfig(isSubprocess: boolean, isArchived: boolean
},
{
id: "process-panel",
title: "process",
title: "scenario",
buttons: processPanelButtons,
},
{
Expand Down
24 changes: 14 additions & 10 deletions ui/client/containers/Archive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {ProcessesTabData} from "./Processes"
import {Filterable, ProcessesList, RowsRenderer} from "./ProcessesList"
import tabStyles from "../components/tabs/processTabs.styl"
import {SearchItem} from "./TableFilters"
import {useTranslation} from "react-i18next";

const ElementsRenderer: RowsRenderer = ({processes}) => processes.map(process => (
<Tr className="row-hover" key={process.name}>
Expand All @@ -31,18 +32,21 @@ const ElementsRenderer: RowsRenderer = ({processes}) => processes.map(process =>

const sortable = ["name", "category", "modifyDate", "createdAt", "createdBy", "subprocess", "actionDate", "actionUser"]
const filterable: Filterable = ["name", "processCategory", "createdBy"]
const columns = [
{key: "name", label: "Scenario name"},
{key: "category", label: "Category"},
{key: "createdBy", label: "Created by"},
{key: "createdAt", label: "Created at"},
{key: "actionDate", label: "Archived at"},
{key: "actionUser", label: "Archived by"},
{key: "subprocess", label: "Fragment"},
{key: "view", label: "View"},
]

function Archive() {
const {t} = useTranslation()
const columns = [
{key: "name", label: t("archiveList.name", "Name")},
{key: "category", label: t("archiveList.category", "Category")},
{key: "createdBy", label: t("archiveList.createdBy", "Created by")},
{key: "createdAt", label: t("archiveList.createdAt", "Created at")},
{key: "actionDate", label: t("archiveList.archivedAt", "Archived at")},
{key: "actionUser", label: t("archiveList.archivedBy", "Archived by")},
{key: "subprocess", label: t("archiveList.subprocess", "Fragment")},
{key: "view", label: t("archiveList.view", "View")},
]


return (
<Page className={tabStyles.tabContentPage}>
<ProcessesList
Expand Down
26 changes: 15 additions & 11 deletions ui/client/containers/Processes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import {Filterable, getProcessState, ProcessesList, RowsRenderer} from "./Proces
import tabStyles from "../components/tabs/processTabs.styl"
import {SearchItem} from "./TableFilters"
import ProcessLastAction from "../components/Process/ProcessLastAction"
import {useTranslation} from "react-i18next"

const ElementsRenderer: RowsRenderer = ({processes, statuses}) => {
const processState = getProcessState(statuses)

return processes.map((process, index) => {
return (
<Tr key={index} className="row-hover">
Expand Down Expand Up @@ -51,19 +53,21 @@ const ElementsRenderer: RowsRenderer = ({processes, statuses}) => {

const sortable = ["name", "category", "modifyDate", "createdAt", "createdBy", "lastAction"]
const filterable: Filterable = ["name", "processCategory", "createdBy"]
const columns = [
{key: "name", label: "Name"},
{key: "category", label: "Category"},
{key: "createdBy", label: "Created by"},
{key: "createdAt", label: "Created at"},
{key: "modifyDate", label: "Last modification"},
{key: "lastAction", label: "Last action"},
{key: "status", label: "Status"},
{key: "edit", label: "Edit"},
{key: "metrics", label: "Metrics"},
]

function Processes() {
const {t} = useTranslation()
const columns = [
{key: "name", label: t("processList.name", "Name")},
{key: "category", label: t("processList.category", "Category")},
{key: "createdBy", label: t("processList.createdBy", "Created by")},
{key: "createdAt", label: t("processList.createdAt", "Created at")},
{key: "modifyDate", label: t("processList.modifyDate", "Last modification")},
{key: "lastAction", label: t("processList.lastAction", "Last action")},
{key: "status", label: t("processList.status", "Status")},
{key: "edit", label: t("processList.edit", "Edit")},
{key: "metrics", label: t("processList.metrics", "Metrics")},
]

return (
<Page className={tabStyles.tabContentPage}>
<ProcessesList
Expand Down
13 changes: 6 additions & 7 deletions ui/client/containers/Signals.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ActionsUtils from "../actions/ActionsUtils"
import QueriedStateTable from "../components/QueriedStateTable"
import {InputWithFocus, SelectWithFocus} from "../components/withFocus"
import HttpService from "../http/HttpService"
import i18next from "i18next"

//this needs some love
export class Signals extends React.Component {
Expand Down Expand Up @@ -34,9 +35,9 @@ export class Signals extends React.Component {
const currentSignal = this.findSignal(this.state.signalType)
let sendSignalButtonTooltip
if (_.isEmpty(this.state.signalType)) {
sendSignalButtonTooltip = "Signal type is not selected"
sendSignalButtonTooltip = i18next.t("signals.notSelected.tooltip.type", "Signal type is not selected")
} else if (_.isEmpty(this.state.processId)) {
sendSignalButtonTooltip = "Process id is not selected"
sendSignalButtonTooltip = i18next.t("signals.notSelected.tooltip.scenario", "Scenario is not selected")
}
//fixme simplify this view as in QueriedStateTable
return (
Expand All @@ -45,7 +46,7 @@ export class Signals extends React.Component {
<div className="node-table">
<div className="node-table-body">
<div className="node-row">
<div className="node-label">Signal type</div>
<div className="node-label">{i18next.t("signals.type", "Signal type")}</div>
<div className="node-value">
<SelectWithFocus
className="node-input"
Expand All @@ -64,7 +65,7 @@ export class Signals extends React.Component {
</div>
</div>
<div className="node-row">
<div className="node-label">Process id</div>
<div className="node-label">{i18next.t("signals.scenario", "Scenario")}</div>
<div className="node-value">
<SelectWithFocus className="node-input" onChange={(e) => this.setState({processId: e.target.value})}>
{(currentSignal.availableProcesses || [])
Expand Down Expand Up @@ -94,9 +95,7 @@ export class Signals extends React.Component {
disabled={_.isEmpty(this.state.signalType) || _.isEmpty(this.state.processId)}
title={sendSignalButtonTooltip}
onClick={this.sendSignal.bind(this, this.state.signalType, this.state.processId, this.state.signalParams)}
>Send
signal
</button>
>{i18next.t("signals.send.button", "Send signal")}</button>
</div>
</div>
<hr/>
Expand Down
18 changes: 10 additions & 8 deletions ui/client/containers/SubProcesses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,18 @@ const ElementsRenderer: RowsRenderer = ({processes}) => processes.map(process =>

const sortable = ["name", "category", "modifyDate", "createdAt", "createdBy"]
const filterable: Filterable = ["name", "processCategory", "createdBy"]
const columns = [
{key: "name", label: "Name"},
{key: "category", label: "Category"},
{key: "createdBy", label: "Created by"},
{key: "createdAt", label: "Created at"},
{key: "modifyDate", label: "Last modification"},
{key: "edit", label: "Edit"},
]


function SubProcesses() {
const {t} = useTranslation()
const columns = [
{key: "name", label: t("fragmentList.name", "Name")},
{key: "category", label: t("fragmentList.category", "Category")},
{key: "createdBy", label: t("fragmentList.createdBy", "Created by")},
{key: "createdAt", label: t("fragmentList.createdAt", "Created at")},
{key: "modifyDate", label: t("fragmentList.modifyDate", "Last modification")},
{key: "edit", label: t("fragmentList.edit", "Edit")},
]
return (
<Page className={tabStyles.tabContentPage}>
<ProcessesList
Expand Down
25 changes: 14 additions & 11 deletions ui/client/containers/admin/CustomProcesses.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable i18next/no-literal-string */
import React from "react"
import {Td, Tr} from "reactable"
import Date from "../../components/common/Date"
Expand All @@ -10,6 +9,7 @@ import {Page} from "../Page"
import {Filterable, getProcessState, ProcessesList, RowsRenderer} from "../ProcessesList"
import {CancelIcon} from "./CancelIcon"
import {DeployIcon} from "./DeployIcon"
import {useTranslation} from "react-i18next"

const ElementsRenderer: RowsRenderer = ({processes, getProcesses, statuses}) => {
const processState = getProcessState(statuses)
Expand All @@ -36,17 +36,20 @@ const ElementsRenderer: RowsRenderer = ({processes, getProcesses, statuses}) =>

const sortable = ["name", "category", "modifyDate", "createdAt"]
const filterable: Filterable = ["name", "processCategory"]
const columns = [
{key: "name", label: "Process name"},
{key: "category", label: "Category"},
{key: "createdAt", label: "Created at"},
{key: "modifyDate", label: "Last modification"},
{key: "status", label: "Status"},
{key: "deploy", label: "Deploy"},
{key: "cancel", label: "Cancel"},
]


export function CustomProcesses(): JSX.Element {
const {t} = useTranslation()

const columns = [
{key: "name", label: t("customScenario.name", "Name")},
{key: "category", label: t("customScenario.category", "Category")},
{key: "createdAt", label: t("customScenario.createdAt", "Created at")},
{key: "modifyDate", label: t("customScenario.modifyDate", "Last modification")},
{key: "status", label: t("customScenario.status", "Status")},
{key: "deploy", label: t("customScenario.deploy", "Deploy")},
{key: "cancel", label: t("customScenario.cancel", "Cancel")},
]

return (
<Page className={tabStyles.tabContentPage}>
Expand All @@ -67,7 +70,7 @@ export function CustomProcesses(): JSX.Element {
}

export const CustomProcessesTabData = {
header: "Custom Processes",
header: "Custom scenarios",
key: "custom-processes",
Component: CustomProcesses,
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 98bce16

Please sign in to comment.