98
98
<div class =" input-wrapper" >
99
99
<FilterInput
100
100
v-model =" filter"
101
- :tags =" availableTags "
101
+ :tags =" suggestedTags "
102
102
:translatableTags =" translatableTags"
103
- :selected-tags.sync =" selectedTagsModelValue "
103
+ :selected-tags.sync =" selectedTags "
104
104
:placeholder =" $t('filter.title')"
105
105
:should-keep-open-on-blur =" false"
106
+ :shouldTruncateTags =" shouldTruncateTags"
106
107
:position-reversed =" !renderFilterOnTop"
107
108
:clear-filter-on-tag-select =" false"
108
109
class =" filter-component"
@@ -133,8 +134,10 @@ import BaseNavigatorCard from 'docc-render/components/Navigator/BaseNavigatorCar
133
134
import { TopicTypes } from ' docc-render/constants/TopicTypes' ;
134
135
import FilterInput from ' docc-render/components/Filter/FilterInput.vue' ;
135
136
import keyboardNavigation from ' docc-render/mixins/keyboardNavigation' ;
137
+ import filteredChildrenMixin from ' theme/mixins/navigator/filteredChildren' ;
138
+ import tagsProvider from ' theme/mixins/navigator/tagsProvider' ;
139
+ import { FILTER_TAGS , CHANGES_TAGS } from ' docc-render/constants/Tags' ;
136
140
import { isEqual , last } from ' docc-render/utils/arrays' ;
137
- import { ChangeNames , ChangeNameToType } from ' docc-render/constants/Changes' ;
138
141
import {
139
142
convertChildrenArrayToObject ,
140
143
getAllChildren ,
@@ -147,43 +150,10 @@ import Badge from 'docc-render/components/Badge.vue';
147
150
148
151
const STORAGE_KEY = ' navigator.state' ;
149
152
150
- const FILTER_TAGS = {
151
- sampleCode: ' sampleCode' ,
152
- tutorials: ' tutorials' ,
153
- articles: ' articles' ,
154
- webServiceEndpoints: ' webServiceEndpoints' ,
155
- };
156
-
157
- const FILTER_TAGS_TO_LABELS = {
158
- [FILTER_TAGS .sampleCode ]: ' Sample Code' ,
159
- [FILTER_TAGS .tutorials ]: ' Tutorials' ,
160
- [FILTER_TAGS .articles ]: ' Articles' ,
161
- [FILTER_TAGS .webServiceEndpoints ]: ' Web Service Endpoints' ,
162
- };
163
-
164
- const FILTER_LABELS_TO_TAGS = Object .fromEntries (
165
- Object
166
- .entries (FILTER_TAGS_TO_LABELS )
167
- .map (([key , value ]) => [value, key]),
168
- );
169
-
170
- const TOPIC_TYPE_TO_TAG = {
171
- [TopicTypes .article ]: FILTER_TAGS .articles ,
172
- [TopicTypes .learn ]: FILTER_TAGS .tutorials ,
173
- [TopicTypes .overview ]: FILTER_TAGS .tutorials ,
174
- [TopicTypes .resources ]: FILTER_TAGS .tutorials ,
175
- [TopicTypes .sampleCode ]: FILTER_TAGS .sampleCode ,
176
- [TopicTypes .section ]: FILTER_TAGS .tutorials ,
177
- [TopicTypes .tutorial ]: FILTER_TAGS .tutorials ,
178
- [TopicTypes .project ]: FILTER_TAGS .tutorials ,
179
- [TopicTypes .httpRequest ]: FILTER_TAGS .webServiceEndpoints ,
180
- };
181
-
182
153
const NO_RESULTS = ' navigator.no-results' ;
183
154
const NO_CHILDREN = ' navigator.no-children' ;
184
155
const ERROR_FETCHING = ' navigator.error-fetching' ;
185
156
const ITEMS_FOUND = ' navigator.items-found' ;
186
- const HIDE_DEPRECATED = ' navigator.tags.hide-deprecated' ;
187
157
188
158
/**
189
159
* Renders the card for a technology and it's child symbols, in the navigator.
@@ -194,13 +164,8 @@ export default {
194
164
name: ' NavigatorCard' ,
195
165
constants: {
196
166
STORAGE_KEY ,
197
- FILTER_TAGS ,
198
- FILTER_TAGS_TO_LABELS ,
199
- FILTER_LABELS_TO_TAGS ,
200
- TOPIC_TYPE_TO_TAG ,
201
167
ERROR_FETCHING ,
202
168
ITEMS_FOUND ,
203
- HIDE_DEPRECATED ,
204
169
},
205
170
components: {
206
171
FilterInput,
@@ -266,7 +231,7 @@ export default {
266
231
},
267
232
},
268
233
mixins: [
269
- keyboardNavigation,
234
+ keyboardNavigation, filteredChildrenMixin, tagsProvider,
270
235
],
271
236
data () {
272
237
return {
@@ -282,7 +247,6 @@ export default {
282
247
activeUID: null ,
283
248
lastFocusTarget: null ,
284
249
allNodesToggled: false ,
285
- translatableTags: [HIDE_DEPRECATED ],
286
250
INDEX_ROOT_KEY ,
287
251
};
288
252
},
@@ -300,76 +264,6 @@ export default {
300
264
if (errorFetching) return ERROR_FETCHING ;
301
265
return NO_CHILDREN ;
302
266
},
303
- /**
304
- * Generates an array of tag labels for filtering.
305
- * Shows only tags, that have children matches.
306
- */
307
- availableTags ({
308
- selectedTags,
309
- renderableChildNodesMap,
310
- apiChangesObject,
311
- hideAvailableTags,
312
- }) {
313
- if (hideAvailableTags || selectedTags .length ) return [];
314
- const apiChangesTypesSet = new Set (Object .values (apiChangesObject));
315
- const tagLabelsSet = new Set (Object .values (FILTER_TAGS_TO_LABELS ));
316
- const generalTags = new Set ([HIDE_DEPRECATED ]);
317
- // when API changes are available, remove the `HIDE_DEPRECATED` option
318
- if (apiChangesTypesSet .size ) {
319
- generalTags .delete (HIDE_DEPRECATED );
320
- }
321
-
322
- const availableTags = {
323
- type: [],
324
- changes: [],
325
- other: [],
326
- };
327
- // iterate over the nodes to render
328
- for (const childID in renderableChildNodesMap) {
329
- if (! Object .hasOwnProperty .call (renderableChildNodesMap, childID)) {
330
- continue ;
331
- }
332
- // if there are no more tags to iterate over, end early
333
- if (! tagLabelsSet .size && ! apiChangesTypesSet .size && ! generalTags .size ) {
334
- break ;
335
- }
336
- // extract props
337
- const { type , path , deprecated } = renderableChildNodesMap[childID];
338
- // grab the tagLabel
339
- const tagLabel = FILTER_TAGS_TO_LABELS [TOPIC_TYPE_TO_TAG [type]];
340
- const changeType = apiChangesObject[path];
341
- // try to match a tag
342
- if (tagLabelsSet .has (tagLabel)) {
343
- // if we have a match, store it
344
- availableTags .type .push (tagLabel);
345
- // remove the match, so we can end the filter early
346
- tagLabelsSet .delete (tagLabel);
347
- }
348
- if (changeType && apiChangesTypesSet .has (changeType)) {
349
- availableTags .changes .push (this .$t (ChangeNames[changeType]));
350
- apiChangesTypesSet .delete (changeType);
351
- }
352
- if (deprecated && generalTags .has (HIDE_DEPRECATED )) {
353
- availableTags .other .push (HIDE_DEPRECATED );
354
- generalTags .delete (HIDE_DEPRECATED );
355
- }
356
- }
357
- return availableTags .type .concat (availableTags .changes , availableTags .other );
358
- },
359
- selectedTagsModelValue: {
360
- get () {
361
- return this .selectedTags .map (tag => (
362
- FILTER_TAGS_TO_LABELS [tag] || this .$t (ChangeNames[tag]) || tag
363
- ));
364
- },
365
- set (values ) {
366
- // guard against accidental clearings
367
- if (! this .selectedTags .length && ! values .length ) return ;
368
- this .selectedTags = values .map (label => (
369
- FILTER_LABELS_TO_TAGS [label] || ChangeNameToType[label] || label
370
- ));
371
- },
372
- },
373
267
filterPattern : ({ debouncedFilter }) => (! debouncedFilter
374
268
? null
375
269
// remove the `g` for global, as that causes bugs when matching
@@ -401,41 +295,6 @@ export default {
401
295
activeIndex : ({ activeUID, nodesToRender }) => (
402
296
nodesToRender .findIndex (node => node .uid === activeUID)
403
297
),
404
- /**
405
- * Returns a list of the child nodes, that match the filter pattern.
406
- * @returns NavigatorFlatItem[]
407
- */
408
- filteredChildren ({
409
- hasFilter, children, filterPattern, selectedTags, apiChanges,
410
- }) {
411
- if (! hasFilter) return [];
412
- const tagsSet = new Set (selectedTags);
413
- // find children that match current filters
414
- return children .filter (({
415
- title, path, type, deprecated, deprecatedChildrenCount, childUIDs,
416
- }) => {
417
- // groupMarkers know how many children they have and how many are deprecated
418
- const isDeprecated = deprecated || deprecatedChildrenCount === childUIDs .length ;
419
- // check if `title` matches the pattern, if provided
420
- const titleMatch = filterPattern ? filterPattern .test (title) : true ;
421
- // check if `type` matches any of the selected tags
422
- let tagMatch = true ;
423
- if (tagsSet .size ) {
424
- tagMatch = tagsSet .has (TOPIC_TYPE_TO_TAG [type]);
425
- // if there are API changes and there is no tag match, try to match change types
426
- if (apiChanges && ! tagMatch) {
427
- tagMatch = tagsSet .has (apiChanges[path]);
428
- }
429
- if (! isDeprecated && tagsSet .has (HIDE_DEPRECATED )) {
430
- tagMatch = true ;
431
- }
432
- }
433
- // find items, that have API changes
434
- const hasAPIChanges = apiChanges ? !! apiChanges[path] : true ;
435
- // make sure groupMarker's dont get matched
436
- return titleMatch && tagMatch && hasAPIChanges;
437
- });
438
- },
439
298
/**
440
299
* This generates a map of all the nodes we are allowed to render at a certain time.
441
300
* This is used on both toggling, as well as on navigation and filtering.
@@ -505,7 +364,7 @@ export default {
505
364
* @returns boolean
506
365
*/
507
366
deprecatedHidden : ({ selectedTags }) => (
508
- selectedTags[0 ] === HIDE_DEPRECATED
367
+ selectedTags[0 ] === FILTER_TAGS . hideDeprecated
509
368
),
510
369
apiChangesObject () {
511
370
return this .apiChanges || {};
@@ -524,7 +383,7 @@ export default {
524
383
apiChanges (value ) {
525
384
if (value) return ;
526
385
// if we remove APIChanges, remove all related tags as well
527
- this .selectedTags = this .selectedTags .filter (t => ! this . $t (ChangeNames[t] ));
386
+ this .selectedTags = this .selectedTags .filter (t => ! Object . values ( CHANGES_TAGS ). includes (t ));
528
387
},
529
388
async activeUID (newUid , oldUID ) {
530
389
// Update the dynamicScroller item's size, when we change the UID,
0 commit comments