diff --git a/docs/dev/web/embed-mode.md b/docs/dev/web/embed-mode.md
index ad0b32832..206cf9f88 100644
--- a/docs/dev/web/embed-mode.md
+++ b/docs/dev/web/embed-mode.md
@@ -40,30 +40,30 @@ To maintain uniformity and ease of handling, each event encapsulates the same st
```
@@ -80,15 +80,15 @@ In special scenarios you also want the user to set a file name, this can be achi
```
@@ -110,15 +110,15 @@ combination of both. If the embed-file-types parameter is not provided, all file
```
diff --git a/docs/dev/web/extension-system/advanced-topics/configuration.md b/docs/dev/web/extension-system/advanced-topics/configuration.md
index 31436976a..36396018d 100644
--- a/docs/dev/web/extension-system/advanced-topics/configuration.md
+++ b/docs/dev/web/extension-system/advanced-topics/configuration.md
@@ -43,15 +43,15 @@ There are two ways to override the defaults:
The merged config is passed to the `setup` function of your app definition as `applicationConfig`:
```typescript title="src/index.ts"
-import { defineWebApplication } from '@opencloud-eu/web-pkg';
+import { defineWebApplication } from '@opencloud-eu/web-pkg'
export default defineWebApplication({
setup({ applicationConfig }) {
- const showPreview = applicationConfig?.showPreview ?? true;
+ const showPreview = applicationConfig?.showPreview ?? true
// ...
}
-});
+})
```
Always provide a fallback value. The config can be empty, and an administrator can set any value.
diff --git a/docs/dev/web/extension-system/advanced-topics/styling.md b/docs/dev/web/extension-system/advanced-topics/styling.md
index c72174bcd..74009d036 100644
--- a/docs/dev/web/extension-system/advanced-topics/styling.md
+++ b/docs/dev/web/extension-system/advanced-topics/styling.md
@@ -33,7 +33,7 @@ The `@opencloud-eu/extension-sdk` package ships a preconfigured [Tailwind CSS](h
its stylesheet in your entrypoint (typically `src/index.ts`) to use it:
```typescript title="src/index.ts"
-import '@opencloud-eu/extension-sdk/tailwind.css';
+import '@opencloud-eu/extension-sdk/tailwind.css'
```
Tailwind classes need the `ext:` prefix in apps. The prefix avoids style conflicts with the OpenCloud Web runtime.
diff --git a/docs/dev/web/extension-system/advanced-topics/testing.md b/docs/dev/web/extension-system/advanced-topics/testing.md
index 5a8094d4c..9155c3b23 100644
--- a/docs/dev/web/extension-system/advanced-topics/testing.md
+++ b/docs/dev/web/extension-system/advanced-topics/testing.md
@@ -20,15 +20,15 @@ The `@opencloud-eu/web-test-helpers` package provides utilities for mounting com
context. Without them, every component that uses a composable of `web-pkg` fails to mount.
```typescript title="tests/unit/App.spec.ts"
-import { defaultPlugins, mount } from '@opencloud-eu/web-test-helpers';
-import App from '../../src/App.vue';
+import { defaultPlugins, mount } from '@opencloud-eu/web-test-helpers'
+import App from '../../src/App.vue'
describe('App', () => {
it('renders the title', () => {
- const wrapper = mount(App, { global: { plugins: [...defaultPlugins()] } });
- expect(wrapper.text()).toContain('My app');
- });
-});
+ const wrapper = mount(App, { global: { plugins: [...defaultPlugins()] } })
+ expect(wrapper.text()).toContain('My app')
+ })
+})
```
For details, please refer to the package's
diff --git a/docs/dev/web/extension-system/advanced-topics/translations.md b/docs/dev/web/extension-system/advanced-topics/translations.md
index 0485a2686..8decd3737 100644
--- a/docs/dev/web/extension-system/advanced-topics/translations.md
+++ b/docs/dev/web/extension-system/advanced-topics/translations.md
@@ -14,11 +14,11 @@ Translations are optional. An app without them simply shows its original strings
In a script or a composable, get `$gettext` from `useGettext`:
```typescript
-import { useGettext } from 'vue3-gettext';
+import { useGettext } from 'vue3-gettext'
-const { $gettext } = useGettext();
+const { $gettext } = useGettext()
-const title = $gettext('Your application name');
+const title = $gettext('Your application name')
```
In a template, `$gettext` is globally available:
@@ -33,20 +33,20 @@ Pass variables as an object. Use the `%{name}` syntax in the string, never strin
changes between languages:
```typescript
-$gettext('Open Β«%{resource}Β»', { resource: resource.name });
+$gettext('Open Β«%{resource}Β»', { resource: resource.name })
```
For plurals, use `$ngettext` with the singular form, the plural form, the count, and the variables:
```typescript
-const { $ngettext } = useGettext();
+const { $ngettext } = useGettext()
$ngettext(
'Delete the selected resource?',
'Delete %{amount} selected resources?',
resources.length,
{ amount: resources.length.toString() }
-);
+)
```
:::warning
@@ -76,7 +76,7 @@ module.exports = {
flat: false,
linguas: false
}
-};
+}
```
Add two scripts to your `package.json`:
@@ -105,13 +105,13 @@ Import `translations.json` and return it from your app definition. The Web runti
translations when your app is loaded.
```typescript title="src/index.ts"
-import { defineWebApplication } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
-import translations from '../l10n/translations.json';
+import { defineWebApplication } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
+import translations from '../l10n/translations.json'
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
return {
appInfo: {
@@ -119,9 +119,9 @@ export default defineWebApplication({
id: 'your-app'
},
translations
- };
+ }
}
-});
+})
```
The file is a map of language key to message map:
diff --git a/docs/dev/web/extension-system/extensions/extension-points.md b/docs/dev/web/extension-system/extensions/extension-points.md
index 56e85e7ff..a5f9126ab 100644
--- a/docs/dev/web/extension-system/extensions/extension-points.md
+++ b/docs/dev/web/extension-system/extensions/extension-points.md
@@ -103,13 +103,13 @@ An extension point is a plain object of the `ExtensionPoint` type. Keep it in it
`src/extensionPoints.ts`, so that you can use it in several places:
```typescript title="src/extensionPoints.ts"
-import { ActionExtension, ExtensionPoint } from '@opencloud-eu/web-pkg';
+import { ActionExtension, ExtensionPoint } from '@opencloud-eu/web-pkg'
export const toolbarExtensionPoint: ExtensionPoint = {
id: 'app.my-app.toolbar',
extensionType: 'action',
multiple: true
-};
+}
```
`ExtensionPoint` accepts the following keys:
@@ -126,9 +126,9 @@ export const toolbarExtensionPoint: ExtensionPoint = {
Return your extension points from the app definition. The key takes a `Ref`, so use a `computed`:
```typescript title="src/index.ts"
-import { defineWebApplication } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
-import { toolbarExtensionPoint } from './extensionPoints';
+import { defineWebApplication } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
+import { toolbarExtensionPoint } from './extensionPoints'
export default defineWebApplication({
setup() {
@@ -138,9 +138,9 @@ export default defineWebApplication({
id: 'my-app'
},
extensionPoints: computed(() => [toolbarExtensionPoint])
- };
+ }
}
-});
+})
```
Registration is not needed to query extensions. It makes your extension point known to the runtime, which is required
@@ -157,25 +157,25 @@ the registry and respects the user preference:
```
For all other types, query the registry yourself and render the result the way your extension point needs it:
```typescript
-import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
-import { toolbarExtensionPoint } from './extensionPoints';
+import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
+import { toolbarExtensionPoint } from './extensionPoints'
-const extensionRegistry = useExtensionRegistry();
+const extensionRegistry = useExtensionRegistry()
const actions = computed(() =>
extensionRegistry
.requestExtensions(toolbarExtensionPoint)
.map(({ action }) => action)
-);
+)
```
### Letting users choose
@@ -184,10 +184,10 @@ Add a `userPreference` to your extension point to let users pick one of the regi
sense when `multiple` is `false`:
```typescript title="src/extensionPoints.ts"
-import { ExtensionPoint, CustomComponentExtension } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
+import { ExtensionPoint, CustomComponentExtension } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
-const { $gettext } = useGettext();
+const { $gettext } = useGettext()
export const progressBarExtensionPoint: ExtensionPoint = {
id: 'app.my-app.progress-bar',
@@ -196,7 +196,7 @@ export const progressBarExtensionPoint: ExtensionPoint
label: $gettext('Progress bar'),
description: $gettext('Choose how the loading state is shown.')
}
-};
+}
```
The extension point then gets a dropdown on the preferences page, reachable via the top right user menu. The dropdown
diff --git a/docs/dev/web/extension-system/extensions/extension-types/account-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/account-extensions.md
index a25f38c4f..42afb6bea 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/account-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/account-extensions.md
@@ -15,12 +15,12 @@ To define an account extension, you implement the `AccountExtension` interface.
```typescript
interface AccountExtension {
- id: string;
- type: 'accountExtension';
- extensionPointIds?: string[];
- content: Slot | Component;
- label: () => string;
- icon: string;
+ id: string
+ type: 'accountExtension'
+ extensionPointIds?: string[]
+ content: Slot | Component
+ label: () => string
+ icon: string
}
```
@@ -42,5 +42,5 @@ const extension: AccountExtension = {
label: () => $gettext('App Tokens'),
icon: 'key-2',
content: AppTokens
-};
+}
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/action-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/action-extensions.md
index 6d1509ff7..6549b7dd2 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/action-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/action-extensions.md
@@ -14,10 +14,10 @@ This is what the `ActionExtension` interface looks like:
```typescript
interface ActionExtension {
- id: string;
- type: 'action';
- extensionPointIds?: string[];
- action: Action; // Please check the Action section below
+ id: string
+ type: 'action'
+ extensionPointIds?: string[]
+ action: Action // Please check the Action section below
}
```
@@ -43,7 +43,7 @@ The following example shows how an action extension for downloading files could
```typescript title="src/extensions.ts"
export const useDownloadFilesExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.download-action',
@@ -56,19 +56,19 @@ export const useDownloadFilesExtension = () => {
label: () => $gettext('Download'),
isVisible: ({ space, resources }) => {
if (resources.length === 0) {
- return false;
+ return false
}
- return true;
+ return true
},
handler: ({ space, resources }) => {
- console.log('Triggering download...');
+ console.log('Triggering download...')
}
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -76,7 +76,7 @@ The extension could then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useFileActionDownloadFiles();
+ const { extension } = useFileActionDownloadFiles()
return {
appInfo: {
@@ -84,7 +84,7 @@ export default defineWebApplication({
id: 'download-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md
index 4f06e356d..d11704e3c 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md
@@ -14,16 +14,16 @@ The Interface for an `AppMenuItemExtension` looks like so:
```typescript
interface AppMenuItemExtension {
- id: string;
- type: 'appMenuItem';
- extensionPointIds?: string[];
- label: () => string;
- color?: string;
- handler?: () => Promise | void;
- icon?: string;
- path?: string;
- priority?: number;
- url?: string;
+ id: string
+ type: 'appMenuItem'
+ extensionPointIds?: string[]
+ label: () => string
+ color?: string
+ handler?: () => Promise | void
+ icon?: string
+ path?: string
+ priority?: number
+ url?: string
}
```
@@ -46,8 +46,8 @@ The following example shows how an app creates an extension that registers an ap
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
- const appId = 'my-cool-app';
+ const { $gettext } = useGettext()
+ const appId = 'my-cool-app'
const menuItems = computed(() => [
{
@@ -59,7 +59,7 @@ export default defineWebApplication({
color: '#0D856F',
priority: 60
}
- ]);
+ ])
return {
appInfo: {
@@ -67,7 +67,7 @@ export default defineWebApplication({
id: appId
},
extensions: menuItems
- };
+ }
}
-});
+})
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md
index 5ff4af3ee..39c1bb9ac 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md
@@ -16,11 +16,11 @@ Here's what it looks like:
```typescript
interface CustomComponentExtension {
- id: string;
- type: 'customComponent';
- extensionPointIds?: string[];
- content: Slot | Component;
- componentProps?: () => Record;
+ id: string
+ type: 'customComponent'
+ extensionPointIds?: string[]
+ content: Slot | Component
+ componentProps?: () => Record
}
```
@@ -42,7 +42,7 @@ const extension = {
userPreference: {
optionLabel: $gettext('Nyan Cat progress bar')
}
-};
+}
```
The `content` property in this example can also be defined as `content: NyanCat`.
diff --git a/docs/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md
index 8cf972396..7862a2a37 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md
@@ -18,18 +18,18 @@ To define a floating action button extension, you implement the `FloatingActionB
```typescript
interface FloatingActionButtonExtension {
- id: string;
- type: 'floatingActionButton';
- extensionPointIds?: string[];
- label: () => string;
- tooltip?: () => string;
- isVisible?: () => boolean;
- isDisabled?: () => boolean;
- color?: string;
- icon?: string;
- mode: () => 'drop' | 'handler';
- handler?: () => Promise | void;
- dropComponent?: Component;
+ id: string
+ type: 'floatingActionButton'
+ extensionPointIds?: string[]
+ label: () => string
+ tooltip?: () => string
+ isVisible?: () => boolean
+ isDisabled?: () => boolean
+ color?: string
+ icon?: string
+ mode: () => 'drop' | 'handler'
+ handler?: () => Promise | void
+ dropComponent?: Component
}
```
@@ -46,14 +46,14 @@ The `mode` property determines whether the floating action button triggers a han
The following example shows how the files app is registering a floating action button extension for creating new files or folders. Note that the example assumes you're in a Vue injection context (e.g. within the `setup` method of your app's `defineWebApplication` call).
```typescript title="src/extensions.ts"
-import { useGettext } from 'vue3-gettext';
-import CreateOrUploadMenu from './components/CreateOrUploadMenu.vue';
-import { markRaw } from 'vue';
-import { useIsFilesAppActive, useResourcesStore } from '@opencloud-eu/web-pkg';
+import { useGettext } from 'vue3-gettext'
+import CreateOrUploadMenu from './components/CreateOrUploadMenu.vue'
+import { markRaw } from 'vue'
+import { useIsFilesAppActive, useResourcesStore } from '@opencloud-eu/web-pkg'
-const { $gettext } = useGettext();
-const isFilesAppActive = useIsFilesAppActive();
-const resourcesStore = useResourcesStore();
+const { $gettext } = useGettext()
+const isFilesAppActive = useIsFilesAppActive()
+const resourcesStore = useResourcesStore()
const extension = {
id: 'com.github.opencloud-eu.web.files.floating-action-button',
@@ -62,12 +62,12 @@ const extension = {
icon: 'add',
label: () => $gettext('New'),
isVisible: () => {
- return unref(isFilesAppActive);
+ return unref(isFilesAppActive)
},
isDisabled: () => {
- return !resourcesStore.currentFolder?.canUpload();
+ return !resourcesStore.currentFolder?.canUpload()
},
mode: () => 'drop',
dropComponent: markRaw(CreateOrUploadMenu)
-};
+}
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md
index 4795c81cd..2f6f29846 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md
@@ -14,10 +14,10 @@ This is what the FolderViewExtension interface looks like:
```typescript
interface FolderViewExtension {
- id: string;
- type: 'folderView';
- extensionPointIds?: string[];
- folderView: FolderView; // See FolderView section below
+ id: string
+ type: 'folderView'
+ extensionPointIds?: string[]
+ folderView: FolderView // See FolderView section below
}
```
@@ -39,7 +39,7 @@ The following example shows how an extension for a custom folder view could look
```typescript title="src/extensions.ts"
export const useCustomFolderViewExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.folder-view.custom',
@@ -54,10 +54,10 @@ export const useCustomFolderViewExtension = () => {
},
component: YourCustomFolderViewComponent
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -65,7 +65,7 @@ The extension could then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useCustomFolderViewExtension();
+ const { extension } = useCustomFolderViewExtension()
return {
appInfo: {
@@ -73,7 +73,7 @@ export default defineWebApplication({
id: 'custom-folder-view-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md
index a683a971a..ed10603ce 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md
@@ -14,10 +14,10 @@ To define a left sidebar menu item, you implement the `SidebarNavExtension` inte
```typescript
interface SidebarNavExtension {
- id: string;
- type: 'sidebarNav';
- extensionPointIds?: string[];
- navItem: AppNavigationItem; // Please check the AppNavigationItem section below
+ id: string
+ type: 'sidebarNav'
+ extensionPointIds?: string[]
+ navItem: AppNavigationItem // Please check the AppNavigationItem section below
}
```
@@ -42,15 +42,15 @@ Please check the [`AppNavigationItem` type](https://github.com/opencloud-eu/web/
The following example is taken from the [office settings app](https://github.com/opencloud-eu/web/blob/main/packages/web-app-office-settings/src/index.ts). It adds a nav item to the left sidebar of the admin settings app, linking to a view of the office settings app.
```typescript title="src/index.ts"
-import { defineWebApplication, SidebarNavExtension } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
-import { computed } from 'vue';
-import App from './App.vue';
+import { defineWebApplication, SidebarNavExtension } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
+import { computed } from 'vue'
+import App from './App.vue'
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
- const appId = 'admin-settings/office';
+ const { $gettext } = useGettext()
+ const appId = 'admin-settings/office'
const extensions = computed(() => [
{
@@ -66,7 +66,7 @@ export default defineWebApplication({
}
}
}
- ]);
+ ])
const routes = [
{
@@ -78,7 +78,7 @@ export default defineWebApplication({
authContext: 'user'
}
}
- ];
+ ]
return {
appInfo: {
@@ -87,7 +87,7 @@ export default defineWebApplication({
},
routes,
extensions
- };
+ }
}
-});
+})
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/resource-indicator-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/resource-indicator-extensions.md
index 85e5da0a6..f5729cc67 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/resource-indicator-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/resource-indicator-extensions.md
@@ -16,10 +16,10 @@ like:
```typescript
interface ResourceIndicatorExtension {
- id: string;
- type: 'resourceIndicator';
- extensionPointIds?: string[];
- getResourceIndicators: (resource: Resource) => ResourceIndicator[] | void;
+ id: string
+ type: 'resourceIndicator'
+ extensionPointIds?: string[]
+ getResourceIndicators: (resource: Resource) => ResourceIndicator[] | void
}
```
@@ -32,25 +32,25 @@ An indicator is either an icon or a tag:
```typescript
interface ResourceIndicatorIcon {
- id: string;
- kind: 'icon';
- label: string;
- accessibleDescription: string;
- type: string;
- category: 'system' | 'sharing' | 'space';
- icon: string;
- fillType: IconFillType;
- handler?: (resource: Resource, event?: MouseEvent) => void;
+ id: string
+ kind: 'icon'
+ label: string
+ accessibleDescription: string
+ type: string
+ category: 'system' | 'sharing' | 'space'
+ icon: string
+ fillType: IconFillType
+ handler?: (resource: Resource, event?: MouseEvent) => void
}
interface ResourceIndicatorTag {
- id: string;
- kind: 'tag';
- label: string;
- accessibleDescription: string;
- type: string;
- category: 'system' | 'sharing' | 'space';
- class?: string;
+ id: string
+ kind: 'tag'
+ label: string
+ accessibleDescription: string
+ type: string
+ category: 'system' | 'sharing' | 'space'
+ class?: string
}
```
@@ -65,7 +65,7 @@ const extension: ResourceIndicatorExtension = {
extensionPointIds: ['global.files.resource-indicator'],
getResourceIndicators(resource) {
if (resource.canRename()) {
- return;
+ return
}
return [
@@ -79,7 +79,7 @@ const extension: ResourceIndicatorExtension = {
category: 'system',
type: 'read-only'
}
- ];
+ ]
}
-};
+}
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md
index 1351c586b..f24c53774 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md
@@ -21,10 +21,10 @@ It can be found below:
```typescript
interface SidebarPanelExtension {
- id: string;
- type: 'sidebarPanel';
- extensionPointIds?: string[];
- panel: SideBarPanel; // Please check the SideBarPanel section below
+ id: string
+ type: 'sidebarPanel'
+ extensionPointIds?: string[]
+ panel: SideBarPanel // Please check the SideBarPanel section below
}
```
@@ -37,9 +37,9 @@ The `panel` object configures the actual sidebar panel. It consists of different
```typescript
interface SideBarPanelContext {
- root?: R;
- parent?: P;
- items?: T[];
+ root?: R
+ parent?: P
+ items?: T[]
}
```
@@ -54,14 +54,14 @@ interface SideBarPanelContext {
```typescript
interface SideBarPanel {
- name: string;
- icon: string;
- iconFillType?: IconFillType;
- title(context: SideBarPanelContext): string;
- isVisible(context: SideBarPanelContext): boolean;
- component: Component;
- componentAttrs?(context: SideBarPanelContext): any;
- isRoot?(context: SideBarPanelContext): boolean;
+ name: string
+ icon: string
+ iconFillType?: IconFillType
+ title(context: SideBarPanelContext): string
+ isVisible(context: SideBarPanelContext): boolean
+ component: Component
+ componentAttrs?(context: SideBarPanelContext): any
+ isRoot?(context: SideBarPanelContext): boolean
}
```
@@ -85,7 +85,7 @@ The following example shows how a sidebar panel for displaying exif data for a r
```typescript title="src/extensions.ts"
export const useExifDataPanelExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed>(() => ({
id: 'com.github.opencloud-eu.web.files.sidebar-panel.exif-data',
@@ -99,16 +99,16 @@ export const useExifDataPanelExtension = () => {
isRoot: () => true,
isVisible: ({ items }) => {
if (items?.length !== 1) {
- return false;
+ return false
}
- return true;
+ return true
}
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension can then be registered in any app like so:
@@ -116,7 +116,7 @@ The extension can then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useExifDataPanelExtension();
+ const { extension } = useExifDataPanelExtension()
return {
appInfo: {
@@ -124,7 +124,7 @@ export default defineWebApplication({
id: 'exif-panel-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/search-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/search-extensions.md
index 1971be525..71b292790 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/search-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/search-extensions.md
@@ -15,16 +15,16 @@ An example of a search extension configuration can be found below:
```typescript
interface SearchExtension {
- id: string;
- type: 'search';
- extensionPointIds?: string[];
+ id: string
+ type: 'search'
+ extensionPointIds?: string[]
searchProvider: {
- id: string;
- available: boolean;
- displayName?: string;
- previewSearch?: SearchPreview; // See SearchPreview section below
- listSearch?: SearchList; // See SearchList section below
- };
+ id: string
+ available: boolean
+ displayName?: string
+ previewSearch?: SearchPreview // See SearchPreview section below
+ listSearch?: SearchList // See SearchList section below
+ }
}
```
@@ -57,32 +57,32 @@ The following example shows how a search extension that queries a Solr search en
```typescript title="src/extensions.ts"
export const useSolrSearchExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const previewSearch: SearchPreview = {
component: SolarSearchComponent, // see the next example snippet
available: () => true,
search: (term) => {
// actual search implementation
- console.log('Querying solr search engine...');
+ console.log('Querying solr search engine...')
}
- };
+ }
const searchProvider: SearchProvider = {
id: 'solr-search',
available: true,
displayName: 'Solr Search',
previewSearch
- };
+ }
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.solr-search',
type: 'search',
searchProvider
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The search component for the preview search container may look like this:
@@ -93,13 +93,13 @@ The search component for the preview search container may look like this:
```
@@ -108,7 +108,7 @@ The extension can then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useSolrSearchExtension();
+ const { extension } = useSolrSearchExtension()
return {
appInfo: {
@@ -116,7 +116,7 @@ export default defineWebApplication({
id: 'solrs-search-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/docs/dev/web/extension-system/extensions/extension-types/vault-extensions.md b/docs/dev/web/extension-system/extensions/extension-types/vault-extensions.md
index 436a3a404..f2e4f985d 100644
--- a/docs/dev/web/extension-system/extensions/extension-types/vault-extensions.md
+++ b/docs/dev/web/extension-system/extensions/extension-types/vault-extensions.md
@@ -24,12 +24,12 @@ To define a vault extension, you implement the `VaultExtension` interface. Here'
```typescript
interface VaultExtension {
- id: string;
- type: 'vault';
- extensionPointIds?: string[];
- claimsPath: (space: SpaceResource, path: string) => VaultClaim | null;
- resolve: (space: SpaceResource, path: string) => Promise;
- creation?: VaultCreation;
+ id: string
+ type: 'vault'
+ extensionPointIds?: string[]
+ claimsPath: (space: SpaceResource, path: string) => VaultClaim | null
+ resolve: (space: SpaceResource, path: string) => Promise
+ creation?: VaultCreation
}
```
@@ -46,9 +46,9 @@ For `id`, `type`, and `extensionPointIds`, please see [base configuration sectio
```typescript
interface VaultClaim {
- vaultRoot: string;
- encryptsNames: boolean;
- unlockRoute?: RouteLocationNamedRaw;
+ vaultRoot: string
+ encryptsNames: boolean
+ unlockRoute?: RouteLocationNamedRaw
}
```
@@ -64,14 +64,14 @@ bare resource name is a relative path with one segment, so a name must encrypt i
```typescript
interface VaultEngine {
- vaultRoot: string;
- encryptPath: (relativePath: string) => Promise;
- decryptPath: (relativePath: string) => Promise;
- encryptContent: (plaintext: ReadableStream) => ReadableStream;
- decryptContent: (encrypted: ReadableStream) => ReadableStream;
- createIntegrityToken: () => Promise;
- verifyIntegrityToken: (token: string) => Promise;
- verifySegment: (sampleEncryptedSegment: string) => Promise;
+ vaultRoot: string
+ encryptPath: (relativePath: string) => Promise
+ decryptPath: (relativePath: string) => Promise
+ encryptContent: (plaintext: ReadableStream) => ReadableStream
+ decryptContent: (encrypted: ReadableStream) => ReadableStream
+ createIntegrityToken: () => Promise
+ verifyIntegrityToken: (token: string) => Promise
+ verifySegment: (sampleEncryptedSegment: string) => Promise
}
```
@@ -86,9 +86,9 @@ calling the engine directly.
```typescript
interface VaultCreation {
- vaultExtension: string;
- vaultContentType: string;
- setupComponent: Component;
+ vaultExtension: string
+ vaultContentType: string
+ setupComponent: Component
}
```
@@ -101,23 +101,23 @@ interface VaultCreation {
### Example
```typescript title="src/extensions.ts"
-import { markRaw } from 'vue';
-import { VaultExtension } from '@opencloud-eu/web-pkg';
-import VaultSetup from './components/VaultSetup.vue';
+import { markRaw } from 'vue'
+import { VaultExtension } from '@opencloud-eu/web-pkg'
+import VaultSetup from './components/VaultSetup.vue'
export const vaultSchemeExtension: VaultExtension = {
id: 'app.rclone-crypt.vault',
type: 'vault',
resolve(space, path) {
- return Promise.resolve(resolveVault(space, path));
+ return Promise.resolve(resolveVault(space, path))
},
claimsPath(space, path) {
- return claimsVaultPath(space, path);
+ return claimsVaultPath(space, path)
},
creation: {
vaultExtension: 'vault',
vaultContentType: 'application/vnd.opencloud.vault',
setupComponent: markRaw(VaultSetup)
}
-};
+}
```
diff --git a/docs/dev/web/extension-system/extensions/index.md b/docs/dev/web/extension-system/extensions/index.md
index d8bff39f5..71655bce9 100644
--- a/docs/dev/web/extension-system/extensions/index.md
+++ b/docs/dev/web/extension-system/extensions/index.md
@@ -34,8 +34,8 @@ The `extensions` key of an app definition takes a `Ref`, so use a `
content when your app is loaded:
```typescript title="src/index.ts"
-import { defineWebApplication, Extension } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
+import { defineWebApplication, Extension } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
export default defineWebApplication({
setup() {
@@ -48,7 +48,7 @@ export default defineWebApplication({
// See the action extension docs
}
}
- ]);
+ ])
return {
appInfo: {
@@ -56,9 +56,9 @@ export default defineWebApplication({
id: 'my-app'
},
extensions
- };
+ }
}
-});
+})
```
Because the value is a ref, the list is reactive. You can hide or show an extension based on the app config, the
@@ -67,10 +67,10 @@ capabilities of the server, or the permissions of the user:
```typescript
const extensions = computed(() => {
if (!unref(isFeatureAvailable)) {
- return [];
+ return []
}
- return [myExtension];
-});
+ return [myExtension]
+})
```
### At runtime
@@ -79,17 +79,17 @@ You can also register extensions from any place that has access to the injection
composable:
```typescript
-import { useExtensionRegistry } from '@opencloud-eu/web-pkg';
+import { useExtensionRegistry } from '@opencloud-eu/web-pkg'
-const extensionRegistry = useExtensionRegistry();
+const extensionRegistry = useExtensionRegistry()
-extensionRegistry.registerExtensions(computed(() => [myExtension]));
+extensionRegistry.registerExtensions(computed(() => [myExtension]))
```
Remove them again via `unregisterExtensions`, which takes the ids:
```typescript
-extensionRegistry.unregisterExtensions([myExtension.id]);
+extensionRegistry.unregisterExtensions([myExtension.id])
```
Prefer the app definition. Use the runtime API only when the extensions are not known at that point, for example because
@@ -106,14 +106,14 @@ Use `requestExtensions` to get all extensions of an extension point. The registr
`type` matches the `extensionType` of the extension point, and whose `extensionPointIds` allow this extension point:
```typescript
-import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
+import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
-const extensionRegistry = useExtensionRegistry();
+const extensionRegistry = useExtensionRegistry()
const actions = computed(() =>
extensionRegistry.requestExtensions(myExtensionPoint).map(({ action }) => action)
-);
+)
```
To learn how to define `myExtensionPoint`, please refer to the
diff --git a/docs/dev/web/extension-system/getting-started.md b/docs/dev/web/extension-system/getting-started.md
index 595abec01..ebdd5ac2b 100644
--- a/docs/dev/web/extension-system/getting-started.md
+++ b/docs/dev/web/extension-system/getting-started.md
@@ -88,7 +88,7 @@ The `src/index.ts` file acts as the entrypoint of the app. This file has to expo
```typescript title="src/index.ts"
import { defineWebApplication } from '@opencloud-eu/web-pkg'
-import { useGettext } from 'vue3-gettext';
+import { useGettext } from 'vue3-gettext'
// Needs to be unique within all installed applications in any OpenCloud
// web instance. Should be short, unique and expressive as it is used as
@@ -98,7 +98,7 @@ const appId = 'your-app'
export default defineWebApplication({
setup({ applicationConfig }) {
// Here, you have access to the full injection context.
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
return {
appInfo: {
@@ -136,11 +136,11 @@ Apps are built with [Vite](https://vite.dev/). The `@opencloud-eu/extension-sdk`
config, so your `vite.config.ts` stays short:
```typescript title="vite.config.ts"
-import { defineConfig } from '@opencloud-eu/extension-sdk';
+import { defineConfig } from '@opencloud-eu/extension-sdk'
export default defineConfig({
name: 'my-app'
-});
+})
```
`defineConfig` accepts any [Vite option](https://vite.dev/config/), plus the following:
diff --git a/docs/dev/web/extension-system/viewer-editor-apps/collaborative-editing.md b/docs/dev/web/extension-system/viewer-editor-apps/collaborative-editing.md
index f1bcb0a23..eb5c37976 100644
--- a/docs/dev/web/extension-system/viewer-editor-apps/collaborative-editing.md
+++ b/docs/dev/web/extension-system/viewer-editor-apps/collaborative-editing.md
@@ -45,15 +45,15 @@ Collaboration is a `yjs` option on `AppWrapperRoute`. The rest of the app setup
app:
```typescript title="src/index.ts"
-import { AppWrapperRoute, defineWebApplication } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
-import App from './App.vue';
-import { makeMyAdapter } from './yjs';
+import { AppWrapperRoute, defineWebApplication } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
+import App from './App.vue'
+import { makeMyAdapter } from './yjs'
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
- const appId = 'my-editor';
+ const { $gettext } = useGettext()
+ const appId = 'my-editor'
const routes = [
{
@@ -75,7 +75,7 @@ export default defineWebApplication({
patchCleanPath: true
}
}
- ];
+ ]
return {
appInfo: {
@@ -85,9 +85,9 @@ export default defineWebApplication({
extensions: [{ extension: 'md', routeName: appId }]
},
routes
- };
+ }
}
-});
+})
```
## The adapter
@@ -98,16 +98,16 @@ content between the native file format and the Y.Doc.
```typescript
interface YjsAdapter {
/** Seed an empty Y.Doc from the file content. Must be a no-op if the doc already has content. */
- hydrate(ydoc: Y.Doc, content: string): void;
+ hydrate(ydoc: Y.Doc, content: string): void
/** Render the current Y.Doc state back to the native file format. */
- serialize(ydoc: Y.Doc): string | Promise;
+ serialize(ydoc: Y.Doc): string | Promise
/** True if the Y.Doc already holds app content. */
- hasContent(ydoc: Y.Doc): boolean;
+ hasContent(ydoc: Y.Doc): boolean
/** Optional. Wipe the shared content so `hasContent` returns false again. */
- reset?(ydoc: Y.Doc): void;
+ reset?(ydoc: Y.Doc): void
}
```
@@ -123,21 +123,21 @@ Rules to keep in mind:
If your editor is built on Tiptap, use `makeTiptapYjsAdapter`. It takes a content strategy and returns a ready adapter:
```typescript title="src/yjs.ts"
-import { ref } from 'vue';
-import type { YjsAdapter, YjsAdapterContext } from '@opencloud-eu/web-pkg';
-import { makeTiptapYjsAdapter, useContentStrategy } from '@opencloud-eu/web-pkg/editor';
+import { ref } from 'vue'
+import type { YjsAdapter, YjsAdapterContext } from '@opencloud-eu/web-pkg'
+import { makeTiptapYjsAdapter, useContentStrategy } from '@opencloud-eu/web-pkg/editor'
export function makeMyAdapter({ resource }: YjsAdapterContext): YjsAdapter {
- const { resolveStrategy } = useContentStrategy();
+ const { resolveStrategy } = useContentStrategy()
const strategy = resolveStrategy('markdown', {
sourceMode: ref(false),
linkPanel: ref(null),
editorZoom: ref(100),
currentResource: resource
- });
+ })
- return makeTiptapYjsAdapter(strategy);
+ return makeTiptapYjsAdapter(strategy)
}
```
@@ -153,20 +153,20 @@ collaborative editors:
```typescript
type YjsEditorSlotProps = {
- resource: Resource;
- space: SpaceResource;
- currentContent: string;
- isReadOnly: boolean;
+ resource: Resource
+ space: SpaceResource
+ currentContent: string
+ isReadOnly: boolean
/** The shared document. */
- ydoc: Y.Doc | null;
+ ydoc: Y.Doc | null
/** Peer presence: cursors, selections and user identity. */
- awareness: Awareness | null;
+ awareness: Awareness | null
/** 'connecting' | 'connected' | 'disconnected' | 'local' */
- yjsStatus: YjsStatus | null;
-};
+ yjsStatus: YjsStatus | null
+}
```
The `AppWrapper` keeps its loading screen up until the session is synced and hydrated. Your component therefore mounts
@@ -174,11 +174,11 @@ against a Y.Doc that is ready, and `ydoc` and `awareness` are never null inside
```html title="src/App.vue"
```
@@ -200,9 +200,9 @@ against a Y.Doc that is ready, and `ydoc` and `awareness` are never null inside
name. A user with several tabs open appears once.
```typescript
-import { useYjsCollaborators } from '@opencloud-eu/web-pkg';
+import { useYjsCollaborators } from '@opencloud-eu/web-pkg'
-const collaborators = useYjsCollaborators(awareness);
+const collaborators = useYjsCollaborators(awareness)
// [{ id, name, color, isSelf }]
```
diff --git a/docs/dev/web/extension-system/viewer-editor-apps/index.md b/docs/dev/web/extension-system/viewer-editor-apps/index.md
index 11ef30ecc..67488aa66 100644
--- a/docs/dev/web/extension-system/viewer-editor-apps/index.md
+++ b/docs/dev/web/extension-system/viewer-editor-apps/index.md
@@ -11,21 +11,21 @@ This section will guide you through the process of implementing such an app with
The `src/index.ts` file for a viewer or editor app may look like this:
```typescript title="src/index.ts"
-import { AppWrapperRoute, defineWebApplication, AppMenuItemExtension } from '@opencloud-eu/web-pkg';
-import { urlJoin } from '@opencloud-eu/web-client';
-import translations from '../l10n/translations.json';
-import { useGettext } from 'vue3-gettext';
-import { computed } from 'vue';
+import { AppWrapperRoute, defineWebApplication, AppMenuItemExtension } from '@opencloud-eu/web-pkg'
+import { urlJoin } from '@opencloud-eu/web-client'
+import translations from '../l10n/translations.json'
+import { useGettext } from 'vue3-gettext'
+import { computed } from 'vue'
// This is the base component of your app.
-import App from './App.vue';
+import App from './App.vue'
export default defineWebApplication({
setup() {
// The ID of your app.
- const appId = 'advanced-pdf-viewer';
+ const appId = 'advanced-pdf-viewer'
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
// This creates a route under which your app can be opened.
// Later, this route will be bound to one or more file extensions.
@@ -42,7 +42,7 @@ export default defineWebApplication({
patchCleanPath: true
}
}
- ];
+ ]
// if you want your app to be present in the app menu on the top left.
const menuItems = computed(() => [
@@ -55,7 +55,7 @@ export default defineWebApplication({
priority: 30,
path: urlJoin(appId)
}
- ]);
+ ])
return {
appInfo: {
@@ -72,7 +72,7 @@ export default defineWebApplication({
// Add this if you want your app to be present in the "New" file menu.
newFileMenu: {
menuTitle() {
- return $gettext('PDF document');
+ return $gettext('PDF document')
}
}
}
@@ -81,28 +81,28 @@ export default defineWebApplication({
routes,
translations,
extensions: menuItems
- };
+ }
}
-});
+})
```
Here is the interface defining the `extensions` property of the `appInfo` object.
```typescript
interface ApplicationFileExtension {
- app?: string;
- extension?: string;
+ app?: string
+ extension?: string
createFileHandler?: (arg: {
- fileName: string;
- space: SpaceResource;
- currentFolder: Resource;
- }) => Promise;
- hasPriority?: boolean;
- label?: string;
- name?: string;
- icon?: string;
- mimeType?: string;
- newFileMenu?: { menuTitle: () => string };
- routeName?: string;
+ fileName: string
+ space: SpaceResource
+ currentFolder: Resource
+ }) => Promise
+ hasPriority?: boolean
+ label?: string
+ name?: string
+ icon?: string
+ mimeType?: string
+ newFileMenu?: { menuTitle: () => string }
+ routeName?: string
}
```
diff --git a/docs/dev/web/testing/e2e-testing-standards.md b/docs/dev/web/testing/e2e-testing-standards.md
index 40d6099f6..4351f15d4 100644
--- a/docs/dev/web/testing/e2e-testing-standards.md
+++ b/docs/dev/web/testing/e2e-testing-standards.md
@@ -61,16 +61,16 @@ Consider including comments defining each section to ease readability.
```typescript
// arrange, set up the initial conditions for the test
// create a property
-await createProperty();
+await createProperty()
// act, perform the action that you want to test
// raise a charge
// this could involve calling methods or functions defined in your page objects
-await raiseCharge();
+await raiseCharge()
// assert, verify that the action had the expected outcome
// confirm charge has been raised
-expect(charge).toBe('raised');
+expect(charge).toBe('raised')
```
## Page Object Model (POM)
@@ -88,25 +88,25 @@ DO π
// add all locators and functions related to the page,
// allowing all tests to reuse them
-import { Locator, Page } from '@playwright/test';
+import { Locator, Page } from '@playwright/test'
export class FooPage {
- #page: Page;
+ #page: Page
constructor({ page }: { page: Page }) {
- this.#page = page;
+ this.#page = page
}
}
// step definition file './steps/ui/foo.ts'
-import { expect } from '@playwright/test';
-import { Then } from '../../environment/fixtures';
-import { FooPage } from '../../support/objects/foo';
+import { expect } from '@playwright/test'
+import { Then } from '../../environment/fixtures'
+import { FooPage } from '../../support/objects/foo'
Then('the error message should be visible', async ({ page }) => {
- const fooPage = new FooPage(page);
- await expect(fooPage.errorMessage).toBeVisible();
-});
+ const fooPage = new FooPage(page)
+ await expect(fooPage.errorMessage).toBeVisible()
+})
```
DO NOT βοΈ
@@ -114,12 +114,12 @@ DO NOT βοΈ
```typescript
// step definition file './steps/ui/foo.ts'
// include locators directly in the step
-import { expect } from '@playwright/test';
-import { Then } from '../../environment/fixtures';
+import { expect } from '@playwright/test'
+import { Then } from '../../environment/fixtures'
Then('the error message should be visible', async ({ page }) => {
- await expect(page.locator('.error-message')).toBeVisible();
-});
+ await expect(page.locator('.error-message')).toBeVisible()
+})
```
## Waiting
@@ -129,7 +129,7 @@ Playwright uses auto-waiting, so we avoid artificial waiting, the exception bein
DO NOT βοΈ
```typescript
-await page.waitForTimeout(5000);
+await page.waitForTimeout(5000)
```
This can cause flaky tests as we can rarely be certain the amount of wait time is enough. It can also unnecessarily increase the test run time. Instead, we can try:
@@ -139,21 +139,21 @@ DO π
```typescript
await page.goto(fooBarURL, {
waitUntil: 'domcontentloaded'
-});
+})
```
DO π
```typescript
-const element = page.locator('some-locator-path');
-element.waitFor({ visible: true });
+const element = page.locator('some-locator-path')
+element.waitFor({ visible: true })
```
DO π
```typescript
-await fooPage.buttonFoo.click();
-await expect(fooPage.titlePage).toBeVisible();
+await fooPage.buttonFoo.click()
+await expect(fooPage.titlePage).toBeVisible()
```
## Selectors
@@ -171,14 +171,14 @@ Instead, we can prioritize the below, based on [testing-library guiding principl
DO NOT βοΈ
```javascript
-page.locator('.opt-u > div > .summary > div:nth-child(4) > div');
+page.locator('.opt-u > div > .summary > div:nth-child(4) > div')
```
DO π
```javascript
-page.locator('#foo-button');
-page.getByText('OK');
+page.locator('#foo-button')
+page.getByText('OK')
```
## Naming Conventions
@@ -197,7 +197,7 @@ Declare in **_camelCase_**.
Start with βisβ, βhasβ, βareβ, βhaveβ. This helps spot that this is a boolean while skimming the code. Still declared in **_camelCase_**.
```typescript
-let isTurnedOn = false;
+let isTurnedOn = false
```
### Page Objects / Classes
@@ -232,14 +232,14 @@ DO π
```typescript
// This element is a submit button for the user registration form
-const submitButton = await page.locator('');
+const submitButton = await page.locator('')
```
DO π
```typescript
// This element is a button for uploading a profile picture
-const uploadProfilePictureButton = await page.locator('');
+const uploadProfilePictureButton = await page.locator('')
```
### Function names
@@ -249,9 +249,9 @@ Always start function names with a **_βverbβ_**, followed by the **_βcompo
DO π
```typescript
-getWorksOrder();
-printTransactions();
-deleteProperty();
+getWorksOrder()
+printTransactions()
+deleteProperty()
```
## Gherkin Best Practices: Do's and Don'ts for Effective Features & Scenarios
diff --git a/prettier.config.js b/prettier.config.js
index 7d3f53bbc..f4e264c55 100644
--- a/prettier.config.js
+++ b/prettier.config.js
@@ -1,4 +1,10 @@
module.exports = {
...require("@opencloud-eu/prettier-config"),
- semi: true
-};
\ No newline at end of file
+ semi: true,
+ overrides: [
+ {
+ files: ["docs/dev/web/**", "versioned_docs/*/dev/web/**"],
+ options: { semi: false }
+ }
+ ]
+};
diff --git a/versioned_docs/version-4.0/dev/web/embed-mode.md b/versioned_docs/version-4.0/dev/web/embed-mode.md
index ad0b32832..206cf9f88 100644
--- a/versioned_docs/version-4.0/dev/web/embed-mode.md
+++ b/versioned_docs/version-4.0/dev/web/embed-mode.md
@@ -40,30 +40,30 @@ To maintain uniformity and ease of handling, each event encapsulates the same st
```
@@ -80,15 +80,15 @@ In special scenarios you also want the user to set a file name, this can be achi
```
@@ -110,15 +110,15 @@ combination of both. If the embed-file-types parameter is not provided, all file
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/action-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/action-extensions.md
index 248dbfc10..06d64bb74 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/action-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/action-extensions.md
@@ -14,10 +14,10 @@ This is what the `ActionExtension` interface looks like:
```typescript
interface ActionExtension {
- id: string;
- type: 'action';
- extensionPointIds?: string[];
- action: Action; // Please check the Action section below
+ id: string
+ type: 'action'
+ extensionPointIds?: string[]
+ action: Action // Please check the Action section below
}
```
@@ -43,7 +43,7 @@ The following example shows how an action extension for downloading files could
```typescript
export const useDownloadFilesExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.download-action',
@@ -56,19 +56,19 @@ export const useDownloadFilesExtension = () => {
label: () => $gettext('Download'),
isVisible: ({ space, resources }) => {
if (resources.length === 0) {
- return false;
+ return false
}
- return true;
+ return true
},
handler: ({ space, resources }) => {
- console.log('Triggering download...');
+ console.log('Triggering download...')
}
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -76,7 +76,7 @@ The extension could then be registered in any app like so:
```typescript
export default defineWebApplication({
setup() {
- const { extension } = useFileActionDownloadFiles();
+ const { extension } = useFileActionDownloadFiles()
return {
appInfo: {
@@ -84,7 +84,7 @@ export default defineWebApplication({
id: 'download-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/app-menu-item-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/app-menu-item-extensions.md
index 1f73b88e0..23da2bdc4 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/app-menu-item-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/app-menu-item-extensions.md
@@ -14,16 +14,16 @@ The Interface for an `AppMenuItemExtension` looks like so:
```typescript
interface AppMenuItemExtension {
- id: string;
- type: 'appMenuItem';
- extensionPointIds?: string[];
- label: () => string;
- color?: string;
- handler?: () => void;
- icon?: string;
- path?: string;
- priority?: number;
- url?: string;
+ id: string
+ type: 'appMenuItem'
+ extensionPointIds?: string[]
+ label: () => string
+ color?: string
+ handler?: () => void
+ icon?: string
+ path?: string
+ priority?: number
+ url?: string
}
```
@@ -46,8 +46,8 @@ The following example shows how an app creates an extension that registers an ap
```typescript
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
- const appId = 'my-cool-app';
+ const { $gettext } = useGettext()
+ const appId = 'my-cool-app'
const menuItems = computed(() => [
{
@@ -59,7 +59,7 @@ export default defineWebApplication({
color: '#0D856F',
priority: 60
}
- ]);
+ ])
return {
appInfo: {
@@ -67,7 +67,7 @@ export default defineWebApplication({
id: appId
},
extensions: menuItems
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/custom-component-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/custom-component-extensions.md
index 06fd5407f..82e50800e 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/custom-component-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/custom-component-extensions.md
@@ -16,10 +16,10 @@ Here's what it looks like:
```typescript
interface CustomComponentExtension {
- id: string;
- type: 'customComponent';
- extensionPointIds?: string[];
- content: Slot | Component;
+ id: string
+ type: 'customComponent'
+ extensionPointIds?: string[]
+ content: Slot | Component
}
```
@@ -41,7 +41,7 @@ const extension = {
userPreference: {
optionLabel: $gettext('Nyan Cat progress bar')
}
-};
+}
```
The `content` property in this example can also be defined as `content: NyanCat`.
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/folder-view-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/folder-view-extensions.md
index 4acf4f8a7..0726b511e 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/folder-view-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/folder-view-extensions.md
@@ -14,10 +14,10 @@ This is what the FolderViewExtension interface looks like:
```typescript
interface FolderViewExtension {
- id: string;
- type: 'folderView';
- extensionPointIds?: string[];
- folderView: FolderView; // See FolderView section below
+ id: string
+ type: 'folderView'
+ extensionPointIds?: string[]
+ folderView: FolderView // See FolderView section below
}
```
@@ -40,7 +40,7 @@ The following example shows how an extension for a custom folder view could look
```typescript
export const useCustomFolderViewExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.folder-view.custom',
@@ -55,10 +55,10 @@ export const useCustomFolderViewExtension = () => {
},
component: YourCustomFolderViewComponent
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -66,7 +66,7 @@ The extension could then be registered in any app like so:
```typescript
export default defineWebApplication({
setup() {
- const { extension } = useCustomFolderViewExtension();
+ const { extension } = useCustomFolderViewExtension()
return {
appInfo: {
@@ -74,7 +74,7 @@ export default defineWebApplication({
id: 'custom-folder-view-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/left-sidebar-menu-item-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/left-sidebar-menu-item-extensions.md
index 29b92b6f0..929107a51 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/left-sidebar-menu-item-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/left-sidebar-menu-item-extensions.md
@@ -42,7 +42,7 @@ The following example shows an extension that adds a left sidebar nav item insid
```typescript
export const useCustomPageExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.left-nav.custom-page',
@@ -59,10 +59,10 @@ export const useCustomPageExtension = () => {
},
activeFor: [{ path: '/files/custom-page' }]
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -70,7 +70,7 @@ The extension could then be registered in any app like so:
```typescript
export default defineWebApplication({
setup() {
- const { extension } = useCustomPageExtension();
+ const { extension } = useCustomPageExtension()
return {
appInfo: {
@@ -86,7 +86,7 @@ export default defineWebApplication({
}
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/right-sidebar-panel-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/right-sidebar-panel-extensions.md
index 018782c5f..f6d149c82 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/right-sidebar-panel-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/right-sidebar-panel-extensions.md
@@ -21,10 +21,10 @@ It can be found below:
```typescript
interface SidebarPanelExtension {
- id: string;
- type: 'sidebarPanel';
- extensionPointIds?: string[];
- panel: SideBarPanel; // Please check the SideBarPanel section below
+ id: string
+ type: 'sidebarPanel'
+ extensionPointIds?: string[]
+ panel: SideBarPanel // Please check the SideBarPanel section below
}
```
@@ -37,9 +37,9 @@ The `panel` object configures the actual sidebar panel. It consists of different
```typescript
interface SideBarPanelContext {
- root?: R;
- parent?: P;
- items?: T[];
+ root?: R
+ parent?: P
+ items?: T[]
}
```
@@ -54,14 +54,14 @@ interface SideBarPanelContext {
```typescript
interface SideBarPanel {
- name: string;
- icon: string;
- iconFillType?: IconFillType;
- title(context: SideBarPanelContext): string;
- isVisible(context: SideBarPanelContext): boolean;
- component: Component;
- componentAttrs?(context: SideBarPanelContext): any;
- isRoot?(context: SideBarPanelContext): boolean;
+ name: string
+ icon: string
+ iconFillType?: IconFillType
+ title(context: SideBarPanelContext): string
+ isVisible(context: SideBarPanelContext): boolean
+ component: Component
+ componentAttrs?(context: SideBarPanelContext): any
+ isRoot?(context: SideBarPanelContext): boolean
}
```
@@ -85,7 +85,7 @@ The following example shows how a sidebar panel for displaying exif data for a r
```typescript
export const useExifDataPanelExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed>(() => ({
id: 'com.github.opencloud-eu.web.files.sidebar-panel.exif-data',
@@ -99,16 +99,16 @@ export const useExifDataPanelExtension = () => {
isRoot: () => true,
isVisible: ({ items }) => {
if (items?.length !== 1) {
- return false;
+ return false
}
- return true;
+ return true
}
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension can then be registered in any app like so:
@@ -116,7 +116,7 @@ The extension can then be registered in any app like so:
```typescript
export default defineWebApplication({
setup() {
- const { extension } = useExifDataPanelExtension();
+ const { extension } = useExifDataPanelExtension()
return {
appInfo: {
@@ -124,7 +124,7 @@ export default defineWebApplication({
id: 'exif-panel-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/search-extensions.md b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/search-extensions.md
index 6f9bf5fa4..9ae746f14 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/extension-types/search-extensions.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/extension-types/search-extensions.md
@@ -15,16 +15,16 @@ An example of a search extension configuration can be found below:
```typescript
interface SearchExtension {
- id: string;
- type: 'search';
- extensionPointIds?: string[];
+ id: string
+ type: 'search'
+ extensionPointIds?: string[]
searchProvider: {
- id: string;
- available: boolean;
- displayName?: string;
- previewSearch?: SearchPreview; // See SearchPreview section below
- listSearch?: SearchList; // See SearchList section below
- };
+ id: string
+ available: boolean
+ displayName?: string
+ previewSearch?: SearchPreview // See SearchPreview section below
+ listSearch?: SearchList // See SearchList section below
+ }
}
```
@@ -57,32 +57,32 @@ The following example shows how a search extension that queries a Solr search en
```typescript
export const useSolrSearchExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const previewSearch: SearchPreview = {
component: SolarSearchComponent, // see the next example snippet
available: () => true,
search: (term) => {
// actual search implementation
- console.log('Querying solr search engine...');
+ console.log('Querying solr search engine...')
}
- };
+ }
const searchProvider: SearchProvider = {
id: 'solr-search',
available: true,
displayName: 'Solr Search',
previewSearch
- };
+ }
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.solr-search',
type: 'search',
searchProvider
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The search component for the preview search container may look like this:
@@ -93,13 +93,13 @@ The search component for the preview search container may look like this:
```
@@ -108,7 +108,7 @@ The extension can then be registered in any app like so:
```typescript
export default defineWebApplication({
setup() {
- const { extension } = useSolrSearchExtension();
+ const { extension } = useSolrSearchExtension()
return {
appInfo: {
@@ -116,7 +116,7 @@ export default defineWebApplication({
id: 'solrs-search-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-4.0/dev/web/extension-system/viewer-editor-apps.md b/versioned_docs/version-4.0/dev/web/extension-system/viewer-editor-apps.md
index 041b1c71a..c310e7e72 100644
--- a/versioned_docs/version-4.0/dev/web/extension-system/viewer-editor-apps.md
+++ b/versioned_docs/version-4.0/dev/web/extension-system/viewer-editor-apps.md
@@ -22,20 +22,20 @@ To learn more about apps in general, please refer to the [Web app docs](.).
Inside the `src` folder you will need an `index.ts` file that sets up the app so it can be registered by the Web runtime. It follows the basic structure as described in [the apps section](.), so it may look like this:
```typescript
-import { AppWrapperRoute, defineWebApplication, AppMenuItemExtension } from '@opencloud-eu/web-pkg';
-import translations from '../l10n/translations.json';
-import { useGettext } from 'vue3-gettext';
-import { computed } from 'vue';
+import { AppWrapperRoute, defineWebApplication, AppMenuItemExtension } from '@opencloud-eu/web-pkg'
+import translations from '../l10n/translations.json'
+import { useGettext } from 'vue3-gettext'
+import { computed } from 'vue'
// This is the base component of your app.
-import App from './App.vue';
+import App from './App.vue'
export default defineWebApplication({
setup() {
// The ID of your app.
- const appId = 'advanced-pdf-viewer';
+ const appId = 'advanced-pdf-viewer'
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
// This creates a route under which your app can be opened.
// Later, this route will be bound to one or more file extensions.
@@ -52,7 +52,7 @@ export default defineWebApplication({
patchCleanPath: true
}
}
- ];
+ ]
// if you want your app to be present in the app menu on the top left.
const menuItems = computed(() => [
@@ -63,7 +63,7 @@ export default defineWebApplication({
// do stuff...
}
}
- ]);
+ ])
return {
appInfo: {
@@ -80,7 +80,7 @@ export default defineWebApplication({
// Add this if you want your app to be present in the "New" file menu.
newFileMenu: {
menuTitle() {
- return $gettext('PDF document');
+ return $gettext('PDF document')
}
}
}
@@ -89,28 +89,28 @@ export default defineWebApplication({
routes,
translations,
extensions: menuItems
- };
+ }
}
-});
+})
```
Here is the interface defining the `extensions` property of the `appInfo` object.
```typescript
interface ApplicationFileExtension {
- app?: string;
- extension?: string;
+ app?: string
+ extension?: string
createFileHandler?: (arg: {
- fileName: string;
- space: SpaceResource;
- currentFolder: Resource;
- }) => Promise;
- hasPriority?: boolean;
- label?: string;
- name?: string;
- icon?: string;
- mimeType?: string;
- newFileMenu?: { menuTitle: () => string };
- routeName?: string;
+ fileName: string
+ space: SpaceResource
+ currentFolder: Resource
+ }) => Promise
+ hasPriority?: boolean
+ label?: string
+ name?: string
+ icon?: string
+ mimeType?: string
+ newFileMenu?: { menuTitle: () => string }
+ routeName?: string
}
```
diff --git a/versioned_docs/version-4.0/dev/web/testing/e2e-testing-standards.md b/versioned_docs/version-4.0/dev/web/testing/e2e-testing-standards.md
index 49cd8b2e5..7609510f0 100644
--- a/versioned_docs/version-4.0/dev/web/testing/e2e-testing-standards.md
+++ b/versioned_docs/version-4.0/dev/web/testing/e2e-testing-standards.md
@@ -61,16 +61,16 @@ Consider including comments defining each section to ease readability.
```typescript
// arrange, set up the initial conditions for the test
// create a property
-await createProperty();
+await createProperty()
// act, perform the action that you want to test
// raise a charge
// this could involve calling methods or functions defined in your page objects
-await raiseCharge();
+await raiseCharge()
// assert, verify that the action had the expected outcome
// confirm charge has been raised
-expect(charge).toBe('raised');
+expect(charge).toBe('raised')
```
## Page Object Model (POM)
@@ -88,26 +88,26 @@ DO π
// add all locators and functions related to the page.
// allowing all tests to reuse
-import { expect, Locator, Page } from '@playwright/test';
+import { expect, Locator, Page } from '@playwright/test'
export class FooPage {
- readonly errorMessage: Locator;
+ readonly errorMessage: Locator
constructor(page: Page) {
- this.page = page;
- this.errorMessage = page.locator('.error-message');
+ this.page = page
+ this.errorMessage = page.locator('.error-message')
}
}
// test file './steps/foo.ts'
-import { FooPage } from './pageObjects/foo';
+import { FooPage } from './pageObjects/foo'
-let fooPage: FooPage;
+let fooPage: FooPage
Then('error message should be visible', async function ({ page }) {
- const fooPage = new FooPage({ page });
- await expect(fooPage.errorMessage).toBeVisible();
-});
+ const fooPage = new FooPage({ page })
+ await expect(fooPage.errorMessage).toBeVisible()
+})
```
DO NOT βοΈ
@@ -115,11 +115,11 @@ DO NOT βοΈ
```typescript
// test file './steps/foo.ts'
// include locators directly in test
-import { Locator, Page } from '@playwright/test';
+import { Locator, Page } from '@playwright/test'
Then('error message should be visible', async function ({ page }) {
- await expect(page.locator('.error-message')).toBeVisible();
-});
+ await expect(page.locator('.error-message')).toBeVisible()
+})
```
## Waiting
@@ -129,7 +129,7 @@ Playwright uses auto-waiting, so we avoid artificial waiting, the exception bein
DO NOT βοΈ
```typescript
-await page.waitForTimeout(5000);
+await page.waitForTimeout(5000)
```
This can cause flaky tests as we can rarely be certain the amount of wait time is enough. It can also unnecessarily increase the test run time. Instead, we can try:
@@ -139,21 +139,21 @@ DO π
```typescript
await page.goto(fooBarURL, {
waitUntil: 'domcontentloaded'
-});
+})
```
DO π
```typescript
-const element = page.locator('some-locator-path');
-element.waitFor({ visible: true });
+const element = page.locator('some-locator-path')
+element.waitFor({ visible: true })
```
DO π
```typescript
-await fooPage.buttonFoo.click();
-await expect(fooPage.titlePage).toBeVisible();
+await fooPage.buttonFoo.click()
+await expect(fooPage.titlePage).toBeVisible()
```
## Selectors
@@ -171,14 +171,14 @@ Instead, we can prioritize the below, based on [testing-library guiding principl
DO NOT βοΈ
```javascript
-page.locator('.opt-u > div > .summary > div:nth-child(4) > div');
+page.locator('.opt-u > div > .summary > div:nth-child(4) > div')
```
DO π
```javascript
-page.locator('#foo-button');
-page.getByText('OK');
+page.locator('#foo-button')
+page.getByText('OK')
```
## Naming Conventions
@@ -197,7 +197,7 @@ Declare in **_camelCase_**.
Start with βisβ, βhasβ, βareβ, βhaveβ. This helps spot that this is a boolean while skimming the code. Still declared in **_camelCase_**.
```typescript
-let isTurnedOn = false;
+let isTurnedOn = false
```
### Page Objects / Classes
@@ -232,14 +232,14 @@ DO π
```typescript
// This element is a submit button for the user registration form
-const submitButton = await page.locator('');
+const submitButton = await page.locator('')
```
DO π
```typescript
// This element is a button for uploading a profile picture
-const uploadProfilePictureButton = await page.locator('');
+const uploadProfilePictureButton = await page.locator('')
```
### Function names
@@ -249,9 +249,9 @@ Always start function names with a **_βverbβ_**, followed by the **_βcompo
DO π
```typescript
-getWorksOrder();
-printTransactions();
-deleteProperty();
+getWorksOrder()
+printTransactions()
+deleteProperty()
```
## Gherkin Best Practices: Do's and Don'ts for Effective Features & Scenarios
diff --git a/versioned_docs/version-7.2/dev/web/embed-mode.md b/versioned_docs/version-7.2/dev/web/embed-mode.md
index ad0b32832..206cf9f88 100644
--- a/versioned_docs/version-7.2/dev/web/embed-mode.md
+++ b/versioned_docs/version-7.2/dev/web/embed-mode.md
@@ -40,30 +40,30 @@ To maintain uniformity and ease of handling, each event encapsulates the same st
```
@@ -80,15 +80,15 @@ In special scenarios you also want the user to set a file name, this can be achi
```
@@ -110,15 +110,15 @@ combination of both. If the embed-file-types parameter is not provided, all file
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/configuration.md b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/configuration.md
index 84024cd6b..9a71604b5 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/configuration.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/configuration.md
@@ -42,15 +42,15 @@ There are two ways to override the defaults:
The merged config is passed to the `setup` function of your app definition as `applicationConfig`:
```typescript title="src/index.ts"
-import { defineWebApplication } from '@opencloud-eu/web-pkg';
+import { defineWebApplication } from '@opencloud-eu/web-pkg'
export default defineWebApplication({
setup({ applicationConfig }) {
- const showPreview = applicationConfig?.showPreview ?? true;
+ const showPreview = applicationConfig?.showPreview ?? true
// ...
}
-});
+})
```
Always provide a fallback value. The config can be empty, and an administrator can set any value.
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/styling.md b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/styling.md
index 9600b3127..3f3a3b89a 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/styling.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/styling.md
@@ -33,7 +33,7 @@ The `@opencloud-eu/extension-sdk` package ships a preconfigured [Tailwind CSS](h
its stylesheet in your entrypoint (typically `src/index.ts`) to use it:
```typescript title="src/index.ts"
-import '@opencloud-eu/extension-sdk/tailwind.css';
+import '@opencloud-eu/extension-sdk/tailwind.css'
```
Tailwind classes need the `ext:` prefix in apps. The prefix avoids style conflicts with the OpenCloud Web runtime.
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/testing.md b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/testing.md
index 5af9fc9d3..47660df40 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/testing.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/testing.md
@@ -20,15 +20,15 @@ The `@opencloud-eu/web-test-helpers` package provides utilities for mounting com
context. Without them, every component that uses a composable of `web-pkg` fails to mount.
```typescript title="tests/unit/App.spec.ts"
-import { defaultPlugins, mount } from '@opencloud-eu/web-test-helpers';
-import App from '../../src/App.vue';
+import { defaultPlugins, mount } from '@opencloud-eu/web-test-helpers'
+import App from '../../src/App.vue'
describe('App', () => {
it('renders the title', () => {
- const wrapper = mount(App, { global: { plugins: [...defaultPlugins()] } });
- expect(wrapper.text()).toContain('My app');
- });
-});
+ const wrapper = mount(App, { global: { plugins: [...defaultPlugins()] } })
+ expect(wrapper.text()).toContain('My app')
+ })
+})
```
For details, please refer to the package's
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/translations.md b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/translations.md
index 0485a2686..8decd3737 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/translations.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/advanced-topics/translations.md
@@ -14,11 +14,11 @@ Translations are optional. An app without them simply shows its original strings
In a script or a composable, get `$gettext` from `useGettext`:
```typescript
-import { useGettext } from 'vue3-gettext';
+import { useGettext } from 'vue3-gettext'
-const { $gettext } = useGettext();
+const { $gettext } = useGettext()
-const title = $gettext('Your application name');
+const title = $gettext('Your application name')
```
In a template, `$gettext` is globally available:
@@ -33,20 +33,20 @@ Pass variables as an object. Use the `%{name}` syntax in the string, never strin
changes between languages:
```typescript
-$gettext('Open Β«%{resource}Β»', { resource: resource.name });
+$gettext('Open Β«%{resource}Β»', { resource: resource.name })
```
For plurals, use `$ngettext` with the singular form, the plural form, the count, and the variables:
```typescript
-const { $ngettext } = useGettext();
+const { $ngettext } = useGettext()
$ngettext(
'Delete the selected resource?',
'Delete %{amount} selected resources?',
resources.length,
{ amount: resources.length.toString() }
-);
+)
```
:::warning
@@ -76,7 +76,7 @@ module.exports = {
flat: false,
linguas: false
}
-};
+}
```
Add two scripts to your `package.json`:
@@ -105,13 +105,13 @@ Import `translations.json` and return it from your app definition. The Web runti
translations when your app is loaded.
```typescript title="src/index.ts"
-import { defineWebApplication } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
-import translations from '../l10n/translations.json';
+import { defineWebApplication } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
+import translations from '../l10n/translations.json'
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
return {
appInfo: {
@@ -119,9 +119,9 @@ export default defineWebApplication({
id: 'your-app'
},
translations
- };
+ }
}
-});
+})
```
The file is a map of language key to message map:
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-points.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-points.md
index ae1440c0a..432b1f96c 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-points.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-points.md
@@ -100,13 +100,13 @@ An extension point is a plain object of the `ExtensionPoint` type. Keep it in it
`src/extensionPoints.ts`, so that you can use it in several places:
```typescript title="src/extensionPoints.ts"
-import { ActionExtension, ExtensionPoint } from '@opencloud-eu/web-pkg';
+import { ActionExtension, ExtensionPoint } from '@opencloud-eu/web-pkg'
export const toolbarExtensionPoint: ExtensionPoint = {
id: 'app.my-app.toolbar',
extensionType: 'action',
multiple: true
-};
+}
```
`ExtensionPoint` accepts the following keys:
@@ -123,9 +123,9 @@ export const toolbarExtensionPoint: ExtensionPoint = {
Return your extension points from the app definition. The key takes a `Ref`, so use a `computed`:
```typescript title="src/index.ts"
-import { defineWebApplication } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
-import { toolbarExtensionPoint } from './extensionPoints';
+import { defineWebApplication } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
+import { toolbarExtensionPoint } from './extensionPoints'
export default defineWebApplication({
setup() {
@@ -135,9 +135,9 @@ export default defineWebApplication({
id: 'my-app'
},
extensionPoints: computed(() => [toolbarExtensionPoint])
- };
+ }
}
-});
+})
```
Registration is not needed to query extensions. It makes your extension point known to the runtime, which is required
@@ -154,25 +154,25 @@ the registry and respects the user preference:
```
For all other types, query the registry yourself and render the result the way your extension point needs it:
```typescript
-import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
-import { toolbarExtensionPoint } from './extensionPoints';
+import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
+import { toolbarExtensionPoint } from './extensionPoints'
-const extensionRegistry = useExtensionRegistry();
+const extensionRegistry = useExtensionRegistry()
const actions = computed(() =>
extensionRegistry
.requestExtensions(toolbarExtensionPoint)
.map(({ action }) => action)
-);
+)
```
### Letting users choose
@@ -181,10 +181,10 @@ Add a `userPreference` to your extension point to let users pick one of the regi
sense when `multiple` is `false`:
```typescript title="src/extensionPoints.ts"
-import { ExtensionPoint, CustomComponentExtension } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
+import { ExtensionPoint, CustomComponentExtension } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
-const { $gettext } = useGettext();
+const { $gettext } = useGettext()
export const progressBarExtensionPoint: ExtensionPoint = {
id: 'app.my-app.progress-bar',
@@ -193,7 +193,7 @@ export const progressBarExtensionPoint: ExtensionPoint
label: $gettext('Progress bar'),
description: $gettext('Choose how the loading state is shown.')
}
-};
+}
```
The extension point then gets a dropdown on the preferences page, reachable via the top right user menu. The dropdown
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/account-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/account-extensions.md
index a25f38c4f..42afb6bea 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/account-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/account-extensions.md
@@ -15,12 +15,12 @@ To define an account extension, you implement the `AccountExtension` interface.
```typescript
interface AccountExtension {
- id: string;
- type: 'accountExtension';
- extensionPointIds?: string[];
- content: Slot | Component;
- label: () => string;
- icon: string;
+ id: string
+ type: 'accountExtension'
+ extensionPointIds?: string[]
+ content: Slot | Component
+ label: () => string
+ icon: string
}
```
@@ -42,5 +42,5 @@ const extension: AccountExtension = {
label: () => $gettext('App Tokens'),
icon: 'key-2',
content: AppTokens
-};
+}
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/action-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/action-extensions.md
index fca7b2080..83a556f39 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/action-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/action-extensions.md
@@ -14,10 +14,10 @@ This is what the `ActionExtension` interface looks like:
```typescript
interface ActionExtension {
- id: string;
- type: 'action';
- extensionPointIds?: string[];
- action: Action; // Please check the Action section below
+ id: string
+ type: 'action'
+ extensionPointIds?: string[]
+ action: Action // Please check the Action section below
}
```
@@ -43,7 +43,7 @@ The following example shows how an action extension for downloading files could
```typescript title="src/extensions.ts"
export const useDownloadFilesExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.download-action',
@@ -56,19 +56,19 @@ export const useDownloadFilesExtension = () => {
label: () => $gettext('Download'),
isVisible: ({ space, resources }) => {
if (resources.length === 0) {
- return false;
+ return false
}
- return true;
+ return true
},
handler: ({ space, resources }) => {
- console.log('Triggering download...');
+ console.log('Triggering download...')
}
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -76,7 +76,7 @@ The extension could then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useFileActionDownloadFiles();
+ const { extension } = useFileActionDownloadFiles()
return {
appInfo: {
@@ -84,7 +84,7 @@ export default defineWebApplication({
id: 'download-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md
index 152ba7ca8..f2cc59f14 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/app-menu-item-extensions.md
@@ -14,16 +14,16 @@ The Interface for an `AppMenuItemExtension` looks like so:
```typescript
interface AppMenuItemExtension {
- id: string;
- type: 'appMenuItem';
- extensionPointIds?: string[];
- label: () => string;
- color?: string;
- handler?: () => Promise | void;
- icon?: string;
- path?: string;
- priority?: number;
- url?: string;
+ id: string
+ type: 'appMenuItem'
+ extensionPointIds?: string[]
+ label: () => string
+ color?: string
+ handler?: () => Promise | void
+ icon?: string
+ path?: string
+ priority?: number
+ url?: string
}
```
@@ -46,8 +46,8 @@ The following example shows how an app creates an extension that registers an ap
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
- const appId = 'my-cool-app';
+ const { $gettext } = useGettext()
+ const appId = 'my-cool-app'
const menuItems = computed(() => [
{
@@ -59,7 +59,7 @@ export default defineWebApplication({
color: '#0D856F',
priority: 60
}
- ]);
+ ])
return {
appInfo: {
@@ -67,7 +67,7 @@ export default defineWebApplication({
id: appId
},
extensions: menuItems
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md
index 5ff4af3ee..39c1bb9ac 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/custom-component-extensions.md
@@ -16,11 +16,11 @@ Here's what it looks like:
```typescript
interface CustomComponentExtension {
- id: string;
- type: 'customComponent';
- extensionPointIds?: string[];
- content: Slot | Component;
- componentProps?: () => Record;
+ id: string
+ type: 'customComponent'
+ extensionPointIds?: string[]
+ content: Slot | Component
+ componentProps?: () => Record
}
```
@@ -42,7 +42,7 @@ const extension = {
userPreference: {
optionLabel: $gettext('Nyan Cat progress bar')
}
-};
+}
```
The `content` property in this example can also be defined as `content: NyanCat`.
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md
index d65c415bc..bfff57498 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/floating-action-button-extensions.md
@@ -18,17 +18,17 @@ To define a floating action button extension, you implement the `FloatingActionB
```typescript
interface FloatingActionButtonExtension {
- id: string;
- type: 'floatingActionButton';
- extensionPointIds?: string[];
- label: () => string;
- isVisible?: () => boolean;
- isDisabled?: () => boolean;
- color?: string;
- icon?: string;
- mode: () => 'drop' | 'handler';
- handler?: () => Promise | void;
- dropComponent?: Component;
+ id: string
+ type: 'floatingActionButton'
+ extensionPointIds?: string[]
+ label: () => string
+ isVisible?: () => boolean
+ isDisabled?: () => boolean
+ color?: string
+ icon?: string
+ mode: () => 'drop' | 'handler'
+ handler?: () => Promise | void
+ dropComponent?: Component
}
```
@@ -45,14 +45,14 @@ The `mode` property determines whether the floating action button triggers a han
The following example shows how the files app is registering a floating action button extension for creating new files or folders. Note that the example assumes you're in a Vue injection context (e.g. within the `setup` method of your app's `defineWebApplication` call).
```typescript title="src/extensions.ts"
-import { useGettext } from 'vue3-gettext';
-import CreateOrUploadMenu from './components/CreateOrUploadMenu.vue';
-import { markRaw } from 'vue';
-import { useIsFilesAppActive, useResourcesStore } from '@opencloud-eu/web-pkg';
+import { useGettext } from 'vue3-gettext'
+import CreateOrUploadMenu from './components/CreateOrUploadMenu.vue'
+import { markRaw } from 'vue'
+import { useIsFilesAppActive, useResourcesStore } from '@opencloud-eu/web-pkg'
-const { $gettext } = useGettext();
-const isFilesAppActive = useIsFilesAppActive();
-const resourcesStore = useResourcesStore();
+const { $gettext } = useGettext()
+const isFilesAppActive = useIsFilesAppActive()
+const resourcesStore = useResourcesStore()
const extension = {
id: 'com.github.opencloud-eu.web.files.floating-action-button',
@@ -61,12 +61,12 @@ const extension = {
icon: 'add',
label: () => $gettext('New'),
isVisible: () => {
- return unref(isFilesAppActive);
+ return unref(isFilesAppActive)
},
isDisabled: () => {
- return !resourcesStore.currentFolder?.canUpload();
+ return !resourcesStore.currentFolder?.canUpload()
},
mode: () => 'drop',
dropComponent: markRaw(CreateOrUploadMenu)
-};
+}
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md
index 14d14ae6c..2bd685135 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/folder-view-extensions.md
@@ -14,10 +14,10 @@ This is what the FolderViewExtension interface looks like:
```typescript
interface FolderViewExtension {
- id: string;
- type: 'folderView';
- extensionPointIds?: string[];
- folderView: FolderView; // See FolderView section below
+ id: string
+ type: 'folderView'
+ extensionPointIds?: string[]
+ folderView: FolderView // See FolderView section below
}
```
@@ -39,7 +39,7 @@ The following example shows how an extension for a custom folder view could look
```typescript title="src/extensions.ts"
export const useCustomFolderViewExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.files.folder-view.custom',
@@ -54,10 +54,10 @@ export const useCustomFolderViewExtension = () => {
},
component: YourCustomFolderViewComponent
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension could then be registered in any app like so:
@@ -65,7 +65,7 @@ The extension could then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useCustomFolderViewExtension();
+ const { extension } = useCustomFolderViewExtension()
return {
appInfo: {
@@ -73,7 +73,7 @@ export default defineWebApplication({
id: 'custom-folder-view-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md
index bea0c9585..834d8987d 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/left-sidebar-menu-item-extensions.md
@@ -14,10 +14,10 @@ To define a left sidebar menu item, you implement the `SidebarNavExtension` inte
```typescript
interface SidebarNavExtension {
- id: string;
- type: 'sidebarNav';
- extensionPointIds?: string[];
- navItem: AppNavigationItem; // Please check the AppNavigationItem section below
+ id: string
+ type: 'sidebarNav'
+ extensionPointIds?: string[]
+ navItem: AppNavigationItem // Please check the AppNavigationItem section below
}
```
@@ -43,15 +43,15 @@ The following example shows an app that adds a nav item to the left sidebar of t
links to a view of the app itself.
```typescript title="src/index.ts"
-import { defineWebApplication, SidebarNavExtension } from '@opencloud-eu/web-pkg';
-import { useGettext } from 'vue3-gettext';
-import { computed } from 'vue';
-import App from './App.vue';
+import { defineWebApplication, SidebarNavExtension } from '@opencloud-eu/web-pkg'
+import { useGettext } from 'vue3-gettext'
+import { computed } from 'vue'
+import App from './App.vue'
export default defineWebApplication({
setup() {
- const { $gettext } = useGettext();
- const appId = 'admin-settings/office';
+ const { $gettext } = useGettext()
+ const appId = 'admin-settings/office'
const extensions = computed(() => [
{
@@ -67,7 +67,7 @@ export default defineWebApplication({
}
}
}
- ]);
+ ])
const routes = [
{
@@ -79,7 +79,7 @@ export default defineWebApplication({
authContext: 'user'
}
}
- ];
+ ]
return {
appInfo: {
@@ -88,7 +88,7 @@ export default defineWebApplication({
},
routes,
extensions
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md
index 3b5d97320..d82b1b8a1 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/right-sidebar-panel-extensions.md
@@ -21,10 +21,10 @@ It can be found below:
```typescript
interface SidebarPanelExtension {
- id: string;
- type: 'sidebarPanel';
- extensionPointIds?: string[];
- panel: SideBarPanel; // Please check the SideBarPanel section below
+ id: string
+ type: 'sidebarPanel'
+ extensionPointIds?: string[]
+ panel: SideBarPanel // Please check the SideBarPanel section below
}
```
@@ -37,9 +37,9 @@ The `panel` object configures the actual sidebar panel. It consists of different
```typescript
interface SideBarPanelContext {
- root?: R;
- parent?: P;
- items?: T[];
+ root?: R
+ parent?: P
+ items?: T[]
}
```
@@ -54,14 +54,14 @@ interface SideBarPanelContext {
```typescript
interface SideBarPanel {
- name: string;
- icon: string;
- iconFillType?: IconFillType;
- title(context: SideBarPanelContext): string;
- isVisible(context: SideBarPanelContext): boolean;
- component: Component;
- componentAttrs?(context: SideBarPanelContext): any;
- isRoot?(context: SideBarPanelContext): boolean;
+ name: string
+ icon: string
+ iconFillType?: IconFillType
+ title(context: SideBarPanelContext): string
+ isVisible(context: SideBarPanelContext): boolean
+ component: Component
+ componentAttrs?(context: SideBarPanelContext): any
+ isRoot?(context: SideBarPanelContext): boolean
}
```
@@ -85,7 +85,7 @@ The following example shows how a sidebar panel for displaying exif data for a r
```typescript title="src/extensions.ts"
export const useExifDataPanelExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const extension = computed>(() => ({
id: 'com.github.opencloud-eu.web.files.sidebar-panel.exif-data',
@@ -99,16 +99,16 @@ export const useExifDataPanelExtension = () => {
isRoot: () => true,
isVisible: ({ items }) => {
if (items?.length !== 1) {
- return false;
+ return false
}
- return true;
+ return true
}
}
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The extension can then be registered in any app like so:
@@ -116,7 +116,7 @@ The extension can then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useExifDataPanelExtension();
+ const { extension } = useExifDataPanelExtension()
return {
appInfo: {
@@ -124,7 +124,7 @@ export default defineWebApplication({
id: 'exif-panel-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/search-extensions.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/search-extensions.md
index ce46c8baa..8cc857e9b 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/search-extensions.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/extension-types/search-extensions.md
@@ -15,16 +15,16 @@ An example of a search extension configuration can be found below:
```typescript
interface SearchExtension {
- id: string;
- type: 'search';
- extensionPointIds?: string[];
+ id: string
+ type: 'search'
+ extensionPointIds?: string[]
searchProvider: {
- id: string;
- available: boolean;
- displayName?: string;
- previewSearch?: SearchPreview; // See SearchPreview section below
- listSearch?: SearchList; // See SearchList section below
- };
+ id: string
+ available: boolean
+ displayName?: string
+ previewSearch?: SearchPreview // See SearchPreview section below
+ listSearch?: SearchList // See SearchList section below
+ }
}
```
@@ -57,32 +57,32 @@ The following example shows how a search extension that queries a Solr search en
```typescript title="src/extensions.ts"
export const useSolrSearchExtension = () => {
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
const previewSearch: SearchPreview = {
component: SolarSearchComponent, // see the next example snippet
available: () => true,
search: (term) => {
// actual search implementation
- console.log('Querying solr search engine...');
+ console.log('Querying solr search engine...')
}
- };
+ }
const searchProvider: SearchProvider = {
id: 'solr-search',
available: true,
displayName: 'Solr Search',
previewSearch
- };
+ }
const extension = computed(() => ({
id: 'com.github.opencloud-eu.web.solr-search',
type: 'search',
searchProvider
- }));
+ }))
- return { extension };
-};
+ return { extension }
+}
```
The search component for the preview search container may look like this:
@@ -93,13 +93,13 @@ The search component for the preview search container may look like this:
```
@@ -108,7 +108,7 @@ The extension can then be registered in any app like so:
```typescript title="src/index.ts"
export default defineWebApplication({
setup() {
- const { extension } = useSolrSearchExtension();
+ const { extension } = useSolrSearchExtension()
return {
appInfo: {
@@ -116,7 +116,7 @@ export default defineWebApplication({
id: 'solrs-search-app'
},
extensions: computed(() => [unref(extension)])
- };
+ }
}
-});
+})
```
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/extensions/index.md b/versioned_docs/version-7.2/dev/web/extension-system/extensions/index.md
index d8bff39f5..71655bce9 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/extensions/index.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/extensions/index.md
@@ -34,8 +34,8 @@ The `extensions` key of an app definition takes a `Ref`, so use a `
content when your app is loaded:
```typescript title="src/index.ts"
-import { defineWebApplication, Extension } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
+import { defineWebApplication, Extension } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
export default defineWebApplication({
setup() {
@@ -48,7 +48,7 @@ export default defineWebApplication({
// See the action extension docs
}
}
- ]);
+ ])
return {
appInfo: {
@@ -56,9 +56,9 @@ export default defineWebApplication({
id: 'my-app'
},
extensions
- };
+ }
}
-});
+})
```
Because the value is a ref, the list is reactive. You can hide or show an extension based on the app config, the
@@ -67,10 +67,10 @@ capabilities of the server, or the permissions of the user:
```typescript
const extensions = computed(() => {
if (!unref(isFeatureAvailable)) {
- return [];
+ return []
}
- return [myExtension];
-});
+ return [myExtension]
+})
```
### At runtime
@@ -79,17 +79,17 @@ You can also register extensions from any place that has access to the injection
composable:
```typescript
-import { useExtensionRegistry } from '@opencloud-eu/web-pkg';
+import { useExtensionRegistry } from '@opencloud-eu/web-pkg'
-const extensionRegistry = useExtensionRegistry();
+const extensionRegistry = useExtensionRegistry()
-extensionRegistry.registerExtensions(computed(() => [myExtension]));
+extensionRegistry.registerExtensions(computed(() => [myExtension]))
```
Remove them again via `unregisterExtensions`, which takes the ids:
```typescript
-extensionRegistry.unregisterExtensions([myExtension.id]);
+extensionRegistry.unregisterExtensions([myExtension.id])
```
Prefer the app definition. Use the runtime API only when the extensions are not known at that point, for example because
@@ -106,14 +106,14 @@ Use `requestExtensions` to get all extensions of an extension point. The registr
`type` matches the `extensionType` of the extension point, and whose `extensionPointIds` allow this extension point:
```typescript
-import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg';
-import { computed } from 'vue';
+import { ActionExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg'
+import { computed } from 'vue'
-const extensionRegistry = useExtensionRegistry();
+const extensionRegistry = useExtensionRegistry()
const actions = computed(() =>
extensionRegistry.requestExtensions(myExtensionPoint).map(({ action }) => action)
-);
+)
```
To learn how to define `myExtensionPoint`, please refer to the
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/getting-started.md b/versioned_docs/version-7.2/dev/web/extension-system/getting-started.md
index 1c5d60e9e..5b10fc8dd 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/getting-started.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/getting-started.md
@@ -93,8 +93,8 @@ The `src/index.ts` file acts as the entrypoint of the app. This file has to expo
```typescript title="src/index.ts"
import { defineWebApplication } from '@opencloud-eu/web-pkg'
-import { computed } from 'vue';
-import { useGettext } from 'vue3-gettext';
+import { computed } from 'vue'
+import { useGettext } from 'vue3-gettext'
// Needs to be unique within all installed applications in any OpenCloud
// web instance. Should be short, unique and expressive as it is used as
@@ -104,7 +104,7 @@ const appId = 'your-app'
export default defineWebApplication({
setup({ applicationConfig }) {
// Here, you have access to the full injection context.
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
return {
appInfo: {
@@ -142,11 +142,11 @@ Apps are built with [Vite](https://vite.dev/). The `@opencloud-eu/extension-sdk`
config, so your `vite.config.ts` stays short:
```typescript title="vite.config.ts"
-import { defineConfig } from '@opencloud-eu/extension-sdk';
+import { defineConfig } from '@opencloud-eu/extension-sdk'
export default defineConfig({
name: 'my-app'
-});
+})
```
`defineConfig` accepts any [Vite option](https://vite.dev/config/), plus the following:
diff --git a/versioned_docs/version-7.2/dev/web/extension-system/viewer-editor-apps/index.md b/versioned_docs/version-7.2/dev/web/extension-system/viewer-editor-apps/index.md
index 69e16ca75..11a5b465a 100644
--- a/versioned_docs/version-7.2/dev/web/extension-system/viewer-editor-apps/index.md
+++ b/versioned_docs/version-7.2/dev/web/extension-system/viewer-editor-apps/index.md
@@ -11,21 +11,21 @@ This section will guide you through the process of implementing such an app with
The `src/index.ts` file for a viewer or editor app may look like this:
```typescript title="src/index.ts"
-import { AppWrapperRoute, defineWebApplication, AppMenuItemExtension } from '@opencloud-eu/web-pkg';
-import { urlJoin } from '@opencloud-eu/web-client';
-import translations from '../l10n/translations.json';
-import { useGettext } from 'vue3-gettext';
-import { computed } from 'vue';
+import { AppWrapperRoute, defineWebApplication, AppMenuItemExtension } from '@opencloud-eu/web-pkg'
+import { urlJoin } from '@opencloud-eu/web-client'
+import translations from '../l10n/translations.json'
+import { useGettext } from 'vue3-gettext'
+import { computed } from 'vue'
// This is the base component of your app.
-import App from './App.vue';
+import App from './App.vue'
export default defineWebApplication({
setup() {
// The ID of your app.
- const appId = 'advanced-pdf-viewer';
+ const appId = 'advanced-pdf-viewer'
- const { $gettext } = useGettext();
+ const { $gettext } = useGettext()
// This creates a route under which your app can be opened.
// Later, this route will be bound to one or more file extensions.
@@ -42,7 +42,7 @@ export default defineWebApplication({
patchCleanPath: true
}
}
- ];
+ ]
// if you want your app to be present in the app menu on the top left.
const menuItems = computed(() => [
@@ -55,7 +55,7 @@ export default defineWebApplication({
priority: 30,
path: urlJoin(appId)
}
- ]);
+ ])
return {
appInfo: {
@@ -72,7 +72,7 @@ export default defineWebApplication({
// Add this if you want your app to be present in the "New" file menu.
newFileMenu: {
menuTitle() {
- return $gettext('PDF document');
+ return $gettext('PDF document')
}
}
}
@@ -81,30 +81,30 @@ export default defineWebApplication({
routes,
translations,
extensions: menuItems
- };
+ }
}
-});
+})
```
Here is the interface defining the `extensions` property of the `appInfo` object.
```typescript
interface ApplicationFileExtension {
- app?: string;
- extension?: string;
- type?: 'file' | 'folder';
+ app?: string
+ extension?: string
+ type?: 'file' | 'folder'
createFileHandler?: (arg: {
- fileName: string;
- space: SpaceResource;
- currentFolder: Resource;
- }) => Promise;
- hasPriority?: boolean;
- label?: string | (() => string);
- name?: string;
- icon?: string;
- mimeType?: string;
- newFileMenu?: { menuTitle: () => string };
- routeName?: string;
- secureView?: boolean;
+ fileName: string
+ space: SpaceResource
+ currentFolder: Resource
+ }) => Promise
+ hasPriority?: boolean
+ label?: string | (() => string)
+ name?: string
+ icon?: string
+ mimeType?: string
+ newFileMenu?: { menuTitle: () => string }
+ routeName?: string
+ secureView?: boolean
}
```
diff --git a/versioned_docs/version-7.2/dev/web/testing/e2e-testing-standards.md b/versioned_docs/version-7.2/dev/web/testing/e2e-testing-standards.md
index 49cd8b2e5..7609510f0 100644
--- a/versioned_docs/version-7.2/dev/web/testing/e2e-testing-standards.md
+++ b/versioned_docs/version-7.2/dev/web/testing/e2e-testing-standards.md
@@ -61,16 +61,16 @@ Consider including comments defining each section to ease readability.
```typescript
// arrange, set up the initial conditions for the test
// create a property
-await createProperty();
+await createProperty()
// act, perform the action that you want to test
// raise a charge
// this could involve calling methods or functions defined in your page objects
-await raiseCharge();
+await raiseCharge()
// assert, verify that the action had the expected outcome
// confirm charge has been raised
-expect(charge).toBe('raised');
+expect(charge).toBe('raised')
```
## Page Object Model (POM)
@@ -88,26 +88,26 @@ DO π
// add all locators and functions related to the page.
// allowing all tests to reuse
-import { expect, Locator, Page } from '@playwright/test';
+import { expect, Locator, Page } from '@playwright/test'
export class FooPage {
- readonly errorMessage: Locator;
+ readonly errorMessage: Locator
constructor(page: Page) {
- this.page = page;
- this.errorMessage = page.locator('.error-message');
+ this.page = page
+ this.errorMessage = page.locator('.error-message')
}
}
// test file './steps/foo.ts'
-import { FooPage } from './pageObjects/foo';
+import { FooPage } from './pageObjects/foo'
-let fooPage: FooPage;
+let fooPage: FooPage
Then('error message should be visible', async function ({ page }) {
- const fooPage = new FooPage({ page });
- await expect(fooPage.errorMessage).toBeVisible();
-});
+ const fooPage = new FooPage({ page })
+ await expect(fooPage.errorMessage).toBeVisible()
+})
```
DO NOT βοΈ
@@ -115,11 +115,11 @@ DO NOT βοΈ
```typescript
// test file './steps/foo.ts'
// include locators directly in test
-import { Locator, Page } from '@playwright/test';
+import { Locator, Page } from '@playwright/test'
Then('error message should be visible', async function ({ page }) {
- await expect(page.locator('.error-message')).toBeVisible();
-});
+ await expect(page.locator('.error-message')).toBeVisible()
+})
```
## Waiting
@@ -129,7 +129,7 @@ Playwright uses auto-waiting, so we avoid artificial waiting, the exception bein
DO NOT βοΈ
```typescript
-await page.waitForTimeout(5000);
+await page.waitForTimeout(5000)
```
This can cause flaky tests as we can rarely be certain the amount of wait time is enough. It can also unnecessarily increase the test run time. Instead, we can try:
@@ -139,21 +139,21 @@ DO π
```typescript
await page.goto(fooBarURL, {
waitUntil: 'domcontentloaded'
-});
+})
```
DO π
```typescript
-const element = page.locator('some-locator-path');
-element.waitFor({ visible: true });
+const element = page.locator('some-locator-path')
+element.waitFor({ visible: true })
```
DO π
```typescript
-await fooPage.buttonFoo.click();
-await expect(fooPage.titlePage).toBeVisible();
+await fooPage.buttonFoo.click()
+await expect(fooPage.titlePage).toBeVisible()
```
## Selectors
@@ -171,14 +171,14 @@ Instead, we can prioritize the below, based on [testing-library guiding principl
DO NOT βοΈ
```javascript
-page.locator('.opt-u > div > .summary > div:nth-child(4) > div');
+page.locator('.opt-u > div > .summary > div:nth-child(4) > div')
```
DO π
```javascript
-page.locator('#foo-button');
-page.getByText('OK');
+page.locator('#foo-button')
+page.getByText('OK')
```
## Naming Conventions
@@ -197,7 +197,7 @@ Declare in **_camelCase_**.
Start with βisβ, βhasβ, βareβ, βhaveβ. This helps spot that this is a boolean while skimming the code. Still declared in **_camelCase_**.
```typescript
-let isTurnedOn = false;
+let isTurnedOn = false
```
### Page Objects / Classes
@@ -232,14 +232,14 @@ DO π
```typescript
// This element is a submit button for the user registration form
-const submitButton = await page.locator('');
+const submitButton = await page.locator('')
```
DO π
```typescript
// This element is a button for uploading a profile picture
-const uploadProfilePictureButton = await page.locator('');
+const uploadProfilePictureButton = await page.locator('')
```
### Function names
@@ -249,9 +249,9 @@ Always start function names with a **_βverbβ_**, followed by the **_βcompo
DO π
```typescript
-getWorksOrder();
-printTransactions();
-deleteProperty();
+getWorksOrder()
+printTransactions()
+deleteProperty()
```
## Gherkin Best Practices: Do's and Don'ts for Effective Features & Scenarios