Skip to content

Commit

Permalink
Save status quo on app-provider enriched fileActions
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalwengerter committed Sep 21, 2021
1 parent fd9d9a1 commit 42fb8eb
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 62 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-new-fileactions
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Add AppProvider actions to fileactions

If the AppProvider within oCIS communicates a fitting application
for the mime type of a file, there are now additional actions in
the default actions and actions in the contextmenu and right sidebar.

https://github.com/owncloud/web/pull/5805
72 changes: 51 additions & 21 deletions packages/web-app-files/src/components/FilesList/ContextActions.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,50 @@
<template>
<ul id="oc-files-context-actions" class="uk-list oc-mt-s">
<div>
<div v-if="item.extension && appList.length > 0">
<ul id="oc-files-context-default-actions" class="uk-list oc-my-xs oc-files-context-actions">
<li v-for="(app, index) in appList" :key="`app-${index}`">
<oc-button
appearance="raw"
class="oc-text-bold"
@click="$_fileActions_openLink(app.name, item)"
>
<img :src="app.icon" :alt="app.name" class="oc-icon oc-icon-m" />
<span class="oc-files-context-action-label">{{ 'Open in ' + app.name }}</span>
</oc-button>
</li>
</ul>
<hr />
</div>
<template v-for="(section, i) in menuSections">
<li
v-for="(action, j) in section.items"
:key="`section-${section.name}-action-${j}`"
class="oc-files-context-action"
<ul
id="`oc-files-context-actions-${section.name}`"
:key="`section-${section.name}-list`"
class="uk-list oc-mt-s oc-files-context-actions"
>
<component
:is="action.componentType"
v-bind="getComponentProps(action, item)"
:class="['oc-text-bold', action.class]"
v-on="getComponentListeners(action, item)"
<li
v-for="(action, j) in section.items"
:key="`section-${section.name}-action-${j}`"
class="oc-files-context-action"
>
<oc-icon :name="action.icon" size="medium" />
<span class="oc-files-context-action-label">{{ action.label(item) }}</span>
<span
v-if="action.opensInNewWindow"
class="oc-invisible-sr"
v-text="$gettext('(Opens in new window)')"
/>
</component>
</li>
<component
:is="action.componentType"
v-bind="getComponentProps(action, item)"
:class="['oc-text-bold', action.class]"
v-on="getComponentListeners(action, item)"
>
<oc-icon :name="action.icon" size="medium" />
<span class="oc-files-context-action-label">{{ action.label(item) }}</span>
<span
v-if="action.opensInNewWindow"
class="oc-invisible-sr"
v-text="$gettext('(Opens in new window)')"
/>
</component>
</li>
</ul>
<hr v-if="i < menuSections.length - 1" :key="`section-${section.name}-separator`" />
</template>
</ul>
</div>
</template>

<script>
Expand Down Expand Up @@ -67,6 +88,9 @@ export default {
required: true
}
},
data: () => ({
appList: []
}),
computed: {
...mapGetters('Files', ['currentFolder']),
Expand Down Expand Up @@ -147,7 +171,13 @@ export default {
return [...this.$_showDetails_items].filter(item => item.isEnabled(this.filterParams))
}
},
mounted() {
this.loadApps()
},
methods: {
loadApps() {
this.appList = this.$_fileActions_loadApps(this.item)
},
getComponentProps(action, resource) {
if (action.componentType === 'router-link' && action.route) {
return {
Expand Down Expand Up @@ -188,7 +218,7 @@ export default {
</script>

<style lang="scss">
#oc-files-context-actions {
.oc-files-context-actions {
text-align: left;
white-space: normal;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<template>
<ul id="oc-files-actions-sidebar" class="uk-list oc-mt-s">
<ul id="oc-files-actions-sidebar" class="uk-list oc-mt-s oc-files-actions-sidebar-actions">
<li v-for="(app, index) in appList" :key="`app-${index}`" class="oc-py-xs">
<oc-button
appearance="raw"
class="oc-text-bold"
@click="$_fileActions_openLink(app.name, item)"
>
<img :src="app.icon" :alt="`Icon for ${app.name} app`" class="oc-icon oc-icon-m" />
<span class="oc-files-actions-sidebar-action-label">{{ 'Open in ' + app.name }}</span>
</oc-button>
</li>
<li v-for="(action, index) in actions" :key="`action-${index}`" class="oc-py-xs">
<component
:is="action.componentType"
Expand Down Expand Up @@ -32,6 +42,9 @@ export default {
return $gettext('Actions')
},
mixins: [FileActions],
data: () => ({
appList: []
}),
computed: {
...mapGetters('Files', ['highlightedFile', 'currentFolder']),
Expand All @@ -46,7 +59,13 @@ export default {
)
}
},
mounted() {
this.loadApps()
},
methods: {
loadApps() {
this.appList = this.$_fileActions_loadApps(this.highlightedFile)
},
getComponentProps(action, highlightedFile) {
if (action.componentType === 'router-link' && action.route) {
return {
Expand Down
34 changes: 33 additions & 1 deletion packages/web-app-files/src/mixins/fileActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export default {
},

methods: {
...mapGetters('External', ['getMimeTypes']),
...mapActions(['openFile']),

$_fileActions_openEditor(editor, filePath, fileId, mode) {
Expand Down Expand Up @@ -135,7 +136,16 @@ export default {
})
},

// returns the _first_ action from actions array
// which we now construct from available mime-types (app-provider)
// and existing, basic actions
$_fileActions_triggerDefaultAction(resource) {
const availableExternalAppActions = this.$_fileActions_loadApps(resource)

for (const action of availableExternalAppActions) {
action.handler = this.$_fileActions_openLink(action.name, resource)
}

let actions = this.$_fileActions_editorActions.concat(this.$_fileActions_systemActions)

actions = actions.filter(action => {
Expand All @@ -146,7 +156,29 @@ export default {
}) && action.canBeDefault
)
})
actions[0].handler(resource, actions[0].handlerData)

const finalActions = availableExternalAppActions.concat(actions)
// all things `handler` don't really work for external apps, yet
finalActions[0].handler(resource, finalActions[0].handlerData)
},

// returns an array of available external Apps
$_fileActions_loadApps(resource) {
const { mimeType } = resource
if (mimeType === undefined) {
return
}
return this.getMimeTypes()[mimeType].app_providers
},

$_fileActions_openLink(appName, resource) {
// also include the server name here?
const actionableId = resource.fileId.replaceAll('=', '')
const routeData = this.$router.resolve({
name: 'external-apps',
params: { app: appName, file_id: actionableId }
})
window.open(routeData.href, '_blank')
}
}
}
18 changes: 18 additions & 0 deletions packages/web-app-files/tests/__fixtures__/mimeTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export default {
'application/fileFormat1': {
app_providers: [
{ name: 'ExampleApp1Name', icon: 'https://www.example-app.com/assets/icon1.png' }
]
},
'application/fileFormat2': {
app_providers: [
{ name: 'ExampleApp2Name', icon: 'https://www.example-app.com/assets/icon2.png' }
]
},
'application/fileFormat3': {
app_providers: [
{ name: 'ExampleApp1Name', icon: 'https://www.example-app.com/assets/icon1.png' },
{ name: 'ExampleApp2Name', icon: 'https://www.example-app.com/assets/icon2.png' }
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ describe('ContextActions', () => {
}

describe('renders a list of actions', () => {
test.todo('if externalApps are available')
test.todo('if no externalApps are available')

it('for a file', () => {
const wrapper = getWrapper('files-personal', {
name: 'exampleFile',
Expand Down Expand Up @@ -163,6 +166,15 @@ function createStore(state) {
user
},
modules: {
External: {
state: {
...state
},
namespaced: true,
getters: {
getMimeTypes: () => ''
}
},
Files: {
state: {
...state
Expand Down
Loading

0 comments on commit 42fb8eb

Please sign in to comment.