init Template use
This commit is contained in:
1 parent
27797679ac
commit
2434383953
8 files changed
+95
-2
No files matched your search
@@ -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(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))
|
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 {
|
||||||
|
|||||||