import { END_HARD, END_SOFT } from "../definitions.js"; import UIAlert from "./UIAlert.js"; import UIContextMenu from "./UIContextMenu.js"; import UIWindow from "./UIWindow.js"; const UIWindowTaskManager = async function UIWindowTaskManager () { const svc_process = globalThis.services.get('process'); const w = await UIWindow({ title: i18n('task_manager'), icon: globalThis.icons['cog.svg'], uid: null, is_dir: false, message: 'message', app: 'taskmgr', // body_icon: options.body_icon, // backdrop: options.backdrop ?? false, is_resizable: true, is_droppable: false, has_head: true, selectable_body: true, draggable_body: false, allow_context_menu: false, // allow_native_ctxmenu: true, show_in_taskbar: true, dominant: true, body_content: '', width: 350, // parent_uuid: options.parent_uuid, // ...options.window_options, window_css:{ height: 'initial', }, body_css: { width: 'initial', padding: '20px', 'background-color': `hsla( var(--primary-hue), var(--primary-saturation), var(--primary-lightness), var(--primary-alpha))`, 'backdrop-filter': 'blur(3px)', } }); const w_body = w.querySelector('.window-body'); w_body.classList.add('taskmgr'); const Indent = ({ has_trunk, has_branch }) => { const el = document.createElement('div'); el.classList.add('taskmgr-indentcell'); if ( has_trunk ) { // Add new child element const el_indentcell_child = document.createElement('div'); el_indentcell_child.classList.add('taskmgr-indentcell-trunk'); el.appendChild(el_indentcell_child); } if ( has_branch ) { const el_indentcell_child = document.createElement('div'); el_indentcell_child.classList.add('taskmgr-indentcell-branch'); el.appendChild(el_indentcell_child); } return { appendTo (parent) { parent.appendChild(el); return this; } }; }; const Task = ({ placement, name }) => { const { indent_level, last_item, parent_last_item, } = placement; const el = document.createElement('div'); el.classList.add('taskmgr-task'); for ( let i=0; i < indent_level; i++ ) { const last_cell = i === indent_level - 1; Indent({ has_trunk: (last_cell && ( ! last_item )) || (!last_cell && !parent_last_item[i+1]), has_branch: last_cell }).appendTo(el); } const el_title = document.createElement('div'); el_title.classList.add('taskmgr-task-title'); el_title.innerText = name; el.appendChild(el_title); return { el () { return el; }, appendTo (parent) { parent.appendChild(el); return this; } }; } // https://codepen.io/fomkin/pen/gOgoBVy const Table = ({ headings }) => { const el_table = $(` ${headings.map(heading => ``).join('')}
${heading}
`)[0]; const el_tbody = el_table.querySelector('tbody'); return { el () { return el_table; }, add (el) { if ( typeof el.el === 'function' ) el = el.el(); el_tbody.appendChild(el); return this; }, clear () { el_tbody.innerHTML = ''; } }; }; const Row = () => { const el_tr = document.createElement('tr'); return { attach (parent) { parent.appendChild(el_tr); return this; }, el () { return el_tr; }, add (el) { if ( typeof el.el === 'function' ) el = el.el(); const el_td = document.createElement('td'); el_td.appendChild(el); el_tr.appendChild(el_td); return this; } }; }; const el_taskarea = document.createElement('div'); el_taskarea.classList.add('taskmgr-taskarea'); const tasktable = Table({ headings: [ i18n('taskmgr_header_name'), i18n('taskmgr_header_type'), i18n('taskmgr_header_status'), ] }); el_taskarea.appendChild(tasktable.el()); const end_process_ = async (process, force) => { let confirmation; if ( process.is_init() ) { if ( ! force ) { confirmation = i18n('close_all_windows_confirm'); } else { confirmation = i18n('restart_puter_confirm'); } } else if ( force ) { confirmation = i18n('end_process_force_confirm'); } if ( confirmation ) { const alert_resp = await UIAlert({ message: confirmation, buttons:[ { label: i18n('yes'), value: true, type: 'primary', }, { label: i18n('no'), value: false, }, ] }) if ( ! alert_resp ) return; } process.signal(force ? END_HARD : END_SOFT); } const iter_tasks = (items, { indent_level, parent_last_item }) => { for ( let i=0 ; i < items.length; i++ ) { const row = Row(); const item = items[i]; const last_item = i === items.length - 1; row.add(Task({ placement: { parent_last_item, indent_level, last_item, }, name: item.name })); row.add($(`${i18n('process_type_' + item.type)}`)[0]) row.add($(`${i18n('process_status_' + item.status.i18n_key)}`)[0]) tasktable.add(row); $(row.el()).on('contextmenu', () => { UIContextMenu({ parent_element: $(el_taskarea), items: [ { html: i18n('close'), onClick: () => { end_process_(item); } }, { html: i18n('force_quit'), onClick: () => { end_process_(item, true); } } ] }); }) const children = svc_process.get_children_of(item.uuid); if ( children ) { iter_tasks(children, { indent_level: indent_level + 1, parent_last_item: [...parent_last_item, last_item], }); } } }; const interval = setInterval(() => { tasktable.clear(); const processes = [svc_process.get_init()]; iter_tasks(processes, { indent_level: 0, parent_last_item: [] }); }, 500) w.on_close = () => { clearInterval(interval); } w_body.appendChild(el_taskarea); } export default UIWindowTaskManager;