/
spirzen
/
it-knowledge-base
Обзор
Документация
Войти
/
spirzen
/
it-knowledge-base
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
Mobile
src/components/IntegrationDataFlowPlay.jsx
119 строк
4 KB
Spirzen
Components pack 2
23 май 2026, 03:42
23 май 2026, 03:42
b7f65e4
Код
Авторство
О чём код?
import React, {useMemo, useState} from 'react'; import BrowserOnly from '@docusaurus/BrowserOnly'; import clsx from 'clsx'; import DemoShell, {DemoCard} from './shared/DemoShell'; import {demoLoadingFallback} from './shared/demoFallback'; import toolStyles from './shared/toolDemo.module.css'; import styles from './IntegrationDataFlowPlay.module.css'; const FLOW_TYPES = [ {id: 'sync', label: 'Синхронный', desc: 'Клиент ждёт ответа (REST request-response).'}, {id: 'async', label: 'Асинхронный', desc: 'Сообщение в очередь, ack позже.'}, {id: 'etl', label: 'ETL', desc: 'Извлечь → преобразовать → загрузить в несколько систем.'}, {id: 'saga', label: 'Saga', desc: 'Цепочка шагов с компенсацией при сбое.'}, ]; const STAGES = ['trigger', 'queue', 'validate', 'transform', 'route', 'deliver']; const SAMPLE = { trigger: '{"event":"order.pay","user":"u42"}', queue: 'orders.raw (буфер)', validate: 'сумма > 0, email OK', transform: 'userId → customerId, +timestamp', route: 'RU → 1С, EU → SAP', deliver: 'orders.validated → сервис заказов', }; function IntegrationDataFlowPlayInner() { const [flowId, setFlowId] = useState('async'); const [stageIdx, setStageIdx] = useState(0); const [invalid, setInvalid] = useState(false); const flow = FLOW_TYPES.find((f) => f.id === flowId) ?? FLOW_TYPES[1]; const activeStages = useMemo(() => { if (flowId === 'sync') return ['trigger', 'deliver']; if (flowId === 'saga') return ['trigger', 'validate', 'deliver']; return STAGES; }, [flowId]); const current = activeStages[Math.min(stageIdx, activeStages.length - 1)]; const failed = invalid && current === 'validate'; const advance = () => { if (stageIdx >= activeStages.length - 1) { setStageIdx(0); setInvalid(false); return; } setStageIdx((i) => i + 1); }; return ( <DemoShell> <DemoCard title="Интеграционный поток данных" subtitle={flow.desc}> <div className={toolStyles.chips} style={{marginBottom: '0.75rem'}}> {FLOW_TYPES.map((f) => ( <button key={f.id} type="button" className={clsx(toolStyles.chip, flowId === f.id && toolStyles.chipActive)} onClick={() => { setFlowId(f.id); setStageIdx(0); setInvalid(false); }} > {f.label} </button> ))} </div> <div className={styles.pipeline}> {activeStages.map((id, i) => ( <React.Fragment key={id}> {i > 0 && ( <span className={styles.arrow} aria-hidden> → </span> )} <div className={clsx( styles.node, i === stageIdx && styles.nodeActive, failed && id === 'validate' && styles.nodeFail, )} > {id} </div> </React.Fragment> ))} </div> <p className={styles.payload}> {failed ? 'DLQ: orders.invalid — email пустой' : SAMPLE[current] ?? '—'} </p> <div style={{display: 'flex', flexWrap: 'wrap', gap: '0.45rem', justifyContent: 'center'}}> <button type="button" className="it-demo__btn it-demo__btn--primary" onClick={advance}> {stageIdx >= activeStages.length - 1 ? 'Сброс потока' : 'Следующий этап'} </button> <button type="button" className="it-demo__btn it-demo__btn--secondary" onClick={() => setInvalid((v) => !v)} > {invalid ? 'Валидные данные' : 'Сломать валидацию'} </button> </div> </DemoCard> </DemoShell> ); } export default function IntegrationDataFlowPlay() { return ( <BrowserOnly fallback={demoLoadingFallback}> {() => <IntegrationDataFlowPlayInner />} </BrowserOnly> ); }