Skip to content

Commit

Permalink
Incorp small UI paper review comments (#402)
Browse files Browse the repository at this point in the history
Closes #378 

- use taxon label instead of id in pheno explorer dropdown
- dedupe autocomplete case insensitive
- fix header search dropdown z-index
- scroll results into view on pheno explorer
- fix pheno explorer -> header search bug
- revise evidence select button and tooltips in association summary and
table views
- rename evidence section to associations details
- always show breadcrumbs section, show placeholder help message
- reorder node page sections
- rename details section to extra info and move to bottom of page
  • Loading branch information
vincerubinetti authored Oct 13, 2023
1 parent 3fad76e commit c45f839
Show file tree
Hide file tree
Showing 19 changed files with 172 additions and 126 deletions.
2 changes: 1 addition & 1 deletion frontend/src/api/phenotype-explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const getPhenotypes = async (search = ""): ReturnType<OptionsFunc> => {
: async () => await getPhenotypeAssociations(item.id),
highlight: item.highlight,
icon: "category-" + item.category,
info: item.in_taxon || "",
info: item.in_taxon_label || "",
})),
};
};
Expand Down
28 changes: 26 additions & 2 deletions frontend/src/api/search.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { SearchResults } from "@/api/model";
import { groupBy, uniq } from "lodash";
import type { SearchResult, SearchResults } from "@/api/model";
import { monarch, request } from "./index";

export type Filters = { [key: string]: string[] };
Expand All @@ -16,11 +17,34 @@ export const getSearch = async (
limit,
...filters,
});

return response;
};

type DedupedSearchResults = Omit<SearchResults, "items"> & {
items: (SearchResult & { dupes: string[] })[];
};

export const getAutocomplete = async (q: string) => {
const url = `${monarch}/autocomplete`;
const response = await request<SearchResults>(url, { q });
return response;

const transformedResponse: DedupedSearchResults = {
...response,
items: Object.values(
/** consolidate items */
groupBy(
response.items,
/** by name, case insensitively */
(item) => item.name.toLowerCase(),
),
).map((dupes) => ({
...dupes[0],
/** keep list of duplicated names */
/** de-dupe this list case sensitively */
dupes: uniq(dupes.map((dupe) => dupe.name)),
})),
};

return transformedResponse;
};
15 changes: 0 additions & 15 deletions frontend/src/api/source.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/src/components/AppCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function onChange(event: Event) {
display: inline-flex;
position: relative;
align-items: center;
padding: 2px 8px;
padding: 5px 10px;
gap: 10px;
border-radius: $rounded;
cursor: pointer;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/AppSelectAutocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ watch(highlighted, () => {
}

.list {
z-index: 1000;
z-index: 1020;
max-height: 300px;
overflow-x: auto;
overflow-y: auto;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/AppSelectMulti.vue
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ watch(
}

.list {
z-index: 1000;
z-index: 1020;
max-width: 90vw;
max-height: 300px;
overflow-x: auto;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/AppSelectSingle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ watch(
}

.list {
z-index: 1000;
z-index: 1020;
position: fixed;
max-width: 90vw;
max-height: 300px;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/about/PageCite.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
To link to a specific page or to algorithmic results presented on this
website, please use the URL in your browser's address bar. For example,
you would cite the prefixed identifier
<AppLink to="/disease/OMIM:154700">OMIM:154700</AppLink>
<AppLink to="/OMIM:154700">OMIM:154700</AppLink>
as:
</p>
<blockquote>
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/pages/about/PageTerms.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
>3-Clause BSD License</AppLink
>. Licensing information for the data sources and ontologies that make up
the Monarch knowledge graph can be found on the
<AppLink to="/sources">sources page</AppLink>. Licensing information for
tools, APIs, algorithms, and workflows can be found on the
<AppLink to="/overview">overview page</AppLink>.
<AppLink to="https://monarch-initiative.github.io/monarch-ingest/Sources"
>sources page</AppLink
>. Licensing information for tools, APIs, algorithms, and workflows can be
found on the <AppLink to="/overview">overview page</AppLink>.
</p>
<AppHeading>Tracking</AppHeading>
<p>
Expand Down
16 changes: 15 additions & 1 deletion frontend/src/pages/explore/TabPhenotypeExplorer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,17 @@
v-if="bMode.id.includes('these phenotypes')"
text="Analyze"
icon="bars-progress"
:disabled="isLoading || !aPhenotypes.length || !bPhenotypes.length"
@click="runAnalysis"
/>
<AppAlert v-else
>This feature is still being worked on. Check back soon!</AppAlert
>
</AppSection>

<AppSection>
<AppSection v-if="comparison.summary.length || isLoading || isError">
<AppHeading>Results</AppHeading>

<!-- analysis status -->
<AppStatus v-if="isLoading" code="loading">Running analysis</AppStatus>
<AppStatus v-if="isError" code="error">Error running analysis</AppStatus>
Expand Down Expand Up @@ -132,7 +135,9 @@ import type { Option, Options } from "@/components/AppSelectTags.vue";
import AppSelectTags from "@/components/AppSelectTags.vue";
import ThePhenogrid from "@/components/ThePhenogrid.vue";
import { snackbar } from "@/components/TheSnackbar.vue";
import { scrollToElement } from "@/router";
import { useQuery } from "@/util/composables";
import { waitFor } from "@/util/dom";
import { parse } from "@/util/object";
import examples from "./phenotype-explorer.json";

Expand Down Expand Up @@ -207,6 +212,8 @@ const {
isError,
} = useQuery(
async function () {
scrollToResults();

// /** run appropriate analysis based on selected mode */
// if (bMode.value.id.includes("these phenotypes"))
return await compareSetToSet(
Expand All @@ -222,8 +229,15 @@ const {

/** default value */
{ summary: [], phenogrid: { cols: [], rows: [], cells: {}, unmatched: [] } },

scrollToResults,
);

/** scroll results into view */
async function scrollToResults() {
scrollToElement(await waitFor("#results"));
}

/** when multi select component runs spread options function */
function spreadOptions(option: Option, options: Options, set: string) {
/** notify */
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/pages/explore/TabSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,11 @@ async function runGetAutocomplete(
/** if something typed in, get autocomplete options from backend */
if (search.trim())
return (await getAutocomplete(search)).items.map((item) => ({
label: item.name,
icon: getCategoryIcon(item.category),
label: item.name.toLowerCase(),
tooltip: "",
info:
/** show duplicates for gene symbols */
item.name === item.symbol ? item.dupes.join(" / ") : undefined,
}));

/**
Expand Down Expand Up @@ -368,7 +370,7 @@ watch(search, async () => {
const query: { [key: string]: string } = {};
if (search.value) query.search = search.value;
/** navigate to explore page */
await router.push({ ...route, name: "Explore", query });
await router.push({ ...route, name: "Explore", query, hash: "#search" });
});

/** when start page changes */
Expand Down
16 changes: 9 additions & 7 deletions frontend/src/pages/node/AssociationsSummary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
:key="index"
class="result"
>
<AppFlex direction="col" align-h="left" gap="small" class="details">
<AppFlex direction="col" align-h="left" gap="small" class="info">
<AppNodeBadge
:node="{
id: item.subject,
Expand All @@ -46,11 +46,13 @@
<AppButton
v-tooltip="
item.id === association?.id
? 'Viewing supporting evidence. Click again to hide.'
: 'View supporting evidence for this association'
? 'Deselect this association'
: `Show evidence (${
item.evidence_count || 0
}) and other info about this association`
"
class="evidence"
:text="`Evidence (${item?.evidence_count || 0})`"
class="details"
text="Details"
:aria-pressed="item.id === association?.id"
:icon="item.id === association?.id ? 'check' : 'flask'"
:color="item.id === association?.id ? 'primary' : 'secondary'"
Expand Down Expand Up @@ -202,13 +204,13 @@ onMounted(getAssociations);
color: $gray;
}

.details {
.info {
flex-grow: 1;
width: 0;
text-align: left;
}

.evidence {
.details {
min-width: unset !important;
min-height: unset !important;
}
Expand Down
16 changes: 8 additions & 8 deletions frontend/src/pages/node/AssociationsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@
/>
</template>

<!-- button to show evidence -->
<template #evidence="{ cell, row }">
<!-- button to show details -->
<template #details="{ cell, row }">
<AppButton
v-tooltip="
row.id === association?.id
? 'Viewing supporting evidence. Click again to hide.'
: 'View supporting evidence for this association'
? `Show evidence (${row.evidence_count}) and other info about this association`
: 'Deselect this association'
"
class="evidence"
class="details"
:text="String(cell || 0)"
:aria-pressed="row.id === association?.id"
:icon="row.id === association?.id ? 'check' : 'flask'"
Expand Down Expand Up @@ -166,9 +166,9 @@ const cols = computed((): Cols<Datum> => {
sortable: true,
},
{
slot: "evidence",
slot: "details",
key: "evidence_count",
heading: "Evidence",
heading: "Details",
width: 1,
align: "center",
sortable: true,
Expand Down Expand Up @@ -317,7 +317,7 @@ onMounted(() => queryAssociations(true));
color: $gray;
}

.evidence {
.details {
width: 100%;
min-height: unset !important;
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/node/PageNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
<template v-else-if="node">
<SectionTitle :node="node" />
<SectionOverview :node="node" />
<SectionDetails :node="node" />
<SectionHierarchy :node="node" />
<SectionVisualization :node="node" />
<SectionAssociations :node="node" />
<SectionBreadcrumbs :node="node" />
<SectionHierarchy :node="node" />
<SectionExtra :node="node" />
<Teleport to="body">
<TheTableOfContents />
</Teleport>
Expand All @@ -46,7 +46,7 @@ import SectionBreadcrumbs from "@/pages/node/SectionBreadcrumbs.vue";
import { scrollToHash } from "@/router";
import { useQuery } from "@/util/composables";
import SectionAssociations from "./SectionAssociations.vue";
import SectionDetails from "./SectionDetails.vue";
import SectionExtra from "./SectionExtra.vue";
import SectionHierarchy from "./SectionHierarchy.vue";
import SectionOverview from "./SectionOverview.vue";
import SectionTitle from "./SectionTitle.vue";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<!--
node page associations section, viewer for supporting evidence of an
association
node page association details section, viewer for supporting evidence of an
association
-->

<template>
<AppSection>
<AppHeading icon="flask">Evidence</AppHeading>
<AppHeading icon="flask">Association Details</AppHeading>

<div>
Evidence for the selected association, <br />
Details for the selected association, <br />
<AppNodeBadge
:node="{
id: association.subject,
Expand Down Expand Up @@ -91,9 +91,9 @@ type Props = {

const props = defineProps<Props>();

/** scroll evidence section into view */
/** scroll details section into view */
async function scrollIntoView() {
scrollToElement(await waitFor("#evidence"));
scrollToElement(await waitFor("#association-details"));
}

watch(() => props.association, scrollIntoView);
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/pages/node/SectionAssociations.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@
</template>
</AppSection>

<!-- evidence viewer of association -->
<EvidenceViewer v-if="association" :node="node" :association="association" />
<!-- details viewer of association -->
<SectionAssociationDetails
v-if="association"
:node="node"
:association="association"
/>
</template>

<script setup lang="ts">
Expand All @@ -70,7 +74,7 @@ import AppSelectSingle from "@/components/AppSelectSingle.vue";
import AppTabs from "@/components/AppTabs.vue";
import AssociationsSummary from "@/pages/node/AssociationsSummary.vue";
import AssociationsTable from "@/pages/node/AssociationsTable.vue";
import EvidenceViewer from "@/pages/node/EvidenceViewer.vue";
import SectionAssociationDetails from "@/pages/node/SectionAssociationDetails.vue";
import { scrollToHash } from "@/router";

/** route info */
Expand Down
Loading

0 comments on commit c45f839

Please sign in to comment.