init Template use

This commit is contained in:
boxi committed 2026-04-05 20:50:14 +02:00
1 parent 27797679ac
commit 2434383953
8 files changed
+96 -3

No files matched your search

+8 -2
View File
@@ -27,13 +27,19 @@ GET http://localhost:31009/v1/spaces/{{spaceId}}/properties/{{priorityPropertyId
Authorization: Bearer {{apiKey}} Authorization: Bearer {{apiKey}}
Anytype-Version: 0.1 Anytype-Version: 0.1
### Get Templates
GET http://localhost:31009/v1/spaces/{{spaceId}}/types/{{taskTypeId}}/templates
Authorization: Bearer {{apiKey}}
Anytype-Version: 0.1
### Create Task ### Create Task
POST http://localhost:31009/v1/spaces/{{spaceId}}/objects POST http://localhost:31009/v1/spaces/{{spaceId}}/objects
Authorization: Bearer {{apiKey}} Authorization: Bearer {{apiKey}}
Content-Type: application/json Content-Type: application/json
{ {
"name": "Test Task II", "name": "With Template - II",
"body": "Created via HTTP client", "body": "And here comes the body",
"template_id": "bafyreidivup2xrqn4xbgimukkgst3ao24izqnpxdesbkdtnc5owvhf6i6i",
"type_key": "ot-task" "type_key": "ot-task"
} }
@@ -88,10 +88,20 @@ class AnyTypeApi(
response.body<SearchObjectsResponse>().data response.body<SearchObjectsResponse>().data
} }
suspend fun getTemplates(typeId: String): Result<List<Template>> =
runCatching {
val response = http.get("$baseUrl/v1/spaces/$spaceId/types/$typeId/templates") {
header("Anytype-Version", "0.1")
bearerAuth(apiKey)
}
response.body<TemplatesResponse>().data
}
suspend fun createObject( suspend fun createObject(
title: String, title: String,
details: String = "", details: String = "",
typeKey: String, typeKey: String,
templateId: String? = null,
properties: List<JsonElement> = emptyList(), properties: List<JsonElement> = emptyList(),
): Result<String> = ): Result<String> =
runCatching { runCatching {
@@ -104,6 +114,7 @@ class AnyTypeApi(
name = title, name = title,
body = details, body = details,
typeKey = typeKey, typeKey = typeKey,
templateId = templateId,
properties = properties, properties = properties,
) )
) )
@@ -9,5 +9,6 @@ data class CreateObjectRequest(
val name: String, val name: String,
val body: String, val body: String,
@SerialName("type_key") val typeKey: String, @SerialName("type_key") val typeKey: String,
@SerialName("template_id") val templateId: String? = null,
val properties: List<JsonElement> = emptyList(), val properties: List<JsonElement> = emptyList(),
) )
@@ -0,0 +1,18 @@
package ch.ergon.anytask.api.dto
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Template(
val id: String,
val name: String,
val archived: Boolean = false,
val icon: Icon? = null,
val layout: String = "",
val `object`: String = "",
val properties: List<Property> = emptyList(),
val snippet: String = "",
@SerialName("space_id") val spaceId: String = "",
val type: ObjectType? = null,
)
@@ -0,0 +1,8 @@
package ch.ergon.anytask.api.dto
import kotlinx.serialization.Serializable
@Serializable
data class TemplatesResponse(
val data: List<Template>,
)
@@ -29,6 +29,7 @@ data class Configuration(
val connection: Connection = Connection(), val connection: Connection = Connection(),
val spaceId: String = "", val spaceId: String = "",
@SerialName("task_type_key") val taskTypeKey: String = "", @SerialName("task_type_key") val taskTypeKey: String = "",
@SerialName("template_id") val templateId: String = "",
val properties: List<PropertyConfig> = emptyList(), val properties: List<PropertyConfig> = emptyList(),
) )
@@ -49,6 +49,7 @@ import ch.ergon.anytask.api.AnyTypeApi
import ch.ergon.anytask.api.dto.ObjectType import ch.ergon.anytask.api.dto.ObjectType
import ch.ergon.anytask.api.dto.Property import ch.ergon.anytask.api.dto.Property
import ch.ergon.anytask.api.dto.Space import ch.ergon.anytask.api.dto.Space
import ch.ergon.anytask.api.dto.Template
import ch.ergon.anytask.config.Configuration import ch.ergon.anytask.config.Configuration
import ch.ergon.anytask.config.Connection import ch.ergon.anytask.config.Connection
import ch.ergon.anytask.config.PropertyConfig import ch.ergon.anytask.config.PropertyConfig
@@ -66,12 +67,15 @@ fun SettingsWindow(
var loadedApiKey by remember { mutableStateOf(config.connection.apiKey) } var loadedApiKey by remember { mutableStateOf(config.connection.apiKey) }
var selectedSpaceId by remember { mutableStateOf(config.spaceId) } var selectedSpaceId by remember { mutableStateOf(config.spaceId) }
var selectedTypeKey by remember { mutableStateOf(config.taskTypeKey) } var selectedTypeKey by remember { mutableStateOf(config.taskTypeKey) }
var selectedTemplateId by remember { mutableStateOf(config.templateId) }
val propertyConfigs = remember { mutableStateListOf<PropertyConfig>().also { it.addAll(config.properties) } } val propertyConfigs = remember { mutableStateListOf<PropertyConfig>().also { it.addAll(config.properties) } }
var spaces by remember { mutableStateOf<List<Space>>(emptyList()) } var spaces by remember { mutableStateOf<List<Space>>(emptyList()) }
var isLoadingSpaces by remember { mutableStateOf(false) } var isLoadingSpaces by remember { mutableStateOf(false) }
var types by remember { mutableStateOf<List<ObjectType>>(emptyList()) } var types by remember { mutableStateOf<List<ObjectType>>(emptyList()) }
var isLoadingTypes by remember { mutableStateOf(false) } var isLoadingTypes by remember { mutableStateOf(false) }
var templates by remember { mutableStateOf<List<Template>>(emptyList()) }
var isLoadingTemplates by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) } var errorMessage by remember { mutableStateOf<String?>(null) }
// Property edit state // Property edit state
@@ -105,6 +109,20 @@ fun SettingsWindow(
isLoadingTypes = false isLoadingTypes = false
} }
suspend fun loadTemplates(key: String, spaceId: String, typeId: String) {
templates = emptyList()
isLoadingTemplates = true
val tempClient = AnyTypeApi(baseUrl = config.connection.baseUrl, apiKey = key, spaceId = spaceId)
try {
tempClient.getTemplates(typeId)
.onSuccess { templates = it }
.onFailure { errorMessage = "Failed to load templates: ${it.message}" }
} finally {
tempClient.close()
}
isLoadingTemplates = false
}
// Initial load // Initial load
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
loadSpaces(apiKey) loadSpaces(apiKey)
@@ -113,6 +131,14 @@ fun SettingsWindow(
} }
} }
// Load templates when type changes
LaunchedEffect(selectedTypeKey, types) {
val type = types.find { it.key == selectedTypeKey }
if (type != null && selectedSpaceId.isNotEmpty()) {
loadTemplates(apiKey, selectedSpaceId, type.id)
}
}
val selectedType = types.find { it.key == selectedTypeKey } val selectedType = types.find { it.key == selectedTypeKey }
val availableProperties = selectedType?.properties.orEmpty() val availableProperties = selectedType?.properties.orEmpty()
@@ -120,6 +146,7 @@ fun SettingsWindow(
connection = Connection(apiKey = apiKey, baseUrl = config.connection.baseUrl), connection = Connection(apiKey = apiKey, baseUrl = config.connection.baseUrl),
spaceId = selectedSpaceId, spaceId = selectedSpaceId,
taskTypeKey = selectedTypeKey, taskTypeKey = selectedTypeKey,
templateId = selectedTemplateId,
properties = propertyConfigs.toList(), properties = propertyConfigs.toList(),
) )
@@ -142,6 +169,8 @@ fun SettingsWindow(
loadedApiKey = apiKey loadedApiKey = apiKey
selectedSpaceId = "" selectedSpaceId = ""
selectedTypeKey = "" selectedTypeKey = ""
selectedTemplateId = ""
templates = emptyList()
propertyConfigs.clear() propertyConfigs.clear()
editingIndex = null editingIndex = null
types = emptyList() types = emptyList()
@@ -155,6 +184,8 @@ fun SettingsWindow(
loadedApiKey = apiKey loadedApiKey = apiKey
selectedSpaceId = "" selectedSpaceId = ""
selectedTypeKey = "" selectedTypeKey = ""
selectedTemplateId = ""
templates = emptyList()
propertyConfigs.clear() propertyConfigs.clear()
editingIndex = null editingIndex = null
types = emptyList() types = emptyList()
@@ -174,6 +205,8 @@ fun SettingsWindow(
onSelect = { id -> onSelect = { id ->
selectedSpaceId = id selectedSpaceId = id
selectedTypeKey = "" selectedTypeKey = ""
selectedTemplateId = ""
templates = emptyList()
propertyConfigs.clear() propertyConfigs.clear()
editingIndex = null editingIndex = null
scope.launch { loadTypes(apiKey, id) } scope.launch { loadTypes(apiKey, id) }
@@ -189,12 +222,26 @@ fun SettingsWindow(
options = types.map { it.key to it.name }, options = types.map { it.key to it.name },
onSelect = { key -> onSelect = { key ->
selectedTypeKey = key selectedTypeKey = key
selectedTemplateId = ""
templates = emptyList()
propertyConfigs.clear() propertyConfigs.clear()
editingIndex = null editingIndex = null
}, },
isLoading = isLoadingTypes, isLoading = isLoadingTypes,
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(12.dp))
// Template dropdown
if (selectedTypeKey.isNotEmpty()) {
DropdownSelector(
label = "Template",
selectedValue = templates.find { it.id == selectedTemplateId }?.name ?: selectedTemplateId,
options = listOf("" to "(none)") + templates.map { it.id to it.name },
onSelect = { id -> selectedTemplateId = id },
isLoading = isLoadingTemplates,
)
Spacer(modifier = Modifier.height(16.dp))
}
// Properties section // Properties section
Text("Properties", style = MaterialTheme.typography.subtitle1, fontWeight = FontWeight.Bold) Text("Properties", style = MaterialTheme.typography.subtitle1, fontWeight = FontWeight.Bold)
@@ -79,6 +79,7 @@ fun TaskWindow(client: AnyTypeApi, config: Configuration, isVisible: Boolean, on
title = title.trim(), title = title.trim(),
details = details.trim(), details = details.trim(),
typeKey = typeKey, typeKey = typeKey,
templateId = config.templateId.ifEmpty { null },
properties = propElements, properties = propElements,
) )
.onSuccess { .onSuccess {
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.