Skip to content

Commit

Permalink
feat: project table view (#1869)
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnyama authored Sep 21, 2023
1 parent 50d6fdd commit e8ae6dc
Show file tree
Hide file tree
Showing 4 changed files with 418 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,6 @@
@click.stop="showProjectMenu"
/>
<Menu ref="projectMenu" :model="projectMenuItems" :popup="true" />
<Dialog :header="`Remove ${project.name}`" v-model:visible="isRemoveDialog">
<p>
You are about to remove project <em>{{ project.name }}</em
>.
</p>
<p>Are you sure?</p>
<template #footer>
<Button label="Cancel" class="p-button-secondary" @click="closeRemoveDialog" />
<Button label="Remove project" @click="removeProject" />
</template>
</Dialog>
</template>
</Card>
<Card v-else>
Expand Down Expand Up @@ -76,20 +65,26 @@ import { ref, computed } from 'vue';
import { Project } from '@/types/Types';
import Button from 'primevue/button';
import Card from 'primevue/card';
import Dialog from 'primevue/dialog';
import Menu from 'primevue/menu';
import Skeleton from 'primevue/skeleton';
import { formatDdMmmYyyy } from '@/utils/date';
import { placeholder } from '@/utils/project-card';
import { logger } from '@/utils/logger';
import * as ProjectService from '@/services/project';
import DatasetIcon from '@/assets/svg/icons/dataset.svg?component';
const props = defineProps<{ project?: Project }>();
const emit = defineEmits<{
(e: 'removed', projectId: Project['id']): void;
const props = defineProps<{
project?: Project;
projectMenuItems?: any[];
}>();
const emit = defineEmits(['update-chosen-project-menu']);
const projectMenu = ref();
const showProjectMenu = (event) => {
projectMenu.value.toggle(event);
emit('update-chosen-project-menu');
};
const titleRef = ref();
const descriptionLines = computed(() => {
const titleHeight = titleRef.value?.clientHeight;
Expand All @@ -106,39 +101,13 @@ const stats = computed(() =>
? null
: {
contributors: 1,
models: parseInt(props.project?.metadata?.['models-count'] ?? '0', 10),
papers: parseInt(props.project?.metadata?.['publications-count'] ?? '0', 10),
datasets: parseInt(props.project?.metadata?.['datasets-count'] ?? '0', 10),
papers: parseInt(props.project?.metadata?.['publications-count'] ?? '0', 10)
models: parseInt(props.project?.metadata?.['models-count'] ?? '0', 10)
}
);
const image = computed(() => (stats.value ? placeholder(stats.value) : undefined));
/*
* User Menu
*/
const isRemoveDialog = ref(false);
const openRemoveDialog = () => {
isRemoveDialog.value = true;
};
const closeRemoveDialog = () => {
isRemoveDialog.value = false;
};
const projectMenu = ref();
const projectMenuItems = ref([{ label: 'Remove', command: openRemoveDialog }]);
const showProjectMenu = (event) => projectMenu.value.toggle(event);
const removeProject = async () => {
if (!props.project || !props.project?.id) return;
const isDeleted = await ProjectService.remove(props.project.id);
closeRemoveDialog();
if (isDeleted) {
logger.info(`The project ${props.project?.name} was removed`, { showToast: true });
emit('removed', props.project.id);
} else {
logger.error(`Unable to delete the project ${props.project?.name}`, { showToast: true });
}
};
</script>

<style scoped>
Expand Down
162 changes: 162 additions & 0 deletions packages/client/hmi-client/src/components/home/tera-project-table.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<template>
<DataTable
:value="projects"
dataKey="id"
:rowsPerPageOptions="[10, 20, 50]"
scrollable
scrollHeight="45rem"
>
<Column
v-for="(col, index) in selectedColumns"
:field="col.field"
:header="col.header"
:sortable="col.field !== 'stats'"
:key="index"
:style="`width: ${getColumnWidth(col.field)}%`"
>
<template v-if="col.field !== 'username'" #body="{ data }">
<a
v-if="col.field === 'name'"
class="project-title-link"
@click.stop="emit('open-project', data.id)"
>
{{ data.name }}
</a>
<tera-show-more-text
v-else-if="col.field === 'description'"
:text="data.description"
:lines="1"
/>
<div v-else-if="col.field === 'stats'" class="stats">
<span><i class="pi pi-user" />1</span>
<span><i class="pi pi-file" /> {{ data.metadata?.['publications-count'] }}</span>
<span>
<dataset-icon fill="var(--text-color-secondary)" />
{{ data.metadata?.['datasets-count'] }}
</span>
<span><i class="pi pi-share-alt" /> {{ data.metadata?.['models-count'] }}</span>
</div>
<!--FIXME: There is no 'last updated' property in project yet-->
<template v-else-if="col.field === 'timestamp'">
{{ formatDdMmmYyyy(data.timestamp) }}
</template>
</template>
</Column>
<Column style="width: 0">
<template #body="{ data }">
<Button
icon="pi pi-ellipsis-v"
class="project-options p-button-icon-only p-button-text p-button-rounded"
@click.stop="(event) => showProjectMenu(event, data)"
/>
<Menu ref="projectMenu" :model="projectMenuItems" :popup="true" />
</template>
</Column>
</DataTable>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import DataTable from 'primevue/datatable';
import Column from 'primevue/column';
import TeraShowMoreText from '@/components/widgets/tera-show-more-text.vue';
import { formatDdMmmYyyy } from '@/utils/date';
import DatasetIcon from '@/assets/svg/icons/dataset.svg?component';
import Menu from 'primevue/menu';
import { Project } from '@/types/Types';
import Button from 'primevue/button';
defineProps<{
projects: Project[];
projectMenuItems?: any[];
selectedColumns: { field: string; header: string }[];
}>();
const emit = defineEmits(['open-project', 'update-chosen-project-menu']);
const projectMenu = ref();
const showProjectMenu = (event, project: Project) => {
projectMenu.value.toggle(event);
emit('update-chosen-project-menu', project);
};
function getColumnWidth(columnField: string) {
switch (columnField) {
case 'description':
return 60;
case 'name':
return 20;
default:
return 5;
}
}
</script>

<style scoped>
.stats {
display: flex;
width: fit-content;
gap: 0.5rem;
font-size: var(--font-caption);
vertical-align: bottom;
}
.stats span {
display: flex;
gap: 0.1rem;
align-items: center;
width: 2rem;
}
.p-datatable {
border: 1px solid var(--surface-border-light);
border-radius: var(--border-radius);
}
.p-datatable:deep(.p-datatable-tbody > tr > td),
.p-datatable:deep(.p-datatable-thead > tr > th) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
}
.p-datatable:deep(.p-datatable-thead > tr > th) {
padding: 1rem 0.5rem;
background-color: var(--surface-ground);
}
.p-datatable:deep(.p-datatable-tbody > tr:not(.p-highlight):focus) {
background-color: transparent;
}
.p-datatable:deep(.p-datatable-tbody > tr > td) {
color: var(--text-color-secondary);
padding: 0.5rem;
max-width: 32rem;
}
.p-datatable:deep(.p-datatable-tbody > tr > td:not(:last-child)) {
padding-top: 1rem;
}
.p-datatable:deep(.p-datatable-tbody > tr .project-options) {
visibility: hidden;
float: right;
}
.p-datatable:deep(.p-datatable-tbody > tr:hover .project-options) {
visibility: visible;
}
.p-datatable:deep(.p-datatable-tbody > tr > td > a) {
color: var(--text-color-primary);
font-weight: var(--font-weight-semibold);
cursor: pointer;
}
.p-datatable:deep(.p-datatable-tbody > tr > td > a:hover) {
color: var(--primary-color);
text-decoration: underline;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import { onMounted, onUpdated, ref, nextTick } from 'vue';
defineProps<{
lines?: number;
text: string;
lines?: number;
}>();
const expanded = ref(false);
Expand All @@ -34,6 +34,7 @@ function determineShowMore() {
function collapseOrExpand() {
expanded.value = !expanded.value;
}
onMounted(async () => {
await nextTick();
determineShowMore();
Expand Down
Loading

0 comments on commit e8ae6dc

Please sign in to comment.