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

Add selection model to tiles view #8392

Merged
merged 9 commits into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/unreleased/enhancement-resources-tiles-view
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ Tiles can be dynamically resized on screens bigger than mobile, using the "displ

https://github.com/owncloud/web/pull/7991
https://github.com/owncloud/web/pull/8372
https://github.com/owncloud/web/pull/8392
https://github.com/owncloud/web/issues/6378
https://github.com/owncloud/web/issues/6379
https://github.com/owncloud/web/issues/6380
https://github.com/owncloud/web/issues/8367
https://github.com/owncloud/web/issues/8368
https://github.com/owncloud/web/issues/8365
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ export default defineComponent({
'oc-checkbox',
'oc-rounded',
'oc-checkbox-' + getSizeClass(this.size),
{ 'oc-checkbox-outline': this.outline }
{ 'oc-checkbox-outline': this.outline },
{ 'oc-checkbox-checked': this.modelValue }
]
},
labelClasses() {
Expand Down Expand Up @@ -180,12 +181,14 @@ export default defineComponent({
cursor: pointer;
}

&:checked,
&-checked,
:checked,
&:indeterminate {
background-color: var(--oc-color-swatch-inverse-default);
}

&:checked {
&-checked,
:checked {
@include svg-fill($internal-form-checkbox-image, '#000', $form-radio-checked-icon-color);
}

Expand Down
31 changes: 13 additions & 18 deletions packages/design-system/src/components/OcTile/OcTile.spec.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,33 @@
import { shallowMount } from 'web-test-helpers'
import { defaultPlugins, shallowMount } from 'web-test-helpers'
import OcTile from './OcTile.vue'

const defaultSpace = {
const getSpaceMock = (disabled = false) => ({
name: 'Space 1',
path: '',
type: 'space',
isFolder: true,
disabled,
getDriveAliasAndItem: () => '1'
}
const disabledSpace = {
name: 'Space 1',
path: '',
type: 'space',
isFolder: true,
disabled: true,
getDriveAliasAndItem: () => '1'
}
})

describe('OcTile component', () => {
it('renders default space correctly', () => {
const wrapper = getWrapper({ resource: defaultSpace })
const wrapper = getWrapper({ resource: getSpaceMock() })
expect(wrapper.html()).toMatchSnapshot()
})
it('renders disabled space correctly', () => {
const wrapper = getWrapper({ resource: disabledSpace })
const wrapper = getWrapper({ resource: getSpaceMock(true) })
expect(wrapper.html()).toMatchSnapshot()
})
it('renders selected resource correctly', () => {
const wrapper = getWrapper({ resource: getSpaceMock(), isResourceSelected: true })
expect(wrapper.find('.oc-tile-card-selected').exists()).toBeTruthy()
})

function getWrapper(props = {}, slots = {}) {
function getWrapper(props = {}) {
return shallowMount(OcTile, {
props: {
...props
},
global: { renderStubDefaultSlot: true }
props,
global: { plugins: [...defaultPlugins()], renderStubDefaultSlot: true }
})
}
})
113 changes: 89 additions & 24 deletions packages/design-system/src/components/OcTile/OcTile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,40 @@
<div
class="oc-tile-card oc-card oc-card-default oc-rounded"
:data-item-id="resource.id"
:class="resource.disabled ? 'state-trashed' : ''"
:class="{
'oc-tile-card-selected': isResourceSelected,
'state-trashed': resource.disabled
}"
@contextmenu="$emit('contextmenu', $event)"
>
<oc-resource-link
class="oc-card-media-top oc-border-b oc-flex oc-flex-center oc-flex-middle"
class="oc-card-media-top oc-flex oc-flex-center oc-flex-middle oc-m-rm"
:resource="resource"
:folder-link="resourceRoute"
@click="$emit('click')"
>
<div class="oc-tile-card-selection">
<slot name="selection" :item="resource" />
</div>
<oc-tag
v-if="resource.disabled"
class="resource-disabled-indicator oc-position-absolute"
type="span"
>
<span v-translate>Disabled</span>
<span v-text="$gettext('Disabled')" />
</oc-tag>
<!-- Slot for resource image, renders resource type icon by default -->
<slot name="imageField" :item="resource">
<oc-img
v-if="resource.thumbnail"
class="tile-preview oc-rounded-top"
:src="resource.thumbnail"
/>
<oc-resource-icon
v-else
:resource="resource"
size="xxlarge"
class="tile-default-image oc-pt-s"
/>
</slot>
<div class="oc-tile-card-preview oc-flex oc-flex-middle oc-flex-center">
<div class="oc-tile-card-hover"></div>
<slot name="imageField" :item="resource">
<oc-img v-if="resource.thumbnail" class="tile-preview" :src="resource.thumbnail" />
<oc-resource-icon
v-else
:resource="resource"
size="xlarge"
class="tile-default-image oc-pt-xs"
/>
</slot>
</div>
</oc-resource-link>
<div class="oc-card-body oc-p-s">
<div class="oc-flex oc-flex-between oc-flex-middle">
Expand All @@ -50,10 +54,7 @@
<slot name="contextMenu" :item="resource" />
</div>
</div>
<p
v-if="resource.description"
class="oc-text-left oc-ml-xs oc-mt-xs oc-mb-rm oc-text-truncate"
>
<p v-if="resource.description" class="oc-text-left oc-my-rm oc-text-truncate">
<small v-text="resource.description" />
</p>
</div>
Expand Down Expand Up @@ -92,17 +93,24 @@ export default defineComponent({
resourceRoute: {
type: Object,
default: () => {}
},
isResourceSelected: {
type: Boolean,
required: false,
default: false
}
},
emits: ['click', 'contextmenu']
})
</script>

<style lang="scss" scoped>
<style lang="scss">
.oc-tile-card {
background-color: var(--oc-color-background-highlight) !important;
box-shadow: none !important;
box-shadow: none;
height: 100%;
display: flex;
flex-flow: column;
outline: 1px solid var(--oc-color-border);

&.state-trashed {
Expand All @@ -116,6 +124,7 @@ export default defineComponent({
}

.oc-card-media-top {
position: relative;
aspect-ratio: 16/9;
justify-content: center;
width: 100%;
Expand All @@ -130,12 +139,68 @@ export default defineComponent({

.tile-preview {
aspect-ratio: 16/9;
height: auto;
height: 100%;
object-fit: cover;
width: 100%;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}

&:hover {
.oc-tile-card-hover {
opacity: 15%;
}
}
}

&-selected {
outline: 2px solid var(--oc-color-swatch-primary-hover);

.oc-tile-card-preview {
width: calc(100% - var(--oc-space-medium));
height: calc(100% - var(--oc-space-medium));

.tile-preview,
.oc-tile-card-hover {
border-radius: 5px !important;
}
.oc-tile-card-hover {
opacity: 10%;
}
}
}

&-selection {
z-index: 1;
position: absolute;
top: 0;
left: 0;

input {
background-color: var(--oc-color-background-muted);
}
input.oc-checkbox-checked {
background-color: var(--oc-color-swatch-inverse-default);
}
}

&-preview {
position: absolute;
height: 100%;
width: 100%;
text-align: center;
}

&-hover {
position: absolute;
width: 100%;
height: 100%;
background: #000;
opacity: 0;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}

.resource-name-wrapper {
color: var(--oc-color-text-default);
max-width: 70%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

exports[`OcTile component renders default space correctly 1`] = `
<div class="oc-tile-card oc-card oc-card-default oc-rounded">
<oc-resource-link-stub class="oc-card-media-top oc-border-b oc-flex oc-flex-center oc-flex-middle" isresourceclickable="true" resource="[object Object]">
<oc-resource-link-stub class="oc-card-media-top oc-flex oc-flex-center oc-flex-middle oc-m-rm" isresourceclickable="true" resource="[object Object]">
<div class="oc-tile-card-selection"></div>
<!--v-if-->
<!-- Slot for resource image, renders resource type icon by default -->
<oc-resource-icon-stub class="tile-default-image oc-pt-s" resource="[object Object]" size="xxlarge"></oc-resource-icon-stub>
<div class="oc-tile-card-preview oc-flex oc-flex-middle oc-flex-center">
<div class="oc-tile-card-hover"></div>
<oc-resource-icon-stub class="tile-default-image oc-pt-xs" resource="[object Object]" size="xlarge"></oc-resource-icon-stub>
</div>
</oc-resource-link-stub>
<div class="oc-card-body oc-p-s">
<div class="oc-flex oc-flex-between oc-flex-middle">
Expand All @@ -24,11 +27,15 @@ exports[`OcTile component renders default space correctly 1`] = `

exports[`OcTile component renders disabled space correctly 1`] = `
<div class="oc-tile-card oc-card oc-card-default oc-rounded state-trashed">
<oc-resource-link-stub class="oc-card-media-top oc-border-b oc-flex oc-flex-center oc-flex-middle" isresourceclickable="true" resource="[object Object]">
<oc-resource-link-stub class="oc-card-media-top oc-flex oc-flex-center oc-flex-middle oc-m-rm" isresourceclickable="true" resource="[object Object]">
<div class="oc-tile-card-selection"></div>
<oc-tag-stub class="resource-disabled-indicator oc-position-absolute" rounded="false" size="medium" type="span">
<span>Disabled</span>
</oc-tag-stub> <!-- Slot for resource image, renders resource type icon by default -->
<oc-resource-icon-stub class="tile-default-image oc-pt-s" resource="[object Object]" size="xxlarge"></oc-resource-icon-stub>
</oc-tag-stub>
<div class="oc-tile-card-preview oc-flex oc-flex-middle oc-flex-center">
<div class="oc-tile-card-hover"></div>
<oc-resource-icon-stub class="tile-default-image oc-pt-xs" resource="[object Object]" size="xlarge"></oc-resource-icon-stub>
</div>
</oc-resource-link-stub>
<div class="oc-card-body oc-p-s">
<div class="oc-flex oc-flex-between oc-flex-middle">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ exports[`SpacesList should render all spaces in a table 1`] = `
<span class="oc-icon oc-icon-m oc-icon-passive">
<!---->
</span>
<div class="oc-drop oc-box-shadow-medium oc-rounded" id="context-menu-drop-1">
<div class="oc-drop oc-box-shadow-medium oc-rounded oc-overflow-hidden" id="context-menu-drop-1">
<div class="oc-card oc-card-body oc-background-secondary oc-p-s"></div>
</div>
</button>
Expand Down
17 changes: 12 additions & 5 deletions packages/web-app-files/src/components/AppBar/ViewOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,13 @@ export default defineComponent({
name: ViewModeConstants.queryName,
defaultValue: ViewModeConstants.defaultModeName
})

const viewSizeQuery = useRouteQueryPersisted({
name: ViewModeConstants.tilesSizeQueryName,
defaultValue: ViewModeConstants.tilesSizeDefault.toString()
})
watch(
[perPageQuery, viewModeQuery],
[perPageQuery, viewModeQuery, viewSizeQuery],
(params) => {
queryParamsLoading.value = params.some((p) => !p)
},
Expand All @@ -126,6 +127,11 @@ export default defineComponent({
queryParamsLoading
}
},
mounted() {
if (!this.queryParamsLoading) {
this.setTilesViewSize()
}
},
computed: {
...mapState('Files', ['areHiddenFilesShown', 'areFileExtensionsShown']),

Expand Down Expand Up @@ -161,9 +167,10 @@ export default defineComponent({
this.viewModeCurrent = mode.name
},
setTilesViewSize() {
document
.querySelector(':root')
.style.setProperty(`--oc-size-tiles-resize-step`, `${this.viewSizeCurrent * 12}rem`)
;(document.querySelector(':root') as HTMLElement).style.setProperty(
`--oc-size-tiles-resize-step`,
`${this.viewSizeCurrent * 12}rem`
)
},
updateHiddenFilesShownModel(event) {
this.hiddenFilesShownModel = event
Expand Down Expand Up @@ -203,7 +210,7 @@ export default defineComponent({
-webkit-appearance: none;
-webkit-transition: 0.2s;
border-radius: 0.3rem;
background: var(--oc-color-input-border);
background: var(--oc-color-border);
height: 0.5rem;
opacity: 0.7;
outline: none;
Expand Down
Loading