Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/staging' into improve-run-now-st…
Browse files Browse the repository at this point in the history
…ate-handling

# Conflicts:
#	docs/Changelog.md
  • Loading branch information
mgoworko committed Nov 20, 2024
2 parents 9b4bf81 + 14a9a75 commit 879fd84
Show file tree
Hide file tree
Showing 83 changed files with 941 additions and 427 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package pl.touk.nussknacker.engine.api

case class TemplateEvaluationResult(renderedParts: List[TemplateRenderedPart]) {
def renderedTemplate: String = renderedParts.map(_.value).mkString("")
}

sealed trait TemplateRenderedPart {
def value: String
}

object TemplateRenderedPart {
case class RenderedLiteral(value: String) extends TemplateRenderedPart

case class RenderedSubExpression(value: String) extends TemplateRenderedPart
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ object DatabaseQueryEnricher {

final val queryParamName: ParameterName = ParameterName("Query")

final val queryParamDeclaration =
ParameterDeclaration
.mandatory[String](queryParamName)
.withCreator(modify = _.copy(editor = Some(SqlParameterEditor)))
final val queryParam = Parameter[String](queryParamName).copy(editor = Some(SqlParameterEditor))

final val resultStrategyParamName: ParameterName = ParameterName("Result strategy")

Expand Down Expand Up @@ -132,7 +129,7 @@ class DatabaseQueryEnricher(val dbPoolConfig: DBPoolConfig, val dbMetaDataProvid
): ContextTransformationDefinition = { case TransformationStep(Nil, _) =>
NextParameters(parameters =
resultStrategyParamDeclaration.createParameter() ::
queryParamDeclaration.createParameter() ::
queryParam ::
cacheTTLParamDeclaration.createParameter() :: Nil
)
}
Expand All @@ -142,14 +139,15 @@ class DatabaseQueryEnricher(val dbPoolConfig: DBPoolConfig, val dbMetaDataProvid
): ContextTransformationDefinition = {
case TransformationStep(
(`resultStrategyParamName`, DefinedEagerParameter(strategyName: String, _)) ::
(`queryParamName`, DefinedEagerParameter(query: String, _)) ::
(`queryParamName`, DefinedEagerParameter(query: TemplateEvaluationResult, _)) ::
(`cacheTTLParamName`, _) :: Nil,
None
) =>
if (query.isEmpty) {
val renderedQuery = query.renderedTemplate
if (renderedQuery.isEmpty) {
FinalResults(context, errors = CustomNodeError("Query is missing", Some(queryParamName)) :: Nil, state = None)
} else {
parseQuery(context, dependencies, strategyName, query)
parseQuery(context, dependencies, strategyName, renderedQuery)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package pl.touk.nussknacker.sql.service

import pl.touk.nussknacker.engine.api.TemplateRenderedPart.RenderedLiteral
import pl.touk.nussknacker.engine.api.context.ProcessCompilationError.CustomNodeError
import pl.touk.nussknacker.engine.api.context.transformation.{DefinedEagerParameter, OutputVariableNameValue}
import pl.touk.nussknacker.engine.api.context.{OutputVar, ValidationContext}
import pl.touk.nussknacker.engine.api.typed.typing.{Typed, Unknown}
import pl.touk.nussknacker.engine.api.NodeId
import pl.touk.nussknacker.engine.api.{NodeId, TemplateEvaluationResult}
import pl.touk.nussknacker.sql.db.query.{ResultSetStrategy, SingleResultStrategy}
import pl.touk.nussknacker.sql.db.schema.MetaDataProviderFactory
import pl.touk.nussknacker.sql.utils.BaseHsqlQueryEnricherTest
Expand Down Expand Up @@ -32,8 +33,10 @@ class DatabaseQueryEnricherValidationTest extends BaseHsqlQueryEnricherTest {
service.TransformationStep(
List(
DatabaseQueryEnricher.resultStrategyParamName -> eagerValueParameter(SingleResultStrategy.name),
DatabaseQueryEnricher.queryParamName -> eagerValueParameter("select from"),
DatabaseQueryEnricher.cacheTTLParamName -> eagerValueParameter(Duration.ofMinutes(1)),
DatabaseQueryEnricher.queryParamName -> eagerValueParameter(
TemplateEvaluationResult(List(RenderedLiteral("select from")))
),
DatabaseQueryEnricher.cacheTTLParamName -> eagerValueParameter(Duration.ofMinutes(1)),
),
None
)
Expand Down Expand Up @@ -62,8 +65,10 @@ class DatabaseQueryEnricherValidationTest extends BaseHsqlQueryEnricherTest {
service.TransformationStep(
List(
DatabaseQueryEnricher.resultStrategyParamName -> eagerValueParameter(ResultSetStrategy.name),
DatabaseQueryEnricher.queryParamName -> eagerValueParameter("select * from persons"),
DatabaseQueryEnricher.cacheTTLParamName -> eagerValueParameter(Duration.ofMinutes(1)),
DatabaseQueryEnricher.queryParamName -> eagerValueParameter(
TemplateEvaluationResult(List(RenderedLiteral("select * from persons")))
),
DatabaseQueryEnricher.cacheTTLParamName -> eagerValueParameter(Duration.ofMinutes(1)),
),
None
)
Expand Down
4 changes: 1 addition & 3 deletions designer/client/cypress/e2e/description.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ describe("Description", () => {
it("should display markdown", () => {
cy.get(`[title="toggle description view"]`).should("not.exist");

cy.contains(/^properties$/i)
.should("be.enabled")
.dblclick();
cy.contains(/^properties$/i).click();
cy.get("[data-testid=window]").should("be.visible").as("window");

cy.get("[data-testid=window]").contains("Description").next().find(".ace_editor").should("be.visible").click("center")
Expand Down
3 changes: 2 additions & 1 deletion designer/client/src/actions/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ export type ActionTypes =
| "PROCESS_VERSIONS_LOADED"
| "UPDATE_BACKEND_NOTIFICATIONS"
| "MARK_BACKEND_NOTIFICATION_READ"
| "ARCHIVED";
| "ARCHIVED"
| "EDIT_PROPERTIES";
34 changes: 3 additions & 31 deletions designer/client/src/actions/nk/calculateProcessAfterChange.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,16 @@
import NodeUtils from "../../components/graph/NodeUtils";
import { fetchProcessDefinition } from "./processDefinitionData";
import { getProcessDefinitionData } from "../../reducers/selectors/settings";
import { mapProcessWithNewNode, replaceNodeOutputEdges } from "../../components/graph/utils/graphUtils";
import { alignFragmentWithSchema } from "../../components/graph/utils/fragmentSchemaAligner";
import { Edge, NodeType, ScenarioGraph, ProcessDefinitionData, ScenarioGraphWithName } from "../../types";
import { Edge, NodeType, ScenarioGraphWithName } from "../../types";
import { ThunkAction } from "../reduxTypes";
import { Scenario } from "../../components/Process/types";

function alignFragmentsNodeWithSchema(scenarioGraph: ScenarioGraph, processDefinitionData: ProcessDefinitionData): ScenarioGraph {
return {
...scenarioGraph,
nodes: scenarioGraph.nodes.map((node) => {
return node.type === "FragmentInput" ? alignFragmentWithSchema(processDefinitionData, node) : node;
}),
};
}

export function calculateProcessAfterChange(
scenario: Scenario,
before: NodeType,
after: NodeType,
outputEdges: Edge[],
): ThunkAction<Promise<ScenarioGraphWithName>> {
return async (dispatch, getState) => {
if (NodeUtils.nodeIsProperties(after)) {
const processDefinitionData = await dispatch(fetchProcessDefinition(scenario.processingType, scenario.isFragment));
const processWithNewFragmentSchema = alignFragmentsNodeWithSchema(scenario.scenarioGraph, processDefinitionData);
// TODO: We shouldn't keep scenario name in properties.id - it is a top-level scenario property
if (after.id !== before.id) {
dispatch({ type: "PROCESS_RENAME", name: after.id });
}

const { id, ...properties } = after;

return {
processName: after.id,
scenarioGraph: { ...processWithNewFragmentSchema, properties },
};
}

return async (_, getState) => {
let changedProcess = scenario.scenarioGraph;
if (outputEdges) {
const processDefinitionData = getProcessDefinitionData(getState());
Expand All @@ -54,7 +26,7 @@ export function calculateProcessAfterChange(
}

return {
processName: scenario.scenarioGraph.properties.id || scenario.name,
processName: scenario.name,
scenarioGraph: mapProcessWithNewNode(changedProcess, before, after),
};
};
Expand Down
4 changes: 0 additions & 4 deletions designer/client/src/actions/nk/editNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ export type EditNodeAction = {
validationResult: ValidationResult;
scenarioGraphAfterChange: ScenarioGraph;
};
export type RenameProcessAction = {
type: "PROCESS_RENAME";
name: string;
};

export type EditScenarioLabels = {
type: "EDIT_LABELS";
Expand Down
58 changes: 58 additions & 0 deletions designer/client/src/actions/nk/editProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ProcessDefinitionData, PropertiesType, ScenarioGraph, ScenarioGraphWithName, ValidationResult } from "../../types";
import { alignFragmentWithSchema } from "../../components/graph/utils/fragmentSchemaAligner";
import { fetchProcessDefinition } from "./processDefinitionData";
import { Scenario } from "../../components/Process/types";
import HttpService from "../../http/HttpService";
import { ThunkAction } from "../reduxTypes";

type EditPropertiesAction = {
type: "EDIT_PROPERTIES";
validationResult: ValidationResult;
scenarioGraphAfterChange: ScenarioGraph;
};

type RenameProcessAction = {
type: "PROCESS_RENAME";
name: string;
};

export type PropertiesActions = EditPropertiesAction | RenameProcessAction;

// TODO: We synchronize fragment changes with a scenario in case of properties changes. We need to find a better way to hande it
function alignFragmentsNodeWithSchema(scenarioGraph: ScenarioGraph, processDefinitionData: ProcessDefinitionData): ScenarioGraph {
return {
...scenarioGraph,
nodes: scenarioGraph.nodes.map((node) => {
return node.type === "FragmentInput" ? alignFragmentWithSchema(processDefinitionData, node) : node;
}),
};
}

const calculateProperties = (scenario: Scenario, changedProperties: PropertiesType): ThunkAction<Promise<ScenarioGraphWithName>> => {
return async (dispatch) => {
const processDefinitionData = await dispatch(fetchProcessDefinition(scenario.processingType, scenario.isFragment));
const processWithNewFragmentSchema = alignFragmentsNodeWithSchema(scenario.scenarioGraph, processDefinitionData);

if (scenario.name !== changedProperties.name) {
dispatch({ type: "PROCESS_RENAME", name: changedProperties.name });
}

return {
processName: changedProperties.name,
scenarioGraph: { ...processWithNewFragmentSchema, properties: changedProperties },
};
};
};

export function editProperties(scenario: Scenario, changedProperties: PropertiesType): ThunkAction {
return async (dispatch) => {
const { processName, scenarioGraph } = await dispatch(calculateProperties(scenario, changedProperties));
const response = await HttpService.validateProcess(scenario.name, processName, scenarioGraph);

dispatch({
type: "EDIT_PROPERTIES",
validationResult: response.data,
scenarioGraphAfterChange: scenarioGraph,
});
};
}
1 change: 1 addition & 0 deletions designer/client/src/actions/nk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from "./ui/layout";
export * from "./zoom";
export * from "./nodeDetails";
export * from "./loadProcessToolbarsConfiguration";
export * from "./editProperties";
3 changes: 1 addition & 2 deletions designer/client/src/actions/nk/node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Edge, EdgeType, NodeId, NodeType, ProcessDefinitionData, ValidationResult } from "../../types";
import { ThunkAction } from "../reduxTypes";
import { layoutChanged, Position } from "./ui/layout";
import { EditNodeAction, EditScenarioLabels, RenameProcessAction } from "./editNode";
import { EditNodeAction, EditScenarioLabels } from "./editNode";
import { getProcessDefinitionData } from "../../reducers/selectors/settings";
import { batchGroupBy } from "../../reducers/graph/batchGroupBy";
import NodeUtils from "../../components/graph/NodeUtils";
Expand Down Expand Up @@ -154,5 +154,4 @@ export type NodeActions =
| NodesWithEdgesAddedAction
| ValidationResultAction
| EditNodeAction
| RenameProcessAction
| EditScenarioLabels;
6 changes: 1 addition & 5 deletions designer/client/src/actions/nk/nodeDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,7 @@ const validate = debounce(
validationRequestData: ValidationRequest,
callback: (nodeId: NodeId, data?: ValidationData | void) => void,
) => {
const validate = (node: NodeType) =>
NodeUtils.nodeIsProperties(node)
? //NOTE: we don't validationRequestData contains processProperties, but they are refreshed only on modal open
HttpService.validateProperties(processName, { additionalFields: node.additionalFields, name: node.id })
: HttpService.validateNode(processName, { ...validationRequestData, nodeData: node });
const validate = (node: NodeType) => HttpService.validateNode(processName, { ...validationRequestData, nodeData: node });

const nodeId = validationRequestData.nodeData.id;
const nodeWithChangedName = applyIdFromFakeName(validationRequestData.nodeData);
Expand Down
5 changes: 3 additions & 2 deletions designer/client/src/actions/reduxTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AnyAction, Reducer as ReduxReducer } from "redux";
import { ThunkAction as TA, ThunkDispatch as TD } from "redux-thunk";

import { ActionTypes } from "./actionTypes";
import { CountsActions, NodeActions, ScenarioActions, SelectionActions, NodeDetailsActions } from "./nk";
import { CountsActions, NodeActions, ScenarioActions, SelectionActions, NodeDetailsActions, PropertiesActions } from "./nk";
import { UserSettingsActions } from "./nk/userSettings";
import { UiActions } from "./nk/ui/uiActions";
import { SettingsActions } from "./settingsActions";
Expand All @@ -25,7 +25,8 @@ type TypedAction =
| NotificationActions
| DisplayTestResultsDetailsAction
| CountsActions
| ScenarioActions;
| ScenarioActions
| PropertiesActions;

interface UntypedAction extends AnyAction {
type: Exclude<ActionTypes, TypedAction["type"]>;
Expand Down
3 changes: 0 additions & 3 deletions designer/client/src/assets/json/nodeAttributes.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@
"Aggregate": {
"name": "Aggregate"
},
"Properties": {
"name": "Properties"
},
"CustomNode": {
"name": "CustomNode"
},
Expand Down
4 changes: 4 additions & 0 deletions designer/client/src/components/ComponentDragPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export const ComponentDragPreview = forwardRef<HTMLDivElement, { scale: () => nu
willChange: "transform",
});

if (!node) {
return null;
}

return createPortal(
<div ref={forwardedRef} className={wrapperStyles} style={{ transform: `translate(${x}px, ${y}px)` }}>
<div
Expand Down
2 changes: 1 addition & 1 deletion designer/client/src/components/ComponentPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function ComponentPreview({ node, isActive, isOver }: { node: NodeType; i
});

const imageColors = css({
background: theme.palette.custom.getNodeStyles(node)?.fill,
background: theme.palette.custom.getNodeStyles(node.type)?.fill,
color: theme.palette.common.white,
});

Expand Down
2 changes: 1 addition & 1 deletion designer/client/src/components/graph/EspNode/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function makeElement(processDefinitionData: ProcessDefinitionData, theme:
opacity: node.isDisabled ? 0.5 : 1,
},
iconBackground: {
fill: theme.palette.custom.getNodeStyles(node).fill,
fill: theme.palette.custom.getNodeStyles(node.type).fill,
opacity: node.isDisabled ? 0.5 : 1,
},
icon: {
Expand Down
3 changes: 1 addition & 2 deletions designer/client/src/components/graph/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,7 @@ export class Graph extends React.Component<Props> {
addNode(node: NodeType, position: Position): void {
if (this.props.isFragment === true) return;

const canAddNode =
this.props.capabilities.editFrontend && NodeUtils.isNode(node) && NodeUtils.isAvailable(node, this.props.processDefinitionData);
const canAddNode = this.props.capabilities.editFrontend && NodeUtils.isAvailable(node, this.props.processDefinitionData);

if (canAddNode) {
this.props.nodeAdded(node, position);
Expand Down
Loading

0 comments on commit 879fd84

Please sign in to comment.