112112 @click =" actionDelete" >
113113 {{ t('deck', 'Delete board') }}
114114 </NcActionButton >
115+
116+ <NcActionButton v-if =" canLeave && !isDueSubmenuActive"
117+ icon =" icon-delete"
118+ :close-after-click =" true"
119+ @click =" actionLeave" >
120+ <template #icon >
121+ <LeaveIcon :size =" 20" decorative />
122+ </template >
123+ {{ t('deck', 'Leave board') }}
124+ </NcActionButton >
115125 </template >
116126 </NcAppNavigationItem >
117127 <div v-else-if =" editing" class =" board-edit" >
@@ -152,12 +162,15 @@ import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcButton
152162import ClickOutside from ' vue-click-outside'
153163import ArchiveIcon from ' vue-material-design-icons/Archive.vue'
154164import CloneIcon from ' vue-material-design-icons/ContentDuplicate.vue'
165+ import LeaveIcon from ' vue-material-design-icons/ExitRun.vue'
155166import AccountIcon from ' vue-material-design-icons/Account.vue'
156167import CloseIcon from ' vue-material-design-icons/Close.vue'
157168import CheckIcon from ' vue-material-design-icons/Check.vue'
158169
159170import { loadState } from ' @nextcloud/initial-state'
160171import { emit } from ' @nextcloud/event-bus'
172+ import { getCurrentUser } from ' @nextcloud/auth'
173+ import { showError } from ' @nextcloud/dialogs'
161174
162175import isTouchDevice from ' ../../mixins/isTouchDevice.js'
163176import BoardCloneModal from ' ./BoardCloneModal.vue'
@@ -178,6 +191,7 @@ export default {
178191 CloneIcon,
179192 CloseIcon,
180193 CheckIcon,
194+ LeaveIcon,
181195 BoardCloneModal,
182196 },
183197 directives: {
@@ -207,6 +221,7 @@ export default {
207221 updateDueSetting: null ,
208222 canCreate: canCreateState,
209223 cloneModalOpen: false ,
224+ currentUser: getCurrentUser (),
210225 }
211226 },
212227 computed: {
@@ -228,6 +243,9 @@ export default {
228243 canManage () {
229244 return this .board .permissions .PERMISSION_MANAGE
230245 },
246+ canLeave () {
247+ return this .board .acl ? .find ((acl ) => acl .participant .uid === this .currentUser ? .uid && acl .participant .type === 0 ) !== undefined
248+ },
231249 dueDateReminderIcon () {
232250 if (this .board .settings [' notify-due' ] === ' all' ) {
233251 return ' icon-sound'
@@ -315,6 +333,33 @@ export default {
315333 true ,
316334 )
317335 },
336+ actionLeave () {
337+ OC .dialogs .confirmDestructive (
338+ t (' deck' , ' Are you sure you want to leave the board {title}?' , { title: this .board .title }),
339+ t (' deck' , ' Leave the board?' ),
340+ {
341+ type: OC .dialogs .YES_NO_BUTTONS ,
342+ confirm: t (' deck' , ' Leave' ),
343+ confirmClasses: ' error' ,
344+ cancel: t (' deck' , ' Cancel' ),
345+ },
346+ (result ) => {
347+ if (result) {
348+ this .loading = true
349+ this .boardApi .leaveBoard (this .board )
350+ .then (() => {
351+ this .loading = false
352+ this .$store .dispatch (' removeBoard' , this .board )
353+ })
354+ .catch (() => {
355+ showError (t (' deck' , ' Failed to leave the board' ))
356+ this .loading = false
357+ })
358+ }
359+ },
360+ true ,
361+ )
362+ },
318363 actionDetails () {
319364 this .$router .push ({ name: ' board.details' , params: { id: this .board .id } })
320365 },
0 commit comments