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] Use icon from app registered for the file type #9088

Merged
merged 10 commits into from
Jun 9, 2023
8 changes: 8 additions & 0 deletions changelog/unreleased/enhancement-app-icons-for-files
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Use app icons for files

Icons of apps are now rendered next to files that can be opened with them.
Until now oC Web itself defined icons for file types, with this change an icon
can be shown even if oC Web does not know the file type - there just needs to
be an app loaded that supports opening the file type.

https://github.com/owncloud/web/pull/9088
6 changes: 1 addition & 5 deletions packages/design-system/build/webpack.system.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,7 @@ const webpackConfig = merge(baseWebpackConfig, {
to: config.system.assetsSubDirectory
},
{
from: path.resolve(__dirname, '../src/helpers/resourceIconColorExtensionMapping.json'),
to: config.system.assetsSubDirectory
},
{
from: path.resolve(__dirname, '../src/helpers/resourceIconExtensionMapping.json'),
from: path.resolve(__dirname, '../src/helpers/resourceIconMapping.json'),
to: config.system.assetsSubDirectory
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,70 @@
import { shallowMount } from 'web-test-helpers'
import { AVAILABLE_SIZES } from '../../helpers/constants'
import { OcResourceIcon } from '..'
import { OcResourceIconMapping, ocResourceIconMappingInjectionKey } from './types'
import { Resource } from 'web-client'

const resources = ['file', 'folder', 'space']
const resourceIconMapping: OcResourceIconMapping = {
extension: {
'not-a-real-extension': {
name: 'resource-type-madeup-extension',
color: 'red'
}
},
mimeType: {
'not-a-real-mimetype': {
name: 'resource-type-madeup-mimetype',
color: 'blue'
}
}
}

describe('OcResourceIcon', () => {
resources.forEach((resourceType) => {
AVAILABLE_SIZES.forEach((size) => {
it(`renders OcIcon for resource type ${resourceType} in size ${size}`, () => {
const { wrapper } = getWrapper({ resourceType, size })
expect(wrapper.html()).toMatchSnapshot()
})
;['file', 'folder', 'space'].forEach((type) => {
match({
type
})
})

match(
{
type: 'file',
extension: 'not-a-real-extension'
},
'with extension "not-a-real-extension"'
)

match(
{
type: 'file',
mimeType: 'not-a-real-mimetype'
},
'with mimetype "not-a-real-mimetype"'
)
})

function getWrapper(props) {
function match(resource: Partial<Resource>, additionalText?: string) {
AVAILABLE_SIZES.forEach((size) => {
it(`renders OcIcon for resource type ${resource.type}${
additionalText ? ` ${additionalText}` : ''
} in size ${size}`, () => {
const { wrapper } = getWrapper({ resource, size })
expect(wrapper.html()).toMatchSnapshot()
})
})
}

function getWrapper({ resource, size }: { resource: Partial<Resource>; size: string }) {
return {
wrapper: shallowMount(OcResourceIcon as any, {
global: {
provide: {
[ocResourceIconMappingInjectionKey]: resourceIconMapping
}
},
props: {
resource: { type: props.resourceType },
size: props.size
resource,
size
}
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
<template>
<oc-icon
:key="`resource-icon-${iconName}`"
:name="iconName"
:color="iconColor"
:key="`resource-icon-${icon.name}`"
:name="icon.name"
:color="icon.color"
:size="size"
:class="['oc-resource-icon', iconTypeClass]"
/>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'
import { computed, defineComponent, inject, PropType, unref } from 'vue'
import { Resource } from 'web-client'

import OcIcon from '../OcIcon/OcIcon.vue'
import { AVAILABLE_SIZES } from '../../helpers'
import * as iconColorMap from '../../helpers/resourceIconColorExtensionMapping.json'
import * as iconNameMap from '../../helpers/resourceIconExtensionMapping.json'
import { AVAILABLE_SIZES, IconType } from '../../helpers'
import * as iconMapping from '../../helpers/resourceIconMapping.json'

const defaultFolderColor = 'var(--oc-color-icon-folder)'
const defaultFolderIcon = 'resource-type-folder'
const defaultSpaceColor = 'var(--oc-color-swatch-passive-default)'
const defaultSpaceIcon = 'layout-grid'
const defaultFallbackIconColor = 'var(--oc-color-text-default)'
const defaultFallbackIcon = 'file'
import { OcResourceIconMapping, ocResourceIconMappingInjectionKey } from './types'

const defaultFolderIcon: IconType = {
name: 'resource-type-folder',
color: 'var(--oc-color-icon-folder)'
}

const defaultSpaceIcon: IconType = {
name: 'layout-grid',
color: 'var(--oc-color-swatch-passive-default)'
}
const defaultFallbackIcon: IconType = {
name: 'resource-type-file',
color: 'var(--oc-color-text-default)'
}

export default defineComponent({
name: 'OcResourceIcon',
Expand All @@ -49,47 +57,57 @@ export default defineComponent({
}
}
},
computed: {
iconName() {
if (this.isSpace) {
setup(props) {
const iconMappingInjection = inject<OcResourceIconMapping>(ocResourceIconMappingInjectionKey)

const isFolder = computed(() => {
// fallback is necessary since
// sometimes resources without a type
// but with `isFolder` are being passed
return props.resource.type === 'folder' || props.resource.isFolder
})

const isSpace = computed(() => {
return props.resource.type === 'space'
})
const extension = computed(() => {
return props.resource.extension?.toLowerCase()
})
const mimeType = computed(() => {
return props.resource.mimeType?.toLowerCase()
})

const icon = computed((): IconType => {
if (unref(isSpace)) {
return defaultSpaceIcon
}
if (this.isFolder) {
if (unref(isFolder)) {
return defaultFolderIcon
}
const icon = iconNameMap[this.extension]
return `resource-type-${icon ? icon : defaultFallbackIcon}`
},
iconColor() {
if (this.isSpace) {
return defaultSpaceColor
}
if (this.isFolder) {
return defaultFolderColor

let icon =
(iconMapping[unref(extension)] as IconType) ||
iconMappingInjection?.mimeType[unref(mimeType)] ||
iconMappingInjection?.extension[unref(extension)]
return {
...defaultFallbackIcon,
...icon
}
const color = iconColorMap[this.extension]
return color ? color : defaultFallbackIconColor
},
iconTypeClass() {
if (this.isSpace) {
})

const iconTypeClass = computed(() => {
if (unref(isSpace)) {
return 'oc-resource-icon-space'
}
if (this.isFolder) {
if (unref(isFolder)) {
return 'oc-resource-icon-folder'
}
return 'oc-resource-icon-file'
},
isFolder() {
// fallback is necessary since
// sometimes resources without a type
// but with `isFolder` are being passed
return this.resource.type === 'folder' || this.resource.isFolder
},
isSpace() {
return this.resource.type === 'space'
},
extension() {
return this.resource.extension?.toLowerCase()
})

return {
icon,
iconTypeClass
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,34 @@ exports[`OcResourceIcon renders OcIcon for resource type file in size xxlarge 1`

exports[`OcResourceIcon renders OcIcon for resource type file in size xxxlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="var(--oc-color-text-default)" filltype="fill" name="resource-type-file" size="xxxlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size large 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="large" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size medium 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="medium" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size small 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="small" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size xlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="xlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size xsmall 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="xsmall" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size xxlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="xxlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with extension "not-a-real-extension" in size xxxlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="red" filltype="fill" name="resource-type-madeup-extension" size="xxxlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size large 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="large" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size medium 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="medium" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size small 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="small" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size xlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="xlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size xsmall 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="xsmall" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size xxlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="xxlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type file with mimetype "not-a-real-mimetype" in size xxxlarge 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-file" color="blue" filltype="fill" name="resource-type-madeup-mimetype" size="xxxlarge" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type folder in size large 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-folder" color="var(--oc-color-icon-folder)" filltype="fill" name="resource-type-folder" size="large" type="span" variation="passive"></oc-icon-stub>`;

exports[`OcResourceIcon renders OcIcon for resource type folder in size medium 1`] = `<oc-icon-stub accessiblelabel="" class="oc-resource-icon oc-resource-icon-folder" color="var(--oc-color-icon-folder)" filltype="fill" name="resource-type-folder" size="medium" type="span" variation="passive"></oc-icon-stub>`;
Expand Down
4 changes: 4 additions & 0 deletions packages/design-system/src/components/OcResourceIcon/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { IconType } from 'design-system/src/helpers'

export type OcResourceIconMapping = Record<'mimeType' | 'extension', Record<string, IconType>>
export const ocResourceIconMappingInjectionKey = 'oc-resource-icon-mapping'

This file was deleted.

Loading