154154 </section >
155155 </div >
156156 </div >
157+
158+ <ScheduleTaskModal ref =" scheduleModal" @save =" handleTaskSave" />
157159 </div >
158160</template >
159161
160162<script setup lang="ts">
161- import { ref , computed , defineProps } from " vue" ;
163+ import { ref , computed } from " vue" ;
162164import { Multiselect } from " vue-multiselect" ;
163165import {
164166 PlusIcon ,
@@ -170,7 +172,7 @@ import {
170172 SortAscendingIcon as AscendingIcon ,
171173 SortDescendingIcon as DescendingIcon ,
172174} from " @modrinth/assets" ;
173- import { Toggle , Checkbox , RaisedBadge , ButtonStyled } from " @modrinth/ui" ;
175+ import { Toggle , Checkbox , RaisedBadge , ButtonStyled , ScheduleTaskModal } from " @modrinth/ui" ;
174176import cronstrue from " cronstrue" ;
175177import type { ScheduledTask } from " @modrinth/utils" ;
176178import { ModrinthServer } from " ~/composables/servers/modrinth-servers.ts" ;
@@ -179,10 +181,16 @@ const props = defineProps<{
179181 server: ModrinthServer ;
180182}>();
181183
182- const tasks = ref <ScheduledTask []>(props .server .scheduling .tasks );
184+ onBeforeMount (async () => {
185+ await props .server .scheduling .fetch ();
186+ });
187+
183188const selectedTasks = ref <ScheduledTask []>([]);
184189const sortBy = ref (" Name" );
185190const descending = ref (false );
191+ const scheduleModal = ref ();
192+
193+ const tasks = computed (() => props .server .scheduling .tasks );
186194
187195const sortedTasks = computed (() => {
188196 const sorted = [... tasks .value ];
@@ -208,88 +216,112 @@ const sortedTasks = computed(() => {
208216 return descending .value ? sorted .reverse () : sorted ;
209217});
210218
211- const handleSelectAll = (selected : boolean ) => {
219+ function handleSelectAll(selected : boolean ): void {
212220 selectedTasks .value = selected ? [... tasks .value ] : [];
213- };
221+ }
214222
215- const handleTaskSelect = (task : ScheduledTask , selected : boolean ) => {
223+ function handleTaskSelect(task : ScheduledTask , selected : boolean ): void {
216224 if (selected ) {
217225 selectedTasks .value .push (task );
218226 } else {
219227 selectedTasks .value = selectedTasks .value .filter ((t ) => t !== task );
220228 }
221- };
229+ }
222230
223- const handleTaskToggle = async (task : ScheduledTask , enabled : boolean ) = > {
231+ async function handleTaskToggle (task : ScheduledTask , enabled : boolean ): Promise < void > {
224232 try {
225- task .enabled = enabled ;
233+ await props . server . scheduling . editTask ( task .title , { enabled }) ;
226234 console .log (" Toggle task:" , task .title , enabled );
227235 } catch (error ) {
228236 console .error (" Failed to toggle task:" , error );
229237 task .enabled = ! enabled ;
230238 }
231- };
239+ }
232240
233- const handleTaskEdit = (task : ScheduledTask ) => {
234- console . log ( " Edit task: " , task . title );
235- };
241+ function handleTaskEdit(task : ScheduledTask ): void {
242+ scheduleModal . value ?. show ( task );
243+ }
236244
237- const handleTaskDelete = async (task : ScheduledTask ) = > {
245+ async function handleTaskDelete (task : ScheduledTask ): Promise < void > {
238246 if (confirm (` Are you sure you want to delete "${task .title }"? ` )) {
239247 try {
240- const index = tasks .value .indexOf (task );
241- if (index > - 1 ) {
242- tasks .value .splice (index , 1 );
243- }
248+ await props .server .scheduling .deleteTask (task );
244249 selectedTasks .value = selectedTasks .value .filter ((t ) => t !== task );
245250 console .log (" Delete task:" , task .title );
246251 } catch (error ) {
247252 console .error (" Failed to delete task:" , error );
248253 }
249254 }
250- };
255+ }
251256
252- const handleCreateTask = () => {
253- console . log ( " Create new task " );
254- };
257+ function handleCreateTask() : void {
258+ scheduleModal . value ?. showNew ( );
259+ }
255260
256- const handleBulkToggle = async () = > {
261+ async function handleBulkToggle() : Promise < void > {
257262 const enabledCount = selectedTasks .value .filter ((t ) => t .enabled ).length ;
258263 const shouldEnable = enabledCount < selectedTasks .value .length / 2 ;
259264
260265 try {
261- selectedTasks .value .forEach ((task : ScheduledTask ) => {
262- task .enabled = shouldEnable ;
263- });
266+ await Promise .all (
267+ selectedTasks .value .map ((task ) =>
268+ props .server .scheduling .editTask (task .title , { enabled: shouldEnable }),
269+ ),
270+ );
264271 console .log (" Bulk toggle tasks:" , selectedTasks .value .length , " to" , shouldEnable );
265272 } catch (error ) {
266273 console .error (" Failed to bulk toggle tasks:" , error );
267274 }
268- };
275+ }
269276
270- const handleBulkDelete = async () => {
271- // TODO: Confirm delete modal.
272- // `Are you sure you want to delete ${selectedTasks.value.length} selected tasks?`
273- };
277+ async function handleBulkDelete(): Promise <void > {
278+ if (confirm (` Are you sure you want to delete ${selectedTasks .value .length } selected tasks? ` )) {
279+ try {
280+ await Promise .all (
281+ selectedTasks .value .map ((task ) => props .server .scheduling .deleteTask (task )),
282+ );
283+ selectedTasks .value = [];
284+ console .log (" Bulk delete completed" );
285+ } catch (error ) {
286+ console .error (" Failed to bulk delete tasks:" , error );
287+ }
288+ }
289+ }
274290
275- const updateSort = () => {
276- // Trigger reactivity for sortedTasks somehow.
277- };
291+ async function handleTaskSave(data : ScheduledTask ): Promise <void > {
292+ try {
293+ if (scheduleModal .value ?.mode === " edit" ) {
294+ await props .server .scheduling .editTask (
295+ scheduleModal .value .originalData ?.title || data .title ,
296+ data ,
297+ );
298+ console .log (" Updated task:" , data .title );
299+ } else {
300+ await props .server .scheduling .createTask (data );
301+ console .log (" Created task:" , data .title );
302+ }
303+ } catch (error ) {
304+ console .error (" Failed to save task:" , error );
305+ }
306+ }
307+
308+ function updateSort(): void {
309+ // Trigger reactivity for sortedTasks
310+ }
278311
279- const updateDescending = () => {
312+ function updateDescending() : void {
280313 descending .value = ! descending .value ;
281- };
314+ }
282315
283- const getHumanReadableCron = (cronExpression : string ) => {
316+ function getHumanReadableCron(cronExpression : string ): string {
284317 try {
285- // eslint-disable-next-line import/no-named-as-default-member
286318 return cronstrue .toString (cronExpression );
287319 } catch {
288320 return cronExpression ;
289321 }
290- };
322+ }
291323
292- const formatWarningIntervals = (intervals : number []) => {
324+ function formatWarningIntervals(intervals : number []): string {
293325 return intervals
294326 .sort ((a , b ) => b - a )
295327 .map ((seconds ) => {
@@ -298,7 +330,7 @@ const formatWarningIntervals = (intervals: number[]) => {
298330 return ` ${seconds }s ` ;
299331 })
300332 .join (" , " );
301- };
333+ }
302334 </script >
303335
304336<style lang="scss" scoped>
@@ -321,12 +353,10 @@ const formatWarningIntervals = (intervals: number[]) => {
321353 justify-content : center ;
322354 padding : var (--spacing-card-sm );
323355
324- // Left edge of table
325356 & :first-child {
326357 padding-left : var (--spacing-card-bg );
327358 }
328359
329- // Right edge of table
330360 & :last-child {
331361 padding-right : var (--spacing-card-bg );
332362 }
0 commit comments