@sfgrp/taxonpages 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/README.markdown +432 -0
  2. package/bin/taxonpages.js +78 -0
  3. package/index.html +22 -0
  4. package/package.json +82 -0
  5. package/postcss.config.cjs +17 -0
  6. package/server.js +142 -0
  7. package/src/App.vue +31 -0
  8. package/src/assets/css/leaflet.css +24 -0
  9. package/src/assets/css/main.css +23 -0
  10. package/src/assets/css/tailwind.css +3 -0
  11. package/src/assets/css/vars.css +58 -0
  12. package/src/assets/css/webkit.css +19 -0
  13. package/src/assets/images/taxonworks_full_logo.svg +22 -0
  14. package/src/assets/images/taxonworks_logo.svg +7 -0
  15. package/src/cli/commands/build.js +60 -0
  16. package/src/cli/commands/dev.js +48 -0
  17. package/src/cli/commands/init.js +65 -0
  18. package/src/cli/commands/preview.js +27 -0
  19. package/src/cli/commands/serve.js +26 -0
  20. package/src/cli/utils/resolveConfig.js +112 -0
  21. package/src/components/AddressMaker.global.vue +67 -0
  22. package/src/components/Animation/AnimationOpacity.global.vue +12 -0
  23. package/src/components/Autocomplete/Autocomplete.global.vue +223 -0
  24. package/src/components/Autocomplete/AutocompleteOtu.global.vue +33 -0
  25. package/src/components/Autocomplete/AutocompleteSpinner.vue +36 -0
  26. package/src/components/Button/ButtonExpand.global.vue +40 -0
  27. package/src/components/Button/VButton.global.vue +39 -0
  28. package/src/components/Card/VCard.global.vue +18 -0
  29. package/src/components/Card/VCardContent.global.vue +5 -0
  30. package/src/components/Card/VCardHeader.global.vue +7 -0
  31. package/src/components/Clipboard/VClipboard.global.vue +50 -0
  32. package/src/components/Dropdown/Dropdown.global.vue +108 -0
  33. package/src/components/Footer/FooterAnalytics.vue +26 -0
  34. package/src/components/Footer/FooterCitation.vue +45 -0
  35. package/src/components/Footer/FooterCopyright.vue +20 -0
  36. package/src/components/Gallery/GalleryCarousel/GalleryCarousel.global.vue +138 -0
  37. package/src/components/Gallery/GalleryImage.global.vue +65 -0
  38. package/src/components/Gallery/GalleryMainImage.vue +63 -0
  39. package/src/components/Gallery/GalleryMosaic/GalleryMosaic.global.vue +75 -0
  40. package/src/components/Gallery/GalleryThumbnail.vue +26 -0
  41. package/src/components/Gallery/GalleryThumbnailList.vue +34 -0
  42. package/src/components/Gallery/useGallery.js +50 -0
  43. package/src/components/Icon/IconArrowDown.global.vue +19 -0
  44. package/src/components/Icon/IconArrowLeft.global.vue +20 -0
  45. package/src/components/Icon/IconArrowRight.global.vue +20 -0
  46. package/src/components/Icon/IconArrowUp.global.vue +16 -0
  47. package/src/components/Icon/IconCalendar.global.vue +25 -0
  48. package/src/components/Icon/IconCheck.global.vue +16 -0
  49. package/src/components/Icon/IconClipboard.global.vue +16 -0
  50. package/src/components/Icon/IconClose.global.vue +20 -0
  51. package/src/components/Icon/IconDocument.global.vue +20 -0
  52. package/src/components/Icon/IconDownload.global.vue +16 -0
  53. package/src/components/Icon/IconFiles.global.vue +23 -0
  54. package/src/components/Icon/IconGithub.global.vue +11 -0
  55. package/src/components/Icon/IconHamburger.global.vue +18 -0
  56. package/src/components/Icon/IconInformation.global.vue +16 -0
  57. package/src/components/Icon/IconJson.global.vue +14 -0
  58. package/src/components/Icon/IconMinusCircle.global.vue +19 -0
  59. package/src/components/Icon/IconPause.global.vue +16 -0
  60. package/src/components/Icon/IconPlay.global.vue +16 -0
  61. package/src/components/Icon/IconPlusCircle.global.vue +19 -0
  62. package/src/components/Icon/IconSearch.global.vue +19 -0
  63. package/src/components/Icon/IconSpeakerWave.global.vue +16 -0
  64. package/src/components/Icon/IconSpeakerX.global.vue +16 -0
  65. package/src/components/Icon/IconTrash.global.vue +16 -0
  66. package/src/components/Icon/IconWarning.global.vue +16 -0
  67. package/src/components/ImageViewer/ControlImageNext.vue +11 -0
  68. package/src/components/ImageViewer/ControlImagePrevious.vue +10 -0
  69. package/src/components/ImageViewer/ImageAttribution.vue +15 -0
  70. package/src/components/ImageViewer/ImageDepictions.vue +21 -0
  71. package/src/components/ImageViewer/ImageSource.vue +15 -0
  72. package/src/components/ImageViewer/ImageToolbar.vue +14 -0
  73. package/src/components/ImageViewer/ImageViewer.global.vue +197 -0
  74. package/src/components/ImageViewer/ImageViewerClose.vue +12 -0
  75. package/src/components/ImageViewer/ImageViewerCounter.vue +16 -0
  76. package/src/components/Input/InputText.global.vue +30 -0
  77. package/src/components/Input/SelectInput.global.vue +31 -0
  78. package/src/components/Layout/LayoutFooter.vue +67 -0
  79. package/src/components/Layout/LayoutHeader.vue +62 -0
  80. package/src/components/Map/VMap.client.vue +365 -0
  81. package/src/components/Map/constants/disableLayerOptions.js +7 -0
  82. package/src/components/Map/constants/index.js +1 -0
  83. package/src/components/Map/icons/AssertedDistribution.js +5 -0
  84. package/src/components/Map/icons/CollectionObject.js +5 -0
  85. package/src/components/Map/icons/FieldOccurrence.js +5 -0
  86. package/src/components/Map/icons/Georeference.js +5 -0
  87. package/src/components/Map/icons/TypeMaterial.js +5 -0
  88. package/src/components/Map/icons/index.js +5 -0
  89. package/src/components/Map/shapes/Absent.js +8 -0
  90. package/src/components/Map/shapes/Aggregate.js +7 -0
  91. package/src/components/Map/shapes/AssertedDistribution.js +7 -0
  92. package/src/components/Map/shapes/CollectionObject.js +5 -0
  93. package/src/components/Map/shapes/FieldOccurrence.js +5 -0
  94. package/src/components/Map/shapes/TypeMaterial.js +5 -0
  95. package/src/components/Map/shapes/index.js +6 -0
  96. package/src/components/Map/utils/addPatternToMap.js +45 -0
  97. package/src/components/Map/utils/geojsonOptions.js +62 -0
  98. package/src/components/Map/utils/makeTileFromConfiguration.js +31 -0
  99. package/src/components/Markdown/MarkdownLayout.global.vue +36 -0
  100. package/src/components/Modal/VModal.global.vue +107 -0
  101. package/src/components/Navbar/NavbarMenu.vue +36 -0
  102. package/src/components/Navbar/NavbarMobile.vue +93 -0
  103. package/src/components/Navbar/NavbarSubmenu.vue +112 -0
  104. package/src/components/Pagination/VPagination.global.vue +139 -0
  105. package/src/components/Pagination/VPaginationInfo.global.vue +36 -0
  106. package/src/components/ProjectStats.global.vue +69 -0
  107. package/src/components/Ssr/ClientOnly.global.vue +14 -0
  108. package/src/components/SwitchTheme.vue +86 -0
  109. package/src/components/Tab/TabItem.global.vue +20 -0
  110. package/src/components/Tab/TabMenu.global.vue +7 -0
  111. package/src/components/Table/VTable.global.vue +7 -0
  112. package/src/components/Table/VTableBody.global.vue +7 -0
  113. package/src/components/Table/VTableBodyCell.global.vue +7 -0
  114. package/src/components/Table/VTableBodyRow.global.vue +5 -0
  115. package/src/components/Table/VTableHeader.global.vue +7 -0
  116. package/src/components/Table/VTableHeaderCell.global.vue +7 -0
  117. package/src/components/Table/VTableHeaderRow.global.vue +5 -0
  118. package/src/components/TrackerReport.global.vue +92 -0
  119. package/src/components/VSkeleton.global.vue +48 -0
  120. package/src/components/VSpinner.global.vue +219 -0
  121. package/src/components/clientComponents.js +28 -0
  122. package/src/components/globalComponents.js +29 -0
  123. package/src/constants/configPaths.cjs +4 -0
  124. package/src/constants/defaultConfig.js +7 -0
  125. package/src/constants/objectTypes.js +8 -0
  126. package/src/entry-client.js +39 -0
  127. package/src/entry-server.js +114 -0
  128. package/src/layout/Application.vue +21 -0
  129. package/src/main.js +20 -0
  130. package/src/modules/DwCFilter/components/DropdownMenu.vue +79 -0
  131. package/src/modules/DwCFilter/components/Facet/FacetDistribution.vue +47 -0
  132. package/src/modules/DwCFilter/components/Facet/FacetInstitutionCode.vue +17 -0
  133. package/src/modules/DwCFilter/components/Facet/FacetOrder.vue +38 -0
  134. package/src/modules/DwCFilter/components/Facet/FacetTypeStatus.vue +35 -0
  135. package/src/modules/DwCFilter/components/FilterBar.vue +123 -0
  136. package/src/modules/DwCFilter/components/OtuModal/OtuModal.vue +177 -0
  137. package/src/modules/DwCFilter/components/OtuModal/RecordItems.vue +89 -0
  138. package/src/modules/DwCFilter/components/OtuModal/TabList.vue +32 -0
  139. package/src/modules/DwCFilter/router/index.js +7 -0
  140. package/src/modules/DwCFilter/utils/flattenParameters.js +20 -0
  141. package/src/modules/DwCFilter/views/index.vue +183 -0
  142. package/src/modules/ImageMatrix/components/ListImages.vue +54 -0
  143. package/src/modules/ImageMatrix/router/index.js +7 -0
  144. package/src/modules/ImageMatrix/services/Keys.js +9 -0
  145. package/src/modules/ImageMatrix/utils/makeImageObject.js +15 -0
  146. package/src/modules/ImageMatrix/views/id.vue +133 -0
  147. package/src/modules/bibliography/components/DropdownMenu.vue +53 -0
  148. package/src/modules/bibliography/components/Facet/FacetFullCitation.vue +0 -0
  149. package/src/modules/bibliography/components/OtuModal.vue +129 -0
  150. package/src/modules/bibliography/components/VSlider.vue +154 -0
  151. package/src/modules/bibliography/components/YearPicker.vue +40 -0
  152. package/src/modules/bibliography/router/index.js +7 -0
  153. package/src/modules/bibliography/utils/getPagination.js +7 -0
  154. package/src/modules/bibliography/views/index.vue +225 -0
  155. package/src/modules/home/router/index.js +8 -0
  156. package/src/modules/home/views/index.vue +11 -0
  157. package/src/modules/httpErrorPages/router/index.js +18 -0
  158. package/src/modules/httpErrorPages/view/404.vue +10 -0
  159. package/src/modules/httpErrorPages/view/500.vue +11 -0
  160. package/src/modules/interactiveKeys/router/index.js +7 -0
  161. package/src/modules/interactiveKeys/views/InteractiveKey.vue +108 -0
  162. package/src/modules/keys/components/MetadataModal.vue +53 -0
  163. package/src/modules/keys/router/index.js +7 -0
  164. package/src/modules/keys/views/keyId.vue +161 -0
  165. package/src/modules/news/adapters/makeNews.js +21 -0
  166. package/src/modules/news/components/NewsCard.vue +35 -0
  167. package/src/modules/news/components/NewsCategories.vue +31 -0
  168. package/src/modules/news/components/PinnedNews.vue +70 -0
  169. package/src/modules/news/components/WidgetNews.global.vue +53 -0
  170. package/src/modules/news/router/index.js +12 -0
  171. package/src/modules/news/services/News.js +11 -0
  172. package/src/modules/news/store/news.js +50 -0
  173. package/src/modules/news/utils/getPagination.js +7 -0
  174. package/src/modules/news/views/id.vue +77 -0
  175. package/src/modules/news/views/index.vue +69 -0
  176. package/src/modules/otus/components/Breadcrumb/Breadcrumb.vue +40 -0
  177. package/src/modules/otus/components/Breadcrumb/BreadcrumbDropdown.vue +57 -0
  178. package/src/modules/otus/components/CommonNames.vue +14 -0
  179. package/src/modules/otus/components/DWCDownload.vue +33 -0
  180. package/src/modules/otus/components/DataMap.vue +57 -0
  181. package/src/modules/otus/components/Export.vue +1 -0
  182. package/src/modules/otus/components/ExternalResources.vue +11 -0
  183. package/src/modules/otus/components/Panel/PanelBiologicalAssociations/PanelBiologicalAssociations.vue +184 -0
  184. package/src/modules/otus/components/Panel/PanelBiologicalAssociations/main.js +6 -0
  185. package/src/modules/otus/components/Panel/PanelBiologicalAssociations/utils/makeBiologicalAssociation.js +30 -0
  186. package/src/modules/otus/components/Panel/PanelContent/PanelContent.vue +58 -0
  187. package/src/modules/otus/components/Panel/PanelContent/PanelContentTopic.vue +42 -0
  188. package/src/modules/otus/components/Panel/PanelContent/main.js +6 -0
  189. package/src/modules/otus/components/Panel/PanelDescendants/DescendantsSynonymList.vue +21 -0
  190. package/src/modules/otus/components/Panel/PanelDescendants/DescendantsTree.vue +122 -0
  191. package/src/modules/otus/components/Panel/PanelDescendants/PanelDescendants.vue +82 -0
  192. package/src/modules/otus/components/Panel/PanelDescendants/main.js +6 -0
  193. package/src/modules/otus/components/Panel/PanelDropdown.vue +63 -0
  194. package/src/modules/otus/components/Panel/PanelGallery/PanelGallery.vue +42 -0
  195. package/src/modules/otus/components/Panel/PanelGallery/main.js +7 -0
  196. package/src/modules/otus/components/Panel/PanelKeys/PanelKeys.vue +103 -0
  197. package/src/modules/otus/components/Panel/PanelKeys/main.js +6 -0
  198. package/src/modules/otus/components/Panel/PanelMap/PanelMap.vue +124 -0
  199. package/src/modules/otus/components/Panel/PanelMap/clusters/Mixed.js +50 -0
  200. package/src/modules/otus/components/Panel/PanelMap/clusters/index.js +2 -0
  201. package/src/modules/otus/components/Panel/PanelMap/clusters/makeClusterIconFor.js +10 -0
  202. package/src/modules/otus/components/Panel/PanelMap/components/CachedMap.vue +118 -0
  203. package/src/modules/otus/components/Panel/PanelMap/components/DwcTable.vue +64 -0
  204. package/src/modules/otus/components/Panel/PanelMap/components/MapPopup.vue +34 -0
  205. package/src/modules/otus/components/Panel/PanelMap/components/Search/ListResults.vue +51 -0
  206. package/src/modules/otus/components/Panel/PanelMap/components/Search/OtuSearch.vue +167 -0
  207. package/src/modules/otus/components/Panel/PanelMap/components/Search/SearchBar.vue +27 -0
  208. package/src/modules/otus/components/Panel/PanelMap/composables/useGeojsonOptions.js +36 -0
  209. package/src/modules/otus/components/Panel/PanelMap/constants/index.js +1 -0
  210. package/src/modules/otus/components/Panel/PanelMap/constants/legend.js +30 -0
  211. package/src/modules/otus/components/Panel/PanelMap/main.js +6 -0
  212. package/src/modules/otus/components/Panel/PanelMap/store/useDistributionStore.js +130 -0
  213. package/src/modules/otus/components/Panel/PanelMap/utils/index.js +4 -0
  214. package/src/modules/otus/components/Panel/PanelMap/utils/isRankGroup.js +5 -0
  215. package/src/modules/otus/components/Panel/PanelMap/utils/makeGeoJSONFeature.js +13 -0
  216. package/src/modules/otus/components/Panel/PanelMap/utils/makeSegmentedCircle.js +37 -0
  217. package/src/modules/otus/components/Panel/PanelMap/utils/removeDuplicateShapes.js +40 -0
  218. package/src/modules/otus/components/Panel/PanelNomenclature/PanelCitationRow.vue +25 -0
  219. package/src/modules/otus/components/Panel/PanelNomenclature/PanelNomenclature.vue +97 -0
  220. package/src/modules/otus/components/Panel/PanelNomenclature/PanelNomenclatureShowMore.vue +22 -0
  221. package/src/modules/otus/components/Panel/PanelNomenclature/main.js +6 -0
  222. package/src/modules/otus/components/Panel/PanelNomenclature/splitList.js +14 -0
  223. package/src/modules/otus/components/Panel/PanelNomenclatureReferences/PanelNomenclatureReferences.vue +72 -0
  224. package/src/modules/otus/components/Panel/PanelNomenclatureReferences/PanelReferenceRow.vue +20 -0
  225. package/src/modules/otus/components/Panel/PanelNomenclatureReferences/main.js +6 -0
  226. package/src/modules/otus/components/Panel/PanelSounds/PanelSounds.vue +42 -0
  227. package/src/modules/otus/components/Panel/PanelSounds/components/AudioPlayer.vue +275 -0
  228. package/src/modules/otus/components/Panel/PanelSounds/components/PanelSoundRow.vue +21 -0
  229. package/src/modules/otus/components/Panel/PanelSounds/components/SoundObservations.vue +73 -0
  230. package/src/modules/otus/components/Panel/PanelSounds/components/TableObservations.vue +31 -0
  231. package/src/modules/otus/components/Panel/PanelSounds/constants/observationTypes.js +15 -0
  232. package/src/modules/otus/components/Panel/PanelSounds/main.js +7 -0
  233. package/src/modules/otus/components/Panel/PanelSounds/utils/index.js +5 -0
  234. package/src/modules/otus/components/Panel/PanelSounds/utils/makeContinuousObservation.js +5 -0
  235. package/src/modules/otus/components/Panel/PanelSounds/utils/makeMediaObservation.js +5 -0
  236. package/src/modules/otus/components/Panel/PanelSounds/utils/makeObservation.js +40 -0
  237. package/src/modules/otus/components/Panel/PanelSounds/utils/makePresenceAbsenceObservation.js +5 -0
  238. package/src/modules/otus/components/Panel/PanelSounds/utils/makeQualitativeObservation.js +5 -0
  239. package/src/modules/otus/components/Panel/PanelSounds/utils/makeSampleObservation.js +29 -0
  240. package/src/modules/otus/components/Panel/PanelSounds/utils/makeWorkingObservation.js +5 -0
  241. package/src/modules/otus/components/Panel/PanelStats/PanelStats.vue +160 -0
  242. package/src/modules/otus/components/Panel/PanelStats/main.js +6 -0
  243. package/src/modules/otus/components/Panel/PanelTypeDesignation/PanelTypeDesignation.vue +37 -0
  244. package/src/modules/otus/components/Panel/PanelTypeDesignation/main.js +8 -0
  245. package/src/modules/otus/components/Panel/PanelTypeSpecimen/PanelTypeSpecimen.vue +52 -0
  246. package/src/modules/otus/components/Panel/PanelTypeSpecimen/main.js +8 -0
  247. package/src/modules/otus/components/TaxaInfo.vue +38 -0
  248. package/src/modules/otus/composables/index.js +2 -0
  249. package/src/modules/otus/composables/useChildrenRoutes.js +32 -0
  250. package/src/modules/otus/composables/useUserLifeCycleHooks.js +24 -0
  251. package/src/modules/otus/constants/index.js +3 -0
  252. package/src/modules/otus/constants/layouts/index.js +1 -0
  253. package/src/modules/otus/constants/layouts/overview.js +23 -0
  254. package/src/modules/otus/constants/layouts.js +43 -0
  255. package/src/modules/otus/constants/rankGroups.js +5 -0
  256. package/src/modules/otus/constants/responseError.js +3 -0
  257. package/src/modules/otus/constants/typeOrder.js +11 -0
  258. package/src/modules/otus/helpers/useOtuPageRequest.js +19 -0
  259. package/src/modules/otus/router/index.js +28 -0
  260. package/src/modules/otus/services/TaxonWorks.js +77 -0
  261. package/src/modules/otus/store/request.js +34 -0
  262. package/src/modules/otus/store/store.js +92 -0
  263. package/src/modules/otus/store/useImageStore.js +57 -0
  264. package/src/modules/otus/utils/index.js +2 -0
  265. package/src/modules/otus/utils/isAvailableForRank.js +6 -0
  266. package/src/modules/otus/utils/stripHtml.js +5 -0
  267. package/src/modules/otus/views/Index.vue +218 -0
  268. package/src/modules/otus/views/PageLayout.vue +78 -0
  269. package/src/modules/setup/views/Index.vue +66 -0
  270. package/src/plugins/markdown/index.js +2 -0
  271. package/src/plugins/markdown/relativeToRouter.js +51 -0
  272. package/src/plugins/markdown/variableReplacement.js +14 -0
  273. package/src/plugins/schemaOrg/composables/index.js +28 -0
  274. package/src/plugins/schemaOrg/index.js +31 -0
  275. package/src/plugins/schemaOrg/loadResolver.js +10 -0
  276. package/src/plugins/schemaOrg/nodes/Taxon.js +82 -0
  277. package/src/plugins/schemaOrg/nodes/index.js +1 -0
  278. package/src/plugins/vite/index.js +2 -0
  279. package/src/plugins/vite/projectStyle.js +29 -0
  280. package/src/plugins/vite/restart.js +30 -0
  281. package/src/router/index.js +46 -0
  282. package/src/ssr/utils/generateConsoleMessage.js +16 -0
  283. package/src/ssr/utils/registerFakeClientComponents.js +20 -0
  284. package/src/ssr/utils/taxonPagesMark.txt +9 -0
  285. package/src/store/index.js +1 -0
  286. package/src/store/useFooterStore.js +13 -0
  287. package/src/utils/color.js +9 -0
  288. package/src/utils/files.js +21 -0
  289. package/src/utils/globalVars.js +7 -0
  290. package/src/utils/index.js +5 -0
  291. package/src/utils/loadConfiguration.js +34 -0
  292. package/src/utils/loadLayouts.js +21 -0
  293. package/src/utils/parseEnvConfig.js +0 -0
  294. package/src/utils/request.js +18 -0
  295. package/src/utils/strings.js +12 -0
  296. package/src/utils/url.js +8 -0
  297. package/tailwind.config.cjs +92 -0
  298. package/templates/config/analytics.yml.example +22 -0
  299. package/templates/config/api.yml +5 -0
  300. package/templates/config/copyright.yml +5 -0
  301. package/templates/config/header.yml +17 -0
  302. package/templates/config/maps.yml +16 -0
  303. package/templates/config/metadata.yml +10 -0
  304. package/templates/config/news.yml.example +15 -0
  305. package/templates/config/project.yml +6 -0
  306. package/templates/config/router.yml.example +4 -0
  307. package/templates/config/style/theme.css +48 -0
  308. package/templates/config/taxa_page.yml.example +22 -0
  309. package/templates/config/tracker.yml.example +8 -0
  310. package/templates/pages/about.md +44 -0
  311. package/templates/pages/home.md +26 -0
  312. package/vite.config.js +92 -0
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <div class="relative">
3
+ <div>
4
+ <button
5
+ class="inline-flex items-center text-sm hover:text-gray-900 text-primary-500 dark:hover:text-gray-500"
6
+ @click="dropdownOpen = !dropdownOpen"
7
+ >
8
+ <slot />
9
+ <svg
10
+ class="h-5 w-5 text-primary-500 print:hidden"
11
+ xmlns="http://www.w3.org/2000/svg"
12
+ viewBox="0 0 20 20"
13
+ fill="currentColor"
14
+ >
15
+ <path
16
+ fill-rule="evenodd"
17
+ d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
18
+ clip-rule="evenodd"
19
+ />
20
+ </svg>
21
+ </button>
22
+
23
+ <div
24
+ v-if="dropdownOpen"
25
+ class="fixed inset-0 h-full w-full z-10"
26
+ @click="dropdownOpen = false"
27
+ />
28
+
29
+ <div
30
+ v-if="dropdownOpen"
31
+ class="absolute right-0 py-2 bg-white dark:bg-gray-900 rounded-md shadow-xl z-20"
32
+ >
33
+ <router-link
34
+ v-for="otu in list"
35
+ :key="otu.id"
36
+ class="block px-4 py-2 text-sm capitalize hover:bg-secondary-color hover:bg-opacity-5"
37
+ :to="{ name: 'otus-id', params: { id: otu.id } }"
38
+ >
39
+ {{ otu.name || key }}
40
+ </router-link>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </template>
45
+
46
+ <script setup>
47
+ import { ref } from 'vue'
48
+
49
+ const props = defineProps({
50
+ list: {
51
+ type: Array,
52
+ required: true
53
+ }
54
+ })
55
+
56
+ const dropdownOpen = ref(false)
57
+ </script>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <span>{{ commonNameLabel }}</span>
3
+ </template>
4
+
5
+ <script setup>
6
+ import { computed } from 'vue'
7
+ import { useOtuStore } from '../store/store'
8
+
9
+ const store = useOtuStore()
10
+
11
+ const commonNameLabel = computed(() =>
12
+ store.taxonomy.commonNames.map((item) => item.name).join('; ')
13
+ )
14
+ </script>
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <VButton
3
+ primary
4
+ class="text-sm flex items-center"
5
+ title="Download DwC Occurrences"
6
+ @click="
7
+ () => {
8
+ downloadCSV()
9
+ }
10
+ "
11
+ >
12
+ <IconDownload class="w-4 h-4 mr-1" />
13
+ DwC
14
+ </VButton>
15
+ </template>
16
+
17
+ <script setup>
18
+ const { url, project_token } = __APP_ENV__
19
+
20
+ const props = defineProps({
21
+ otu: {
22
+ type: Object,
23
+ required: true
24
+ }
25
+ })
26
+
27
+ function downloadCSV() {
28
+ window.open(
29
+ `${url}/otus/${props.otu.id}/inventory/dwc.csv?project_token=${project_token}`,
30
+ '_self'
31
+ )
32
+ }
33
+ </script>
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <div>
3
+ <VButton
4
+ primary
5
+ class="text-sm md:flex items-center gap-1 hidden"
6
+ title="Links used to obtain the information present on this page in JSON format."
7
+ @click="isModalVisible = true"
8
+ >
9
+ <IconJson class="w-4 h-4" />
10
+ Datamap
11
+ </VButton>
12
+ <VModal
13
+ v-if="isModalVisible"
14
+ @close="isModalVisible = false"
15
+ >
16
+ <template #header>
17
+ <h3 class="font-medium">Datamap</h3>
18
+ </template>
19
+ <div class="p-4 pt-0">
20
+ <p class="text-sm mb-2">
21
+ The following links provide the information present on this page in
22
+ JSON format.
23
+ </p>
24
+
25
+ <VTable>
26
+ <VTableHeader>
27
+ <VTableHeaderRow>
28
+ <VTableHeaderCell> Request Key </VTableHeaderCell>
29
+ <VTableHeaderCell> URL </VTableHeaderCell>
30
+ </VTableHeaderRow>
31
+ </VTableHeader>
32
+ <VTableBody>
33
+ <VTableBodyRow
34
+ v-for="(item, key) in store.datamap"
35
+ :key="key"
36
+ >
37
+ <VTableBodyCell class="capitalize">{{
38
+ key.replaceAll(':', ' ')
39
+ }}</VTableBodyCell>
40
+ <VTableBodyCell
41
+ ><a :href="item">{{ item }}</a></VTableBodyCell
42
+ >
43
+ </VTableBodyRow>
44
+ </VTableBody>
45
+ </VTable>
46
+ </div>
47
+ </VModal>
48
+ </div>
49
+ </template>
50
+
51
+ <script setup>
52
+ import { ref } from 'vue'
53
+ import { useOtuPageRequestStore } from '../store/request'
54
+
55
+ const isModalVisible = ref(false)
56
+ const store = useOtuPageRequestStore()
57
+ </script>
@@ -0,0 +1 @@
1
+ <template />
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <VCard>
3
+ <h1>External resources</h1>
4
+ <ul class="text-sm">
5
+ <li />
6
+ </ul>
7
+ </VCard>
8
+ </template>
9
+
10
+ <script setup>
11
+ </script>
@@ -0,0 +1,184 @@
1
+ <template>
2
+ <VCard>
3
+ <ClientOnly>
4
+ <VSpinner v-if="isLoading" />
5
+ </ClientOnly>
6
+ <VCardHeader>
7
+ Biological associations ({{ pagination.total }})
8
+ </VCardHeader>
9
+ <VCardContent class="min-h-[6rem] overflow-x-auto">
10
+ <VPagination
11
+ v-if="biologicalAssociations.length"
12
+ class="mb-4"
13
+ v-model="pagination.page"
14
+ :total="pagination.total"
15
+ :per="pagination.per"
16
+ @select="
17
+ (value) => {
18
+ loadBiologicalAssociations(value)
19
+ }
20
+ "
21
+ />
22
+ <VTable v-if="biologicalAssociations.length">
23
+ <VTableHeader class="normal-case">
24
+ <VTableHeaderRow>
25
+ <VTableHeaderCell colspan="5">Subject</VTableHeaderCell>
26
+ <VTableHeaderCell class="border-l-2 border-r-2">
27
+ Biological
28
+ </VTableHeaderCell>
29
+ <VTableHeaderCell colspan="5">Object</VTableHeaderCell>
30
+ <VTableHeaderCell class="border-l-2" />
31
+ </VTableHeaderRow>
32
+ <VTableHeaderRow>
33
+ <VTableHeaderCell>Order</VTableHeaderCell>
34
+ <VTableHeaderCell>Family</VTableHeaderCell>
35
+ <VTableHeaderCell>Genus</VTableHeaderCell>
36
+ <VTableHeaderCell>Label</VTableHeaderCell>
37
+ <VTableHeaderCell>Properties</VTableHeaderCell>
38
+ <VTableHeaderCell class="border-l-2 border-r-2"
39
+ >Relationship</VTableHeaderCell
40
+ >
41
+ <VTableHeaderCell>Properties</VTableHeaderCell>
42
+ <VTableHeaderCell>Order</VTableHeaderCell>
43
+ <VTableHeaderCell>Family</VTableHeaderCell>
44
+ <VTableHeaderCell>Genus</VTableHeaderCell>
45
+ <VTableHeaderCell>Label</VTableHeaderCell>
46
+ <VTableHeaderCell class="border-l-2">Citations</VTableHeaderCell>
47
+ </VTableHeaderRow>
48
+ </VTableHeader>
49
+ <VTableBody>
50
+ <VTableBodyRow
51
+ v-for="ba in biologicalAssociations"
52
+ :key="ba.id"
53
+ >
54
+ <VTableBodyCell> {{ ba.subjectOrder }}</VTableBodyCell>
55
+ <VTableBodyCell> {{ ba.subjectFamily }}</VTableBodyCell>
56
+ <VTableBodyCell> {{ ba.subjectGenus }}</VTableBodyCell>
57
+ <VTableBodyCell>
58
+ <template v-if="ba.subjectType === 'Otu'">
59
+ <RouterLink
60
+ :to="{ name: 'otus-id', params: { id: ba.subjectId } }"
61
+ v-html="ba.subjectLabel"
62
+ />
63
+ </template>
64
+ <template v-else>
65
+ {{ ba.subjectLabel }}
66
+ </template>
67
+ </VTableBodyCell>
68
+ <VTableBodyCell> {{ ba.biologicalPropertySubject }}</VTableBodyCell>
69
+ <VTableBodyCell class="border-l-2 border-r-2">
70
+ {{ ba.biologicalRelationship }}
71
+ </VTableBodyCell>
72
+ <VTableBodyCell> {{ ba.biologicalPropertyObject }}</VTableBodyCell>
73
+ <VTableBodyCell> {{ ba.objectOrder }}</VTableBodyCell>
74
+ <VTableBodyCell> {{ ba.objectFamily }}</VTableBodyCell>
75
+ <VTableBodyCell> {{ ba.objectGenus }}</VTableBodyCell>
76
+ <VTableBodyCell>
77
+ <template v-if="ba.objectType === 'Otu'">
78
+ <RouterLink
79
+ :to="{ name: 'otus-id', params: { id: ba.objectId } }"
80
+ v-html="ba.objectLabel"
81
+ />
82
+ </template>
83
+ <template v-else>
84
+ {{ ba.objectLabel }}
85
+ </template>
86
+ </VTableBodyCell>
87
+ <VTableBodyCell
88
+ class="border-l-2"
89
+ v-html="ba.citations"
90
+ />
91
+ </VTableBodyRow>
92
+ </VTableBody>
93
+ </VTable>
94
+ <VPagination
95
+ v-if="biologicalAssociations.length"
96
+ class="mt-4"
97
+ v-model="pagination.page"
98
+ :total="pagination.total"
99
+ :per="pagination.per"
100
+ @select="
101
+ (value) => {
102
+ loadBiologicalAssociations(value)
103
+ }
104
+ "
105
+ />
106
+ <div
107
+ v-if="!isLoading && !biologicalAssociations.length"
108
+ class="text-xl text-center my-8 w-full"
109
+ >
110
+ No records found.
111
+ </div>
112
+ </VCardContent>
113
+ </VCard>
114
+ </template>
115
+
116
+ <script setup>
117
+ import { onMounted, ref } from 'vue'
118
+ import { makeAPIRequest } from '@/utils'
119
+ import { useOtuPageRequest } from '@/modules/otus/helpers/useOtuPageRequest.js'
120
+ import { makeBiologicalAssociation } from './utils/makeBiologicalAssociation.js'
121
+
122
+ const extend = [
123
+ 'object',
124
+ 'subject',
125
+ 'biological_relationship',
126
+ 'taxonomy',
127
+ 'biological_relationship_types'
128
+ ]
129
+
130
+ const props = defineProps({
131
+ otuId: {
132
+ type: Number,
133
+ required: true
134
+ },
135
+
136
+ per: {
137
+ type: Number,
138
+ default: 50
139
+ }
140
+ })
141
+
142
+ const biologicalAssociations = ref([])
143
+ const isLoading = ref(false)
144
+ const pagination = ref({
145
+ page: 1,
146
+ per: props.per,
147
+ total: 0
148
+ })
149
+
150
+ onMounted(() => {
151
+ loadBiologicalAssociations()
152
+ })
153
+
154
+ function loadBiologicalAssociations(page = 1) {
155
+ isLoading.value = true
156
+
157
+ useOtuPageRequest('panel:biological-associations', () =>
158
+ makeAPIRequest.get('/biological_associations/basic', {
159
+ params: {
160
+ 'otu_query[coordinatify]': true,
161
+ 'otu_query[otu_id][]': props.otuId,
162
+ per: pagination.value.per,
163
+ page,
164
+ extend
165
+ }
166
+ })
167
+ )
168
+ .then(async ({ data, headers }) => {
169
+ const items = data.map(makeBiologicalAssociation)
170
+
171
+ pagination.value = {
172
+ page: Number(headers['pagination-page']),
173
+ per: Number(headers['pagination-per-page']),
174
+ total: Number(headers['pagination-total'])
175
+ }
176
+
177
+ isLoading.value = false
178
+ biologicalAssociations.value = items
179
+ })
180
+ .catch(() => {
181
+ isLoading.value = false
182
+ })
183
+ }
184
+ </script>
@@ -0,0 +1,6 @@
1
+ import PanelBiologicalAssociations from './PanelBiologicalAssociations.vue'
2
+
3
+ export default {
4
+ id: 'panel:biological-associations',
5
+ component: PanelBiologicalAssociations
6
+ }
@@ -0,0 +1,30 @@
1
+ function getBiologicalProperty(biologicalRelationshipTypes, type) {
2
+ return biologicalRelationshipTypes.find((r) => r.target === type)
3
+ ?.biological_property?.name
4
+ }
5
+
6
+ function parseRank(rank) {
7
+ return Array.isArray(rank) ? rank.filter(Boolean).join(' ') : rank
8
+ }
9
+
10
+ export function makeBiologicalAssociation(data) {
11
+ return {
12
+ id: data.id,
13
+ subjectId: data.subject.id,
14
+ subjectType: data.subject.type,
15
+ subjectOrder: data.subject.order,
16
+ subjectFamily: data.subject.family,
17
+ subjectGenus: data.subject.genus,
18
+ subjectLabel: data.subject.label,
19
+ biologicalPropertySubject: data.subject.properties,
20
+ biologicalRelationship: data.relationship,
21
+ biologicalPropertyObject: data.object.properties,
22
+ objectId: data.object.id,
23
+ objectType: data.object.type,
24
+ objectOrder: data.object.order,
25
+ objectFamily: data.object.family,
26
+ objectGenus: data.object.genus,
27
+ objectLabel: data.object.label,
28
+ citations: data.citations
29
+ }
30
+ }
@@ -0,0 +1,58 @@
1
+ <template>
2
+ <VCard v-if="contents.length">
3
+ <ContentTopic
4
+ v-for="(text, title) in contentList"
5
+ :key="title"
6
+ :title="title"
7
+ :text-list="text"
8
+ />
9
+ </VCard>
10
+ </template>
11
+
12
+ <script setup>
13
+ import { computed, ref, onBeforeMount, onBeforeUnmount } from 'vue'
14
+ import { useOtuPageRequest } from '@/modules/otus/helpers/useOtuPageRequest'
15
+ import TaxonWorks from '../../../services/TaxonWorks'
16
+ import ContentTopic from './PanelContentTopic.vue'
17
+
18
+ const props = defineProps({
19
+ otuId: {
20
+ type: Number,
21
+ required: true
22
+ }
23
+ })
24
+
25
+ const contents = ref([])
26
+ const controller = new AbortController()
27
+
28
+ const contentList = computed(() =>
29
+ contents.value.reduce((acc, current) => {
30
+ if (acc[current.name]) {
31
+ acc[current.name].push(current.text)
32
+ } else {
33
+ acc[current.name] = [current.text]
34
+ }
35
+
36
+ return acc
37
+ }, {})
38
+ )
39
+
40
+ onBeforeMount(() => {
41
+ useOtuPageRequest('panel:content', () =>
42
+ TaxonWorks.getOtuContent(props.otuId, {
43
+ params: {
44
+ extend: ['depiction']
45
+ },
46
+ signal: controller.signal
47
+ })
48
+ )
49
+ .then(({ data }) => {
50
+ contents.value = data
51
+ })
52
+ .catch((e) => {})
53
+ })
54
+
55
+ onBeforeUnmount(() => {
56
+ controller.abort()
57
+ })
58
+ </script>
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <VCardHeader class="border-t border-base-muted first:border-t-0">
3
+ {{ title }}
4
+ </VCardHeader>
5
+ <VCardContent class="panel-content-list">
6
+ <div
7
+ v-for="(text, index) in textList"
8
+ :key="index"
9
+ class="pt-1 text-sm"
10
+ v-html="text"
11
+ ></div>
12
+ </VCardContent>
13
+ </template>
14
+
15
+ <script setup>
16
+ defineProps({
17
+ title: {
18
+ type: String,
19
+ required: true
20
+ },
21
+
22
+ textList: {
23
+ type: Array,
24
+ required: true
25
+ }
26
+ })
27
+ </script>
28
+
29
+ <style>
30
+ .panel-content-list {
31
+ ul {
32
+ margin: 1rem 0;
33
+ list-style: disc;
34
+ margin-left: 1rem;
35
+ }
36
+
37
+ ol {
38
+ list-style-type: decimal;
39
+ margin-left: 1rem;
40
+ }
41
+ }
42
+ </style>
@@ -0,0 +1,6 @@
1
+ import PanelContent from './PanelContent.vue'
2
+
3
+ export default {
4
+ id: 'panel:content',
5
+ component: PanelContent
6
+ }
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <ul class="synonyms">
3
+ <li
4
+ v-for="synonym in props.list"
5
+ :key="synonym"
6
+ >
7
+ <span class="text-orange-500 mr-1">=</span>
8
+ <span v-html="synonym" />
9
+ </li>
10
+ </ul>
11
+ </template>
12
+
13
+ <script setup>
14
+
15
+ const props = defineProps({
16
+ list: {
17
+ type: Array,
18
+ required: true
19
+ }
20
+ })
21
+ </script>
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <li
3
+ v-if="Object.keys(taxonomy).length"
4
+ :key="taxonomy.otu_id"
5
+ >
6
+ <button-expand
7
+ v-if="!taxonomy.leaf_node"
8
+ v-model="isTreeVisible"
9
+ class="absolute -left-2.5"
10
+ />
11
+ <router-link
12
+ class="text-primary-500"
13
+ :to="{ name: 'otus-id', params: { id: taxonomy.otu_id } }"
14
+ v-html="taxonomy.name"
15
+ />
16
+ <DescendantsSynonymList
17
+ v-if="taxonomy.nomenclatural_synonyms.length"
18
+ class="pb-4"
19
+ :list="taxonomy.nomenclatural_synonyms"
20
+ />
21
+ <AnimationOpacity>
22
+ <ul
23
+ v-if="descendants.length"
24
+ class="tree"
25
+ >
26
+ <template
27
+ v-for="item in descendants"
28
+ :key="item.otu_id"
29
+ >
30
+ <AnimationOpacity>
31
+ <DescendantsTree
32
+ v-if="isTreeVisible"
33
+ :taxonomy="item"
34
+ />
35
+ </AnimationOpacity>
36
+ </template>
37
+ </ul>
38
+ </AnimationOpacity>
39
+ </li>
40
+ </template>
41
+
42
+ <script setup>
43
+ import DescendantsTree from './DescendantsTree.vue'
44
+ import DescendantsSynonymList from './DescendantsSynonymList.vue'
45
+ import TaxonWorks from '../../../services/TaxonWorks'
46
+ import { ref, watch } from 'vue'
47
+
48
+ const props = defineProps({
49
+ taxonomy: {
50
+ type: Object,
51
+ required: true
52
+ },
53
+
54
+ level: {
55
+ type: Number,
56
+ default: 1
57
+ }
58
+ })
59
+
60
+ const isTreeVisible = ref(!!props.taxonomy.descendants.length)
61
+ const descendants = ref([...props.taxonomy.descendants])
62
+
63
+ watch(isTreeVisible, (newVal) => {
64
+ if (newVal) {
65
+ loadDescendants()
66
+ }
67
+ })
68
+
69
+ const loadDescendants = () => {
70
+ if (descendants.value.length) {
71
+ return
72
+ }
73
+ TaxonWorks.getTaxonomy(props.taxonomy.otu_id, {
74
+ params: {
75
+ max_descendants_depth: 1
76
+ }
77
+ })
78
+ .then(({ data }) => {
79
+ descendants.value = data.descendants
80
+ })
81
+ .catch(() => {})
82
+ }
83
+ </script>
84
+
85
+ <style lang="scss" scoped>
86
+ .tree {
87
+ list-style: none;
88
+ margin: 0;
89
+ padding: 0;
90
+
91
+ ul {
92
+ margin-left: 14px;
93
+ }
94
+
95
+ li {
96
+ position: relative;
97
+ margin: 0;
98
+ padding: 0px 6px;
99
+ border-left: 1px solid rgb(100, 100, 100);
100
+ }
101
+
102
+ li:last-child {
103
+ border-left: none;
104
+ }
105
+
106
+ li:before {
107
+ position: relative;
108
+ top: -0.3em;
109
+ height: 1em;
110
+ width: 12px;
111
+ color: white;
112
+ border-bottom: 1px solid rgb(100, 100, 100);
113
+ content: '';
114
+ display: inline-block;
115
+ left: -6px;
116
+ }
117
+
118
+ li:last-child:before {
119
+ border-left: 1px solid rgb(100, 100, 100);
120
+ }
121
+ }
122
+ </style>