Skip to content

Commit

Permalink
Docs extension system (#10400)
Browse files Browse the repository at this point in the history
* change: Remove skeleton app
* docs: Add extension system docs

---------

Co-authored-by: Pascal Wengerter <[email protected]>
  • Loading branch information
kulmann and pascalwengerter authored Jan 25, 2024
1 parent 0bf8f81 commit 0b8cbcf
Show file tree
Hide file tree
Showing 21 changed files with 436 additions and 343 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ The repository's `packages` also contains the following apps, which can be en-/d
- **pdf-viewer:** An extension for opening PDF files without leaving the UI
- **preview:** An extension for opening audio, video and image files
- **search:** An extension for registering search providers, which then get rendered into the layout in the **runtime** using a portal
- **skeleton:** Bare extension serving as a playground for prototyping new custom extensions
- **text-editor:** An extension for creating, opening and editing plain text files, like e.g. `.md` or `.txt`
- **user-management:** An extension for basic user and group management by the admin. Only works with the Infinite Scale platform, as it uses the graph API.

Expand Down
7 changes: 7 additions & 0 deletions changelog/unreleased/change-remove-skeleton-app
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Change: Remove skeleton app

Due to improvements in the extension system in general, we have removed the skeleton app.
Documentation regarding the extension API and guides/examples can be found in the dev docs.

https://github.com/owncloud/web/issues/9892
https://github.com/owncloud/web/pull/10067
86 changes: 0 additions & 86 deletions docs/custom-apps/_index.md

This file was deleted.

148 changes: 148 additions & 0 deletions docs/extension-system/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
title: 'Extension system'
date: 2024-01-23T00:00:00+00:00
weight: 60
geekdocRepo: https://github.com/owncloud/web
geekdocEditPath: edit/master/docs/extension-system
geekdocFilePath: _index.md
geekdocCollapseSection: true
---

{{< toc >}}

## Concepts and Building Blocks

The ownCloud Web can be extended through various entry points with custom **apps** and **extensions**.

### Distinction between Apps and Extensions

An Application in the context of ownCloud Web is an artifact which can be installed in an ownCloud Infinite Scale instance.
It serves two main purposes:
1. It makes the full app viewport (everything below the top bar) available to the application developer for any custom
application code. This includes the ability to define views with routes, navigation items for the left sidebar, and more.
2. Through the `extensions` key in the application interface you can register extensions of any extension type. Those extensions
are then available in standardized extension points. Additionally, they can be queried from the extension registry for
your own purposes.

Both parts are optional. This means that an application can be a file editor without any custom extensions, or even contain
no custom application code at all and only host extensions to be registered in the extension registry, or a combination of both.

### Apps

To get started, define a `src/index.ts`. Below is the most basic example of its content:

```typescript
// Install '@ownclouders/web-pkg' as a devDependency first (only relevant for types and autocompletion, dependency is already provided by ownCloud Web at runtime).
import {
AppWrapperRoute,
ApplicationFileExtension,
defineWebApplication
} from '@ownclouders/web-pkg'


export default defineWebApplication({
setup({ applicationConfig }) {
// Here, you have access to the full injection context, meaning you can use all composables that we provide via web-pkg

// Needs to be unique within all installed applications in any ownCloud web instance
// Should be short, unique and expressive as it is used as prefix on all routes within your application
const appId = 'your-extension'

// See extensions section below
const extensions = [
...
]

// See details below
const navItems = [
...
]

// See details below
const routes = [
...
]

return {
appInfo: {
name: $gettext('Your application name'),
id: appId,
icon: 'aliens', // See https://owncloud.design/#/Design%20Tokens/IconList for available options
},
extensions,
navItems,
routes
}
}
})
```

By defining an application via `defineWebApplication` you can provide the following:
- `appInfo` - the application metadata, which is used to make the application available via the app switcher and the app registry.
- `navItems` - the statically defined navigation items for the left sidebar. Only gets rendered when more than 1 navigation item exists at runtime.
Additional dynamic navigation items can be registered via the extension registry.
- `routes` - the routes to the different views of your application. May be referenced within the `navItems`. Authentication requirements can be defined per item.
- `extensions` - the extensions to be registered in the extension registry. For more details see the `Extensions` section below.

### Extensions

In contrast to applications, extensions usually have a rather small scope and dedicated functionality.

#### Extension Registry

The globally available extension registry provided by the ownCloud Web runtime can be used to both register and query extensions. All extensions
which are being made available via an `app` get registered in the extension registry automatically. In your custom application code you can
then query any of the available extensions by providing a `type` string and optionally a list of `scopes`. Throughout the ownCloud Web platform
and most prominently also in the `files` app we have defined some extension points which automatically use certain extensions, see the
`Extension Points` section below.

#### Extension Types

For building an extension you can choose from the types predefined by the ownCloud Web extension system. See the full list of available extension types below.

1. `ActionExtension` (type `action`) - An extension that can register `Action` items which then get shown in various places (e.g. context menus, batch actions), depending on their
respective scope. Most commonly used for file and folder actions (e.g. copy, rename, delete, etc.). For details, please refer to the [action docs]({{< ref "extension-types/actions.md" >}})
2. `SearchExtension` (type `search`) - An extension that can register additional search providers. For details, please refer to the [search docs]({{< ref "extension-types/search.md" >}})
3. `SidebarNavExtension` (type `sidebarNav`) - An extension that can register additional navigation items to the left sidebar. These can be scoped to specific apps, and programmatically enabled/disabled.
For details, please refer to the [sidebar nav docs]({{< ref "extension-types/left-sidebar-menu-item.md" >}})
4. `SidebarPanelExtension`, (type `sidebarPanel`) - An extension that can register panels to the right sidebar. For details, please refer to the [sidebar panel docs]({{< ref "extension-types/right-sidebar-panels.md" >}})
5. `FolderViewExtension` (type `folderView`) - An extension that can register additional ways of displaying the content of a folder (resources, so spaces, folders or files) to the user.
For details, please refer to the [folder view docs]({{< ref "extension-types/folder-view.md" >}})

You're free to introduce your own extension types within your application code and use the extension registry to query the available ones. However, if you have the impression
that an important extension type is missing and would be beneficial for the platform, please reach out to us by opening a [GitHub issue](https://github.com/owncloud/web/issues/new/choose).

#### Extension Base Configuration

Any extension is required to define at least an `id` and a `type`.

The `id` is supposed to be unique throughout the ownCloud Web ecosystem. In order to keep `id`s readable for humans we didn't want to enforce uniqueness through e.g. uuids.
Instead, we chose to use dot-formatted namespaces like e.g. `com.github.owncloud.web.files.search`. We'd like to encourage you to follow the same format for your own extensions.

For the `type` you can choose from the ones listed above or define a custom one.

In addition, you can also pass optional `scopes` to further limit the usage of an extension. The extension system predefines some scopes which are then used in the default extension
points (see section below). Those include:
- `resource` - For extensions which are meant to work with a `file`, `folder` or `space` as data context.
- `user` - For extensions which are meant to work with a `user` as data context.
- `group` - For extensions which are meant to work with a `group` as data context.

Similar to the extension types, you are always free to define and handle custom scopes within your own application. If you have the impression
that an important scope is missing and would be beneficial for the platform, please reach out to us by opening a [GitHub issue](https://github.com/owncloud/web/issues/new/choose).

{{< hint info >}}
Scopes are meant to be defined in singular form, e.g. `resource` instead of `resources`, even when the data context holds multiple items.
{{< /hint >}}

#### Extension Points

There are standardized components and places where extensions are being used automatically. These are the ones that are currently provided:

1. Left Sidebar for Navigation
2. Right Sidebar in any file(s) context
3. Folder Views in the files app
4. Right click context menu in the files app
5. Batch actions in the files app
6. Upload menu in the files app
7. Quick actions in the files list of the files app
8. Search results in the search app
12 changes: 12 additions & 0 deletions docs/extension-system/extension-types/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "Extension Types"
date: 2024-01-25T00:00:00+00:00
weight: 50
geekdocRepo: https://github.com/owncloud/web
geekdocEditPath: edit/master/docs/extension-system
geekdocFilePath: _index.md
geekdocCollapseSection: true
---

This section is a guide about the different predefined extension types of ownCloud Web. Please refer to the respective
subpages to learn more about the individual extension types.
43 changes: 43 additions & 0 deletions docs/extension-system/extension-types/actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: 'Action extensions'
date: 2024-01-23T00:00:00+00:00
weight: 60
geekdocRepo: https://github.com/owncloud/web
geekdocEditPath: edit/master/docs/extension-system/extension-types
geekdocFilePath: actions.md
geekdocCollapseSection: true
---

{{< toc >}}

## Action extension type

Actions are one of the possible extension types. Registered actions get rendered in various places across the UI, depending on their scope and targets.

### Configuration

This is what the ActionExtension interface looks like:

```typescript
interface ActionExtension {
id: string
type: 'action'
scopes?: ExtensionScope[]
action: Action // Please check the Action section below
}
```

For `id`, `type`, and `scopes`, please see [extension base section]({{< ref "../_index.md#extension-base-configuration" >}}) in top level docs.

#### Action

The most important configuration options are:
- `icon` - The icon to be displayed, can be picked from https://owncloud.design/#/Design%20Tokens/IconList
- `name` - The name of the action (not displayed in the UI)
- `label` - The text to be displayed
- `route` - The string/route to navigate to, if the nav item should be a `<router-link>`
- `handler` - The action to perform upon click, if the nav item should be a `<button>`
- `componentType` - Either `'button'` or `'router-link'`, depending on whether the action should be a link or button
- `isEnabled` - Determines whether the action is displayed to the user

Please check the [`Action` type](https://github.com/owncloud/web/blob/236c185540fc6758dc7bd84985c8834fa4145530/packages/web-pkg/src/composables/actions/types.ts#L6) for a full list of configuration options.
40 changes: 40 additions & 0 deletions docs/extension-system/extension-types/folder-view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: 'Folder View extensions'
date: 2024-01-23T00:00:00+00:00
weight: 60
geekdocRepo: https://github.com/owncloud/web
geekdocEditPath: edit/master/docs/extension-system/extension-types
geekdocFilePath: folder-view.md
geekdocCollapseSection: true
---

## Folder view extension type

The folder view is one of the possible extension types. Registered folder view can be used to render multiple resources (folders, files, spaces) in the UI.

### Configuration

This is what the FolderViewExtension interface looks like:

```typescript
interface FolderViewExtension {
id: string
scopes?: ExtensionScope[]
type: 'folderView'
folderView: FolderView // See FolderView section below
}

```

For `id`, `type`, and `scopes`, please see [extension base section]({{< ref "../_index.md#extension-base-configuration" >}}) in top level docs.

#### FolderView

For the folderView object, you have the following configuration options:

- `name` - The name of the action (not displayed in the UI)
- `label` - The text to be displayed to the user when switching between different FolderView options
- `icon` - Object, expecting an icon `name` and a corresponding `IconFillType`, see https://owncloud.design/#/Design%20Tokens/IconList for available options
- `isScrollable` - Optional boolean, determines whether the user can scroll inside the component or it statically fills the viewport
- `component` - The Vue component to render the resources. It should expect a prop of type `Resource[]`
- `componentAttrs` - Optional additional configuration for the component mentioned above
44 changes: 44 additions & 0 deletions docs/extension-system/extension-types/left-sidebar-menu-item.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: 'Left sidebar menu item extensions'
date: 2024-01-23T00:00:00+00:00
weight: 60
geekdocRepo: https://github.com/owncloud/web
geekdocEditPath: edit/master/docs/extension-system/extension-types
geekdocFilePath: left-sidebar-menu-item.md
geekdocCollapseSection: true
---

{{< toc >}}


## Left sidebar menu item extension type

One possible extension type is left sidebar menu items. Registered left sidebar menu items get rendered in the left sidebar, as long as there is more than one available.

### Configuration

To define a left sidebar menu item, you implement the SidebarNavExtension interface.
It looks like this:

```typescript
interface SidebarNavExtension {
id: string
type: 'sidebarNav'
scopes?: ExtensionScope[]
navItem: AppNavigationItem // Please check the AppNavigationItem section below
}
}
```

For `id`, `type`, and `scopes`, please see [extension base section]({{< ref "../_index.md#extension-base-configuration" >}}) in top level docs.


#### AppNavigationItem

The most important configuration options are:
- `icon` - The icon to be displayed, can be picked from https://owncloud.design/#/Design%20Tokens/IconList
- `name` - The text to be displayed
- `route` - The string/route to navigate to, if the nav item should be a `<router-link>` (Mutually exclusive with `handler`)
- `handler` - The action to perform upon click, if the nav item should be a `<button>` (Mutually exclusive with `route`)

Please check the [`AppNavigationItem` type](https://github.com/owncloud/web/blob/f069ce44919cde5d112c68a519d433e015a4a011/packages/web-pkg/src/apps/types.ts#L14) for a full list of configuration options.
Loading

0 comments on commit 0b8cbcf

Please sign in to comment.