Skip to content

Commit

Permalink
feat: Text processing assistant integration
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliushaertl committed Aug 4, 2023
1 parent c998357 commit a3ffbd8
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 0 deletions.
222 changes: 222 additions & 0 deletions src/components/Assistant.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<!--
- @copyright Copyright (c) 2023 Julius Härtl <[email protected]>
-
- @author Julius Härtl <[email protected]>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<div class="text-assistant" v-if="showAssistant">

Check warning on line 22 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Attribute "v-if" should go before "class"
<h4>
<span class="assistant-bubble">
<CreationIcon :size="16" class="icon" />
<span>{{ t('text', 'Nextcloud assistant') }}</span>
</span>
<NcActions :aria-label="t('text', 'Run assistant tasks')">
<template #icon>
<CreationIcon :size="20" class="icon" />
</template>
<NcActionButton v-for="provider in providers" :key="provider.task" @click="openAssistantForm(provider.task)">
<template #icon>

Check warning on line 33 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Require self-closing on HTML elements (<template>)
</template>
{{ provider.name }}
</NcActionButton>
</NcActions>
</h4>
<ul>
<NcListItem v-for="task in tasks"

Check failure on line 40 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Custom elements in iteration require 'v-bind:key' directives
:name="task.title"
:bold="false"
:force-display-actions="true">
<template #icon>
<CheckIcon v-if="task.status === STATUS_SUCCESSFUL" :size="20" />
<AlertCircleOutline v-else-if="task.status === STATUS_FAILED" :size="20" />
<ClockOutline v-else :size="20" />
</template>
<template #actions>
<NcActionButton v-if="task.status === STATUS_SUCCESSFUL" :title="task.output">
<template #icon>
<TextBoxPlusOutlineIcon :size="20" />
</template>
{{ t('text', 'Insert result') }}
</NcActionButton>
</template>
</NcListItem>
</ul>
</div>
</template>
<script>
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'
import CreationIcon from 'vue-material-design-icons/Creation.vue'
import ClockOutline from 'vue-material-design-icons/ClockOutline.vue'
import CheckIcon from 'vue-material-design-icons/Check.vue'
import TextBoxPlusOutlineIcon from 'vue-material-design-icons/TextBoxPlusOutline.vue'
const STATUS_FAILED = 4;

Check failure on line 70 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Extra semicolon
const STATUS_SUCCESSFUL = 3;

Check failure on line 71 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Extra semicolon
const STATUS_RUNNING = 2;

Check failure on line 72 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Extra semicolon
const STATUS_SCHEDULED = 1;

Check failure on line 73 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Extra semicolon
const STATUS_UNKNOWN = 0;

Check failure on line 74 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Extra semicolon

Check failure on line 76 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

More than 1 blank line not allowed
import { NcActions, NcActionButton, NcButton, NcListItem } from '@nextcloud/vue'

Check failure on line 77 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Import in body of module; reorder to top
import {

Check failure on line 78 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Import in body of module; reorder to top
useEditorMixin,
useIsRichWorkspaceMixin,
useFileMixin,
useIsPublicMixin,
} from './Editor.provider.js'
export default {
name: 'Assistant',
components: {
AlertCircleOutline,
CreationIcon,
ClockOutline,
CheckIcon,
TextBoxPlusOutlineIcon,
NcActions,
NcActionButton,
NcButton,

Check failure on line 95 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

The "NcButton" component has been registered but not used
NcListItem,
},
mixins: [
useEditorMixin,
useIsPublicMixin,
useIsRichWorkspaceMixin,
useFileMixin,
],
data() {
return {
providers: OCP.InitialState.loadState('text','textprocessing'),
selection: '',
tasks: [],
STATUS_FAILED,
STATUS_RUNNING,
STATUS_SCHEDULED,
STATUS_SUCCESSFUL,
STATUS_UNKNOWN,
/** {

Check warning on line 115 in src/components/Assistant.vue

View workflow job for this annotation

GitHub Actions / eslint

Should have no text on the "0th" line (after the `/**`)
"id": 9,
"type": "OCP\\TextProcessing\\HeadlineTaskType",
"status": 1,
"userId": "admin",
"appId": "text",
"input": "25 April to 10 May 2022 \"Open Source Programme Office\" at the European Commission organizes NextGov Hackathon and awards up to 5000 EUR for improvements to Nextcloud apps and security.[43][44][45]Nextcloud is a suite of client-server software for creating and using file hosting services. Nextcloud provides functionality similar to Dropbox, Office 365 or Google Drive when used with integrated office suites Collabora Online or OnlyOffice. It can be hosted in the cloud or on-premises. It is scalable, from home office software based on the low cost Raspberry Pi, all the way through to full sized data centers that support millions of users.[8][9][10] Translations in 60 languages exist for web interface and client applications.[11] ",
"output": null,
"identifier": "text-file:1486"
}*/
}
},
computed: {
showAssistant() {
return !this.$isRichWorkspace && !this.$isPublic && window?.OCA?.TPAssistant?.openAssistantForm
},
identifier() {
return 'text-file:' + this.$file.fileId
},
},
beforeMount() {
if (!this.showAssistant) {
return
}
this.$editor.on('selectionUpdate', this.onSelection)
this.fetchTasks()
},
beforeDestroy() {
if (!this.showAssistant) {
return
}
this.$editor.off('selectionUpdate', this.onSelection)
},
methods: {
async fetchTasks() {
const result = await axios.get(generateOcsUrl('/textprocessing/tasks/app/text') + '?identifier=' + this.identifier)
const taskMap = {}
for (const index in this.providers) {
const provider = this.providers[index]
taskMap[provider.task] = provider
}
this.tasks = result.data.ocs.data.tasks.map((task) => {
return {
...task,
title: taskMap[task.type].name,
}
})
},
onSelection() {
const { state } = this.$editor
const { from, to } = state.selection
this.selection = state.doc.textBetween(from, to, ' ')
},
async openAssistantForm(taskType = null) {
try {
await window.OCA.TPAssistant.openAssistantForm('text', this.identifier, taskType, this.selection, true)
this.fetchTasks()
} catch (e) {}
},
},
}
</script>
<style scoped lang="scss">
.text-assistant {
position: fixed;
bottom: 0;
left: 0;
margin: calc(var(--default-grid-baseline) * 3);
overflow: auto;
width: 250px;
max-height: 200px;
}
h4 {
display: flex;
align-items: center;
justify-items: center;
justify-content: space-between;
position: sticky;
top: 0;
z-index: 1;
}
.assistant-bubble {
display: flex;
gap: 8px;
background-color: var(--color-primary-element-light);
border-radius: var(--border-radius-rounded);
padding: 2px 8px;
.icon {
color: var(--color-primary);
}
}
ul {
width: calc(100% - 16px);
& :deep(.list-item) {
padding-top: 0;
padding-bottom: 0;
}
}
</style>
3 changes: 3 additions & 0 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
:content="syncError.data.outsideChange"
:is-rich-editor="isRichEditor" />
</Wrapper>
<Assistant v-if="$editor"/>
</div>
</template>

Expand Down Expand Up @@ -119,6 +120,7 @@ import Status from './Editor/Status.vue'
import MainContainer from './Editor/MainContainer.vue'
import Wrapper from './Editor/Wrapper.vue'
import SkeletonLoading from './SkeletonLoading.vue'
import Assistant from './Assistant.vue'
export default {
name: 'Editor',
Expand All @@ -132,6 +134,7 @@ export default {
MenuBar,
Reader: () => import(/* webpackChunkName: "editor" */'./Reader.vue'),
Status,
Assistant,
},
mixins: [
isMobile,
Expand Down

0 comments on commit a3ffbd8

Please sign in to comment.