date fields

master
Josha von Gizycki 2 weeks ago
parent 19d9ed1da9
commit a5c2f5024f

@ -6,6 +6,8 @@ import org.springframework.data.jdbc.repository.query.Modifying
import org.springframework.data.jdbc.repository.query.Query import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.relational.core.mapping.Table import org.springframework.data.relational.core.mapping.Table
import org.springframework.data.repository.Repository import org.springframework.data.repository.Repository
import java.time.LocalDateTime
import java.time.LocalDateTime.now
import java.time.ZonedDateTime import java.time.ZonedDateTime
typealias DocumentId = Long typealias DocumentId = Long
@ -18,25 +20,40 @@ data class Document(
val id: DocumentId = 0, val id: DocumentId = 0,
val name: DocumentName, val name: DocumentName,
val description: DocumentDescription = "", val description: DocumentDescription = "",
val updatedAt: ZonedDateTime = ZonedDateTime.now(), val updatedAt: LocalDateTime = now(),
val createdAt: ZonedDateTime = ZonedDateTime.now(), val createdAt: LocalDateTime = now(),
val labelFields: Set<LabelField> = emptySet(), val labelFields: Set<LabelField> = emptySet(),
val dateFields: Set<DateField> = emptySet(), val dateFields: Set<DateField> = emptySet(),
) { ) {
fun labelFieldsSorted() = fun labelFieldsSorted() =
labelFields.sortedBy { it.order } labelFields.sortedBy { it.order }
fun dateFieldsSorted() =
dateFields.sortedBy { it.order }
fun withLabel(field: LabelField) = fun withLabel(field: LabelField) =
copy( copy(
labelFields = labelFields + field, labelFields = labelFields + field,
updatedAt = ZonedDateTime.now() updatedAt = now()
)
fun withDate(field: DateField) =
copy(
dateFields = dateFields + field,
updatedAt = now()
) )
fun withoutLabel(fieldId: FieldId) = fun withoutLabel(fieldId: FieldId) =
copy( copy(
updatedAt = ZonedDateTime.now(), updatedAt = now(),
labelFields = labelFields.filter { it.id != fieldId }.toSet() labelFields = labelFields.filter { it.id != fieldId }.toSet()
) )
fun withoutDate(fieldId: FieldId) =
copy(
updatedAt = now(),
dateFields = dateFields.filter { it.id != fieldId }.toSet()
)
} }
@Table("T_DOCUMENT") @Table("T_DOCUMENT")

@ -0,0 +1,27 @@
package wanijo.wanijo2.domain.event
import jakarta.validation.constraints.Min
import jakarta.validation.constraints.NotEmpty
import wanijo.wanijo2.domain.DateField
import wanijo.wanijo2.domain.DocumentId
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.ZonedDateTime
data class AddDateFieldCommand(
@Min(1)
val documentId: DocumentId,
@NotEmpty
val dateName: String,
@NotEmpty
val dateValue: LocalDateTime,
val order: Int = 0,
) {
fun toField() =
DateField(
name = dateName,
value = dateValue,
order = order
)
}

@ -3,6 +3,7 @@ package wanijo.wanijo2.domain.event
import jakarta.validation.constraints.Min import jakarta.validation.constraints.Min
import jakarta.validation.constraints.NotEmpty import jakarta.validation.constraints.NotEmpty
import wanijo.wanijo2.domain.DocumentId import wanijo.wanijo2.domain.DocumentId
import wanijo.wanijo2.domain.LabelField
data class AddLabelFieldCommand( data class AddLabelFieldCommand(
@Min(1) @Min(1)
@ -12,4 +13,11 @@ data class AddLabelFieldCommand(
@NotEmpty @NotEmpty
val labelValue: String, val labelValue: String,
val order: Int = 0 val order: Int = 0
) ) {
fun toField() =
LabelField(
order = order,
name = labelName,
value = labelValue
)
}

@ -0,0 +1,12 @@
package wanijo.wanijo2.domain.event
import jakarta.validation.constraints.Min
import wanijo.wanijo2.domain.DocumentId
import wanijo.wanijo2.domain.FieldId
data class DeleteDateFieldCommand(
@Min(1)
val documentId: DocumentId,
@Min(1)
val dateFieldId: FieldId
)

@ -2,7 +2,8 @@ package wanijo.wanijo2.domain
import org.springframework.data.annotation.Id import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Table import org.springframework.data.relational.core.mapping.Table
import java.time.ZonedDateTime import java.time.LocalDateTime
import java.time.LocalDateTime.now
typealias FieldId = Long typealias FieldId = Long
@ -13,8 +14,8 @@ data class LabelField(
val order: Int = 0, val order: Int = 0,
val name: String, val name: String,
val value: String = "", val value: String = "",
val updatedAt: ZonedDateTime = ZonedDateTime.now(), val updatedAt: LocalDateTime = now(),
val createdAt: ZonedDateTime = ZonedDateTime.now(), val createdAt: LocalDateTime = now(),
) )
@Table("T_DATE_FIELD") @Table("T_DATE_FIELD")
@ -23,7 +24,7 @@ data class DateField(
val id: FieldId = 0, val id: FieldId = 0,
val order: Int = 0, val order: Int = 0,
val name: String, val name: String,
val value: ZonedDateTime, val value: LocalDateTime,
val updatedAt: ZonedDateTime = ZonedDateTime.now(), val updatedAt: LocalDateTime = now(),
val createdAt: ZonedDateTime = ZonedDateTime.now(), val createdAt: LocalDateTime = now(),
) )

@ -0,0 +1,22 @@
package wanijo.wanijo2.domain.handler
import org.springframework.stereotype.Service
import wanijo.wanijo2.domain.DateField
import wanijo.wanijo2.domain.DocumentDao
import wanijo.wanijo2.domain.LabelField
import wanijo.wanijo2.domain.event.AddDateFieldCommand
import wanijo.wanijo2.http.DocumentNotFound
@Service
class AddDateFieldHandler(
val documentDao: DocumentDao
) {
fun exec(command: AddDateFieldCommand) {
val doc = documentDao.findById(command.documentId) ?: throw DocumentNotFound()
documentDao.save(
doc.withDate(command.toField())
)
}
}

@ -2,7 +2,6 @@ package wanijo.wanijo2.domain.handler
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import wanijo.wanijo2.domain.DocumentDao import wanijo.wanijo2.domain.DocumentDao
import wanijo.wanijo2.domain.LabelField
import wanijo.wanijo2.domain.event.AddLabelFieldCommand import wanijo.wanijo2.domain.event.AddLabelFieldCommand
import wanijo.wanijo2.http.DocumentNotFound import wanijo.wanijo2.http.DocumentNotFound
@ -14,13 +13,7 @@ class AddLabelFieldHandler(
fun exec(command: AddLabelFieldCommand) { fun exec(command: AddLabelFieldCommand) {
val doc = documentDao.findById(command.documentId) ?: throw DocumentNotFound() val doc = documentDao.findById(command.documentId) ?: throw DocumentNotFound()
documentDao.save( documentDao.save(
doc.withLabel( doc.withLabel(command.toField())
LabelField(
order = command.order,
name = command.labelName,
value = command.labelValue
)
)
) )
} }

@ -0,0 +1,18 @@
package wanijo.wanijo2.domain.handler
import org.springframework.stereotype.Service
import wanijo.wanijo2.domain.DocumentDao
import wanijo.wanijo2.domain.event.DeleteDateFieldCommand
import wanijo.wanijo2.http.DocumentNotFound
@Service
class DeleteDateFieldHandler(
val dao: DocumentDao
) {
fun exec(command: DeleteDateFieldCommand) {
val doc = dao.findById(command.documentId) ?: throw DocumentNotFound()
dao.save(doc.withoutDate(command.dateFieldId))
}
}

@ -6,6 +6,8 @@ import org.springframework.data.jdbc.repository.query.Modifying
import org.springframework.data.jdbc.repository.query.Query import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.relational.core.mapping.Table import org.springframework.data.relational.core.mapping.Table
import org.springframework.data.repository.Repository import org.springframework.data.repository.Repository
import java.time.LocalDateTime
import java.time.LocalDateTime.now
import java.time.ZonedDateTime import java.time.ZonedDateTime
typealias TagId = Long typealias TagId = Long
@ -16,7 +18,7 @@ data class Tag(
@Id @Id
val id: TagId = 0, val id: TagId = 0,
val name: TagName, val name: TagName,
val createdAt: ZonedDateTime = ZonedDateTime.now() val createdAt: LocalDateTime = now()
) )
typealias DocumentTaggingId = Long typealias DocumentTaggingId = Long
@ -26,7 +28,8 @@ data class DocumentTagging(
@Id @Id
val id: DocumentTaggingId = 0, val id: DocumentTaggingId = 0,
val tagId: AggregateReference<Tag, TagId>, val tagId: AggregateReference<Tag, TagId>,
val documentId: AggregateReference<Document, DocumentId> val documentId: AggregateReference<Document, DocumentId>,
val createdAt: LocalDateTime = now()
) { ) {
companion object { companion object {
fun between(doc: Document, tagId: TagId) = fun between(doc: Document, tagId: TagId) =

@ -7,36 +7,44 @@ import org.springframework.ui.set
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import wanijo.wanijo2.domain.DocumentBriefDao import wanijo.wanijo2.domain.DocumentBriefDao
import wanijo.wanijo2.domain.DocumentId import wanijo.wanijo2.domain.DocumentId
import wanijo.wanijo2.domain.event.AddDateFieldCommand
import wanijo.wanijo2.domain.event.AddLabelFieldCommand import wanijo.wanijo2.domain.event.AddLabelFieldCommand
import wanijo.wanijo2.domain.handler.AddDateFieldHandler
import wanijo.wanijo2.domain.handler.AddLabelFieldHandler import wanijo.wanijo2.domain.handler.AddLabelFieldHandler
import java.time.LocalDateTime
import java.time.ZonedDateTime.now
@Controller @Controller
@RequestMapping("/document/{id}/field/label/add") class AddFieldController(
class AddLabelFieldController(
val documentBriefDao: DocumentBriefDao, val documentBriefDao: DocumentBriefDao,
val addLabelFieldHandler: AddLabelFieldHandler val addLabelFieldHandler: AddLabelFieldHandler,
val addDateFieldHandler: AddDateFieldHandler
) { ) {
@GetMapping @GetMapping("/document/{id}/field/add")
fun addLabel( fun addLabel(
@PathVariable @PathVariable
id: DocumentId, id: DocumentId,
model: Model model: Model
): String { ): String {
model["form"] = AddLabelFieldCommand( model["labelForm"] = AddLabelFieldCommand(
documentId = id, documentId = id,
labelName = "", labelName = "",
labelValue = "" labelValue = ""
) )
model["dateForm"] = AddDateFieldCommand(
documentId = id,
dateName = "",
dateValue = LocalDateTime.now()
)
model["document"] = documentBriefDao.findById(id) model["document"] = documentBriefDao.findById(id)
return "addLabelField" return "addLabelField"
} }
@PostMapping @PostMapping("/document/{id}/field/label/add")
fun addLabel( fun addLabel(
@PathVariable @PathVariable
id: DocumentId, id: DocumentId,
@ -47,4 +55,15 @@ class AddLabelFieldController(
return "redirect:/document/$id" return "redirect:/document/$id"
} }
@PostMapping("/document/{id}/field/date/add")
fun addDate(
@PathVariable
id: DocumentId,
@Valid
command: AddDateFieldCommand
): String {
addDateFieldHandler.exec(command)
return "redirect:/document/$id"
}
} }

@ -5,12 +5,15 @@ import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PostMapping
import wanijo.wanijo2.domain.DocumentId import wanijo.wanijo2.domain.DocumentId
import wanijo.wanijo2.domain.event.DeleteDateFieldCommand
import wanijo.wanijo2.domain.event.DeleteLabelFieldCommand import wanijo.wanijo2.domain.event.DeleteLabelFieldCommand
import wanijo.wanijo2.domain.handler.DeleteDateFieldHandler
import wanijo.wanijo2.domain.handler.DeleteLabelFieldHandler import wanijo.wanijo2.domain.handler.DeleteLabelFieldHandler
@Controller @Controller
class DeleteLabelFieldController( class DeleteFieldController(
val handler: DeleteLabelFieldHandler val labelFieldhandler: DeleteLabelFieldHandler,
val dateFieldHandler: DeleteDateFieldHandler
) { ) {
@PostMapping("/document/{id}/field/label/delete") @PostMapping("/document/{id}/field/label/delete")
@ -20,7 +23,18 @@ class DeleteLabelFieldController(
@Valid @Valid
command: DeleteLabelFieldCommand command: DeleteLabelFieldCommand
): String { ): String {
handler.exec(command) labelFieldhandler.exec(command)
return "redirect:/document/$id"
}
@PostMapping("/document/{id}/field/date/delete")
fun removeDateField(
@PathVariable
id: DocumentId,
@Valid
command: DeleteDateFieldCommand
): String {
dateFieldHandler.exec(command)
return "redirect:/document/$id" return "redirect:/document/$id"
} }

@ -0,0 +1,2 @@
ALTER TABLE t_document_tagging
ADD COLUMN created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now();

@ -16,7 +16,9 @@
<span class="low-key-hint">hinzufügen</span> <span class="low-key-hint">hinzufügen</span>
</h2> </h2>
<form th:action="@{/document/{id}/field/label/add(id=${document.id})}" th:object="${form}" method="post"> <form th:action="@{/document/{id}/field/label/add(id=${document.id})}"
th:object="${labelForm}"
method="post">
<input type="hidden" th:field="*{documentId}"> <input type="hidden" th:field="*{documentId}">
<label for="labelName">name</label> <label for="labelName">name</label>
@ -25,8 +27,33 @@
<label for="labelValue">wert</label> <label for="labelValue">wert</label>
<input id="labelValue" th:field="*{labelValue}" type="text" required> <input id="labelValue" th:field="*{labelValue}" type="text" required>
<label for="order">sortierung</label> <label for="labelOrder">sortierung</label>
<input id="order" th:field="*{order}" type="number" required> <input id="labelOrder" th:field="*{order}" type="number" required>
<button type="submit">
hinzufügen
</button>
</form>
<h2>
<span class="low-key-hint">datum zu</span>
<th:block th:text="${document.name}"/>
<span class="low-key-hint">hinzufügen</span>
</h2>
<form th:action="@{/document/{id}/field/date/add(id=${document.id})}"
th:object="${dateForm}"
method="post">
<input type="hidden" th:field="*{documentId}">
<label for="dateName">name</label>
<input id="dateName" type="text" th:field="*{dateName}" required>
<label for="dateValue">wert</label>
<input id="dateValue" th:field="*{dateValue}" type="datetime-local" required>
<label for="dateOrder">sortierung</label>
<input id="dateOrder" th:field="*{order}" type="number" required>
<button type="submit"> <button type="submit">
hinzufügen hinzufügen

@ -53,14 +53,16 @@
<div class="show__markdown" th:utext="${descHtml}"></div> <div class="show__markdown" th:utext="${descHtml}"></div>
</fieldset> </fieldset>
<h2 class="low-key-hint">felder</h2> <h2 class="low-key-hint">
<h3 class="low-key-hint"> felder
label <a th:href="@{/document/{id}/field/add(id=${document.id})}">
<a th:href="@{/document/{id}/field/label/add(id=${document.id})}">
<button> <button>
neu neu
</button> </button>
</a> </a>
</h2>
<h3 class="low-key-hint">
label
</h3> </h3>
<dl> <dl>
<th:block th:each="field : ${document.labelFieldsSorted()}"> <th:block th:each="field : ${document.labelFieldsSorted()}">
@ -79,8 +81,15 @@
datumsangaben datumsangaben
</h3> </h3>
<dl> <dl>
<th:block th:each="field : ${document.dateFields}"> <th:block th:each="field : ${document.dateFieldsSorted()}">
<dt th:text="${field.name}"></dt> <dt>
<th:block th:text="${field.name}" />
<form class="form-inline" th:action="@{/document/{id}/field/date/delete(id=${document.id})}" method="post">
<input type="hidden" name="dateFieldId" th:value="${field.id}">
<input type="hidden" name="documentId" th:value="${document.id}">
<button type="submit" class="warning">weg</button>
</form>
</dt>
<dd th:text="${#temporals.format(field.value, 'yyyy-MM-dd HH:mm')}"></dd> <dd th:text="${#temporals.format(field.value, 'yyyy-MM-dd HH:mm')}"></dd>
</th:block> </th:block>
</dl> </dl>

Loading…
Cancel
Save