Skip to content

Commit edf0982

Browse files
committed
feat(skills): enhance candidate promotion buttons with loading and disabled states
1 parent a219a8b commit edf0982

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

dashboard/src/components/extension/SkillsSection.vue

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,24 @@
188188
<v-btn size="x-small" color="warning" variant="tonal" @click="evaluateCandidate(item, false)">
189189
{{ tm("skills.neoReject") }}
190190
</v-btn>
191-
<v-btn size="x-small" color="primary" variant="tonal" @click="promoteCandidate(item, 'canary')">
191+
<v-btn
192+
size="x-small"
193+
color="primary"
194+
variant="tonal"
195+
:loading="isCandidatePromoteLoading(item.id, 'canary')"
196+
:disabled="isCandidatePromoting(item.id)"
197+
@click="promoteCandidate(item, 'canary')"
198+
>
192199
Canary
193200
</v-btn>
194-
<v-btn size="x-small" color="primary" variant="tonal" @click="promoteCandidate(item, 'stable')">
201+
<v-btn
202+
size="x-small"
203+
color="primary"
204+
variant="tonal"
205+
:loading="isCandidatePromoteLoading(item.id, 'stable')"
206+
:disabled="isCandidatePromoting(item.id)"
207+
@click="promoteCandidate(item, 'stable')"
208+
>
195209
Stable
196210
</v-btn>
197211
<v-btn
@@ -347,6 +361,7 @@ export default {
347361
status: "",
348362
stage: "",
349363
});
364+
const candidatePromoteLoading = reactive({});
350365
const payloadDialog = reactive({
351366
show: false,
352367
content: "",
@@ -631,10 +646,21 @@ export default {
631646
}
632647
};
633648
649+
const candidatePromoteLoadingKey = (candidateId, stage) => `${candidateId}:${stage}`;
650+
const isCandidatePromoteLoading = (candidateId, stage) =>
651+
!!candidatePromoteLoading[candidatePromoteLoadingKey(candidateId, stage)];
652+
const isCandidatePromoting = (candidateId) =>
653+
isCandidatePromoteLoading(candidateId, "canary") || isCandidatePromoteLoading(candidateId, "stable");
654+
634655
const promoteCandidate = async (candidate, stage) => {
656+
const candidateId = candidate?.id;
657+
if (!candidateId) return;
658+
const loadingKey = candidatePromoteLoadingKey(candidateId, stage);
659+
if (candidatePromoteLoading[loadingKey]) return;
660+
candidatePromoteLoading[loadingKey] = true;
635661
try {
636662
const res = await axios.post("/api/skills/neo/promote", {
637-
candidate_id: candidate.id,
663+
candidate_id: candidateId,
638664
stage,
639665
sync_to_local: true,
640666
});
@@ -650,6 +676,8 @@ export default {
650676
}
651677
} catch (_err) {
652678
showMessage(tm("skills.neoPromoteFailed"), "error");
679+
} finally {
680+
candidatePromoteLoading[loadingKey] = false;
653681
}
654682
};
655683
@@ -818,6 +846,8 @@ export default {
818846
deleteSkill,
819847
evaluateCandidate,
820848
promoteCandidate,
849+
isCandidatePromoteLoading,
850+
isCandidatePromoting,
821851
rollbackRelease,
822852
deactivateRelease,
823853
handleReleaseLifecycleAction,

0 commit comments

Comments
 (0)