Skip to content

Commit

Permalink
Show all association tables together (#775)
Browse files Browse the repository at this point in the history
Show all association tables at once on a node page rather than having to
select the association type from an option box. From the initial first
pass, I think the minimum to make this work is going to also include
making the page nav always visible and making sure it has scrollspy
functionality. This may turn into a longer lived PR if we find that we
need to tweak table content before we want to merge.
  • Loading branch information
kevinschaper authored Oct 4, 2024
1 parent 510a4a1 commit 2c878e8
Show file tree
Hide file tree
Showing 20 changed files with 254 additions and 323 deletions.
34 changes: 1 addition & 33 deletions frontend/e2e/node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,12 @@ test("Table of contents works", async ({ page }) => {
/table of contents/i,
);

/** starts closed (due to small screen size) */
await expect(page.locator(".toc button")).toHaveAttribute(
"aria-expanded",
"false",
);

/** click button to open */
await page.locator(".toc").click();
await expect(page.locator(".toc button")).toHaveAttribute(
"aria-expanded",
"true",
);

/** click off to close (with small screen size) */
await page.locator("body").click({ position: { x: 500, y: 500 } });
await expect(page.locator(".toc button")).toHaveAttribute(
"aria-expanded",
"false",
);

/** open again and check contents */
await page.locator(".toc").click();
await expect(
page.locator(".toc", { hasText: /Overview/i }).first(),
).toBeVisible();
await expect(
page.locator(".toc", { hasText: /Hierarchy/i }).first(),
).toBeVisible();
await expect(
page.locator(".toc", { hasText: /Associations/i }).first(),
).toBeVisible();

/** check if solo selection mode works */
await page.locator(".toc .checkbox").click();
await expect(
page
.locator("main")
.getByText(/Overview/i)
.getByText(/Ehlers-Danlos syndrome, hypermobility/i)
.first(),
).toBeVisible();
await expect(
Expand Down
2 changes: 1 addition & 1 deletion frontend/e2e/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test("Recent/frequent results show", async ({ page }) => {

for (const node of nodes) {
await page.goto("/" + node);
await expect(page.locator("#overview")).toBeVisible();
await expect(page.locator("#hierarchy")).toBeVisible();
}

await page.goto("/explore");
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/components/AppHeading.vue
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,13 @@ section.fill {
}
}
}
section.inset {
h1,
h2,
h3 {
margin-bottom: 1px;
padding-bottom: 3px;
border-bottom: 2px solid $theme;
}
}
</style>
7 changes: 3 additions & 4 deletions frontend/src/components/AppPredicateBadge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

<template>
<span class="predicate">
<AppIcon class="arrow" :icon="`arrow-${arrowDirection}`" />
<AppIcon v-if="arrows" class="arrow" :icon="`arrow-${arrowDirection}`" />
<span v-if="association.negated">NOT</span>
{{ startCase(getCategoryLabel(association.predicate)).toLowerCase() }}
<AppIcon class="arrow" :icon="`arrow-${arrowDirection}`" />
<AppIcon v-if="arrows" class="arrow" :icon="`arrow-${arrowDirection}`" />
</span>
</template>

Expand All @@ -24,6 +24,7 @@ type Props = {
reverse?: boolean;
/** whether to display arrows vertically */
vertical?: boolean;
arrows?: boolean;
};

const props = defineProps<Props>();
Expand All @@ -42,8 +43,6 @@ const arrowDirection = computed(() =>

<style lang="scss" scoped>
.predicate {
white-space: nowrap;

& > * {
white-space: normal;
overflow-wrap: anywhere;
Expand Down
52 changes: 43 additions & 9 deletions frontend/src/components/AppSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-->

<template>
<section :class="['section', width, design]">
<section :class="['section', width, design, alignment, { inset }, { node }]">
<slot />
</section>
</template>
Expand All @@ -14,10 +14,18 @@ type Props = {
/** width of section */
width?: "full" | "medium" | "big";
/** visual design */
design?: "normal" | "fill";
design?: "normal" | "fill" | "bare";
alignment?: "left" | "center";
inset?: boolean;
node?: boolean;
};

withDefaults(defineProps<Props>(), { width: "medium", design: "normal" });
withDefaults(defineProps<Props>(), {
width: "medium",
design: "normal",
alignment: "center",
inset: false,
});

type Slots = {
default: () => unknown;
Expand All @@ -30,21 +38,47 @@ defineSlots<Slots>();
.section {
display: flex;
flex-direction: column;
align-items: center;
gap: 40px;
text-align: center;
transition: background $fast;
&.center {
align-items: center;
gap: 40px;
text-align: center;
}

&.left {
align-items: flex-start;
gap: 20px;
text-align: left;
}

&.full {
padding: 50px 40px;
padding: 30px 20px;
}

&.node {
margin: 10px 20px 10px $toc-width + 20px !important;
}
&.inset {
padding: 30px 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

&.left {
margin: 10px 20px;
}

&.medium {
padding: 50px max(40px, calc((100% - $section) / 2));
&.center {
padding: 30px max(20px, calc((100% - $section) / 2));
}
&.left {
padding: 5px 15px;
}
}

&.big {
padding: 50px max(40px, calc((100% - $section-big) / 2));
padding: 30px 20px;
//padding: 30px max(20px, calc((100% - $section-big) / 2));
}

&.normal {
Expand Down
84 changes: 38 additions & 46 deletions frontend/src/components/AppTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

<template>
<!-- table data -->
<AppFlex direction="col" :class="['container', { expanded }]">
<div ref="scroll" class="scroll force-scrollbar">
<AppFlex direction="col" align-h="left" :class="['container']">
<div ref="scroll" style="width: 100%">
<table
class="table"
:aria-colcount="cols.length"
Expand Down Expand Up @@ -183,13 +183,6 @@
design="small"
@click="emitDownload"
/>
<AppButton
v-tooltip="expanded ? 'Collapse table' : 'Expand table to full width'"
:text="expanded ? 'Collapse' : 'Expand'"
:icon="expanded ? 'minimize' : 'maximize'"
design="small"
@click="expanded = !expanded"
/>
</div>
</div>
</AppFlex>
Expand Down Expand Up @@ -226,14 +219,11 @@ export type Sort<Key extends string = string> = {
</script>

<script setup lang="ts" generic="Datum extends object">
import { computed, watch, type VNode } from "vue";
import { useLocalStorage } from "@vueuse/core";
import { useScrollable } from "@/composables/use-scrollable";
import { computed, type VNode } from "vue";
import type { Options } from "./AppSelectMulti.vue";
import AppSelectMulti from "./AppSelectMulti.vue";
import AppSelectSingle from "./AppSelectSingle.vue";
import AppTextbox from "./AppTextbox.vue";
import { closeToc } from "./TheTableOfContents.vue";

/** possible keys on datum (remove number and symbol from default object type) */
type Keys = Extract<keyof Datum, string>;
Expand Down Expand Up @@ -306,13 +296,6 @@ defineSlots<{
[slot in SlotNames]: (props: SlotProps) => VNode;
}>();

/** whether table is expanded to be full width */
const expanded = useLocalStorage(`${props.id}-table-expanded`, false);

/** style scroll states */
const { ref: scroll, updateScroll } = useScrollable();
watch(expanded, updateScroll);

/** when user clicks to first page */
function clickFirst() {
emit("update:start", 0);
Expand Down Expand Up @@ -390,28 +373,18 @@ const ariaSort = computed(() => {
if (props.sort?.direction === "down") return "descending";
return "none";
});

/** close table of contents when expanding or starting expanded */
watch(
expanded,
() => {
if (expanded.value) closeToc();
},
{ immediate: true },
);
</script>

<style lang="scss" scoped>
.container {
&.expanded {
left: 0;
width: calc(100vw - 100px);
transform: translateX(0);

.cell {
width: max-content !important;
}
}
left: 0;
//width: calc(100vw - 50px);
width: 100%;
overflow-x: auto;
transform: translateX(0);
//.cell {
// width: max-content !important;
//}
}

.scroll {
Expand All @@ -420,18 +393,21 @@ watch(
}

.table {
margin: 0 auto;
width: 100%;
// margin: 0 auto;
border-collapse: collapse;
table-layout: fixed;
font-size: 0.9em;
//table-layout: fixed;
table-layout: auto;
}

/** all cells */
.cell {
display: flex;
align-items: center;
max-width: max-content;
padding: 5px 10px;
gap: 10px;
//display: flex;
//align-items: center;
//max-width: max-content;
padding: 3px 6px;
gap: 5px;

&.left {
justify-content: flex-start;
Expand All @@ -456,6 +432,7 @@ watch(
.th,
.td {
padding: 0;
white-space: nowrap;

&.divider {
position: relative;
Expand All @@ -472,11 +449,26 @@ watch(

/** heading cells */
.th {
padding-bottom: 10px;
padding-bottom: 3px;
font-weight: 600;
text-transform: capitalize;
}

/* first th */
.th:nth-child(1) {
width: 30%;
}

/* second th */
.th:nth-child(2) {
width: 5%;
}

/* third th */
.th:nth-child(3) {
width: 30%;
}

/** body cells */
.td {
border-bottom: solid 2px $light-gray;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ThePhenogrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</template>
</tooltip>

<div ref="scroll" class="scroll force-scrollbar">
<div ref="scroll">
<svg
ref="svg"
xmlns="http://www.w3.org/2000/svg"
Expand Down
Loading

0 comments on commit 2c878e8

Please sign in to comment.