web/satellite: match projects table with the designs
This change updates the projects table on all projects dashboard to more closely match the designs. Change-Id: I547a83352fba8c3ad7958802db7b38b342b383e8
This commit is contained in:
parent
8d8f6734de
commit
f131047f1a
@ -14,8 +14,13 @@
|
|||||||
v-for="(val, keyVal, index) in item" :key="index" class="align-left data"
|
v-for="(val, keyVal, index) in item" :key="index" class="align-left data"
|
||||||
:class="{'overflow-visible': showBucketGuide(index)}"
|
:class="{'overflow-visible': showBucketGuide(index)}"
|
||||||
>
|
>
|
||||||
<div v-if="Array.isArray(val)" class="few-items">
|
<div v-if="Array.isArray(val)" class="few-items-container">
|
||||||
<p v-for="str in val" :key="str" class="array-val">{{ str }}</p>
|
<div v-if="icon && index === 0 && itemType?.includes('project')" class="item-icon file-background" :class="customIconClasses">
|
||||||
|
<component :is="icon" />
|
||||||
|
</div>
|
||||||
|
<div class="few-items">
|
||||||
|
<p v-for="str in val" :key="str" class="array-val">{{ str }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="table-item">
|
<div v-else class="table-item">
|
||||||
<div v-if="icon && index === 0" class="item-icon file-background" :class="customIconClasses">
|
<div v-if="icon && index === 0" class="item-icon file-background" :class="customIconClasses">
|
||||||
@ -83,17 +88,15 @@ const icon = computed((): string => ObjectType.findIcon(props.itemType));
|
|||||||
const customIconClasses = computed(() => {
|
const customIconClasses = computed(() => {
|
||||||
const classes = {};
|
const classes = {};
|
||||||
if (props.itemType === 'project') {
|
if (props.itemType === 'project') {
|
||||||
if (props.item['role'] === ProjectRole.Owner) {
|
classes['project-owner'] = true;
|
||||||
classes['project-owner'] = true;
|
} else if (props.itemType === 'shared-project') {
|
||||||
} else if (props.item['role'] === ProjectRole.Member) {
|
classes['project-member'] = true;
|
||||||
classes['project-member'] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return classes;
|
return classes;
|
||||||
});
|
});
|
||||||
|
|
||||||
function isProjectRoleIconShown(role: ProjectRole) {
|
function isProjectRoleIconShown(role: ProjectRole) {
|
||||||
return props.itemType === 'project' || role === ProjectRole.Invited || role === ProjectRole.InviteExpired;
|
return props.itemType.includes('project') || role === ProjectRole.Invited || role === ProjectRole.InviteExpired;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectClicked(event: Event): void {
|
function selectClicked(event: Event): void {
|
||||||
@ -204,11 +207,27 @@ function cellContentClicked(cellIndex: number, event: Event) {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
&__subtitle {
|
&__subtitle {
|
||||||
font-family: 'font_regular', sans-serif;
|
font-family: 'font_regular', sans-serif;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
color: var(--c-grey-6);
|
color: var(--c-grey-6);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.few-items-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@media screen and (width <= 370px) {
|
||||||
|
max-width: 9rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ export class ObjectType {
|
|||||||
['text', TxtIcon],
|
['text', TxtIcon],
|
||||||
['archive', ZipIcon],
|
['archive', ZipIcon],
|
||||||
['project', ProjectIcon],
|
['project', ProjectIcon],
|
||||||
|
['shared-project', ProjectIcon],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
static findIcon(type: string): string {
|
static findIcon(type: string): string {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<heading class="all-dashboard__heading" />
|
<heading class="all-dashboard__heading" />
|
||||||
|
|
||||||
<div class="all-dashboard__content">
|
<div class="all-dashboard__content" :class="{ 'no-x-padding': isMyProjectsPage }">
|
||||||
<div class="all-dashboard__content__divider" />
|
<div class="all-dashboard__content__divider" />
|
||||||
|
|
||||||
<router-view />
|
<router-view />
|
||||||
@ -134,6 +134,10 @@ const sessionDuration = computed((): number => {
|
|||||||
return duration;
|
return duration;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isMyProjectsPage = computed((): boolean => {
|
||||||
|
return route.path === RouteConfig.AllProjectsDashboard.path;
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session refresh interval from the store.
|
* Returns the session refresh interval from the store.
|
||||||
*/
|
*/
|
||||||
@ -565,6 +569,11 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-x-padding {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.all-dashboard {
|
.all-dashboard {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -64,7 +64,10 @@
|
|||||||
|
|
||||||
<all-projects-dashboard-banners v-if="content" :parent-ref="content" />
|
<all-projects-dashboard-banners v-if="content" :parent-ref="content" />
|
||||||
|
|
||||||
<div v-if="projects.length || invites.length" class="my-projects__list">
|
<div
|
||||||
|
v-if="projects.length || invites.length" class="my-projects__list"
|
||||||
|
:style="{'padding': isTableViewSelected && isMobile ? '0' : '0 20px'}"
|
||||||
|
>
|
||||||
<projects-table v-if="isTableViewSelected" :invites="invites" class="my-projects__list__table" />
|
<projects-table v-if="isTableViewSelected" :invites="invites" class="my-projects__list__table" />
|
||||||
<div v-else-if="!isTableViewSelected" class="my-projects__list__cards">
|
<div v-else-if="!isTableViewSelected" class="my-projects__list__cards">
|
||||||
<project-invitation-item v-for="invite in invites" :key="invite.projectID" :invitation="invite" />
|
<project-invitation-item v-for="invite in invites" :key="invite.projectID" :invitation="invite" />
|
||||||
@ -98,6 +101,7 @@ import { useProjectsStore } from '@/store/modules/projectsStore';
|
|||||||
import { useConfigStore } from '@/store/modules/configStore';
|
import { useConfigStore } from '@/store/modules/configStore';
|
||||||
import ProjectsTable from '@/views/all-dashboard/components/ProjectsTable.vue';
|
import ProjectsTable from '@/views/all-dashboard/components/ProjectsTable.vue';
|
||||||
import AllProjectsDashboardBanners from '@/views/all-dashboard/components/AllProjectsDashboardBanners.vue';
|
import AllProjectsDashboardBanners from '@/views/all-dashboard/components/AllProjectsDashboardBanners.vue';
|
||||||
|
import { useResize } from '@/composables/resize';
|
||||||
|
|
||||||
import VButton from '@/components/common/VButton.vue';
|
import VButton from '@/components/common/VButton.vue';
|
||||||
import VChip from '@/components/common/VChip.vue';
|
import VChip from '@/components/common/VChip.vue';
|
||||||
@ -113,6 +117,8 @@ const projectsStore = useProjectsStore();
|
|||||||
|
|
||||||
const analytics = new AnalyticsHttpApi();
|
const analytics = new AnalyticsHttpApi();
|
||||||
|
|
||||||
|
const { isMobile } = useResize();
|
||||||
|
|
||||||
const content = ref<HTMLElement | null>(null);
|
const content = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
const hasProjectTableViewConfigured = ref(appStore.hasProjectTableViewConfigured());
|
const hasProjectTableViewConfigured = ref(appStore.hasProjectTableViewConfigured());
|
||||||
@ -173,6 +179,7 @@ function onCreateProjectClicked(): void {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
@media screen and (width <= 500px) {
|
@media screen and (width <= 500px) {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
@ -268,6 +275,10 @@ function onCreateProjectClicked(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& :deep(.all-dashboard-banners) {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
&__list {
|
&__list {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|
||||||
@ -276,7 +287,7 @@ function onCreateProjectClicked(): void {
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
|
||||||
& :deep(.project-item) {
|
& :deep(.project-item), &:deep(.invite-item) {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,41 +3,43 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<table-item
|
<table-item
|
||||||
item-type="project"
|
item-type="shared-project"
|
||||||
:item="itemToRender"
|
:item="itemToRender"
|
||||||
class="invitation-item"
|
class="invitation-item"
|
||||||
>
|
>
|
||||||
<template #options>
|
<template #options>
|
||||||
<th class="options overflow-visible">
|
<th class="overflow-visible">
|
||||||
<v-button
|
<div class="options">
|
||||||
:loading="isLoading"
|
<v-button
|
||||||
:disabled="isLoading"
|
:loading="isLoading"
|
||||||
:on-press="onJoinClicked"
|
:disabled="isLoading"
|
||||||
border-radius="8px"
|
:on-press="onJoinClicked"
|
||||||
font-size="12px"
|
border-radius="8px"
|
||||||
label="Join Project"
|
font-size="12px"
|
||||||
class="invitation-item__menu__button"
|
label="Join Project"
|
||||||
/>
|
class="invitation-item__button"
|
||||||
<v-button
|
/>
|
||||||
:loading="isLoading"
|
<v-button
|
||||||
:disabled="isLoading"
|
:loading="isLoading"
|
||||||
:on-press="onJoinClicked"
|
:disabled="isLoading"
|
||||||
border-radius="8px"
|
:on-press="onJoinClicked"
|
||||||
font-size="12px"
|
border-radius="8px"
|
||||||
label="Join"
|
font-size="12px"
|
||||||
class="invitation-item__menu__mobile-button"
|
label="Join"
|
||||||
/>
|
class="invitation-item__mobile-button"
|
||||||
<div class="invitation-item__menu">
|
/>
|
||||||
<div class="invitation-item__menu__icon" @click.stop="toggleDropDown">
|
<div class="invitation-item__menu">
|
||||||
<div class="invitation-item__menu__icon__content" :class="{open: isDropdownOpen}">
|
<div class="invitation-item__menu__icon" @click.stop="toggleDropDown">
|
||||||
<menu-icon />
|
<div class="invitation-item__menu__icon__content" :class="{open: isDropdownOpen}">
|
||||||
|
<menu-icon />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="isDropdownOpen" v-click-outside="closeDropDown" class="invitation-item__menu__dropdown">
|
<div v-if="isDropdownOpen" v-click-outside="closeDropDown" class="invitation-item__menu__dropdown">
|
||||||
<div class="invitation-item__menu__dropdown__item" @click.stop="onDeclineClicked">
|
<div class="invitation-item__menu__dropdown__item" @click.stop="onDeclineClicked">
|
||||||
<logout-icon />
|
<logout-icon />
|
||||||
<p class="invitation-item__menu__dropdown__item__label">Decline invite</p>
|
<p class="invitation-item__menu__dropdown__item__label">Decline invite</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -59,6 +61,7 @@ import { useAppStore } from '@/store/modules/appStore';
|
|||||||
import { useProjectsStore } from '@/store/modules/projectsStore';
|
import { useProjectsStore } from '@/store/modules/projectsStore';
|
||||||
import { useResize } from '@/composables/resize';
|
import { useResize } from '@/composables/resize';
|
||||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||||
|
import { useLoading } from '@/composables/useLoading';
|
||||||
|
|
||||||
import VButton from '@/components/common/VButton.vue';
|
import VButton from '@/components/common/VButton.vue';
|
||||||
import TableItem from '@/components/common/TableItem.vue';
|
import TableItem from '@/components/common/TableItem.vue';
|
||||||
@ -72,25 +75,36 @@ const notify = useNotify();
|
|||||||
|
|
||||||
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
||||||
|
|
||||||
const isLoading = ref<boolean>(false);
|
const { isLoading, withLoading } = useLoading();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
invitation: ProjectInvitation,
|
invitation: ProjectInvitation,
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { isMobile } = useResize();
|
const { isMobile, screenWidth } = useResize();
|
||||||
|
|
||||||
const itemToRender = computed((): { [key: string]: unknown | string[] } => {
|
const itemToRender = computed((): { [key: string]: unknown | string[] } => {
|
||||||
if (!isMobile.value) {
|
if (screenWidth.value <= 600 && !isMobile.value) {
|
||||||
|
return {
|
||||||
|
multi: { title: props.invitation.projectName, subtitle: props.invitation.projectDescription },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (screenWidth.value <= 850 && !isMobile.value) {
|
||||||
return {
|
return {
|
||||||
multi: { title: props.invitation.projectName, subtitle: props.invitation.projectDescription },
|
multi: { title: props.invitation.projectName, subtitle: props.invitation.projectDescription },
|
||||||
date: props.invitation.invitedDate,
|
|
||||||
memberCount: '',
|
|
||||||
role: ProjectRole.Invited,
|
role: ProjectRole.Invited,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (isMobile.value) {
|
||||||
|
return { info: [ props.invitation.projectName, props.invitation.projectDescription ] };
|
||||||
|
}
|
||||||
|
|
||||||
return { info: [ props.invitation.projectName, props.invitation.projectDescription ] };
|
return {
|
||||||
|
multi: { title: props.invitation.projectName, subtitle: props.invitation.projectDescription },
|
||||||
|
date: props.invitation.invitedDate,
|
||||||
|
memberCount: '',
|
||||||
|
role: ProjectRole.Invited,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,25 +125,22 @@ function onJoinClicked(): void {
|
|||||||
/**
|
/**
|
||||||
* Declines the project member invitation.
|
* Declines the project member invitation.
|
||||||
*/
|
*/
|
||||||
async function onDeclineClicked(): Promise<void> {
|
function onDeclineClicked(): void {
|
||||||
if (isLoading.value) return;
|
withLoading(async () => {
|
||||||
isLoading.value = true;
|
try {
|
||||||
|
await projectsStore.respondToInvitation(props.invitation.projectID, ProjectInvitationResponse.Decline);
|
||||||
|
analytics.eventTriggered(AnalyticsEvent.PROJECT_INVITATION_DECLINED);
|
||||||
|
} catch (error) {
|
||||||
|
notify.error(`Failed to decline project invitation. ${error.message}`, AnalyticsErrorEventSource.PROJECT_INVITATION);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await projectsStore.respondToInvitation(props.invitation.projectID, ProjectInvitationResponse.Decline);
|
await projectsStore.getUserInvitations();
|
||||||
analytics.eventTriggered(AnalyticsEvent.PROJECT_INVITATION_DECLINED);
|
await projectsStore.getProjects();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notify.error(`Failed to decline project invitation. ${error.message}`, AnalyticsErrorEventSource.PROJECT_INVITATION);
|
notify.error(`Failed to reload projects and invitations list. ${error.message}`, AnalyticsErrorEventSource.PROJECT_INVITATION);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
try {
|
|
||||||
await projectsStore.getUserInvitations();
|
|
||||||
await projectsStore.getProjects();
|
|
||||||
} catch (error) {
|
|
||||||
notify.error(`Failed to reload projects and invitations list. ${error.message}`, AnalyticsErrorEventSource.PROJECT_INVITATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
isLoading.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleDropDown() {
|
function toggleDropDown() {
|
||||||
@ -149,31 +160,35 @@ function closeDropDown() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
column-gap: 10px;
|
column-gap: 20px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
|
|
||||||
|
@media screen and (width <= 900px) {
|
||||||
|
column-gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
padding: 10px 16px;
|
||||||
|
|
||||||
|
@media screen and (width <= 900px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__mobile-button {
|
||||||
|
display: none;
|
||||||
|
padding: 10px 16px;
|
||||||
|
|
||||||
|
@media screen and (width <= 900px) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__menu {
|
&__menu {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&__button {
|
|
||||||
padding: 10px 16px;
|
|
||||||
|
|
||||||
@media screen and (width <= 500px) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__mobile-button {
|
|
||||||
display: none;
|
|
||||||
padding: 10px 16px;
|
|
||||||
|
|
||||||
@media screen and (width <= 500px) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
&__icon {
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
|
@ -3,28 +3,48 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<table-item
|
<table-item
|
||||||
item-type="project"
|
:item-type="isOwner ? 'project' : 'shared-project'"
|
||||||
:item="itemToRender"
|
:item="itemToRender"
|
||||||
:on-click="onOpenClicked"
|
:on-click="onOpenClicked"
|
||||||
class="project-item"
|
class="project-item"
|
||||||
>
|
>
|
||||||
<template #options>
|
<template #options>
|
||||||
<th class="project-item__menu options overflow-visible" @click.stop="toggleDropDown">
|
<th class="overflow-visible">
|
||||||
<div class="project-item__menu__icon">
|
<div class="options">
|
||||||
<div class="project-item__menu__icon__content" :class="{open: isDropdownOpen}">
|
<v-button
|
||||||
<menu-icon />
|
:on-press="onOpenClicked"
|
||||||
</div>
|
is-white
|
||||||
</div>
|
border-radius="8px"
|
||||||
|
font-size="12px"
|
||||||
|
label="Open Project"
|
||||||
|
class="project-item__button"
|
||||||
|
/>
|
||||||
|
<v-button
|
||||||
|
:on-press="onOpenClicked"
|
||||||
|
is-white
|
||||||
|
border-radius="8px"
|
||||||
|
font-size="12px"
|
||||||
|
label="Open"
|
||||||
|
class="project-item__mobile-button"
|
||||||
|
/>
|
||||||
|
<div class="project-item__menu">
|
||||||
|
<div class="project-item__menu__icon" @click.stop="toggleDropDown">
|
||||||
|
<div class="project-item__menu__icon__content" :class="{open: isDropdownOpen}">
|
||||||
|
<menu-icon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="isDropdownOpen" v-click-outside="closeDropDown" class="project-item__menu__dropdown">
|
<div v-if="isDropdownOpen" v-click-outside="closeDropDown" class="project-item__menu__dropdown">
|
||||||
<div v-if="isOwner" class="project-item__menu__dropdown__item" @click.stop="goToProjectEdit">
|
<div v-if="isOwner" class="project-item__menu__dropdown__item" @click.stop="goToProjectEdit">
|
||||||
<gear-icon />
|
<gear-icon />
|
||||||
<p class="project-item__menu__dropdown__item__label">Project settings</p>
|
<p class="project-item__menu__dropdown__item__label">Project settings</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="project-item__menu__dropdown__item" @click.stop="goToProjectMembers">
|
<div class="project-item__menu__dropdown__item" @click.stop="goToProjectMembers">
|
||||||
<users-icon />
|
<users-icon />
|
||||||
<p class="project-item__menu__dropdown__item__label">Invite members</p>
|
<p class="project-item__menu__dropdown__item__label">Invite members</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
@ -53,6 +73,7 @@ import { useProjectsStore } from '@/store/modules/projectsStore';
|
|||||||
import { useResize } from '@/composables/resize';
|
import { useResize } from '@/composables/resize';
|
||||||
|
|
||||||
import TableItem from '@/components/common/TableItem.vue';
|
import TableItem from '@/components/common/TableItem.vue';
|
||||||
|
import VButton from '@/components/common/VButton.vue';
|
||||||
|
|
||||||
import UsersIcon from '@/../static/images/navigation/users.svg';
|
import UsersIcon from '@/../static/images/navigation/users.svg';
|
||||||
import GearIcon from '@/../static/images/common/gearIcon.svg';
|
import GearIcon from '@/../static/images/common/gearIcon.svg';
|
||||||
@ -71,19 +92,30 @@ const props = defineProps<{
|
|||||||
project: Project,
|
project: Project,
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { isMobile } = useResize();
|
const { isMobile, screenWidth } = useResize();
|
||||||
|
|
||||||
const itemToRender = computed((): { [key: string]: unknown | string[] } => {
|
const itemToRender = computed((): { [key: string]: unknown | string[] } => {
|
||||||
if (!isMobile.value) {
|
if (screenWidth.value <= 600 && !isMobile.value) {
|
||||||
|
return {
|
||||||
|
multi: { title: props.project.name, subtitle: props.project.description },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (screenWidth.value <= 850 && !isMobile.value) {
|
||||||
return {
|
return {
|
||||||
multi: { title: props.project.name, subtitle: props.project.description },
|
multi: { title: props.project.name, subtitle: props.project.description },
|
||||||
date: props.project.createdDate(),
|
|
||||||
memberCount: props.project.memberCount.toString(),
|
|
||||||
role: isOwner.value ? ProjectRole.Owner : ProjectRole.Member,
|
role: isOwner.value ? ProjectRole.Owner : ProjectRole.Member,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (isMobile.value) {
|
||||||
|
return { info: [ props.project.name, props.project.description ] };
|
||||||
|
}
|
||||||
|
|
||||||
return { info: [ props.project.name, props.project.description ] };
|
return {
|
||||||
|
multi: { title: props.project.name, subtitle: props.project.description },
|
||||||
|
date: props.project.createdDate(),
|
||||||
|
memberCount: props.project.memberCount.toString(),
|
||||||
|
role: isOwner.value ? ProjectRole.Owner : ProjectRole.Member,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,8 +198,38 @@ async function goToProjectEdit(): Promise<void> {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.project-item {
|
.project-item {
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
column-gap: 20px;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
@media screen and (width <= 900px) {
|
||||||
|
column-gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
padding: 10px 16px;
|
||||||
|
box-shadow: 0 0 20px 0 rgb(0 0 0 / 4%);
|
||||||
|
|
||||||
|
@media screen and (width <= 900px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__mobile-button {
|
||||||
|
display: none;
|
||||||
|
padding: 10px 16px;
|
||||||
|
box-shadow: 0 0 20px 0 rgb(0 0 0 / 4%);
|
||||||
|
|
||||||
|
@media screen and (width <= 900px) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__menu {
|
&__menu {
|
||||||
padding: 0 10px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@ -176,8 +238,6 @@ async function goToProjectEdit(): Promise<void> {
|
|||||||
&__content {
|
&__content {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
margin-left: auto;
|
|
||||||
margin-right: 0;
|
|
||||||
padding: 12px 5px;
|
padding: 12px 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -193,9 +253,9 @@ async function goToProjectEdit(): Promise<void> {
|
|||||||
|
|
||||||
&__dropdown {
|
&__dropdown {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 55px;
|
top: 40px;
|
||||||
right: 10px;
|
right: 0;
|
||||||
background: var(--c-white);
|
background: #fff;
|
||||||
box-shadow: 0 7px 20px rgb(0 0 0 / 15%);
|
box-shadow: 0 7px 20px rgb(0 0 0 / 15%);
|
||||||
border: 1px solid var(--c-grey-2);
|
border: 1px solid var(--c-grey-2);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
items-label="projects"
|
items-label="projects"
|
||||||
>
|
>
|
||||||
<template #head>
|
<template #head>
|
||||||
<th class="sort-header-container__name-item align-left">Project</th>
|
<th class="align-left">Project</th>
|
||||||
<th class="sort-header-container__date-item align-left">Date Added</th>
|
<th class="date-added align-left">Date Added</th>
|
||||||
<th class="sort-header-container__date-item align-left">Members</th>
|
<th class="members align-left">Members</th>
|
||||||
<th class="sort-header-container__date-item align-left">Role</th>
|
<th class="role align-left">Role</th>
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<project-table-invitation-item
|
<project-table-invitation-item
|
||||||
@ -54,3 +54,28 @@ const projects = computed((): Project[] => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.projects-table {
|
||||||
|
@media screen and (width <= 550px) {
|
||||||
|
|
||||||
|
:deep(.table-footer), :deep(.base-table) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (width <= 850px) {
|
||||||
|
|
||||||
|
.date-added, .members {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (width <= 600px) {
|
||||||
|
|
||||||
|
.role {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user