Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion apps/files/lib/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,38 @@ private function getChildren(array $nodes, int $depth = 1, int $currentDepth = 0
return $children;
}

/**
* Get all parents with their contents of the current folder.
*
* @param Folder $currentFolder - The current folder to get the parents for
* @param string $root - The root path to stop at
* @param array $children - The children of the current folder to include in the response
*/
private function getParents(Folder $currentFolder, string $root, array $children): array {
$parentFolder = $currentFolder->getParent();
$parentContent = array_filter($parentFolder->getDirectoryListing(), fn (Node $node) => $node instanceof Folder);
$parentData = array_map(fn (Folder $node) => [
'id' => $node->getId(),
'basename' => basename($node->getPath()),
'displayName' => $node->getName(),
'children' => $node->getId() === $currentFolder->getId()
? $children
: [],
], $parentContent);

if ($parentFolder->getPath() === $root) {
return array_values($parentData);
}

return $this->getParents($parentFolder, $root, array_values($parentData));
}

/**
* Returns the folder tree of the user
*
* @param string $path The path relative to the user folder
* @param int $depth The depth of the tree
* @param bool $withParents Whether to include parent folders in the response
*
* @return JSONResponse<Http::STATUS_OK, FilesFolderTree, array{}>|JSONResponse<Http::STATUS_UNAUTHORIZED|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
*
Expand All @@ -291,7 +318,7 @@ private function getChildren(array $nodes, int $depth = 1, int $currentDepth = 0
#[NoAdminRequired]
#[ApiRoute(verb: 'GET', url: '/api/v1/folder-tree')]
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT)]
public function getFolderTree(string $path = '/', int $depth = 1): JSONResponse {
public function getFolderTree(string $path = '/', int $depth = 1, bool $withParents = false): JSONResponse {
$user = $this->userSession->getUser();
if (!($user instanceof IUser)) {
return new JSONResponse([
Expand All @@ -310,6 +337,10 @@ public function getFolderTree(string $path = '/', int $depth = 1): JSONResponse
}
$nodes = $node->getDirectoryListing();
$tree = $this->getChildren($nodes, $depth);

if ($withParents && $path !== '/') {
$tree = $this->getParents($node, $userFolderPath, $tree);
}
} catch (NotFoundException $e) {
return new JSONResponse([
'message' => $this->l10n->t('Folder not found'),
Expand Down
9 changes: 9 additions & 0 deletions apps/files/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2647,6 +2647,15 @@
"default": 1
}
},
{
"name": "withParents",
"in": "query",
"description": "Whether to include parent folders in the response",
"schema": {
"type": "boolean",
"default": false
}
},
{
"name": "OCS-APIRequest",
"in": "header",
Expand Down
186 changes: 0 additions & 186 deletions apps/files/src/components/FilesNavigationItem.vue

This file was deleted.

56 changes: 56 additions & 0 deletions apps/files/src/components/FilesNavigationList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup lang="ts">
import type { IView } from '@nextcloud/files'
import { getCanonicalLocale, getLanguage, t } from '@nextcloud/l10n'
import { computed } from 'vue'
import NcAppNavigationList from '@nextcloud/vue/components/NcAppNavigationList'
import FilesNavigationListItem from './FilesNavigationListItem.vue'
import { useVisibleViews } from '../composables/useViews.ts'
const views = useVisibleViews()
const rootViews = computed(() => views.value
.filter((view) => !view.parent)
.sort(sortViews))
const collator = Intl.Collator(
[getLanguage(), getCanonicalLocale()],
{ numeric: true, usage: 'sort' },
)
/**
* Sort views by their order property if available, otherwise sort alphabetically by name.
*
* @param a - first view
* @param b - second view
*/
function sortViews(a: IView, b: IView): number {
if (a.order !== undefined && b.order === undefined) {
return -1
} else if (a.order === undefined && b.order !== undefined) {
return 1
}
return collator.compare(a.name, b.name)
}
</script>

<template>
<NcAppNavigationList
:class="$style.filesNavigationList"
:aria-label="t('files', 'Views')">
<FilesNavigationListItem
v-for="view in rootViews"
:key="view.id"
:view="view" />
</NcAppNavigationList>
</template>

<style module>
.filesNavigationList {
height: 100%; /* Fill all available space for sticky views */
}
</style>
Loading
Loading