@abi-software/map-side-bar 2.14.8-demo.2 → 2.14.8-demo.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-side-bar",
3
- "version": "2.14.8-demo.2",
3
+ "version": "2.14.8-demo.4",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -152,8 +152,16 @@
152
152
  </div>
153
153
  <div v-if="cellType.relatedCells?.length" class="card-section">
154
154
  <div class="card-section-title">Related Species Variants</div>
155
- <ul v-for="relatedCell in cellType.relatedCells" :key="relatedCell">
156
- <li>{{ relatedCell.label }}</li>
155
+ <ul class="related-cell-list">
156
+ <li v-for="relatedCell in cellType.relatedCells" :key="relatedCell">
157
+ <button
158
+ class="related-cell-item"
159
+ @click.stop="$emit('related-cell-click', relatedCell)"
160
+ title="Click to view this cell type"
161
+ >
162
+ {{ relatedCell.label }}
163
+ </button>
164
+ </li>
157
165
  </ul>
158
166
  </div>
159
167
  <div v-if="cellType.sourceNomenclature" class="card-section source-publication-section">
@@ -236,7 +244,7 @@ export default {
236
244
  default: false,
237
245
  },
238
246
  },
239
- emits: ['open', 'close', 'soma-location-hovered', 'dataset-search', 'connectivity-search'],
247
+ emits: ['open', 'close', 'soma-location-hovered', 'dataset-search', 'connectivity-search', 'related-cell-click'],
240
248
  data() {
241
249
  return {
242
250
  cardElement: null,
@@ -741,6 +749,11 @@ export default {
741
749
  margin: 0;
742
750
  padding-left: 1rem;
743
751
 
752
+ &.related-cell-list {
753
+ list-style-type: none;
754
+ padding-left: 0;
755
+ }
756
+
744
757
  li {
745
758
  color: #606266;
746
759
  }
@@ -955,4 +968,27 @@ export default {
955
968
  }
956
969
  }
957
970
  }
971
+
972
+ .related-cell-list {
973
+ li + li {
974
+ margin-top: 0.5rem;
975
+ }
976
+ }
977
+
978
+ .related-cell-item {
979
+ cursor: pointer;
980
+ color: $app-primary-color;
981
+ background: none;
982
+ border: 1px solid $app-primary-color;
983
+ border-radius: 4px;
984
+ padding: 2px 4px;
985
+ font-family: inherit;
986
+ font-size: inherit;
987
+ line-height: inherit;
988
+ transition: background-color 0.2s ease, border-color 0.2s ease, text-decoration-color 0.2s ease;
989
+
990
+ &:hover {
991
+ background-color: rgba($app-primary-color, 0.08);
992
+ }
993
+ }
958
994
  </style>
@@ -92,6 +92,7 @@
92
92
  @dataset-search="onDatasetSearch"
93
93
  @connectivity-search="onConnectivitySearch"
94
94
  @soma-location-hovered="showSomaLocation"
95
+ @related-cell-click="onRelatedCellClick"
95
96
  />
96
97
  <el-pagination
97
98
  class="pagination"
@@ -608,8 +609,8 @@ export default {
608
609
  const selectedSomaLocationFilters = this.getSelectedSomaLocationFilters();
609
610
  const shouldFilterBySelectedSomaLocations = (this.activeFilters || []).length > 0 && selectedSomaLocationFilters.length > 0;
610
611
  const selectedSomaLocationSet = new Set(selectedSomaLocationFilters);
611
- const scopedCellTypes = this.getCellTypesForActiveSpecies();
612
- const somaLocationCounts = scopedCellTypes.reduce((counts, cellType) => {
612
+ const filteredCellTypes = this.getFilteredCellTypes(this.activeFilters, this.searchInput);
613
+ const somaLocationCounts = filteredCellTypes.reduce((counts, cellType) => {
613
614
  (Array.isArray(cellType?.somaLocations) ? cellType.somaLocations : []).forEach((location) => {
614
615
  const normalizedLocation = String(location || '').trim().toLowerCase();
615
616
  if (!normalizedLocation) return;
@@ -703,8 +704,8 @@ export default {
703
704
 
704
705
  return false;
705
706
  },
706
- applyFilters: function(filters) {
707
- const searchTerms = this.normalizeSearchTerms(this.searchInput);
707
+ getFilteredCellTypes: function(filters = this.activeFilters, searchInput = this.searchInput) {
708
+ const searchTerms = this.normalizeSearchTerms(searchInput);
708
709
  const activeFilters = (filters || []).filter((filter) => {
709
710
  return filter?.term && filter?.facet && this.normalizeFacetValue(filter.facet) !== 'show all';
710
711
  });
@@ -720,11 +721,16 @@ export default {
720
721
 
721
722
  const filterGroups = Object.values(filtersByTerm);
722
723
 
723
- const filtered = this.allCellTypes.filter((cellType) => {
724
- return filterGroups.every((termGroup) => {
725
- return termGroup.some((filter) => this.matchFieldFilter(cellType, filter));
726
- });
727
- }).filter((cellType) => this.matchSearchQuery(cellType, searchTerms));
724
+ return this.allCellTypes
725
+ .filter((cellType) => {
726
+ return filterGroups.every((termGroup) => {
727
+ return termGroup.some((filter) => this.matchFieldFilter(cellType, filter));
728
+ });
729
+ })
730
+ .filter((cellType) => this.matchSearchQuery(cellType, searchTerms));
731
+ },
732
+ applyFilters: function(filters) {
733
+ const filtered = this.getFilteredCellTypes(filters, this.searchInput);
728
734
 
729
735
  this.totalFilteredCount = filtered.length;
730
736
  this.cellTypes = filtered.slice(this.start, this.start + this.numberPerPage);
@@ -739,6 +745,52 @@ export default {
739
745
  tabType: "cellType",
740
746
  });
741
747
  },
748
+ onRelatedCellClick: function(relatedCell) {
749
+ const species = relatedCell.species;
750
+ const label = relatedCell.label;
751
+
752
+ // Normalize species (e.g., "human male" -> "human")
753
+ const normalizedSpecies = this.normalizeActiveSpeciesFilterTerm(species);
754
+
755
+ // Check if this species filter already exists
756
+ const speciesFilterExists = this.activeFilters.some(function(filter) {
757
+ return this.normalizeFacetValue(filter.term) === 'species'
758
+ && this.normalizeFacetValue(filter.facet) === this.normalizeFacetValue(normalizedSpecies);
759
+ }, this);
760
+
761
+ // Add species filter if not already present
762
+ if (!speciesFilterExists && normalizedSpecies) {
763
+ this.activeFilters.push({
764
+ facetPropPath: 'species',
765
+ facet: capitalise(normalizedSpecies),
766
+ term: 'Species',
767
+ tagLabel: capitalise(normalizedSpecies),
768
+ });
769
+ }
770
+
771
+ // Clear search input to avoid text search interfering
772
+ this.searchInput = '';
773
+ this.page = 1;
774
+ this.start = 0;
775
+
776
+ // Apply filters and sync cascader UI
777
+ this.applyFilters(this.activeFilters);
778
+ this.syncCascaderFromActiveFilters();
779
+ this.emitSomaLocations(this.filterOptions);
780
+
781
+ // Find the matching cell type by preferredLabel and open its card
782
+ const matchingCellType = this.allCellTypes.find(function(ct) {
783
+ return (ct.preferredLabel || '').toLowerCase() === (label || '').toLowerCase();
784
+ });
785
+
786
+ if (matchingCellType) {
787
+ this.activeCardId = matchingCellType.id;
788
+ }
789
+
790
+ this.$nextTick(function() {
791
+ this.scrollToTop();
792
+ });
793
+ },
742
794
  showSomaLocation: function (name) {
743
795
  this.$emit('soma-location-hovered', name);
744
796
  },