Skip to content

Commit

Permalink
[studio] expand table row #1458 (#1459)
Browse files Browse the repository at this point in the history
studio - expand table row
  • Loading branch information
janavlachova authored Jan 4, 2025
1 parent d285278 commit e62a513
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 65 deletions.
6 changes: 6 additions & 0 deletions agdb_studio/src/assets/button.less
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
--borderColor: #af2836;
}

.button-transparent {
--backgroundColor: transparent;
--color: var(--color-text);
--borderColor: transparent;
}

.button:hover {
opacity: 0.8;
}
Expand Down
6 changes: 3 additions & 3 deletions agdb_studio/src/components/base/dropdown/AgdbDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { vOnClickOutside } from "@vueuse/components";
import { ref } from "vue";
import DropdownContent from "./DropdownContent.vue";
import FadeTrasition from "@/components/transitions/FadeTrasition.vue";
import SlideUpTransition from "@/components/transitions/SlideUpTransition.vue";
const opened = ref(false);
const close = () => {
Expand All @@ -25,7 +25,7 @@ const buttonRef = ref<HTMLElement>();
<slot name="trigger"></slot>
</button>
<Teleport to="body">
<FadeTrasition>
<SlideUpTransition>
<DropdownContent
:button-ref="buttonRef"
:opened="opened"
Expand All @@ -34,7 +34,7 @@ const buttonRef = ref<HTMLElement>();
>
<slot name="content"></slot>
</DropdownContent>
</FadeTrasition>
</SlideUpTransition>
</Teleport>
</div>
</template>
Expand Down
6 changes: 3 additions & 3 deletions agdb_studio/src/components/base/menu/AgdbMenu.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { ref, type PropType } from "vue";
import { AkChevronRightSmall } from "@kalimahapps/vue-icons";
import FadeTrasition from "@/components/transitions/FadeTrasition.vue";
import SlideUpTransition from "@/components/transitions/SlideUpTransition.vue";
const props = defineProps({
actions: { type: Array as PropType<Action[]>, required: true },
Expand Down Expand Up @@ -41,13 +41,13 @@ const openSubmenu = (key: string) => {
<AkChevronRightSmall />
</span>
</a>
<FadeTrasition>
<SlideUpTransition>
<AgdbMenu
class="sub-menu"
v-if="openedSubmenu === action.key && action.actions"
:actions="action.actions"
/>
</FadeTrasition>
</SlideUpTransition>
</li>
</ul>
</template>
Expand Down
10 changes: 7 additions & 3 deletions agdb_studio/src/components/base/modal/AgdbModal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ describe("AgdbModal", () => {
content: convertArrayOfStringsToContent(["Test Body"]),
});
await wrapper.vm.$nextTick();
await wrapper.find(".modal-header .close-button").trigger("click");
await wrapper
.find(".modal-header .button[data-testid=close-modal]")
.trigger("click");
await wrapper.vm.$nextTick();
expect(wrapper.isVisible()).toBe(false);
});
Expand All @@ -64,8 +66,10 @@ describe("AgdbModal", () => {
],
});
await wrapper.vm.$nextTick();
expect(wrapper.findAll(".button")).toHaveLength(2);
expect(wrapper.find(".button").text()).toBe("Custom Button");
expect(wrapper.findAll(".modal-footer .button")).toHaveLength(2);
expect(wrapper.find(".modal-footer .button").text()).toBe(
"Custom Button",
);
});
it("sets focus on the submit button", async () => {
const wrapper = mount(AgdbModal, {
Expand Down
16 changes: 5 additions & 11 deletions agdb_studio/src/components/base/modal/AgdbModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ watch(modalIsVisible, async () => {
<section class="modal">
<header class="modal-header">
<h3>{{ modal.header }}</h3>
<button @click="hideModal" class="close-button">
<button
@click="hideModal"
class="button button-transparent"
data-testid="close-modal"
>
<ClCloseMd />
</button>
</header>
Expand Down Expand Up @@ -99,14 +103,4 @@ watch(modalIsVisible, async () => {
border-top: 1px solid var(--color-border);
gap: 1rem;
}
.close-button {
background: none;
border: none;
cursor: pointer;
color: var(--color-text);
transition: opacity 0.2s;
&:hover {
opacity: 0.8;
}
}
</style>
8 changes: 5 additions & 3 deletions agdb_studio/src/components/base/table/AgdbTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
const props = defineProps({
name: {
type: String,
type: [Symbol, String],
required: true,
},
});
Expand All @@ -23,7 +23,7 @@ const rows = computed(() => {
const columns = computed(() => {
return getTableColumns<TRow>(props.name);
});
const tableKey = props.name;
const tableKey = computed(() => props.name);
provide(INJECT_KEY_TABLE_NAME, tableKey);
provide(INJECT_KEY_COLUMNS, columns);
</script>
Expand Down Expand Up @@ -52,7 +52,9 @@ provide(INJECT_KEY_COLUMNS, columns);
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 1rem;
padding: 0.5rem;
border-bottom: 1px solid var(--color-border);
white-space: nowrap;
&.expandable {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) 50px;
}
}
</style>
26 changes: 16 additions & 10 deletions agdb_studio/src/components/base/table/AgdbTableHeader.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
<script lang="ts" setup>
import { getTableColumnsArray } from "@/composables/table/tableConfig";
import { computed } from "vue";
const props = defineProps({
tableKey: {
type: String,
required: true,
},
});
import { INJECT_KEY_TABLE_NAME } from "@/composables/table/constants";
import {
getTable,
getTableColumnsArray,
} from "@/composables/table/tableConfig";
import { computed, inject, type Ref } from "vue";
const tableKey = inject<Ref<Symbol | string>>(INJECT_KEY_TABLE_NAME);
const columns = computed(() => {
return getTableColumnsArray(props.tableKey);
if (!tableKey?.value) {
return [];
}
return getTableColumnsArray(tableKey.value);
});
const rowsExpandable = computed(() => {
return tableKey ? !!getTable(tableKey.value)?.rowDetailsComponent : false;
});
</script>

<template>
<div class="agdb-table-header columns">
<div :class="['agdb-table-header columns', { expandable: rowsExpandable }]">
<div v-for="column in columns" :key="column.key">
{{ column.title }}
</div>
<div v-if="rowsExpandable"></div>
</div>
</template>

Expand Down
45 changes: 43 additions & 2 deletions agdb_studio/src/components/base/table/AgdbTableRow.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { mount } from "@vue/test-utils";
import AgdbTableRow from "./AgdbTableRow.vue";
import { columnsMap } from "@/tests/tableMocks";
import { columnsMap, TABLE_NAME, tableConfig } from "@/tests/tableMocks";
import { describe, it, expect } from "vitest";
import { INJECT_KEY_COLUMNS } from "@/composables/table/constants";
import {
INJECT_KEY_COLUMNS,
INJECT_KEY_TABLE_NAME,
} from "@/composables/table/constants";
import { addTable } from "@/composables/table/tableConfig";

describe("TableRow", () => {
addTable({
name: TABLE_NAME,
columns: tableConfig,
rowDetailsComponent: "component",
});

it("should render", () => {
const wrapper = mount(AgdbTableRow, {
props: {
Expand All @@ -28,4 +38,35 @@ describe("TableRow", () => {
expect(wrapper.text()).toContain("admin");
expect(wrapper.text()).toContain("app3");
});

it("should expand row", async () => {
const wrapper = mount(AgdbTableRow, {
props: {
columns: columnsMap,
row: {
role: "admin",
owner: "admin",
db: "app3",
db_type: "file",
size: 50,
backup: 0,
},
},
global: {
provide: {
[INJECT_KEY_COLUMNS]: { value: columnsMap },
[INJECT_KEY_TABLE_NAME]: { value: TABLE_NAME },
},
stubs: {
transitions: false,
},
},
});

expect(wrapper.find(".expanded-row").exists()).toBe(false);
await wrapper.find(".expand-row").trigger("click");
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
expect(wrapper.find(".expanded-row").exists()).toBe(true);
});
});
57 changes: 51 additions & 6 deletions agdb_studio/src/components/base/table/AgdbTableRow.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
<script lang="ts" setup>
import { computed, type PropType, provide } from "vue";
import { computed, inject, type PropType, provide, type Ref, ref } from "vue";
import { type Column, type TRow } from "@/composables/table/types";
import { INJECT_KEY_ROW } from "@/composables/table/constants";
import {
INJECT_KEY_ROW,
INJECT_KEY_TABLE_NAME,
} from "@/composables/table/constants";
import AgdbCell from "./AgdbCell.vue";
import { getTable } from "@/composables/table/tableConfig";
import { AkChevronDownSmall, AkChevronUpSmall } from "@kalimahapps/vue-icons";
import SlideUpTransition from "@/components/transitions/SlideUpTransition.vue";
const props = defineProps({
row: {
Expand All @@ -22,14 +28,53 @@ const rowData = computed(() => {
return props.row;
});
provide(INJECT_KEY_ROW, rowData);
const tableKey = inject<Ref<Symbol | string>>(INJECT_KEY_TABLE_NAME);
const rowDetailsComponent = computed(() => {
return tableKey ? getTable(tableKey.value)?.rowDetailsComponent : undefined;
});
const rowExpanded = ref(false);
const toggleExpandRow = (): void => {
rowExpanded.value = !rowExpanded.value;
};
</script>

<template>
<div class="agdb-table-row columns">
<div v-for="cellKey in cellKeys" :key="cellKey">
<AgdbCell :cell-key="cellKey" />
<div class="agdb-table-row-wrap">
<div
:class="[
'agdb-table-row columns',
{ expandable: rowDetailsComponent },
]"
>
<div v-for="cellKey in cellKeys" :key="cellKey">
<AgdbCell :cell-key="cellKey" />
</div>
<div v-if="rowDetailsComponent">
<button
@click="toggleExpandRow"
class="button button-transparent expand-row"
>
<AkChevronDownSmall v-if="!rowExpanded" />
<AkChevronUpSmall v-else />
</button>
</div>
</div>
<SlideUpTransition>
<div v-if="rowExpanded && rowDetailsComponent" class="expanded-row">
details
<component :is="rowDetailsComponent" />
</div>
</SlideUpTransition>
</div>
</template>

<style lang="less" scoped></style>
<style lang="less" scoped>
.agdb-table-row-wrap {
border-bottom: 1px solid var(--color-border);
.expanded-row {
border: 1px solid var(--color-border);
border-bottom: none;
}
}
</style>
5 changes: 3 additions & 2 deletions agdb_studio/src/components/db/DbTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { dbColumns } from "@/composables/db/dbConfig";
const { databases } = useDbStore();
const TABLE_KEY = "databases";
const TABLE_KEY = Symbol("databases");
addTable({
name: TABLE_KEY,
columns: dbColumns,
rowDetailsComponent: "DbTableRowDetails",
});
watchEffect(() => {
Expand All @@ -35,7 +36,7 @@ watchEffect(() => {
overflow: auto;
}
.db-table {
width: 1300px;
width: 1400px;
margin: 0 auto;
}
</style>
22 changes: 22 additions & 0 deletions agdb_studio/src/components/transitions/SlideUpTransition.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
<transition name="slide-up">
<slot></slot>
</transition>
</template>

<style lang="less" scoped>
.slide-up-enter-active,
.slide-up-leave-active {
transition:
max-height 0.25s ease,
opacity 0.25s ease;
max-height: 500px;
overflow: hidden;
}
.slide-up-enter-from,
.slide-up-leave-to {
opacity: 0;
max-height: 0;
}
</style>
Loading

0 comments on commit e62a513

Please sign in to comment.