refactor(server)!: add/remove album assets (#3109)

* refactor: add/remove album assets

* chore: open api

* feat: remove owned assets from album

* refactor: move to bulk id req/res dto

* chore: open api

* chore: merge main

* dev: mobile work

* fix: adding asset from web not sync with mobile

* remove print statement

---------

Co-authored-by: Alex Tran <Alex.Tran@conductix.com>
This commit is contained in:
Jason Rasmussen
2023-08-01 21:29:14 -04:00
committed by GitHub
parent ba71c83948
commit b9cda59172
51 changed files with 890 additions and 1282 deletions

View File

@@ -99,44 +99,6 @@ export interface APIKeyUpdateDto {
*/
'name': string;
}
/**
*
* @export
* @interface AddAssetsDto
*/
export interface AddAssetsDto {
/**
*
* @type {Array<string>}
* @memberof AddAssetsDto
*/
'assetIds': Array<string>;
}
/**
*
* @export
* @interface AddAssetsResponseDto
*/
export interface AddAssetsResponseDto {
/**
*
* @type {AlbumResponseDto}
* @memberof AddAssetsResponseDto
*/
'album'?: AlbumResponseDto;
/**
*
* @type {Array<string>}
* @memberof AddAssetsResponseDto
*/
'alreadyInAlbum': Array<string>;
/**
*
* @type {number}
* @memberof AddAssetsResponseDto
*/
'successfullyAdded': number;
}
/**
*
* @export
@@ -821,6 +783,19 @@ export const BulkIdResponseDtoErrorEnum = {
export type BulkIdResponseDtoErrorEnum = typeof BulkIdResponseDtoErrorEnum[keyof typeof BulkIdResponseDtoErrorEnum];
/**
*
* @export
* @interface BulkIdsDto
*/
export interface BulkIdsDto {
/**
*
* @type {Array<string>}
* @memberof BulkIdsDto
*/
'ids': Array<string>;
}
/**
*
* @export
@@ -1927,19 +1902,6 @@ export interface QueueStatusDto {
*/
'isPaused': boolean;
}
/**
*
* @export
* @interface RemoveAssetsDto
*/
export interface RemoveAssetsDto {
/**
*
* @type {Array<string>}
* @memberof RemoveAssetsDto
*/
'assetIds': Array<string>;
}
/**
*
* @export
@@ -3679,16 +3641,16 @@ export const AlbumApiAxiosParamCreator = function (configuration?: Configuration
/**
*
* @param {string} id
* @param {AddAssetsDto} addAssetsDto
* @param {BulkIdsDto} bulkIdsDto
* @param {string} [key]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
addAssetsToAlbum: async (id: string, addAssetsDto: AddAssetsDto, key?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
addAssetsToAlbum: async (id: string, bulkIdsDto: BulkIdsDto, key?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('addAssetsToAlbum', 'id', id)
// verify required parameter 'addAssetsDto' is not null or undefined
assertParamExists('addAssetsToAlbum', 'addAssetsDto', addAssetsDto)
// verify required parameter 'bulkIdsDto' is not null or undefined
assertParamExists('addAssetsToAlbum', 'bulkIdsDto', bulkIdsDto)
const localVarPath = `/album/{id}/assets`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
@@ -3722,7 +3684,7 @@ export const AlbumApiAxiosParamCreator = function (configuration?: Configuration
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(addAssetsDto, localVarRequestOptions, configuration)
localVarRequestOptions.data = serializeDataIfNeeded(bulkIdsDto, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
@@ -3999,15 +3961,15 @@ export const AlbumApiAxiosParamCreator = function (configuration?: Configuration
/**
*
* @param {string} id
* @param {RemoveAssetsDto} removeAssetsDto
* @param {BulkIdsDto} bulkIdsDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
removeAssetFromAlbum: async (id: string, removeAssetsDto: RemoveAssetsDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
removeAssetFromAlbum: async (id: string, bulkIdsDto: BulkIdsDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('removeAssetFromAlbum', 'id', id)
// verify required parameter 'removeAssetsDto' is not null or undefined
assertParamExists('removeAssetFromAlbum', 'removeAssetsDto', removeAssetsDto)
// verify required parameter 'bulkIdsDto' is not null or undefined
assertParamExists('removeAssetFromAlbum', 'bulkIdsDto', bulkIdsDto)
const localVarPath = `/album/{id}/assets`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
@@ -4037,7 +3999,7 @@ export const AlbumApiAxiosParamCreator = function (configuration?: Configuration
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(removeAssetsDto, localVarRequestOptions, configuration)
localVarRequestOptions.data = serializeDataIfNeeded(bulkIdsDto, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
@@ -4151,13 +4113,13 @@ export const AlbumApiFp = function(configuration?: Configuration) {
/**
*
* @param {string} id
* @param {AddAssetsDto} addAssetsDto
* @param {BulkIdsDto} bulkIdsDto
* @param {string} [key]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async addAssetsToAlbum(id: string, addAssetsDto: AddAssetsDto, key?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AddAssetsResponseDto>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.addAssetsToAlbum(id, addAssetsDto, key, options);
async addAssetsToAlbum(id: string, bulkIdsDto: BulkIdsDto, key?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<BulkIdResponseDto>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.addAssetsToAlbum(id, bulkIdsDto, key, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
@@ -4225,12 +4187,12 @@ export const AlbumApiFp = function(configuration?: Configuration) {
/**
*
* @param {string} id
* @param {RemoveAssetsDto} removeAssetsDto
* @param {BulkIdsDto} bulkIdsDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async removeAssetFromAlbum(id: string, removeAssetsDto: RemoveAssetsDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AlbumResponseDto>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.removeAssetFromAlbum(id, removeAssetsDto, options);
async removeAssetFromAlbum(id: string, bulkIdsDto: BulkIdsDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<BulkIdResponseDto>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.removeAssetFromAlbum(id, bulkIdsDto, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
@@ -4268,13 +4230,13 @@ export const AlbumApiFactory = function (configuration?: Configuration, basePath
/**
*
* @param {string} id
* @param {AddAssetsDto} addAssetsDto
* @param {BulkIdsDto} bulkIdsDto
* @param {string} [key]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
addAssetsToAlbum(id: string, addAssetsDto: AddAssetsDto, key?: string, options?: any): AxiosPromise<AddAssetsResponseDto> {
return localVarFp.addAssetsToAlbum(id, addAssetsDto, key, options).then((request) => request(axios, basePath));
addAssetsToAlbum(id: string, bulkIdsDto: BulkIdsDto, key?: string, options?: any): AxiosPromise<Array<BulkIdResponseDto>> {
return localVarFp.addAssetsToAlbum(id, bulkIdsDto, key, options).then((request) => request(axios, basePath));
},
/**
*
@@ -4335,12 +4297,12 @@ export const AlbumApiFactory = function (configuration?: Configuration, basePath
/**
*
* @param {string} id
* @param {RemoveAssetsDto} removeAssetsDto
* @param {BulkIdsDto} bulkIdsDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
removeAssetFromAlbum(id: string, removeAssetsDto: RemoveAssetsDto, options?: any): AxiosPromise<AlbumResponseDto> {
return localVarFp.removeAssetFromAlbum(id, removeAssetsDto, options).then((request) => request(axios, basePath));
removeAssetFromAlbum(id: string, bulkIdsDto: BulkIdsDto, options?: any): AxiosPromise<Array<BulkIdResponseDto>> {
return localVarFp.removeAssetFromAlbum(id, bulkIdsDto, options).then((request) => request(axios, basePath));
},
/**
*
@@ -4380,10 +4342,10 @@ export interface AlbumApiAddAssetsToAlbumRequest {
/**
*
* @type {AddAssetsDto}
* @type {BulkIdsDto}
* @memberof AlbumApiAddAssetsToAlbum
*/
readonly addAssetsDto: AddAssetsDto
readonly bulkIdsDto: BulkIdsDto
/**
*
@@ -4499,10 +4461,10 @@ export interface AlbumApiRemoveAssetFromAlbumRequest {
/**
*
* @type {RemoveAssetsDto}
* @type {BulkIdsDto}
* @memberof AlbumApiRemoveAssetFromAlbum
*/
readonly removeAssetsDto: RemoveAssetsDto
readonly bulkIdsDto: BulkIdsDto
}
/**
@@ -4562,7 +4524,7 @@ export class AlbumApi extends BaseAPI {
* @memberof AlbumApi
*/
public addAssetsToAlbum(requestParameters: AlbumApiAddAssetsToAlbumRequest, options?: AxiosRequestConfig) {
return AlbumApiFp(this.configuration).addAssetsToAlbum(requestParameters.id, requestParameters.addAssetsDto, requestParameters.key, options).then((request) => request(this.axios, this.basePath));
return AlbumApiFp(this.configuration).addAssetsToAlbum(requestParameters.id, requestParameters.bulkIdsDto, requestParameters.key, options).then((request) => request(this.axios, this.basePath));
}
/**
@@ -4638,7 +4600,7 @@ export class AlbumApi extends BaseAPI {
* @memberof AlbumApi
*/
public removeAssetFromAlbum(requestParameters: AlbumApiRemoveAssetFromAlbumRequest, options?: AxiosRequestConfig) {
return AlbumApiFp(this.configuration).removeAssetFromAlbum(requestParameters.id, requestParameters.removeAssetsDto, options).then((request) => request(this.axios, this.basePath));
return AlbumApiFp(this.configuration).removeAssetFromAlbum(requestParameters.id, requestParameters.bulkIdsDto, options).then((request) => request(this.axios, this.basePath));
}
/**

View File

@@ -92,6 +92,7 @@
let multiSelectAsset: Set<AssetResponseDto> = new Set();
$: isMultiSelectionMode = multiSelectAsset.size > 0;
$: isMultiSelectionUserOwned = Array.from(multiSelectAsset).every((asset) => asset.ownerId === currentUser?.id);
afterNavigate(({ from }) => {
backUrl = from?.url.pathname ?? '/albums';
@@ -182,24 +183,24 @@
const createAlbumHandler = async (event: CustomEvent) => {
const { assets }: { assets: AssetResponseDto[] } = event.detail;
try {
const { data } = await api.albumApi.addAssetsToAlbum({
const { data: results } = await api.albumApi.addAssetsToAlbum({
id: album.id,
addAssetsDto: {
assetIds: assets.map((a) => a.id),
},
bulkIdsDto: { ids: assets.map((a) => a.id) },
key: sharedLink?.key,
});
if (data.album) {
album = data.album;
}
const count = results.filter(({ success }) => success).length;
notificationController.show({
type: NotificationType.Info,
message: `Added ${count} asset${count === 1 ? '' : 's'}`,
});
const { data } = await api.albumApi.getAlbumInfo({ id: album.id });
album = data;
isShowAssetSelection = false;
} catch (e) {
console.error('Error [createAlbumHandler] ', e);
notificationController.show({
type: NotificationType.Error,
message: 'Error creating album, check console for more details',
});
handleError(e, 'Error creating album');
}
};
@@ -307,7 +308,7 @@
{#if sharedLink?.allowDownload || !isPublicShared}
<DownloadAction filename="{album.albumName}.zip" sharedLinkKey={sharedLink?.key} />
{/if}
{#if isOwned}
{#if isOwned || isMultiSelectionUserOwned}
<RemoveFromAlbum bind:album />
{/if}
</AssetSelectControlBar>

View File

@@ -189,11 +189,8 @@
isShowAlbumPicker = false;
const album = event.detail.album;
addAssetsToAlbum(album.id, [asset.id]).then((dto) => {
if (dto.successfullyAdded === 1 && dto.album) {
appearsInAlbums = [...appearsInAlbums, dto.album];
}
});
await addAssetsToAlbum(album.id, [asset.id]);
await getAllAlbums();
};
const disableKeyDownEvent = () => {

View File

@@ -44,10 +44,9 @@
const handleAddToAlbum = async (event: CustomEvent<{ album: AlbumResponseDto }>) => {
showAlbumPicker = false;
const album = event.detail.album;
const assetIds = Array.from(getAssets()).map((asset) => asset.id);
addAssetsToAlbum(album.id, assetIds).then(clearSelect);
await addAssetsToAlbum(album.id, assetIds);
clearSelect();
};
</script>

View File

@@ -17,14 +17,20 @@
const removeFromAlbum = async () => {
try {
const { data } = await api.albumApi.removeAssetFromAlbum({
const { data: results } = await api.albumApi.removeAssetFromAlbum({
id: album.id,
removeAssetsDto: {
assetIds: Array.from(getAssets()).map((a) => a.id),
},
bulkIdsDto: { ids: Array.from(getAssets()).map((a) => a.id) },
});
const { data } = await api.albumApi.getAlbumInfo({ id: album.id });
album = data;
const count = results.filter(({ success }) => success).length;
notificationController.show({
type: NotificationType.Info,
message: `Removed ${count} asset${count === 1 ? '' : 's'}`,
});
clearSelect();
} catch (e) {
console.error('Error [album-viewer] [removeAssetFromAlbum]', e);

View File

@@ -1,23 +1,24 @@
import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification';
import { downloadManager } from '$lib/stores/download';
import { AddAssetsResponseDto, api, AssetApiGetDownloadInfoRequest, AssetResponseDto, DownloadResponseDto } from '@api';
import { api, AssetApiGetDownloadInfoRequest, BulkIdResponseDto, AssetResponseDto, DownloadResponseDto } from '@api';
import { handleError } from './handle-error';
export const addAssetsToAlbum = async (
albumId: string,
assetIds: Array<string>,
key: string | undefined = undefined,
): Promise<AddAssetsResponseDto> =>
api.albumApi.addAssetsToAlbum({ id: albumId, addAssetsDto: { assetIds }, key }).then(({ data: dto }) => {
if (dto.successfullyAdded > 0) {
): Promise<BulkIdResponseDto[]> =>
api.albumApi.addAssetsToAlbum({ id: albumId, bulkIdsDto: { ids: assetIds }, key }).then(({ data: results }) => {
const count = results.filter(({ success }) => success).length;
if (count > 0) {
// This might be 0 if the user tries to add an asset that is already in the album
notificationController.show({
message: `Added ${dto.successfullyAdded} to ${dto.album?.albumName}`,
type: NotificationType.Info,
message: `Added ${count} asset${count === 1 ? '' : 's'}`,
});
}
return dto;
return results;
});
const downloadBlob = (data: Blob, filename: string) => {