load selectValues from Tags-endpoint

This commit is contained in:
Thomas Boksberger committed 2026-04-07 07:56:38 +02:00
1 parent 2434383953
commit af0d8b77a5
7 files changed
+47 -27

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="com.nbadal.ktlint.KtlintProjectSettings">
<ktlintRulesetVersion>DEFAULT</ktlintRulesetVersion>
</component>
</project>
+5
View File
@@ -27,6 +27,11 @@ GET http://localhost:31009/v1/spaces/{{spaceId}}/properties/{{priorityPropertyId
Authorization: Bearer {{apiKey}}
Anytype-Version: 0.1
### Get Property Tags
GET http://localhost:31009/v1/spaces/{{spaceId}}/properties/{{priorityPropertyId}}/tags
Authorization: Bearer {{apiKey}}
Anytype-Version: 0.1
### Get Templates
GET http://localhost:31009/v1/spaces/{{spaceId}}/types/{{taskTypeId}}/templates
Authorization: Bearer {{apiKey}}
+1 -1
View File
@@ -152,7 +152,7 @@ private fun setupSystemTray(onShow: () -> Unit, onSettings: () -> Unit, onExit:
val icon = createTrayIcon(size)
val menu = PopupMenu().apply {
add(MenuItem("Open").also { it.addActionListener { onShow() } })
add(MenuItem("Create Task").also { it.addActionListener { onShow() } })
add(MenuItem("Settings").also { it.addActionListener { onSettings() } })
addSeparator()
add(MenuItem("Quit").also { it.addActionListener { onExit() } })
@@ -88,6 +88,15 @@ class AnyTypeApi(
response.body<SearchObjectsResponse>().data
}
suspend fun getTags(propertyId: String): Result<List<Tag>> =
runCatching {
val response = http.get("$baseUrl/v1/spaces/$spaceId/properties/$propertyId/tags") {
header("Anytype-Version", "2025-11-08")
bearerAuth(apiKey)
}
response.body<TagsResponse>().data
}
suspend fun getTemplates(typeId: String): Result<List<Template>> =
runCatching {
val response = http.get("$baseUrl/v1/spaces/$spaceId/types/$typeId/templates") {
@@ -17,10 +17,10 @@ data class Connection(
@Serializable
data class PropertyConfig(
val key: String,
val id: String = "",
val name: String = "",
val format: String = "",
val indicator: String = "",
@SerialName("possible_values") val possibleValues: List<String> = emptyList(),
@SerialName("object_type_key") val objectTypeKey: String = "",
)
@@ -364,7 +364,6 @@ private fun PropertyTable(
Text("Name", fontWeight = FontWeight.Bold, modifier = Modifier.weight(2f))
Text("Type", fontWeight = FontWeight.Bold, modifier = Modifier.weight(1.5f))
Text("Ind.", fontWeight = FontWeight.Bold, modifier = Modifier.weight(0.7f))
Text("Values", fontWeight = FontWeight.Bold, modifier = Modifier.weight(2f))
Text("Obj Type", fontWeight = FontWeight.Bold, modifier = Modifier.weight(1.5f))
Spacer(modifier = Modifier.width(40.dp))
}
@@ -383,11 +382,6 @@ private fun PropertyTable(
Text(prop.name, modifier = Modifier.weight(2f), maxLines = 1)
Text(prop.format, modifier = Modifier.weight(1.5f), maxLines = 1)
Text(prop.indicator, modifier = Modifier.weight(0.7f), maxLines = 1)
Text(
prop.possibleValues.joinToString(", "),
modifier = Modifier.weight(2f),
maxLines = 1,
)
Text(prop.objectTypeKey, modifier = Modifier.weight(1.5f), maxLines = 1)
IconButton(onClick = { onDelete(index) }) {
Icon(Icons.Default.Delete, contentDescription = "Delete", tint = Color.Gray)
@@ -409,7 +403,6 @@ private fun PropertyEditPanel(
) {
var selectedPropertyKey by remember(existing) { mutableStateOf(existing?.key ?: "") }
var indicator by remember(existing) { mutableStateOf(existing?.indicator ?: "") }
var possibleValuesText by remember(existing) { mutableStateOf(existing?.possibleValues?.joinToString("\n") ?: "") }
var objectTypeKey by remember(existing) { mutableStateOf(existing?.objectTypeKey ?: "") }
val selectedProperty = availableProperties.find { it.key == selectedPropertyKey }
@@ -446,15 +439,6 @@ private fun PropertyEditPanel(
// Format-specific fields
when (format) {
"select", "multi_select" -> {
OutlinedTextField(
value = possibleValuesText,
onValueChange = { possibleValuesText = it },
label = { Text("Possible Values (one per line)") },
modifier = Modifier.fillMaxWidth().height(120.dp),
maxLines = 10,
)
}
"object", "objects" -> {
DropdownSelector(
label = "Object Type",
@@ -470,14 +454,13 @@ private fun PropertyEditPanel(
TextButton(onClick = onCancel) { Text("Cancel") }
Button(
onClick = {
val values = possibleValuesText.lines().map { it.trim() }.filter { it.isNotEmpty() }
onConfirm(
PropertyConfig(
key = selectedPropertyKey,
id = selectedProperty?.id ?: existing?.id ?: "",
name = selectedProperty?.name ?: existing?.name ?: "",
format = format,
indicator = indicator,
possibleValues = values,
objectTypeKey = objectTypeKey,
)
)
@@ -49,6 +49,7 @@ import androidx.compose.ui.input.key.type
import androidx.compose.ui.unit.dp
import ch.ergon.anytask.api.AnyTypeApi
import ch.ergon.anytask.api.dto.SearchObject
import ch.ergon.anytask.api.dto.Tag
import ch.ergon.anytask.config.Configuration
import ch.ergon.anytask.api.dto.buildPropertyValue
import ch.ergon.anytask.config.PropertyConfig
@@ -62,6 +63,7 @@ fun TaskWindow(client: AnyTypeApi, config: Configuration, isVisible: Boolean, on
var isLoading by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) }
val propertyValues = remember { mutableStateMapOf<String, String>() }
val propertyTags = remember { mutableStateMapOf<String, List<Tag>>() }
val focusRequester = remember { FocusRequester() }
@@ -144,6 +146,7 @@ fun TaskWindow(client: AnyTypeApi, config: Configuration, isVisible: Boolean, on
value = propertyValues[prop.key] ?: "",
onValueChange = { propertyValues[prop.key] = it },
client = client,
tags = propertyTags[prop.key] ?: emptyList(),
)
}
}
@@ -174,7 +177,19 @@ fun TaskWindow(client: AnyTypeApi, config: Configuration, isVisible: Boolean, on
}
}
LaunchedEffect(isVisible) { if (isVisible) focusRequester.requestFocus() }
LaunchedEffect(isVisible) {
if (isVisible) {
focusRequester.requestFocus()
config.properties
.filter { it.format in listOf("select", "multi_select") && it.id.isNotEmpty() }
.forEach { prop ->
launch {
client.getTags(prop.id)
.onSuccess { propertyTags[prop.key] = it }
}
}
}
}
}
@Composable
@@ -183,13 +198,14 @@ private fun PropertyField(
value: String,
onValueChange: (String) -> Unit,
client: AnyTypeApi,
tags: List<Tag> = emptyList(),
) {
when (prop.format) {
"select", "multi_select" -> {
SelectField(
label = prop.name,
value = value,
options = prop.possibleValues,
tags = tags,
onValueChange = onValueChange,
)
}
@@ -231,16 +247,17 @@ private fun PropertyField(
private fun SelectField(
label: String,
value: String,
options: List<String>,
tags: List<Tag>,
onValueChange: (String) -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
val selectedName = tags.find { it.id == value }?.name ?: value
Column {
Text(label, style = MaterialTheme.typography.caption)
Box {
OutlinedButton(onClick = { expanded = true }, modifier = Modifier.fillMaxWidth()) {
Text(value.ifEmpty { "Select..." })
Text(selectedName.ifEmpty { "Select..." })
}
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
DropdownMenuItem(onClick = {
@@ -249,12 +266,12 @@ private fun SelectField(
}) {
Text("(none)", style = MaterialTheme.typography.caption)
}
options.forEach { option ->
tags.forEach { tag ->
DropdownMenuItem(onClick = {
onValueChange(option)
onValueChange(tag.id)
expanded = false
}) {
Text(option)
Text(tag.name)
}
}
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.