Skip to content

Commit

Permalink
feat: transfer table ownership frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
enjeck committed Dec 13, 2023
1 parent 44272dd commit 91bdeae
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/modules/main/sections/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
</template>
{{ t('tables', 'Edit table') }}
</NcActionButton>
<NcActionButton v-if="ownsTable(table) "
:close-after-click="true"
@click="emit('tables:table:transfer', table.id)">
<template #icon>
<IconRename :size="20" decorative />
</template>
{{ t('tables', 'Transfer table') }}
</NcActionButton>
<NcActionButton v-if="canManageElement(table) "
:close-after-click="true"
@click="$emit('create-view')">
Expand Down Expand Up @@ -92,6 +100,14 @@
</template>
{{ t('tables', 'Edit table') }}
</NcActionButton>
<NcActionButton v-if="ownsTable(table) "
:close-after-click="true"
@click="emit('tables:table:transfer', table.id)">
<template #icon>
<IconRename :size="20" decorative />
</template>
{{ t('tables', 'Transfer table') }}
</NcActionButton>
<NcActionButton v-if="canManageElement(table) "
:close-after-click="true"
@click="$emit('create-view')">
Expand Down
6 changes: 6 additions & 0 deletions src/modules/modals/Modals.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@close="importToElement = null" />
<EditTable :table-id="editTable" :show-modal="editTable !== null" @close="editTable = null" />
<TransferTable :table="tableToTransfer" :show-modal="tableToTransfer !== null" @close="tableToTransfer = null" />
</div>
</template>
Expand All @@ -50,6 +51,7 @@ import DeleteTable from './DeleteTable.vue'
import CreateTable from './CreateTable.vue'
import DeleteView from './DeleteView.vue'
import EditTable from './EditTable.vue'
import TransferTable from './TransferTable.vue'
export default {
components: {
Expand All @@ -65,6 +67,7 @@ export default {
DeleteColumn,
CreateRow,
DeleteTable,
TransferTable,
},
data() {
Expand All @@ -82,6 +85,7 @@ export default {
tableToDelete: null,
viewToDelete: null,
editTable: null,
tableToTransfer: null,
}
},
Expand All @@ -90,6 +94,7 @@ export default {
subscribe('tables:table:create', () => { this.showModalCreateTable = true })
subscribe('tables:table:delete', table => { this.tableToDelete = table })
subscribe('tables:table:edit', tableId => { this.editTable = tableId })
subscribe('tables:table:transfer', table => { this.tableToTransfer = table })
// views
subscribe('tables:view:reload', () => { this.reload(true) })
Expand Down Expand Up @@ -136,6 +141,7 @@ export default {
unsubscribe('tables:modal:import', element => { this.importToElement = element })
unsubscribe('tables:table:delete', table => { this.tableToDelete = table })
unsubscribe('tables:table:edit', tableId => { this.editTable = tableId })
unsubscribe('tables:table:transfer', table => { this.tableToTransfer = table })
},
}
</script>
107 changes: 107 additions & 0 deletions src/modules/modals/TransferTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<template>
<NcModal v-if="showModal"
size="normal"
@close="actionCancel">
<div class="modal__content">
<div class="row">
<div class="col-4">
<h2>{{ t('tables', 'Transfer table') }}</h2>
</div>
</div>
<div class="row">
<TransferForm :newOwnerUserId="newOwnerUserId" @add="addTransfer"/>

Check warning on line 12 in src/modules/modals/TransferTable.vue

View workflow job for this annotation

GitHub Actions / eslint

Attribute ':newOwnerUserId' must be hyphenated

Check failure on line 12 in src/modules/modals/TransferTable.vue

View workflow job for this annotation

GitHub Actions / eslint

Expected a space before '/>', but not found
</div>
<div class="row">
<div class="fix-col-4 space-T justify-between">
<NcButton v-if="!prepareTransferTable" type="error" @click="prepareTransferTable = true">
{{ t('tables', 'Transfer') }}
</NcButton>
<NcButton v-if="prepareTransferTable"
:wide="true"
type="error"
@click="transferMe">
{{ t('tables', 'I really want to transfer this table!') }}
</NcButton>
</div>
</div>
</div>
</NcModal>
</template>

<script>
import { NcModal, NcButton } from '@nextcloud/vue'
import TransferForm from '../sidebar/partials/TransferForm.vue'
import shareAPI from '../sidebar/mixins/shareAPI.js'
import { showSuccess } from '@nextcloud/dialogs'
import '@nextcloud/dialogs/dist/index.css'
import { mapGetters } from 'vuex'
import { getCurrentUser } from '@nextcloud/auth'
import permissionsMixin from '../../shared/components/ncTable/mixins/permissionsMixin.js'
export default {
name: 'TransferTable',
components: {
NcModal,
NcButton,
TransferForm,
},
mixins: [shareAPI, permissionsMixin],
props: {
showModal: {
type: Boolean,
default: false,
},
table: {
type: Object,
default: null,
},
},
data() {
return {
prepareTransferTable: false,
loading: false,
newOwnerUserId: '',
}
},
computed: {
...mapGetters(['activeElement', 'isView']),
getTranslatedDescription() {
return t('tables', 'Do you really want to transfer the table "{table}"?', { table: this.table?.title })
},
},
methods: {
actionCancel() {
this.reset()
this.$emit('close')
},
reset() {
this.prepareDeleteTable = false
},
async transferMe() {
console.info(this.table)
console.info(getCurrentUser().uid)
const transferId = this.table.id
let activeTableId
if (this.activeElement){

Check failure on line 85 in src/modules/modals/TransferTable.vue

View workflow job for this annotation

GitHub Actions / eslint

Missing space before opening brace
activeTableId = this.isView ? this.activeElement.id : this.activeElement.tableId
this.prepareTransferTable = false
}

Check failure on line 88 in src/modules/modals/TransferTable.vue

View workflow job for this annotation

GitHub Actions / eslint

Trailing spaces not allowed
const res = await this.$store.dispatch('transferTable', { tableId: this.table.id, newOwnerUserId: 'test', userId: getCurrentUser().uid})

Check failure on line 89 in src/modules/modals/TransferTable.vue

View workflow job for this annotation

GitHub Actions / eslint

Multiple spaces found before 'userId'

Check failure on line 89 in src/modules/modals/TransferTable.vue

View workflow job for this annotation

GitHub Actions / eslint

A space is required before '}'
if (res) {
showSuccess(t('tables', 'Table "{emoji}{table}" transfered', { emoji: this.table?.icon ? this.table?.icon + ' ' : '', table: this.table?.title }))
// if the actual table was transfered, go to startpage
if (transferId === activeTableId) {
await this.$router.push('/').catch(err => err)
}
this.actionCancel()
}
},
async addTransfer(id) {
this.newOwnerUserId = id
},
},
}
</script>
8 changes: 8 additions & 0 deletions src/modules/navigation/partials/NavigationTableItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
</template>
{{ t('tables', 'Edit table') }}
</NcActionButton>
<NcActionButton v-if="ownsTable(table)"
:close-after-click="true"
@click="emit('tables:table:transfer', table.id)">
<template #icon>
<IconRename :size="20" decorative />
</template>
{{ t('tables', 'Transfer table') }}
</NcActionButton>
<NcActionButton v-if="canManageElement(table)"
:close-after-click="true"
@click="createView">
Expand Down
187 changes: 187 additions & 0 deletions src/modules/sidebar/partials/TransferForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<template>
<div class="row space-B">
<h3>{{ t('tables', 'Share with accounts') }}</h3>
<NcSelect id="transfer-ownership-select" style="width: 100%;" :loading="loading" :options="options"
:placeholder="t('tables', 'User…')" :searchable="true" label="displayName" @search="asyncFind">
<template #no-options>
{{ t('tables', 'No recommendations. Start typing.') }}
</template>
<template #noResult>
{{ noResultText }}
</template>
</NcSelect>
</div>
</template>

<script>
import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import axios from '@nextcloud/axios'
import debounce from 'debounce'
import { NcSelect } from '@nextcloud/vue'
import { mapState } from 'vuex'
import formatting from '../../../shared/mixins/formatting.js'
import ShareTypes from '../mixins/shareTypesMixin.js'
export default {
name: 'TransferForm',
components: {
NcSelect,
},
mixins: [ShareTypes, formatting],
props: {
newOwnerUserId: {
type: String,
default: '',
},
},
data() {
return {
query: '',
loading: false,
minSearchStringLength: 1,
maxAutocompleteResults: 20,
recommendations: [],
suggestions: [],
}
},
computed: {
...mapState(['tables', 'tablesLoading']),
isValidQuery() {
return this.query && this.query.trim() !== '' && this.query.length > this.minSearchStringLength
},
options() {
if (this.isValidQuery) {
return this.suggestions
}
return this.recommendations
},
noResultText() {
if (this.loading) {
return t('tables', 'Searching …')
}
return t('tables', 'No elements found.')
},
},
mounted() {
this.getRecommendations()
},
methods: {
addShare(id) {
this.newOwnerUserId = id

Check failure on line 80 in src/modules/sidebar/partials/TransferForm.vue

View workflow job for this annotation

GitHub Actions / eslint

Unexpected mutation of "newOwnerUserId" prop
},
async asyncFind(query) {
this.query = query.trim()
if (this.isValidQuery) {
this.loading = true
await this.debounceGetSuggestions(query)
}
},
async getSuggestions(search) {
this.loading = true
const shareType = [
this.SHARE_TYPES.SHARE_TYPE_USER,
]
const request = await axios.get(generateOcsUrl('apps/files_sharing/api/v1/sharees'), {
params: {
format: 'json',
itemType: 'file',
search,
perPage: this.maxAutocompleteResults,
shareType,
},
})
const data = request.data.ocs.data
const exact = data.exact
data.exact = []
const rawExactSuggestions = Object.values(exact).reduce((arr, elem) => arr.concat(elem), [])
const rawSuggestions = Object.values(data).reduce((arr, elem) => arr.concat(elem), [])
const exactSuggestions = this.filterOutCurrentUser(rawExactSuggestions)
.map(share => this.formatForSelect(share))
const suggestions = this.filterOutCurrentUser(rawSuggestions)
.map(share => this.formatForSelect(share))
this.suggestions = exactSuggestions.concat(suggestions)
this.loading = false
console.info('suggestions', this.suggestions)
},
debounceGetSuggestions: debounce(function (...args) {

Check failure on line 125 in src/modules/sidebar/partials/TransferForm.vue

View workflow job for this annotation

GitHub Actions / eslint

Unexpected space before function parentheses
this.getSuggestions(...args)
}, 300),
async getRecommendations() {
this.loading = true
const request = await axios.get(generateOcsUrl('apps/files_sharing/api/v1/sharees_recommended'), {
params: {
format: 'json',
itemType: 'file',
},
})
const exact = request.data.ocs.data.exact
// flatten array of arrays
const rawRecommendations = Object.values(exact).reduce((arr, elem) => arr.concat(elem), [])
this.recommendations = this.filterOutCurrentUser(rawRecommendations)
.map(share => this.formatForSelect(share))
this.loading = false
console.info('recommendations', this.recommendations)
},

Check failure on line 151 in src/modules/sidebar/partials/TransferForm.vue

View workflow job for this annotation

GitHub Actions / eslint

More than 1 blank line not allowed
filterOutCurrentUser(shares) {
return shares.reduce((arr, share) => {
if (typeof share !== 'object') {
return arr
}
try {
if (share.value.shareWith === getCurrentUser().uid) {
return arr
}
arr.push(share)
} catch {
return arr
}
return arr
}, [])
},
formatForSelect(result) {
return {
user: result.uuid || result.value.shareWith,
displayName: result.name || result.label,
icon: 'icon-user',
key: result.uuid || result.label,
}
},
},
}
</script>

<style lang="scss" scoped>
.multiselect {
width: 100% !important;
max-width: 100% !important;
}
</style>
3 changes: 3 additions & 0 deletions src/shared/components/ncTable/mixins/permissionsMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { getCurrentUser } from '@nextcloud/auth'

export default {
methods: {
ownsTable(element) {
return element?.ownership === getCurrentUser().uid
},
// views have the flag manageTable set if the user has manage rights for the corresponding table
canManageTable(element) {
if (!element.isShared) {
Expand Down
Loading

0 comments on commit 91bdeae

Please sign in to comment.