UNCLASSIFIED

Commit e624c051 authored by Michael Winberry's avatar Michael Winberry
Browse files

Merge branch 'master' into Valkyrie

parents b86406f4 bfd390a0
......@@ -320,6 +320,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -4267,6 +4273,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -5144,6 +5156,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz",
"integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==",
"dev": true
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
}
}
},
......@@ -6216,6 +6234,12 @@
}
}
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -7276,6 +7300,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -12310,9 +12340,9 @@
},
"dependencies": {
"ws": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
"integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==",
"dev": true
}
}
......@@ -12346,9 +12376,9 @@
}
},
"ws": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg=="
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
"integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg=="
}
}
},
......@@ -12897,9 +12927,9 @@
"dev": true
},
"ws": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
"integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==",
"dev": true
}
}
......@@ -15329,6 +15359,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001244.tgz",
"integrity": "sha512-Wb4UFZPkPoJoKKVfELPWytRzpemjP/s0pe22NriANru1NoI+5bGNxzKtk7edYL8rmCWTfQO8eRiF0pn1Dqzx7Q=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -15726,6 +15762,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -15889,6 +15931,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -16368,6 +16416,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -16569,6 +16623,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -19105,6 +19165,12 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz",
"integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA=="
},
"colorette": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.811",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz",
......@@ -21437,9 +21503,9 @@
"dev": true
},
"ws": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
"integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==",
"dev": true
}
}
......@@ -21715,9 +21781,9 @@
}
},
"ws": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz",
"integrity": "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==",
"dev": true
}
}
......
......@@ -26,8 +26,7 @@ export default {
syncDarkMode() {
// make sure vuetify matches the current preference
if (this.$store && this.$store.state.userPreferences.userPreference) {
this.$vuetify.theme.dark =
this.$store.state.userPreferences.userPreference.darkMode;
this.$vuetify.theme.dark = this.$store.state.userPreferences.userPreference.darkMode;
}
},
},
......
......@@ -16,7 +16,7 @@ HTTP.interceptors.response.use(
// If err.status does not exist a general networking error occurred.
// We'll assume that their keycloak session has expired, so refresh the
// page which will redirect them to login
if (!err.status) {
if (!err.status && !err.response?.status) {
location.reload();
} else {
throw err;
......
......@@ -95,8 +95,9 @@ export default {
if (!this.$refs.editingElementWrapper) {
return null;
}
const editInputs =
this.$refs.editingElementWrapper.getElementsByTagName("input");
const editInputs = this.$refs.editingElementWrapper.getElementsByTagName(
"input"
);
if (!editInputs || editInputs.length === 0) {
return null;
}
......
......@@ -84,8 +84,7 @@ export default {
mounted() {
this.user = this.$store.state.user.user;
this.darkMode = this.$store.state.userPreferences.userPreference.darkMode;
this.welcomeMenu =
this.$store.state.userPreferences.userPreference.welcomeMessage;
this.welcomeMenu = this.$store.state.userPreferences.userPreference.welcomeMessage;
this.changeLoadingColor();
},
methods: {
......
......@@ -25,7 +25,13 @@
and star the projects that you are interested in.</v-card-text
>
</v-card>
<v-expansion-panels accordion multiple hover flat v-else>
<v-expansion-panels
accordion
multiple
hover
flat
v-else-if="this.panelView === true"
>
<v-expansion-panel
v-for="(project, index) in filteredProjects"
:key="index"
......@@ -231,6 +237,100 @@
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
<v-row class="justify-content-center" v-else-if="this.cardView === true">
<v-col
v-for="(project, index) in filteredProjects"
:lg="projectCardColumnLgCount"
:key="index"
:project="project"
:cols="12"
>
<v-card class="card">
<div
v-bind:class="{
'project-card-header-failed':
project.latestPipeline.status === 'failed',
'project-card-header-passed':
project.latestPipeline.status === 'passed',
}"
>
<v-card-title class="justify-content-center project-card-title">
<div>
<p>
{{ project.name }}
</p>
<v-row class="justify-content-center">
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<v-btn
icon
:href="project.links.repo"
rel="noopener noreferer"
target="_blank"
v-bind="attrs"
v-on="on"
@click.native.stop
color="primary"
>
<v-icon small>$vuetify.icons.gitlab</v-icon>
</v-btn>
</template>
<span>GitLab repository</span>
</v-tooltip>
</v-row>
</div>
</v-card-title>
</div>
<v-card-actions>
<v-layout row justify-center class="project-card-detail">
<v-card-text v-if="project.latestPipeline">
<div class="project-card-text">
Pipeline: {{ project.latestPipeline.message }}
</div>
</v-card-text>
<v-tooltip bottom>
<template v-slot:activator="{ on, attrs }">
<span v-bind="attrs" v-on="on">
<GitLabIcon
v-if="
project.latestPipeline.status === 'running' ||
project.latestPipeline.status === 'pending'
"
class="status-icon"
:status="'running'"
/>
<GitLabIcon
v-if="project.latestPipeline.status === 'failed'"
class="status-icon"
:status="'failed'"
/> </span
></template>
<span>
Latest Pipeline: {{ project.latestPipeline.status }}
</span>
</v-tooltip>
<router-link
class="project-title"
target="_blank"
v-for="(
job, jIndex
) in retrieveFailedProjectJobsFromFailedPipeline(project)"
:key="jIndex"
:to="job.link"
>
<a
class="project-card-text"
:href="job.link"
rel="noopener noreferer"
target="_blank"
>{{ job.name }};
</a>
</router-link>
</v-layout>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-skeleton-loader>
</v-container>
</template>
......@@ -248,6 +348,10 @@ export default {
ErrorMessage,
},
props: {
projectCardColumnLgCount: {
type: Number,
default: 4,
},
detailed: {
type: Boolean,
default: true,
......@@ -258,6 +362,8 @@ export default {
},
data: () => ({
loading: false,
panelView: false,
cardView: true,
emptyString: false,
error: false,
errorMessage: "",
......@@ -281,11 +387,13 @@ export default {
async refreshProjects() {
if (this.setProjectLoading) {
this.setProjectLoading(true);
this.loading = true;
}
this.error = false;
this.emptyString = false;
try {
const projects = await ProjectService.getProjectsSummary();
this.failedProjectJobs = this.projects;
if (projects) {
this.setProjects(projects);
}
......@@ -299,6 +407,22 @@ export default {
}
if (this.setProjectLoading) {
this.setProjectLoading(false);
this.loading = false;
}
},
setCardView() {
this.panelView = false;
this.cardView = true;
},
setPanelView() {
this.panelView = true;
this.cardView = false;
},
retrieveFailedProjectJobsFromFailedPipeline(project) {
if (project.latestPipeline.status === "failed") {
return (project.latestPipeline.jobs || []).filter(
(o) => o.status === "failed"
);
}
},
},
......@@ -330,6 +454,35 @@ export default {
.status-icon {
width: 24px;
height: 24px;
margin-right: 10px;
}
.project-card-header-passed {
background-color: map-get($material-light, "background-accent-1");
color: map-get($material-light, "secondary-text-color");
fill: map-get($material-light, "secondary-text-color");
}
.project-card-header-failed {
background-color: #ff3838;
color: map-get($material-light, "secondary-text-color");
fill: map-get($material-light, "secondary-text-color");
}
.project-card-title {
padding-bottom: 20px;
}
.project-card-detail {
padding-top: 30px;
padding-bottom: 45px;
padding-left: 45px;
padding-right: 45px;
}
.project-card-text {
font-size: medium;
}
.card {
min-height: 100%;
min-width: 100%;
max-width: 400px;
margin: auto;
}
}
</style>
......@@ -20,6 +20,7 @@
</template>
<span>Refresh</span>
</v-tooltip>
<slot name="header-bar-icons"> </slot>
<v-btn
v-if="!hideCollapse && !hideCollapseButton"
icon
......
......@@ -13,12 +13,7 @@
>
<div class="d-flex banner-row subhead section-header">
<div
class="
d-flex
align-items-center
flex-wrap flex-sm-nowrap
name-container
"
class="d-flex align-items-center flex-wrap flex-sm-nowrap name-container"
>
<v-avatar class="mr-2 mr-md-4">
<img v-if="avatar" :src="avatar" :alt="name" />
......@@ -28,23 +23,13 @@
</div>
<div
v-if="$vuetify.breakpoint.mdAndUp"
class="
d-flex
align-items-center
justify-content-center
company-container
"
class="d-flex align-items-center justify-content-center company-container"
>
{{ company }}
</div>
<div
v-if="$vuetify.breakpoint.mdAndUp"
class="
d-flex
align-items-center
justify-content-center
position-container
"
class="d-flex align-items-center justify-content-center position-container"
>
{{ position }}
</div>
......@@ -59,22 +44,12 @@
>
<div class="d-flex banner-row subhead section-content">
<div
class="
d-flex
align-items-center
justify-content-center
company-container
"
class="d-flex align-items-center justify-content-center company-container"
>
{{ company }}
</div>
<div
class="
d-flex
align-items-center
justify-content-center
position-container
"
class="d-flex align-items-center justify-content-center position-container"
>
{{ position }}
</div>
......
......@@ -49,7 +49,7 @@
<img v-if="item.avatar" :src="item.avatar" :alt="data.item.name" />
<v-icon x-large v-else>mdi-account-circle</v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-content>
<v-list-item-title class="text-left">{{ item.name }}</v-list-item-title>
<v-list-item-subtitle class="text-left">{{
item.email
......
......@@ -15,10 +15,44 @@
:loading="loadingProjectData"
:refreshClick="refreshProjectData"
>
<div
class="align-items-center d-flex"
slot="header-bar-icons"
:cardViewProjects="cardViewProjects"
:panelViewProjects="panelViewProjects"
>
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<v-btn
icon
v-bind="attrs"
v-on="on"
@click="cardViewProjects"
>
<v-icon>mdi-view-grid</v-icon>
</v-btn>
</template>
<span>Card View</span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<v-btn
icon
v-bind="attrs"
v-on="on"
@click="panelViewProjects"
>
<v-icon>mdi-reorder-horizontal</v-icon>
</v-btn>
</template>
<span>Panel View</span>
</v-tooltip>
</div>
<ProjectsSummary
slot="content"
ref="projectSummary"
:setProjectLoading="setProjectLoading"
:projectCardColumnLgCount="4"
detailed
/>
</Section>
......@@ -58,6 +92,12 @@ export default {
refreshProjectData() {
this.$refs.projectSummary.refreshProjects();
},
cardViewProjects() {
this.$refs.projectSummary.setCardView();
},
panelViewProjects() {
this.$refs.projectSummary.setPanelView();
},
setProjectLoading(loading) {
this.loadingProjectData = loading;
},
......
<template>
<div>
<v-container class="team">
<div v-if="!Object.entries(team).length">
<NotFoundComponent />
</div>
<v-container class="team" v-else>
<div class="d-flex flex-column justify-center align-top flex-sm-row mb-4">
<div>
<h1
......@@ -304,6 +308,7 @@ import SelectAddStudentsToCourseDialog from "@/components/Dialogs/SelectAddStude
import TeamService from "@/api/services/team";
import UserSelect from "@/components/UserSelect";
import AddTeam from "@/components/AddTeam";
import NotFoundComponent from "@/components/NotFoundComponent";
import { defaultSnackbarTimeout } from "@/config/config";
import inputRules from "@/utils/inputRules";
import Permission from "@/config/user-permissions";
......@@ -317,6 +322,7 @@ export default {
SelectAddStudentsToCourseDialog,
AddTeam,
BaseDialog,
NotFoundComponent,
},
data: () => ({
editValid: false,
......
<template>
<div>
<v-container class="course">
<div v-if="!Object.entries(trainingCourse).length">
<NotFoundComponent />
</div>
<v-container class="course" v-else>
<v-skeleton-loader
:loading="initialLoad"
type="table-heading,table-thead, table-tbody"
......@@ -384,6 +387,7 @@
import moment from "moment";
import TrainingService from "@/api/services/training";
import inputRules from "@/utils/inputRules";
import NotFoundComponent from "@/components/NotFoundComponent";
import TrainingAttendance from "@/components/Training/TrainingAttendance";
import { SET_ERROR_MESSAGE, SET_ERROR_DIALOG } from "@/store/mutation-types";
import UserSelect from "@/components/UserSelect";
......@@ -391,7 +395,12 @@ import { DEFAULT_PAGINATION_PARAMS } from "@/config/table-constants";
import AddStudentsToCourseDialog from "@/components/Dialogs/AddStudentsToCourseDialog";
export default {
components: { AddStudentsToCourseDialog, TrainingAttendance, UserSelect },
components: {
AddStudentsToCourseDialog,
TrainingAttendance,
UserSelect,
NotFoundComponent,
},
data: () => ({
selectedInstructors: [],
loading: false,
......@@ -529,11 +538,10 @@ export default {
},
async fetchStudentData() {
try {
const studentResponse =
await TrainingService.getCourseRegistrationsById(
this.$route.params.trainingId,
{ ...this.params, attendance: true }
);
const studentResponse = await TrainingService.getCourseRegistrationsById(
this.$route.params.trainingId,
{ ...this.params, attendance: true }
);
this.listItems =
studentResponse.registrations?.map((item) => {
item.completed = { value: item.completed, loading: false };
......
......@@ -69,7 +69,6 @@
:add-busy="state.isAddingBusy"
/>
</template>
<template v-slot:[`item.name`]="{ item }">
<router-link
:to="{ name: 'TeamDetails', params: { teamId: item.id } }"
......@@ -93,6 +92,7 @@
>
</div>
</template>
<template v-slot:[`item.email`]="{ item }" class="team-leads">
<div
class="d-flex flex-wrap white-space-nowrap"
......
......@@ -59,6 +59,29 @@
:refreshClick="refreshProjectData"
headerTitle="My Project Summary"
>
<div
class="align-items-center d-flex"
slot="header-bar-icons"
:cardViewProjects="cardViewProjects"
:panelViewProjects="panelViewProjects"
>
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on" @click="cardViewProjects">
<v-icon>mdi-view-grid</v-icon>
</v-btn>
</template>
<span>Card View</span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on" @click="panelViewProjects">
<v-icon>mdi-reorder-horizontal</v-icon>
</v-btn>
</template>
<span>Panel View</span>
</v-tooltip>
</div>
<span slot="userinfo">
<TutorialTooltip tooltipName="projects">
<span id="projectsTutorialTooltip"></span>
......@@ -68,6 +91,7 @@
slot="content"
ref="projectSummary"
:setProjectLoading="setProjectLoading"
:projectCardColumnLgCount="6"
/>
</Section>
......@@ -135,6 +159,12 @@ export default {
refreshProjectData() {
this.$refs.projectSummary.refreshProjects();
},
cardViewProjects() {
this.$refs.projectSummary.setCardView();
},
panelViewProjects() {
this.$refs.projectSummary.setPanelView();
},
refreshCurriculumSchedule() {
this.$refs.curriculumSchedule.refreshCurriculumSchedule();
},
......
......@@ -9,7 +9,6 @@
"members": [
{
"id": 1,
"keycloakId": "aaaaaaaa-da97-4f57-a322-5e2685be6591",
"picture": null,
"name": "Test User",
"personnelType": null,
......@@ -33,7 +32,6 @@
},
{
"id": 2,
"keycloakId": "bbbbbbbb-da97-4f57-a322-5e2685be6591",
"picture": null,
"name": "Test Admin",
"personnelType": null,
......
......@@ -9,7 +9,6 @@
"users": [
{
"id": 2,
"keycloakId": "aaaaaaaa-56ff-4ddb-803a-8a1f4b73014e",
"picture": null,
"name": "Test Admin",
"personnelType": "P1 Personnel",
......
{
"result": {
"id": 1,
"keycloakId": "aaaaaaaa-da97-4f57-b322-5e2685be6591",
"picture": null,
"name": "Test Admin",
"personnelType": null,
......
{
"result": {
"id": 1,
"keycloakId": "aaaaaaaa-da97-4f57-c322-5e2685be6591",
"picture": null,
"name": "Test Super Admin",
"personnelType": null,
......
{
"result": {
"id": 1,
"keycloakId": "aaaaaaaa-da97-4f57-a322-5e2685be6591",
"picture": null,
"name": "Test User",
"personnelType": null,
......
......@@ -35,6 +35,102 @@ describe("ProjectsSummary", () => {
expect(wrapper.find(".error").exists()).toBe(false);
});
it("should set panelView true and cardView false", () => {
ProjectService.getProjectsSummary = jest.fn();
// render the component
const wrapper = shallowMount(ProjectsSummary, {
mocks: {
$store: {
state: {
error: {},
projects: {
list: [],
},
},
commit: jest.fn(),
},
},
data() {
return {
cardView: true,
panelView: false,
};
},
localVue,
vuetify,
});
wrapper.vm.setPanelView();
expect(
wrapper.vm.panelView === true && wrapper.vm.cardView === false
).toBeTruthy();
});
it("should set panelView false and cardView true", () => {
ProjectService.getProjectsSummary = jest.fn();
// render the component
const wrapper = shallowMount(ProjectsSummary, {
mocks: {
$store: {
state: {
error: {},
projects: {
list: [],
},
},
commit: jest.fn(),
},
},
data() {
return {
cardView: true,
panelView: false,
};
},
localVue,
vuetify,
});
wrapper.vm.setCardView();
expect(
wrapper.vm.panelView === false && wrapper.vm.cardView === true
).toBeTruthy();
});
it("should return only failed jobs from a failed pipeline given a project", () => {
ProjectService.getProjectsSummary = jest.fn();
// render the component
const wrapper = shallowMount(ProjectsSummary, {
mocks: {
$store: {
state: {
error: {},
projects: {
list: [],
},
},
commit: jest.fn(),
},
},
localVue,
vuetify,
});
const failedProjectJobs = wrapper.vm.retrieveFailedProjectJobsFromFailedPipeline(
{
id: "1",
links: {},
latestPipeline: {
name: "testPipeline",
status: "failed",
latestPipeline: "",
message: "test",
jobs: [
{ name: "e2e-test", status: "failed", link: "" },
{ name: "e2e-test2", status: "passed", link: "" },
],
},
favorite: true,
}
);
expect(failedProjectJobs.length === 1).toBeTruthy();
});
it("should filter by favorited projects", () => {
ProjectService.getProjectsSummary = jest.fn();
// render the component
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment