change module delete logic...
This commit is contained in:
@@ -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)
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user