UNCLASSIFIED
Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
Platform One
P
Party Bus
Launchboard
launchboard-fe
Commits
e624c051
Commit
e624c051
authored
Sep 02, 2021
by
Michael Winberry
Browse files
Merge branch 'master' into Valkyrie
parents
b86406f4
bfd390a0
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
437 additions
and
69 deletions
+437
-69
package-lock.json
package-lock.json
+81
-15
src/App.vue
src/App.vue
+1
-2
src/api/http-common.js
src/api/http-common.js
+1
-1
src/components/EditableInput.vue
src/components/EditableInput.vue
+3
-2
src/components/LaunchboardSettings.vue
src/components/LaunchboardSettings.vue
+1
-2
src/components/ProjectsSummary.vue
src/components/ProjectsSummary.vue
+154
-1
src/components/Section.vue
src/components/Section.vue
+1
-0
src/components/UserBanner.vue
src/components/UserBanner.vue
+5
-30
src/components/UserSelect.vue
src/components/UserSelect.vue
+1
-1
src/views/Projects.vue
src/views/Projects.vue
+40
-0
src/views/Team.vue
src/views/Team.vue
+7
-1
src/views/TrainingDetails.vue
src/views/TrainingDetails.vue
+15
-7
src/views/super-admin/Teams.vue
src/views/super-admin/Teams.vue
+1
-1
src/views/user/LaunchboardUser.vue
src/views/user/LaunchboardUser.vue
+30
-0
tests/e2e/fixtures/api/teams.json
tests/e2e/fixtures/api/teams.json
+0
-2
tests/e2e/fixtures/api/users.json
tests/e2e/fixtures/api/users.json
+0
-1
tests/e2e/fixtures/users/admin.json
tests/e2e/fixtures/users/admin.json
+0
-1
tests/e2e/fixtures/users/superAdmin.json
tests/e2e/fixtures/users/superAdmin.json
+0
-1
tests/e2e/fixtures/users/user.json
tests/e2e/fixtures/users/user.json
+0
-1
tests/unit/components/ProjectsSummary.spec.js
tests/unit/components/ProjectsSummary.spec.js
+96
-0
No files found.
package-lock.json
View file @
e624c051
...
...
@@ -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+VSOqEAFt5w
g==",
"version": "7.5.
4
",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.
4
.tgz",
"integrity": "sha512-
zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljoh
g==",
"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+VSOqEAFt5w
g=="
"version": "7.5.
4
",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.
4
.tgz",
"integrity": "sha512-
zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljoh
g=="
}
}
},
...
...
@@ -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+VSOqEAFt5w
g==",
"version": "7.5.
4
",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.
4
.tgz",
"integrity": "sha512-
zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljoh
g==",
"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+VSOqEAFt5w
g==",
"version": "7.5.
4
",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.
4
.tgz",
"integrity": "sha512-
zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljoh
g==",
"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+VSOqEAFt5w
g==",
"version": "7.5.
4
",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.
4
.tgz",
"integrity": "sha512-
zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljoh
g==",
"dev": true
}
}
...
...
src/App.vue
View file @
e624c051
...
...
@@ -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
;
}
},
},
...
...
src/api/http-common.js
View file @
e624c051
...
...
@@ -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
;
...
...
src/components/EditableInput.vue
View file @
e624c051
...
...
@@ -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
;
}
...
...
src/components/LaunchboardSettings.vue
View file @
e624c051
...
...
@@ -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
:
{
...
...
src/components/ProjectsSummary.vue
View file @
e624c051
...
...
@@ -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
>
src/components/Section.vue
View file @
e624c051
...
...
@@ -20,6 +20,7 @@
</
template
>
<span>
Refresh
</span>
</v-tooltip>
<slot
name=
"header-bar-icons"
>
</slot>
<v-btn
v-if=
"!hideCollapse && !hideCollapseButton"
icon
...
...
src/components/UserBanner.vue
View file @
e624c051
...
...
@@ -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>
...
...
src/components/UserSelect.vue
View file @
e624c051
...
...
@@ -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
...
...
src/views/Projects.vue
View file @
e624c051
...
...
@@ -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
;
},
...
...
src/views/Team.vue
View file @
e624c051
<
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
,
...
...
src/views/TrainingDetails.vue
View file @
e624c051
<
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
};
...
...
src/views/super-admin/Teams.vue
View file @
e624c051
...
...
@@ -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"
...
...
src/views/user/LaunchboardUser.vue
View file @
e624c051
...
...
@@ -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
();
},
...
...
tests/e2e/fixtures/api/teams.json
View file @
e624c051
...
...
@@ -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
,
...
...
tests/e2e/fixtures/api/users.json
View file @
e624c051
...
...
@@ -9,7 +9,6 @@
"users"
:
[
{
"id"
:
2
,
"keycloakId"
:
"aaaaaaaa-56ff-4ddb-803a-8a1f4b73014e"
,
"picture"
:
null
,
"name"
:
"Test Admin"
,
"personnelType"
:
"P1 Personnel"
,
...
...
tests/e2e/fixtures/users/admin.json
View file @
e624c051
{
"result"
:
{
"id"
:
1
,
"keycloakId"
:
"aaaaaaaa-da97-4f57-b322-5e2685be6591"
,
"picture"
:
null
,
"name"
:
"Test Admin"
,
"personnelType"
:
null
,
...
...
tests/e2e/fixtures/users/superAdmin.json
View file @
e624c051
{
"result"
:
{
"id"
:
1
,
"keycloakId"
:
"aaaaaaaa-da97-4f57-c322-5e2685be6591"
,
"picture"
:
null
,
"name"
:
"Test Super Admin"
,
"personnelType"
:
null
,
...
...
tests/e2e/fixtures/users/user.json
View file @
e624c051
{
"result"
:
{
"id"
:
1
,
"keycloakId"
:
"aaaaaaaa-da97-4f57-a322-5e2685be6591"
,
"picture"
:
null
,
"name"
:
"Test User"
,
"personnelType"
:
null
,
...
...
tests/unit/components/ProjectsSummary.spec.js
View file @
e624c051
...
...
@@ -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
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment