From 6a617b92183c14a442fff82515afaa1b4d1290e9 Mon Sep 17 00:00:00 2001 From: Wilson Gaturu Date: Mon, 24 Jul 2023 07:21:00 +0300 Subject: [PATCH] adds taxonomy api endpoint --- indigo/bulk_creator.py | 46 +-- .../management/commands/migrate_taxonomies.py | 21 ++ indigo_api/management/commands/taxonomies.py | 66 ++++ indigo_api/migrations/0026_taxonomy_topic.py | 6 +- indigo_api/models/works.py | 36 ++- indigo_api/serializers.py | 13 +- indigo_app/forms.py | 14 + indigo_app/js/components/TaxonomyTOC.vue | 42 +++ indigo_app/js/components/index.js | 1 + indigo_app/static/javascript/indigo-app.js | 89 +++++- .../indigo_api/_task_filter_form.html | 4 + .../indigo_api/_work_filter_form.html | 3 + .../templates/indigo_api/task_list.html | 62 ++-- .../templates/indigo_api/work_form.html | 2 +- indigo_app/templates/place/works.html | 288 +++++++++--------- indigo_app/views/places.py | 4 +- indigo_app/views/tasks.py | 4 +- indigo_content_api/v2/serializers.py | 15 +- indigo_content_api/v2/urls.py | 1 + indigo_content_api/v2/views.py | 9 +- 20 files changed, 505 insertions(+), 221 deletions(-) create mode 100644 indigo_api/management/commands/migrate_taxonomies.py create mode 100644 indigo_api/management/commands/taxonomies.py create mode 100644 indigo_app/js/components/TaxonomyTOC.vue diff --git a/indigo/bulk_creator.py b/indigo/bulk_creator.py index 4c120caeb2..cef276a8da 100644 --- a/indigo/bulk_creator.py +++ b/indigo/bulk_creator.py @@ -36,6 +36,9 @@ def __init__(self, data, errors): for k, v in data.items(): setattr(self, k, v) + def __getitem__(cls, key): + return cls.__dict__[key] + class LowerChoiceField(forms.ChoiceField): def to_python(self, value): @@ -419,8 +422,7 @@ def update_relationships(self): self.link_taxonomy(row) if row.taxonomy_topic: - self.link_taxonomy_topic(row) - + self.link_taxonomy(row, model=TaxonomyTopic, attr='taxonomy_topics', attr_single='taxonomy_topic') if row.amended_by: self.link_amendment_passive(row) @@ -911,22 +913,23 @@ def link_amendment_active(self, row): task_type='apply-amendment', amendment=amendment) - def link_taxonomy(self, row): - topics = [x.strip() for x in row.taxonomy.split(';') if x.strip()] + def link_taxonomy(self, row, model=VocabularyTopic, attr='taxonomies', attr_single='taxonomy'): + topics = [x.strip() for x in getattr(row, attr_single).split(';') if x.strip()] unlinked_topics = [] for t in topics: - topic = VocabularyTopic.get_topic(t) + topic = model.get_topic(t) if topic: - row.taxonomies.append(topic) + row[attr].append(topic) if not self.dry_run: - row.work.taxonomies.add(topic) + getattr(row.work, attr).add(topic) row.work.save_with_revision(self.user) else: unlinked_topics.append(t) if unlinked_topics: if self.dry_run: - row.notes.append(f'Taxonomy not found: {"; ".join(unlinked_topics)}') + + row.notes.append(f'{" ".join(attr_single.split("_")).capitalize()} not found: {"; ".join(unlinked_topics)}') else: row.unlinked_topics = "; ".join(unlinked_topics) try: @@ -934,33 +937,6 @@ def link_taxonomy(self, row): except Task.DoesNotExist: self.create_task(row.work, row, task_type='link-taxonomy') - def link_taxonomy_topic(self, row): - topics = [x.strip() for x in row.taxonomy_topic.split(',') if x.strip()] - unlinked_topics = [] - - for t in topics: - topic = TaxonomyTopic.objects.filter(slug=t).first() - if topic: - row.taxonomy_topics.append(topic) - if not self.dry_run: - row.work.taxonomy_topics.add(topic) - row.work.save_with_revision(self.user) - else: - unlinked_topics.append(t) - if unlinked_topics: - if self.dry_run: - row.notes.append(f'Taxonomy topic not found: {"; ".join(unlinked_topics)}') - else: - row.unlinked_topics = "; ".join(unlinked_topics) - try: - existing_task = Task.objects.get(work=row.work, code='link-taxonomy-topic', description__contains=row.unlinked_topics) - except Task.DoesNotExist: - self.create_task(row.work, row, task_type='link-taxonomy-topic') - - - - - def preview_task(self, row, task_type): task_preview = task_type.replace('-', ' ') if task_type == 'import-content': diff --git a/indigo_api/management/commands/migrate_taxonomies.py b/indigo_api/management/commands/migrate_taxonomies.py new file mode 100644 index 0000000000..b1d5add578 --- /dev/null +++ b/indigo_api/management/commands/migrate_taxonomies.py @@ -0,0 +1,21 @@ +from django.core.management import BaseCommand +from indigo_api.models import TaxonomyTopic, TaxonomyVocabulary, Work + + +class Command(BaseCommand): + def handle(self, *args, **kwargs): + for t in TaxonomyVocabulary.objects.all().iterator(): + root = TaxonomyTopic.add_root(name=t.title) + for vocabulary in t.topics.all(): + if vocabulary.level_1: + child = TaxonomyTopic.add_child(root, name=vocabulary.level_1) + if vocabulary.level_2: + TaxonomyTopic.add_child(child, name=vocabulary.level_2) + + for work in Work.objects.all().iterator(): + for taxonomy in work.taxonomies.all(): + topic = taxonomy.title + level_1 = taxonomy.level_1 + level_2 = taxonomy.level_2 + topics = TaxonomyTopic.objects.filter(name__in=[topic, level_1, level_2]) + work.taxonomy_topics.add(*topics) diff --git a/indigo_api/management/commands/taxonomies.py b/indigo_api/management/commands/taxonomies.py new file mode 100644 index 0000000000..ffc82cf8de --- /dev/null +++ b/indigo_api/management/commands/taxonomies.py @@ -0,0 +1,66 @@ +import argparse +import json +import sys + +from django.core.management import BaseCommand +from django.db import transaction + +from indigo_api.models import TaxonomyTopic + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument( + "--root", type=str, help="Root of the taxonomy to import or export" + ) + parser.add_argument( + "--import", action="store_true", help="Import the taxonomy tree" + ) + parser.add_argument( + "--export", action="store_true", help="Export the taxonomy tree" + ) + parser.add_argument( + "infile", + nargs="?", + type=argparse.FileType("r"), + default=sys.stdin, + help="File to import from (JSON)", + ) + parser.add_argument( + "outfile", + nargs="?", + type=argparse.FileType("w"), + default=sys.stdout, + help="File to export to (JSON)", + ) + + def handle(self, *args, **kwargs): + if kwargs["import"] and kwargs["export"]: + raise ValueError("Specify only one of --import or --export") + + with transaction.atomic(): + if kwargs["import"]: + self.do_import(**kwargs) + + if kwargs["export"]: + self.do_export(**kwargs) + + def do_import(self, **kwargs): + root_node = None + root = kwargs.get("root") + if root: + root_node = TaxonomyTopic.get_root_nodes().filter(name=root).first() + if not root_node: + root_node = TaxonomyTopic.add_root(name=root) + data = json.load(kwargs["infile"]) + TaxonomyTopic.load_bulk(data, parent=root_node) + + def do_export(self, **kwargs): + root_node = None + root = kwargs.get("root") + if root: + root_node = TaxonomyTopic.get_root_nodes().filter(name=root).first() + if not root_node: + raise ValueError("Root node not found: " + root) + data = TaxonomyTopic.dump_bulk(root_node, keep_ids=False) + json.dump(data, kwargs["outfile"]) diff --git a/indigo_api/migrations/0026_taxonomy_topic.py b/indigo_api/migrations/0026_taxonomy_topic.py index cad9308f76..8b529d35ba 100644 --- a/indigo_api/migrations/0026_taxonomy_topic.py +++ b/indigo_api/migrations/0026_taxonomy_topic.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-07-17 10:52 +# Generated by Django 3.2.13 on 2023-07-31 09:20 from django.db import migrations, models @@ -18,7 +18,7 @@ class Migration(migrations.Migration): ('depth', models.PositiveIntegerField()), ('numchild', models.PositiveIntegerField(default=0)), ('name', models.CharField(max_length=512)), - ('slug', models.SlugField(unique=True)), + ('slug', models.SlugField(max_length=512, unique=True)), ], options={ 'verbose_name': 'taxonomy topic', @@ -28,6 +28,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='work', name='taxonomy_topics', - field=models.ManyToManyField(related_name='works', to='indigo_api.TaxonomyTopic'), + field=models.ManyToManyField(blank=True, related_name='works', to='indigo_api.TaxonomyTopic'), ), ] diff --git a/indigo_api/models/works.py b/indigo_api/models/works.py index 45ca9fc9d6..8bb522645e 100644 --- a/indigo_api/models/works.py +++ b/indigo_api/models/works.py @@ -14,6 +14,8 @@ from reversion.models import Version from cobalt import FrbrUri, RepealEvent from treebeard.mp_tree import MP_Node +from django.urls import reverse +from django.http import QueryDict from indigo.plugins import plugins @@ -94,7 +96,7 @@ def get_topic(self, value): class TaxonomyTopic(MP_Node): name = models.CharField(max_length=512, null=False, blank=False) - slug = models.SlugField(null=False, unique=True, blank=False) + slug = models.SlugField(max_length=512, null=False, unique=True, blank=False) node_order_by = ['name'] class Meta: @@ -106,13 +108,43 @@ def __str__(self): @property def range_space(self): + # helper for adding space indents in templates return range(self.depth) + @classmethod + def get_topic(cls, value): + return cls.objects.filter(slug=value).first() + def save(self, *args, **kwargs): parent = self.get_parent() self.slug = (f"{parent.slug}-" if parent else "") + slugify(self.name) super().save(*args, **kwargs) + @classmethod + def get_toc_tree(cls, query_dict): + # capture all preserve all filter parameters and add taxonomy_topic + new_query = query_dict.copy() + new_query.pop('taxonomy_topic', None) + + def fix_up(item): + item["title"] = item["data"]["name"] + new_query.update({'taxonomy_topic': item['data']['slug']}) + item["href"] = f"?{new_query.urlencode()}" + new_query.pop('taxonomy_topic', None) + for kid in item.get("children", []): + fix_up(kid) + + tree = cls.dump_bulk() + for x in tree: + fix_up(x) + + tree = [{ + "title": "All topics", + "href": f"?{new_query.urlencode()}", + "children": tree + }] + return tree + class WorkMixin(object): """ Support methods that define behaviour for a work, independent of the database model. @@ -419,7 +451,7 @@ class Meta: # taxonomies taxonomies = models.ManyToManyField(VocabularyTopic, related_name='works') - taxonomy_topics = models.ManyToManyField(TaxonomyTopic, related_name='works') + taxonomy_topics = models.ManyToManyField(TaxonomyTopic, related_name='works', blank=True) as_at_date_override = models.DateField(null=True, blank=True, help_text="Date up to which this work was last checked for updates") consolidation_note_override = models.CharField(max_length=1024, null=True, blank=True, help_text='Consolidation note about this particular work, to override consolidation note for place') diff --git a/indigo_api/serializers.py b/indigo_api/serializers.py index 605ade8650..3647c9f998 100644 --- a/indigo_api/serializers.py +++ b/indigo_api/serializers.py @@ -629,18 +629,7 @@ def get_taxonomies(self, instance): return taxonomies def get_taxonomy_topics(self, instance): - taxonomies = [] - for t in instance.taxonomy_topics.all(): - taxonomies.append({ - "name": t.name, - "slug": t.slug - }) - for ancestor in t.get_ancestors(): - taxonomies.append({ - "name": ancestor.name, - "slug": ancestor.slug - }) - return taxonomies + return [t.slug for t in instance.taxonomy_topics.all()] class WorkAmendmentSerializer(serializers.ModelSerializer): diff --git a/indigo_app/forms.py b/indigo_app/forms.py index 897c07843f..b29c1030a7 100644 --- a/indigo_app/forms.py +++ b/indigo_app/forms.py @@ -303,6 +303,7 @@ class TaskFilterForm(forms.Form): submitted_by = forms.ModelMultipleChoiceField(queryset=User.objects) type = forms.MultipleChoiceField(choices=Task.CODES) country = forms.ModelMultipleChoiceField(queryset=Country.objects) + taxonomy_topic = forms.CharField() def __init__(self, country, *args, **kwargs): self.country = country @@ -338,6 +339,11 @@ def filter_queryset(self, queryset): queryset = queryset.filter(state__in=['pending_review', 'closed'])\ .filter(submitted_by_user__in=self.cleaned_data['submitted_by']) + if self.cleaned_data.get('taxonomy_topic'): + topic = TaxonomyTopic.objects.filter(slug=self.cleaned_data['taxonomy_topic']).first() + topics = [topic] + [t for t in topic.get_descendants()] + queryset = queryset.filter(work__taxonomy_topics__in=topics) + return queryset def data_as_url(self): @@ -380,6 +386,8 @@ class WorkFilterForm(forms.Form): advanced_filters = ['assent', 'publication', 'repeal', 'amendment', 'commencement', 'primary_subsidiary', 'taxonomies', 'completeness', 'status'] + taxonomy_topic = forms.CharField() + def __init__(self, country, *args, **kwargs): self.country = country super(WorkFilterForm, self).__init__(*args, **kwargs) @@ -511,6 +519,12 @@ def filter_queryset(self, queryset): end_date = self.cleaned_data['commencement_date_end'] queryset = queryset.filter(commencements__date__range=[start_date, end_date]).order_by('-commencements__date') + if self.cleaned_data.get('taxonomy_topic'): + topic = TaxonomyTopic.objects.filter(slug=self.cleaned_data['taxonomy_topic']).first() + if topic: + topics = [topic] + [t for t in topic.get_descendants()] + queryset = queryset.filter(taxonomy_topics__in=topics) + return queryset def filter_document_queryset(self, queryset): diff --git a/indigo_app/js/components/TaxonomyTOC.vue b/indigo_app/js/components/TaxonomyTOC.vue new file mode 100644 index 0000000000..1fc1f41d35 --- /dev/null +++ b/indigo_app/js/components/TaxonomyTOC.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/indigo_app/js/components/index.js b/indigo_app/js/components/index.js index d2d5ecdb83..8c2dca53ac 100644 --- a/indigo_app/js/components/index.js +++ b/indigo_app/js/components/index.js @@ -1,2 +1,3 @@ export { default as DocumentTOCView } from './DocumentTOCView.vue'; export { default as LinterPopup } from './LinterPopup.vue'; +export { default as TaxonomyTOC } from './TaxonomyTOC.vue'; diff --git a/indigo_app/static/javascript/indigo-app.js b/indigo_app/static/javascript/indigo-app.js index aa272b2fd8..365d52dba1 100644 --- a/indigo_app/static/javascript/indigo-app.js +++ b/indigo_app/static/javascript/indigo-app.js @@ -27,7 +27,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _enr /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"DocumentTOCView\": () => (/* reexport safe */ _DocumentTOCView_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]),\n/* harmony export */ \"LinterPopup\": () => (/* reexport safe */ _LinterPopup_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"])\n/* harmony export */ });\n/* harmony import */ var _DocumentTOCView_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./DocumentTOCView.vue */ \"./indigo_app/js/components/DocumentTOCView.vue\");\n/* harmony import */ var _LinterPopup_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./LinterPopup.vue */ \"./indigo_app/js/components/LinterPopup.vue\");\n\n\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"DocumentTOCView\": () => (/* reexport safe */ _DocumentTOCView_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]),\n/* harmony export */ \"LinterPopup\": () => (/* reexport safe */ _LinterPopup_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"]),\n/* harmony export */ \"TaxonomyTOC\": () => (/* reexport safe */ _TaxonomyTOC_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"])\n/* harmony export */ });\n/* harmony import */ var _DocumentTOCView_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./DocumentTOCView.vue */ \"./indigo_app/js/components/DocumentTOCView.vue\");\n/* harmony import */ var _LinterPopup_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./LinterPopup.vue */ \"./indigo_app/js/components/LinterPopup.vue\");\n/* harmony import */ var _TaxonomyTOC_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./TaxonomyTOC.vue */ \"./indigo_app/js/components/TaxonomyTOC.vue\");\n\n\n\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/index.js?"); /***/ }), @@ -272,6 +272,17 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css&": +/*!*********************************************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css& ***! + \*********************************************************************************************************************************************************************************************************************************************************/ +/***/ ((module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"\\n.active {\\n background-color: #2d7ad4;\\n color: white;\\n}\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib/index.js??vue-loader-options"); + +/***/ }), + /***/ "./node_modules/css-loader/dist/runtime/api.js": /*!*****************************************************!*\ !*** ./node_modules/css-loader/dist/runtime/api.js ***! @@ -338,6 +349,28 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./indigo_app/js/components/TaxonomyTOC.vue": +/*!**************************************************!*\ + !*** ./indigo_app/js/components/TaxonomyTOC.vue ***! + \**************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _TaxonomyTOC_vue_vue_type_template_id_f274e9d2___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./TaxonomyTOC.vue?vue&type=template&id=f274e9d2& */ \"./indigo_app/js/components/TaxonomyTOC.vue?vue&type=template&id=f274e9d2&\");\n/* harmony import */ var _TaxonomyTOC_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./TaxonomyTOC.vue?vue&type=script&lang=js& */ \"./indigo_app/js/components/TaxonomyTOC.vue?vue&type=script&lang=js&\");\n/* harmony import */ var _TaxonomyTOC_vue_vue_type_style_index_0_id_f274e9d2_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css& */ \"./indigo_app/js/components/TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css&\");\n/* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ \"./node_modules/vue-loader/lib/runtime/componentNormalizer.js\");\n\n\n\n;\n\n\n/* normalize component */\n\nvar component = (0,_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(\n _TaxonomyTOC_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n _TaxonomyTOC_vue_vue_type_template_id_f274e9d2___WEBPACK_IMPORTED_MODULE_0__.render,\n _TaxonomyTOC_vue_vue_type_template_id_f274e9d2___WEBPACK_IMPORTED_MODULE_0__.staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\n/* hot reload */\nif (false) { var api; }\ncomponent.options.__file = \"indigo_app/js/components/TaxonomyTOC.vue\"\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (component.exports);\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?"); + +/***/ }), + +/***/ "./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=script&lang=js&": +/*!**************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=script&lang=js& ***! + \**************************************************************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'TaxonomyTOC',\n data () {\n return {\n taxonomy_toc: JSON.parse(document.querySelector('#taxonomy_toc').textContent),\n };\n },\n mounted () {\n const params = new URLSearchParams(window.location.search);\n const toc = document.getElementsByTagName('la-table-of-contents-controller');\n toc[0].addEventListener('itemRendered', (e) => {\n const tocItem = e.target;\n if (!tocItem) return;\n const anchor = tocItem.querySelector('.content__action__title');\n const href = new URLSearchParams(anchor.getAttribute('href'));\n if (params.get('taxonomy_topic') === href.get('taxonomy_topic')) {\n anchor.classList.add('active');\n }\n });\n }\n});\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?./node_modules/vue-loader/lib/index.js??vue-loader-options"); + +/***/ }), + /***/ "./indigo_app/js/components/DocumentTOCView.vue?vue&type=script&lang=js&": /*!*******************************************************************************!*\ !*** ./indigo_app/js/components/DocumentTOCView.vue?vue&type=script&lang=js& ***! @@ -382,6 +415,28 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./indigo_app/js/components/TaxonomyTOC.vue?vue&type=script&lang=js&": +/*!***************************************************************************!*\ + !*** ./indigo_app/js/components/TaxonomyTOC.vue?vue&type=script&lang=js& ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TaxonomyTOC.vue?vue&type=script&lang=js& */ \"./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=script&lang=js&\");\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[\"default\"]); \n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?"); + +/***/ }), + +/***/ "./indigo_app/js/components/TaxonomyTOC.vue?vue&type=template&id=f274e9d2&": +/*!*********************************************************************************!*\ + !*** ./indigo_app/js/components/TaxonomyTOC.vue?vue&type=template&id=f274e9d2& ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* reexport safe */ _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_template_id_f274e9d2___WEBPACK_IMPORTED_MODULE_0__.render),\n/* harmony export */ \"staticRenderFns\": () => (/* reexport safe */ _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_template_id_f274e9d2___WEBPACK_IMPORTED_MODULE_0__.staticRenderFns)\n/* harmony export */ });\n/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_template_id_f274e9d2___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TaxonomyTOC.vue?vue&type=template&id=f274e9d2& */ \"./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=template&id=f274e9d2&\");\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?"); + +/***/ }), + /***/ "./indigo_app/js/components/DocumentTOCView.vue?vue&type=style&index=0&id=3c32905c&lang=css&": /*!***************************************************************************************************!*\ !*** ./indigo_app/js/components/DocumentTOCView.vue?vue&type=style&index=0&id=3c32905c&lang=css& ***! @@ -393,6 +448,17 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _nod /***/ }), +/***/ "./indigo_app/js/components/TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css&": +/*!***********************************************************************************************!*\ + !*** ./indigo_app/js/components/TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css& ***! + \***********************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_style_index_0_id_f274e9d2_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/vue-style-loader/index.js!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css& */ \"./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=style&index=0&id=f274e9d2&lang=css&\");\n/* harmony import */ var _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_style_index_0_id_f274e9d2_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_style_index_0_id_f274e9d2_lang_css___WEBPACK_IMPORTED_MODULE_0__);\n/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_style_index_0_id_f274e9d2_lang_css___WEBPACK_IMPORTED_MODULE_0__) if(__WEBPACK_IMPORT_KEY__ !== \"default\") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_vue_loader_lib_index_js_vue_loader_options_TaxonomyTOC_vue_vue_type_style_index_0_id_f274e9d2_lang_css___WEBPACK_IMPORTED_MODULE_0__[__WEBPACK_IMPORT_KEY__]\n/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?"); + +/***/ }), + /***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/DocumentTOCView.vue?vue&type=template&id=3c32905c&": /*!****************************************************************************************************************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/DocumentTOCView.vue?vue&type=template&id=3c32905c& ***! @@ -415,6 +481,17 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=template&id=f274e9d2&": +/*!************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options!./indigo_app/js/components/TaxonomyTOC.vue?vue&type=template&id=f274e9d2& ***! + \************************************************************************************************************************************************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function () {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"la-table-of-contents-controller\", {\n class: _vm.active,\n attrs: {\n \"collapse-all-btn-classes\": \"btn btn-sm btn-secondary\",\n \"expand-all-btn-classes\": \"btn btn-sm btn-secondary\",\n \"title-filter-clear-btn-classes\": \"btn btn-sm btn-secondary\",\n \"title-filter-input-classes\": \"form-field\",\n \"title-filter-placeholder\": \"Filter by topic\",\n },\n domProps: { items: _vm.taxonomy_toc },\n })\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://indigo/./indigo_app/js/components/TaxonomyTOC.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); + +/***/ }), + /***/ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js": /*!********************************************************************!*\ !*** ./node_modules/vue-loader/lib/runtime/componentNormalizer.js ***! @@ -436,6 +513,16 @@ eval("// style-loader: Adds some css to the DOM by adding a