7 Commits

Author SHA1 Message Date
842bb959ab 1.4.2
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 21:22:34 +03:00
eb5bc8a10a Update authUser mutation to accept optional workplaceNumber parameter and adjust login function accordingly. Enhance API logging for authentication requests to include workplaceNumber for better debugging.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 18:03:10 +03:00
a0ac758049 Add refreshChains function to ChallengeContext and integrate it into ChainsPage for improved data management. This allows for manual refreshing of chain data when the component mounts, enhancing user experience.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 17:43:21 +03:00
23ec02e29a 1.4.1
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-14 16:05:18 +03:00
1291519cda Refactor TaskWorkspace to use getFeatureValue for feature flag retrieval, improving clarity and consistency in skip button functionality.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-14 16:05:05 +03:00
d2783d01c9 1.4.0
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-14 16:00:07 +03:00
e29242accf Add feature flag for task skip functionality in TaskWorkspace. Update bro.config.js to enable skip button based on feature toggle, enhancing user experience in task management.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-14 15:59:07 +03:00
8 changed files with 54 additions and 18 deletions

View File

@@ -23,6 +23,7 @@ module.exports = {
features: { features: {
'challenge': { 'challenge': {
// add your features here in the format [featureName]: { value: string } // add your features here in the format [featureName]: { value: string }
'task.skip.enabled': { value: 'true' }, // Включить кнопку пропуска задания
}, },
}, },
config: { config: {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "challenge", "name": "challenge",
"version": "1.3.0", "version": "1.4.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "challenge", "name": "challenge",
"version": "1.3.0", "version": "1.4.2",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@brojs/cli": "^1.9.4", "@brojs/cli": "^1.9.4",

View File

@@ -1,6 +1,6 @@
{ {
"name": "challenge", "name": "challenge",
"version": "1.3.0", "version": "1.4.2",
"description": "", "description": "",
"main": "./src/index.tsx", "main": "./src/index.tsx",
"scripts": { "scripts": {

View File

@@ -33,7 +33,7 @@ export const api = createApi({
}), }),
tagTypes: ['Chains', 'Chain', 'UserStats', 'SystemStats', 'Submissions', 'Queue'], tagTypes: ['Chains', 'Chain', 'UserStats', 'SystemStats', 'Submissions', 'Queue'],
endpoints: (builder) => ({ endpoints: (builder) => ({
authUser: builder.mutation<ChallengeAuthResponse, { nickname: string }>({ authUser: builder.mutation<ChallengeAuthResponse, { nickname: string; workplaceNumber?: string }>({
query: (body) => ({ query: (body) => ({
url: '/auth', url: '/auth',
method: 'POST', method: 'POST',

View File

@@ -9,6 +9,7 @@ import {
} from '@chakra-ui/react' } from '@chakra-ui/react'
import ReactMarkdown from 'react-markdown' import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm' import remarkGfm from 'remark-gfm'
import { getFeatureValue } from '@brojs/cli'
import type { ChallengeTask } from '../../__data__/types' import type { ChallengeTask } from '../../__data__/types'
import { useChallenge } from '../../context/ChallengeContext' import { useChallenge } from '../../context/ChallengeContext'
@@ -27,6 +28,9 @@ export const TaskWorkspace = ({ task, onTaskComplete, onTaskSkip }: TaskWorkspac
taskId: task.id, taskId: task.id,
}) })
// Проверяем, включена ли кнопка пропуска через feature flag
const skipEnabled = getFeatureValue('challenge', 'task.skip.enabled', 'false').value === 'true'
// Сохраняем последний результат, чтобы блок не исчезал // Сохраняем последний результат, чтобы блок не исчезал
const [lastResult, setLastResult] = useState<typeof finalSubmission>(null) const [lastResult, setLastResult] = useState<typeof finalSubmission>(null)
// Состояние для показа дополнительного материала // Состояние для показа дополнительного материала
@@ -397,16 +401,18 @@ export const TaskWorkspace = ({ task, onTaskComplete, onTaskSkip }: TaskWorkspac
<HStack justify="space-between" gap={2}> <HStack justify="space-between" gap={2}>
{!isAccepted && ( {!isAccepted && (
<> <>
<Button {skipEnabled && (
onClick={onTaskSkip} <Button
variant="outline" onClick={onTaskSkip}
size="sm" variant="outline"
colorScheme="gray" size="sm"
// @ts-expect-error Chakra UI v2 uses isDisabled colorScheme="gray"
isDisabled={isChecking} // @ts-expect-error Chakra UI v2 uses isDisabled
> isDisabled={isChecking}
Пропустить >
</Button> Пропустить
</Button>
)}
{/* @ts-expect-error Chakra UI v2 uses isLoading/isDisabled */} {/* @ts-expect-error Chakra UI v2 uses isLoading/isDisabled */}
<Button onClick={submit} colorScheme="teal" size="sm" isLoading={isChecking} isDisabled={!result.trim() || isChecking}> <Button onClick={submit} colorScheme="teal" size="sm" isLoading={isChecking} isDisabled={!result.trim() || isChecking}>
{needsRevision ? 'Отправить снова' : 'Отправить на проверку'} {needsRevision ? 'Отправить снова' : 'Отправить на проверку'}

View File

@@ -65,6 +65,7 @@ interface ChallengeContextValue {
login: (nickname: string, workplaceNumber: string) => Promise<void> login: (nickname: string, workplaceNumber: string) => Promise<void>
logout: () => void logout: () => void
refreshStats: () => Promise<void> refreshStats: () => Promise<void>
refreshChains: () => Promise<void>
eventEmitter: ChallengeEventEmitter eventEmitter: ChallengeEventEmitter
pollingManager: PollingManager pollingManager: PollingManager
metricsCollector: MetricsCollector metricsCollector: MetricsCollector
@@ -96,10 +97,23 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
const [authUser, { isLoading: isAuthLoading }] = useAuthUserMutation() const [authUser, { isLoading: isAuthLoading }] = useAuthUserMutation()
const [triggerStats, statsResult] = useLazyGetUserStatsQuery() const [triggerStats, statsResult] = useLazyGetUserStatsQuery()
const { data: chainsData, isLoading: isChainsLoading } = useGetChainsQuery(undefined, { const {
data: chainsData,
isLoading: isChainsLoading,
refetch: refetchChains,
} = useGetChainsQuery(undefined, {
skip: !userId, skip: !userId,
}) })
const refreshChains = useCallback(async () => {
if (!userId) {
return
}
cacheRef.current.clear('chains')
await refetchChains()
}, [refetchChains, userId])
useEffect(() => { useEffect(() => {
if (chainsData) { if (chainsData) {
setChains(chainsData) setChains(chainsData)
@@ -146,7 +160,10 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
const login = useCallback( const login = useCallback(
async (nicknameValue: string, workplaceNumberValue: string) => { async (nicknameValue: string, workplaceNumberValue: string) => {
const response = await authUser({ nickname: nicknameValue }).unwrap() const response = await authUser({
nickname: nicknameValue,
workplaceNumber: workplaceNumberValue || undefined
}).unwrap()
setUserId(response.userId) setUserId(response.userId)
setNickname(nicknameValue) setNickname(nicknameValue)
setWorkplaceNumber(workplaceNumberValue) setWorkplaceNumber(workplaceNumberValue)
@@ -189,6 +206,7 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
login, login,
logout, logout,
refreshStats, refreshStats,
refreshChains,
eventEmitter, eventEmitter,
pollingManager, pollingManager,
metricsCollector, metricsCollector,
@@ -213,6 +231,7 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
personalDashboard, personalDashboard,
pollingManager, pollingManager,
refreshStats, refreshStats,
refreshChains,
saveDraft, saveDraft,
stats, stats,
userId, userId,

View File

@@ -10,7 +10,7 @@ import type { ChallengeChain } from '../../__data__/types'
export const ChainsPage = () => { export const ChainsPage = () => {
const navigate = useNavigate() const navigate = useNavigate()
const { nickname } = useChallenge() const { nickname, refreshChains } = useChallenge()
// Проверяем авторизацию // Проверяем авторизацию
useEffect(() => { useEffect(() => {
@@ -24,6 +24,10 @@ export const ChainsPage = () => {
} }
}, [navigate, nickname]) }, [navigate, nickname])
useEffect(() => {
refreshChains()
}, [refreshChains])
const handleSelectChain = (chain: ChallengeChain) => { const handleSelectChain = (chain: ChallengeChain) => {
storage.setSelectedChainId(chain.id) storage.setSelectedChainId(chain.id)

View File

@@ -24,7 +24,13 @@ router.use((req, res, next) => {
// Challenge API endpoints // Challenge API endpoints
router.post('/challenge/auth', (req, res) => { router.post('/challenge/auth', (req, res) => {
res.json(readJson('auth.json')) const { nickname, workplaceNumber } = req.body
const response = readJson('auth.json')
// Логируем для отладки
console.log('Auth request:', { nickname, workplaceNumber })
res.json(response)
}) })
router.get('/challenge/chains', (req, res) => { router.get('/challenge/chains', (req, res) => {