Compare commits

...

2 Commits

Author SHA1 Message Date
chyoo 94300fc7ef version up! 2026-07-08 13:57:12 +09:00
chyoo f323fe5706 change module delete logic... 2026-07-08 13:55:26 +09:00
4 changed files with 48 additions and 9 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "lms",
"version": "1.0.18",
"version": "1.0.19",
"description": "Autonomy Studio LMS Electron app",
"main": "./out/main/index.js",
"author": {
+18 -3
View File
@@ -1486,10 +1486,25 @@ function LocalPcWorkspaceMockup({
prepareRemoteRuntimeModule,
onTitlebarNotice
})
const deleteModule = async (module: ModuleRow): Promise<void> => {
const deleteModule = async (module: ModuleRow, options: { deleteRepository?: boolean } = {}): Promise<void> => {
setModuleInstallError(null)
try {
await window.localWorkspace.moduleFiles.delete(module.name, `modules/${module.name}`, clonePathPreview, module.folderName)
if (options.deleteRepository) {
const response = await fetchWithFreshAuth(`${LMS_API_BASE_URL}/studio/repositories`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
courseId: courseKey,
week: weekNumber,
moduleName: module.name,
folderName: module.folderName
})
})
if (!response.ok) throw new Error(await response.text())
}
setModuleTabs((tabs) => tabs.filter((tab) => tab.name !== module.name))
if (selectedModule?.name === module.name) {
setSelectedModule(null)
@@ -1523,7 +1538,7 @@ function LocalPcWorkspaceMockup({
return nextRoots
})
await loadAvailableModules()
onTitlebarNotice(`[${module.name}] 삭제되었습니다`, 'info')
onTitlebarNotice(options.deleteRepository ? `[${module.name}] 모듈과 저장소가 삭제되었습니다` : `[${module.name}] 삭제되었습니다`, 'info')
} catch (error) {
console.error('[modules] delete failed', error)
setModuleInstallError(error instanceof Error ? error.message : '모듈 삭제 실패')
@@ -2603,7 +2618,7 @@ function LocalPcWorkspaceMockup({
onAddModuleTab={addModuleTabOnly}
onOpenSource={openModuleSource}
onInstallModule={(module) => void installModule(module)}
onDeleteModule={(module) => void deleteModule(module)}
onDeleteModule={(module, options) => void deleteModule(module, options)}
onUpdateModuleParameters={(module, rosParams) => void updateModuleParameters(module, rosParams)}
onStartModule={(module) => void runModuleControl(module, 'start')}
onStopModule={(module) => void runModuleControl(module, 'stop')}
@@ -1,4 +1,5 @@
import { Trash2 } from 'lucide-react'
import { useState } from 'react'
import type React from 'react'
type DeletableModule = {
@@ -9,7 +10,7 @@ type ModuleDeleteConfirmProps<Module extends DeletableModule> = {
dark: boolean
module: Module
onCancel: () => void
onConfirm: (module: Module) => void
onConfirm: (module: Module, options: { deleteRepository: boolean }) => void
}
export default function ModuleDeleteConfirm<Module extends DeletableModule>({
@@ -18,6 +19,8 @@ export default function ModuleDeleteConfirm<Module extends DeletableModule>({
onCancel,
onConfirm
}: ModuleDeleteConfirmProps<Module>): React.JSX.Element {
const [deleteRepository, setDeleteRepository] = useState(false)
return (
<div className="absolute inset-0 z-50 grid place-items-center bg-black/36">
<section
@@ -37,6 +40,27 @@ export default function ModuleDeleteConfirm<Module extends DeletableModule>({
<p className={['mt-2 text-[12px] font-medium leading-relaxed', dark ? 'text-white/45' : 'text-[#727b8c]'].join(' ')}>
워크스페이스에 설치된 모듈 폴더가 삭제됩니다.
</p>
<label
className={[
'mt-4 flex cursor-pointer items-start gap-2 rounded-md border p-3',
dark ? 'border-white/10 bg-white/[0.03]' : 'border-[#d8dee9] bg-[#f8fafc]'
].join(' ')}
>
<input
type="checkbox"
checked={deleteRepository}
onChange={(event) => setDeleteRepository(event.target.checked)}
className="mt-[2px] h-4 w-4 cursor-pointer accent-[#d14b4b]"
/>
<span>
<span className={['block text-[12px] font-bold', dark ? 'text-white/82' : 'text-[#1f2937]'].join(' ')}>
학생 저장소도 함께 삭제
</span>
<span className={['mt-1 block text-[11px] font-medium leading-relaxed', dark ? 'text-white/42' : 'text-[#7a8494]'].join(' ')}>
제출 커밋과 작업 이력이 삭제되고, 다음 설치 시 템플릿 저장소 기준으로 새로 생성됩니다.
</span>
</span>
</label>
<div className="mt-4 flex justify-end gap-2">
<button
type="button"
@@ -50,7 +74,7 @@ export default function ModuleDeleteConfirm<Module extends DeletableModule>({
</button>
<button
type="button"
onClick={() => onConfirm(module)}
onClick={() => onConfirm(module, { deleteRepository })}
className="h-8 cursor-pointer rounded-md bg-[#d14b4b] px-3 text-[12px] font-bold text-white transition hover:bg-[#bd3838]"
>
삭제
@@ -20,7 +20,7 @@ type ModuleListViewProps = {
onAddModuleTab: (module: ModuleRow) => void
onOpenSource: (module: ModuleRow) => void
onInstallModule: (module: ModuleRow) => void
onDeleteModule: (module: ModuleRow) => void
onDeleteModule: (module: ModuleRow, options: { deleteRepository: boolean }) => void
onUpdateModuleParameters: (module: ModuleRow, parameters: ModuleParameterPair[]) => void
onStartModule: (module: ModuleRow) => void
onStopModule: (module: ModuleRow) => void
@@ -146,8 +146,8 @@ export default function ModuleListView({
dark={dark}
module={deleteConfirmModule}
onCancel={() => setDeleteConfirmModule(null)}
onConfirm={(module) => {
onDeleteModule(module)
onConfirm={(module, options) => {
onDeleteModule(module, options)
setDeleteConfirmModule(null)
}}
/>