Skip to content

Commit

Permalink
Merge pull request #766 from molgenis/feat/preview-col-names
Browse files Browse the repository at this point in the history
feat: preview col names
  • Loading branch information
timcadman authored Oct 3, 2024
2 parents 45b11f5 + e952aed commit 5180587
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 35 deletions.
42 changes: 42 additions & 0 deletions ui/src/components/ColumnNamesPreview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<div>
<button
type="button"
class="btn btn-secondary"
@click="toggleColumnNames()"
>
{{ buttonName }} <i class="bi bi-chevron-down" v-if="!isCollapsed"></i>
<i class="bi bi-chevron-up" v-else></i>
</button>
<div class="fst-italic text-secondary" v-show="isCollapsed">
{{ columnNamesString }}
</div>
</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "ColumnNamesPreview",
props: {
columnNames: { type: Array, required: true },
buttonName: String,
},
data() {
return {
isCollapsed: false,
};
},
computed: {
columnNamesString() {
return this.columnNames.join(", ");
},
},
methods: {
toggleColumnNames() {
this.isCollapsed = !this.isCollapsed;
},
},
});
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,19 @@
<th scope="col" v-for="key in tableHeader" :key="key">
{{ key }}
</th>
<!-- Not required if there are not at least 11 columns -->
<th v-if="nCols > 10" scope="col">...</th>
</tr>
</thead>
<tbody class="table-group-divider">
<!-- for each row-->
<tr v-for="(row, index) in dataToPreview" :key="index">
<!-- for each value in row -->
<td v-for="(value, key) in row" :key="key">
{{ value }}
</td>
<!-- Will display the "+ x more" if 11 or more columns are present, else hides the column entirely -->
<td rowspan="10" v-if="index === 0 && nCols > 10" class="fst-italic">
{{ `+ ${nCols - 10} more` }}
</td>
</tr>
<tr class="text-end fst-italic">
<!-- Same goes for rows, only display when there are at least 11 or more rows -->
<td colspan="11" v-if="nRows > 10">
{{ `+ ${nRows - 10} more rows` }}
<td v-for="(value, key, index) in row" :key="key">
<span v-if="value.toString().length > tableHeader[index].length">
{{ value.toString().slice(0, tableHeader[index].length - 2 ) }}..
</span>
<span v-else>
{{ value }}
</span>
</td>
</tr>
</tbody>
Expand All @@ -41,7 +34,7 @@ import { defineComponent, PropType } from "vue";
import { isIntArray, transformTable, truncate } from "@/helpers/utils";
export default defineComponent({
name: "SimpleTable",
name: "DataPreviewTable",
props: {
data: {
type: Array as PropType<{ [key: string]: string }[]>,
Expand All @@ -55,10 +48,6 @@ export default defineComponent({
type: Number,
required: true,
},
nCols: {
type: Number,
required: true,
},
},
computed: {
maxNumberCharacters() {
Expand Down
1 change: 1 addition & 0 deletions ui/src/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type ProjectsExplorerData = {
selectedFolder: string;
createLinkFromTarget: boolean;
createLinkFromSrc: boolean;
columnNames: Array<string>;
};

export type ProjectsData = {
Expand Down
58 changes: 44 additions & 14 deletions ui/src/views/ProjectsExplorer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,18 @@
:viewTable="selectedFile"
:onSave="doCreateLinkFile"
></ViewEditor>
<SimpleTable
<DataPreviewTable
v-else
:data="filePreview"
:maxWidth="previewContainerWidth"
:n-rows="fileInfo.dataSizeRows"
:n-cols="fileInfo.dataSizeColumns"
></SimpleTable>
></DataPreviewTable>
<ColumnNamesPreview
v-if="!editView"
:columnNames="columnNames"
:buttonName="columnNames.length > 10 ? '+ ' + (columnNames.length - 10) + ' variables: ' : columnNames.length + ' variables: '"
>
</ColumnNamesPreview>
</div>
<div v-else-if="!loading_preview && askIfPreviewIsEmpty()">
<div class="fst-italic">
Expand All @@ -209,12 +214,14 @@ import FolderInput from "@/components/FolderInput.vue";
import ListGroup from "@/components/ListGroup.vue";
import LoadingSpinner from "@/components/LoadingSpinner.vue";
import FeedbackMessage from "@/components/FeedbackMessage.vue";
import ColumnNamesPreview from "@/components/ColumnNamesPreview.vue";
import {
getProject,
deleteObject,
previewObject,
getFileDetails,
createLinkFile,
getTableVariables,
} from "@/api/api";
import {
isEmptyObject,
Expand All @@ -228,7 +235,7 @@ import { StringArray, ProjectsExplorerData } from "@/types/types";
import { useRoute, useRouter } from "vue-router";
import FileUpload from "@/components/FileUpload.vue";
import FileExplorer from "@/components/FileExplorer.vue";
import SimpleTable from "@/components/SimpleTable.vue";
import DataPreviewTable from "@/components/DataPreviewTable.vue";
import { processErrorMessages } from "@/helpers/errorProcessing";
import ViewEditor from "@/components/ViewEditor.vue";
Expand All @@ -244,8 +251,9 @@ export default defineComponent({
FileUpload,
FileExplorer,
FolderInput,
SimpleTable,
DataPreviewTable,
ViewEditor,
ColumnNamesPreview,
},
setup() {
const project: Ref<StringArray> = ref([]);
Expand Down Expand Up @@ -301,6 +309,7 @@ export default defineComponent({
},
createLinkFromTarget: false,
createLinkFromSrc: false,
columnNames: [],
};
},
watch: {
Expand All @@ -318,32 +327,38 @@ export default defineComponent({
this.loading_preview = true;
previewObject(
this.projectId,
`${this.selectedFolder}/${this.selectedFile}`
`${this.selectedObject}`
)
.then((data) => {
this.filePreview = data;
this.loading_preview = false;
})
.catch((error) => {
this.errorMessage = `Cannot load preview for [${this.selectedFolder}/${this.selectedFile}] of project [${this.projectId}]. Because: ${error}.`;
this.errorMessage = `Cannot load preview for [${this.selectedObject}] of project [${this.projectId}]. Because: ${error}.`;
this.clearFilePreview();
this.loading_preview = false;
});
}
getFileDetails(
getFileDetails(
this.projectId,
`${this.selectedFolder}/${this.selectedFile}`
`${this.selectedObject}`
)
.then((data) => {
this.fileInfo.fileSize = data["size"];
this.fileInfo.dataSizeRows = parseInt(data["rows"]);
this.fileInfo.dataSizeColumns = parseInt(data["columns"]);
this.fileInfo.sourceLink = data["sourceLink"];
this.fileInfo.variables = data["variables"];
if (isLinkFileType(this.selectedFile)) {
this.columnNames = this.fileInfo.variables
} else {
this.getTableColumnNames( this.projectId, `${this.selectedObject}`)
}
})
.catch((error) => {
this.errorMessage = `Cannot load details for [${this.selectedFolder}/${this.selectedFile}] of project [${this.projectId}]. Because: ${error}.`;
});
this.errorMessage = `Cannot load details for [${this.selectedObject}] of project [${this.projectId}]. Because: ${error}.`;
});
}
}
},
project() {
Expand All @@ -358,6 +373,9 @@ export default defineComponent({
projectFolders(): StringArray {
return Object.keys(this.projectContent) as StringArray;
},
selectedObject(): String {
return `${this.selectedFolder}/${this.selectedFile}`
}
},
methods: {
isTableType,
Expand Down Expand Up @@ -400,6 +418,18 @@ export default defineComponent({
this.errorMessage = "Folder name cannot be empty";
}
},
getTableColumnNames (project: string, object: string) {
getTableVariables(
project,
object
)
.then((data) => {
this.columnNames = data;
})
.catch((error) => {
this.errorMessage = `Cannot load column names for [${object}] of project [${project}]. Because: ${error}.`;
});
},
cancelNewFolder() {
this.createNewFolder = false;
},
Expand Down Expand Up @@ -431,7 +461,7 @@ export default defineComponent({
const folder = splittedFileAndFolder[0];
const response = deleteObject(
this.projectId,
`${this.selectedFolder}/${this.selectedFile}`
`${this.selectedObject}`
);
response
.then(() => {
Expand Down Expand Up @@ -555,7 +585,7 @@ export default defineComponent({
this.editView = false;
if (this.projectId !== "" && this.selectedFolder !== "") {
this.router.push(
`/projects-explorer/${this.projectId}/${this.selectedFolder}/${this.selectedFile}`
`/projects-explorer/${this.projectId}/${this.selectedObject}`
);
}
})
Expand Down
23 changes: 23 additions & 0 deletions ui/tests/unit/components/ColumnNamesPreview.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { shallowMount, VueWrapper } from "@vue/test-utils";
import ColumnNamesPreview from "@/components/ColumnNamesPreview.vue";

describe("ColumnNamesPreview", () => {
let wrapper: VueWrapper<any>;
beforeEach(function () {
wrapper = shallowMount(ColumnNamesPreview, {
props: {
columnNames: ["col1", "col2"],
buttonName: "+ 2 more columns",
},
});
});

test("Toggle column names", () => {
expect(wrapper.vm.isCollapsed).toBe(false)
wrapper.vm.toggleColumnNames()
expect(wrapper.vm.isCollapsed).toBe(true)
});
test("Join column names with comma", () => {
expect(wrapper.vm.columnNamesString).toBe("col1, col2")
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { shallowMount, VueWrapper } from "@vue/test-utils";
import SimpleTable from "@/components/SimpleTable.vue";
import DataPreviewTable from "@/components/DataPreviewTable.vue";

function getListOfColumnValues(
data: {
Expand All @@ -18,7 +18,7 @@ function getListOfColumnValues(
});
}

describe("SimpleTable", () => {
describe("DataPreviewTable", () => {
const data = [
{
firstName: "Bofke",
Expand Down
3 changes: 3 additions & 0 deletions ui/tests/unit/views/ProjectExplorer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ describe("ProjectsExplorer", () => {
api.getFileDetails.mockImplementation(() => {
return Promise.resolve({});
});
api.getTableVariables.mockImplementation(() => {
return Promise.resolve({});
});
// Important: selectedFolder before selectedFile, since watcher for selectedFolder resets selectedFile to ""
expect(wrapper.vm.fileToDelete).toBe("");
expect(wrapper.vm.folderToDeleteFrom).toBe("");
Expand Down

0 comments on commit 5180587

Please sign in to comment.