signalk-maintenance-tracker 1.5.0 → 1.5.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # v1.5.1
2
+
3
+ Phone-sized polish for the task list and modals.
4
+
5
+ - The status column no longer crowds out task names on narrow displays: badges
6
+ stack below 640px, and the name column keeps a minimum width instead of the
7
+ status column claiming a fixed 220px.
8
+ - Notes keep their font size when an iPhone rotates to landscape — iOS text
9
+ autosizing was inflating them.
10
+ - Task rows drop their edit and delete buttons; both live on the task detail
11
+ page, so tapping a row goes there instead of hitting a stray button.
12
+ - The mark-complete modal loses some redundant explanatory text.
13
+
1
14
  # v1.5.0
2
15
 
3
16
  The tracker learns the difference between maintenance you repeat and jobs you
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-maintenance-tracker",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Track recurring boat maintenance tasks with runtime and calendar based intervals.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -244,14 +244,6 @@ export function LogEntryModal(props) {
244
244
  value=${runtime}
245
245
  onInput=${(/** @type {any} */ e) => setRuntime(e.currentTarget.value)}
246
246
  />
247
- ${
248
- !isEdit
249
- ? html`<div class="field-hint">
250
- Prefilled with the current runtime reading when
251
- available.
252
- </div>`
253
- : null
254
- }
255
247
  </div>`
256
248
  : null
257
249
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { html } from '../lib/html.js';
6
6
  import { useState, useEffect } from '../../vendor/preact-hooks.js';
7
- import { useTasks, useTags, deleteTask } from '../api/hooks.js';
7
+ import { useTasks, useTags } from '../api/hooks.js';
8
8
  import { useAuth } from '../auth/auth.js';
9
9
  import { useListParams } from '../lib/useListParams.js';
10
10
  import {
@@ -13,14 +13,12 @@ import {
13
13
  formatRemainingTime,
14
14
  statusLabel,
15
15
  } from '../lib/format.js';
16
- import { toast } from '../lib/toasts.js';
17
16
  import { Table } from '../components/Table.js';
18
17
  import { Pagination } from '../components/Pagination.js';
19
18
  import { StatusBadge } from '../components/StatusBadge.js';
20
19
  import { StockBadge } from '../components/StockBadge.js';
21
20
  import { TaskFormModal } from '../components/TaskFormModal.js';
22
21
  import { LogEntryModal } from '../components/LogEntryModal.js';
23
- import { ConfirmModal } from '../components/ConfirmModal.js';
24
22
 
25
23
  /** @typedef {import('../types.js').TaskDTO} TaskDTO */
26
24
 
@@ -62,17 +60,16 @@ export function TaskListPage() {
62
60
  });
63
61
  const tagsRes = useTags();
64
62
 
65
- /** @type {[TaskDTO|null|undefined, any]} editor: undefined=closed, null=create, TaskDTO=edit */
63
+ /** @type {[null|undefined, any]} editor: undefined=closed, null=create (edit lives on task detail) */
66
64
  const [editorTask, setEditorTask] = useState(
67
- /** @type {TaskDTO|null|undefined} */ (undefined),
65
+ /** @type {null|undefined} */ (undefined),
68
66
  );
69
- // What the editor's "Recurring task" toggle defaults to on create: true
70
- // from "New task", false from "New todo". Ignored when editing.
67
+ // What the editor's "Recurring task" toggle defaults to: true from
68
+ // "New task", false from "New todo".
71
69
  const [editorRecurring, setEditorRecurring] = useState(true);
72
70
  const [completing, setCompleting] = useState(
73
71
  /** @type {TaskDTO|null} */ (null),
74
72
  );
75
- const [deleting, setDeleting] = useState(/** @type {TaskDTO|null} */ (null));
76
73
 
77
74
  // Tags and status are single-select, so search, tag and status simply AND
78
75
  // together. A task has exactly one status, and tags are used as categories,
@@ -110,7 +107,6 @@ export function TaskListPage() {
110
107
  key: 'status',
111
108
  label: 'Status',
112
109
  sortable: true,
113
- className: 'col-status',
114
110
  render: (/** @type {TaskDTO} */ t) =>
115
111
  html`<span class="status-badges"
116
112
  ><${StatusBadge} status=${t.status} /><${StockBadge} consumables=${t.consumables}
@@ -120,6 +116,7 @@ export function TaskListPage() {
120
116
  key: 'name',
121
117
  label: 'Name',
122
118
  sortable: true,
119
+ className: 'col-name',
123
120
  render: (/** @type {TaskDTO} */ t) =>
124
121
  html`<a href=${'#/tasks/' + encodeURIComponent(t.slug)}>${t.name}</a>`,
125
122
  },
@@ -160,24 +157,6 @@ export function TaskListPage() {
160
157
  >
161
158
  <i class="bi bi-check2-circle" />
162
159
  </button>
163
- <button
164
- type="button"
165
- class="btn-icon primary"
166
- aria-label=${'Edit ' + t.name}
167
- title="Edit"
168
- onClick=${() => setEditorTask(t)}
169
- >
170
- <i class="bi bi-pencil" />
171
- </button>
172
- <button
173
- type="button"
174
- class="btn-icon danger"
175
- aria-label=${'Delete ' + t.name}
176
- title="Delete"
177
- onClick=${() => setDeleting(t)}
178
- >
179
- <i class="bi bi-trash" />
180
- </button>
181
160
  `
182
161
  : null
183
162
  }
@@ -307,20 +286,6 @@ export function TaskListPage() {
307
286
  : null
308
287
  }
309
288
  ${completing ? html`<${LogEntryModal} task=${completing} onClose=${() => setCompleting(null)} />` : null}
310
- ${
311
- deleting
312
- ? html`<${ConfirmModal}
313
- title="Delete task"
314
- message=${'Delete "' + deleting.name + '" and its entire maintenance log? This cannot be undone.'}
315
- onConfirm=${async () => {
316
- await deleteTask(deleting.slug);
317
- toast('Task deleted.', 'success');
318
- setDeleting(null);
319
- }}
320
- onClose=${() => setDeleting(null)}
321
- />`
322
- : null
323
- }
324
289
  </div>
325
290
  `;
326
291
  }
@@ -9,6 +9,10 @@ html,
9
9
  body {
10
10
  margin: 0;
11
11
  padding: 0;
12
+ /* iOS WebKit inflates some text blocks in landscape ("text autosizing"),
13
+ giving rendered notes mismatched font sizes. Keep sizes as authored. */
14
+ -webkit-text-size-adjust: 100%;
15
+ text-size-adjust: 100%;
12
16
  }
13
17
 
14
18
  body {
@@ -583,10 +587,11 @@ pre {
583
587
  font-variant-numeric: tabular-nums;
584
588
  }
585
589
 
586
- /* status column: room for status + stock badges side by side */
587
- .table th.col-status,
588
- .table td.col-status {
589
- width: 220px;
590
+ /* columns size to content, so status expands to fit its badges side by side
591
+ when there's room; this floor keeps a name from being squeezed to one word
592
+ wide when it isn't */
593
+ .table td.col-name {
594
+ min-width: min(8em, 35vw);
590
595
  }
591
596
  .status-badges {
592
597
  display: flex;
@@ -622,6 +627,16 @@ pre {
622
627
  .table td.hide-sm {
623
628
  display: none;
624
629
  }
630
+
631
+ /* auto table layout hands every column a share of the slack in proportion to
632
+ how much wider it wants to be, so side-by-side badges keep claiming half a
633
+ phone's width and the name wraps beneath them. Stacking pins the status
634
+ column to its widest single badge — it wants nothing more, so the rest of
635
+ the row is the name's. */
636
+ .status-badges {
637
+ flex-direction: column;
638
+ align-items: flex-start;
639
+ }
625
640
  }
626
641
 
627
642
  .table-empty {