clocktopus 1.6.10 → 1.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/views.js +70 -2
- package/package.json +1 -1
package/dist/dashboard/views.js
CHANGED
|
@@ -80,6 +80,18 @@ export function indexPage() {
|
|
|
80
80
|
.sessions-table .in-progress { color: #3fb950; font-style: italic; }
|
|
81
81
|
.delete-btn { background: transparent; color: #8b949e; border: none; cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 0 0.4rem; margin-top: 0; }
|
|
82
82
|
.delete-btn:hover { color: #f85149; background: transparent; }
|
|
83
|
+
.delete-btn[disabled] { color: #484f58; cursor: not-allowed; opacity: 0.5; }
|
|
84
|
+
.delete-btn[disabled]:hover { color: #484f58; }
|
|
85
|
+
.modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: none; align-items: center; justify-content: center; z-index: 1000; }
|
|
86
|
+
.modal-backdrop.open { display: flex; }
|
|
87
|
+
.modal { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 1.25rem 1.5rem; max-width: 420px; width: calc(100% - 2rem); }
|
|
88
|
+
.modal h3 { margin: 0 0 0.5rem 0; font-size: 1rem; color: #c9d1d9; }
|
|
89
|
+
.modal p { margin: 0 0 1rem 0; font-size: 0.875rem; color: #8b949e; }
|
|
90
|
+
.modal-actions { display: flex; gap: 0.5rem; justify-content: flex-end; }
|
|
91
|
+
.modal-actions button { margin-top: 0; padding: 0.4rem 0.9rem; font-size: 0.85rem; }
|
|
92
|
+
.modal-actions .cancel-btn { background: #30363d; }
|
|
93
|
+
.modal-actions .danger-btn { background: #da3633; }
|
|
94
|
+
.modal-actions .danger-btn:hover { background: #f85149; }
|
|
83
95
|
.empty-state { color: #8b949e; font-size: 0.9rem; padding: 2rem; text-align: center; }
|
|
84
96
|
|
|
85
97
|
/* Inline form row */
|
|
@@ -249,6 +261,18 @@ export function indexPage() {
|
|
|
249
261
|
</div>
|
|
250
262
|
</div>
|
|
251
263
|
|
|
264
|
+
<!-- Confirm modal -->
|
|
265
|
+
<div id="confirm-modal" class="modal-backdrop" role="dialog" aria-modal="true">
|
|
266
|
+
<div class="modal">
|
|
267
|
+
<h3 id="confirm-title">Are you sure?</h3>
|
|
268
|
+
<p id="confirm-message"></p>
|
|
269
|
+
<div class="modal-actions">
|
|
270
|
+
<button type="button" class="cancel-btn" id="confirm-cancel">Cancel</button>
|
|
271
|
+
<button type="button" class="danger-btn" id="confirm-ok">Delete</button>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
</div>
|
|
275
|
+
|
|
252
276
|
<!-- SETTINGS TAB -->
|
|
253
277
|
<div id="tab-settings" class="tab-content">
|
|
254
278
|
<div class="cards">
|
|
@@ -859,8 +883,13 @@ export function indexPage() {
|
|
|
859
883
|
duration = '<span class="in-progress">In progress</span>';
|
|
860
884
|
}
|
|
861
885
|
const jira = s.jiraTicket || '-';
|
|
886
|
+
const canDelete = !!s.completedAt && !(s.jiraTicket && !s.jiraWorklogId);
|
|
887
|
+
const disabledAttr = canDelete ? '' : ' disabled';
|
|
888
|
+
const btnTitle = canDelete
|
|
889
|
+
? 'Delete entry'
|
|
890
|
+
: 'Cannot delete: Jira worklog id not tracked for this entry';
|
|
862
891
|
const deleteBtn = s.completedAt
|
|
863
|
-
? '<button class="delete-btn" title="
|
|
892
|
+
? '<button class="delete-btn" title="' + btnTitle + '" data-delete-id="' + escapeHtml(s.id) + '"' + disabledAttr + '>×</button>'
|
|
864
893
|
: '';
|
|
865
894
|
return '<tr>' +
|
|
866
895
|
'<td>' + escapeHtml(s.description) + '</td>' +
|
|
@@ -889,8 +918,41 @@ export function indexPage() {
|
|
|
889
918
|
loadSessions();
|
|
890
919
|
}
|
|
891
920
|
|
|
921
|
+
function showConfirm(message) {
|
|
922
|
+
return new Promise(function(resolve) {
|
|
923
|
+
const backdrop = document.getElementById('confirm-modal');
|
|
924
|
+
const msg = document.getElementById('confirm-message');
|
|
925
|
+
const okBtn = document.getElementById('confirm-ok');
|
|
926
|
+
const cancelBtn = document.getElementById('confirm-cancel');
|
|
927
|
+
msg.textContent = message;
|
|
928
|
+
backdrop.classList.add('open');
|
|
929
|
+
|
|
930
|
+
function cleanup(result) {
|
|
931
|
+
backdrop.classList.remove('open');
|
|
932
|
+
okBtn.removeEventListener('click', onOk);
|
|
933
|
+
cancelBtn.removeEventListener('click', onCancel);
|
|
934
|
+
backdrop.removeEventListener('click', onBackdrop);
|
|
935
|
+
document.removeEventListener('keydown', onKey);
|
|
936
|
+
resolve(result);
|
|
937
|
+
}
|
|
938
|
+
function onOk() { cleanup(true); }
|
|
939
|
+
function onCancel() { cleanup(false); }
|
|
940
|
+
function onBackdrop(e) { if (e.target === backdrop) cleanup(false); }
|
|
941
|
+
function onKey(e) {
|
|
942
|
+
if (e.key === 'Escape') cleanup(false);
|
|
943
|
+
if (e.key === 'Enter') cleanup(true);
|
|
944
|
+
}
|
|
945
|
+
okBtn.addEventListener('click', onOk);
|
|
946
|
+
cancelBtn.addEventListener('click', onCancel);
|
|
947
|
+
backdrop.addEventListener('click', onBackdrop);
|
|
948
|
+
document.addEventListener('keydown', onKey);
|
|
949
|
+
okBtn.focus();
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
|
|
892
953
|
async function deleteSession(id) {
|
|
893
|
-
|
|
954
|
+
const ok = await showConfirm('Delete this entry from Clockify and Jira?');
|
|
955
|
+
if (!ok) return;
|
|
894
956
|
try {
|
|
895
957
|
const res = await fetch('/api/timer/' + encodeURIComponent(id), { method: 'DELETE' });
|
|
896
958
|
const result = await res.json();
|
|
@@ -904,6 +966,12 @@ export function indexPage() {
|
|
|
904
966
|
}
|
|
905
967
|
}
|
|
906
968
|
|
|
969
|
+
document.addEventListener('click', function(e) {
|
|
970
|
+
const btn = e.target.closest && e.target.closest('[data-delete-id]');
|
|
971
|
+
if (!btn || btn.disabled) return;
|
|
972
|
+
deleteSession(btn.getAttribute('data-delete-id'));
|
|
973
|
+
});
|
|
974
|
+
|
|
907
975
|
function escapeHtml(str) {
|
|
908
976
|
const div = document.createElement('div');
|
|
909
977
|
div.textContent = str;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clocktopus",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.12",
|
|
4
4
|
"description": "Time-tracking automation for Clockify with idle monitoring, Jira integration, Google Calendar sync, CLI, web dashboard, and desktop app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|