Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[full-ci] Add remove/add users to group batch actions #8553

Merged
merged 16 commits into from
Mar 9, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Add and remove users from groups batch actions

We've introduced add and remove users from groups batch actions to the admin-settings app.

https://github.com/owncloud/web/pull/8553
https://github.com/owncloud/web/issues/8559
https://github.com/owncloud/web/issues/8558
https://github.com/owncloud/web/issues/8472
55 changes: 50 additions & 5 deletions packages/web-app-admin-settings/src/components/AppTemplate.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<main class="oc-flex oc-height-1-1 app-content oc-width-1-1">
<main ref="appBarRef" class="oc-flex oc-height-1-1 app-content oc-width-1-1">
<app-loading-spinner v-if="loading" />
<template v-else>
<div id="admin-settings-wrapper" class="oc-width-expand">
Expand All @@ -24,7 +24,16 @@
</oc-button>
</div>
</div>
<slot name="topbarActions" class="oc-flex-1 oc-flex oc-flex-start" />
<div class="oc-flex oc-flex-middle oc-mt-xs">
<slot name="topbarActions" class="oc-flex-1 oc-flex oc-flex-start" />
<batch-actions
v-if="showBatchActions"
class="oc-ml-s"
:items="batchActionItems"
:actions="batchActions"
:limited-screen-space="limitedScreenSpace"
/>
</div>
</div>
<slot name="mainContent" />
</div>
Expand All @@ -49,14 +58,16 @@
<script lang="ts">
import AppLoadingSpinner from 'web-pkg/src/components/AppLoadingSpinner.vue'
import SideBar from 'web-pkg/src/components/sideBar/SideBar.vue'
import { defineComponent } from 'vue'
import BatchActions from 'web-pkg/src/components/BatchActions.vue'
import { defineComponent, onBeforeUnmount, onMounted, PropType, ref, unref } from 'vue'
import { eventBus, useAppDefaults } from 'web-pkg'
import { SideBarEventTopics } from 'web-pkg/src/composables/sideBar'

export default defineComponent({
components: {
SideBar,
AppLoadingSpinner
AppLoadingSpinner,
BatchActions
},
props: {
breadcrumbs: {
Expand Down Expand Up @@ -92,9 +103,33 @@ export default defineComponent({
required: false,
type: Boolean,
default: false
},
showBatchActions: {
type: Boolean,
required: false,
default: false
},
batchActionItems: {
type: Array as PropType<any>,
required: false,
default: () => []
},
batchActions: {
type: Array as PropType<any>,
required: false,
default: () => []
}
},
setup() {
setup(props) {
const appBarRef = ref()
const limitedScreenSpace = ref(false)
const onResize = () => {
limitedScreenSpace.value = props.sideBarOpen
? window.innerWidth <= 1400
: window.innerWidth <= 1000
}
const resizeObserver = new ResizeObserver(onResize as ResizeObserverCallback)

const closeSideBar = () => {
eventBus.publish(SideBarEventTopics.close)
}
Expand All @@ -104,7 +139,17 @@ export default defineComponent({
const selectPanel = (panel) => {
eventBus.publish(SideBarEventTopics.setActivePanel, panel)
}

onMounted(() => {
resizeObserver.observe(unref(appBarRef))
})
onBeforeUnmount(() => {
resizeObserver.unobserve(unref(appBarRef))
})

return {
appBarRef,
limitedScreenSpace,
closeSideBar,
toggleSideBar,
selectPanel,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<template>
<oc-modal
:title="title"
:message="message"
AlexAndBear marked this conversation as resolved.
Show resolved Hide resolved
:button-cancel-text="$gettext('Cancel')"
:button-confirm-text="$gettext('Confirm')"
:button-confirm-disabled="!selectedOptions.length"
@cancel="$emit('cancel')"
@confirm="$emit('confirm', { users, groups: selectedOptions })"
>
<template #content>
<p class="oc-modal-body-message" v-text="message" />
<GroupSelect
:selected-groups="selectedOptions"
:group-options="groups"
@selected-option-change="changeSelectedGroupOption"
/>
</template>
</oc-modal>
</template>

<script lang="ts">
import { defineComponent, PropType, ref } from 'vue'
import { Group, User } from 'web-client/src/generated'
import GroupSelect from './GroupSelect.vue'

export default defineComponent({
name: 'GroupsModal',
components: { GroupSelect },
props: {
title: {
type: String,
required: true
},
message: {
type: String,
required: true
},
groups: {
AlexAndBear marked this conversation as resolved.
Show resolved Hide resolved
type: Array as PropType<Group[]>,
required: true
},
users: {
type: Array as PropType<User[]>,
required: true
}
},
emits: ['confirm', 'cancel'],
setup() {
const selectedOptions = ref([])
const changeSelectedGroupOption = (options: Group[]) => {
selectedOptions.value = options
}
return {
selectedOptions,
changeSelectedGroupOption
}
}
})
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ import { computed, defineComponent, PropType, ref, unref } from 'vue'
import * as EmailValidator from 'email-validator'
import UserInfoBox from './UserInfoBox.vue'
import CompareSaveDialog from 'web-pkg/src/components/sideBar/CompareSaveDialog.vue'
import GroupSelect from './GroupSelect.vue'
import GroupSelect from '../GroupSelect.vue'
import QuotaSelect from 'web-pkg/src/components/QuotaSelect.vue'
import { cloneDeep } from 'lodash-es'
import { Group, User } from 'web-client/src/generated'
Expand Down Expand Up @@ -156,9 +156,7 @@ export default defineComponent({
})
const groupOptions = computed(() => {
const { memberOf: selectedGroups } = unref(editUser)
return props.groups
.filter((g) => !selectedGroups.some((s) => s.id === g.id))
.sort((a, b) => a.displayName.localeCompare(b.displayName))
return props.groups.filter((g) => !selectedGroups.some((s) => s.id === g.id))
})

const isLoginInputDisabled = computed(() => currentUser.uuid === (props.user as User).id)
Expand Down Expand Up @@ -239,7 +237,7 @@ export default defineComponent({
changeSelectedQuotaOption(option) {
this.editUser.drive.quota.total = option.value
},
changeSelectedGroupOption(option: Group) {
changeSelectedGroupOption(option: Group[]) {
this.editUser.memberOf = option
},
async validateUserName() {
Expand Down
25 changes: 25 additions & 0 deletions packages/web-app-admin-settings/src/mixins/users/addToGroups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { eventBus } from 'web-pkg/src/services/eventBus'
import { computed, Ref } from 'vue'
import { useGettext } from 'vue3-gettext'

export const useAddToGroups = (): { actions: Ref<unknown[]> } => {
const { $gettext } = useGettext()

const actions = computed((): unknown[] => [
{
name: 'add-to-groups',
icon: 'add',
componentType: 'button',
class: 'oc-users-actions-add-to-groups-trigger',
label: () => $gettext('Add to groups'),
isEnabled: ({ resources }) => resources.length > 0,
handler() {
eventBus.publish('app.admin-settings.users.actions.add-to-groups')
}
}
])

return {
actions
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { eventBus } from 'web-pkg/src/services/eventBus'
import { computed, Ref } from 'vue'
import { useGettext } from 'vue3-gettext'

export const useRemoveFromGroups = (): { actions: Ref<unknown[]> } => {
const { $gettext } = useGettext()

const actions = computed((): unknown[] => [
{
name: 'remove-users-from-groups',
icon: 'subtract',
componentType: 'button',
class: 'oc-users-actions-remove-from-groups-trigger',
label: () => $gettext('Remove from groups'),
isEnabled: ({ resources }) => resources.length > 0,
handler() {
eventBus.publish('app.admin-settings.users.actions.remove-from-groups')
}
}
])

return {
actions
}
}
12 changes: 6 additions & 6 deletions packages/web-app-admin-settings/src/views/Groups.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@
:side-bar-active-panel="sideBarActivePanel"
:side-bar-available-panels="sideBarAvailablePanels"
:side-bar-open="sideBarOpen"
:show-batch-actions="!!selectedGroups.length"
:batch-actions="batchActions"
:batch-action-items="selectedGroups"
>
<template #topbarActions>
<div class="admin-settings-app-bar-actions oc-mt-xs">
<div class="admin-settings-app-bar-actions">
<div v-if="selectedGroups.length" class="oc-flex oc-flex-middle">
<span v-text="selectedGroupsText" />
<oc-button
id="files-clear-selection"
id="groups-clear-selection"
v-oc-tooltip="$gettext('Clear selection')"
:aria-label="$gettext('Clear selection')"
class="oc-ml-m"
class="oc-ml-m oc-py-s"
appearance="outline"
@click="unselectAllGroups"
>
<oc-icon name="close" />
</oc-button>
<batch-actions class="oc-ml-s" :items="selectedGroups" :actions="batchActions" />
</div>
<div v-else>
<oc-button variation="primary" appearance="filled" @click="toggleCreateGroupModal">
Expand Down Expand Up @@ -72,7 +74,6 @@
import GroupsList from '../components/Groups/GroupsList.vue'
import CreateGroupModal from '../components/Groups/CreateGroupModal.vue'
import ContextActions from '../components/Groups/ContextActions.vue'
import BatchActions from 'web-pkg/src/components/BatchActions.vue'
import NoContentMessage from 'web-pkg/src/components/NoContentMessage.vue'
import {
computed,
Expand All @@ -99,7 +100,6 @@ export default defineComponent({
GroupsList,
NoContentMessage,
CreateGroupModal,
BatchActions,
ContextActions
},
mixins: [Delete],
Expand Down
30 changes: 6 additions & 24 deletions packages/web-app-admin-settings/src/views/Spaces.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
:side-bar-available-panels="sideBarAvailablePanels"
:side-bar-open="sideBarOpen"
:is-side-bar-header-compact="selectedSpaces.length === 1"
:show-batch-actions="!!selectedSpaces.length"
:batch-actions="batchActions"
:batch-action-items="selectedSpaces"
>
<template #sideBarHeader>
<space-info
Expand All @@ -17,23 +20,18 @@
/>
</template>
<template #topbarActions>
<div ref="appBarActionsRef" class="admin-settings-app-bar-actions oc-mt-xs">
<div class="admin-settings-app-bar-actions">
<div v-if="selectedSpaces.length >= 1" class="oc-flex oc-flex-middle">
<oc-button
id="files-clear-selection"
id="spaces-clear-selection"
v-oc-tooltip="$gettext('Clear selection')"
:aria-label="$gettext('Clear selection')"
class="oc-py-s"
appearance="outline"
@click="unselectAllSpaces"
>
<oc-icon name="close" />
</oc-button>
<batch-actions
class="oc-ml-s"
:items="selectedSpaces"
:actions="batchActions"
:limited-screen-space="limitedScreenSpace"
/>
</div>
</div>
</template>
Expand Down Expand Up @@ -104,7 +102,6 @@ import SpaceNoSelection from 'web-pkg/src/components/sideBar/Spaces/SpaceNoSelec
import ContextActions from '../components/Spaces/ContextActions.vue'
import MembersPanel from '../components/Spaces/SideBar/MembersPanel.vue'
import SpaceInfo from 'web-pkg/src/components/sideBar/Spaces/SpaceInfo.vue'
import BatchActions from 'web-pkg/src/components/BatchActions.vue'
import ActionsPanel from '../components/Spaces/SideBar/ActionsPanel.vue'
import Delete from 'web-pkg/src/mixins/spaces/delete'
import Disable from 'web-pkg/src/mixins/spaces/disable'
Expand All @@ -122,7 +119,6 @@ export default defineComponent({
NoContentMessage,
ContextActions,
SpaceInfo,
BatchActions,
QuotaModal
},
mixins: [Delete, Disable, Restore, EditQuota],
Expand Down Expand Up @@ -251,15 +247,6 @@ export default defineComponent({
].filter((p) => p.enabled)
})

const limitedScreenSpace = ref(false)
const appBarActionsRef = ref()
const onResize = () => {
limitedScreenSpace.value = unref(sideBarOpen)
? window.innerWidth <= 1280
: window.innerWidth <= 1000
}
const resizeObserver = new ResizeObserver(onResize)

onMounted(async () => {
await loadResourcesTask.perform()
loadResourcesEventToken.value = eventBus.subscribe('app.admin-settings.list.load', () => {
Expand All @@ -269,7 +256,6 @@ export default defineComponent({

calculateListHeaderPosition()
window.addEventListener('resize', calculateListHeaderPosition)
resizeObserver.observe(unref(appBarActionsRef))

updateQuotaForSpaceEventToken = eventBus.subscribe(
'app.admin-settings.spaces.space.quota.updated',
Expand All @@ -288,7 +274,6 @@ export default defineComponent({
'app.admin-settings.spaces.space.quota.updated',
updateQuotaForSpaceEventToken
)
resizeObserver.unobserve(unref(appBarActionsRef))
})

const quotaModalIsOpen = computed(() => instance.$data.$_editQuota_modalOpen)
Expand Down Expand Up @@ -316,9 +301,6 @@ export default defineComponent({
toggleSelectAllSpaces,
toggleSelectSpace,
unselectAllSpaces,
limitedScreenSpace,
appBarActionsRef,
onResize,
quotaModalIsOpen,
closeQuotaModal,
spaceQuotaUpdated
Expand Down
Loading