From 5a807a10e627ee69a2a92499033319ef9220a769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=A2=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D1=85=D0=BE=D0=B2?= Date: Tue, 17 Sep 2024 13:47:52 +0400 Subject: [PATCH] feat(state): ability to calculate any table and to see its log Closes: #67 --- .../ru/ewc/checklogic/ServerInstance.java | 4 ++ .../server/ResourceTemplateRender.java | 2 +- .../ru/ewc/checklogic/server/StatePage.java | 63 +++++++++++++++++-- src/main/resources/templates/outcomes.html | 51 +++++++++++++++ src/main/resources/templates/state.html | 13 +++- 5 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 src/main/resources/templates/outcomes.html diff --git a/src/main/java/ru/ewc/checklogic/ServerInstance.java b/src/main/java/ru/ewc/checklogic/ServerInstance.java index ef8438b..6aed460 100644 --- a/src/main/java/ru/ewc/checklogic/ServerInstance.java +++ b/src/main/java/ru/ewc/checklogic/ServerInstance.java @@ -131,6 +131,10 @@ public boolean isAvailable(final String command, final String field) { return "true".equalsIgnoreCase(this.context.decisionFor(command).get(field)); } + public ComputationContext computation() { + return this.context; + } + public void update(final List values) { final InMemoryLocator request = InMemoryLocator.empty(this.server.requestLocatorName()); values.forEach( diff --git a/src/main/java/ru/ewc/checklogic/server/ResourceTemplateRender.java b/src/main/java/ru/ewc/checklogic/server/ResourceTemplateRender.java index 01ed1ad..49b0f5f 100644 --- a/src/main/java/ru/ewc/checklogic/server/ResourceTemplateRender.java +++ b/src/main/java/ru/ewc/checklogic/server/ResourceTemplateRender.java @@ -54,7 +54,7 @@ public String renderInLayout(final String template, final Map va ); } - private String renderTemplateWith(final String template, final Map values) { + public String renderTemplateWith(final String template, final Map values) { this.processors.putIfAbsent( template, ResourceTemplateRender.templateProcessorFor(template) ); diff --git a/src/main/java/ru/ewc/checklogic/server/StatePage.java b/src/main/java/ru/ewc/checklogic/server/StatePage.java index 3cbb978..3c7125b 100644 --- a/src/main/java/ru/ewc/checklogic/server/StatePage.java +++ b/src/main/java/ru/ewc/checklogic/server/StatePage.java @@ -29,11 +29,14 @@ import com.renomad.minum.web.WebFramework; import java.net.URI; import java.nio.file.Path; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import ru.ewc.checklogic.ServerConfiguration; import ru.ewc.checklogic.ServerInstance; import ru.ewc.checklogic.testing.CheckSuite; +import ru.ewc.decisions.api.ComputationContext; +import ru.ewc.decisions.api.OutputTracker; import ru.ewc.decisions.input.CombinedCsvFileReader; /** @@ -70,7 +73,7 @@ public StatePage( @Override public void register(final WebFramework web) { web.registerPath(GET, "state", this::statePage); - web.registerPath(POST, "state", this::createState); + web.registerPath(POST, "state", this::postRouter); web.registerPath(DELETE, "state", this::resetState); } @@ -82,17 +85,60 @@ private Response statePage(final Request request) { "templates/state.html", Map.of( "state", stored.asHtmlList(), - "includes", this.listOfIncludes() + "includes", this.listOfIncludes(), + "tables", this.listOfTables() ) ) ); } - private Response createState(final Request request) { + private Response postRouter(final Request request) { assert request.requestLine().getMethod().equals(RequestLine.Method.POST); final String include = request.body().asString("include"); - this.context.createState(include, this.testSuite()); - return Response.htmlOk("OK", Map.of("HX-Redirect", "/state")); + final String table = request.body().asString("table"); + final ComputationContext computation = this.context.computation(); + final Response result; + if (StatePage.isSpecified(include)) { + this.testSuite().findAndPerform(include, computation); + result = Response.htmlOk("OK", Map.of("HX-Redirect", "/state")); + } else if (StatePage.isSpecified(table)) { + final OutputTracker tracker = computation.startTracking(); + final Map outcomes = computation.decisionFor(table); + result = Response.htmlOk( + this.processors.renderTemplateWith( + "templates/outcomes.html", + Map.of( + "outcomes", StatePage.asTable(outcomes), + "events", StatePage.asCollapsible(tracker.events()) + ) + ) + ); + } else { + result = Response.htmlOk("OK", Map.of("HX-Redirect", "/state")); + } + return result; + } + + private static boolean isSpecified(final String include) { + return !include.isBlank(); + } + + private static String asCollapsible(final List events) { + return events.stream() + .map("
  • %s
  • "::formatted) + .collect(Collectors.joining()); + } + + private static String asTable(final Map outcomes) { + return outcomes.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .map( + entry -> "%s%s".formatted( + entry.getKey(), + entry.getValue() + ) + ) + .collect(Collectors.joining()); } private Response resetState(final Request request) { @@ -119,4 +165,11 @@ private String listOfIncludes() { .map(name -> "".formatted(name, name)) .collect(Collectors.joining()); } + + private String listOfTables() { + return this.context.computation().tableNames().stream() + .sorted() + .map(name -> "".formatted(name, name)) + .collect(Collectors.joining()); + } } diff --git a/src/main/resources/templates/outcomes.html b/src/main/resources/templates/outcomes.html new file mode 100644 index 0000000..095b601 --- /dev/null +++ b/src/main/resources/templates/outcomes.html @@ -0,0 +1,51 @@ + + + + + + + + + {{ outcomes }} + +
    OutcomeValue
    +
    +
    +

    + +

    +
    +
    +
      {{ events }}
    +
    +
    +
    +
    diff --git a/src/main/resources/templates/state.html b/src/main/resources/templates/state.html index 1277ecc..9dedaa3 100644 --- a/src/main/resources/templates/state.html +++ b/src/main/resources/templates/state.html @@ -33,7 +33,7 @@

    State entities

    @@ -46,6 +46,17 @@

    State entities

    +

    Tables

    +
    +
    + + +
    +
    +

    Context