mirror of
https://github.com/immich-app/immich.git
synced 2024-11-28 09:33:27 +02:00
fix(server): album statistics endpoint (#11924)
This commit is contained in:
parent
cde0458dc8
commit
ef9a06be5c
@ -344,16 +344,16 @@ describe('/albums', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /albums/count', () => {
|
||||
describe('GET /albums/statistics', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/albums/count');
|
||||
const { status, body } = await request(app).get('/albums/statistics');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should return total count of albums the user has access to', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/albums/count')
|
||||
.get('/albums/statistics')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
BIN
mobile/openapi/README.md
generated
BIN
mobile/openapi/README.md
generated
Binary file not shown.
BIN
mobile/openapi/lib/api.dart
generated
BIN
mobile/openapi/lib/api.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/api/albums_api.dart
generated
BIN
mobile/openapi/lib/api/albums_api.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/api_client.dart
generated
BIN
mobile/openapi/lib/api_client.dart
generated
Binary file not shown.
Binary file not shown.
@ -660,16 +660,16 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/albums/count": {
|
||||
"/albums/statistics": {
|
||||
"get": {
|
||||
"operationId": "getAlbumCount",
|
||||
"operationId": "getAlbumStatistics",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AlbumCountResponseDto"
|
||||
"$ref": "#/components/schemas/AlbumStatisticsResponseDto"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -7505,25 +7505,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AlbumCountResponseDto": {
|
||||
"properties": {
|
||||
"notShared": {
|
||||
"type": "integer"
|
||||
},
|
||||
"owned": {
|
||||
"type": "integer"
|
||||
},
|
||||
"shared": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"notShared",
|
||||
"owned",
|
||||
"shared"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AlbumResponseDto": {
|
||||
"properties": {
|
||||
"albumName": {
|
||||
@ -7611,6 +7592,25 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AlbumStatisticsResponseDto": {
|
||||
"properties": {
|
||||
"notShared": {
|
||||
"type": "integer"
|
||||
},
|
||||
"owned": {
|
||||
"type": "integer"
|
||||
},
|
||||
"shared": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"notShared",
|
||||
"owned",
|
||||
"shared"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AlbumUserAddDto": {
|
||||
"properties": {
|
||||
"role": {
|
||||
|
@ -268,7 +268,7 @@ export type CreateAlbumDto = {
|
||||
assetIds?: string[];
|
||||
description?: string;
|
||||
};
|
||||
export type AlbumCountResponseDto = {
|
||||
export type AlbumStatisticsResponseDto = {
|
||||
notShared: number;
|
||||
owned: number;
|
||||
shared: number;
|
||||
@ -1369,11 +1369,11 @@ export function createAlbum({ createAlbumDto }: {
|
||||
body: createAlbumDto
|
||||
})));
|
||||
}
|
||||
export function getAlbumCount(opts?: Oazapfts.RequestOpts) {
|
||||
export function getAlbumStatistics(opts?: Oazapfts.RequestOpts) {
|
||||
return oazapfts.ok(oazapfts.fetchJson<{
|
||||
status: 200;
|
||||
data: AlbumCountResponseDto;
|
||||
}>("/albums/count", {
|
||||
data: AlbumStatisticsResponseDto;
|
||||
}>("/albums/statistics", {
|
||||
...opts
|
||||
}));
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query } from '@
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
AddUsersDto,
|
||||
AlbumCountResponseDto,
|
||||
AlbumInfoDto,
|
||||
AlbumResponseDto,
|
||||
AlbumStatisticsResponseDto,
|
||||
CreateAlbumDto,
|
||||
GetAlbumsDto,
|
||||
UpdateAlbumDto,
|
||||
@ -22,12 +22,6 @@ import { ParseMeUUIDPipe, UUIDParamDto } from 'src/validation';
|
||||
export class AlbumController {
|
||||
constructor(private service: AlbumService) {}
|
||||
|
||||
@Get('count')
|
||||
@Authenticated({ permission: Permission.ALBUM_STATISTICS })
|
||||
getAlbumCount(@Auth() auth: AuthDto): Promise<AlbumCountResponseDto> {
|
||||
return this.service.getCount(auth);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@Authenticated({ permission: Permission.ALBUM_READ })
|
||||
getAllAlbums(@Auth() auth: AuthDto, @Query() query: GetAlbumsDto): Promise<AlbumResponseDto[]> {
|
||||
@ -40,6 +34,12 @@ export class AlbumController {
|
||||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@Get('statistics')
|
||||
@Authenticated({ permission: Permission.ALBUM_STATISTICS })
|
||||
getAlbumStatistics(@Auth() auth: AuthDto): Promise<AlbumStatisticsResponseDto> {
|
||||
return this.service.getStatistics(auth);
|
||||
}
|
||||
|
||||
@Authenticated({ permission: Permission.ALBUM_READ, sharedLink: true })
|
||||
@Get(':id')
|
||||
getAlbumInfo(
|
||||
|
@ -95,7 +95,7 @@ export class GetAlbumsDto {
|
||||
assetId?: string;
|
||||
}
|
||||
|
||||
export class AlbumCountResponseDto {
|
||||
export class AlbumStatisticsResponseDto {
|
||||
@ApiProperty({ type: 'integer' })
|
||||
owned!: number;
|
||||
|
||||
|
@ -43,12 +43,12 @@ describe(AlbumService.name, () => {
|
||||
expect(sut).toBeDefined();
|
||||
});
|
||||
|
||||
describe('getCount', () => {
|
||||
describe('getStatistics', () => {
|
||||
it('should get the album count', async () => {
|
||||
albumMock.getOwned.mockResolvedValue([]);
|
||||
albumMock.getShared.mockResolvedValue([]);
|
||||
albumMock.getNotShared.mockResolvedValue([]);
|
||||
await expect(sut.getCount(authStub.admin)).resolves.toEqual({
|
||||
await expect(sut.getStatistics(authStub.admin)).resolves.toEqual({
|
||||
owned: 0,
|
||||
shared: 0,
|
||||
notShared: 0,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||
import {
|
||||
AddUsersDto,
|
||||
AlbumCountResponseDto,
|
||||
AlbumInfoDto,
|
||||
AlbumResponseDto,
|
||||
AlbumStatisticsResponseDto,
|
||||
CreateAlbumDto,
|
||||
GetAlbumsDto,
|
||||
UpdateAlbumDto,
|
||||
@ -37,7 +37,7 @@ export class AlbumService {
|
||||
@Inject(IAlbumUserRepository) private albumUserRepository: IAlbumUserRepository,
|
||||
) {}
|
||||
|
||||
async getCount(auth: AuthDto): Promise<AlbumCountResponseDto> {
|
||||
async getStatistics(auth: AuthDto): Promise<AlbumStatisticsResponseDto> {
|
||||
const [owned, shared, notShared] = await Promise.all([
|
||||
this.albumRepository.getOwned(auth.user.id),
|
||||
this.albumRepository.getShared(auth.user.id),
|
||||
|
@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { type AlbumCountResponseDto, getAlbumCount } from '@immich/sdk';
|
||||
import { type AlbumStatisticsResponseDto, getAlbumStatistics } from '@immich/sdk';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
export let albumCountType: keyof AlbumCountResponseDto;
|
||||
export let albumType: keyof AlbumStatisticsResponseDto;
|
||||
|
||||
const handleAlbumCount = async () => {
|
||||
try {
|
||||
return await getAlbumCount();
|
||||
return await getAlbumStatistics();
|
||||
} catch {
|
||||
return { owned: 0, shared: 0, notShared: 0 };
|
||||
}
|
||||
@ -18,6 +18,6 @@
|
||||
<LoadingSpinner />
|
||||
{:then data}
|
||||
<div>
|
||||
<p>{$t('albums_count', { values: { count: data[albumCountType] } })}</p>
|
||||
<p>{$t('albums_count', { values: { count: data[albumType] } })}</p>
|
||||
</div>
|
||||
{/await}
|
||||
|
@ -79,7 +79,7 @@
|
||||
bind:isSelected={isSharingSelected}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
<MoreInformationAlbums albumCountType="shared" />
|
||||
<MoreInformationAlbums albumType="shared" />
|
||||
</svelte:fragment>
|
||||
</SideBarLink>
|
||||
{/if}
|
||||
@ -100,7 +100,7 @@
|
||||
</SideBarLink>
|
||||
<SideBarLink title={$t('albums')} routeId="/(user)/albums" icon={mdiImageAlbum} flippedLogo>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
<MoreInformationAlbums albumCountType="owned" />
|
||||
<MoreInformationAlbums albumType="owned" />
|
||||
</svelte:fragment>
|
||||
</SideBarLink>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user