From b98339d299d9450494ee85495b02771910a5d40b Mon Sep 17 00:00:00 2001 From: web-admin Date: Tue, 4 Aug 2026 11:20:33 +0900 Subject: [PATCH] remove topics.. --- src/lms-renderer/App.tsx | 32 ++++++++++++++----- .../features/curriculum/LearningInfoCard.tsx | 17 +--------- .../features/platforms/PlatformCards.tsx | 8 +++-- .../platforms/PlatformSelectionPanel.tsx | 16 +++++++--- .../features/workspace/workspaceModules.ts | 2 +- 5 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/lms-renderer/App.tsx b/src/lms-renderer/App.tsx index 70dfe98..0a3729d 100644 --- a/src/lms-renderer/App.tsx +++ b/src/lms-renderer/App.tsx @@ -778,15 +778,18 @@ function LocalPcWorkspaceMockup({ const storedParameters = readStoredModuleParameters() return modules.map((module) => { const override = storedParameters[getModuleParameterStorageKey(module)] - if (!override) return module + const defaultParameters = runtimeModules.find((item) => item.folderName === module.folderName)?.defaultParameters + ?.filter((parameter): parameter is string => typeof parameter === 'string') ?? [] return { ...module, - parameters: serializeModuleParameters(override).split(/\s+/).filter(Boolean) + parameters: override + ? serializeModuleParameters(override).split(/\s+/).filter(Boolean) + : defaultParameters.length ? defaultParameters : module.parameters } }) - }, [courseKey, weekNumber]) + }, [courseKey, runtimeModules, weekNumber]) const curriculumModuleKey = runtimeModules - .map((module) => `${module.id}:${module.name}:${module.folderName}:${module.sortOrder}:${JSON.stringify(module.prebuiltArtifacts ?? [])}`) + .map((module) => `${module.id}:${module.name}:${module.folderName}:${module.sortOrder}:${JSON.stringify(module.prebuiltArtifacts ?? [])}:${JSON.stringify(module.defaultParameters ?? [])}`) .join('|') const { availableModules, @@ -2929,6 +2932,7 @@ export default function App(): React.JSX.Element { const connectedPlatformRef = useRef(null) const runningPlatformsRef = useRef([]) const platformStatusRequestSequenceRef = useRef(0) + const [checkedRemotePlatformStatusIds, setCheckedRemotePlatformStatusIds] = useState>(() => new Set()) const forcedPlatformTerminationHandlerRef = useRef<(payload: PlatformControlTerminatedPayload) => void>(() => undefined) const [workspaceWeekState, setWorkspaceWeekState] = useState(null) const [sessionConfirmAction, setSessionConfirmAction] = useState<'disconnect' | 'release' | null>(null) @@ -3329,6 +3333,11 @@ export default function App(): React.JSX.Element { return status ? { ...platform, ...status } : platform } setPlatformOptions((current) => current.map(mergePlatformStatus)) + setCheckedRemotePlatformStatusIds((current) => { + const next = new Set(current) + platforms.forEach((platform) => next.add(platform.id)) + return next + }) const lostControlPlatformIds = new Set( runningPlatformsRef.current .filter((platform) => { @@ -3499,15 +3508,19 @@ export default function App(): React.JSX.Element { cancelled = true } }, [authReady, authSession?.accessToken, fetchWithFreshAuth]) + const isRemotePlatformStatusPending = (platform: PlatformOption): boolean => ( + platform.platformKey !== 'futuredrive-local-pc' && !checkedRemotePlatformStatusIds.has(platform.id) + ) const filteredPlatformOptions = platformOptions.filter((platform) => { - if (platformFilter === 'available') return platform.state === 'ready' - if (platformFilter === 'unavailable') return platform.state !== 'ready' + const pending = isRemotePlatformStatusPending(platform) + if (platformFilter === 'available') return platform.state === 'ready' && !pending + if (platformFilter === 'unavailable') return platform.state !== 'ready' && !pending return true }) const platformFilterCounts = { all: platformOptions.length, - available: platformOptions.filter((platform) => platform.state === 'ready').length, - unavailable: platformOptions.filter((platform) => platform.state !== 'ready').length + available: platformOptions.filter((platform) => platform.state === 'ready' && !isRemotePlatformStatusPending(platform)).length, + unavailable: platformOptions.filter((platform) => platform.state !== 'ready' && !isRemotePlatformStatusPending(platform)).length } const localPcPlatform = platformOptions.find((platform) => platform.platformKey === 'futuredrive-local-pc') const openPlatformSettings = (platform: PlatformOption): void => { @@ -3992,6 +4005,8 @@ export default function App(): React.JSX.Element { setLocalPcLayoutOpen(false) setRecentSessionModalOpen(false) setPlatformModalMode('select') + platformStatusRequestSequenceRef.current += 1 + setCheckedRemotePlatformStatusIds(new Set()) await loadCurriculum() setPlatformModalOpen(true) } @@ -4507,6 +4522,7 @@ export default function App(): React.JSX.Element { counts={platformFilterCounts} workspaceWeekTitle={workspaceWeek.title} platformLoading={platformLoading} + checkedRemotePlatformStatusIds={checkedRemotePlatformStatusIds} isPlatformUnavailable={isPlatformUnavailable} getPlatformDotClass={getPlatformDotClass} onFilterChange={setPlatformFilter} diff --git a/src/lms-renderer/features/curriculum/LearningInfoCard.tsx b/src/lms-renderer/features/curriculum/LearningInfoCard.tsx index c0c609a..6af5713 100644 --- a/src/lms-renderer/features/curriculum/LearningInfoCard.tsx +++ b/src/lms-renderer/features/curriculum/LearningInfoCard.tsx @@ -6,7 +6,6 @@ type LearningInfoWeek = { title: string tags: string[] progress: number - topics: string[] duration: string detail: { requiresSourceSubmission?: boolean @@ -60,21 +59,7 @@ export default function LearningInfoCard({ -
-
- - - 학습 주제 - -
- {week.topics.map((topic, index) => ( -
- {index + 1} - {topic} -
- ))} -
-
+
{[ { label: '예상 학습 시간', value: week.duration, Icon: Clock3 }, ...(week.detail.requiresSourceSubmission diff --git a/src/lms-renderer/features/platforms/PlatformCards.tsx b/src/lms-renderer/features/platforms/PlatformCards.tsx index 0f98c46..09c9d78 100644 --- a/src/lms-renderer/features/platforms/PlatformCards.tsx +++ b/src/lms-renderer/features/platforms/PlatformCards.tsx @@ -1,4 +1,4 @@ -import { AlertCircle, CheckCircle2, Link2, Lock, Power, Settings } from 'lucide-react' +import { AlertCircle, CheckCircle2, Link2, LoaderCircle, Lock, Power, Settings } from 'lucide-react' import type { LucideIcon } from 'lucide-react' import type React from 'react' import type { PlatformOption } from './types' @@ -60,6 +60,7 @@ type PlatformOptionCardProps = { Icon: LucideIcon dotClassName: string unavailable: boolean + statusPending: boolean displayStatus: string primaryAction: string actionDisabled: boolean @@ -73,6 +74,7 @@ export function PlatformOptionCard({ Icon, dotClassName, unavailable, + statusPending, displayStatus, primaryAction, actionDisabled, @@ -106,7 +108,9 @@ export function PlatformOptionCard({

{platform.description}

- {unavailable + {statusPending + ? + : unavailable ? : ready ? diff --git a/src/lms-renderer/features/platforms/PlatformSelectionPanel.tsx b/src/lms-renderer/features/platforms/PlatformSelectionPanel.tsx index 2ca883d..40441d6 100644 --- a/src/lms-renderer/features/platforms/PlatformSelectionPanel.tsx +++ b/src/lms-renderer/features/platforms/PlatformSelectionPanel.tsx @@ -19,6 +19,7 @@ type PlatformSelectionPanelProps = { counts: Record workspaceWeekTitle: string platformLoading: boolean + checkedRemotePlatformStatusIds: ReadonlySet isPlatformUnavailable: (platform: PlatformOption) => boolean getPlatformDotClass: (platform: PlatformOption) => string onFilterChange: (filter: PlatformFilter) => void @@ -36,6 +37,7 @@ export default function PlatformSelectionPanel({ counts, workspaceWeekTitle, platformLoading, + checkedRemotePlatformStatusIds, isPlatformUnavailable, getPlatformDotClass, onFilterChange, @@ -81,14 +83,17 @@ export default function PlatformSelectionPanel({ const { id, status, action, state, iconKey } = platform const Icon = PLATFORM_ICONS[iconKey] ?? Monitor const locked = state === 'locked' - const unavailable = isPlatformUnavailable(platform) - const actionDisabled = locked || unavailable + const statusPending = platform.platformKey !== 'futuredrive-local-pc' && !checkedRemotePlatformStatusIds.has(id) + const unavailable = !statusPending && isPlatformUnavailable(platform) + const actionDisabled = statusPending || locked || unavailable const runningInSelectionList = runningPlatforms.some((runningPlatform) => runningPlatform.id === platform.id) - const displayStatus = unavailable && !status.includes('연결 끊김') && !status.includes('연결 불가') + const displayStatus = statusPending + ? '확인 중' + : unavailable && !status.includes('연결 끊김') && !status.includes('연결 불가') ? '연결 끊김' : status const hasControl = platform.control?.status === 'ACTIVE' - const primaryAction = hasControl ? '연결' : action + const primaryAction = statusPending ? '확인 중' : hasControl ? '연결' : action const platformActionDisabled = runningInSelectionList || actionDisabled return ( @@ -96,8 +101,9 @@ export default function PlatformSelectionPanel({ key={id} platform={platform} Icon={Icon} - dotClassName={getPlatformDotClass(platform)} + dotClassName={statusPending ? 'bg-[#94a3b8] shadow-[0_0_6px_rgba(148,163,184,0.45)]' : getPlatformDotClass(platform)} unavailable={unavailable} + statusPending={statusPending} displayStatus={displayStatus} primaryAction={primaryAction} actionDisabled={platformActionDisabled} diff --git a/src/lms-renderer/features/workspace/workspaceModules.ts b/src/lms-renderer/features/workspace/workspaceModules.ts index 5ea83ac..b02eb6f 100644 --- a/src/lms-renderer/features/workspace/workspaceModules.ts +++ b/src/lms-renderer/features/workspace/workspaceModules.ts @@ -18,7 +18,7 @@ export function makeUninstalledModuleRows(curriculumModules: CurriculumWeek['mod templateRepositoryUrl: module.templateRepositoryUrl ?? null, sourceType: module.sourceType ?? null, prebuiltArtifacts: module.prebuiltArtifacts ?? null, - parameters: [], + parameters: module.defaultParameters?.filter((parameter): parameter is string => typeof parameter === 'string') ?? [], cpu: null, memory: null, runtime: '-'