An open API service indexing awesome lists of open source software.

https://github.com/nextcloud-libraries/nextcloud-files

Nextcloud Files helpers for Nextcloud apps and libraries https://npmjs.org/@nextcloud/files
https://github.com/nextcloud-libraries/nextcloud-files

nextcloud nextcloud-plugin

Last synced: 3 months ago
JSON representation

Nextcloud Files helpers for Nextcloud apps and libraries https://npmjs.org/@nextcloud/files

Awesome Lists containing this project

README

          

# @nextcloud/files
[![npm last version](https://img.shields.io/npm/v/@nextcloud/files.svg?style=flat-square)](https://www.npmjs.com/package/@nextcloud/files) [![REUSE status](https://api.reuse.software/badge/github.com/nextcloud-libraries/nextcloud-files)](https://api.reuse.software/info/github.com/nextcloud-libraries/nextcloud-files) [![Code coverage](https://img.shields.io/codecov/c/github/nextcloud-libraries/nextcloud-files?style=flat-square)](https://app.codecov.io/gh/nextcloud-libraries/nextcloud-files) [![Project documentation](https://img.shields.io/badge/documentation-online-blue?style=flat-square)](https://nextcloud-libraries.github.io/nextcloud-files/)

Nextcloud Files helpers for Nextcloud apps and libraries.

This library provides three kinds of utils:
1. WebDAV helper functions to work with the Nextcloud WebDAV interface.
Those functions are available in `@nextcloud/files/dav`
2. Geneal purpose function related to files or folders, like filename validation.
3. Functions and classes to interact with the Nextcloud **files** app, like registering a new view or a file action.

## Compatibility

| `@nextcloud/files` version | Supported | Nextcloud version |
|----------------------------|-----------|-------------------|
| 4.x | ✅ | 33+ |
| 3.x | ✅ | 26-32 |
| 2.x | ❌ | 23-25 |
| 1.x | ❌ | 20-22 |

## Usage examples

### Files app

#### Register a "New"-menu entry

The "New"-menu allows to create new entries or upload files, it is also possible for other apps to register their own actions here.

```ts
import type { Entry } from '@nextcloud/files'
import { addNewFileMenuEntry } from '@nextcloud/files'
import { t } from '@nextcloud/l10n'

const myEntry: Entry = {
// unique ID of the entry
id: 'my-app',
// The display name in the menu
displayName: t('my-app', 'New something'),
// optionally pass an SVG (string) to be used as the menu entry icon
iconSvgInline: importedSVGFile,
handler(context: Folder, content: Node[]): void {
// `context` is the current active folder
// `content` is the content of the currently active folder
// You can add new files here e.g. use the WebDAV functions to create files.
// If new content is added, ensure to emit the event-bus signals so the files app can update the list.
}
}

addNewFileMenuEntry(myEntry)
```

#### Register a sidebar tab

It is possible to provide your own sidebar tabs for the files app.
For this you need to create a [custom web component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components),
which can either be done without any framework by using vanilla JavaScript but is also [possible with Vue](https://vuejs.org/guide/extras/web-components#building-custom-elements-with-vue).

This example will make use of the Vue framework for building a sidebar tab as this is the official UI framework for Nextcloud apps.

The sidebar tab consists of two parts:
1. The web component which will be rendered within the sidebar.
2. A definition object that provides all information needed by the files app.

##### SidebarTab definition object

This object provides the requires information such as:
- The order (to ensure a consistent tabs order)
- The display name for the tab navigation
- An icon, to be used in the tab navigation
- A callback to check if the sidebar tab is enabled for the current node shown in the sidebar.
- The web component tag name

The registration must happen in an `initScript`.

```ts
import type { ISidebarTab } from '@nextcloud/files'

import { getSidebar } from '@nextcloud/files'
import { t } from '@nextcloud/l10n'

const MyTab: ISidebarTab = {
// Unique ID of the tab
id: 'my_app',

// The display name in the tab list
displayName: t('my_app', 'Sharing'),

// Pass an SVG (string) to be used as the tab button icon
iconSvgInline: '...',

// Lower values mean a more prominent position
order: 50,

// The tag name of the web component
tagName: 'my_app-files_sidebar_tab',

// Optional callback to check if the tab should be shown
enabled({ node, folder, view }) {
// you can disable this tab for some cased based on:
// - node: The node the sidebar was opened for
// - folder: The folder currently shown in the files app
// - view: The currently active files view
return true
},

// Optional, recommended to large tabs
async onInit() {
// This is called when the tab is about to be activated the first time.
// So this can be used to do some initialization or even to define the web component.
},
}

// the you need to register it in the sidebar
getSidebar()
.registerTab(MyTab)
```

##### SidebarTab web component

The web component needs to have those properties:
- node of type `INode`
- folder of type `IFolder`
- view of type `IView`
- active of type `boolean`

When using Vue you need to first create the Vue component:

```vue

import type { IFolder, INode, IView } from '@nextcloud/files'

defineProps<{
node: INode
folder: IFolder
view: IView
active: boolean
}>()


Showing node: {{ node.source }}

... in folder: {{ folder.source }}

... with view: {{ view.id }}

```

Which then can be wrapped in a web component and registered.

```ts
import { getSidebar } from '@nextcloud/files'
import { defineAsyncComponent, defineCustomElement } from 'vue'

getSidebar().registerTab({
// ...

tagName: `my_app-files_sidebar_tab`,

onInit() {
const MySidebarTab = defineAsyncComponent(() => import('./views/MySidebarTab.vue'))
// make sure to disable the shadow root to allow theming with Nextcloud provided global styles.
const MySidebarTabWebComponent = defineCustomElement(MySidebarTab, { shadowRoot: false })
customElements.define('my_app-files_sidebar_tab', MySidebarTabWebComponent)
},
})
```

### WebDAV
The `getClient` exported function returns a webDAV client that's a wrapper around [webdav's webDAV client](https://www.npmjs.com/package/webdav).
All its methods are available here.

#### Using WebDAV to query favorite nodes

```ts
import { getClient, defaultRootPath, getFavoriteNodes } from '@nextcloud/files/dav'

const client = getClient()
// query favorites for the root folder (meaning all favorites)
const favorites = await getFavoriteNodes(client)
// which is the same as writing:
const favorites = await getFavoriteNodes(client, '/', defaultRootPath)
```

#### Using WebDAV to list all nodes in directory

```ts
import {
getClient,
getDefaultPropfind,
resultToNode,
defaultRootPath,
defaultRemoteURL
} from '@nextcloud/files/dav'

// Get the DAV client for the default remote
const client = getClient()
// which is the same as writing
const client = getClient(defaultRemoteURL)
// of cause you can also configure another WebDAV remote
const client = getClient('https://example.com/dav')

const path = '/my-folder/' // the directory you want to list

// Query the directory content using the webdav library
// `davRootPath` is the files root, for Nextcloud this is '/files/USERID', by default the current user is used
const results = client.getDirectoryContents(`${defaultRootPath}${path}`, {
details: true,
// Query all required properties for a Node
data: getDefaultPropfind()
})

// Convert the result to an array of Node
const nodes = results.data.map((result) => resultToNode(r))
// If you specified a different root in the `getDirectoryContents` you must add this also on the `resultToNode` call:
const nodes = results.data.map((result) => resultToNode(r, myRoot))
// Same if you used a different remote URL:
const nodes = results.data.map((result) => resultToNode(r, myRoot, myRemoteURL))

```

#### Using WebDAV to get a Node from a file's name

```ts
import { getClient, davGetDefaultPropfind, resultToNode, davRootPath } from '@nextcloud/files'
import { emit } from '@nextcloud/event-bus'
const client = getClient()
client.stat(`${davRootPath}${filename}`, {
details: true,
data: davGetDefaultPropfind(),
}).then((result) => {
const node = resultToNode(result.data)
emit('files:node:updated', node)
})
```