mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-22 01:11:06 +00:00
260 lines
7.8 KiB
JavaScript
260 lines
7.8 KiB
JavaScript
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 = $(`
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
${headings.map(heading =>
|
|
`<th><span>${heading}<span></th>`).join('')}
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
`)[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($(`<span>${i18n('process_type_' + item.type)}</span>`)[0])
|
|
row.add($(`<span>${i18n('process_status_' + item.status.i18n_key)}</span>`)[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;
|