Skip to content

Commit

Permalink
now possible to try again from result form, add copy button in result…
Browse files Browse the repository at this point in the history
… form

Signed-off-by: Julien Veyssier <[email protected]>
  • Loading branch information
julien-nc committed Aug 5, 2023
1 parent a64066b commit 94e499c
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 27 deletions.
42 changes: 42 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@nextcloud/vue": "^7.8.2",
"v-click-outside": "^3.2.0",
"vue": "^2.7.12",
"vue-clipboard2": "^0.3.3",
"vue-material-design-icons": "^5.1.2",
"vue2-audio-recorder": "^1.0.4"
},
Expand Down
36 changes: 26 additions & 10 deletions src/assistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ __webpack_public_path__ = linkTo('textprocessing_assistant', 'js/') // eslint-di
/**
* Creates an assistant modal and return a promise which provides the result
*
* OCA.TPAssistant.openAssistantForm('my_app_id', 'my task identifier', 'OCP\\TextProcessing\\FreePromptTaskType', 'count to 3').then(r => {console.debug('scheduled task', r.data.ocs.data.task)})
* OCA.TPAssistant.openAssistantForm({
* appId: 'my_app_id',
* identifier: 'my task identifier',
* taskType: 'OCP\\TextProcessing\\FreePromptTaskType',
* input: 'count to 3'
* }).then(r => {console.debug('scheduled task', r.data.ocs.data.task)})
*
* @param {string} appId the scheduling app id
* @param {string} identifier the task identifier
* @param {string} taskType the task type class
* @param {string} inputText optional initial input text
* @param {boolean} isInsideViewer Should be true if this function is called while the Viewer is displayed
* @param {object} params parameters for the assistant
* @param {string} params.appId the scheduling app id
* @param {string} params.identifier the task identifier
* @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
* @return {Promise<unknown>}
*/
export async function openAssistantForm(appId, identifier = '', taskType = null, inputText = '', isInsideViewer = undefined) {
export async function openAssistantForm({ appId, identifier = '', taskType = null, input = '', isInsideViewer = 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 @@ -30,7 +36,7 @@ export async function openAssistantForm(appId, identifier = '', taskType = null,
const view = new View({
propsData: {
isInsideViewer,
input: inputText,
input,
selectedTaskTypeId: taskType,
},
}).$mount(modalElement)
Expand Down Expand Up @@ -143,13 +149,22 @@ async function openAssistantResult(task) {
input: task.input,
output: task.output,
selectedTaskTypeId: task.type,
readonly: true,
},
}).$mount(modalElement)

view.$on('cancel', () => {
view.$destroy()
})
view.$on('submit', (data) => {
view.$destroy()
scheduleTask(task.appId, task.identifier, data.taskTypeId, data.input)
.then((response) => {
console.debug('scheduled task', response.data?.ocs?.data?.task)
})
.catch(error => {
console.error('Assistant scheduling error', error)
})
})
}

async function addAssistantMenuEntry() {
Expand All @@ -168,7 +183,7 @@ async function addAssistantMenuEntry() {
}).$mount(menuEntry)

view.$on('click', () => {
openAssistantForm('textprocessing_assistant')
openAssistantForm({ appId: 'textprocessing_assistant' })
.then(r => {
console.debug('scheduled task', r)
})
Expand All @@ -177,6 +192,7 @@ async function addAssistantMenuEntry() {

/**
* Expose OCA.TPAssistant.openTextProcessingModal to let apps use the assistant
* and add a header right menu entry
*/
function init() {
if (!OCA.TPAssistant) {
Expand Down
89 changes: 73 additions & 16 deletions src/components/AssistantForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,48 @@
:link-autocomplete="false" />
<NcRichContenteditable
v-if="myOutput"
ref="output"
:value.sync="myOutput"
class="editable-output"
:multiline="true"
:disabled="loading"
:placeholder="t('textprocessing_assistant', 'Result')"
:link-autocomplete="false" />
<NcButton
v-if="showSubmit"
class="submit-button"
:disabled="!canSubmit"
:aria-label="t('textprocessing_assistant', 'Submit assistant task')"
:title="t('textprocessing_assistant', 'Submit')"
@click="onSubmit">
{{ selectedTaskType.name }}
<template #icon>
<CreationIcon />
</template>
</NcButton>
<div class="footer">
<NcButton
v-if="showSubmit"
:type="submitButtonType"
class="submit-button"
:disabled="!canSubmit"
:aria-label="t('textprocessing_assistant', 'Submit assistant task')"
:title="t('textprocessing_assistant', 'Submit')"
@click="onSubmit">
{{ submitButtonLabel }}
<template #icon>
<CreationIcon />
</template>
</NcButton>
<NcButton
v-if="showCopy"
type="primary"
class="copy-button"
:aria-label="t('textprocessing_assistant', 'Copy task output')"
:title="t('textprocessing_assistant', 'Copy')"
@click="onCopy">
{{ t('textprocessing_assistant', 'Copy') }}
<template #icon>
<ClipboardCheckOutlineIcon v-if="copied"
class="success-icon" />
<ContentCopyIcon v-else />
</template>
</NcButton>
</div>
</div>
</template>

<script>
import ContentCopyIcon from 'vue-material-design-icons/ContentCopy.vue'
import ClipboardCheckOutlineIcon from 'vue-material-design-icons/ClipboardCheckOutline.vue'
import CreationIcon from 'vue-material-design-icons/Creation.vue'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
Expand All @@ -55,6 +75,11 @@ import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import VueClipboard from 'vue-clipboard2'
import Vue from 'vue'
Vue.use(VueClipboard)
export default {
name: 'AssistantForm',
Expand All @@ -63,6 +88,8 @@ export default {
NcRichContenteditable,
NcSelect,
CreationIcon,
ContentCopyIcon,
ClipboardCheckOutlineIcon,
},
props: {
input: {
Expand All @@ -89,6 +116,7 @@ export default {
loading: false,
taskTypes: [],
mySelectedTaskTypeId: this.selectedTaskTypeId,
copied: false,
}
},
computed: {
Expand All @@ -98,12 +126,21 @@ export default {
}
return this.taskTypes.find(tt => tt.id === this.mySelectedTaskTypeId)
},
submitButtonType() {
return this.myOutput.trim() ? 'secondary' : 'primary'
},
showSubmit() {
return this.selectedTaskType && this.myOutput.trim() === ''
return this.selectedTaskType
},
canSubmit() {
return this.selectedTaskType && !!this.myInput.trim()
},
submitButtonLabel() {
return this.myOutput.trim() ? t('textprocessing_assistant', 'Try again') : this.selectedTaskType.name
},
showCopy() {
return !!this.myOutput.trim()
},
},
mounted() {
this.getTaskTypes()
Expand All @@ -128,7 +165,20 @@ export default {
this.$emit('cancel')
},
onSubmit() {
this.$emit('submit', { input: this.myInput, taskTypeId: this.mySelectedTaskTypeId })
this.$emit('submit', { input: this.myInput.trim(), taskTypeId: this.mySelectedTaskTypeId })
},
async onCopy() {
try {
const container = this.$refs.output.$el
await this.$copyText(this.myOutput.trim(), container)
this.copied = true
setTimeout(() => {
this.copied = false
}, 5000)
} catch (error) {
console.error(error)
showError(t('textprocessing_assistant', 'Result could not be copied to clipboard'))
}
},
},
}
Expand Down Expand Up @@ -172,8 +222,15 @@ export default {
align-self: start;
}
.submit-button {
align-self: end;
.footer {
width: 100%;
display: flex;
justify-content: end;
gap: 4px;
}
.success-icon {
color: var(--color-success);
}
}
</style>
3 changes: 2 additions & 1 deletion src/components/AssistantHeaderMenuEntry.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div id="assistant"
class="header-menu">
class="header-menu"
:title="t('textprocessing_assistant', 'Nextcloud assistant')">
<a
href="#"
@click="$emit('click')">
Expand Down

0 comments on commit 94e499c

Please sign in to comment.