Skip to content

Commit

Permalink
web/satellite/vuetify-poc: unmock all projects dashboard data
Browse files Browse the repository at this point in the history
The all projects dashboard of the Vuetify project has been updated to
display real project information rather than mock data. Additionally,
projects may now be selected and project invitations replied to through
the all projects dashboard.

Resolves #6036
Resolves #6038

Change-Id: I8aef0dc07c172e2bc8e2f7eb26a3d205bd56067f
  • Loading branch information
jewharton authored and Storj Robot committed Jul 24, 2023
1 parent 9086078 commit 5a03e29
Show file tree
Hide file tree
Showing 16 changed files with 655 additions and 289 deletions.
3 changes: 3 additions & 0 deletions web/satellite/vuetify-poc/src/assets/icon-trash.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -22,9 +22,9 @@
hover
>
<template #item.name="{ item }">
<v-list-item class="font-weight-bold pl-0">
{{ item.columns.name }}
</v-list-item>
<span class="font-weight-bold">
{{ item.raw.name }}
</span>
</template>
<template #item.status="{ item }">
<v-chip :color="item.raw.status == 'Active' ? 'success' : 'warning'" variant="tonal" size="small" rounded="xl" class="font-weight-bold">
Expand All @@ -37,7 +37,7 @@

<script setup lang="ts">
import { ref } from 'vue';
import { VCard, VTextField, VListItem, VChip } from 'vuetify/components';
import { VCard, VTextField, VChip } from 'vuetify/components';
import { VDataTable } from 'vuetify/labs/components';
const search = ref<string>('');
Expand Down
18 changes: 11 additions & 7 deletions web/satellite/vuetify-poc/src/components/BrowserTableComponent.vue
Expand Up @@ -22,13 +22,18 @@
show-select
>
<template #item.name="{ item }">
<v-list-item class="rounded-lg font-weight-bold pl-1" link @click="previewFile">
<template #prepend>
<!-- Filetype icons -->
<div>
<v-btn
class="rounded-lg w-100 pl-1 pr-4 justify-start font-weight-bold"
variant="text"
height="40"
color="default"
@click="previewFile"
>
<img :src="icons.get(item.raw.icon) || fileIcon" alt="Item icon" class="mr-3">
</template>
{{ item.columns.name }}
</v-list-item>
{{ item.raw.name }}
</v-btn>
</div>
</template>
</v-data-table>

Expand Down Expand Up @@ -146,7 +151,6 @@ import { ref } from 'vue';
import {
VCard,
VTextField,
VListItem,
VDialog,
VCarousel,
VBtn,
Expand Down
18 changes: 12 additions & 6 deletions web/satellite/vuetify-poc/src/components/BucketsDataTable.vue
Expand Up @@ -21,20 +21,26 @@
show-select
>
<template #item.name="{ item }">
<v-list-item class="rounded-lg font-weight-bold pl-1" link router-link to="/bucket">
<template #prepend>
<div>
<v-btn
class="rounded-lg w-100 pl-1 pr-4 justify-start font-weight-bold"
variant="text"
height="40"
color="default"
to="/bucket"
>
<img src="../assets/icon-bucket-tonal.svg" alt="Bucket" class="mr-3">
</template>
{{ item.columns.name }}
</v-list-item>
{{ item.raw.name }}
</v-btn>
</div>
</template>
</v-data-table>
</v-card>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { VCard, VTextField, VListItem } from 'vuetify/components';
import { VCard, VTextField, VBtn } from 'vuetify/components';
import { VDataTable } from 'vuetify/labs/components';
const props = defineProps<{
Expand Down
143 changes: 143 additions & 0 deletions web/satellite/vuetify-poc/src/components/ProjectCard.vue
@@ -0,0 +1,143 @@
// Copyright (C) 2023 Storj Labs, Inc.
// See LICENSE for copying information.

<template>
<v-card variant="flat" :border="true" rounded="xlg">
<div class="h-100 d-flex flex-column justify-space-between">
<v-card-item>
<div class="d-flex justify-space-between">
<v-chip rounded :color="item ? PROJECT_ROLE_COLORS[item.role] : 'primary'" variant="tonal" class="font-weight-bold my-2" size="small">
<icon-project width="12px" class="mr-1" />
{{ item?.role || 'Project' }}
</v-chip>

<v-btn v-if="item?.role === ProjectRole.Owner" color="default" variant="text" size="small">
<v-icon icon="mdi-dots-vertical" />

<v-menu activator="parent" location="end" transition="scale-transition">
<v-list class="pa-2">
<v-list-item link rounded="lg">
<template #prepend>
<icon-settings />
</template>
<v-list-item-title class="text-body-2 ml-3">
Project Settings
</v-list-item-title>
</v-list-item>

<v-divider class="my-2" />

<v-list-item link class="mt-1" rounded="lg">
<template #prepend>
<icon-team />
</template>
<v-list-item-title class="text-body-2 ml-3">
Invite Members
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</div>
<v-card-title :class="{ 'text-primary': item && item.role !== ProjectRole.Invited }">
<a v-if="item && item.role !== ProjectRole.Invited" class="link" @click="openProject">
{{ item.name }}
</a>
<template v-else>
{{ item ? item.name : 'Welcome' }}
</template>
</v-card-title>
<v-card-subtitle v-if="!item || item.description">
{{ item ? item.description : 'Create a project to get started.' }}
</v-card-subtitle>
</v-card-item>
<v-card-text class="flex-grow-0">
<v-divider class="mt-1 mb-4" />
<v-btn v-if="!item" color="primary" size="small" class="mr-2">Create Project</v-btn>
<template v-else-if="item?.role === ProjectRole.Invited">
<v-btn color="primary" size="small" class="mr-2" :disabled="isDeclining" @click="emit('joinClick')">
Join Project
</v-btn>
<v-btn
variant="outlined"
color="default"
size="small"
class="mr-2"
:loading="isDeclining"
@click="declineInvitation"
>
Decline
</v-btn>
</template>
<v-btn v-else color="primary" size="small" class="mr-2" @click="openProject">Open Project</v-btn>
</v-card-text>
</div>
</v-card>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import {
VCard,
VCardItem,
VChip,
VBtn,
VIcon,
VMenu,
VList,
VListItem,
VListItemTitle,
VDivider,
VCardTitle,
VCardSubtitle,
VCardText,
} from 'vuetify/components';

import { ProjectItemModel, PROJECT_ROLE_COLORS } from '@poc/types/projects';
import { ProjectInvitationResponse } from '@/types/projects';
import { ProjectRole } from '@/types/projectMembers';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { LocalData } from '@/utils/localData';

import IconProject from '@poc/components/icons/IconProject.vue';
import IconSettings from '@poc/components/icons/IconSettings.vue';
import IconTeam from '@poc/components/icons/IconTeam.vue';

const props = defineProps<{
item?: ProjectItemModel,
}>();

const emit = defineEmits<{
(event: 'joinClick'): void;
}>();

const projectsStore = useProjectsStore();
const router = useRouter();

const isDeclining = ref<boolean>(false);

/**
* Selects the project and navigates to the project dashboard.
*/
function openProject(): void {
if (!props.item) return;
projectsStore.selectProject(props.item.id);
LocalData.setSelectedProjectId(props.item.id);
router.push('/dashboard');
}

/**
* Declines the project invitation.
*/
async function declineInvitation(): Promise<void> {
if (!props.item || isDeclining.value) return;
isDeclining.value = true;

await projectsStore.respondToInvitation(props.item.id, ProjectInvitationResponse.Decline).catch(_ => {});
await projectsStore.getUserInvitations().catch(_ => {});
await projectsStore.getProjects().catch(_ => {});

isDeclining.value = false;
}
</script>

0 comments on commit 5a03e29

Please sign in to comment.