Skip to content

Commit

Permalink
108-comments-model: 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
ikovalyov committed Jul 21, 2024
1 parent 945a5a7 commit bf88075
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 25 deletions.
9 changes: 0 additions & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,4 @@ spotless {
),
)
}
kotlinGradle {
ktlint("1.3.0")
.editorConfigOverride(
mapOf(
"max_line_length" to "256",
"insert_final_newline" to "true",
),
)
}
}
103 changes: 103 additions & 0 deletions src/commonMain/kotlin/com.github.ikovalyov.model/Comment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
@file:UseSerializers(UuidSerializer::class)
package com.github.ikovalyov.model

import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom
import com.github.ikovalyov.model.markers.IEditable
import com.github.ikovalyov.model.security.User
import com.github.ikovalyov.model.serializer.UuidSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
data class Comment(
override val id: Uuid,
val body: String,
val author: User,
val article: Article,
val userList: List<User>,
val articleList: List<Article>,
): IEditable {
override fun getMetadata(): List<IEditable.EditableMetadata<*, out IEditable>> = listOf(
IEditable.EditableMetadata(
fieldType = IEditable.FieldType.Id,
readOnly = true,
serialize = {
it.toString()
},
deserialize = {
uuidFrom(it)
},
update = {
copy(id = it)
},
get = {
id
},
fieldName = "Id",
predefinedList = null,
),
IEditable.EditableMetadata(
fieldType = IEditable.FieldType.Body,
readOnly = true,
serialize = {
it
},
deserialize = {
it
},
update = {
copy(body = it)
},
get = {
body
},
fieldName = "Body",
predefinedList = null,
),
IEditable.EditableMetadata(
fieldType = IEditable.FieldType.Author,
readOnly = false,
serialize = {
it.id.toString()
},
deserialize = { uuid ->
userList.first {
it.id.toString() == uuid
}
},
update = {
copy(author = it)
},
get = {
author
},
fieldName = "Author",
predefinedList = userList,
),
IEditable.EditableMetadata(
fieldType = IEditable.FieldType.Article,
readOnly = false,
serialize = {
it.id.toString()
},
deserialize = { uuid ->
articleList.first {
it.id.toString() == uuid
}
},
update = {
copy(article = it)
},
get = {
article
},
fieldName = "Author",
predefinedList = articleList,
),
)

override fun serialize(): String = Json.encodeToString(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.github.ikovalyov.model.markers
import com.benasher44.uuid.Uuid
import com.github.ikovalyov.model.security.User
import kotlinx.datetime.Instant
import kotlinx.serialization.ExperimentalSerializationApi

interface IEditable {
data class EditableMetadata<F : Any, I : IEditable>(
Expand All @@ -19,8 +18,6 @@ interface IEditable {

sealed class FieldType<T : Any> {
object Id : FieldType<Uuid>()

@OptIn(ExperimentalSerializationApi::class)
object Author : FieldType<User>()
object LastModified : FieldType<Instant>()
object Body : FieldType<String>()
Expand All @@ -33,9 +30,8 @@ interface IEditable {
object StringListFiledType : FieldType<List<String>>()
object Tags : FieldType<List<String>>()
object Metadata : FieldType<List<String>>()

@OptIn(ExperimentalSerializationApi::class)
object Template : FieldType<com.github.ikovalyov.model.Template>()
object Article : FieldType<com.github.ikovalyov.model.Article>()
}

val id: Uuid
Expand All @@ -48,14 +44,14 @@ fun <T : IEditable, F : Any> T.updateField(field: IEditable.EditableMetadata<F,
return field.update(this, data)
}

fun <T : IEditable, F : Any> T.getFieldValueAsString(field: IEditable.EditableMetadata<F, T>): String? {
fun <T : IEditable, F : Any> getFieldValueAsString(field: IEditable.EditableMetadata<F, T>): String? {
val fieldValue = field.get()
return fieldValue?.let {
field.serialize(it)
}
}

fun <T : IEditable, F : Any> T.getPredefinedValuesAsStrings(field: IEditable.EditableMetadata<F, T>): Map<String, String> {
fun <T : IEditable, F : Any> getPredefinedValuesAsStrings(field: IEditable.EditableMetadata<F, T>): Map<String, String> {
val fieldValues = field.predefinedList
return fieldValues?.associate {
it.hashCode().toString() to field.serialize(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class TemplateEdit<I : IEditable>(props: ItemEditProps<I>, private val initialSt
name = it.hashCode().toString()
readOnly = it.readOnly
if (!it.readOnly) {
defaultValue = state.item.getFieldValueAsString(it)
defaultValue = getFieldValueAsString(it)
onChange =
{ event ->
launch {
Expand All @@ -101,7 +101,7 @@ class TemplateEdit<I : IEditable>(props: ItemEditProps<I>, private val initialSt
}
}
} else {
value = state.item.getFieldValueAsString(it)
value = getFieldValueAsString(it)
}
}
} else {
Expand All @@ -111,15 +111,15 @@ class TemplateEdit<I : IEditable>(props: ItemEditProps<I>, private val initialSt
if (!it.readOnly) {
val storedObject = it.get()
if (storedObject != null) {
defaultValue = state.item.getFieldValueAsString(it)
defaultValue = getFieldValueAsString(it)
}
onChange =
{ event ->
val stringValue = event.target.asDynamic().value.toString()
state.item =
state.item.updateField(field = it, serializedData = stringValue)
}
val optionsList = state.item.getPredefinedValuesAsStrings(it)
val optionsList = getPredefinedValuesAsStrings(it)
optionsList.forEach {
option {
value = it.key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class TemplateInsert<I : IEditable>(props: TemplateInsertProps<I>, initialState:
}
}
} else {
value = state.currentItem.getFieldValueAsString(it)
value = getFieldValueAsString(it)
}
}
} else {
Expand All @@ -106,7 +106,7 @@ class TemplateInsert<I : IEditable>(props: TemplateInsertProps<I>, initialState:
if (!it.readOnly) {
val storedObject = it.get()
if (storedObject != null) {
defaultValue = state.currentItem.getFieldValueAsString(it)
defaultValue = getFieldValueAsString(it)
}
onChange =
{ event ->
Expand All @@ -119,7 +119,7 @@ class TemplateInsert<I : IEditable>(props: TemplateInsertProps<I>, initialState:
)
}
}
val optionsList = state.currentItem.getPredefinedValuesAsStrings(it)
val optionsList = getPredefinedValuesAsStrings(it)
optionsList.forEach {
ReactHTML.option {
value = it.key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class TemplateView<I : IEditable>(props: TemplateViewProps<I>, state: TemplateVi
fields.forEach {
section {
h1 { +it.fieldType::class.simpleName!! }
p { +(state.item.getFieldValueAsString(it) ?: "") }
p { +(getFieldValueAsString(it) ?: "") }
}
}
buttonChild<I> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private fun <T : IEditable> buildTableColumns(componentProps: TableProps<T>, ite

accessorFn = { row, _ ->
val itemMetadata = row.getMetadata().filterIsInstance<IEditable.EditableMetadata<*, T>>()[counter]
val str = row.getFieldValueAsString(itemMetadata) ?: ""
val str = getFieldValueAsString(itemMetadata) ?: ""
if (str.length > 128) {
str.substring(0, 128)
} else {
Expand Down

0 comments on commit bf88075

Please sign in to comment.