Skip to content

Commit

Permalink
feat(customer_team_list): Add team list on the teams view for the cus…
Browse files Browse the repository at this point in the history
…tomer (#1515)
  • Loading branch information
NyraSama authored Jun 20, 2024
1 parent 3bbda1e commit dd3b0b5
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 5 deletions.
6 changes: 4 additions & 2 deletions yaki_admin/src/assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"editTeam": "Edit team",
"deleteTeam": "Delete team",
"close": "Close",
"downloadCsv": "Export in CSV"
"downloadCsv": "Export in CSV",
"seeDetail": "See detail"
},
"loginPage": {
"changePasswordInfo": "Your logging informations also are utilized on YAKI mobile.",
Expand Down Expand Up @@ -46,7 +47,8 @@
"howToCreateATeam1": "You can create a new team using the ",
"howToCreateATeam2": "Teams can be created using ",
"createTeam": "create team",
"option": "option"
"option": "option",
"lastActivity": "Last activity : "
},
"tutorials": {
"captainTitle": "Welcome to the captain management section",
Expand Down
6 changes: 4 additions & 2 deletions yaki_admin/src/assets/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"editTeam": "Éditer l'équipe",
"deleteTeam": "Supprimer l'équipe",
"close": "Fermer",
"downloadCsv": "Exporter en CSV"
"downloadCsv": "Exporter en CSV",
"seeDetail": "Voir le détail"
},
"loginPage": {
"changePasswordInfo": "Vos informations de connexion sont également utilisées sur YAKI mobile.",
Expand Down Expand Up @@ -46,7 +47,8 @@
"howToCreateATeam1": "Vous pouvez créer une nouvelle équipe en utilisant l'option ",
"howToCreateATeam2": "Les équipes peuvent être créées en utilisant ",
"createTeam": "créer une équipe",
"option": "option"
"option": "option",
"lastActivity": "Dernière activité : "
},
"tutorials": {
"captainTitle": "Bienvenue dans la section gestion des capitaines.",
Expand Down
74 changes: 74 additions & 0 deletions yaki_admin/src/ui/components/TeamInfoCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<script setup lang="ts">
import buttonIcon from "@/ui/components/buttons/ButtonIcon.vue";
import eyeIcon from "@/assets/icons_svg/Eye.svg";
import InitialAvatar from "@/ui/components/InitialAvatar.vue";
import { PropType, onBeforeMount, ref } from "vue";
import { TeamType } from "@/models/team.type";
import { TeamLogoType } from "@/models/TeamLogo.type";
import { teamLogoService } from "@/services/teamLogo.service";
import { setTeamLogoUrl } from "@/utils/images.utils";
import { useModalStore } from "@/stores/modalStore";
import ModalComingSoon from "./modals/ModalComingSoon.vue";
import { MODALMODE } from "@/constants/modalMode.enum";
const modalStore = useModalStore();
const teamLogo = ref<TeamLogoType>({
teamId: 0,
teamLogoBlob: null,
});
//define the props
const props = defineProps({
team: {
type: Object as PropType<TeamType>,
required: true,
},
});
//before mount, set logo of the team
onBeforeMount(async () => {
teamLogo.value = await getTeamLogo(props.team.id);
});
//define the computed
const getTeamLogo = async (teamId: number) => {
const teamLogo: TeamLogoType = await teamLogoService.getTeamLogo(teamId);
return teamLogo;
};
//define the methods
const onSeeDetailPress = () => {
modalStore.switchModalVisibility(true, MODALMODE.comingSoon);
};
</script>

<template>
<article class="user-card__container user-card__accepted_status">
<figure class="user-card__avatar rounded">
<div>
<img
class="user-card__avatar-img"
:src="setTeamLogoUrl(teamLogo!.teamLogoBlob)"
alt="user-card"
/>
</div>
</figure>

<div class="user-card__wrapper-user-infos">
<p class="user-card__name-text">{{ team.teamName }}</p>
<p class="user-card__info-text">
{{ $t("teamStatus.lastActivity") }}{{ $t("general.comingSoon") }}
</p>
</div>
<section class="user-card__wrapper-status">
<div class="user-card__wrapper-status_buttons">
<button-icon
@click.prevent="onSeeDetailPress"
:icon="eyeIcon"
:alt="$t('buttons.seeDetail')"
/>
</div>
</section>
</article>
</template>
56 changes: 56 additions & 0 deletions yaki_admin/src/ui/components/TeamList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import TeamInfoCard from "@/ui/components/TeamInfoCard.vue";
import { TeamType } from "@/models/team.type";
import { PropType } from "vue";
import { useTeamStore } from "@/stores/teamStore";
//Get the stores
const teamStore = useTeamStore();
const props = defineProps({
teamList: {
type: Object as PropType<TeamType[]>,
required: true,
},
});
</script>

<template>
<section class="user-list__container">
<section class="user-list__in-team-container">
<team-info-card
v-for="team in teamList"
:team="team"
:key="team.id"
/>
</section>
</section>
</template>

<style scoped lang="scss">
$border-radius: 24px;
.user-list__container {
padding-block-end: 10rem;
> p:nth-of-type(1) {
padding-block-end: 32px;
}
> p:nth-of-type(2) {
padding-block-end: 16px;
}
.user-list__in-team-container {
border-radius: $border-radius;
article:nth-of-type(1) {
border-top-left-radius: $border-radius;
border-top-right-radius: $border-radius;
}
article:last-of-type {
border-bottom-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
}
}
}
</style>
139 changes: 138 additions & 1 deletion yaki_admin/src/ui/views/TeamListView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,51 @@
<script setup lang="ts">
import { useSelectedRoleStore } from "@/stores/selectedRole";
import { useTeamStore } from "@/stores/teamStore";
import PageContentHeader from "@/ui/components/PageContentHeader.vue";
import PageContentLayout from "@/ui/layouts/PageContentLayout.vue";
import { computed, onBeforeMount, onMounted, ref } from "vue";
import InviteMemberTutorial from "@/ui/components/tutoriels/InviteMemberTutorial.vue";
import TeamList from "@/ui/components/TeamList.vue";
import chevronLeftIcon from "@/assets/icons_svg/Chevron-left.svg";
import chevronRightIcon from "@/assets/icons_svg/Chevron-right.svg";
const selectedRoleStore = useSelectedRoleStore();
const teamStore = useTeamStore();
onBeforeMount(() => {
// If the user is a customer
teamStore.setTeamsListByCustomerId(selectedRoleStore.getCustomerIdSelected);
});
const getTeamList = () => {
return teamStore.getTeamListByCustomer;
};
// Pagination variables
const currentPage = ref(1);
const rowsPerPage = 10;
// Computed property for pagination
const paginatedTeamsArray = computed(() => {
// We get the start using the currentPage and rowsPerPage=
let start = (currentPage.value - 1) * rowsPerPage;
// We get the end using the start and rowsPerPage
let end = start + rowsPerPage;
return getTeamList().slice(start, end);
});
// Methods for pagination
const nextPage = () => {
if (currentPage.value * rowsPerPage < getTeamList().length) {
currentPage.value++;
}
};
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--;
}
};
</script>

<template>
Expand All @@ -9,7 +54,99 @@ import PageContentLayout from "@/ui/layouts/PageContentLayout.vue";
<page-content-header :title="$t('sidebar.teams')" />
</template>
<template #content>
<p>{{ $t("general.comingSoon") }}</p>
<team-list
v-if="paginatedTeamsArray.length > 0"
:teamList="paginatedTeamsArray"
/>

<invite-member-tutorial v-else />
</template>
</page-content-layout>
<section
v-if="getTeamList().length > rowsPerPage"
class="page_handling__container"
>
<button
class="page_count_button"
@click.prevent="prevPage"
:style="currentPage === 1 ? 'pointer-events: none; opacity: 0.2;' : ''"
>
<figure>
<img
:src="chevronLeftIcon"
alt=""
/>
</figure>
</button>

<div>
<p>Page : {{ currentPage }} / {{ Math.ceil(getTeamList().length / rowsPerPage) }}</p>
</div>

<button
class="page_count_button"
@click.prevent="nextPage"
:style="
currentPage * rowsPerPage >= getTeamList().length
? 'pointer-events: none; opacity: 0.2;'
: ''
"
>
<figure>
<img
:src="chevronRightIcon"
alt=""
/>
</figure>
</button>
</section>
</template>

<style scoped lang="scss">
.page_handling__container {
position: absolute;
bottom: 0;
width: 95%;
height: 80px;
margin-inline: 1rem;
display: flex;
justify-content: center;
align-items: center;
gap: 3rem;
$size: 40px;
background-color: $background-color-theme-primary;
figure {
width: $size;
height: $size;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
p {
font-family: $font-sf-pro;
}
.page_count_button {
border: none;
background-color: $background-color-theme-primary;
cursor: pointer;
&:hover {
cursor: pointer;
}
&:active {
transform: scale(0.9);
}
}
}
</style>
6 changes: 6 additions & 0 deletions yaki_admin/test/features/team_management.feature
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ Feature: Team Management
Given I launch the application and login as a "captain"
Then I should not see the button "Teams" in the sidebar
Then I close the application

Scenario: Customer can see the list of teams
Given I launch the application and login as a "customer"
When I click on the button "Teams" in the sidebar
Then I should see the list of teams
Then I close the application
7 changes: 7 additions & 0 deletions yaki_admin/test/steps/detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Then("I should be on {string} path", async (path: string) => {

// Sidebar buttons
const isButtonInSidebar = async (text: string) => {
await page.waitForSelector(".sidebar__container");
const sidebarElements = await page.$$(
".sidebar__container .text-icon__container:not(.dropdown__container)",
);
Expand All @@ -35,3 +36,9 @@ Then("I should not see the button {string} in the sidebar", async (text: string)
const buttonIsInSidebar = await isButtonInSidebar(text);
expect(buttonIsInSidebar).toBe(false);
});

Then("I should see the list of teams", async () => {
await page.waitForSelector(".user-list__container");
const teamList = await page.$(".user-list__container");
expect(teamList).not.toBeNull();
});

0 comments on commit dd3b0b5

Please sign in to comment.