mirror of
https://github.com/immich-app/immich.git
synced 2025-12-01 03:39:43 +09:00
feat: tags (#11980)
* feat: tags * fix: folder tree icons * navigate to tag from detail panel * delete tag * Tag position and add tag button * Tag asset in detail panel * refactor form * feat: navigate to tag page from clicking on a tag * feat: delete tags from the tag page * refactor: moving tag section in detail panel and add + tag button * feat: tag asset action in detail panel * refactor add tag form * fdisable add tag button when there is no selection * feat: tag bulk endpoint * feat: tag colors * chore: clean up * chore: unit tests * feat: write tags to sidecar * Remove tag and auto focus on tag creation form opened * chore: regenerate migration * chore: linting * add color picker to tag edit form * fix: force render tags timeline on navigating back from asset viewer * feat: read tags from keywords * chore: clean up --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
@@ -46,4 +46,8 @@ export interface IAccessRepository {
|
||||
stack: {
|
||||
checkOwnerAccess(userId: string, stackIds: Set<string>): Promise<Set<string>>;
|
||||
};
|
||||
|
||||
tag: {
|
||||
checkOwnerAccess(userId: string, tagIds: Set<string>): Promise<Set<string>>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ export interface AssetBuilderOptions {
|
||||
isTrashed?: boolean;
|
||||
isDuplicate?: boolean;
|
||||
albumId?: string;
|
||||
tagId?: string;
|
||||
personId?: string;
|
||||
userIds?: string[];
|
||||
withStacked?: boolean;
|
||||
|
||||
@@ -17,6 +17,10 @@ type EmitEventMap = {
|
||||
'album.update': [{ id: string; updatedBy: string }];
|
||||
'album.invite': [{ id: string; userId: string }];
|
||||
|
||||
// tag events
|
||||
'asset.tag': [{ assetId: string }];
|
||||
'asset.untag': [{ assetId: string }];
|
||||
|
||||
// user events
|
||||
'user.signup': [{ notify: boolean; id: string; tempPassword?: string }];
|
||||
};
|
||||
|
||||
@@ -155,6 +155,7 @@ export interface ISidecarWriteJob extends IEntityJob {
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
rating?: number;
|
||||
tags?: true;
|
||||
}
|
||||
|
||||
export interface IDeferrableJob extends IEntityJob {
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { AssetEntity } from 'src/entities/asset.entity';
|
||||
import { TagEntity } from 'src/entities/tag.entity';
|
||||
import { IBulkAsset } from 'src/utils/asset.util';
|
||||
|
||||
export const ITagRepository = 'ITagRepository';
|
||||
|
||||
export interface ITagRepository {
|
||||
getById(userId: string, tagId: string): Promise<TagEntity | null>;
|
||||
export type AssetTagItem = { assetId: string; tagId: string };
|
||||
|
||||
export interface ITagRepository extends IBulkAsset {
|
||||
getAll(userId: string): Promise<TagEntity[]>;
|
||||
getByValue(userId: string, value: string): Promise<TagEntity | null>;
|
||||
|
||||
create(tag: Partial<TagEntity>): Promise<TagEntity>;
|
||||
update(tag: Partial<TagEntity>): Promise<TagEntity>;
|
||||
remove(tag: TagEntity): Promise<void>;
|
||||
hasName(userId: string, name: string): Promise<boolean>;
|
||||
hasAsset(userId: string, tagId: string, assetId: string): Promise<boolean>;
|
||||
getAssets(userId: string, tagId: string): Promise<AssetEntity[]>;
|
||||
addAssets(userId: string, tagId: string, assetIds: string[]): Promise<void>;
|
||||
removeAssets(userId: string, tagId: string, assetIds: string[]): Promise<void>;
|
||||
get(id: string): Promise<TagEntity | null>;
|
||||
update(tag: { id: string } & Partial<TagEntity>): Promise<TagEntity>;
|
||||
delete(id: string): Promise<void>;
|
||||
|
||||
upsertAssetTags({ assetId, tagIds }: { assetId: string; tagIds: string[] }): Promise<void>;
|
||||
upsertAssetIds(items: AssetTagItem[]): Promise<AssetTagItem[]>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user