diff --git a/jest.config.js b/jest.config.js index 77e3b5a7..e5c564f3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ +/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */ module.exports = { preset: "ts-jest", testEnvironment: "node", diff --git a/src/lib/stores/translations/en.json b/src/lib/stores/translations/en.json index c3252a66..424eae73 100644 --- a/src/lib/stores/translations/en.json +++ b/src/lib/stores/translations/en.json @@ -293,6 +293,12 @@ "check": "Check", "none": "None" }, + "tooltips": { + "checklist-items": "Checklist items", + "task-points": "Story points", + "checked-total": "Cards checked/total", + "task-points-total": "Story point total" + }, "unprioritized": "Unprioritized", "include-fields": "Include fields", "settings": { @@ -308,6 +314,10 @@ "order-sync-field": { "name": "Sync card order with field", "description": "Field to store the position of cards in the board." + }, + "points-field": { + "name": "Card story points field", + "description": "Use the selected field as the card story point value." } }, "note": { diff --git a/src/ui/components/Indicator/Indicator.svelte b/src/ui/components/Indicator/Indicator.svelte new file mode 100644 index 00000000..e02c1fa4 --- /dev/null +++ b/src/ui/components/Indicator/Indicator.svelte @@ -0,0 +1,18 @@ + + +
+ + +
+ + diff --git a/src/ui/views/Board/BoardView.svelte b/src/ui/views/Board/BoardView.svelte index 0c51acef..81b91358 100644 --- a/src/ui/views/Board/BoardView.svelte +++ b/src/ui/views/Board/BoardView.svelte @@ -436,6 +436,7 @@ )} {columnWidth} checkField={fields.find((field) => field.name === config?.checkField)?.name} + pointsField={fields.find((field) => field.name === config?.pointsField)?.name} includeFields={fields.filter((field) => includeFields.includes(field.name))} customHeader={fields.find((field) => field.name === customHeader)} onRecordClick={handleRecordClick} diff --git a/src/ui/views/Board/components/Board/Board.svelte b/src/ui/views/Board/components/Board/Board.svelte index 343c0b83..140d2490 100644 --- a/src/ui/views/Board/components/Board/Board.svelte +++ b/src/ui/views/Board/components/Board/Board.svelte @@ -35,6 +35,7 @@ export let onColumnPin: OnColumnPin; export let validateStatusField: () => string; export let checkField: string | undefined; + export let pointsField: string | undefined; export let includeFields: DataField[]; export let customHeader: DataField | undefined; @@ -83,6 +84,7 @@ records={column.records} {onRecordClick} {checkField} + {pointsField} {onRecordCheck} onRecordAdd={() => onRecordAdd(column.id)} onDrop={(record, records, trigger) => { diff --git a/src/ui/views/Board/components/Board/BoardColumn.svelte b/src/ui/views/Board/components/Board/BoardColumn.svelte index 1fd61901..dc652cf6 100644 --- a/src/ui/views/Board/components/Board/BoardColumn.svelte +++ b/src/ui/views/Board/components/Board/BoardColumn.svelte @@ -19,6 +19,7 @@ export let readonly: boolean; export let richText: boolean; export let checkField: string | undefined; + export let pointsField: string | undefined; export let includeFields: DataField[]; export let customHeader: DataField | undefined; export let pinned: boolean; @@ -42,6 +43,9 @@ $: count = records.length; $: checkedCount = records.filter((r) => r.values[checkField ?? ""]).length; + $: pointsCount = records.map((r) => r.values[pointsField ?? ""] as number) + .filter(Number.isFinite) + .reduce((sum, p) => sum + p, 0); function onColumnMenu() { const menu = new Menu(); @@ -109,10 +113,12 @@ value={name} {count} {checkedCount} + {pointsCount} bind:editing {richText} {collapse} {checkField} + {pointsField} {onColumnMenu} {onColumnRename} {onValidate} @@ -125,6 +131,7 @@ {customHeader} {onRecordClick} {checkField} + {pointsField} {onRecordCheck} {onDrop} {includeFields} diff --git a/src/ui/views/Board/components/Board/CardList.svelte b/src/ui/views/Board/components/Board/CardList.svelte index bf5e8f84..1c601d99 100644 --- a/src/ui/views/Board/components/Board/CardList.svelte +++ b/src/ui/views/Board/components/Board/CardList.svelte @@ -2,7 +2,6 @@ // import { Checkbox, InternalLink} from "obsidian-svelte"; import { Checkbox } from "obsidian-svelte"; import InternalLink from "src/ui/components/InternalLink.svelte"; - import { isString, type DataField, @@ -10,8 +9,11 @@ } from "src/lib/dataframe/dataframe"; import { app } from "src/lib/stores/obsidian"; import { settings } from "src/lib/stores/settings"; + import { i18n } from "src/lib/stores/i18n"; + import { get } from "svelte/store"; import CardMetadata from "src/ui/components/CardMetadata/CardMetadata.svelte"; import ColorItem from "src/ui/components/ColorItem/ColorItem.svelte"; + import Indicator from "src/ui/components/Indicator/Indicator.svelte"; import { getRecordColorContext, handleHoverLink, @@ -24,6 +26,7 @@ } from "svelte-dnd-action"; import { flip } from "svelte/animate"; import { getDisplayName } from "./boardHelpers"; + import { getTaskProgress } from "./taskHelpers"; import type { DropTrigger, OnRecordClick, @@ -37,6 +40,10 @@ export let onDrop: OnRecordDrop; export let includeFields: DataField[]; export let checkField: string | undefined; + export let pointsField: string | undefined; + const getTaskPoints = (item: DataRecord) => + pointsField ? (item.values[pointsField] as number) : null; + export let customHeader: DataField | undefined; export let boardEditing: boolean; @@ -88,6 +95,8 @@ > {#each items as item (item.id)} {@const color = getRecordColor(item)} + {@const taskPoints = getTaskPoints(item)} + {@const taskProgress = getTaskProgress(item.id)}
+
+ {#if taskProgress} + + {taskProgress} + + {/if} + {#if taskPoints} + + {taskPoints} + + {/if} +
{/each} @@ -151,6 +172,13 @@ align-items: center; } + div.task-indicators { + display: flex; + gap: 4px; + align-items: center; + gap: 10px; + } + .checkbox-wrapper { display: flex; flex-direction: column; diff --git a/src/ui/views/Board/components/Board/ColumnHeader.svelte b/src/ui/views/Board/components/Board/ColumnHeader.svelte index fdc766c6..d0bda9ac 100644 --- a/src/ui/views/Board/components/Board/ColumnHeader.svelte +++ b/src/ui/views/Board/components/Board/ColumnHeader.svelte @@ -1,8 +1,10 @@