diff --git a/src/assistant.js b/src/assistant.js index c4b53c62..8fae72a4 100644 --- a/src/assistant.js +++ b/src/assistant.js @@ -137,13 +137,63 @@ export async function openAssistantForm({ view.$on('load-task', (task) => { if (!view.loading) { console.debug('[assistant] loading task', task) + cancelTaskPolling() + view.selectedTaskTypeId = task.type view.inputs = task.input view.outputs = task.status === TASK_STATUS_STRING.successful ? task.output : null view.selectedTaskId = task.id lastTask = task + + if ([TASK_STATUS_STRING.scheduled, TASK_STATUS_STRING.running].includes(task?.status)) { + getTask(task.id).then(response => { + const updatedTask = response.data?.ocs?.data?.task + + if (![TASK_STATUS_STRING.scheduled, TASK_STATUS_STRING.running].includes(updatedTask?.status)) { + view.selectedTaskTypeId = updatedTask.type + view.inputs = updatedTask.input + view.outputs = updatedTask.status === TASK_STATUS_STRING.successful ? updatedTask.output : null + view.selectedTaskId = updatedTask.id + lastTask = updatedTask + return + } + + view.loading = true + view.showSyncTaskRunning = true + view.progress = null + view.expectedRuntime = (updatedTask?.completionExpectedAt - updatedTask?.scheduledAt) || null + + const setProgress = (progress) => { + view.progress = progress + } + pollTask(updatedTask.id, setProgress).then(finishedTask => { + console.debug('pollTask.then', finishedTask) + if (finishedTask.status === TASK_STATUS_STRING.successful) { + view.outputs = finishedTask?.output + view.selectedTaskId = finishedTask?.id + } else if (finishedTask.status === TASK_STATUS_STRING.failed) { + showError(t('assistant', 'Your task with ID {id} has failed', { id: finishedTask.id })) + console.error('[assistant] Task failed', finishedTask) + view.outputs = null + } + // resolve(finishedTask) + view.loading = false + view.showSyncTaskRunning = false + }).catch(error => { + console.debug('[assistant] poll error', error) + }) + }).catch(error => { + console.error(error) + }) + } } }) + view.$on('new-task', () => { + console.debug('[assistant] new task') + view.outputs = null + view.selectedTaskId = null + lastTask = null + }) view.$on('background-notify', () => { cancelTaskPolling() view.showScheduleConfirmation = true @@ -166,6 +216,7 @@ export async function openAssistantForm({ view.$destroy() }) view.$on('back-to-assistant', () => { + cancelTaskPolling() view.showScheduleConfirmation = false view.showSyncTaskRunning = false view.loading = false @@ -430,13 +481,63 @@ export async function openAssistantTask(task, { isInsideViewer = undefined, acti }) view.$on('load-task', (task) => { if (!view.loading) { + cancelTaskPolling() + view.selectedTaskTypeId = task.type view.inputs = task.input view.outputs = task.status === TASK_STATUS_STRING.successful ? task.output : null view.selectedTaskId = task.id lastTask = task + + if ([TASK_STATUS_STRING.scheduled, TASK_STATUS_STRING.running].includes(task?.status)) { + getTask(task.id).then(response => { + const updatedTask = response.data?.ocs?.data?.task + + if (![TASK_STATUS_STRING.scheduled, TASK_STATUS_STRING.running].includes(updatedTask?.status)) { + view.selectedTaskTypeId = updatedTask.type + view.inputs = updatedTask.input + view.outputs = updatedTask.status === TASK_STATUS_STRING.successful ? updatedTask.output : null + view.selectedTaskId = updatedTask.id + lastTask = updatedTask + return + } + + view.loading = true + view.showSyncTaskRunning = true + view.progress = null + view.expectedRuntime = (updatedTask?.completionExpectedAt - updatedTask?.scheduledAt) || null + + const setProgress = (progress) => { + view.progress = progress + } + pollTask(updatedTask.id, setProgress).then(finishedTask => { + console.debug('pollTask.then', finishedTask) + if (finishedTask.status === TASK_STATUS_STRING.successful) { + view.outputs = finishedTask?.output + view.selectedTaskId = finishedTask?.id + } else if (finishedTask.status === TASK_STATUS_STRING.failed) { + showError(t('assistant', 'Your task with ID {id} has failed', { id: finishedTask.id })) + console.error('[assistant] Task failed', finishedTask) + view.outputs = null + } + // resolve(finishedTask) + view.loading = false + view.showSyncTaskRunning = false + }).catch(error => { + console.debug('[assistant] poll error', error) + }) + }).catch(error => { + console.error(error) + }) + } } }) + view.$on('new-task', () => { + console.debug('[assistant] new task') + view.outputs = null + view.selectedTaskId = null + lastTask = null + }) view.$on('background-notify', () => { cancelTaskPolling() view.showScheduleConfirmation = true @@ -457,6 +558,7 @@ export async function openAssistantTask(task, { isInsideViewer = undefined, acti view.$destroy() }) view.$on('back-to-assistant', () => { + cancelTaskPolling() view.showScheduleConfirmation = false view.showSyncTaskRunning = false view.loading = false diff --git a/src/components/AssistantFormInputs.vue b/src/components/AssistantFormInputs.vue index d4086ab9..50d9ff73 100644 --- a/src/components/AssistantFormInputs.vue +++ b/src/components/AssistantFormInputs.vue @@ -3,8 +3,7 @@ - SPDX-License-Identifier: AGPL-3.0-or-later --> @@ -468,6 +482,11 @@ export default { > * { margin-right: 6px; } + + .chatty-inputs { + margin-top: 8px; + height: 8000px; + } } .assistant-bubble { @@ -522,7 +541,6 @@ export default { &--list { width: 100%; - overflow: auto; } &--title { @@ -542,4 +560,166 @@ export default { color: var(--color-success); } } + +.container { + overflow: auto; + display: flex; + height: 100%; + + :deep .app-navigation-new { + padding: 0; + } + + .unloaded-sessions { + display: flex; + justify-content: center; + align-items: center; + gap: 1em; + font-weight: bold; + padding: 1em; + height: 100%; + } + + :deep .app-navigation { + --app-navigation-max-width: calc(100vw - (var(--app-navigation-padding) + 24px + var(--default-grid-baseline))); + background-color: var(--color-primary-element-light); + color: var(--color-primary-element-light-text); + border-radius: var(--border-radius-large); + + @media only screen and (max-width: 1024px) { + position: relative !important; + } + + .app-navigation-toggle-wrapper { + margin-right: -49px !important; + top: var(--default-grid-baseline); + } + + &--close { + .app-navigation-toggle-wrapper { + margin-right: -33px !important; + } + } + + &--close ~ .session-area { + .session-area__chat-area, .session-area__input-area { + padding-left: 0 !important; + } + .session-area__top-bar { + padding-left: 36px !important; + } + } + } + + :deep .app-navigation-list { + padding: var(--default-grid-baseline) !important; + box-sizing: border-box; + height: 100%; + + .app-navigation-input-confirm > form { + align-items: center; + height: var(--default-clickable-area); + + > button { + scale: calc(36/44); + } + } + + .app-navigation-entry-wrapper .app-navigation-entry-link { + .app-navigation-entry-icon { + display: none; + } + .app-navigation-entry__name { + margin-left: 16px; + } + } + + .app-navigation-entry { + &-link { + padding-right: 0.3em; + } + + &.active { + font-weight: bold; + + &:hover { + background-color: var(--color-primary-element) !important; + } + } + + &:hover { + background-color: var(--color-primary-element-light-hover); + } + + .app-navigation-entry-button { + border: none !important; + padding-right: 0 !important; + + > span { + font-size: 100% !important; + padding-left: 0; + } + } + + .editingContainer { + margin: 0 !important; + width: 100% !important; + padding-left: 24px; + } + } + } + + .session-area { + display: flex; + flex-direction: column; + justify-content: space-between; + + &__top-bar { + display: flex; + justify-content: space-between; + align-items: center; + gap: 4px; + position: sticky; + top: 0; + height: calc(var(--default-clickable-area) + var(--default-grid-baseline) * 2); + box-sizing: border-box; + border-bottom: 1px solid var(--color-border); + padding-left: 52px; + padding-right: 0.5em; + font-weight: bold; + background-color: var(--color-main-background); + + &__title { + width: 100%; + } + } + + &__chat-area { + flex: 1; + display: flex; + flex-direction: column; + overflow-y: auto; + padding: 1em; + + &__active-session__utility-button { + display: flex; + justify-content: center; + padding: 1em; + } + } + + &__chat-area, &__input-area { + padding-left: 1em; + } + + &__agency-confirmation { + margin-left: 1em; + } + + &__input-area { + position: sticky; + bottom: 0; + } + } +} diff --git a/src/components/AssistantTextProcessingModal.vue b/src/components/AssistantTextProcessingModal.vue index 43ab5af5..83cb3d88 100644 --- a/src/components/AssistantTextProcessingModal.vue +++ b/src/components/AssistantTextProcessingModal.vue @@ -48,7 +48,8 @@ @sync-submit="onSyncSubmit" @action-button-clicked="onActionButtonClicked" @try-again="$emit('try-again', $event)" - @load-task="$emit('load-task', $event)" /> + @load-task="$emit('load-task', $event)" + @new-task="$emit('new-task')" /> @@ -134,6 +135,7 @@ export default { 'action-button-clicked', 'try-again', 'load-task', + 'new-task', 'back-to-assistant', ], data() { diff --git a/src/components/TaskList.vue b/src/components/TaskList.vue index 405575e3..702f8220 100644 --- a/src/components/TaskList.vue +++ b/src/components/TaskList.vue @@ -9,6 +9,7 @@