refactor(server): stacks (#11453)

* refactor: stacks

* mobile: get it built

* chore: feedback

* fix: sync and duplicates

* mobile: remove old stack reference

* chore: add primary asset id

* revert change to asset entity

* mobile: refactor mobile api

* mobile: sync stack info after creating stack

* mobile: update timeline after deleting stack

* server: update asset updatedAt when stack is deleted

* mobile: simplify action

* mobile: rename to match dto property

* fix: web test

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Jason Rasmussen
2024-08-19 13:37:15 -04:00
committed by GitHub
parent ca52cbace1
commit 8338657eaa
63 changed files with 2321 additions and 1152 deletions

View File

@@ -1689,41 +1689,6 @@
]
}
},
"/assets/stack/parent": {
"put": {
"operationId": "updateStackParent",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateStackParentDto"
}
}
},
"required": true
},
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Assets"
]
}
},
"/assets/statistics": {
"get": {
"operationId": "getAssetStatistics",
@@ -5655,6 +5620,248 @@
]
}
},
"/stacks": {
"delete": {
"operationId": "deleteStacks",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkIdsDto"
}
}
},
"required": true
},
"responses": {
"204": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Stacks"
]
},
"get": {
"operationId": "searchStacks",
"parameters": [
{
"name": "primaryAssetId",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/StackResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Stacks"
]
},
"post": {
"operationId": "createStack",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StackCreateDto"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StackResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Stacks"
]
}
},
"/stacks/{id}": {
"delete": {
"operationId": "deleteStack",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"204": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Stacks"
]
},
"get": {
"operationId": "getStack",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StackResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Stacks"
]
},
"put": {
"operationId": "updateStack",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StackUpdateDto"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StackResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Stacks"
]
}
},
"/sync/delta-sync": {
"post": {
"operationId": "getDeltaSync",
@@ -7570,13 +7777,6 @@
"maximum": 5,
"minimum": 0,
"type": "number"
},
"removeParent": {
"type": "boolean"
},
"stackParentId": {
"format": "uuid",
"type": "string"
}
},
"required": [
@@ -8117,18 +8317,12 @@
"$ref": "#/components/schemas/SmartInfoResponseDto"
},
"stack": {
"items": {
"$ref": "#/components/schemas/AssetResponseDto"
},
"type": "array"
},
"stackCount": {
"nullable": true,
"type": "integer"
},
"stackParentId": {
"nullable": true,
"type": "string"
"allOf": [
{
"$ref": "#/components/schemas/AssetStackResponseDto"
}
],
"nullable": true
},
"tags": {
"items": {
@@ -8172,13 +8366,31 @@
"originalPath",
"ownerId",
"resized",
"stackCount",
"thumbhash",
"type",
"updatedAt"
],
"type": "object"
},
"AssetStackResponseDto": {
"properties": {
"assetCount": {
"type": "integer"
},
"id": {
"type": "string"
},
"primaryAssetId": {
"type": "string"
}
},
"required": [
"assetCount",
"id",
"primaryAssetId"
],
"type": "object"
},
"AssetStatsResponseDto": {
"properties": {
"images": {
@@ -9806,6 +10018,10 @@
"sharedLink.read",
"sharedLink.update",
"sharedLink.delete",
"stack.create",
"stack.read",
"stack.update",
"stack.delete",
"systemConfig.read",
"systemConfig.update",
"systemMetadata.read",
@@ -10882,6 +11098,53 @@
],
"type": "object"
},
"StackCreateDto": {
"properties": {
"assetIds": {
"description": "first asset becomes the primary",
"items": {
"format": "uuid",
"type": "string"
},
"type": "array"
}
},
"required": [
"assetIds"
],
"type": "object"
},
"StackResponseDto": {
"properties": {
"assets": {
"items": {
"$ref": "#/components/schemas/AssetResponseDto"
},
"type": "array"
},
"id": {
"type": "string"
},
"primaryAssetId": {
"type": "string"
}
},
"required": [
"assets",
"id",
"primaryAssetId"
],
"type": "object"
},
"StackUpdateDto": {
"properties": {
"primaryAssetId": {
"format": "uuid",
"type": "string"
}
},
"type": "object"
},
"SystemConfigDto": {
"properties": {
"ffmpeg": {
@@ -11735,23 +11998,6 @@
],
"type": "object"
},
"UpdateStackParentDto": {
"properties": {
"newParentId": {
"format": "uuid",
"type": "string"
},
"oldParentId": {
"format": "uuid",
"type": "string"
}
},
"required": [
"newParentId",
"oldParentId"
],
"type": "object"
},
"UpdateTagDto": {
"properties": {
"name": {

View File

@@ -192,6 +192,11 @@ export type SmartInfoResponseDto = {
objects?: string[] | null;
tags?: string[] | null;
};
export type AssetStackResponseDto = {
assetCount: number;
id: string;
primaryAssetId: string;
};
export type TagResponseDto = {
id: string;
name: string;
@@ -226,9 +231,7 @@ export type AssetResponseDto = {
people?: PersonWithFacesResponseDto[];
resized: boolean;
smartInfo?: SmartInfoResponseDto;
stack?: AssetResponseDto[];
stackCount: number | null;
stackParentId?: string | null;
stack?: (AssetStackResponseDto) | null;
tags?: TagResponseDto[];
thumbhash: string | null;
"type": AssetTypeEnum;
@@ -344,8 +347,6 @@ export type AssetBulkUpdateDto = {
latitude?: number;
longitude?: number;
rating?: number;
removeParent?: boolean;
stackParentId?: string;
};
export type AssetBulkUploadCheckItem = {
/** base64 or hex encoded sha1 hash */
@@ -379,10 +380,6 @@ export type MemoryLaneResponseDto = {
assets: AssetResponseDto[];
yearsAgo: number;
};
export type UpdateStackParentDto = {
newParentId: string;
oldParentId: string;
};
export type AssetStatsResponseDto = {
images: number;
total: number;
@@ -973,6 +970,18 @@ export type AssetIdsResponseDto = {
error?: Error2;
success: boolean;
};
export type StackResponseDto = {
assets: AssetResponseDto[];
id: string;
primaryAssetId: string;
};
export type StackCreateDto = {
/** first asset becomes the primary */
assetIds: string[];
};
export type StackUpdateDto = {
primaryAssetId?: string;
};
export type AssetDeltaSyncDto = {
updatedAfter: string;
userIds: string[];
@@ -1632,15 +1641,6 @@ export function getRandom({ count }: {
...opts
}));
}
export function updateStackParent({ updateStackParentDto }: {
updateStackParentDto: UpdateStackParentDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/assets/stack/parent", oazapfts.json({
...opts,
method: "PUT",
body: updateStackParentDto
})));
}
export function getAssetStatistics({ isArchived, isFavorite, isTrashed }: {
isArchived?: boolean;
isFavorite?: boolean;
@@ -2706,6 +2706,70 @@ export function addSharedLinkAssets({ id, key, assetIdsDto }: {
body: assetIdsDto
})));
}
export function deleteStacks({ bulkIdsDto }: {
bulkIdsDto: BulkIdsDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/stacks", oazapfts.json({
...opts,
method: "DELETE",
body: bulkIdsDto
})));
}
export function searchStacks({ primaryAssetId }: {
primaryAssetId?: string;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: StackResponseDto[];
}>(`/stacks${QS.query(QS.explode({
primaryAssetId
}))}`, {
...opts
}));
}
export function createStack({ stackCreateDto }: {
stackCreateDto: StackCreateDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 201;
data: StackResponseDto;
}>("/stacks", oazapfts.json({
...opts,
method: "POST",
body: stackCreateDto
})));
}
export function deleteStack({ id }: {
id: string;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText(`/stacks/${encodeURIComponent(id)}`, {
...opts,
method: "DELETE"
}));
}
export function getStack({ id }: {
id: string;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: StackResponseDto;
}>(`/stacks/${encodeURIComponent(id)}`, {
...opts
}));
}
export function updateStack({ id, stackUpdateDto }: {
id: string;
stackUpdateDto: StackUpdateDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: StackResponseDto;
}>(`/stacks/${encodeURIComponent(id)}`, oazapfts.json({
...opts,
method: "PUT",
body: stackUpdateDto
})));
}
export function getDeltaSync({ assetDeltaSyncDto }: {
assetDeltaSyncDto: AssetDeltaSyncDto;
}, opts?: Oazapfts.RequestOpts) {
@@ -3187,6 +3251,10 @@ export enum Permission {
SharedLinkRead = "sharedLink.read",
SharedLinkUpdate = "sharedLink.update",
SharedLinkDelete = "sharedLink.delete",
StackCreate = "stack.create",
StackRead = "stack.read",
StackUpdate = "stack.update",
StackDelete = "stack.delete",
SystemConfigRead = "systemConfig.read",
SystemConfigUpdate = "systemConfig.update",
SystemMetadataRead = "systemMetadata.read",