Skip to content

Commit

Permalink
Merge pull request #2625 from NationalSecurityAgency/t#2490/cards_sec…
Browse files Browse the repository at this point in the history
…tions_and_more

T#2490/cards sections and more
  • Loading branch information
sudo-may authored Jul 8, 2024
2 parents 73bbb52 + a55ac4b commit 8aebf63
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 74 deletions.
2 changes: 1 addition & 1 deletion dashboard-prime/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SkillTree</title>
</head>
<body class="surface-ground m-0">
<body class="m-0">
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion dashboard-prime/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const isDashboardFooter = computed(() => notSkillsClient.value && !isLoadingApp.
</script>

<template>
<div role="presentation" class="m-0">
<div role="presentation" class="m-0 surface-ground">
<VueAnnouncer class="sr-only" />

<customizable-header v-if="isCustomizableHeader" role="region" aria-label="dynamic customizable header"></customizable-header>
Expand Down
14 changes: 11 additions & 3 deletions dashboard-prime/src/components/myProgress/MyCurrentProjects.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ProjectService from '@/components/projects/ProjectService.js'
import ProjectLinkCard from '@/components/myProgress/ProjectLinkCard.vue'
import Sortable from 'sortablejs'
import SkillsSpinner from '@/components/utils/SkillsSpinner.vue'
import Badge from '@/components/badges/Badge.vue'
const myProgressState = useMyProgressState()
const elementHelper = useElementHelper()
Expand Down Expand Up @@ -88,18 +89,18 @@ const projectOrderUpdate = (projectId, newIndex) => {
v-if="sortOrderLoading"
aria-label="Updating sort order"
class="loading-indicator" />
<div class="grid" id="projectCards">
<div class="flex flex-wrap gap-3 align-items-stretch justify-content-center" id="projectCards">
<div v-for="(proj, index) in myProgressState.myProjects"
:key="proj.projectName"
:id="proj.projectId"
class="col">
class="flex-1 project-link-container">
<project-link-card
:ref="`proj${proj.projectId}`"
:display-order="index"
@sort-changed-requested="updateSortAndReloadProjects"
:proj="proj"
class="fadein animation-duration-500" />
class="h-full" />
</div>
</div>
</BlockUI>
Expand All @@ -118,4 +119,11 @@ const projectOrderUpdate = (projectId, newIndex) => {
bottom: 0;
right: 0;
}
@media (min-width: 50rem) {
.project-link-container {
min-width: 32rem;
max-width: 50rem;
}
}
</style>
126 changes: 67 additions & 59 deletions dashboard-prime/src/components/myProgress/ProjectLinkCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ limitations under the License.
<script setup>
import { computed, ref } from 'vue'
import { useNumberFormat } from '@/common-components/filter/UseNumberFormat.js'
import CardWithVericalSections from '@/components/utils/cards/CardWithVericalSections.vue'
import { useMyProgressState } from '@/stores/UseMyProgressState.js'
const props = defineProps(['proj', 'displayOrder'])
const emit = defineEmits(['sort-changed-requested'])
const numberFormat = useNumberFormat()
const myProgressState = useMyProgressState()
const showSortControl = computed(() => myProgressState.myProjects.length > 1)
const overSortControl = ref(false)
const series = [0]
Expand All @@ -28,7 +33,7 @@ const chartOptions = {
height: 200,
type: 'radialBar',
offsetY: -15,
offsetX: 0
offsetX: -15
},
plotOptions: {
radialBar: {
Expand Down Expand Up @@ -90,45 +95,46 @@ const currentProgressPercent = computed(() => Math.trunc(props.proj.points / pro
</script>

<template>
<Card :pt="{ content: { class: 'p-0' }, body: { class: 'p-0 pb-2' } }"
<CardWithVericalSections
:data-cy="`project-link-card-${proj.projectId}`"
class="conic"
:class="{ 'proj-link-card' : !overSortControl }">
<template #header v-if="showSortControl">
<div class="flex">
<div class="flex-1">
<SkillsButton
:id="`sortControlHandle-${proj.projectId}`"
text
icon="fas fa-arrows-alt"
severity="secondary"
class="pl-2 pr-3 sort-control border-top-none border-left-none border-right-1 border-bottom-1 surface-border text-color-secondary"
:aria-label="`Sort Control. Current position for ${proj.projectName} is ${displayOrder}. Press up or down to change the order.`"
size="large"
data-cy="sortControlHandle"
@keyup.down="moveDown"
@keyup.up="moveUp"
></SkillsButton>
</div>
<div class="text-right">
<!-- todo: support of project removal -->
<!-- <SkillsButton-->
<!-- text-->
<!-- icon="far fa-times-circle"-->
<!-- severity="secondary"-->
<!-- class="pr-3 pt-2"-->
<!-- :aria-label="`Remove ${proj.projectName} from My Projects`"-->
<!-- size="large"></SkillsButton>-->
</div>
</div>
</template>
<template #content>
<div>
<div class="flex">
<div class="flex-1">
<SkillsButton
:id="`sortControlHandle-${proj.projectId}`"
text
icon="fas fa-arrows-alt"
severity="secondary"
class="pl-2 pr-3 sort-control border-top-none border-left-none border-right-1 border-bottom-1 surface-border text-color-secondary"
:aria-label="`Sort Control. Current position for ${proj.projectName} is ${displayOrder}. Press up or down to change the order.`"
size="large"
data-cy="sortControlHandle"
@keyup.down="moveDown"
@keyup.up="moveUp"
></SkillsButton>
</div>
<div class="text-right">
<!-- todo: support of project removal -->
<!-- <SkillsButton-->
<!-- text-->
<!-- icon="far fa-times-circle"-->
<!-- severity="secondary"-->
<!-- class="pr-3 pt-2"-->
<!-- :aria-label="`Remove ${proj.projectName} from My Projects`"-->
<!-- size="large"></SkillsButton>-->
</div>
<div :class="{'pt-4': !showSortControl }">

</div>
<div class="flex">
<div class="flex-grow-0 pt-3" style="width: 200px;">
<apexchart type="radialBar" height="200" :options="chartOptions"
<div class="pt-3" style="min-width: 200px;">
<apexchart type="radialBar" height="200" width="200" :options="chartOptions"
:series="series"></apexchart>
</div>
<div class="flex-grow-1 pt-0 pr-3 text-right">
<div class="flex-1 pt-0 pr-3 text-right">
<div class="uppercase text-2xl text-primary" data-cy="project-card-project-name"
:aria-label="`Project ${proj.projectName}`" :title="proj.projectName ">{{ proj.projectName }}
</div>
Expand All @@ -143,37 +149,39 @@ const currentProgressPercent = computed(() => Math.trunc(props.proj.points / pro
</div>
</div>

<div class="text-right mx-3" style="marginTop: -30px">
<div :id="`projectProgressLabel_${proj.projectId}`"
class="small mb-1"
:aria-label="`${proj.points} out of ${proj.totalPoints} available points`"
data-cy="project-card-project-points">
<span class="text-xl text-orange-700">{{ numberFormat.pretty(proj.points) }}</span>
<span>/</span>
<span>{{ numberFormat.pretty(proj.totalPoints) }}</span>
</div>
<ProgressBar
:value="currentProgressPercent"
:aria-label="`${currentProgressPercent} percent complete`"
style="height: 6px" />
</div>

<div class="px-3 w-full text-center mt-4">
<router-link tabindex="-1"
:to="{ path: `/progress-and-rankings/projects/${proj.projectId}` }"
:data-cy="`project-link-${proj.projectId}`">
<Button
label="View"
icon="far fa-eye"
:aria-label="`Click to navigate to ${proj.projectName} project page.`"
outlined class="w-full" size="small"/>
</router-link>
</div>

</div>
</template>
<template #footer>
<div class="text-right mx-3">
<div :id="`projectProgressLabel_${proj.projectId}`"
class="small mb-1"
:aria-label="`${proj.points} out of ${proj.totalPoints} available points`"
data-cy="project-card-project-points">
<span class="text-xl text-orange-700">{{ numberFormat.pretty(proj.points) }}</span>
<span>/</span>
<span>{{ numberFormat.pretty(proj.totalPoints) }}</span>
</div>
<ProgressBar
:value="currentProgressPercent"
:aria-label="`${currentProgressPercent} percent complete`"
style="height: 6px" />
</div>

<div class="px-3 w-full text-center pt-4 pb-3">
<router-link tabindex="-1"
:to="{ path: `/progress-and-rankings/projects/${proj.projectId}` }"
:data-cy="`project-link-${proj.projectId}`">
<Button
label="View"
icon="far fa-eye"
:aria-label="`Click to navigate to ${proj.projectName} project page.`"
outlined class="w-full" size="small"/>
</router-link>
</div>
</template>
</Card>
</CardWithVericalSections>
</template>

<style scoped>
Expand Down
17 changes: 7 additions & 10 deletions dashboard-prime/src/components/settings/ProjectSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ let settings = ref({
projectId: route.params.projectId,
},
});
let errMsg = ref(null);
let showSavedMsg = ref(false);
const errMsg = ref(null);
const showSavedMsg = ref(false);
// computed
const isDirty = computed(() => {
Expand Down Expand Up @@ -630,15 +630,12 @@ const saveSettings = ((dirtyChanges) => {
<SkillsButton variant="outline-success" @click="save" :disabled="!meta.valid || !isDirty" data-cy="saveSettingsBtn" icon="fas fa-arrow-circle-right" label="Save">
</SkillsButton>
<span v-if="isDirty" class="text-warning ml-2" data-cy="unsavedChangesAlert">
<i class="fa fa-exclamation-circle"
aria-label="Settings have been changed, do not forget to save"
v-tooltip="'Settings have been changed, do not forget to save'"/> Unsaved Changes
</span>
<span v-if="!isDirty && showSavedMsg" class="text-success ml-2" data-cy="settingsSavedAlert">
<i class="fa fa-check" />
<InlineMessage v-if="isDirty" class="ml-2" data-cy="unsavedChangesAlert" severity="warn" icon="fa fa-exclamation-circle">
Unsaved Changes
</InlineMessage>
<InlineMessage v-if="!isDirty && showSavedMsg" class="ml-2" data-cy="settingsSavedAlert" severity="success" icon="fa fa-check">
Settings Updated!
</span>
</InlineMessage>
</div>
</div>
</loading-container>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright 2024 SkillTree

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
<script setup>
</script>

<template>
<Card :pt="{ content: { class: 'p-0 h-full' }, body: { class: 'p-0 h-full' } }">
<template #content>
<div class="flex flex-column h-full">
<div>
<slot name="header"></slot>
</div>
<div class="flex-1">
<slot name="content"></slot>
</div>
<div>
<slot name="footer"></slot>
</div>
</div>
</template>
</Card>
</template>

<style scoped>
</style>

0 comments on commit 8aebf63

Please sign in to comment.