Update README.md with additional SonarCloud badges and improve CI workflow for coverage reporting
Enhanced the README.md file by adding new SonarCloud badges for coverage, bugs, code smells, security rating, and maintainability rating. Updated the CI workflow to remove coverage collection from the test step, as it is now handled by SonarCloud, streamlining the process and ensuring accurate badge representation.
This commit is contained in:
@@ -3,6 +3,7 @@ import { ChevronDown, ChevronRight, Folder } from 'lucide-react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { listShows } from '@/features/admin/shows/api'
|
||||
import { ShowPicker } from '@/features/admin/shows/ShowPicker'
|
||||
import { qk } from '@/shared/api/query-keys'
|
||||
import type { ManualInboxFileDto } from '@/shared/api/types'
|
||||
import { useApiError } from '@/shared/lib/use-api-error'
|
||||
@@ -18,7 +19,6 @@ import {
|
||||
} from '@/shared/ui/dialog'
|
||||
import { Input } from '@/shared/ui/input'
|
||||
import { Label } from '@/shared/ui/label'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
|
||||
import { toast } from '@/shared/ui/toast-store'
|
||||
import { importManualInbox, listManualInbox } from './api'
|
||||
import { compareParsed, formatSeasonEpisode, isValidRegex, parseEpisodeName } from './episode-parse'
|
||||
@@ -221,24 +221,15 @@ export function ManualInboxDialog({ onClose }: Readonly<{ onClose: () => void }>
|
||||
{/* Шоу — первое решение в этом диалоге: остальные поля лишь помогают разложить файлы. */}
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<Label>{t('admin.media.manualShow')}</Label>
|
||||
<Select
|
||||
<ShowPicker
|
||||
value={showId}
|
||||
onValueChange={(value) => {
|
||||
shows={shows}
|
||||
placeholder={t('admin.media.manualPickShow')}
|
||||
onChange={(value) => {
|
||||
setShowPicked(true)
|
||||
setShowId(value)
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('admin.media.manualPickShow')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(shows ?? []).map((show) => (
|
||||
<SelectItem key={show.id} value={show.id}>
|
||||
{show.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
/>
|
||||
{autoDetected && (
|
||||
<p className="text-xs text-muted-foreground">{t('admin.media.manualDetected')}</p>
|
||||
)}
|
||||
|
||||
@@ -14,15 +14,12 @@ import {
|
||||
} from '@/shared/ui/dialog'
|
||||
import { Input } from '@/shared/ui/input'
|
||||
import { Label } from '@/shared/ui/label'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
|
||||
import { listShows } from '@/features/admin/shows/api'
|
||||
import { ShowPicker } from '@/features/admin/shows/ShowPicker'
|
||||
import { compareParsed, formatSeasonEpisode, isValidRegex, parseEpisodeName } from './episode-parse'
|
||||
import { matchShowByName } from './match-show'
|
||||
import { useUploadStore } from './upload-store'
|
||||
|
||||
/** Radix Select запрещает пустое значение — под «в библиотеку» используем спец-значение. */
|
||||
const LIBRARY_VALUE = '__library__'
|
||||
|
||||
export function UploadToShowDialog({
|
||||
files,
|
||||
onClose,
|
||||
@@ -119,19 +116,16 @@ export function UploadToShowDialog({
|
||||
<span className="text-muted-foreground">
|
||||
{t('admin.media.toShowMatched', { matched: matchedCount, total: files.length })}
|
||||
</span>
|
||||
<Select value="" onValueChange={(v) => applyToAll(v === LIBRARY_VALUE ? '' : v)}>
|
||||
<SelectTrigger className="h-8 w-52">
|
||||
<SelectValue placeholder={t('admin.media.applyToAll')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={LIBRARY_VALUE}>{t('admin.media.toShowLibrary')}</SelectItem>
|
||||
{shows?.map((s) => (
|
||||
<SelectItem key={s.id} value={s.id}>
|
||||
{s.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{/* Значение не храним: выбор здесь — это действие «проставить всем», а не состояние,
|
||||
поэтому на кнопке всегда её собственная подпись. */}
|
||||
<ShowPicker
|
||||
value=""
|
||||
shows={shows}
|
||||
noneLabel={t('admin.media.toShowLibrary')}
|
||||
placeholder={t('admin.media.applyToAll')}
|
||||
className="h-8 w-52"
|
||||
onChange={applyToAll}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="crt-panel max-h-72 divide-y divide-border overflow-y-auto rounded-md text-sm">
|
||||
@@ -148,26 +142,13 @@ export function UploadToShowDialog({
|
||||
<span className="min-w-0 flex-1 truncate" title={p.name}>
|
||||
{p.name}
|
||||
</span>
|
||||
<Select
|
||||
value={current || LIBRARY_VALUE}
|
||||
onValueChange={(v) =>
|
||||
setOverrides((o) => ({ ...o, [p.name]: v === LIBRARY_VALUE ? '' : v }))
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="h-8 w-56 shrink-0 whitespace-nowrap [&>span]:truncate">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={LIBRARY_VALUE}>
|
||||
{t('admin.media.toShowLibrary')}
|
||||
</SelectItem>
|
||||
{shows?.map((s) => (
|
||||
<SelectItem key={s.id} value={s.id}>
|
||||
{s.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<ShowPicker
|
||||
value={current}
|
||||
shows={shows}
|
||||
noneLabel={t('admin.media.toShowLibrary')}
|
||||
className="h-8 w-56 shrink-0"
|
||||
onChange={(showId) => setOverrides((o) => ({ ...o, [p.name]: showId }))}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user