Skip to content

Commit

Permalink
Merge pull request #18 from nextcloud/enh/integration-improvements
Browse files Browse the repository at this point in the history
Integration improvements
  • Loading branch information
julien-nc authored Jan 10, 2024
2 parents 7c5e6b1 + dd6fec6 commit 31eb629
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 14 deletions.
51 changes: 44 additions & 7 deletions src/assistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@ __webpack_public_path__ = linkTo('assistant', 'js/') // eslint-disable-line
* appId: 'my_app_id',
* identifier: 'my task identifier',
* taskType: 'OCP\\TextProcessing\\FreePromptTaskType',
* input: 'count to 3'
* input: 'count to 3',
* actionButtons: [
* {
* label: 'Label 1',
* title: 'Title 1',
* type: 'warning',
* iconSvg: cogSvg,
* onClick: (output) => { console.debug('first button clicked', output) },
* },
* {
* label: 'Label 2',
* title: 'Title 2',
* onClick: (output) => { console.debug('second button clicked', output) },
* },
* ],
* }).then(r => {console.debug('scheduled task', r.data.ocs.data.task)})
*
* @param {object} params parameters for the assistant
Expand All @@ -20,9 +34,14 @@ __webpack_public_path__ = linkTo('assistant', 'js/') // eslint-disable-line
* @param {string} params.taskType the task type class
* @param {string} params.input optional initial input text
* @param {boolean} params.isInsideViewer Should be true if this function is called while the Viewer is displayed
* @param {boolean} params.closeOnResult If true, the modal will be closed when getting a sync result
* @param {Array} params.actionButtons List of extra buttons to show in the assistant result form (only if closeOnResult is false)
* @return {Promise<unknown>}
*/
export async function openAssistantForm({ appId, identifier = '', taskType = null, input = '', isInsideViewer = undefined }) {
export async function openAssistantForm({
appId, identifier = '', taskType = null, input = '',
isInsideViewer = undefined, closeOnResult = false, actionButtons = undefined,
}) {
const { default: Vue } = await import(/* webpackChunkName: "vue-lazy" */'vue')
const { default: AssistantModal } = await import(/* webpackChunkName: "assistant-modal-lazy" */'./components/AssistantModal.vue')
Vue.mixin({ methods: { t, n } })
Expand All @@ -44,8 +63,10 @@ export async function openAssistantForm({ appId, identifier = '', taskType = nul
selectedTaskTypeId,
showScheduleConfirmation: false,
showSyncTaskRunning: false,
actionButtons,
},
}).$mount(modalElement)
let lastTask = null

view.$on('cancel', () => {
view.$destroy()
Expand All @@ -56,7 +77,9 @@ export async function openAssistantForm({ appId, identifier = '', taskType = nul
.then((response) => {
view.input = data.input
view.showScheduleConfirmation = true
resolve(response.data?.ocs?.data?.task)
const task = response.data?.ocs?.data?.task
lastTask = task
resolve(task)
})
.catch(error => {
view.$destroy()
Expand All @@ -72,15 +95,20 @@ export async function openAssistantForm({ appId, identifier = '', taskType = nul
runOrScheduleTask(appId, identifier, data.taskTypeId, data.input)
.then((response) => {
const task = response.data?.task
lastTask = task
resolve(task)
view.input = task.input
if (task.status === STATUS.successfull) {
view.output = task?.output
if (closeOnResult) {
view.$destroy()
} else {
view.output = task?.output
}
} else if (task.status === STATUS.scheduled) {
view.input = task.input
view.showScheduleConfirmation = true
}
view.loading = false
view.showSyncTaskRunning = false
resolve(task)
})
.catch(error => {
if (error?.code === 'ERR_CANCELED') {
Expand All @@ -100,14 +128,23 @@ export async function openAssistantForm({ appId, identifier = '', taskType = nul
.then((response) => {
view.showSyncTaskRunning = false
view.showScheduleConfirmation = true
resolve(response.data?.ocs?.data?.task)
const task = response.data?.ocs?.data?.task
lastTask = task
resolve(task)
})
.catch(error => {
view.$destroy()
console.error('Assistant scheduling error', error)
reject(new Error('Assistant scheduling error'))
})
})
view.$on('action-button-clicked', (data) => {
if (data.button?.onClick) {
lastTask.output = data.output
data.button.onClick(lastTask)
}
view.$destroy()
})
})
}

Expand Down
41 changes: 35 additions & 6 deletions src/components/AssistantForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@
:type="submitButtonType"
class="submit-button"
:disabled="!canSubmit"
:aria-label="t('assistant', 'Run an assistant task')"
:title="t('assistant', 'Run')"
:title="t('assistant', 'Run a task')"
@click="onSyncSubmit">
{{ syncSubmitButtonLabel }}
<template #icon>
Expand All @@ -80,18 +79,31 @@
</template>
</NcButton-->
<NcButton
v-if="showCopy"
v-if="hasOutput"
type="primary"
class="copy-button"
:aria-label="t('assistant', 'Copy task output')"
:title="t('assistant', 'Copy')"
:title="t('assistant', 'Copy output')"
@click="onCopy">
{{ t('assistant', 'Copy') }}
<template #icon>
<ClipboardCheckOutlineIcon v-if="copied" />
<ContentCopyIcon v-else />
</template>
</NcButton>
<div v-if="hasOutput"
class="action-buttons">
<NcButton
v-for="(b, i) in actionButtons"
:key="i"
:type="b.type ?? 'secondary'"
:title="b.title"
@click="onActionButtonClick(b)">
{{ b.label }}
<template v-if="b.iconSvg" #icon>
<NcIconSvgWrapper :svg="b.iconSvg" />
</template>
</NcButton>
</div>
</div>
</div>
</template>
Expand All @@ -105,6 +117,7 @@ import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcRichContenteditable from '@nextcloud/vue/dist/Components/NcRichContenteditable.js'
import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
import TaskTypeSelect from './TaskTypeSelect.vue'
Expand All @@ -125,6 +138,7 @@ export default {
NcButton,
NcRichContenteditable,
NcLoadingIcon,
NcIconSvgWrapper,
CreationIcon,
ContentCopyIcon,
ClipboardCheckOutlineIcon,
Expand All @@ -147,10 +161,15 @@ export default {
type: [String, null],
default: null,
},
actionButtons: {
type: Array,
default: () => [],
},
},
emits: [
'sync-submit',
'submit',
'action-button-clicked',
],
data() {
return {
Expand Down Expand Up @@ -191,7 +210,7 @@ export default {
? t('assistant', 'Send request')
: this.selectedTaskType.name
},
showCopy() {
hasOutput() {
return !!this.myOutput.trim()
},
},
Expand Down Expand Up @@ -232,6 +251,9 @@ export default {
showError(t('assistant', 'Result could not be copied to clipboard'))
}
},
onActionButtonClick(button) {
this.$emit('action-button-clicked', { button, output: this.myOutput.trim() })
},
},
}
</script>
Expand Down Expand Up @@ -305,8 +327,15 @@ export default {
.footer {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: end;
gap: 4px;
.action-buttons {
display: flex;
flex-wrap: wrap;
justify-content: end;
gap: 4px;
}
}
.success-icon {
Expand Down
11 changes: 10 additions & 1 deletion src/components/AssistantModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
:output="output"
:selected-task-type-id="selectedTaskTypeId"
:loading="loading"
:action-buttons="actionButtons"
@submit="onSubmit"
@sync-submit="onSyncSubmit" />
@sync-submit="onSyncSubmit"
@action-button-clicked="onActionButtonClicked" />
</div>
</div>
</NcModal>
Expand Down Expand Up @@ -93,6 +95,10 @@ export default {
type: Boolean,
required: true,
},
actionButtons: {
type: Array,
default: () => [],
},
},
emits: [
'cancel',
Expand Down Expand Up @@ -135,6 +141,9 @@ export default {
onCancelNSchedule() {
this.$emit('cancel-sync-n-schedule')
},
onActionButtonClicked(data) {
this.$emit('action-button-clicked', data)
},
},
}
</script>
Expand Down

0 comments on commit 31eb629

Please sign in to comment.