diff --git a/changelog/unreleased/enhancement-spaces-list-in-admin-settings b/changelog/unreleased/enhancement-spaces-list-in-admin-settings index 2b4a3fb5aa1..d2c5bfd9540 100644 --- a/changelog/unreleased/enhancement-spaces-list-in-admin-settings +++ b/changelog/unreleased/enhancement-spaces-list-in-admin-settings @@ -15,4 +15,5 @@ https://github.com/owncloud/web/pull/8236 https://github.com/owncloud/web/pull/8238 https://github.com/owncloud/web/pull/8234 https://github.com/owncloud/web/pull/8249 +https://github.com/owncloud/web/pull/8230 https://github.com/owncloud/web/issues/8219 diff --git a/packages/web-app-admin-settings/src/views/Spaces.vue b/packages/web-app-admin-settings/src/views/Spaces.vue index e5bd0efa237..6aba7b57a60 100644 --- a/packages/web-app-admin-settings/src/views/Spaces.vue +++ b/packages/web-app-admin-settings/src/views/Spaces.vue @@ -172,7 +172,10 @@ export default defineComponent({ title: $gettext('Space details'), component: SpaceDetailsMultiple, default: true, - enabled: unref(selectedSpaces).length > 1 + enabled: unref(selectedSpaces).length > 1, + componentAttrs: { + selectedSpaces: unref(selectedSpaces) + } }, { app: 'SpaceMembers', diff --git a/packages/web-pkg/src/components/sideBar/Spaces/Details/SpaceDetailsMultiple.vue b/packages/web-pkg/src/components/sideBar/Spaces/Details/SpaceDetailsMultiple.vue index 8f4b1560f58..51465a77564 100644 --- a/packages/web-pkg/src/components/sideBar/Spaces/Details/SpaceDetailsMultiple.vue +++ b/packages/web-pkg/src/components/sideBar/Spaces/Details/SpaceDetailsMultiple.vue @@ -1,21 +1,147 @@ <template> - <div class="oc-mt-xl"> - <div class="oc-flex space-info"> - <oc-icon name="layout-grid" size="xxlarge" /> - <p v-translate>Multiple spaces selected</p> + <div id="oc-spaces-details-multiple-sidebar"> + <div class="spaces-preview oc-mb"> + <div class="spaces-preview-body"> + <oc-icon class="preview-icon" size="xxlarge" variation="passive" name="layout-grid" /> + <p class="preview-text" v-text="selectedSpacesString" /> + </div> + </div> + <div> + <table class="details-table" :aria-label="detailsTableLabel"> + <tr> + <th scope="col" class="oc-pr-s" v-text="$gettext('Total quota:')" /> + <td v-text="totalSelectedSpaceQuotaTotal" /> + </tr> + <tr> + <th scope="col" class="oc-pr-s" v-text="$gettext('Remaining quota:')" /> + <td v-text="totalSelectedSpaceQuotaRemaining" /> + </tr> + <tr> + <th scope="col" class="oc-pr-s" v-text="$gettext('Used quota:')" /> + <td v-text="totalSelectedSpaceQuotaUsed" /> + </tr> + <tr> + <th scope="col" class="oc-pr-s" v-text="$gettext('Enabled:')" /> + <td v-text="totalEnabledSpaces" /> + </tr> + <tr> + <th scope="col" class="oc-pr-s" v-text="$gettext('Disabled:')" /> + <td v-text="totalDisabledSpaces" /> + </tr> + </table> </div> </div> </template> <script lang="ts"> -import { defineComponent } from 'vue' +import { formatFileSize } from 'web-pkg/src/helpers' +import { computed, defineComponent, PropType } from 'vue' +import { SpaceResource } from 'web-client/src' +import { useTranslations } from 'web-pkg/src' export default defineComponent({ - name: 'SpaceDetailsMultiple' + name: 'SpaceDetailsMultiple', + props: { + selectedSpaces: { + type: Array as PropType<Array<SpaceResource>>, + required: true + } + }, + setup(props) { + const { $gettext, $ngettext, $gettextInterpolate, $language } = useTranslations() + const totalSelectedSpaceQuotaTotal = computed(() => { + let total = 0 + props.selectedSpaces.forEach((space) => { + total += space.spaceQuota.total + }) + return formatFileSize(total, $language.current) + }) + const totalSelectedSpaceQuotaRemaining = computed(() => { + let remaining = 0 + props.selectedSpaces.forEach((space) => { + if (space.disabled) { + return + } + remaining += space.spaceQuota.remaining + }) + return formatFileSize(remaining, $language.current) + }) + const totalSelectedSpaceQuotaUsed = computed(() => { + let used = 0 + props.selectedSpaces.forEach((space) => { + if (space.disabled) { + return + } + used += space.spaceQuota.used + }) + return formatFileSize(used, $language.current) + }) + const totalEnabledSpaces = computed(() => { + return props.selectedSpaces.filter((s) => !s.disabled).length + }) + const totalDisabledSpaces = computed(() => { + return props.selectedSpaces.filter((s) => s.disabled).length + }) + const detailsTableLabel = computed(() => { + return $gettext('Overview of the information about the selected spaces') + }) + const selectedSpacesString = computed(() => { + return $gettextInterpolate( + $ngettext( + '%{ itemCount } space selected', + '%{ itemCount } spaces selected', + props.selectedSpaces.length + ), + { + itemCount: props.selectedSpaces.length + } + ) + }) + return { + detailsTableLabel, + selectedSpacesString, + totalSelectedSpaceQuotaTotal, + totalSelectedSpaceQuotaRemaining, + totalSelectedSpaceQuotaUsed, + totalEnabledSpaces, + totalDisabledSpaces + } + } }) </script> <style lang="scss"> -.space-info { - align-items: center; - flex-direction: column; +.spaces-preview { + position: relative; + background-color: var(--oc-color-background-muted); + border: 10px solid var(--oc-color-background-muted); + height: 230px; + text-align: center; + color: var(--oc-color-swatch-passive-muted); + + &-body { + margin: 0; + position: absolute; + top: 50%; + left: 50%; + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + + .preview-icon { + display: inline-block; + } + .preview-text { + display: block; + } + } +} +.details-table { + text-align: left; + + tr { + height: 1.5rem; + } + + th { + font-weight: 600; + } } </style> diff --git a/packages/web-pkg/tests/unit/components/sidebar/Spaces/Details/SpaceDetailsMultiple.spec.ts b/packages/web-pkg/tests/unit/components/sidebar/Spaces/Details/SpaceDetailsMultiple.spec.ts new file mode 100644 index 00000000000..84855e8e883 --- /dev/null +++ b/packages/web-pkg/tests/unit/components/sidebar/Spaces/Details/SpaceDetailsMultiple.spec.ts @@ -0,0 +1,34 @@ +import SpaceDetailsMultiple from 'web-pkg/src/components/sideBar/Spaces/Details/SpaceDetailsMultiple.vue' +import { defaultPlugins, shallowMount } from 'web-test-helpers' + +const spaceMock = { + type: 'space', + name: ' space', + id: '1', + mdate: 'Wed, 21 Oct 2015 07:28:00 GMT', + spaceQuota: { + used: 100, + total: 1000, + remaining: 900 + } +} + +describe('Multiple Details SideBar Panel', () => { + it('displays the details side panel', () => { + const { wrapper } = createWrapper(spaceMock) + expect(wrapper.html()).toMatchSnapshot() + }) +}) + +function createWrapper(spaceResource) { + return { + wrapper: shallowMount(SpaceDetailsMultiple, { + global: { + plugins: [...defaultPlugins()] + }, + props: { + selectedSpaces: [spaceResource] + } + }) + } +} diff --git a/packages/web-pkg/tests/unit/components/sidebar/Spaces/Details/__snapshots__/SpaceDetailsMultiple.spec.ts.snap b/packages/web-pkg/tests/unit/components/sidebar/Spaces/Details/__snapshots__/SpaceDetailsMultiple.spec.ts.snap new file mode 100644 index 00000000000..5ad44e2d0d9 --- /dev/null +++ b/packages/web-pkg/tests/unit/components/sidebar/Spaces/Details/__snapshots__/SpaceDetailsMultiple.spec.ts.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Multiple Details SideBar Panel displays the details side panel 1`] = ` +<div id="oc-spaces-details-multiple-sidebar"> + <div class="spaces-preview oc-mb"> + <div class="spaces-preview-body"> + <oc-icon-stub accessiblelabel="" class="preview-icon" color="" filltype="fill" name="layout-grid" size="xxlarge" type="span" variation="passive"></oc-icon-stub> + <p class="preview-text">1 space selected</p> + </div> + </div> + <div> + <table aria-label="Overview of the information about the selected spaces" class="details-table"> + <tbody> + <tr> + <th class="oc-pr-s" scope="col">Total quota:</th> + <td>1 kB</td> + </tr> + <tr> + <th class="oc-pr-s" scope="col">Remaining quota:</th> + <td>900 B</td> + </tr> + <tr> + <th class="oc-pr-s" scope="col">Used quota:</th> + <td>100 B</td> + </tr> + <tr> + <th class="oc-pr-s" scope="col">Enabled:</th> + <td>1</td> + </tr> + <tr> + <th class="oc-pr-s" scope="col">Disabled:</th> + <td>0</td> + </tr> + </tbody> + </table> + </div> +</div> +`;