@fluid-topics/ft-reader-context 2.2.16 → 2.2.18

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.
@@ -3,7 +3,7 @@ import { ClusteringHelper, Optional } from "@fluid-topics/ft-wc-utils";
3
3
  import { FtReaderReduxStore } from "./redux";
4
4
  import type { FtReaderService } from "./utils/FtReaderService";
5
5
  import { FtAnalyticsEventsService } from "@fluid-topics/ft-app-context";
6
- import { FtTranslationLocale, FtTranslationSettings } from "@fluid-topics/public-api";
6
+ import { FtMetadataFilter, FtTranslationLocale, FtTranslationSettings } from "@fluid-topics/public-api";
7
7
  export declare class FtReaderStateManager {
8
8
  store: FtReaderReduxStore;
9
9
  private clusteringHelperProvider?;
@@ -20,8 +20,10 @@ export declare class FtReaderStateManager {
20
20
  setMapId(mapId?: string): Promise<void>;
21
21
  setRenderedTopics(tocIds: string[]): void;
22
22
  setVisibleTopics(tocIds: string[]): void;
23
+ setFilters(filters: FtMetadataFilter[]): Promise<void>;
23
24
  awaitService(): Promise<FtReaderService>;
24
25
  navigateToTopic(tocId?: string, section?: string, pageNumber?: number): Promise<void>;
26
+ private resolvePage;
25
27
  private resolveValidNonRootTocId;
26
28
  navigateToPage(pageNumber: number): Promise<void>;
27
29
  scrollDone(): void;
@@ -29,6 +31,9 @@ export declare class FtReaderStateManager {
29
31
  load(): Promise<void>;
30
32
  clear(): void;
31
33
  reload(): Promise<void>;
34
+ clearFromFilter(): void;
35
+ reloadFromFilter(section?: string, page?: number): Promise<void>;
36
+ private fetchDataFromFilter;
32
37
  private fetchData;
33
38
  private loadConfiguration;
34
39
  reloadConfiguration(): Promise<{
@@ -1,5 +1,5 @@
1
- import { FtReaderStoreEvents, } from "./model";
2
- import { accessResultUrl, CanceledPromiseError, ClusteringHelper, Debouncer, waitFor, waitUntil, } from "@fluid-topics/ft-wc-utils";
1
+ import { FtReaderStoreEvents, FtRequestedTopicFilteredEvent, } from "./model";
2
+ import { accessResultUrl, CanceledPromiseError, ClusteringHelper, Debouncer, deepEqual, waitFor, waitUntil, } from "@fluid-topics/ft-wc-utils";
3
3
  import { createReaderStore, } from "./redux";
4
4
  import { FtOfficialReaderService } from "./utils/FtOfficialReaderService";
5
5
  import { FtAnalyticsEventsService, ftAppInfoStore, } from "@fluid-topics/ft-app-context";
@@ -23,7 +23,9 @@ export class FtReaderStateManager {
23
23
  }
24
24
  async initService(serviceProvider) {
25
25
  this.service = await serviceProvider();
26
- this.service.mapId = this.store.getState().mapId;
26
+ const { mapId, metadataFilters } = this.store.getState();
27
+ this.service.mapId = mapId;
28
+ this.service.metadataFilters = metadataFilters;
27
29
  return this.reload();
28
30
  }
29
31
  async setMapId(mapId) {
@@ -41,15 +43,20 @@ export class FtReaderStateManager {
41
43
  setVisibleTopics(tocIds) {
42
44
  this.store.actions.visibleTopics(tocIds);
43
45
  }
46
+ async setFilters(filters) {
47
+ if (!deepEqual(filters, this.store.getState().metadataFilters)) {
48
+ this.store.actions.metadataFilters(filters);
49
+ if (this.service) {
50
+ this.service.metadataFilters = filters;
51
+ }
52
+ }
53
+ }
44
54
  async awaitService() {
45
55
  return waitFor(() => this.service);
46
56
  }
47
57
  async navigateToTopic(tocId, section, pageNumber) {
48
58
  await this.loaded();
49
- const service = await this.awaitService();
50
- const page = await (pageNumber != null
51
- ? service.getPage(pageNumber, this.getTranslationSettings())
52
- : service.getPageByTocId(tocId !== null && tocId !== void 0 ? tocId : "root", this.getTranslationSettings()));
59
+ const page = await this.resolvePage(tocId, pageNumber);
53
60
  this.store.actions.currentPage(page);
54
61
  const nonRootTocId = this.resolveValidNonRootTocId(tocId, page);
55
62
  this.store.actions.scrollTarget({ tocId: nonRootTocId, section });
@@ -62,16 +69,43 @@ export class FtReaderStateManager {
62
69
  this.store.commands.add({ type: `focus-topic-${tocId}` });
63
70
  }
64
71
  }
72
+ async resolvePage(tocId, pageNumber) {
73
+ var _a, _b;
74
+ const service = await this.awaitService();
75
+ if (pageNumber) {
76
+ return service.getPage(pageNumber, this.getTranslationSettings());
77
+ }
78
+ if (!tocId) {
79
+ return service.getPageByTocId("root", this.getTranslationSettings());
80
+ }
81
+ const maybeFilteredTopic = this.store.getState().filteredTocNodes[tocId];
82
+ const nodeIsInToc = ((_a = this.service) === null || _a === void 0 ? void 0 : _a.getTocNodeNow(tocId)) != null;
83
+ if (maybeFilteredTopic && maybeFilteredTopic.reason !== "ACCESS_RIGHTS_FILTER" && !nodeIsInToc) {
84
+ return service.getPageByTocId((_b = maybeFilteredTopic.closestParent) !== null && _b !== void 0 ? _b : "root", this.getTranslationSettings());
85
+ }
86
+ return service.getPageByTocId(tocId, this.getTranslationSettings());
87
+ }
65
88
  resolveValidNonRootTocId(tocId, page) {
66
- var _a, _b, _c;
89
+ var _a, _b, _c, _d, _e;
67
90
  const nonRootTocId = (_a = (tocId === "root" ? undefined : tocId)) !== null && _a !== void 0 ? _a : page.rootTocId;
68
91
  if (!page.topics.includes(nonRootTocId)) {
69
92
  if (tocId != "root" && !page.hiddenTopics.includes(nonRootTocId)) {
70
93
  // The redirection is expected when tocId = root or when landing from an "only in toc" topic, don't send the event.
71
94
  // Pass the requested tocId as event detail so consumers can probe access rights.
72
- this.store.dispatchEvent(new CustomEvent(FtReaderStoreEvents.requestedTopicNotFound, { detail: { tocId: nonRootTocId } }));
95
+ const maybeFilteredTopic = this.store.getState().filteredTocNodes[nonRootTocId];
96
+ if (maybeFilteredTopic) {
97
+ this.store.dispatchEvent(new FtRequestedTopicFilteredEvent(maybeFilteredTopic));
98
+ const nodeIsInToc = ((_b = this.service) === null || _b === void 0 ? void 0 : _b.getTocNodeNow(maybeFilteredTopic.tocId)) != null;
99
+ if (maybeFilteredTopic.reason === "ACCESS_RIGHTS_FILTER" || nodeIsInToc) {
100
+ return maybeFilteredTopic.tocId;
101
+ }
102
+ else {
103
+ return (_c = maybeFilteredTopic.closestParent) !== null && _c !== void 0 ? _c : "root";
104
+ }
105
+ }
106
+ this.store.dispatchEvent(new CustomEvent(FtReaderStoreEvents.requestedTopicNotFound));
73
107
  }
74
- return (_c = (_b = page.topics[0]) !== null && _b !== void 0 ? _b : page.hiddenTopics[0]) !== null && _c !== void 0 ? _c : "root";
108
+ return (_e = (_d = page.topics[0]) !== null && _d !== void 0 ? _d : page.hiddenTopics[0]) !== null && _e !== void 0 ? _e : "root";
75
109
  }
76
110
  return nonRootTocId;
77
111
  }
@@ -87,7 +121,7 @@ export class FtReaderStateManager {
87
121
  async load() {
88
122
  var _a;
89
123
  if (((_a = this.service) === null || _a === void 0 ? void 0 : _a.mapId) && this.store.getState().map == null) {
90
- await this.loadDebouncer.run(() => this.fetchData(this.getTranslationSettings()));
124
+ await this.loadDebouncer.run(() => this.fetchData());
91
125
  }
92
126
  }
93
127
  clear() {
@@ -117,25 +151,55 @@ export class FtReaderStateManager {
117
151
  this.clear();
118
152
  return this.load();
119
153
  }
120
- async fetchData(translationSettings) {
121
- var _a, _b, _c, _d, _e;
154
+ clearFromFilter() {
155
+ this._loaded = false;
156
+ this.store.actions.toc(undefined);
157
+ this.store.actions.pagesToc(undefined);
158
+ }
159
+ async reloadFromFilter(section, page) {
160
+ var _a, _b, _c;
161
+ this.clearFromFilter();
162
+ const { scrollTarget, visibleTopics, currentPage } = this.store.getState();
163
+ const tocId = (_c = (_b = (_a = scrollTarget === null || scrollTarget === void 0 ? void 0 : scrollTarget.tocId) !== null && _a !== void 0 ? _a : visibleTopics === null || visibleTopics === void 0 ? void 0 : visibleTopics[0]) !== null && _b !== void 0 ? _b : currentPage === null || currentPage === void 0 ? void 0 : currentPage.rootTocId) !== null && _c !== void 0 ? _c : "root";
164
+ await this.fetchDataFromFilter();
165
+ this.navigateToTopic(tocId, section, page);
166
+ }
167
+ async fetchDataFromFilter() {
168
+ var _a, _b, _c, _d;
169
+ const translationSettings = this.getTranslationSettings();
122
170
  try {
123
- if (translationSettings) {
124
- this.setTranslationLoading(true);
125
- }
126
- const handleTranslationError = (e) => {
171
+ await Promise.all([
172
+ (_a = this.service) === null || _a === void 0 ? void 0 : _a.getToc(translationSettings).then((toc) => this.store.actions.toc(toc)),
173
+ (_b = this.service) === null || _b === void 0 ? void 0 : _b.getPagesToc(translationSettings).then((pagesToc) => this.store.actions.pagesToc(pagesToc)),
174
+ (_c = this.service) === null || _c === void 0 ? void 0 : _c.getFilteredTocNodes(translationSettings).then((filteredTocNodes) => this.store.actions.filteredTocNodes(filteredTocNodes)),
175
+ ]);
176
+ this._loaded = true;
177
+ }
178
+ catch (e) {
179
+ if (!(e instanceof CanceledPromiseError)) {
127
180
  if (translationSettings) {
128
181
  this.setTranslationError(true);
129
182
  }
183
+ (_d = this.errorHandler) === null || _d === void 0 ? void 0 : _d.call(this, e);
130
184
  throw e;
131
- };
185
+ }
186
+ }
187
+ }
188
+ async fetchData() {
189
+ var _a, _b, _c, _d, _e, _f, _g;
190
+ const translationSettings = this.getTranslationSettings();
191
+ try {
192
+ if (translationSettings) {
193
+ this.setTranslationLoading(true);
194
+ }
132
195
  await Promise.all([
133
196
  this.loadConfiguration(),
134
- (_a = this.service) === null || _a === void 0 ? void 0 : _a.getMap(translationSettings).then((map) => this.store.actions.map(map)).catch(handleTranslationError),
135
- (_b = this.service) === null || _b === void 0 ? void 0 : _b.getToc(translationSettings).then((toc) => this.store.actions.toc(toc)).catch(handleTranslationError),
136
- (_c = this.service) === null || _c === void 0 ? void 0 : _c.getPagesToc(translationSettings).then((pagesToc) => this.store.actions.pagesToc(pagesToc)).catch(handleTranslationError),
137
- (_d = this.service) === null || _d === void 0 ? void 0 : _d.getPaginationConfiguration().then((conf) => this.store.actions.paginationConfiguration(conf)).catch(handleTranslationError),
138
- (_e = this.service) === null || _e === void 0 ? void 0 : _e.getTranslationError(translationSettings).then((translationError) => this.setTranslationError(translationError)),
197
+ (_a = this.service) === null || _a === void 0 ? void 0 : _a.getMap(translationSettings).then((map) => this.store.actions.map(map)),
198
+ (_b = this.service) === null || _b === void 0 ? void 0 : _b.getToc(translationSettings).then((toc) => this.store.actions.toc(toc)),
199
+ (_c = this.service) === null || _c === void 0 ? void 0 : _c.getPagesToc(translationSettings).then((pagesToc) => this.store.actions.pagesToc(pagesToc)),
200
+ (_d = this.service) === null || _d === void 0 ? void 0 : _d.getPaginationConfiguration().then((conf) => this.store.actions.paginationConfiguration(conf)),
201
+ (_e = this.service) === null || _e === void 0 ? void 0 : _e.getFilteredTocNodes(translationSettings).then((filteredTocNodes) => this.store.actions.filteredTocNodes(filteredTocNodes)),
202
+ (_f = this.service) === null || _f === void 0 ? void 0 : _f.getTranslationError(translationSettings).then((translationError) => this.setTranslationError(translationError)),
139
203
  ]);
140
204
  if (this.metadataForSwitchToRelatives.size > 0) {
141
205
  this.fetchRelatives();
@@ -146,8 +210,12 @@ export class FtReaderStateManager {
146
210
  }
147
211
  }
148
212
  catch (e) {
149
- if (this.errorHandler && !(e instanceof CanceledPromiseError)) {
150
- this.errorHandler(e);
213
+ if (!(e instanceof CanceledPromiseError)) {
214
+ if (translationSettings) {
215
+ this.setTranslationError(true);
216
+ }
217
+ (_g = this.errorHandler) === null || _g === void 0 ? void 0 : _g.call(this, e);
218
+ throw e;
151
219
  }
152
220
  }
153
221
  }
@@ -214,11 +282,11 @@ export class FtReaderStateManager {
214
282
  if (destinationLanguage) {
215
283
  this.sendDocumentOnDemandTranslateEvent(destinationLanguage);
216
284
  }
217
- await this.loadDebouncer.run(() => this.fetchData(this.getTranslationSettings()));
285
+ await this.loadDebouncer.run(() => this.fetchData());
218
286
  }
219
287
  async setTranslationSourceLanguage(sourceLanguage) {
220
288
  this.store.actions.setTranslationSourceLanguage(sourceLanguage);
221
- await this.loadDebouncer.run(() => this.fetchData(this.getTranslationSettings()));
289
+ await this.loadDebouncer.run(() => this.fetchData());
222
290
  }
223
291
  async setTranslationProfileId(profileId) {
224
292
  this.store.actions.setTranslationProfileId(profileId);
@@ -265,7 +333,8 @@ export class FtReaderStateManager {
265
333
  this.metadataForSwitchToRelatives.delete(id);
266
334
  this.updateClusteringHelper();
267
335
  }
268
- getAccurateNavigationData(tocId, currentPage, oldScrollTarget) {
336
+ async getAccurateNavigationData(tocId, currentPage, oldScrollTarget) {
337
+ await this.awaitService();
269
338
  return this.service.getAccurateNavigationData(tocId, currentPage === null || currentPage === void 0 ? void 0 : currentPage.number, oldScrollTarget === null || oldScrollTarget === void 0 ? void 0 : oldScrollTarget.section, this.getTranslationSettings());
270
339
  }
271
340
  buildBreadcrumb(tocId) {
@@ -1,10 +1,14 @@
1
- import { FtMap, FtPaginationConfiguration, FtPublicationRatingSummary, FtRatingType, FtRatingTypeKeys, FtReaderConfiguration, FtSearchResultClusterEntry, FtSession, FtTocNode, FtTopic, FtTopicRating, FtTranslationLocale } from "@fluid-topics/public-api";
1
+ import { FtMap, FtMetadataFilter, FtPaginationConfiguration, FtPublicationRatingSummary, FtRatingType, FtRatingTypeKeys, FtReaderConfiguration, FtSearchResultClusterEntry, FtSession, FtTocNode, FtTocNodeFiltered, FtTopic, FtTopicRating, FtTranslationLocale } from "@fluid-topics/public-api";
2
2
  import { Optional } from "@fluid-topics/ft-wc-utils";
3
3
  export declare enum FtReaderStoreEvents {
4
4
  clusteringHelperCreated = "clustering-helper-created",
5
5
  mapAttachmentsUpdate = "map-attachments-update",
6
6
  visibleTopicChange = "visible-topic-change",
7
- requestedTopicNotFound = "requested-topic-not-found"
7
+ requestedTopicNotFound = "requested-topic-not-found",
8
+ requestedTopicFiltered = "requested-topic-filtered"
9
+ }
10
+ export declare class FtRequestedTopicFilteredEvent extends CustomEvent<FtTocNodeFiltered> {
11
+ constructor(filteredNode: FtTocNodeFiltered);
8
12
  }
9
13
  export interface FtPagesTocNode {
10
14
  depth: number;
@@ -44,6 +48,7 @@ export interface FtReaderState {
44
48
  toc: Optional<Array<FtReaderTocNode>>;
45
49
  pagesToc: Optional<Array<FtPagesTocNode>>;
46
50
  paginationConfiguration: Optional<FtPaginationConfiguration>;
51
+ filteredTocNodes: Record<string, FtTocNodeFiltered>;
47
52
  currentPage: Optional<FtReaderPage>;
48
53
  scrollTarget: Optional<FtReaderScrollTarget>;
49
54
  renderedTopics: string[];
@@ -63,6 +68,7 @@ export interface FtReaderState {
63
68
  isError: boolean;
64
69
  };
65
70
  linkPreviewDialogId: Optional<string>;
71
+ metadataFilters: Array<FtMetadataFilter>;
66
72
  }
67
73
  export interface FtReaderNavigationData {
68
74
  mapId: string;
@@ -73,6 +79,7 @@ export interface FtReaderNavigationData {
73
79
  page?: number;
74
80
  prettyUrl?: string;
75
81
  prettyUrlDuplicated: boolean;
82
+ metadataFilters?: Array<FtMetadataFilter>;
76
83
  }
77
84
  export interface FtTopicRatingSummary {
78
85
  rating?: FtTopicRating;
@@ -4,7 +4,13 @@ export var FtReaderStoreEvents;
4
4
  FtReaderStoreEvents["mapAttachmentsUpdate"] = "map-attachments-update";
5
5
  FtReaderStoreEvents["visibleTopicChange"] = "visible-topic-change";
6
6
  FtReaderStoreEvents["requestedTopicNotFound"] = "requested-topic-not-found";
7
+ FtReaderStoreEvents["requestedTopicFiltered"] = "requested-topic-filtered";
7
8
  })(FtReaderStoreEvents || (FtReaderStoreEvents = {}));
9
+ export class FtRequestedTopicFilteredEvent extends CustomEvent {
10
+ constructor(filteredNode) {
11
+ super(FtReaderStoreEvents.requestedTopicFiltered, { detail: filteredNode });
12
+ }
13
+ }
8
14
  export var FtReaderFeatures;
9
15
  (function (FtReaderFeatures) {
10
16
  FtReaderFeatures["FEEDBACK"] = "FEEDBACK";
@@ -30,6 +30,7 @@ export const createReaderStore = (id) => FtReduxStore.get({
30
30
  map: undefined,
31
31
  toc: undefined,
32
32
  pagesToc: undefined,
33
+ filteredTocNodes: {},
33
34
  paginationConfiguration: undefined,
34
35
  currentPage: undefined,
35
36
  scrollTarget: undefined,
@@ -46,6 +47,7 @@ export const createReaderStore = (id) => FtReduxStore.get({
46
47
  isError: false,
47
48
  },
48
49
  linkPreviewDialogId: undefined,
50
+ metadataFilters: [],
49
51
  },
50
52
  reducers: readerStoreStateReducers,
51
53
  });
@@ -1,4 +1,4 @@
1
- import type { FtMap, FtMapAttachment, FtPaginatedToc, FtRatingSummary, FtRatingType, FtRatingTypeKeys, FtSearchResults, FtTocNode, FtTopic, FtTranslationContent, FtTranslationSettings } from "@fluid-topics/public-api";
1
+ import type { FtMap, FtMapAttachment, FtMetadataFilter, FtPaginatedToc, FtRatingSummary, FtRatingType, FtRatingTypeKeys, FtSearchResults, FtTocNode, FtTopic, FtTranslationContent, FtTranslationSettings } from "@fluid-topics/public-api";
2
2
  import { FtReaderService } from "./FtReaderService";
3
3
  import { FtReaderFeatures } from "../model";
4
4
  export declare class FtOfficialReaderService extends FtReaderService {
@@ -7,7 +7,7 @@ export declare class FtOfficialReaderService extends FtReaderService {
7
7
  clear(): void;
8
8
  protected fetchMap(mapId: string, translationSettings?: FtTranslationSettings): Promise<FtMap>;
9
9
  protected fetchMapRating(mapId: string): Promise<FtRatingSummary>;
10
- protected fetchPages(mapId: string, translationSettings?: FtTranslationSettings): Promise<FtPaginatedToc>;
10
+ protected fetchPages(mapId: string, metadataFilters?: FtMetadataFilter[], translationSettings?: FtTranslationSettings): Promise<FtPaginatedToc>;
11
11
  protected fetchTopicHTMLContent(tocNode: FtTocNode): Promise<string>;
12
12
  protected fetchTranslatedTopicHTMLContent(tocNode: FtTocNode, translationSettings: FtTranslationSettings): Promise<FtTranslationContent>;
13
13
  protected fetchTopicMetadata(tocNode: FtTocNode): Promise<FtTopic>;
@@ -16,9 +16,11 @@ export class FtOfficialReaderService extends FtReaderService {
16
16
  fetchMapRating(mapId) {
17
17
  return this.api.getMapRating(mapId);
18
18
  }
19
- async fetchPages(mapId, translationSettings) {
19
+ async fetchPages(mapId, metadataFilters, translationSettings) {
20
20
  await this.getMap(translationSettings);
21
- return this.api.getPages(mapId, this.fingerprint, translationSettings);
21
+ return (metadataFilters === null || metadataFilters === void 0 ? void 0 : metadataFilters.length)
22
+ ? this.api.getFilteredPages(mapId, translationSettings, metadataFilters)
23
+ : this.api.getPages(mapId, this.fingerprint, translationSettings);
22
24
  }
23
25
  fetchTopicHTMLContent(tocNode) {
24
26
  return this.api.getTopicHTMLContent(this.mapId, tocNode.contentId, "DESIGNED_READER", this.fingerprint);
@@ -1,4 +1,4 @@
1
- import { FtPaginatedToc, FtPaginationConfiguration } from "@fluid-topics/public-api";
1
+ import { FtPaginatedToc, FtPaginationConfiguration, FtTocNodeFiltered } from "@fluid-topics/public-api";
2
2
  import { FtPagesTocNode, FtReaderPage, FtReaderTocNode } from "../model";
3
3
  export type EnrichedToc = {
4
4
  paginationConfiguration: FtPaginationConfiguration;
@@ -10,6 +10,7 @@ export type EnrichedToc = {
10
10
  pages: Array<FtReaderPage>;
11
11
  pageByTocId: Record<string, FtReaderPage>;
12
12
  translationError: boolean;
13
+ filteredTocNodes: Record<string, FtTocNodeFiltered>;
13
14
  };
14
15
  export declare class FtReaderConverter {
15
16
  convertPaginatedToc(mapId: string, paginatedToc: FtPaginatedToc): EnrichedToc;
@@ -19,6 +19,7 @@ class EnrichedTocBuilder {
19
19
  pages: this.pages,
20
20
  pageByTocId: this.pageByTocId,
21
21
  translationError: this.paginatedToc.translationError,
22
+ filteredTocNodes: this.paginatedToc.filteredTocNodes,
22
23
  };
23
24
  }
24
25
  extractPagesToc(nodes, depth, parentTocId) {
@@ -1,4 +1,4 @@
1
- import type { FluidTopicsApi, FtMap, FtMapAttachment, FtMetadata, FtPaginatedToc, FtPaginationConfiguration, FtPublicationRatingSummary, FtRatingSummary, FtRatingTypeKeys, FtReaderConfiguration, FtTocNode, FtTopic, FtTranslationContent, FtTranslationSettings } from "@fluid-topics/public-api";
1
+ import type { FluidTopicsApi, FtMap, FtMapAttachment, FtMetadata, FtMetadataFilter, FtPaginatedToc, FtPaginationConfiguration, FtPublicationRatingSummary, FtRatingSummary, FtRatingTypeKeys, FtReaderConfiguration, FtTocNode, FtTocNodeFiltered, FtTopic, FtTranslationContent, FtTranslationSettings } from "@fluid-topics/public-api";
2
2
  import { FtRatingType, FtSearchResults } from "@fluid-topics/public-api";
3
3
  import { FtPagesTocNode, FtReaderFeatureAccessData, FtReaderFeatures, FtReaderNavigationData, FtReaderPage, FtReaderTocNode, FtTopicRatingSummary } from "../model";
4
4
  import { FtReaderConverter } from "./FtReaderConverter";
@@ -7,7 +7,7 @@ import { FtReaderBreadcrumb } from "../../models";
7
7
  export declare abstract class FtReaderService extends FtServiceWithCache {
8
8
  protected converter: FtReaderConverter;
9
9
  protected abstract fetchMap(mapId: string, translationSettings?: FtTranslationSettings): Promise<FtMap>;
10
- protected abstract fetchPages(mapId: string, translationSettings?: FtTranslationSettings): Promise<FtPaginatedToc>;
10
+ protected abstract fetchPages(mapId: string, metadataFilters?: FtMetadataFilter[], translationSettings?: FtTranslationSettings): Promise<FtPaginatedToc>;
11
11
  protected abstract fetchMapRating(mapId: string): Promise<FtRatingSummary>;
12
12
  protected abstract fetchTopicMetadata(tocNode: FtTocNode): Promise<FtTopic>;
13
13
  protected abstract fetchTopicHTMLContent(tocNode: FtTocNode): Promise<string>;
@@ -24,9 +24,12 @@ export declare abstract class FtReaderService extends FtServiceWithCache {
24
24
  protected abstract getReaderLinkPrefix(): string;
25
25
  protected abstract isFeatureAvailable(feature: FtReaderFeatures): boolean;
26
26
  private _mapId;
27
+ private _metadataFilters;
28
+ get metadataFilters(): FtMetadataFilter[];
29
+ set metadataFilters(value: FtMetadataFilter[] | undefined);
27
30
  get mapId(): string;
28
31
  set mapId(value: string | undefined);
29
- constructor(converter: FtReaderConverter, overrideApi?: FluidTopicsApi, mapId?: string);
32
+ constructor(converter: FtReaderConverter, overrideApi?: FluidTopicsApi, mapId?: string, metadataFilters?: FtMetadataFilter[]);
30
33
  private withMapId;
31
34
  private initCache;
32
35
  clear(): void;
@@ -41,6 +44,7 @@ export declare abstract class FtReaderService extends FtServiceWithCache {
41
44
  getToc(translationSettings?: FtTranslationSettings): Promise<Array<FtReaderTocNode>>;
42
45
  getPagesToc(translationSettings?: FtTranslationSettings): Promise<Array<FtPagesTocNode>>;
43
46
  getTranslationError(translationSettings?: FtTranslationSettings): Promise<boolean>;
47
+ getFilteredTocNodes(translationSettings?: FtTranslationSettings): Promise<Record<string, FtTocNodeFiltered>>;
44
48
  getTocNode(tocId: string, translationSettings?: FtTranslationSettings): Promise<FtReaderTocNode>;
45
49
  getTocNodeNow(tocId: string, translationInput?: FtTranslationSettings): FtReaderTocNode | undefined;
46
50
  getTocNodeNowByUrl(prettyUrlOrMapIdTocId: string, translationInput?: FtTranslationSettings): FtReaderTocNode | undefined;
@@ -55,7 +59,8 @@ export declare abstract class FtReaderService extends FtServiceWithCache {
55
59
  getRelativesForDocument(metadataPivotKey: string, metadataPivotValues: string[]): Promise<FtSearchResults>;
56
60
  getRelativesForTopicInMap(mapId: string, metadataPivotKey: string, metadataPivotValues: string[]): Promise<FtSearchResults>;
57
61
  getAttachmentDownloadLink(id: string): string;
58
- getLink(tocId?: string, pageNumber?: number, section?: string): string;
62
+ getLink(tocId?: string, pageNumber?: number, section?: string, withMetadataFilter?: boolean): string;
63
+ getLinkWithFilter(tocId?: string, pageNumber?: number, section?: string): string;
59
64
  getNavigationData(tocId?: string, pageNumber?: number, section?: string, translationInput?: FtTranslationSettings): FtReaderNavigationData;
60
65
  getAccurateNavigationData(tocId?: string, pageNumber?: number, section?: string, translationInput?: FtTranslationSettings): Promise<FtReaderNavigationData>;
61
66
  private getRatingSummary;
@@ -1,7 +1,14 @@
1
1
  import { FtUserRole, userHasRole, } from "@fluid-topics/public-api";
2
2
  import { FtReaderFeatures, } from "../model";
3
3
  import { ftAppInfoStore, FtServiceWithCache, } from "@fluid-topics/ft-app-context";
4
+ import { SearchPlaceConverter, SearchPlaceQueryParams, } from "@fluid-topics/ft-wc-utils";
4
5
  export class FtReaderService extends FtServiceWithCache {
6
+ get metadataFilters() {
7
+ return this._metadataFilters;
8
+ }
9
+ set metadataFilters(value) {
10
+ this._metadataFilters = value;
11
+ }
5
12
  get mapId() {
6
13
  return this._mapId;
7
14
  }
@@ -11,10 +18,11 @@ export class FtReaderService extends FtServiceWithCache {
11
18
  }
12
19
  this._mapId = value;
13
20
  }
14
- constructor(converter, overrideApi, mapId) {
21
+ constructor(converter, overrideApi, mapId, metadataFilters) {
15
22
  super(false, overrideApi);
16
23
  this.converter = converter;
17
24
  this._mapId = mapId;
25
+ this._metadataFilters = metadataFilters;
18
26
  this.initCache();
19
27
  }
20
28
  async withMapId(provider) {
@@ -23,7 +31,7 @@ export class FtReaderService extends FtServiceWithCache {
23
31
  initCache() {
24
32
  this.cache.register("configuration", () => this.api.getReaderConfiguration());
25
33
  this.cache.register("map", () => this.withMapId((mapId) => this.fetchMap(mapId)));
26
- this.cache.register("enrichedToc", () => this.withMapId((mapId) => this.fetchPages(mapId).then((toc) => this.converter.convertPaginatedToc(mapId, toc))));
34
+ this.cache.register(this.makeCacheKey("enrichedToc", undefined, this.metadataFilters), () => this.withMapId((mapId) => this.fetchPages(mapId, this._metadataFilters).then((toc) => this.converter.convertPaginatedToc(mapId, toc))));
27
35
  this.cache.register("ratingSummary", () => {
28
36
  var _a, _b;
29
37
  const userHaveRatingRole = userHasRole((_b = (_a = ftAppInfoStore.getState().session) === null || _a === void 0 ? void 0 : _a.profile.roles) !== null && _b !== void 0 ? _b : [], "RATING_USER");
@@ -33,8 +41,10 @@ export class FtReaderService extends FtServiceWithCache {
33
41
  clear() {
34
42
  this.cache.clearMatching((key) => key !== "configuration");
35
43
  }
36
- makeCacheKey(base, translationSettings) {
37
- return base + (translationSettings ? "-destinationLanguage-" + (translationSettings === null || translationSettings === void 0 ? void 0 : translationSettings.destinationLanguage) : "");
44
+ makeCacheKey(base, translationSettings, metadataFilters) {
45
+ return base
46
+ + (translationSettings ? "-destinationLanguage-" + (translationSettings === null || translationSettings === void 0 ? void 0 : translationSettings.destinationLanguage) : "")
47
+ + (!metadataFilters || metadataFilters.length == 0 ? "" : "-metadataFilters-" + this.hash(metadataFilters));
38
48
  }
39
49
  getMap(translationSettings) {
40
50
  return this.cache.get(this.makeCacheKey("map", translationSettings), () => this.fetchMap(this.mapId, translationSettings));
@@ -49,10 +59,10 @@ export class FtReaderService extends FtServiceWithCache {
49
59
  this.cache.clear("configuration");
50
60
  }
51
61
  getEnrichedToc(translationSettings) {
52
- return this.cache.get(this.makeCacheKey("enrichedToc", translationSettings), () => this.fetchPages(this.mapId, translationSettings).then((toc) => this.converter.convertPaginatedToc(this.mapId, toc)));
62
+ return this.cache.get(this.makeCacheKey("enrichedToc", translationSettings, this.metadataFilters), () => this.fetchPages(this.mapId, this.metadataFilters, translationSettings).then((toc) => this.converter.convertPaginatedToc(this.mapId, toc)));
53
63
  }
54
64
  getEnrichedTocNow(translationSettings) {
55
- return this.cache.getNow(this.makeCacheKey("enrichedToc", translationSettings));
65
+ return this.cache.getNow(this.makeCacheKey("enrichedToc", translationSettings, this.metadataFilters));
56
66
  }
57
67
  async getPaginationConfiguration() {
58
68
  const enrichedToc = await this.getEnrichedToc();
@@ -70,6 +80,10 @@ export class FtReaderService extends FtServiceWithCache {
70
80
  const enrichedToc = await this.getEnrichedToc(translationSettings);
71
81
  return enrichedToc.translationError;
72
82
  }
83
+ async getFilteredTocNodes(translationSettings) {
84
+ const enrichedToc = await this.getEnrichedToc(translationSettings);
85
+ return enrichedToc.filteredTocNodes;
86
+ }
73
87
  async getTocNode(tocId, translationSettings) {
74
88
  const enrichedToc = await this.getEnrichedToc(translationSettings);
75
89
  return enrichedToc.nodeByTocId[tocId];
@@ -126,7 +140,7 @@ export class FtReaderService extends FtServiceWithCache {
126
140
  getAttachmentDownloadLink(id) {
127
141
  return this.makeAbsolute(`${this.api.endpoints.khub.maps.mapId(this.mapId).attachments.attachmentId(id).content}?download=true&locationValue=reader`);
128
142
  }
129
- getLink(tocId, pageNumber, section) {
143
+ getLink(tocId, pageNumber, section, withMetadataFilter) {
130
144
  const navigationData = this.getNavigationData(tocId, pageNumber, section);
131
145
  const path = this.getReaderLinkPrefix() + (navigationData.prettyUrl ? navigationData.prettyUrl : `${navigationData.mapId}/${navigationData.tocId}`);
132
146
  const url = new URL(path, this.api.tenantBaseUrl);
@@ -139,8 +153,17 @@ export class FtReaderService extends FtServiceWithCache {
139
153
  if (navigationData.section != null) {
140
154
  url.searchParams.set("section", navigationData.section);
141
155
  }
156
+ if (withMetadataFilter && navigationData.metadataFilters) {
157
+ const serializeFilters = SearchPlaceConverter.serializeValueFilters(navigationData.metadataFilters);
158
+ if (serializeFilters) {
159
+ url.searchParams.set(SearchPlaceQueryParams.VALUE_FILTERS, serializeFilters);
160
+ }
161
+ }
142
162
  return url.href;
143
163
  }
164
+ getLinkWithFilter(tocId, pageNumber, section) {
165
+ return this.getLink(tocId, pageNumber, section, true);
166
+ }
144
167
  getNavigationData(tocId, pageNumber, section, translationInput) {
145
168
  var _a, _b;
146
169
  tocId = tocId || "root";
@@ -157,6 +180,7 @@ export class FtReaderService extends FtServiceWithCache {
157
180
  prettyUrl: prettyUrl != null ? prettyUrl.replace(/^r\//, "") : undefined,
158
181
  prettyUrlDuplicated: (_b = enrichedToc === null || enrichedToc === void 0 ? void 0 : enrichedToc.duplicatedPrettyUrls.has(prettyUrl !== null && prettyUrl !== void 0 ? prettyUrl : "")) !== null && _b !== void 0 ? _b : false,
159
182
  section: section,
183
+ metadataFilters: this.metadataFilters,
160
184
  };
161
185
  }
162
186
  async getAccurateNavigationData(tocId, pageNumber, section, translationInput) {
@@ -214,6 +238,9 @@ export class FtReaderService extends FtServiceWithCache {
214
238
  }
215
239
  buildBreadcrumb(tocId, translationInput) {
216
240
  const target = this.getTocNodeNow(tocId, translationInput);
241
+ if (!target) {
242
+ return [];
243
+ }
217
244
  const breadcrumb = [{ tocId: target.tocId, title: target.title, untranslatedTitle: target.untranslatedTitle }];
218
245
  let parent = this.getTocNodeNow(target.parentTocId, translationInput);
219
246
  while (parent) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-topics/ft-reader-context",
3
- "version": "2.2.16",
3
+ "version": "2.2.18",
4
4
  "description": "Context block for integrated reader components",
5
5
  "keywords": [
6
6
  "Lit"
@@ -19,12 +19,12 @@
19
19
  "url": "ssh://git@scm.mrs.antidot.net:2222/fluidtopics/ft-web-components.git"
20
20
  },
21
21
  "dependencies": {
22
- "@fluid-topics/ft-app-context": "2.2.16",
23
- "@fluid-topics/ft-wc-utils": "2.2.16",
22
+ "@fluid-topics/ft-app-context": "2.2.18",
23
+ "@fluid-topics/ft-wc-utils": "2.2.18",
24
24
  "lit": "3.3.3"
25
25
  },
26
26
  "devDependencies": {
27
- "@fluid-topics/public-api": "1.0.142"
27
+ "@fluid-topics/public-api": "1.0.143"
28
28
  },
29
- "gitHead": "c461a5d4f16255f9dd084cb26b2f988702693e2f"
29
+ "gitHead": "0d86a22efcc09de35d3da8d470ae3f1d69f282bc"
30
30
  }