diff --git a/editor/.gitignore b/editor/.gitignore
index ac0ef07..128059b 100644
--- a/editor/.gitignore
+++ b/editor/.gitignore
@@ -1,38 +1,3 @@
node_modules
-HELP.md
-.gradle
-build/
-!gradle/wrapper/gradle-wrapper.jar
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-bin/
-!**/src/main/**/bin/
-!**/src/test/**/bin/
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-out/
-!**/src/main/**/out/
-!**/src/test/**/out/
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-
-### VS Code ###
-.vscode/
+**/frontend/generated/
+.vaadin-node-tasks.lock
\ No newline at end of file
diff --git a/editor/build.gradle b/editor/build.gradle
index 71fee9a..f0a5d38 100644
--- a/editor/build.gradle
+++ b/editor/build.gradle
@@ -16,8 +16,11 @@ ext {
}
dependencies {
- implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework:spring-aspects'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+
+ runtimeOnly 'org.postgresql:postgresql'
implementation 'com.vaadin:vaadin-spring-boot-starter'
diff --git a/editor/database/00-init.sql b/editor/database/00-init.sql
new file mode 100644
index 0000000..e951f35
--- /dev/null
+++ b/editor/database/00-init.sql
@@ -0,0 +1,23 @@
+-- Table definitions
+
+create domain dialogue_package_id as
+ varchar(32) not null;
+
+create domain dialogue_id as
+ varchar(64) not null;
+
+
+create table dialogue_packages (
+ id dialogue_package_id primary key,
+ comment text not null
+);
+
+create table dialogues (
+ id dialogue_id primary key,
+ package dialogue_package_id,
+ comment text not null,
+ ctx json not null,
+
+ foreign key (package) references dialogue_packages (id)
+);
+
diff --git a/editor/database/01-init-insert.sql b/editor/database/01-init-insert.sql
new file mode 100644
index 0000000..d25450b
--- /dev/null
+++ b/editor/database/01-init-insert.sql
@@ -0,0 +1 @@
+-- Default inserts
diff --git a/editor/database/Dockerfile b/editor/database/Dockerfile
new file mode 100644
index 0000000..eb1ffa3
--- /dev/null
+++ b/editor/database/Dockerfile
@@ -0,0 +1,2 @@
+FROM postgres:latest
+COPY *.sql /docker-entrypoint-initdb.d/
\ No newline at end of file
diff --git a/editor/docker-compose.yml b/editor/docker-compose.yml
new file mode 100644
index 0000000..4a61c0f
--- /dev/null
+++ b/editor/docker-compose.yml
@@ -0,0 +1,13 @@
+version: "3"
+
+services:
+ postgres:
+ image: msb3_postgresql
+ build:
+ context: ./database
+ restart: always
+ environment:
+ POSTGRES_DB: 'postgres'
+ POSTGRES_USER: 'postgres'
+ POSTGRES_PASSWORD: 'some_password'
+ ports: [ '5432:5432' ]
diff --git a/editor/src/main/frontend/index.html b/editor/src/main/frontend/index.html
new file mode 100644
index 0000000..d031d69
--- /dev/null
+++ b/editor/src/main/frontend/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ MSB3 Control Panel
+
+
+
+
+
+
diff --git a/editor/src/main/java/ru/dragonestia/editor/component/DialogEditor.java b/editor/src/main/java/ru/dragonestia/editor/component/DialogEditor.java
new file mode 100644
index 0000000..e52b223
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/component/DialogEditor.java
@@ -0,0 +1,49 @@
+package ru.dragonestia.editor.component;
+
+import com.vaadin.flow.component.Unit;
+import com.vaadin.flow.component.details.Details;
+import com.vaadin.flow.component.html.H2;
+import com.vaadin.flow.component.html.Hr;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextArea;
+import ru.dragonestia.editor.model.DialogueContext;
+
+public class DialogEditor extends VerticalLayout {
+
+ private final DialogueContext ctx;
+
+ public DialogEditor(DialogueContext ctx) {
+ this.ctx = ctx;
+
+ add(new H2("Редактор диалога"));
+
+ var commentDetail = new Details("Комментарий");
+ commentDetail.setWidth("100%");
+ commentDetail.add(createFieldComment());
+ commentDetail.setOpened(!(ctx.getComment() == null || ctx.getComment().isEmpty()));
+ add(commentDetail);
+
+ add(new Hr());
+
+ add(createFieldText());
+ }
+
+ private TextArea createFieldComment() {
+ var field = new TextArea("Комментарий");
+ field.setWidth(100, Unit.PERCENTAGE);
+ field.setMinHeight(10, Unit.REM);
+ field.setHelperText("Здесь можно описать какой-нибудь комментарий по поводу диалога. Эта информация имеет роль заметки для разработчиков");
+ field.setPlaceholder("Какая-то заметка для разработчика");
+ if (ctx.getComment() != null) field.setValue(ctx.getComment());
+ return field;
+ }
+
+ private TextArea createFieldText() {
+ var field = new TextArea("Текст диалога");
+ field.setRequired(true);
+ field.setWidth(100, Unit.PERCENTAGE);
+ field.setMinHeight(10, Unit.REM);
+ if (ctx.getText() != null) field.setValue(ctx.getText());
+ return field;
+ }
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/model/Dialogue.java b/editor/src/main/java/ru/dragonestia/editor/model/Dialogue.java
new file mode 100644
index 0000000..5ade51b
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/model/Dialogue.java
@@ -0,0 +1,32 @@
+package ru.dragonestia.editor.model;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import ru.dragonestia.editor.model.converter.DialogueContextConverter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "dialogues")
+public class Dialogue {
+
+ @Id
+ @Column(name = "id", columnDefinition = "dialogue_id")
+ private String id;
+
+ @JoinColumn(name = "package")
+ @ManyToOne(fetch = FetchType.EAGER)
+ private DialoguePackage dialoguePackage;
+
+ @Column(name = "comment")
+ private String comment;
+
+ @Convert(converter = DialogueContextConverter.class)
+ @Column(name = "ctx", columnDefinition = "json")
+ private DialogueContext ctx;
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/model/DialogueContext.java b/editor/src/main/java/ru/dragonestia/editor/model/DialogueContext.java
new file mode 100644
index 0000000..63ea105
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/model/DialogueContext.java
@@ -0,0 +1,13 @@
+package ru.dragonestia.editor.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class DialogueContext {
+
+ private String id;
+ private String text;
+ private String comment;
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/model/DialoguePackage.java b/editor/src/main/java/ru/dragonestia/editor/model/DialoguePackage.java
new file mode 100644
index 0000000..8c18b4e
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/model/DialoguePackage.java
@@ -0,0 +1,26 @@
+package ru.dragonestia.editor.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "dialogue_packages")
+public class DialoguePackage {
+
+ @Id
+ @Column(name = "id", columnDefinition = "dialogue_package_id")
+ private String id;
+
+ @Column(name = "comment")
+ private String comment;
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/model/converter/DialogueContextConverter.java b/editor/src/main/java/ru/dragonestia/editor/model/converter/DialogueContextConverter.java
new file mode 100644
index 0000000..cfe1710
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/model/converter/DialogueContextConverter.java
@@ -0,0 +1,20 @@
+package ru.dragonestia.editor.model.converter;
+
+import jakarta.persistence.AttributeConverter;
+import jakarta.persistence.Converter;
+import ru.dragonestia.editor.model.DialogueContext;
+import ru.dragonestia.editor.util.JsonUtils;
+
+@Converter
+public class DialogueContextConverter implements AttributeConverter {
+
+ @Override
+ public String convertToDatabaseColumn(DialogueContext ctx) {
+ return JsonUtils.toJson(ctx);
+ }
+
+ @Override
+ public DialogueContext convertToEntityAttribute(String json) {
+ return JsonUtils.fromJson(json);
+ }
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/page/Page.java b/editor/src/main/java/ru/dragonestia/editor/page/Page.java
new file mode 100644
index 0000000..77d612c
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/page/Page.java
@@ -0,0 +1,81 @@
+package ru.dragonestia.editor.page;
+
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.BeforeEnterEvent;
+import com.vaadin.flow.router.BeforeEnterObserver;
+import com.vaadin.flow.router.BeforeLeaveEvent;
+import com.vaadin.flow.router.BeforeLeaveObserver;
+
+import java.util.Optional;
+
+public class Page extends VerticalLayout implements BeforeEnterObserver, BeforeLeaveObserver {
+
+ protected void init(QueryParams params) {}
+
+ protected void destroy() {}
+
+ @Override
+ public final void beforeEnter(BeforeEnterEvent event) {
+ init(key -> event.getRouteParameters().get(key));
+ }
+
+ @Override
+ public final void beforeLeave(BeforeLeaveEvent event) {
+ destroy();
+ }
+
+ public interface QueryParams {
+
+ Optional String(String key);
+
+ default Optional Integer(String key) {
+ return String(key).map(str -> {
+ try {
+ return Integer.parseInt(str);
+ } catch (Exception ex) {
+ return null;
+ }
+ });
+ }
+
+ default Optional Long(String key) {
+ return String(key).map(str -> {
+ try {
+ return Long.parseLong(str);
+ } catch (Exception ex) {
+ return null;
+ }
+ });
+ }
+
+ default Optional Float(String key) {
+ return String(key).map(str -> {
+ try {
+ return Float.parseFloat(str);
+ } catch (Exception ex) {
+ return null;
+ }
+ });
+ }
+
+ default Optional Double(String key) {
+ return String(key).map(str -> {
+ try {
+ return Double.parseDouble(str);
+ } catch (Exception ex) {
+ return null;
+ }
+ });
+ }
+
+ default Optional Boolean(String key) {
+ return String(key).map(str -> {
+ try {
+ return Boolean.parseBoolean(str);
+ } catch (Exception ex) {
+ return null;
+ }
+ });
+ }
+ }
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/page/TestPage.java b/editor/src/main/java/ru/dragonestia/editor/page/TestPage.java
new file mode 100644
index 0000000..445e825
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/page/TestPage.java
@@ -0,0 +1,15 @@
+package ru.dragonestia.editor.page;
+
+import com.vaadin.flow.router.Route;
+import ru.dragonestia.editor.component.DialogEditor;
+import ru.dragonestia.editor.model.DialogueContext;
+
+@Route("/")
+public class TestPage extends Page {
+
+ @Override
+ protected void init(QueryParams params) {
+ var ctx = new DialogueContext();
+ add(new DialogEditor(ctx));
+ }
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/repository/DialoguePackageRepository.java b/editor/src/main/java/ru/dragonestia/editor/repository/DialoguePackageRepository.java
new file mode 100644
index 0000000..945e5b2
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/repository/DialoguePackageRepository.java
@@ -0,0 +1,6 @@
+package ru.dragonestia.editor.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import ru.dragonestia.editor.model.DialoguePackage;
+
+public interface DialoguePackageRepository extends JpaRepository {}
diff --git a/editor/src/main/java/ru/dragonestia/editor/repository/DialogueRepository.java b/editor/src/main/java/ru/dragonestia/editor/repository/DialogueRepository.java
new file mode 100644
index 0000000..cc6ea72
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/repository/DialogueRepository.java
@@ -0,0 +1,6 @@
+package ru.dragonestia.editor.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import ru.dragonestia.editor.model.Dialogue;
+
+public interface DialogueRepository extends JpaRepository {}
diff --git a/editor/src/main/java/ru/dragonestia/editor/service/DialoguePackageService.java b/editor/src/main/java/ru/dragonestia/editor/service/DialoguePackageService.java
new file mode 100644
index 0000000..6ee17bf
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/service/DialoguePackageService.java
@@ -0,0 +1,9 @@
+package ru.dragonestia.editor.service;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class DialoguePackageService {
+}
diff --git a/editor/src/main/java/ru/dragonestia/editor/util/JsonUtils.java b/editor/src/main/java/ru/dragonestia/editor/util/JsonUtils.java
new file mode 100644
index 0000000..e7fbd2a
--- /dev/null
+++ b/editor/src/main/java/ru/dragonestia/editor/util/JsonUtils.java
@@ -0,0 +1,30 @@
+package ru.dragonestia.editor.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class JsonUtils {
+
+ private final ObjectMapper mapper = new ObjectMapper();
+ private final ObjectWriter writer = mapper.writer();
+ private final ObjectReader reader = mapper.reader();
+
+ public String toJson(Object object) {
+ try {
+ return writer.writeValueAsString(object);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public T fromJson(String json) {
+ try {
+ return reader.readValue(json);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/editor/src/main/resources/application.yaml b/editor/src/main/resources/application.yaml
index 0c47145..49c10cc 100644
--- a/editor/src/main/resources/application.yaml
+++ b/editor/src/main/resources/application.yaml
@@ -2,5 +2,17 @@ spring:
application:
name: 'editor'
+ datasource:
+ url: ${BFF_POSTGRES_URL:jdbc:postgresql://localhost:5432/postgres}
+ username: ${BFF_POSTGRES_USERNAME:postgres}
+ password: ${BFF_POSTGRES_PASSWORD:some_password}
+
+ jpa:
+ properties:
+ hibernate:
+ dialect: org.hibernate.dialect.PostgreSQLDialect
+ hibernate:
+ ddl-auto: validate
+
server:
port: 8080
diff --git a/editor/src/main/resources/ru/dragonestia/editor/component/DialogueEditor.html b/editor/src/main/resources/ru/dragonestia/editor/component/DialogueEditor.html
new file mode 100644
index 0000000..2c38668
--- /dev/null
+++ b/editor/src/main/resources/ru/dragonestia/editor/component/DialogueEditor.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file