fix(app): resolve Bucket A/C/D lint items (trivial / style / Vuetify class)
WS-3 session 1b-ii Task 4 (audit Buckets A, C, D — 26 items resolved
this commit; 24 indent items in useTimeSlotDropdown.ts remain — see
deviations).
Bucket A — Trivial fixes (12 items resolved):
- A.1: second-pass eslint --fix on App.vue resolved 4 multi-attribute
warnings. AppKpiCard / PortalLayout / PublicLayout
lines-around-comment items were attempted via blank-line addition,
but that introduced an equal number of vue/block-tag-newline
errors (the rules conflict at the SFC <script>-tag boundary). The
blank-line additions were reverted; net-zero, the 3 items remain
for a 1b-iii .eslintrc.cjs override decision.
- A.3: 6 unused-imports / unused-vars manual deletes:
* OrganisationSwitcher.vue: removed orphan toggleMenu() function
* CreateShiftDialog.vue: removed unused 'scenario' from destructure
* pages/events/[id]/time-slots/index.vue: removed unused 'event'
slot scope binding (template <#default="{ event }"> → <#default>)
* pages/organisation/companies.vue: removed unused authStore
declaration + import
* pages/platform/activity-log/index.vue: removed unused
search/searchDebounced pair
* PersonDetailPanel.vue:77: removed redundant single-statement
if-braces (curly autofix that the original pass didn't reach)
Bucket C — Style preference (8 items resolved):
- DismissFailureDialog.vue:43: collapsed two consecutive `if cond return false`
branches into `return !(cond)`
- FormFailureDetail.vue:44: replaced `void clipboard.writeText(...)` with
`clipboard.writeText(...).catch(() => {})` — fire-and-forget with
silent rejection (the no-void rule wants the void operator gone;
.catch() handles it semantically).
- AssignShiftDialog.vue:40-46: hasOverlapWarning collapsed from
always-false branching to `computed(() => false)` (the early-return
was dead code; backend enforces the constraint).
- SectionsShiftsPanel.vue:333 + registration-fields.vue:335: rewrote
`:delay-on-touch-only="true"` to attribute-shorthand `delay-on-touch-only`.
- AssignPersonDialog.vue:120-128: collapsed two `if outer { if inner ... }`
pairs into single `if (outer && inner)` form (sonarjs/no-collapsible-if).
- useImpersonationStore.ts:99-104: collapsed the same nested-if pattern
into `if (!data.data.active && state.value)`.
Bucket D — Vuetify utility class rename (5 items, 3 files):
- ml-1 → ms-1 (PersonDetailPanel:271, SectionsShiftsPanel:357,
AssignPersonDialog:496)
- pl-4 → ps-4 (AssignPersonDialog:457)
- ml-auto → ms-auto (AssignPersonDialog:471)
LTR/RTL-aware Vuetify utilities, matching the Vuexy reference idiom.
Tests + typecheck verified green.
Lint baseline: 62 → 36.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -31,8 +31,15 @@ authStore.initialize()
|
|||||||
<VApp :style="`--v-global-theme-primary: ${hexToRgb(global.current.value.colors.primary)}`">
|
<VApp :style="`--v-global-theme-primary: ${hexToRgb(global.current.value.colors.primary)}`">
|
||||||
<!-- Show loading state while validating auth token -->
|
<!-- Show loading state while validating auth token -->
|
||||||
<template v-if="!authStore.isInitialized">
|
<template v-if="!authStore.isInitialized">
|
||||||
<div class="d-flex align-center justify-center" style="min-height: 100vh;">
|
<div
|
||||||
<VProgressCircular indeterminate color="primary" size="48" />
|
class="d-flex align-center justify-center"
|
||||||
|
style="min-height: 100vh;"
|
||||||
|
>
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
size="48"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -53,7 +60,10 @@ authStore.initialize()
|
|||||||
{{ notificationStore.message }}
|
{{ notificationStore.message }}
|
||||||
|
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<VBtn variant="text" @click="notificationStore.hide()">
|
<VBtn
|
||||||
|
variant="text"
|
||||||
|
@click="notificationStore.hide()"
|
||||||
|
>
|
||||||
Close
|
Close
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -40,10 +40,8 @@ const noteRequired = computed(() => reason.value === 'other')
|
|||||||
const canSubmit = computed(() => {
|
const canSubmit = computed(() => {
|
||||||
if (reason.value === null)
|
if (reason.value === null)
|
||||||
return false
|
return false
|
||||||
if (noteRequired.value && note.value.trim() === '')
|
|
||||||
return false
|
|
||||||
|
|
||||||
return true
|
return !(noteRequired.value && note.value.trim() === '')
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(isDialogOpen, open => {
|
watch(isDialogOpen, open => {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const dismissDialogOpen = ref(false)
|
|||||||
|
|
||||||
function copyText(text: string): void {
|
function copyText(text: string): void {
|
||||||
if (navigator?.clipboard)
|
if (navigator?.clipboard)
|
||||||
void navigator.clipboard.writeText(text)
|
navigator.clipboard.writeText(text).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedContext = computed(() => {
|
const formattedContext = computed(() => {
|
||||||
|
|||||||
@@ -27,11 +27,6 @@ const roleColor = (role: string) => ({
|
|||||||
volunteer_coordinator: 'secondary',
|
volunteer_coordinator: 'secondary',
|
||||||
}[role] ?? 'default')
|
}[role] ?? 'default')
|
||||||
|
|
||||||
function toggleMenu() {
|
|
||||||
if (hasMultiple.value)
|
|
||||||
isMenuOpen.value = !isMenuOpen.value
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectOrg(id: string) {
|
function selectOrg(id: string) {
|
||||||
authStore.setActiveOrganisation(id)
|
authStore.setActiveOrganisation(id)
|
||||||
isMenuOpen.value = false
|
isMenuOpen.value = false
|
||||||
|
|||||||
@@ -74,9 +74,8 @@ function calculateAge(dateStr: string): number | null {
|
|||||||
let age = today.getFullYear() - birth.getFullYear()
|
let age = today.getFullYear() - birth.getFullYear()
|
||||||
const monthDiff = today.getMonth() - birth.getMonth()
|
const monthDiff = today.getMonth() - birth.getMonth()
|
||||||
const dayDiff = today.getDate() - birth.getDate()
|
const dayDiff = today.getDate() - birth.getDate()
|
||||||
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
|
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0))
|
||||||
age--
|
age--
|
||||||
}
|
|
||||||
if (age < 0 || age > 130)
|
if (age < 0 || age > 130)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
@@ -269,7 +268,7 @@ function handleManualLink(userId: string) {
|
|||||||
Mogelijke match gevonden
|
Mogelijke match gevonden
|
||||||
<VChip
|
<VChip
|
||||||
size="x-small"
|
size="x-small"
|
||||||
class="ml-1"
|
class="ms-1"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
>
|
>
|
||||||
{{ person.pending_identity_match.confidence_label }}
|
{{ person.pending_identity_match.confidence_label }}
|
||||||
|
|||||||
@@ -37,13 +37,8 @@ const generalError = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Check for overlap warning
|
// Check for overlap warning
|
||||||
const hasOverlapWarning = computed(() => {
|
// This is informational — the backend enforces the actual constraint
|
||||||
if (!selectedPersonId.value || !props.shift)
|
const hasOverlapWarning = computed(() => false)
|
||||||
return false
|
|
||||||
|
|
||||||
// This is informational — the backend enforces the actual constraint
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
const personItems = computed(() =>
|
const personItems = computed(() =>
|
||||||
persons.value.map((p: Person) => ({
|
persons.value.map((p: Person) => ({
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const { data: eventDetail } = useEventDetail(orgIdRef, eventIdRef)
|
|||||||
const sectionRef = computed(() => props.section ?? null)
|
const sectionRef = computed(() => props.section ?? null)
|
||||||
|
|
||||||
// Determine dropdown scenario
|
// Determine dropdown scenario
|
||||||
const { scenario, showInfoTooltip, hasGroups, tooltipText, fetchParams, sortedItems } = useTimeSlotDropdown(
|
const { showInfoTooltip, hasGroups, tooltipText, fetchParams, sortedItems } = useTimeSlotDropdown(
|
||||||
eventDetail,
|
eventDetail,
|
||||||
sectionRef,
|
sectionRef,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ function onSectionCreated(payload: { name: string; redirectedToParent: boolean;
|
|||||||
drag-class="section-drag"
|
drag-class="section-drag"
|
||||||
:animation="200"
|
:animation="200"
|
||||||
:delay="100"
|
:delay="100"
|
||||||
:delay-on-touch-only="true"
|
delay-on-touch-only
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
class="v-list v-list--nav v-list--density-compact"
|
class="v-list v-list--nav v-list--density-compact"
|
||||||
@end="onDragEnd"
|
@end="onDragEnd"
|
||||||
@@ -354,7 +354,7 @@ function onSectionCreated(payload: { name: string; redirectedToParent: boolean;
|
|||||||
<span>{{ element.name }}</span>
|
<span>{{ element.name }}</span>
|
||||||
<span
|
<span
|
||||||
v-if="element.type === 'cross_event' && parentEvent"
|
v-if="element.type === 'cross_event' && parentEvent"
|
||||||
class="text-caption text-medium-emphasis ml-1"
|
class="text-caption text-medium-emphasis ms-1"
|
||||||
>
|
>
|
||||||
· {{ parentEvent.name }}
|
· {{ parentEvent.name }}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -117,15 +117,11 @@ const filteredPersons = computed(() => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedCrowdType.value) {
|
if (selectedCrowdType.value && person.crowd_type?.system_type !== selectedCrowdType.value)
|
||||||
if (person.crowd_type?.system_type !== selectedCrowdType.value)
|
return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showOnlyAvailable.value) {
|
if (showOnlyAvailable.value && (!person.is_available || person.already_assigned))
|
||||||
if (!person.is_available || person.already_assigned)
|
return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showRecommendedOnly.value) {
|
if (showRecommendedOnly.value) {
|
||||||
const hasPreference = person.section_preferences.some(
|
const hasPreference = person.section_preferences.some(
|
||||||
@@ -458,7 +454,7 @@ async function executeAssign(person: AssignablePerson) {
|
|||||||
</template>
|
</template>
|
||||||
<div class="text-body-2 text-white">
|
<div class="text-body-2 text-white">
|
||||||
<strong>Aanbevolen omdat:</strong>
|
<strong>Aanbevolen omdat:</strong>
|
||||||
<ul class="pl-4 mt-1 mb-0">
|
<ul class="ps-4 mt-1 mb-0">
|
||||||
<li
|
<li
|
||||||
v-for="(reason, i) in getRecommendationReasons(person)"
|
v-for="(reason, i) in getRecommendationReasons(person)"
|
||||||
:key="i"
|
:key="i"
|
||||||
@@ -472,7 +468,7 @@ async function executeAssign(person: AssignablePerson) {
|
|||||||
v-if="person.crowd_type"
|
v-if="person.crowd_type"
|
||||||
size="x-small"
|
size="x-small"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
class="ml-auto"
|
class="ms-auto"
|
||||||
>
|
>
|
||||||
{{ person.crowd_type.name }}
|
{{ person.crowd_type.name }}
|
||||||
</VChip>
|
</VChip>
|
||||||
@@ -497,7 +493,7 @@ async function executeAssign(person: AssignablePerson) {
|
|||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
<span
|
<span
|
||||||
v-if="tag.proficiency"
|
v-if="tag.proficiency"
|
||||||
class="ml-1 font-italic"
|
class="ms-1 font-italic"
|
||||||
>
|
>
|
||||||
({{ { beginner: 'beg.', experienced: 'erv.', expert: 'exp.' }[tag.proficiency] }})
|
({{ { beginner: 'beg.', experienced: 'erv.', expert: 'exp.' }[tag.proficiency] }})
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ const settingsTab = computed(() => {
|
|||||||
handle=".drag-handle"
|
handle=".drag-handle"
|
||||||
:animation="200"
|
:animation="200"
|
||||||
:delay="100"
|
:delay="100"
|
||||||
:delay-on-touch-only="true"
|
delay-on-touch-only
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
@end="onDragEnd"
|
@end="onDragEnd"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ function onDeleteExecute() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<EventTabsNav>
|
<EventTabsNav>
|
||||||
<template #default="{ event }">
|
<template #default>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="d-flex align-center justify-space-between flex-wrap gap-2 mb-4">
|
<div class="d-flex align-center justify-space-between flex-wrap gap-2 mb-4">
|
||||||
<div class="d-flex align-center gap-x-2">
|
<div class="d-flex align-center gap-x-2">
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCompanies, useDeleteCompany } from '@/composables/api/useCompanies'
|
import { useCompanies, useDeleteCompany } from '@/composables/api/useCompanies'
|
||||||
import { useAuthStore } from '@/stores/useAuthStore'
|
|
||||||
import { useOrganisationStore } from '@/stores/useOrganisationStore'
|
import { useOrganisationStore } from '@/stores/useOrganisationStore'
|
||||||
import CompanyDialog from '@/components/organisation/CompanyDialog.vue'
|
import CompanyDialog from '@/components/organisation/CompanyDialog.vue'
|
||||||
import type { Company } from '@/types/organisation'
|
import type { Company } from '@/types/organisation'
|
||||||
|
|
||||||
const authStore = useAuthStore()
|
|
||||||
const orgStore = useOrganisationStore()
|
const orgStore = useOrganisationStore()
|
||||||
|
|
||||||
const orgId = computed(() => orgStore.activeOrganisationId ?? '')
|
const orgId = computed(() => orgStore.activeOrganisationId ?? '')
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ definePage({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const search = ref('')
|
|
||||||
const searchDebounced = refDebounced(search, 400)
|
|
||||||
const logNameFilter = ref('')
|
const logNameFilter = ref('')
|
||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
|
|
||||||
|
|||||||
@@ -96,11 +96,9 @@ export const useImpersonationStore = defineStore('impersonation', () => {
|
|||||||
'/admin/impersonate/status',
|
'/admin/impersonate/status',
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!data.data.active) {
|
if (!data.data.active && state.value) {
|
||||||
if (state.value) {
|
clearState()
|
||||||
clearState()
|
window.location.href = '/platform'
|
||||||
window.location.href = '/platform'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (data.data.session) {
|
else if (data.data.session) {
|
||||||
// Update expiry from server
|
// Update expiry from server
|
||||||
|
|||||||
Reference in New Issue
Block a user