@webx-ui/module-catalog 0.2.0 → 0.3.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.
@@ -1,2 +1,16 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
1
+ type __VLS_Props = {
2
+ /** Videos on this site (`webx-catalog.fields.video`); the server's screen patch says. */
3
+ video?: boolean;
4
+ /** What a video file may be, checked before a byte of it is sent. */
5
+ videoTypes?: string[];
6
+ /** How large, in bytes. */
7
+ videoMaxBytes?: number;
8
+ };
9
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ video: boolean;
11
+ videoTypes: string[];
12
+ videoMaxBytes: number;
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
14
+ picker: HTMLInputElement;
15
+ }, HTMLDivElement>;
2
16
  export default _default;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A video by its address, onto a picture of the gallery: a YouTube link, or a direct link to an
3
+ * MP4 or WebM file the server then downloads in its queue (§5 of the video spec).
4
+ */
5
+ type __VLS_Props = {
6
+ product: number;
7
+ image: number;
8
+ };
9
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
10
+ field: HTMLDivElement;
11
+ }, any>;
12
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { GalleryVideo, VideoJob } from './galleryVideo';
2
+ /**
3
+ * One video on its way into the gallery: what it is doing, and the bar while the file goes up —
4
+ * the share, the speed and the time left, with pause and cancel beside it.
5
+ */
6
+ type __VLS_Props = {
7
+ job: VideoJob;
8
+ video: GalleryVideo;
9
+ };
10
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
11
+ export default _default;
package/dist/api.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AdminContext } from '@webx-ui/module-admin';
2
2
  import { Paginated } from '@webx-ui/core';
3
3
  import { ScreenModel } from '@webx-ui/schema';
4
- import { BulkActionInfo, BulkRun, BulkSelection, CategoryDetail, CategoryNode, CategoryRow, DeletedCategory, DeletedKind, DeletedProduct, FacetRegistryAnswer, ProductDetail, ProductImage, ProductQuery, ProductRow, ProductsPage } from './types';
4
+ import { BulkActionInfo, BulkRun, BulkSelection, CategoryDetail, CategoryNode, CategoryRow, DeletedCategory, DeletedKind, DeletedProduct, FacetRegistryAnswer, ProductDetail, ProductImage, ProductQuery, QueuedVideo, ProductRow, ProductsPage } from './types';
5
5
  export interface CatalogApi {
6
6
  products(query?: ProductQuery): Promise<ProductsPage>;
7
7
  product(id: number): Promise<ProductDetail>;
@@ -15,6 +15,20 @@ export interface CatalogApi {
15
15
  /** The whole gallery in its order, with every picture's words (§11.2). */
16
16
  saveImages(id: number, images: Pick<ProductImage, 'id' | 'alt' | 'title'>[]): Promise<ProductImage[]>;
17
17
  removeImage(id: number, image: number): Promise<void>;
18
+ /**
19
+ * An address the server fetches: a picture or a YouTube video comes back as the new row, a
20
+ * direct link to a video file as `QueuedVideo` — the row appears once the queue has it.
21
+ */
22
+ fetchImage(id: number, url: string): Promise<ProductImage | QueuedVideo>;
23
+ /** A finished chunked upload (`upload` is its id) or an address, onto a picture of the gallery. */
24
+ attachVideo(id: number, image: number, source: {
25
+ upload: string;
26
+ duration?: number | null;
27
+ } | {
28
+ url: string;
29
+ }): Promise<ProductImage | QueuedVideo>;
30
+ /** The file, if it is one, is deleted at once. */
31
+ detachVideo(id: number, image: number): Promise<ProductImage>;
18
32
  categories(): Promise<CategoryNode[]>;
19
33
  category(id: number): Promise<CategoryDetail>;
20
34
  createCategory(values: ScreenModel, parent: number | null): Promise<CategoryDetail>;
package/dist/editor.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { InjectionKey, Ref } from 'vue';
2
+ import { GalleryVideo } from './galleryVideo';
2
3
  import { CategoryRow, ProductImage, ProductRow } from './types';
3
4
  /**
4
5
  * What the product editor knows and the nodes of `catalog.product-form` do not.
@@ -14,6 +15,12 @@ export interface ProductEditorContext {
14
15
  images: Ref<ProductImage[]>;
15
16
  /** Closed for writing: no permission, or a save in flight. */
16
17
  locked: Ref<boolean>;
18
+ /**
19
+ * Video files on their way into the gallery. Kept up here rather than in the gallery field, whose
20
+ * tab is taken down when another is opened — and an upload with it. The field makes its own
21
+ * when an editor leaves it out.
22
+ */
23
+ video?: GalleryVideo;
17
24
  }
18
25
  export declare const productEditorKey: InjectionKey<ProductEditorContext>;
19
26
  export declare function provideProductEditor(editor: ProductEditorContext): void;
@@ -0,0 +1,67 @@
1
+ import { ComputedRef, Ref } from 'vue';
2
+ import { AdminContext, ChunkedUpload, UnfinishedUpload } from '@webx-ui/module-admin';
3
+ import { ProductImage } from './types';
4
+ import { ProbeOptions } from './video';
5
+ /**
6
+ * Video files going into the gallery (§7 of the video spec): the frame, the picture, the file a
7
+ * piece at a time, and the request that puts the two together.
8
+ *
9
+ * Kept by the product editor rather than by the gallery field. The field lives on a tab, and a tab
10
+ * nobody is looking at is taken down — with the chunked upload inside it, which pauses when its
11
+ * scope dies. Up here the upload carries on while the rest of the form is being filled in.
12
+ *
13
+ * One file at a time, as there is one chunked upload: several at once share one connection
14
+ * anyway, and one bar that moves says more than three that crawl.
15
+ */
16
+ export declare const VIDEO_PURPOSE = "catalog.video";
17
+ export type VideoJobStage = 'waiting' | 'poster' | 'uploading' | 'attaching' | 'failed';
18
+ export interface VideoJob {
19
+ key: number;
20
+ file: File;
21
+ /** The product it goes to, as it was when the file was chosen. */
22
+ product: number;
23
+ /** The picture it goes onto; `null` until the frame has been uploaded as one. */
24
+ image: number | null;
25
+ /** The job made that picture itself — a cancel takes it away again. */
26
+ created: boolean;
27
+ /** The frame, until the picture is on the server and the row shows its own. */
28
+ poster: string | null;
29
+ duration: number | null;
30
+ stage: VideoJobStage;
31
+ /** Why it stopped, in words; only in `failed`. */
32
+ error: string | null;
33
+ /** The browser could not open the file, so there is no frame to make a picture of. */
34
+ unreadable: boolean;
35
+ }
36
+ /** An upload this browser left unfinished for this product, with the picture it was for. */
37
+ export interface UnfinishedVideo extends UnfinishedUpload {
38
+ image: number | null;
39
+ }
40
+ export interface GalleryVideo {
41
+ readonly jobs: Readonly<Ref<readonly VideoJob[]>>;
42
+ /** The one upload that moves — its state, progress, speed and time left. */
43
+ readonly upload: ChunkedUpload;
44
+ /** Something is on its way to the server; leaving now loses the rest of it. */
45
+ readonly busy: ComputedRef<boolean>;
46
+ /** What a reload interrupted on this product, to be continued by choosing the file again. */
47
+ readonly unfinished: ComputedRef<UnfinishedVideo[]>;
48
+ /** Onto `image`, or a new row made of its own frame when there is none. */
49
+ add(file: File, image?: number | null): void;
50
+ pause(): void;
51
+ resume(): void;
52
+ /** Try a failed one again: a file the server has part of continues from there. */
53
+ retry(job: VideoJob): void;
54
+ cancel(job: VideoJob): Promise<void>;
55
+ /** Take a failed one off the list. */
56
+ dismiss(job: VideoJob): void;
57
+ /** Stop offering to continue an upload. */
58
+ forget(entry: UnfinishedVideo): void;
59
+ }
60
+ export interface GalleryVideoOptions {
61
+ product: Ref<number | null>;
62
+ images: Ref<ProductImage[]>;
63
+ admin?: AdminContext;
64
+ storage?: Storage | null;
65
+ probe?: ProbeOptions;
66
+ }
67
+ export declare function createGalleryVideo(options: GalleryVideoOptions): GalleryVideo;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { catalog, type CatalogOptions } from './module';
2
2
  export { createCatalogApi, productSearch, CATALOG_API, type CatalogApi } from './api';
3
3
  export { catalogMessages } from './messages';
4
4
  export { provideProductEditor, productEditorKey, useProductEditor, provideCatalogCategoryEditor, categoryEditorKey, useCatalogCategoryEditor, type ProductEditorContext, type CategoryEditorContext, } from './editor';
5
+ export { createGalleryVideo, VIDEO_PURPOSE, type GalleryVideo, type GalleryVideoOptions, type UnfinishedVideo, type VideoJob, type VideoJobStage, } from './galleryVideo';
5
6
  export { useCategoryTree, useFacetRegistry, type CategoryTree, type FacetRegistry } from './store';
6
7
  export { default as WxCatalogProductsPage } from './ProductsPage';
7
8
  export { default as WxCatalogProductEditor } from './ProductEditorPage';
@@ -13,4 +14,4 @@ export { default as WxCatalogDeletedPage } from './DeletedPage';
13
14
  export { default as WxCatalogCategoryField } from './CategoryField';
14
15
  export { default as WxCatalogFacetsField } from './FacetsField';
15
16
  export { default as WxCatalogGallery } from './GalleryField';
16
- export type { CategoryDetail, CategoryNode, CategoryRef, CategoryRow, DeletedCategory, DeletedKind, DeletedProduct, FacetChoice, FacetInfo, FacetKind, FacetSetting, ProductColumnInfo, ProductDetail, ProductImage, ProductQuery, ProductRow, ProductSort, ProductState, ProductsPage, SkuHolder, } from './types';
17
+ export type { CategoryDetail, CategoryNode, CategoryRef, CategoryRow, DeletedCategory, DeletedKind, DeletedProduct, FacetChoice, FacetInfo, FacetKind, FacetSetting, ProductColumnInfo, ProductDetail, ProductImage, ProductQuery, ProductVideo, QueuedVideo, ProductRow, ProductSort, ProductState, ProductsPage, SkuHolder, } from './types';