feat(falukant): implement score threshold logic and enhance UI feedback for certificate progression
All checks were successful
Deploy to production / deploy (push) Successful in 3m3s
All checks were successful
Deploy to production / deploy (push) Successful in 3m3s
- Added a new function to calculate score thresholds based on certificate levels, improving the logic for determining promotion eligibility. - Updated the FalukantService to include new properties for score and requirement checks, enhancing the decision-making process for certificate readiness. - Enhanced the OverviewView component to display detailed hints and states regarding certificate progression, providing users with clearer feedback on their status. - Localized new strings in multiple languages to support the updated UI elements and hints, improving user experience across different languages.
This commit is contained in:
@@ -112,12 +112,13 @@
|
||||
<div class="certificate-panel__score">
|
||||
<span>{{ $t('falukant.overview.certificate.score') }}</span>
|
||||
<strong>{{ certificateProgress.score }}</strong>
|
||||
<span class="certificate-panel__state" :class="{ 'is-ready': certificateProgress.readyForNextCertificate }">
|
||||
{{ certificateProgress.readyForNextCertificate
|
||||
? $t('falukant.overview.certificate.ready')
|
||||
: $t('falukant.overview.certificate.notReady') }}
|
||||
<span class="certificate-panel__state" :class="certificateProgressStateClass">
|
||||
{{ $t(`falukant.overview.certificate.state.${certificateProgressStateKey}`) }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="certificate-panel__hint">
|
||||
{{ certificateProgressHint }}
|
||||
</p>
|
||||
|
||||
<div class="certificate-panel__grid">
|
||||
<article class="certificate-panel__block">
|
||||
@@ -157,6 +158,13 @@
|
||||
<article class="certificate-panel__block">
|
||||
<h4>{{ $t('falukant.overview.certificate.requirements') }}</h4>
|
||||
<div class="certificate-requirements">
|
||||
<div
|
||||
class="certificate-requirement"
|
||||
:class="{ 'is-met': certificateProgress.scoreRequirementMet }"
|
||||
>
|
||||
<span>{{ $t('falukant.overview.certificate.scoreGate') }}</span>
|
||||
<strong>{{ formatCertificateRequirement(certificateProgress.score, certificateProgress.nextScoreThreshold) }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-for="requirement in certificateProgress.nextRequirements"
|
||||
:key="requirement.type"
|
||||
@@ -438,6 +446,52 @@ export default {
|
||||
products: entry.products.map((productKey) => this.$t(`falukant.product.${productKey}`)),
|
||||
}));
|
||||
},
|
||||
certificateProgressStateKey() {
|
||||
const progress = this.certificateProgress;
|
||||
if (!progress) return 'notReady';
|
||||
if (progress.readyForNextCertificate) return 'ready';
|
||||
if (progress.minimumRequirementsMet && !progress.scoreRequirementMet) return 'minimumsMetScoreBlocked';
|
||||
if (!progress.minimumRequirementsMet && progress.scoreRequirementMet) return 'scoreMetMinimumsMissing';
|
||||
return 'notReady';
|
||||
},
|
||||
certificateProgressStateClass() {
|
||||
switch (this.certificateProgressStateKey) {
|
||||
case 'ready':
|
||||
return 'is-ready';
|
||||
case 'minimumsMetScoreBlocked':
|
||||
return 'is-warning';
|
||||
case 'scoreMetMinimumsMissing':
|
||||
return 'is-info';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
},
|
||||
certificateProgressHint() {
|
||||
const progress = this.certificateProgress;
|
||||
if (!progress) return '';
|
||||
if (progress.readyForNextCertificate) {
|
||||
return this.$t('falukant.overview.certificate.hint.ready', {
|
||||
next: progress.nextCertificate,
|
||||
threshold: this.formatCertificateValue(progress.nextScoreThreshold, 1),
|
||||
});
|
||||
}
|
||||
if (progress.minimumRequirementsMet && !progress.scoreRequirementMet) {
|
||||
return this.$t('falukant.overview.certificate.hint.minimumsMetScoreBlocked', {
|
||||
next: progress.nextCertificate,
|
||||
target: progress.targetCertificate,
|
||||
threshold: this.formatCertificateValue(progress.nextScoreThreshold, 1),
|
||||
});
|
||||
}
|
||||
if (!progress.minimumRequirementsMet && progress.scoreRequirementMet) {
|
||||
return this.$t('falukant.overview.certificate.hint.scoreMetMinimumsMissing', {
|
||||
next: progress.nextCertificate,
|
||||
});
|
||||
}
|
||||
return this.$t('falukant.overview.certificate.hint.notReady', {
|
||||
next: progress.nextCertificate,
|
||||
threshold: this.formatCertificateValue(progress.nextScoreThreshold, 1),
|
||||
});
|
||||
},
|
||||
routineActions() {
|
||||
return [
|
||||
{
|
||||
@@ -820,7 +874,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.certificate-panel__state {
|
||||
@@ -838,6 +892,21 @@ export default {
|
||||
color: #2f6b3d;
|
||||
}
|
||||
|
||||
.certificate-panel__state.is-warning {
|
||||
background: rgba(185, 99, 24, 0.16);
|
||||
color: #8d5412;
|
||||
}
|
||||
|
||||
.certificate-panel__state.is-info {
|
||||
background: rgba(34, 96, 164, 0.14);
|
||||
color: #21598f;
|
||||
}
|
||||
|
||||
.certificate-panel__hint {
|
||||
margin: 0 0 16px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.certificate-panel__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user