diff --git a/packages/web-pkg/src/composables/piniaStores/extensionRegistry/types.ts b/packages/web-pkg/src/composables/piniaStores/extensionRegistry/types.ts index 15fe38d4052..f00428cf1c4 100644 --- a/packages/web-pkg/src/composables/piniaStores/extensionRegistry/types.ts +++ b/packages/web-pkg/src/composables/piniaStores/extensionRegistry/types.ts @@ -5,12 +5,14 @@ import { Item } from '@ownclouders/web-client' import { FolderView } from '../../../ui' import { Component, Slot } from 'vue' import { StringUnionOrAnyString } from '../../../utils' +import { ResourceIndicator } from '../../../helpers' export type ExtensionType = StringUnionOrAnyString< | 'action' | 'appMenuItem' | 'customComponent' | 'folderView' + | 'resourceIndicator' | 'search' | 'sidebarNav' | 'sidebarPanel' @@ -67,6 +69,11 @@ export interface AppMenuItemExtension extends Extension { url?: string } +export interface ResourceIndicatorExtension extends Extension { + type: 'resourceIndicator' + getResourceIndicators: (Resource) => ResourceIndicator[] | void +} + export type ExtensionPoint = { id: string extensionType: ExtensionType diff --git a/packages/web-pkg/src/extensionPoints.ts b/packages/web-pkg/src/extensionPoints.ts new file mode 100644 index 00000000000..9c3a8f58816 --- /dev/null +++ b/packages/web-pkg/src/extensionPoints.ts @@ -0,0 +1,14 @@ +import { Extension, ExtensionPoint, ResourceIndicatorExtension } from './' +import { computed } from 'vue' + +export const resourceIndicatorExtensionPoint: ExtensionPoint = { + id: 'global.files.resource-indicator', + extensionType: 'resourceIndicator', + multiple: true +} + +export const extensionPoints = () => { + return computed[]>(() => { + return [resourceIndicatorExtensionPoint] + }) +} diff --git a/packages/web-pkg/src/helpers/statusIndicators.ts b/packages/web-pkg/src/helpers/statusIndicators.ts index 5d8c7d3f879..2a5d39dadc3 100644 --- a/packages/web-pkg/src/helpers/statusIndicators.ts +++ b/packages/web-pkg/src/helpers/statusIndicators.ts @@ -1,6 +1,7 @@ import { ShareTypes } from '@ownclouders/web-client' import { eventBus } from '../services' import { SideBarEventTopics } from '../composables/sideBar' +import { useExtensionRegistry } from '../composables/piniaStores/extensionRegistry' import { Resource } from '@ownclouders/web-client' import { AncestorMetaData } from '../types' import { @@ -10,6 +11,7 @@ import { } from '@ownclouders/web-client' import { User } from '@ownclouders/web-client/graph/generated' import { IconFillType } from './resource' +import { resourceIndicatorExtensionPoint } from '../extensionPoints' // dummy to trick gettext string extraction into recognizing strings const $gettext = (str: string): string => { @@ -157,5 +159,14 @@ export const getIndicators = ({ } } + ;(useExtensionRegistry().requestExtensions(resourceIndicatorExtensionPoint) || []).forEach( + (extension) => { + const extensionIndicators = extension.getResourceIndicators(resource) + if (extensionIndicators) { + indicators.push(...extensionIndicators) + } + } + ) + return indicators } diff --git a/packages/web-pkg/src/index.ts b/packages/web-pkg/src/index.ts index f36b57d54d0..319aa9b291f 100644 --- a/packages/web-pkg/src/index.ts +++ b/packages/web-pkg/src/index.ts @@ -3,6 +3,7 @@ export * from './components' export * from './composables' export * from './constants' export * from './errors' +export * from './extensionPoints' export * from './helpers' export * from './http' export * from './observer' diff --git a/packages/web-pkg/tests/unit/helpers/statusIndicator.spec.ts b/packages/web-pkg/tests/unit/helpers/statusIndicator.spec.ts index 26c11d0967a..b8476722e89 100644 --- a/packages/web-pkg/tests/unit/helpers/statusIndicator.spec.ts +++ b/packages/web-pkg/tests/unit/helpers/statusIndicator.spec.ts @@ -3,10 +3,52 @@ import { Resource, SpaceResource } from '@ownclouders/web-client' import { getIndicators } from '../../../src/helpers/statusIndicators' import { User } from '@ownclouders/web-client/graph/generated' import { AncestorMetaDataValue } from '../../../src/types' +import { ResourceIndicator } from '../../../src/helpers' +import { createTestingPinia } from '@ownclouders/web-test-helpers' +import { + ResourceIndicatorExtension, + useExtensionRegistry +} from '../../../src/composables/piniaStores/extensionRegistry' describe('status indicators', () => { const user = mock() + createTestingPinia() + + describe('indicator extensions', () => { + it('should be requested from the extension registry', () => { + const space = mock({ driveType: 'project' }) + const resource = mock({ id: 'resource' }) + + const { requestExtensions } = useExtensionRegistry() + vi.mocked(requestExtensions).mockReturnValue([ + { + id: 'test.files.resource-indicator.stub', + type: 'resourceIndicator', + extensionPointIds: ['global.files.resource-indicator'], + getResourceIndicators: (resource: Resource): ResourceIndicator[] => { + return [ + { + id: 'some-id', + accessibleDescription: 'some accessible description', + label: 'some label', + icon: 'check_box_outline_blank', + fillType: 'line', + type: 'some-type', + category: 'system' + } + ] + } + } satisfies ResourceIndicatorExtension + ]) + + const indicators = getIndicators({ space, resource, ancestorMetaData: {}, user }) + + expect(requestExtensions).toHaveBeenCalled() + expect(indicators.some(({ id }) => id === 'some-id')).toBeTruthy() + }) + }) + describe('locked indicator', () => { it.each([true, false])('should only be present if the file is locked', (locked) => { const space = mock({ id: 'space' })