diff --git a/app/src/main/java/ru/kalinamall/seaca/data/SacModels.kt b/app/src/main/java/ru/kalinamall/seaca/data/SacModels.kt index 8df1968..6474fcc 100644 --- a/app/src/main/java/ru/kalinamall/seaca/data/SacModels.kt +++ b/app/src/main/java/ru/kalinamall/seaca/data/SacModels.kt @@ -63,6 +63,7 @@ data class EventSummary( @SerialName("rdg_flap_qwinsta_event_id") val rdgFlapQwinstaEventId: Long? = null, @SerialName("rdg_access_path") val rdgAccessPath: String? = null, @SerialName("rdg_qwinsta_enabled") val rdgQwinstaEnabled: Boolean = false, + @SerialName("session_terminated") val sessionTerminated: Boolean = false, ) @Serializable @@ -91,6 +92,7 @@ data class EventDetail( @SerialName("rdg_flap_qwinsta_event_id") val rdgFlapQwinstaEventId: Long? = null, @SerialName("rdg_access_path") val rdgAccessPath: String? = null, @SerialName("rdg_qwinsta_enabled") val rdgQwinstaEnabled: Boolean = false, + @SerialName("session_terminated") val sessionTerminated: Boolean = false, val details: JsonElement? = null, val raw: JsonElement? = null, val payload: JsonElement? = null, diff --git a/app/src/main/java/ru/kalinamall/seaca/ui/screens/DetailScreens.kt b/app/src/main/java/ru/kalinamall/seaca/ui/screens/DetailScreens.kt index b16ff3f..9b2909d 100644 --- a/app/src/main/java/ru/kalinamall/seaca/ui/screens/DetailScreens.kt +++ b/app/src/main/java/ru/kalinamall/seaca/ui/screens/DetailScreens.kt @@ -183,7 +183,11 @@ fun EventDetailScreen(repo: SacRepository, id: Long, onBack: () -> Unit) { terminateMessage = null try { val res = repo.withAuth { it.postEventTerminateSession(id) } - if (!res.ok) terminateMessage = res.message + if (!res.ok) { + terminateMessage = res.message + } else { + data = data?.copy(sessionTerminated = true) + } } catch (e: Exception) { terminateMessage = if (e is HttpException) SacRepository.parseError(e) else e.message } finally { diff --git a/app/src/main/java/ru/kalinamall/seaca/ui/screens/ListScreens.kt b/app/src/main/java/ru/kalinamall/seaca/ui/screens/ListScreens.kt index 76fb396..0bb8e16 100644 --- a/app/src/main/java/ru/kalinamall/seaca/ui/screens/ListScreens.kt +++ b/app/src/main/java/ru/kalinamall/seaca/ui/screens/ListScreens.kt @@ -207,6 +207,7 @@ fun EventsScreen(repo: SacRepository, onOpen: (Long) -> Unit) { var terminateLoadingId by remember { mutableStateOf(null) } var terminateConfirm by remember { mutableStateOf(null) } var terminateError by remember { mutableStateOf(null) } + var locallyTerminatedIds by remember { mutableStateOf(setOf()) } val dateMode by repo.session.dateTimeDisplayMode.collectAsStateWithLifecycle( initialValue = DateTimeDisplayMode.SLASH, ) @@ -230,7 +231,11 @@ fun EventsScreen(repo: SacRepository, onOpen: (Long) -> Unit) { terminateError = null try { val res = repo.withAuth { it.postEventTerminateSession(target.id) } - if (!res.ok) terminateError = res.message + if (!res.ok) { + terminateError = res.message + } else { + locallyTerminatedIds = locallyTerminatedIds + target.id + } } catch (e: Exception) { terminateError = if (e is HttpException) SacRepository.parseError(e) else e.message } finally { @@ -268,7 +273,9 @@ fun EventsScreen(repo: SacRepository, onOpen: (Long) -> Unit) { itemQwinsta = { rdgQwinstaEventId(it) != null }, onQwinsta = { qwinsta.openFor(it, scope) }, qwinstaLoading = qwinsta.loading, - itemTerminate = { eventSupportsSessionTerminate(it) }, + itemTerminate = { + eventSupportsSessionTerminate(it) && it.id !in locallyTerminatedIds + }, onTerminate = { terminateConfirm = it }, terminateLoadingId = terminateLoadingId, onOpen = onOpen, diff --git a/app/src/main/java/ru/kalinamall/seaca/ui/util/SessionActions.kt b/app/src/main/java/ru/kalinamall/seaca/ui/util/SessionActions.kt index 5d765c5..93f6bff 100644 --- a/app/src/main/java/ru/kalinamall/seaca/ui/util/SessionActions.kt +++ b/app/src/main/java/ru/kalinamall/seaca/ui/util/SessionActions.kt @@ -12,10 +12,12 @@ private val LINUX_SESSION_EVENT_TYPES = setOf( private val WINDOWS_SESSION_EVENT_TYPES = setOf("rdp.login.success") fun eventSupportsSessionTerminate(event: EventSummary): Boolean = - event.type in LINUX_SESSION_EVENT_TYPES || event.type in WINDOWS_SESSION_EVENT_TYPES + (event.type in LINUX_SESSION_EVENT_TYPES || event.type in WINDOWS_SESSION_EVENT_TYPES) && + !event.sessionTerminated fun eventSupportsSessionTerminate(event: EventDetail): Boolean = - event.type in LINUX_SESSION_EVENT_TYPES || event.type in WINDOWS_SESSION_EVENT_TYPES + (event.type in LINUX_SESSION_EVENT_TYPES || event.type in WINDOWS_SESSION_EVENT_TYPES) && + !event.sessionTerminated fun sessionTerminateLabel(event: EventSummary): String = event.actorUser?.takeIf { it.isNotBlank() } ?: event.title