@codingfactory/mediables-vue 2.15.0 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/{PixiFrameExporter-QBVjL5I-.js → PixiFrameExporter-B1jinD_-.js} +2 -2
  2. package/dist/{PixiFrameExporter-QBVjL5I-.js.map → PixiFrameExporter-B1jinD_-.js.map} +1 -1
  3. package/dist/{PixiFrameExporter-F0BnA8PJ.cjs → PixiFrameExporter-vNJtMooF.cjs} +2 -2
  4. package/dist/{PixiFrameExporter-F0BnA8PJ.cjs.map → PixiFrameExporter-vNJtMooF.cjs.map} +1 -1
  5. package/dist/components/AlbumNavRail.vue.d.ts +27 -0
  6. package/dist/components/AlbumTree.vue.d.ts +2 -0
  7. package/dist/components/MediaAlbumPickerModal.vue.d.ts +14 -0
  8. package/dist/components/MediaBulkActionBar.vue.d.ts +33 -0
  9. package/dist/components/MediaEmptyState.vue.d.ts +20 -0
  10. package/dist/components/MediaFilterChips.vue.d.ts +26 -0
  11. package/dist/components/MediaInspectorPanel.vue.d.ts +36 -0
  12. package/dist/components/MediaLibraryShell.vue.d.ts +36 -0
  13. package/dist/components/MediaLibraryToolbar.vue.d.ts +11 -0
  14. package/dist/components/MediaLibraryWorkspace.vue.d.ts +70 -0
  15. package/dist/components/MediaManagementView.vue.d.ts +33 -1
  16. package/dist/components/MediaShortcutHelp.vue.d.ts +13 -0
  17. package/dist/components/MediaTrashWorkspace.vue.d.ts +15 -0
  18. package/dist/components/MediaUsageList.vue.d.ts +17 -0
  19. package/dist/components/MediaVariantStrip.vue.d.ts +10 -0
  20. package/dist/composables/useAlbums.d.ts +10 -1
  21. package/dist/composables/useMediaDeletion.d.ts +36 -0
  22. package/dist/composables/useMediaDisplayName.d.ts +19 -0
  23. package/dist/composables/useMediaLibraryQuery.d.ts +25 -2
  24. package/dist/composables/useMediaLibraryUploads.d.ts +41 -0
  25. package/dist/composables/useMediaSelection.d.ts +34 -4
  26. package/dist/composables/useMediaTrash.d.ts +10 -0
  27. package/dist/index-DCTHBp0p.cjs +357 -0
  28. package/dist/index-DCTHBp0p.cjs.map +1 -0
  29. package/dist/{index-CxgL9IC3.js → index-IIKslTrU.js} +19349 -16351
  30. package/dist/index-IIKslTrU.js.map +1 -0
  31. package/dist/index.d.ts +34 -3
  32. package/dist/mediables-vue.cjs +1 -1
  33. package/dist/mediables-vue.mjs +109 -90
  34. package/dist/render-page/assets/{index-jZGmiMRr.js → index-DQB8PyEU.js} +11 -2
  35. package/dist/render-page/index.html +1 -1
  36. package/dist/stores/albumStore.d.ts +17 -0
  37. package/dist/style.css +1 -1
  38. package/dist/types/media.d.ts +5 -0
  39. package/dist/types/mediaLibraryPicker.d.ts +73 -1
  40. package/package.json +1 -1
  41. package/dist/index-CdE6UIlk.cjs +0 -357
  42. package/dist/index-CdE6UIlk.cjs.map +0 -1
  43. package/dist/index-CxgL9IC3.js.map +0 -1
@@ -0,0 +1,15 @@
1
+ import type { MediaLibraryHttpClient } from '../types/mediaLibraryPicker';
2
+ export interface MediaTrashWorkspaceLabels {
3
+ title?: string;
4
+ emptyTitle?: string;
5
+ emptyDescription?: string;
6
+ restore?: string;
7
+ purge?: string;
8
+ emptyTrash?: string;
9
+ }
10
+ export interface MediaTrashWorkspaceProps {
11
+ httpClient: MediaLibraryHttpClient;
12
+ labels?: MediaTrashWorkspaceLabels;
13
+ }
14
+ declare const _default: import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, string, {}, {}, string, {}, {}, {}, string, import("vue").ComponentProvideOptions>;
15
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import type { Media } from '../types/media';
2
+ import type { MediaLibraryHttpClient } from '../types/mediaLibraryPicker';
3
+ export interface MediaUsageListItem {
4
+ id: string;
5
+ label: string;
6
+ href?: string;
7
+ count?: number;
8
+ }
9
+ export interface MediaUsageListProps {
10
+ media: Media | null;
11
+ httpClient?: MediaLibraryHttpClient;
12
+ items?: MediaUsageListItem[];
13
+ title?: string;
14
+ emptyLabel?: string;
15
+ }
16
+ declare const _default: import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, string, {}, {}, string, {}, {}, {}, string, import("vue").ComponentProvideOptions>;
17
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import type { Media } from '../types/media';
2
+ import type { MediaLibraryHttpClient } from '../types/mediaLibraryPicker';
3
+ export interface MediaVariantStripProps {
4
+ media: Media | null;
5
+ httpClient?: MediaLibraryHttpClient;
6
+ variants?: Media[];
7
+ title?: string;
8
+ }
9
+ declare const _default: import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, string, {}, {}, string, {}, {}, {}, string, import("vue").ComponentProvideOptions>;
10
+ export default _default;
@@ -1,5 +1,6 @@
1
1
  import type { Ref } from 'vue';
2
- import type { Album } from '@/types/album';
2
+ import type { Album, CreateAlbumPayload, UpdateAlbumPayload } from '@/types/album';
3
+ import type { Media } from '@/types/media';
3
4
  export interface FetchAlbumsParams {
4
5
  parent_id?: string | null;
5
6
  }
@@ -10,6 +11,14 @@ export interface UseAlbumsReturn {
10
11
  loading: Ref<boolean>;
11
12
  error: Ref<string | null>;
12
13
  fetchAlbums: (params?: FetchAlbumsParams) => Promise<void>;
14
+ fetchAlbum: (albumId: string) => Promise<Album>;
15
+ fetchAlbumMedia: (albumId: string) => Promise<Media[]>;
16
+ attachMedia: (albumId: string, mediaIds: string[], orderColumn?: number) => Promise<Album>;
17
+ detachMedia: (albumId: string, mediaId: string) => Promise<void>;
18
+ reorderAlbumMedia: (albumId: string, orderedIds: string[]) => Promise<void>;
19
+ createAlbum: (payload: CreateAlbumPayload) => Promise<Album>;
20
+ updateAlbum: (albumId: string, payload: UpdateAlbumPayload) => Promise<Album>;
21
+ deleteAlbum: (albumId: string) => Promise<void>;
13
22
  getChildrenOf: (parentId: string | null) => Album[];
14
23
  childrenLoaded: (parentId: string) => boolean;
15
24
  moveAlbum: (albumId: string, newParentId: string | null) => Promise<void>;
@@ -37,6 +37,29 @@ export interface BatchDeleteResponse {
37
37
  results: BatchDeleteResultItem[];
38
38
  summary: Partial<Record<BatchDeleteItemStatus, number>>;
39
39
  }
40
+ /**
41
+ * Thrown when the backend reports `requires_confirmation: true` on a
42
+ * deletion attempt — the host UI should present the {@link softBlocks}
43
+ * to the user, then retry `deleteMany()` with `{ confirmed: true }`.
44
+ *
45
+ * Hard blocks (published galleries, etc.) raise a regular HTTP error
46
+ * with `blocks` and are surfaced via the underlying http client's
47
+ * standard rejection — they are never bypassable via this flow.
48
+ */
49
+ export declare class RequiresConfirmationError extends Error {
50
+ /** Per-uuid soft blocks the user must acknowledge. */
51
+ readonly softBlocks: Record<string, DeletionBlock[]>;
52
+ constructor(softBlocks: Record<string, DeletionBlock[]>, message?: string);
53
+ }
54
+ /**
55
+ * Per-item view of a soft block, suitable for rendering a confirmation
56
+ * prompt. Hosts that inject a `confirmDestructiveAction` callback receive
57
+ * an array of these (one entry per affected media uuid).
58
+ */
59
+ export interface SoftBlock {
60
+ uuid: string;
61
+ blocks: DeletionBlock[];
62
+ }
40
63
  export interface UseMediaDeletionOptions {
41
64
  httpClient: MediaLibraryHttpClient;
42
65
  /** Endpoint paths — overridable for apps with non-default routes (e.g., admin namespace). */
@@ -50,8 +73,21 @@ export interface UseMediaDeletionReturn {
50
73
  lastResponse: Ref<BatchDeleteResponse | null>;
51
74
  error: Ref<Error | null>;
52
75
  checkDependencies: (uuids: string[]) => Promise<DependencyReport[]>;
76
+ /**
77
+ * Trigger the batch-delete endpoint.
78
+ *
79
+ * - `force` — request the server bypass hard dependency blocks (e.g.,
80
+ * admin override). Default `false`.
81
+ * - `confirmed` — acknowledge soft (confirmation-required) blocks
82
+ * surfaced via {@link RequiresConfirmationError}. Default `false`.
83
+ *
84
+ * If the backend responds 409 with `requires_confirmation: true`, this
85
+ * call rejects with a {@link RequiresConfirmationError} so the UI can
86
+ * present the soft blocks and retry with `{ confirmed: true }`.
87
+ */
53
88
  deleteMany: (uuids: string[], options?: {
54
89
  force?: boolean;
90
+ confirmed?: boolean;
55
91
  }) => Promise<BatchDeleteResponse>;
56
92
  reset: () => void;
57
93
  }
@@ -0,0 +1,19 @@
1
+ import type { Media } from '../types/media';
2
+ export declare function cleanFileLikeName(value: string): string;
3
+ /**
4
+ * Resolve a human-readable display name for a Media row.
5
+ *
6
+ * Priority (per plan §14b.10):
7
+ * 1. `custom_properties.display_name`
8
+ * 2. `custom_properties.original_filename`
9
+ * 3. cleaned `file_name`
10
+ *
11
+ * `alt_text` is NEVER used as a title — it's an accessibility field describing
12
+ * the image's content. Surfacing it as a tile/heading title teaches users to
13
+ * write worse alt text.
14
+ */
15
+ export declare function getMediaDisplayName(item: Media): string;
16
+ export declare function useMediaDisplayName(): {
17
+ getMediaDisplayName: typeof getMediaDisplayName;
18
+ cleanFileLikeName: typeof cleanFileLikeName;
19
+ };
@@ -1,11 +1,29 @@
1
- import { type Ref } from 'vue';
1
+ import { type MaybeRefOrGetter, type Ref } from 'vue';
2
2
  import type { Media } from '../types/media';
3
3
  import type { MediaLibraryFilters, MediaLibraryHydratedRecord, MediaLibraryHttpClient, MediaLibraryPickerError, MediaLibraryView } from '../types/mediaLibraryPicker';
4
4
  interface UseMediaLibraryQueryOptions {
5
5
  httpClient: MediaLibraryHttpClient;
6
6
  view: Ref<MediaLibraryView>;
7
7
  filters: Ref<MediaLibraryFilters>;
8
- perPage?: number;
8
+ /**
9
+ * Items per page. Accepts a plain number, a Ref, or a getter so the
10
+ * caller can flip page sizes at runtime (page-size selector). When
11
+ * the resolved value changes, callers should call `refresh()` /
12
+ * `loadInitial()` to re-fetch from the new size.
13
+ */
14
+ perPage?: MaybeRefOrGetter<number>;
15
+ /**
16
+ * Active page number for numbered (offset) pagination. When non-null,
17
+ * the composable runs in paginated mode: each load fetches an exact
18
+ * page slice from the server, items array is replaced (not appended),
19
+ * and `total` / `currentPage` / `totalPages` are populated. When null
20
+ * or omitted, the composable runs in cursor mode (the default).
21
+ */
22
+ page?: MaybeRefOrGetter<number | null>;
23
+ }
24
+ interface LoadAllOptions {
25
+ /** Hard cap on items loaded. Default: 5000. */
26
+ maxItems?: number;
9
27
  }
10
28
  export declare function useMediaLibraryQuery(options: UseMediaLibraryQueryOptions): {
11
29
  items: Ref<Media[]>;
@@ -16,8 +34,13 @@ export declare function useMediaLibraryQuery(options: UseMediaLibraryQueryOption
16
34
  loadingMore: Ref<boolean>;
17
35
  permissionDenied: Ref<boolean>;
18
36
  error: Ref<MediaLibraryPickerError | null>;
37
+ total: Ref<number | null>;
38
+ currentPage: Ref<number | null>;
39
+ totalPages: Ref<number | null>;
19
40
  loadInitial: () => Promise<void>;
20
41
  loadMore: () => Promise<void>;
42
+ loadAll: (options?: LoadAllOptions) => Promise<void>;
43
+ goToPage: (page: number) => Promise<void>;
21
44
  refresh: () => Promise<void>;
22
45
  hydrateSelection: (ids: string[]) => Promise<MediaLibraryHydratedRecord[]>;
23
46
  prepend: (media: Media) => void;
@@ -0,0 +1,41 @@
1
+ import type { Media } from '../types/media';
2
+ import type { MediaLibraryHttpClient } from '../types/mediaLibraryPicker';
3
+ export type MediaLibraryUploadStatus = 'queued' | 'uploading' | 'success' | 'error';
4
+ export interface MediaLibraryOptimisticUpload {
5
+ cid: string;
6
+ fileName: string;
7
+ size: number;
8
+ status: MediaLibraryUploadStatus;
9
+ progress: number;
10
+ errorMessage?: string;
11
+ previewUrl?: string;
12
+ }
13
+ export interface UseMediaLibraryUploadsOptions {
14
+ httpClient: MediaLibraryHttpClient;
15
+ endpoint?: string;
16
+ onMediaUploaded?: (media: Media) => void | Promise<void>;
17
+ }
18
+ export declare function useMediaLibraryUploads(options: UseMediaLibraryUploadsOptions): {
19
+ uploads: import("vue").Ref<{
20
+ cid: string;
21
+ fileName: string;
22
+ size: number;
23
+ status: MediaLibraryUploadStatus;
24
+ progress: number;
25
+ errorMessage?: string | undefined;
26
+ previewUrl?: string | undefined;
27
+ }[], MediaLibraryOptimisticUpload[] | {
28
+ cid: string;
29
+ fileName: string;
30
+ size: number;
31
+ status: MediaLibraryUploadStatus;
32
+ progress: number;
33
+ errorMessage?: string | undefined;
34
+ previewUrl?: string | undefined;
35
+ }[]>;
36
+ hasActiveUploads: import("vue").ComputedRef<boolean>;
37
+ uploadFile: (file: File) => Promise<MediaLibraryOptimisticUpload>;
38
+ uploadFiles: (fileList: FileList | File[]) => Promise<MediaLibraryOptimisticUpload[]>;
39
+ dismiss: (cid: string) => void;
40
+ clear: () => void;
41
+ };
@@ -1,14 +1,41 @@
1
- import { type Ref } from 'vue';
1
+ import { type MaybeRefOrGetter, type Ref } from 'vue';
2
2
  import type { Media } from '../types/media';
3
3
  export interface SelectionEvent {
4
4
  type: 'selection:changed';
5
5
  count: number;
6
6
  selectedIds: string[];
7
7
  }
8
- export declare function useMediaSelection(items: Ref<Media[]>): {
9
- selectedIds: import("vue").ComputedRef<Set<string> & Omit<Set<string>, keyof Set<any>>>;
8
+ export interface SelectAcrossAllPagesResult {
9
+ uuids: string[];
10
+ overCap: boolean;
11
+ totalMatching: number | null;
12
+ }
13
+ export interface MediaSelectionRecord {
14
+ uuid: string;
15
+ selectedAt: number;
16
+ page: number | null;
17
+ }
18
+ export interface UseMediaSelectionOptions {
19
+ scopeKey?: MaybeRefOrGetter<string>;
20
+ currentPage?: MaybeRefOrGetter<number | null>;
21
+ confirmScopeChange?: (payload: {
22
+ from: string;
23
+ to: string;
24
+ selectedCount: number;
25
+ }) => boolean | Promise<boolean>;
26
+ fetchMatchingUuids?: () => Promise<SelectAcrossAllPagesResult>;
27
+ }
28
+ export declare function useMediaSelection(items: Ref<Media[]>, options?: UseMediaSelectionOptions): {
29
+ selectedIds: import("vue").ComputedRef<Set<string>>;
30
+ selectedRecords: import("vue").ComputedRef<Map<string, MediaSelectionRecord>>;
10
31
  selectedItems: import("vue").ComputedRef<Media[]>;
11
32
  selectedCount: import("vue").ComputedRef<number>;
33
+ orderedIds: import("vue").ComputedRef<string[]>;
34
+ crossPageCount: import("vue").ComputedRef<number>;
35
+ selectedPages: import("vue").ComputedRef<Map<number, number>>;
36
+ overCap: import("vue").ComputedRef<boolean>;
37
+ totalMatching: import("vue").ComputedRef<number | null>;
38
+ activeScopeKey: import("vue").ComputedRef<string>;
12
39
  isAllSelected: import("vue").ComputedRef<boolean>;
13
40
  isSomeSelected: import("vue").ComputedRef<boolean>;
14
41
  lastSelectedId: import("vue").ComputedRef<string | null>;
@@ -19,7 +46,10 @@ export declare function useMediaSelection(items: Ref<Media[]>): {
19
46
  selectAll: () => void;
20
47
  clear: () => void;
21
48
  toggleAll: () => void;
22
- rangeSelect: (targetUuid: string, event?: MouseEvent) => void;
49
+ rangeSelect: (targetUuid: string, event?: MouseEvent | PointerEvent) => void;
50
+ selectAcrossAllPages: () => Promise<SelectAcrossAllPagesResult>;
51
+ setScopeKey: (nextScopeKey: string) => Promise<boolean>;
52
+ canChangeScope: (nextScopeKey: string) => Promise<boolean>;
23
53
  selectNext: () => void;
24
54
  selectPrevious: () => void;
25
55
  handleKeydown: (event: KeyboardEvent) => void;
@@ -36,12 +36,18 @@ export interface RestoreResult {
36
36
  duplicate_uuid?: string | null;
37
37
  message?: string;
38
38
  }
39
+ export interface PurgeResult {
40
+ status: 'purging' | 'not_found' | 'not_trashed' | 'failed';
41
+ message?: string;
42
+ }
39
43
  export interface UseMediaTrashOptions {
40
44
  httpClient: MediaLibraryHttpClient;
41
45
  /** Endpoint paths — overridable for apps with non-default routes (e.g., admin namespace). */
42
46
  listEndpoint?: string;
43
47
  /** Function building the restore endpoint URL. Default: `/v1/user/media/{uuid}/restore`. */
44
48
  buildRestoreEndpoint?: (uuid: string) => string;
49
+ /** Function building the permanent purge endpoint URL. Default: `/v1/user/media/{uuid}/purge`. */
50
+ buildPurgeEndpoint?: (uuid: string) => string;
45
51
  perPage?: number;
46
52
  }
47
53
  export interface UseMediaTrashReturn {
@@ -50,15 +56,19 @@ export interface UseMediaTrashReturn {
50
56
  currentPage: Ref<number>;
51
57
  isLoading: Ref<boolean>;
52
58
  isRestoring: Ref<boolean>;
59
+ isPurging: Ref<boolean>;
53
60
  error: Ref<Error | null>;
54
61
  fetch: (page?: number) => Promise<void>;
55
62
  restore: (uuid: string) => Promise<RestoreResult>;
63
+ purge: (uuid: string) => Promise<PurgeResult>;
56
64
  reset: () => void;
57
65
  }
58
66
  declare function buildDefaultRestoreEndpoint(uuid: string): string;
67
+ declare function buildDefaultPurgeEndpoint(uuid: string): string;
59
68
  export declare function useMediaTrash(options: UseMediaTrashOptions): UseMediaTrashReturn;
60
69
  export declare const __testing__: {
61
70
  buildDefaultRestoreEndpoint: typeof buildDefaultRestoreEndpoint;
71
+ buildDefaultPurgeEndpoint: typeof buildDefaultPurgeEndpoint;
62
72
  DEFAULT_LIST_ENDPOINT: string;
63
73
  };
64
74
  export {};