@orangelogic/orange-dam-content-browser-sdk 2.4.8 → 2.4.9
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.
- package/build/GlobalConfigContext.d.ts +4 -0
- package/build/OrangeDAMContentBrowserSDK.min.js +738 -337
- package/build/api/asset/asset.d.ts +2 -1
- package/build/api/asset/asset.types.d.ts +9 -0
- package/build/components/content-browser/content-browser.d.ts +73 -2
- package/build/components/content-browser-asset-card/content-browser-asset-card.d.ts +25 -1
- package/build/components/content-browser-control-bar/content-browser-control-bar.d.ts +1 -0
- package/build/components/content-browser-control-view/content-browser-control-view.d.ts +5 -2
- package/build/components/content-browser-format-dialog/content-browser-format-dialog.d.ts +27 -1
- package/build/components/content-browser-grid/content-browser-grid.d.ts +5 -1
- package/build/components/content-browser-table/column-layout.d.ts +29 -0
- package/build/components/content-browser-table/content-browser-table.d.ts +302 -0
- package/build/components/content-browser-table/content-browser-table.styles.d.ts +2 -0
- package/build/content-browser.mjs +2506 -450
- package/build/events/cx-content-browser-control-view-change.d.ts +2 -2
- package/build/events/cx-content-browser-request-change.d.ts +2 -2
- package/build/events/cx-content-browser-table-column-resize.d.ts +26 -0
- package/build/events/index.d.ts +1 -0
- package/build/index.d.ts +40 -2
- package/build/index.html +4 -0
- package/build/index.mjs +2531 -635
- package/build/tools/fetch-and-merge-assets.d.ts +15 -3
- package/build/types/asset.d.ts +5 -0
- package/build/types/content-browser.d.ts +69 -0
- package/build/utils/table-column-widths.d.ts +5 -0
- package/package.json +2 -2
|
@@ -36,7 +36,8 @@ export declare function resolveAssetExtraFilters(selectedFacets?: Record<string,
|
|
|
36
36
|
};
|
|
37
37
|
export declare function apiGetAssetLinks({ assets, extension, extraFields, parameters, permanentLink, proxyPreference, transformations, useSession, }: GetAssetLinksRequest): Promise<GetAssetLinksResponse>;
|
|
38
38
|
export declare function apiGetAssetsByIDs({ extraFields, recordIds, }: GetAssetsByIDsRequest): Promise<GetAssetsByIDsResponse>;
|
|
39
|
-
export declare
|
|
39
|
+
export declare const ASSET_LIST_FIELDS: string[];
|
|
40
|
+
export declare function apiGetAssets({ fields, folderId, isSeeThrough, limitedToDocTypes, pageSize, searchText, selectedFacets, sortOrder, start, useSession, }: GetAssetsRequest): Promise<GetAssetsResponse>;
|
|
40
41
|
export declare function apiGetAvailableProxies({ assetRecordId, siteUrl, }: {
|
|
41
42
|
assetRecordId: string;
|
|
42
43
|
siteUrl?: string;
|
|
@@ -57,12 +57,21 @@ export type GetAssetsRawResponse = {
|
|
|
57
57
|
contentItems?: ContentItem[];
|
|
58
58
|
facets: Facet[];
|
|
59
59
|
totalCount: number;
|
|
60
|
+
/** Absent on a Cortex build older than L-42BJ3T. */
|
|
61
|
+
unreadableFields?: string[];
|
|
60
62
|
};
|
|
61
63
|
export type GetAssetsResponse = {
|
|
62
64
|
facets: Facet[];
|
|
63
65
|
isError: boolean;
|
|
64
66
|
items: Array<Asset & Record<string, string | boolean>>;
|
|
65
67
|
totalCount: number;
|
|
68
|
+
/**
|
|
69
|
+
* The requested fields, spelled as sent, that the user cannot read on this page of records. Cortex
|
|
70
|
+
* still sends each one on every item, with an empty value, except a field that the
|
|
71
|
+
* `DbBOFieldSecurity_BO.Data.ObjectsInfoRetriever_IgnoredFields` parameter lists, which keeps its
|
|
72
|
+
* value. Empty when Cortex flags none, or when Cortex is too old to flag any.
|
|
73
|
+
*/
|
|
74
|
+
unreadableFields: string[];
|
|
66
75
|
};
|
|
67
76
|
export type GetAvailableProxiesRequest = {
|
|
68
77
|
assetRecordId: string;
|
|
@@ -6,7 +6,8 @@ import CxContentBrowserFormatDialog from '../../components/content-browser-forma
|
|
|
6
6
|
import CxContentBrowserGrid from '../../components/content-browser-grid/content-browser-grid';
|
|
7
7
|
import CxContentBrowserHeader from '../../components/content-browser-header/content-browser-header';
|
|
8
8
|
import CxContentBrowserNoResult from '../../components/content-browser-no-result/content-browser-no-result';
|
|
9
|
-
import
|
|
9
|
+
import CxContentBrowserTable from '../../components/content-browser-table/content-browser-table';
|
|
10
|
+
import { type AutoSelectFormat, type ContentBrowserView, type CtaTextTransform, type TableColumn, type TableRowActionPosition } from '../../types/content-browser';
|
|
10
11
|
import { GetFolderRequest } from '../../types/folder';
|
|
11
12
|
import CxIcon from '@orangelogic/design-system/components/icon';
|
|
12
13
|
import CxIconButton from '@orangelogic/design-system/components/icon-button';
|
|
@@ -18,6 +19,7 @@ export declare const COMPUTED_FIELDS: string[];
|
|
|
18
19
|
* @summary CxContentBrowser
|
|
19
20
|
*/
|
|
20
21
|
export default class CxContentBrowser extends CortexElement {
|
|
22
|
+
#private;
|
|
21
23
|
static readonly styles: CSSResultGroup;
|
|
22
24
|
static readonly dependencies: {
|
|
23
25
|
'cx-content-browser-browser': typeof CxContentBrowserBrowser;
|
|
@@ -26,6 +28,7 @@ export default class CxContentBrowser extends CortexElement {
|
|
|
26
28
|
'cx-content-browser-grid': typeof CxContentBrowserGrid;
|
|
27
29
|
'cx-content-browser-header': typeof CxContentBrowserHeader;
|
|
28
30
|
'cx-content-browser-no-result': typeof CxContentBrowserNoResult;
|
|
31
|
+
'cx-content-browser-table': typeof CxContentBrowserTable;
|
|
29
32
|
'cx-icon': typeof CxIcon;
|
|
30
33
|
'cx-icon-button': typeof CxIconButton;
|
|
31
34
|
'cx-resize-observer': typeof CxResizeObserver;
|
|
@@ -61,6 +64,10 @@ export default class CxContentBrowser extends CortexElement {
|
|
|
61
64
|
*/
|
|
62
65
|
canPinAsset: boolean;
|
|
63
66
|
canUseProxies: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Host-level import behaviour; forwarded to the format dialog. See `AutoSelectFormat`.
|
|
69
|
+
*/
|
|
70
|
+
autoSelectFormat: AutoSelectFormat;
|
|
64
71
|
/**
|
|
65
72
|
* Pick-only mode: no available-proxies lookup, no transformation on confirm. The preview popup
|
|
66
73
|
* shows the asset's LargeSizePreview and confirming emits the asset straight to the host.
|
|
@@ -73,7 +80,29 @@ export default class CxContentBrowser extends CortexElement {
|
|
|
73
80
|
ctaText: string;
|
|
74
81
|
ctaTextTransform: CtaTextTransform;
|
|
75
82
|
extraFields: string[];
|
|
76
|
-
defaultGridView:
|
|
83
|
+
defaultGridView: ContentBrowserView;
|
|
84
|
+
/**
|
|
85
|
+
* Columns of the table view, defined by the host: a title and the Cortex field the column reads.
|
|
86
|
+
* The table fits each column to its content, and the user resizes it. The table view is offered only while this is non-empty — an empty table is not a
|
|
87
|
+
* view mode — and the fields are read once, when the fetch controller is created.
|
|
88
|
+
*/
|
|
89
|
+
tableColumns: TableColumn[];
|
|
90
|
+
/**
|
|
91
|
+
* Where the row action of the table view shows: at the right edge of the host (`host-edge`), or at
|
|
92
|
+
* the end of the last data column (`row-end`). Any other value gives `host-edge`.
|
|
93
|
+
*/
|
|
94
|
+
tableRowActionPosition: TableRowActionPosition;
|
|
95
|
+
/** The widths the user saved for the table columns of this site, in pixels, keyed by field. */
|
|
96
|
+
private tableColumnWidths;
|
|
97
|
+
/**
|
|
98
|
+
* The reads and writes of the saved widths, one after the other: each write reads the stored map
|
|
99
|
+
* and writes it back, and a read that runs before a write would give the table a stale map.
|
|
100
|
+
*/
|
|
101
|
+
private tableWidthQueue;
|
|
102
|
+
/** The number of reads and writes queued on `tableWidthQueue`. Only the last one gives its map to the table. */
|
|
103
|
+
private tableWidthTasks;
|
|
104
|
+
/** Set by a drag or a reset that the table shows, until a map from the storage replaces it. */
|
|
105
|
+
private tableWidthsChangedInTable;
|
|
77
106
|
defaultSortOrderName: string;
|
|
78
107
|
defaultSortDirection: 'ascending' | 'descending';
|
|
79
108
|
defaultSelectedFacets: Record<string, string[]>;
|
|
@@ -109,6 +138,35 @@ export default class CxContentBrowser extends CortexElement {
|
|
|
109
138
|
private initialFolderPending;
|
|
110
139
|
private initialFolderTimeout;
|
|
111
140
|
willUpdate(changedProperties: PropertyValues): void;
|
|
141
|
+
/**
|
|
142
|
+
* Never trust the host's value: it also arrives by direct property assignment, past the converter.
|
|
143
|
+
* Entries are checked one by one, not just the outer array — `field` is dereferenced while the
|
|
144
|
+
* fetch controller is being built, where a throw leaves the controller unassigned and the picker
|
|
145
|
+
* blank. `title` is only rendered, and Lit renders a nullish one as nothing, so a column is not
|
|
146
|
+
* worth dropping over it.
|
|
147
|
+
*/
|
|
148
|
+
private get tableColumnList();
|
|
149
|
+
/**
|
|
150
|
+
* This reads the configured columns, not the shown ones. The shown columns can change with each
|
|
151
|
+
* response, and a table view that goes away with them flips the view and its page size. When
|
|
152
|
+
* Cortex flags each column, the rows stay with only the filler and the CTA column.
|
|
153
|
+
*/
|
|
154
|
+
private get canUseTable();
|
|
155
|
+
/**
|
|
156
|
+
* Runs a read or a write of the saved widths after the ones queued before it. The table gets the
|
|
157
|
+
* map of the last task only: an earlier map does not hold the drags and resets that came after it,
|
|
158
|
+
* and the table already shows them. A map for a site that is no longer the current one is dropped.
|
|
159
|
+
*/
|
|
160
|
+
private queueTableWidthTask;
|
|
161
|
+
/**
|
|
162
|
+
* A map with the same entries keeps the old one, so that the table does not lay out its columns
|
|
163
|
+
* again. After a drag or a reset the table can show widths that the old map does not hold, so the
|
|
164
|
+
* new map always replaces them.
|
|
165
|
+
*/
|
|
166
|
+
private setTableColumnWidths;
|
|
167
|
+
private loadTableColumnWidths;
|
|
168
|
+
handleBaseUrlChangeForTableWidths(): void;
|
|
169
|
+
private handleTableColumnResize;
|
|
112
170
|
runFirstUpdated(): void;
|
|
113
171
|
connectedCallback(): void;
|
|
114
172
|
disconnectedCallback(): void;
|
|
@@ -120,8 +178,20 @@ export default class CxContentBrowser extends CortexElement {
|
|
|
120
178
|
* pin/unpin request (see `cx-content-browser-pin-asset-change`) to reflect the result.
|
|
121
179
|
*/
|
|
122
180
|
setIsAssetPinned(isAssetPinned: boolean): void;
|
|
181
|
+
/**
|
|
182
|
+
* The asset a click is still working on, or undefined. The two private flags below drive the
|
|
183
|
+
* guards; this drives the UI, and is a separate field because they are plain fields rather than
|
|
184
|
+
* reactive state.
|
|
185
|
+
*
|
|
186
|
+
* Cleared the moment the format dialog actually opens: from there the dialog's own confirm button
|
|
187
|
+
* carries the pending state, and two spinners for one operation reads as two operations. It
|
|
188
|
+
* survives when no dialog opens, which is the auto-confirm path, where the CTA is the only thing
|
|
189
|
+
* the user can be told anything by.
|
|
190
|
+
*/
|
|
191
|
+
private busyAssetId;
|
|
123
192
|
private openFormatDialog;
|
|
124
193
|
handleLastRequestChange(): Promise<void>;
|
|
194
|
+
handleTableColumnsChange(): void;
|
|
125
195
|
handleAuthChange(): void;
|
|
126
196
|
handleSiteSessionChange(): void;
|
|
127
197
|
private handleSortOrderChange;
|
|
@@ -144,6 +214,7 @@ export default class CxContentBrowser extends CortexElement {
|
|
|
144
214
|
*/
|
|
145
215
|
private handlePinAssetChange;
|
|
146
216
|
private handleProxyConfirm;
|
|
217
|
+
private reportProxyConfirmFailure;
|
|
147
218
|
private handleFormatConfirm;
|
|
148
219
|
private handleFormatDialogClose;
|
|
149
220
|
private handleSelectedAsset;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CSSResultGroup } from 'lit';
|
|
2
2
|
import CortexElement from '../../base/element';
|
|
3
3
|
import { MediaType } from '../../types/asset';
|
|
4
|
-
import { GridView } from '../../types/content-browser';
|
|
4
|
+
import { type CtaTextTransform, GridView } from '../../types/content-browser';
|
|
5
5
|
import CxArrayLineClamp from '@orangelogic/design-system/components/array-line-clamp';
|
|
6
|
+
import CxButton from '@orangelogic/design-system/components/button';
|
|
6
7
|
import CxCard from '@orangelogic/design-system/components/card';
|
|
7
8
|
import CxCheckbox from '@orangelogic/design-system/components/checkbox';
|
|
8
9
|
import CxLineClamp from '@orangelogic/design-system/components/line-clamp';
|
|
@@ -10,10 +11,19 @@ import CxSpace from '@orangelogic/design-system/components/space';
|
|
|
10
11
|
import CxTag from '@orangelogic/design-system/components/tag';
|
|
11
12
|
import CxTypography from '@orangelogic/design-system/components/typography';
|
|
12
13
|
import CxContentBrowserAssetPreview from '../content-browser-asset-preview/content-browser-asset-preview';
|
|
14
|
+
/**
|
|
15
|
+
* Grid view is pointer-only by design: the card is not focusable, and its CTA overlay is
|
|
16
|
+
* `aria-hidden` with a `tabindex="-1"` button because the overlay only restates what clicking the
|
|
17
|
+
* card already does. This diverges deliberately from `cx-content-browser-table`, whose rows are
|
|
18
|
+
* focusable and announce their CTA — the grid's keyboard gap predates the table view and closing it
|
|
19
|
+
* would change focus and screen-reader behaviour for every existing host. Revisit together with the
|
|
20
|
+
* grid's own keyboard support rather than per-feature.
|
|
21
|
+
*/
|
|
13
22
|
export default class CxContentBrowserAssetCard extends CortexElement {
|
|
14
23
|
static readonly styles: CSSResultGroup;
|
|
15
24
|
static readonly dependencies: {
|
|
16
25
|
'cx-array-line-clamp': typeof CxArrayLineClamp;
|
|
26
|
+
'cx-button': typeof CxButton;
|
|
17
27
|
'cx-card': typeof CxCard;
|
|
18
28
|
'cx-checkbox': typeof CxCheckbox;
|
|
19
29
|
'cx-content-browser-asset-preview': typeof CxContentBrowserAssetPreview;
|
|
@@ -22,6 +32,20 @@ export default class CxContentBrowserAssetCard extends CortexElement {
|
|
|
22
32
|
'cx-tag': typeof CxTag;
|
|
23
33
|
'cx-typography': typeof CxTypography;
|
|
24
34
|
};
|
|
35
|
+
private readonly localize;
|
|
36
|
+
/**
|
|
37
|
+
* Show the hover overlay that says clicking this card inserts. Set when the host has asked to
|
|
38
|
+
* skip the format picker: without the dialog a click hands the asset over immediately, and the
|
|
39
|
+
* card would otherwise carry no sign of that.
|
|
40
|
+
*/
|
|
41
|
+
showCta: boolean;
|
|
42
|
+
ctaText: string;
|
|
43
|
+
ctaTextTransform: CtaTextTransform;
|
|
44
|
+
/**
|
|
45
|
+
* This card's insert is still running: hold the overlay open and spin its CTA, so the feedback
|
|
46
|
+
* does not vanish the moment the pointer leaves.
|
|
47
|
+
*/
|
|
48
|
+
busy: boolean;
|
|
25
49
|
imageUrl: string;
|
|
26
50
|
originalUrl: string;
|
|
27
51
|
scrubUrl: string;
|
|
@@ -10,7 +10,7 @@ import CxSpace from '@orangelogic/design-system/components/space';
|
|
|
10
10
|
import CxSwitch from '@orangelogic/design-system/components/switch';
|
|
11
11
|
import CxTooltip from '@orangelogic/design-system/components/tooltip';
|
|
12
12
|
import CortexElement from '../../base/element';
|
|
13
|
-
import {
|
|
13
|
+
import { type ContentBrowserView, ControlOption } from '../../types/content-browser';
|
|
14
14
|
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
15
15
|
/**
|
|
16
16
|
* @summary DAM view control toolbar for selecting asset view modes and toggling options.
|
|
@@ -41,14 +41,17 @@ export default class CxContentBrowserControlView extends CortexElement {
|
|
|
41
41
|
'cx-tooltip': typeof CxTooltip;
|
|
42
42
|
};
|
|
43
43
|
private readonly localize;
|
|
44
|
-
view:
|
|
44
|
+
view: ContentBrowserView;
|
|
45
45
|
views: ControlOption[];
|
|
46
46
|
isSeeThrough: boolean;
|
|
47
47
|
isMobile: boolean;
|
|
48
|
+
canUseTable: boolean;
|
|
48
49
|
private selectedView;
|
|
50
|
+
private get isTable();
|
|
49
51
|
runConnectedCallback(): void;
|
|
50
52
|
private handleSeeThroughClick;
|
|
51
53
|
private handleViewSelect;
|
|
54
|
+
private renderTableOption;
|
|
52
55
|
handleViewChange(): void;
|
|
53
56
|
render(): TemplateResult;
|
|
54
57
|
}
|
|
@@ -15,7 +15,7 @@ import CxTypography from '@orangelogic/design-system/components/typography';
|
|
|
15
15
|
import CxContentBrowserAssetPreview from '../content-browser-asset-preview/content-browser-asset-preview';
|
|
16
16
|
import CxContentBrowserAssetProxySelector from '../content-browser-asset-proxy-selector/content-browser-asset-proxy-selector';
|
|
17
17
|
import CxContentBrowserAssetVersionHistory from '../content-browser-asset-version-history/content-browser-asset-version-history';
|
|
18
|
-
import { type Parameter, type Transformation, type CtaTextTransform, ContentBrowserFormatDialogVariant } from '../../types/content-browser';
|
|
18
|
+
import { type Parameter, type Transformation, type CtaTextTransform, type AutoSelectFormat, ContentBrowserFormatDialogVariant } from '../../types/content-browser';
|
|
19
19
|
export default class CxContentBrowserFormatDialog extends CortexElement {
|
|
20
20
|
static readonly styles: CSSResultGroup;
|
|
21
21
|
static readonly dependencies: {
|
|
@@ -47,6 +47,12 @@ export default class CxContentBrowserFormatDialog extends CortexElement {
|
|
|
47
47
|
canPinAsset: boolean;
|
|
48
48
|
canTrack: boolean;
|
|
49
49
|
canUseProxies: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Skip the format picker and insert directly — see `resolveAutoSelection` for what each value
|
|
52
|
+
* does. Off by default: this changes what a click does, so a host opts in rather than
|
|
53
|
+
* inheriting it.
|
|
54
|
+
*/
|
|
55
|
+
autoSelectFormat: AutoSelectFormat;
|
|
50
56
|
/**
|
|
51
57
|
* Pick-only mode. Suppresses the custom-format editor entirely: cx-asset-link-format issues its
|
|
52
58
|
* own transformasset request as soon as it is in the DOM, so hiding it with CSS is not enough.
|
|
@@ -97,7 +103,19 @@ export default class CxContentBrowserFormatDialog extends CortexElement {
|
|
|
97
103
|
* One rule for the Insert button and handleProxyConfirm, so an enabled Insert always confirms (L-42BIA4).
|
|
98
104
|
*/
|
|
99
105
|
private get canConfirm();
|
|
106
|
+
private filterProxies;
|
|
100
107
|
handleSupportedExtensionsChange(): void;
|
|
108
|
+
/**
|
|
109
|
+
* What `autoSelectFormat` resolves to for this asset: the proxy to insert with, or `undefined`
|
|
110
|
+
* when the dialog should open as usual.
|
|
111
|
+
*
|
|
112
|
+
* `{ proxy: undefined }` is deliberate rather than a miss — with the picker switched off there is
|
|
113
|
+
* no format to name and the original file is the only outcome, which is `handleProxyConfirm`'s
|
|
114
|
+
* no-proxy branch. With the picker on a proxy must actually resolve: confirming none emits
|
|
115
|
+
* nothing and would turn the click into a silent no-op, so both an empty proxy list and a format
|
|
116
|
+
* name that matches nothing fall back to the dialog.
|
|
117
|
+
*/
|
|
118
|
+
private resolveAutoSelection;
|
|
101
119
|
open({ asset, isFavorite, isAssetPinned, proxies, proxiesFailed, }: {
|
|
102
120
|
asset: Asset & {
|
|
103
121
|
previewUrl: string;
|
|
@@ -108,6 +126,14 @@ export default class CxContentBrowserFormatDialog extends CortexElement {
|
|
|
108
126
|
proxiesFailed?: boolean;
|
|
109
127
|
}): void;
|
|
110
128
|
hide(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Show a dialog that `open()` skipped through the auto-confirm shortcut. The asset, proxies and
|
|
131
|
+
* resolved selection are still in place, so this lands the user on exactly the dialog the
|
|
132
|
+
* shortcut spared them, with its confirm button live again to retry.
|
|
133
|
+
*/
|
|
134
|
+
revealAfterAutoConfirm(): void;
|
|
135
|
+
/** Whether the dialog is actually on screen — false when `open()` took the auto-confirm path. */
|
|
136
|
+
get isDialogOpen(): boolean;
|
|
111
137
|
setVersionHistory(versions: AssetVersion[]): void;
|
|
112
138
|
setIsFavorite(isFavorite: boolean): void;
|
|
113
139
|
setIsAssetPinned(isAssetPinned: boolean): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '@lit-labs/virtualizer';
|
|
2
2
|
import CortexElement from '../../base/element';
|
|
3
3
|
import { Asset } from '../../types/asset';
|
|
4
|
-
import { GridView } from '../../types/content-browser';
|
|
4
|
+
import { GridView, type CtaTextTransform } from '../../types/content-browser';
|
|
5
5
|
import CxButton from '@orangelogic/design-system/components/button';
|
|
6
6
|
import CxIcon from '@orangelogic/design-system/components/icon';
|
|
7
7
|
import CxProgressBar from '@orangelogic/design-system/components/progress-bar';
|
|
@@ -34,6 +34,10 @@ export default class CxContentBrowserGrid extends CortexElement {
|
|
|
34
34
|
showSize: boolean;
|
|
35
35
|
showDimensions: boolean;
|
|
36
36
|
showTags: boolean;
|
|
37
|
+
showCta: boolean;
|
|
38
|
+
ctaText: string;
|
|
39
|
+
ctaTextTransform: CtaTextTransform;
|
|
40
|
+
busyAssetId: string | undefined;
|
|
37
41
|
selectedAssetId: string | undefined;
|
|
38
42
|
assetMap: Map<string, Asset>;
|
|
39
43
|
columnWidth: number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** The narrowest width a table column can have, in pixels. */
|
|
2
|
+
export declare const MIN_COLUMN_WIDTH = 92;
|
|
3
|
+
/**
|
|
4
|
+
* One column for the layout rules.
|
|
5
|
+
* `natural` is the width the column wants, in pixels.
|
|
6
|
+
* `saved` is the width the user set, in pixels. Leave it out for an auto-fit column.
|
|
7
|
+
*/
|
|
8
|
+
export type ColumnLayoutInput = {
|
|
9
|
+
natural: number;
|
|
10
|
+
saved?: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Measure the width of a text with a font, in whole pixels.
|
|
14
|
+
* @param text The text to measure.
|
|
15
|
+
* @param font A CSS font value, such as `'14px sans-serif'`.
|
|
16
|
+
* @returns The width of the text, rounded up. Returns 0 when no canvas context is available.
|
|
17
|
+
*/
|
|
18
|
+
export declare function measureTextWidth(text: string, font: string): number;
|
|
19
|
+
/**
|
|
20
|
+
* Lay out the column widths inside the available width.
|
|
21
|
+
* Saved widths keep their size. Auto-fit columns that fit in a fair share keep their natural
|
|
22
|
+
* width. The other auto-fit columns share the space that is left. Spare space goes to the
|
|
23
|
+
* auto-fit columns in equal parts. No column is narrower than MIN_COLUMN_WIDTH, so the result can
|
|
24
|
+
* be wider than `available`.
|
|
25
|
+
* @param columns The columns, in display order.
|
|
26
|
+
* @param available The width of the host, in pixels.
|
|
27
|
+
* @returns One whole-pixel width for each column, in the same order.
|
|
28
|
+
*/
|
|
29
|
+
export declare function layoutColumnWidths(columns: ColumnLayoutInput[], available: number): number[];
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { type PropertyValues } from 'lit';
|
|
2
|
+
import CortexElement from '../../base/element';
|
|
3
|
+
import { Asset } from '../../types/asset';
|
|
4
|
+
import { type CtaTextTransform, TableColumn, type TableRowActionPosition } from '../../types/content-browser';
|
|
5
|
+
import CxButton from '@orangelogic/design-system/components/button';
|
|
6
|
+
import CxIcon from '@orangelogic/design-system/components/icon';
|
|
7
|
+
import CxLineClamp from '@orangelogic/design-system/components/line-clamp';
|
|
8
|
+
import CxProgressBar from '@orangelogic/design-system/components/progress-bar';
|
|
9
|
+
import CxResizeObserver from '@orangelogic/design-system/components/resize-observer';
|
|
10
|
+
import CxContentBrowserNoResult from '../content-browser-no-result/content-browser-no-result';
|
|
11
|
+
import { MIN_COLUMN_WIDTH } from './column-layout';
|
|
12
|
+
import type { CSSResultGroup } from 'lit';
|
|
13
|
+
/** `cx-table`'s own row height, the one every other Cortex table renders at. */
|
|
14
|
+
export declare const ROW_HEIGHT = 48;
|
|
15
|
+
/** Kept here too, so the old import path of the column floor stays valid. */
|
|
16
|
+
export { MIN_COLUMN_WIDTH };
|
|
17
|
+
/** An invisible column keeps Tabulator rows present when every data column is hidden. */
|
|
18
|
+
export declare const FILLER_FIELD = "filler";
|
|
19
|
+
/**
|
|
20
|
+
* Column values ride on the asset under the Cortex field name as requested (see `apiGetAssets`),
|
|
21
|
+
* which `Asset` cannot declare because the field set is the host's, not the SDK's. Read as an own
|
|
22
|
+
* property: a field named after an `Object.prototype` member (`toString`, `constructor`) would
|
|
23
|
+
* otherwise read back the inherited function.
|
|
24
|
+
*/
|
|
25
|
+
export declare function readCellValue(asset: Asset, field: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* @summary Table layout for the Content Browser: one row per asset, host-configured metadata columns
|
|
28
|
+
* instead of a thumbnail, rendered by the design system's `cx-table`.
|
|
29
|
+
*
|
|
30
|
+
* @description Renders the same asset list the grid does and emits the same item events, so an asset
|
|
31
|
+
* with no rendition — a text fragment, `digitized = 0` — is browsable and selectable by its
|
|
32
|
+
* identifying fields. It fetches nothing of its own: a row exists, and a cell has a value, only
|
|
33
|
+
* because the search response the grid also consumes carried it.
|
|
34
|
+
*
|
|
35
|
+
* @event cx-content-browser-grid-click - Emitted when a row's CTA button is activated, by a click or
|
|
36
|
+
* from the keyboard: once for a double click on it, and never for a click or a double click on the
|
|
37
|
+
* row itself.
|
|
38
|
+
* @event cx-content-browser-grid-resize - Emitted when the number of rows the visible scrollport can
|
|
39
|
+
* show changes, and again once a restarted list's rows are in, so the host can grow the page size.
|
|
40
|
+
* A count measured while a page of the shown list loads is emitted once the load ends and any
|
|
41
|
+
* rows it brings are in. A count measured after the load ends is emitted at once, and it can come
|
|
42
|
+
* before the rows of a new list are in.
|
|
43
|
+
* @event cx-content-browser-grid-retry - Emitted when the user clicks Retry after a search error.
|
|
44
|
+
* @event cx-content-browser-grid-scroll-end - Emitted while `has-more` is set, no page is loading, and
|
|
45
|
+
* the last row comes into view: by scrolling the table's own scrollport, or by scrolling the page when
|
|
46
|
+
* a table taller than the viewport holds its rows without overflowing and so never scrolls itself.
|
|
47
|
+
* @event cx-content-browser-table-column-resize - Emitted when a host-configured column settles on a
|
|
48
|
+
* new width: a drag of its divider released (`detail.reset` is `false`), or a double click on the
|
|
49
|
+
* divider that removes the saved width and auto-fits the column (`detail.reset` is `true`). The
|
|
50
|
+
* filler and the row action have no divider. `detail.width` is the column's width in whole pixels,
|
|
51
|
+
* and is never `undefined`. The SDK saves the width itself.
|
|
52
|
+
*/
|
|
53
|
+
export default class CxContentBrowserTable extends CortexElement {
|
|
54
|
+
#private;
|
|
55
|
+
static readonly styles: CSSResultGroup;
|
|
56
|
+
static readonly dependencies: {
|
|
57
|
+
'cx-button': typeof CxButton;
|
|
58
|
+
'cx-content-browser-no-result': typeof CxContentBrowserNoResult;
|
|
59
|
+
'cx-icon': typeof CxIcon;
|
|
60
|
+
'cx-line-clamp': typeof CxLineClamp;
|
|
61
|
+
'cx-progress-bar': typeof CxProgressBar;
|
|
62
|
+
'cx-resize-observer': typeof CxResizeObserver;
|
|
63
|
+
'cx-table': typeof import("node_modules/@orangelogic/design-system/library/packages/hybrid/table-core/src").default;
|
|
64
|
+
};
|
|
65
|
+
private readonly localize;
|
|
66
|
+
private readonly containerEl;
|
|
67
|
+
private readonly tableEl;
|
|
68
|
+
assets: Asset[];
|
|
69
|
+
columns: TableColumn[];
|
|
70
|
+
ctaText: string;
|
|
71
|
+
ctaTextTransform: CtaTextTransform;
|
|
72
|
+
empty: boolean;
|
|
73
|
+
/** The last search request got an error. With no rows, the error replaces the table. With rows, it shows at the bottom. */
|
|
74
|
+
error: boolean;
|
|
75
|
+
hasMore: boolean;
|
|
76
|
+
loading: boolean;
|
|
77
|
+
selectedAssetId: string | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* The asset whose insert is still running, so its row keeps the CTA on screen and spinning.
|
|
80
|
+
*/
|
|
81
|
+
busyAssetId: string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Fields of `columns`, compared exactly, whose columns the table does not show. A hidden column
|
|
84
|
+
* keeps its place, its cell values and a dragged width, so it comes back with the rows and the
|
|
85
|
+
* scroll position unchanged. The filler and the row action remain when every host column is hidden.
|
|
86
|
+
*/
|
|
87
|
+
hiddenFields: string[];
|
|
88
|
+
/**
|
|
89
|
+
* The widths that the user saved, in pixels, keyed by the trimmed `field`. A column with a saved
|
|
90
|
+
* width shows at that width. The other columns auto-fit to their content. A new map replaces the
|
|
91
|
+
* old one, the drags and resets in memory included.
|
|
92
|
+
*/
|
|
93
|
+
savedWidths: Record<string, number>;
|
|
94
|
+
/**
|
|
95
|
+
* The owner of `savedWidths`, such as the Cortex site. A new value drops the widths that a drag
|
|
96
|
+
* held for the session. A new `savedWidths` for the same owner keeps them.
|
|
97
|
+
*/
|
|
98
|
+
widthScope: string | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Where the row action shows: at the right edge of the host (`host-edge`), or at the end of the
|
|
101
|
+
* last data column (`row-end`).
|
|
102
|
+
*/
|
|
103
|
+
rowActionPosition: TableRowActionPosition;
|
|
104
|
+
assetMap: Map<string, Asset>;
|
|
105
|
+
private get tabulator();
|
|
106
|
+
/**
|
|
107
|
+
* The current Tabulator instance, built or not. Tabulator shows its header and frame as it builds,
|
|
108
|
+
* but fires `tableBuilt` only after its data-load debounce.
|
|
109
|
+
*/
|
|
110
|
+
private get buildingTabulator();
|
|
111
|
+
/** Tabulator's row holder: the one element that scrolls the rows. */
|
|
112
|
+
private get scrollport();
|
|
113
|
+
/** Each host column's row key, in order: a field the host repeats takes a key per occurrence. */
|
|
114
|
+
private resolveColumnKeys;
|
|
115
|
+
private buildColumnDefinitions;
|
|
116
|
+
/**
|
|
117
|
+
* A pixel width for each column, so the `fitData` layout never sizes it from its content. The
|
|
118
|
+
* auto-fit sets the real width once the columns are built (see `applyColumnLayout`). Until then a
|
|
119
|
+
* column keeps the width it had in the previous definitions.
|
|
120
|
+
*/
|
|
121
|
+
private buildDataColumnDefinitions;
|
|
122
|
+
/**
|
|
123
|
+
* Tabulator replaces its rows with a placeholder when no columns remain visible. This invisible
|
|
124
|
+
* column keeps the rows and their actions available when the host hides every data column.
|
|
125
|
+
* Its small, fixed width gives the final resize handle a buffer without a visible empty column.
|
|
126
|
+
*/
|
|
127
|
+
private buildFillerColumnDefinition;
|
|
128
|
+
private get ctaLabel();
|
|
129
|
+
/** The action overlays its row and takes no column width. */
|
|
130
|
+
private renderRowAction;
|
|
131
|
+
private isCtaShown;
|
|
132
|
+
/** In place, never rebuilt: a new button would drop the keyboard focus the old one held. */
|
|
133
|
+
private paintCta;
|
|
134
|
+
private paintRowCta;
|
|
135
|
+
private paintAssetCta;
|
|
136
|
+
private trackPointer;
|
|
137
|
+
private setHoveredRow;
|
|
138
|
+
/**
|
|
139
|
+
* Tabulator takes a row that scrolls out of its render window off the page, and a row taken off
|
|
140
|
+
* the page gets no `mouseleave` to hide its CTA, nor need its button get a `focusout` for the
|
|
141
|
+
* focus it drops.
|
|
142
|
+
*/
|
|
143
|
+
private releaseDetachedCta;
|
|
144
|
+
/** Lays the columns and the rendered rows out again. */
|
|
145
|
+
private redrawTable;
|
|
146
|
+
/** The frame ends at the data columns. The scrollport remains available to the row actions. */
|
|
147
|
+
private syncTableFrame;
|
|
148
|
+
/**
|
|
149
|
+
* Tabulator renders the rows again -- for an appended page, a redraw of its own or one of ours --
|
|
150
|
+
* by taking every rendered row off the page and back, which drops the keyboard focus, so the CTA
|
|
151
|
+
* that held it gets it back.
|
|
152
|
+
*/
|
|
153
|
+
private handleRenderStarted;
|
|
154
|
+
private handleRenderComplete;
|
|
155
|
+
private toRow;
|
|
156
|
+
private findRow;
|
|
157
|
+
/**
|
|
158
|
+
* `aria-current`, not `aria-selected`: this is a `grid` with no selection model of its own. The
|
|
159
|
+
* row is never selected in Tabulator, so an import does not paint `cx-table`'s selected-row highlight.
|
|
160
|
+
*/
|
|
161
|
+
private markCurrentRow;
|
|
162
|
+
/**
|
|
163
|
+
* The fonts and the padding of a rendered header title and data cell. A table with no rendered
|
|
164
|
+
* cell measures the values in the header font, with the header padding.
|
|
165
|
+
*/
|
|
166
|
+
private readColumnMetrics;
|
|
167
|
+
private getScrollbarWidth;
|
|
168
|
+
/** The widest of the title and the values of the loaded rows, plus the padding. */
|
|
169
|
+
private measureNaturalWidth;
|
|
170
|
+
/**
|
|
171
|
+
* Sets the width of each visible host column: a saved or session width as is, and an auto-fit
|
|
172
|
+
* width for the other columns, inside the width of the table (see `layoutColumnWidths`). A hidden
|
|
173
|
+
* column keeps its width. A table with no width, as one in a hidden panel, keeps its widths until
|
|
174
|
+
* it is shown.
|
|
175
|
+
* @param measure Measure the natural widths again. Leave it false to reuse the natural widths of
|
|
176
|
+
* the last full layout, for a change of the available width only.
|
|
177
|
+
*/
|
|
178
|
+
private applyColumnLayout;
|
|
179
|
+
/**
|
|
180
|
+
* The canvas measures with a fallback font while a web font loads, so measure again once the fonts
|
|
181
|
+
* are ready. Guarded by one pending wait, and by the connection of the element.
|
|
182
|
+
*/
|
|
183
|
+
private layoutAgainWhenFontsLoad;
|
|
184
|
+
private readonly debouncedApplyColumnLayout;
|
|
185
|
+
/**
|
|
186
|
+
* `content-browser` hands over the whole list on every page, so a list that only grows by a page
|
|
187
|
+
* is appended: reassigning it would call `setData`, which scrolls the table back to the top. Any
|
|
188
|
+
* other list -- a new search, sort, filter or folder, or a refetch that brings the assets the rows
|
|
189
|
+
* show as new objects -- replaces the rows.
|
|
190
|
+
*/
|
|
191
|
+
private syncRows;
|
|
192
|
+
private handleTableBuilt;
|
|
193
|
+
/**
|
|
194
|
+
* Gives the frame, the scrollport and the header their styles. Runs as soon as Tabulator lays out its
|
|
195
|
+
* columns: until then the frame takes the width of its content, which is not the width of the header.
|
|
196
|
+
*/
|
|
197
|
+
private prepareFrame;
|
|
198
|
+
/**
|
|
199
|
+
* `setData` replaces the rows only once its debounce runs out, and Tabulator emits `dataLoaded` just
|
|
200
|
+
* before it does. Until then, the old rows stay on the page with their hover and focus.
|
|
201
|
+
*/
|
|
202
|
+
private handleDataLoaded;
|
|
203
|
+
/**
|
|
204
|
+
* Every `setColumns` builds the columns again from the definitions: Tabulator calls it as it builds,
|
|
205
|
+
* before `tableBuilt`. `cx-table` calls it again from its own `tableBuilt` handler, after this
|
|
206
|
+
* component's has run, and for every new column set.
|
|
207
|
+
*/
|
|
208
|
+
private handleColumnsLoaded;
|
|
209
|
+
willUpdate(changedProperties: PropertyValues<this>): void;
|
|
210
|
+
/**
|
|
211
|
+
* The new saved widths replace all the widths in memory: a width that the new map does not hold,
|
|
212
|
+
* for example one of another site, goes away. Only a positive width counts: a bad entry has no effect.
|
|
213
|
+
*/
|
|
214
|
+
private applySavedWidths;
|
|
215
|
+
/**
|
|
216
|
+
* Through Tabulator's own column visibility: new definitions would reach it through `setColumns`,
|
|
217
|
+
* and the rows would have to be rebuilt, which scrolls back to the top.
|
|
218
|
+
*/
|
|
219
|
+
private applyHiddenFields;
|
|
220
|
+
updated(changedProperties: PropertyValues<this>): void;
|
|
221
|
+
/** Once `cx-table` has taken the new column definitions. */
|
|
222
|
+
private rebuildRows;
|
|
223
|
+
handleAssetsChange(previous?: unknown): void;
|
|
224
|
+
handleLoadingChange(): Promise<void>;
|
|
225
|
+
handleSelectedAssetIdChange(previous?: unknown): void;
|
|
226
|
+
handleBusyAssetIdChange(previous?: unknown): void;
|
|
227
|
+
handleCtaTextChange(): void;
|
|
228
|
+
private readonly handleNoHoverChange;
|
|
229
|
+
/** In place, as a relabel is: a CTA built again would drop the keyboard focus the old one held. */
|
|
230
|
+
private setNoHover;
|
|
231
|
+
connectedCallback(): void;
|
|
232
|
+
disconnectedCallback(): void;
|
|
233
|
+
private handleResize;
|
|
234
|
+
/**
|
|
235
|
+
* A new container width changes the space that the auto-fit shares out, so the columns are laid
|
|
236
|
+
* out again. `cx-table` renders its rows again for a new container height only until the first drag
|
|
237
|
+
* of a column divider, so a new height redraws the rows, which leaves no blank area under them.
|
|
238
|
+
*/
|
|
239
|
+
private refitToContainer;
|
|
240
|
+
private readonly debouncedRedrawTable;
|
|
241
|
+
private readonly debouncedCalculatePageSize;
|
|
242
|
+
private calculatePageSize;
|
|
243
|
+
/** Counts the rows the last measured height shows, and tells the host when the count changes. */
|
|
244
|
+
private reportRowCount;
|
|
245
|
+
/**
|
|
246
|
+
* Only once the restarted rows are in: the host asks for the next page at once, and a page that
|
|
247
|
+
* lands while `setData` waits replaces the rows again and holds them back for another half second.
|
|
248
|
+
* A measurement still in its debounce reports in the same count, because a second count inside the
|
|
249
|
+
* host's 200 ms fetch debounce cancels the page the first count asked for.
|
|
250
|
+
*/
|
|
251
|
+
private reportRestartedRowCount;
|
|
252
|
+
/**
|
|
253
|
+
* Once the load ends and any rows it brings are in, the count measured meanwhile can ask for the
|
|
254
|
+
* page after it. A table that is not built yet reports it at once.
|
|
255
|
+
*/
|
|
256
|
+
private reportHeldRowCount;
|
|
257
|
+
/**
|
|
258
|
+
* The rows never size the container (see the styles), so this is the height the host gives the
|
|
259
|
+
* picker, and it can run past the viewport. No scrollport shows more rows than the viewport, so
|
|
260
|
+
* while the rows do not overflow the scrollport the count stops there, and the page scrolls to the
|
|
261
|
+
* rest, where the last row coming into view asks for more (`observeLastRow`). One that overflows,
|
|
262
|
+
* or holds no rows yet, measures the space its container gives it and is used as is.
|
|
263
|
+
*/
|
|
264
|
+
private resolveVisibleHeight;
|
|
265
|
+
private isSizedByRows;
|
|
266
|
+
/**
|
|
267
|
+
* A scrollport that holds its rows without overflowing never scrolls, so its own scroll never
|
|
268
|
+
* reaches the end: the page scrolls instead. Once the table is taller than the viewport its count
|
|
269
|
+
* is capped and stops fetching, which leaves the last row coming into view as the only sign the
|
|
270
|
+
* user wants more.
|
|
271
|
+
*/
|
|
272
|
+
private observeLastRow;
|
|
273
|
+
private readonly debouncedHandleLastRowVisible;
|
|
274
|
+
private handleLastRowVisible;
|
|
275
|
+
private insertAsset;
|
|
276
|
+
/** The host field of a row key, or `undefined` for the filler. */
|
|
277
|
+
private fieldOfKey;
|
|
278
|
+
private handleColumnResized;
|
|
279
|
+
/**
|
|
280
|
+
* Holds each other visible auto-fit column at its width when the drag ends, for the session. A drag
|
|
281
|
+
* on one column must not change the width of another column (L-42CA9K issue 2).
|
|
282
|
+
*/
|
|
283
|
+
private holdOtherAutoFitWidths;
|
|
284
|
+
/**
|
|
285
|
+
* A double click on a column divider removes the saved width, and the column auto-fits again. The
|
|
286
|
+
* listener runs in the capture phase, before the listener of the divider, so the Tabulator fit to
|
|
287
|
+
* the content does not run.
|
|
288
|
+
*/
|
|
289
|
+
private readonly handleResizeHandleDoubleClick;
|
|
290
|
+
private handleScrollVertical;
|
|
291
|
+
private readonly debouncedHandleScrollEnd;
|
|
292
|
+
private handleScrollEnd;
|
|
293
|
+
private handleRetry;
|
|
294
|
+
private renderRetry;
|
|
295
|
+
private renderContent;
|
|
296
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
297
|
+
}
|
|
298
|
+
declare global {
|
|
299
|
+
interface HTMLElementTagNameMap {
|
|
300
|
+
'cx-content-browser-table': CxContentBrowserTable;
|
|
301
|
+
}
|
|
302
|
+
}
|