Skip to content

Commit 1234b52

Browse files
committed
feat: routes and icons
- don't use backend generic home route - use 'specs' and apiSpecs - child apis draw their icon in 16 - keep open states Signed-off-by: Sebastien Marinier <seb@smarinier.net>
1 parent 6d86293 commit 1234b52

File tree

7 files changed

+53
-33
lines changed

7 files changed

+53
-33
lines changed

appinfo/routes.php

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@
88
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
99
['name' => 'apps#index', 'url' => '/apps', 'verb' => 'GET'],
1010
['name' => 'apps#load', 'url' => '/apps/{app}', 'verb' => 'GET'],
11-
// The following route is there to prevent redirection to NC's general homepage
12-
// when reloading a page in the application (If we don't add it all pages that
13-
// don't have a route registered here redirect to NC's general homepage upon refresh)
14-
[
15-
'name' => 'page#index',
16-
'url' => '/{path}',
17-
'verb' => 'GET',
18-
'requirements' => ['path' => '.*'],
19-
'defaults' => ['path' => 'dummy'],
20-
'postfix' => 'catchall',
21-
]
11+
['name' => 'page#view', 'url' => '/view/{app}', 'verb' => 'GET'], // handled by Vue router
2212
],
2313
];

lib/Controller/PageController.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@ public function index(): TemplateResponse {
2929
return new TemplateResponse(Application::APP_ID, 'main');
3030
}
3131

32+
/**
33+
* @NoAdminRequired
34+
* @NoCSRFRequired
35+
*/
36+
public function view(): TemplateResponse {
37+
return $this->index();
38+
}
39+
3240
}

lib/Service/AppsService.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,24 @@ public function findSupported(): array {
2929
if (!$this->appManager->isEnabledForUser($app)) {
3030
continue;
3131
}
32-
$appApis = [];
32+
$appSpecs = [];
3333
try {
3434
$baseDir = $this->appManager->getAppPath($app);
3535
$iterator = new \DirectoryIterator($baseDir);
3636
foreach ($iterator as $file) {
3737
if ($file->getFilename() == 'openapi.json') {
38-
$appApis[] = $app;
38+
$appSpecs[] = $app;
3939
} else if (str_starts_with($file->getFilename(), 'openapi-') && str_ends_with($file->getFilename(), '.json')) {
40-
$appApis[] = $app . '-' . substr($file->getFilename(), 8, -5);
40+
$appSpecs[] = $app . '-' . substr($file->getFilename(), 8, -5);
4141
}
4242
}
4343
} catch (AppPathNotFoundException) {
4444
}
45-
if (!empty($appApis)) {
45+
if ($appSpecs !== []) {
4646
$appInfo = $this->appManager->getAppInfo($app);
47-
$apiInfo =[
47+
$apiInfo = [
4848
'id' => $app,
49-
'apis' => $appApis,
49+
'specs' => $appSpecs,
5050
'name' => $appInfo['name'],
5151
'version' => $appInfo['version'],
5252
'always_enabled' => in_array($app, $always),
@@ -62,7 +62,7 @@ public function findSupported(): array {
6262
if (file_exists(\OC::$SERVERROOT . '/core/openapi.json')) {
6363
array_unshift($apis, [
6464
'id' => 'core',
65-
'apis' => ['core'],
65+
'specs' => ['core'],
6666
'name' => 'Core Nextcloud API',
6767
'version' => implode('.', \OCP\Util::getVersion()),
6868
'always_enabled' => true,

src/ApiNavigationList.vue

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
:key="app.id"
55
allow-collapse
66
:name="app.name"
7-
:open="isSelectedChild($route.params.appid, app)"
8-
:to="{path: `/view/${app.id}`}">
7+
:open="isSelectedChild($route.params.appid, app) || isManuallyOpened(app.id)"
8+
:to="{path: `/view/${app.id}`}"
9+
@update:open="(open) => onOpen(app.id, open)">
910
<template #icon>
1011
<AppIcon v-if="app.icon_url"
1112
:href="app.icon_url" />
@@ -14,7 +15,15 @@
1415
<NcAppNavigationItem v-for="child in childApis(app)"
1516
:key="child.id"
1617
:name="child.name"
17-
:to="{path: `/view/${child.id}`}" />
18+
:to="{path: `/view/${child.id}`}">
19+
<template #icon>
20+
<AppIcon v-if="app.icon_url"
21+
size="16"
22+
:href="app.icon_url" />
23+
<ApiIcon v-else
24+
size="16" />
25+
</template>
26+
</NcAppNavigationItem>
1827
</NcAppNavigationItem>
1928
</NcAppNavigationList>
2029
</template>
@@ -42,31 +51,37 @@ export default {
4251
},
4352
computed: {
4453
apps() {
45-
const apps = store.apps
54+
return store.apps
4655
.filter(app => app.always_enabled === this.alwaysEnabled)
4756
.sort(function(a, b) {
4857
// core nextcloud always first
4958
if (a.id === 'core') return -1
5059
if (b.id === 'core') return 1
5160
return OC.Util.naturalSortCompare(a.name, b.name)
5261
})
53-
return apps
5462
},
5563
},
5664
methods: {
5765
isSelectedChild(appId, app) {
5866
if (appId === app.id) {
5967
return false
6068
}
61-
return app.apis.indexOf(appId) >= 0
69+
return app.specs.indexOf(appId) >= 0
6270
},
6371
childApis(app) {
64-
if (app.apis === undefined || app.apis.length === 1) {
72+
if (app.specs === undefined || app.specs.length === 1) {
6573
return []
6674
}
67-
return app.apis.filter(id => id !== app.id)
75+
return app.specs
76+
.filter(id => id !== app.id)
6877
.map(cid => ({ id: cid, name: cid }))
6978
},
79+
isManuallyOpened(appId) {
80+
return store.isAppOpened(appId)
81+
},
82+
onOpen(appId, open) {
83+
store.appOpen(appId, open)
84+
},
7085
},
7186
}
7287
</script>

src/AppIcon.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
<template>
2-
<svg width="24"
3-
height="24"
4-
viewBox="0 0 24 24">
2+
<svg :width="size"
3+
:height="size"
4+
:viewBox="`0 0 ${size} ${size}`">
55
<image x="0"
66
y="0"
7-
width="24"
8-
height="24"
9-
preserveAspectRatio="xMinYMin meet"
7+
:width="size"
8+
:height="size"
109
:xlink:href="href"
1110
class="app-icon" />
1211
</svg>
@@ -17,6 +16,7 @@ export default {
1716
name: 'AppIcon',
1817
props: {
1918
href: { type: String, default: '' },
19+
size: { type: Number, default: 24 },
2020
},
2121
}
2222
</script>

src/Welcome.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<template #icon>
1515
<OpenInNew :size="20" />
1616
</template>
17-
Nextcloud OpenApi extractor
17+
Nextcloud openapi-extractor
1818
</NcActionLink>
1919
</NcActions>
2020
</div>

src/store.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const useAppsStore = defineStore('ocs-api-viewer-apps', {
1515
state: () => ({
1616
loading: true,
1717
apps: [],
18+
appOpened: [],
1819
}),
1920

2021
actions: {
@@ -41,5 +42,11 @@ export const useAppsStore = defineStore('ocs-api-viewer-apps', {
4142
getAppById(appId) {
4243
return this.apps.find(({ id }) => id === appId) ?? null
4344
},
45+
isAppOpened(appId) {
46+
return this.appOpened[appId] ?? false
47+
},
48+
appOpen(appId, open) {
49+
this.appOpened[appId] = open
50+
},
4451
},
4552
})

0 commit comments

Comments
 (0)