chore: explicit formatter groupings and run fmt

This commit is contained in:
Jacobtread 2026-04-10 09:47:50 +12:00
parent 7a169be170
commit 094ed2b30e
63 changed files with 241 additions and 122 deletions

View file

@ -12,6 +12,30 @@
{
"groupName": "fonts",
"elementNamePattern": ["@/fonts/**"]
},
{
"groupName": "modals",
"elementNamePattern": ["@/modals/**"]
},
{
"groupName": "service",
"elementNamePattern": ["@/service/**"]
},
{
"groupName": "timekeep",
"elementNamePattern": ["@/timekeep/**"]
},
{
"groupName": "views",
"elementNamePattern": ["@/views/**"]
},
{
"groupName": "components",
"elementNamePattern": ["@/components/**"]
},
{
"groupName": "commands",
"elementNamePattern": ["@/commands/**"]
}
],
"groups": [
@ -21,6 +45,12 @@
"value-internal",
["type-parent", "type-sibling", "type-index"],
["value-parent", "value-sibling", "value-index"],
"components",
"modals",
"views",
"timekeep",
"service",
"commands",
"fonts",
"unknown"
]

View file

@ -1,10 +1,12 @@
import { App, Command } from "obsidian";
import { TimekeepMergerModal } from "@/modals/TimekeepMergerModal";
import { TimekeepRegistry } from "@/service/registry";
import { TimekeepSettings } from "@/settings";
import { Store } from "@/store";
import { TimekeepMergerModal } from "@/modals/TimekeepMergerModal";
import { TimekeepRegistry } from "@/service/registry";
export default function (
app: App,
registry: TimekeepRegistry,

View file

@ -1,10 +1,12 @@
import { App, Command } from "obsidian";
import { TimekeepMergerModal } from "@/modals/TimekeepMergerModal";
import { TimekeepRegistry } from "@/service/registry";
import { TimekeepSettings } from "@/settings";
import { Store } from "@/store";
import { TimekeepMergerModal } from "@/modals/TimekeepMergerModal";
import { TimekeepRegistry } from "@/service/registry";
export default function (
app: App,
registry: TimekeepRegistry,

View file

@ -1,10 +1,12 @@
import { App, Command } from "obsidian";
import { TimekeepLocatorModal } from "@/modals/TimekeepLocatorModal";
import { TimekeepRegistry } from "@/service/registry";
import { TimekeepSettings } from "@/settings";
import { Store } from "@/store";
import { TimekeepLocatorModal } from "@/modals/TimekeepLocatorModal";
import { TimekeepRegistry } from "@/service/registry";
export default function (
app: App,
registry: TimekeepRegistry,

View file

@ -3,9 +3,10 @@ import type { App, Command } from "obsidian";
import moment from "moment";
import { Notice } from "obsidian";
import { stopAllTimekeeps } from "@/timekeep/stopAllTimekeeps";
import { getErrorMessage } from "@/utils/error";
import { stopAllTimekeeps } from "@/timekeep/stopAllTimekeeps";
async function asyncCallback(app: App) {
const currentTime = moment();

View file

@ -3,9 +3,10 @@ import type { App, Command } from "obsidian";
import moment from "moment";
import { Notice } from "obsidian";
import { stopFileTimekeeps } from "@/timekeep/stopFileTimekeeps";
import { getErrorMessage } from "@/utils/error";
import { stopFileTimekeeps } from "@/timekeep/stopFileTimekeeps";
async function asyncCallback(app: App) {
const currentTime = moment();
const currentFile = app.workspace.activeEditor?.file ?? null;

View file

@ -3,11 +3,12 @@
import { describe, it, expect, beforeEach } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import { DomComponent } from "@/components/DomComponent";
import { ReplaceableComponent } from "@/components/ReplaceableComponent";
import { ContentComponent } from "./ContentComponent";
import { DomComponent } from "@/components/DomComponent";
import { ReplaceableComponent } from "@/components/ReplaceableComponent";
describe("ContentComponent", () => {
let container: HTMLElement;

View file

@ -3,11 +3,12 @@
import { describe, expect, it, vi } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import { ContentComponent } from "@/components/ContentComponent";
import { DomComponent } from "@/components/DomComponent";
import { ReplaceableComponent } from "./ReplaceableComponent";
import { ContentComponent } from "@/components/ContentComponent";
import { DomComponent } from "@/components/DomComponent";
describe("ReplaceableComponent", () => {
it("load in without a previous element should cause a normal append", () => {
const container = createMockContainer();

View file

@ -5,18 +5,21 @@ import type { App } from "obsidian";
import { beforeEach, describe, expect, it, Mock, vi } from "vitest";
import type { CustomOutputFormat } from "@/output";
import type { Timekeep } from "@/timekeep/schema";
import { createMockContainer, MockVault } from "@/__mocks__/obsidian";
import { TimesheetApp } from "@/components/TimesheetApp";
import { TimesheetSaveError } from "@/components/TimesheetSaveError";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
import { defaultSettings, type TimekeepSettings } from "@/settings";
import { createStore, type Store } from "@/store";
import { Timesheet } from "./Timesheet";
import { TimesheetApp } from "@/components/TimesheetApp";
import { TimesheetSaveError } from "@/components/TimesheetSaveError";
import type { Timekeep } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
describe("Timesheet", () => {
let containerEl: HTMLElement;
let vault: MockVault;

View file

@ -3,11 +3,13 @@ import type { App } from "obsidian";
import type { CustomOutputFormat } from "@/output";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { ContentComponent } from "@/components/ContentComponent";
import { TimesheetApp } from "@/components/TimesheetApp";
import { TimesheetSaveError } from "@/components/TimesheetSaveError";
import type { Timekeep } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
/**

View file

@ -5,16 +5,18 @@ import type { App } from "obsidian";
import { beforeEach, describe, expect, it } from "vitest";
import type { CustomOutputFormat } from "@/output";
import type { Timekeep } from "@/timekeep/schema";
import { createMockContainer, MockVault } from "@/__mocks__/obsidian";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
import { defaultSettings, type TimekeepSettings } from "@/settings";
import { createStore, type Store } from "@/store";
import { TimesheetApp } from "./TimesheetApp";
import type { Timekeep } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
describe("TimesheetApp", () => {
let containerEl: HTMLElement;
let vault: MockVault;

View file

@ -1,17 +1,20 @@
import { App } from "obsidian";
import { CustomOutputFormat } from "@/output";
import { TimekeepSettings } from "@/settings";
import { Store } from "@/store";
import { DomComponent } from "@/components/DomComponent";
import { TimesheetCounters } from "@/components/TimesheetCounters";
import { TimesheetExportActions } from "@/components/TimesheetExportActions";
import { TimesheetRunningEntry } from "@/components/TimesheetRunningEntry";
import { TimesheetStartForm } from "@/components/TimesheetStartForm";
import { TimesheetTable } from "@/components/TimesheetTable";
import { CustomOutputFormat } from "@/output";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepSettings } from "@/settings";
import { Store } from "@/store";
import { Timekeep } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
/**
* View component for the timesheet app as a whole
*/

View file

@ -7,12 +7,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings, TimekeepSettings } from "@/settings";
import { createStore, Store } from "@/store";
import * as queries from "@/timekeep/queries";
import { Timekeep } from "@/timekeep/schema";
import { TimesheetCounters } from "./TimesheetCounters";
import { TimesheetTimer } from "./TimesheetTimer";
import * as queries from "@/timekeep/queries";
import { Timekeep } from "@/timekeep/schema";
describe("TimesheetCounters", () => {
let container: HTMLElement;
let settingsStore: Store<TimekeepSettings>;

View file

@ -2,18 +2,20 @@ import moment from "moment";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { formatDuration } from "@/utils/time";
import { TimesheetTimer } from "./TimesheetTimer";
import { DomComponent } from "@/components/DomComponent";
import {
getEntryDuration,
getRunningEntry,
getTotalDuration,
isKeepRunning,
} from "@/timekeep/queries";
import { formatDuration } from "@/utils/time";
import { TimesheetTimer } from "./TimesheetTimer";
import type { Timekeep } from "@/timekeep/schema";
/**
* Component for rendering the two live updating timers at the top of the

View file

@ -4,11 +4,12 @@ import moment from "moment";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import * as queries from "@/timekeep/queries";
import * as timeUtils from "@/utils/time";
import { TimesheetEntryDuration } from "./TimesheetEntryDuration";
import * as queries from "@/timekeep/queries";
describe("TimesheetEntryDuration", () => {
let container: HTMLElement;
let entry: any;

View file

@ -1,11 +1,13 @@
import moment from "moment";
import { DomComponent } from "@/components/DomComponent";
import { getEntryDuration, isEntryRunning } from "@/timekeep/queries";
import { TimeEntry } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { formatDurationLong } from "@/utils/time";
import { DomComponent } from "@/components/DomComponent";
import { getEntryDuration, isEntryRunning } from "@/timekeep/queries";
import { TimeEntry } from "@/timekeep/schema";
/**
* Component for rendering the live-updating duration on
* an entry

View file

@ -1,6 +1,5 @@
import type { App } from "obsidian";
import { DomComponent } from "@/components/DomComponent";
import {
NameSegment,
NameSegmentLink,
@ -9,6 +8,8 @@ import {
parseNameSegments,
} from "@/utils/name";
import { DomComponent } from "@/components/DomComponent";
/**
* Component for rendering the name of a timekeep entry, this
* handles segmenting the name into parts to allow links within

View file

@ -11,10 +11,11 @@ import * as exportPdf from "@/export/pdf";
import { CustomOutputFormat } from "@/output";
import { defaultSettings, TimekeepSettings } from "@/settings";
import { createStore, Store } from "@/store";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
import { TimesheetExportActions } from "./TimesheetExportActions";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
describe("TimesheetExportActions", () => {
let container: HTMLElement;
let app: App;

View file

@ -5,12 +5,14 @@ import type { CustomOutputFormat } from "@/output";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import { DomComponent } from "@/components/DomComponent";
import { createCSV, createMarkdownTable } from "@/export";
import { exportPdf } from "@/export/pdf";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { DomComponent } from "@/components/DomComponent";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
/**
* Export actions section component
*/

View file

@ -5,14 +5,15 @@ import { beforeEach, describe, expect, it, Mock, vi } from "vitest";
import type { Store } from "@/store";
import { createMockContainer, MockVault } from "@/__mocks__/obsidian";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
import { defaultSettings, type TimekeepSettings } from "@/settings";
import { createStore } from "@/store";
import * as debounceUtil from "@/utils/debounce";
import { TimesheetNameInput } from "./TimesheetNameInput";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
describe("TimesheetNameInput", () => {
let containerEl: HTMLElement;
let vault: MockVault;

View file

@ -1,10 +1,12 @@
import Fuse, { FuseResult } from "fuse.js";
import { DomComponent } from "@/components/DomComponent";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { assert } from "@/utils/assert";
import { debounced } from "@/utils/debounce";
import { DomComponent } from "@/components/DomComponent";
import { TimekeepAutocomplete } from "@/service/autocomplete";
export class TimesheetNameInput extends DomComponent {
/** Access to autocomplete */
autocomplete: TimekeepAutocomplete;

View file

@ -6,8 +6,6 @@ import moment from "moment";
import { v4 } from "uuid";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings, TimekeepSettings } from "@/settings";
import { createStore, type Store } from "@/store";
@ -16,6 +14,8 @@ import { TimesheetRow } from "./TimesheetRow";
import { TimesheetRowContent } from "./TimesheetRowContent";
import { TimesheetRowContentEditing } from "./TimesheetRowContentEditing";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
describe("TimesheetRowContainer", () => {
let containerEl: HTMLElement;
let app: App;

View file

@ -2,13 +2,14 @@ import type { App } from "obsidian";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { ContentComponent } from "@/components/ContentComponent";
import { TimesheetRowContent } from "./TimesheetRowContent";
import { TimesheetRowContentEditing } from "./TimesheetRowContentEditing";
import { ContentComponent } from "@/components/ContentComponent";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
/**
* This container allows a entry to switch between the default and
* editable views without re-rendering the entire table or having a

View file

@ -8,10 +8,11 @@ import { beforeEach, describe, expect, it, Mock, vi } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings, TimekeepSettings } from "@/settings";
import { createStore, Store } from "@/store";
import { TimeEntry, Timekeep } from "@/timekeep/schema";
import { TimesheetRowContent } from "./TimesheetRowContent";
import { TimeEntry, Timekeep } from "@/timekeep/schema";
describe("TimesheetRowContent", () => {
const start = moment();

View file

@ -4,17 +4,19 @@ import moment from "moment";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { formatTimestamp } from "@/utils/time";
import { createObsidianIcon } from "@/components/obsidianIcon";
import { ReplaceableComponent } from "@/components/ReplaceableComponent";
import { TimesheetEntryDuration } from "@/components/TimesheetEntryDuration";
import { TimesheetEntryName } from "@/components/TimesheetEntryName";
import { getRunningEntry, isEntryRunning } from "@/timekeep/queries";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { startNewNestedEntry } from "@/timekeep/start";
import { setEntryCollapsed, updateEntry } from "@/timekeep/update";
import { assert } from "@/utils/assert";
import { formatTimestamp } from "@/utils/time";
/**
* Component for the contents of a timesheet row

View file

@ -8,7 +8,6 @@ import { beforeEach, it, describe, Mock, vi, expect, afterEach } from "vitest";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings } from "@/settings";
@ -16,6 +15,8 @@ import { createStore } from "@/store";
import { TimesheetRowContentEditing } from "./TimesheetRowContentEditing";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
describe("TimesheetRowContentEditing", () => {
let containerEl: HTMLElement;
let app: App;

View file

@ -4,13 +4,16 @@ import { assert } from "vitest";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { formatEditableTimestamp, parseEditableTimestamp } from "@/utils/time";
import { createObsidianIcon } from "@/components/obsidianIcon";
import { ReplaceableComponent } from "@/components/ReplaceableComponent";
import { ConfirmModal } from "@/modals/ConfirmModal";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { removeEntry, updateEntry } from "@/timekeep/update";
import { formatEditableTimestamp, parseEditableTimestamp } from "@/utils/time";
/**
* Component for a timesheet row entry that is currently

View file

@ -6,7 +6,6 @@ import { beforeEach, it, describe, expect, afterEach } from "vitest";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings } from "@/settings";
@ -16,6 +15,8 @@ import { TimesheetRunningEntry } from "./TimesheetRunningEntry";
import { TimesheetRunningEntryEditing } from "./TimesheetRunningEntryEditing";
import { TimesheetRunningEntryViewing } from "./TimesheetRunningEntryViewing";
import type { Timekeep } from "@/timekeep/schema";
describe("TimesheetRunningEntry", () => {
let containerEl: HTMLElement;
let timekeep: Store<Timekeep>;

View file

@ -1,14 +1,16 @@
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { ContentComponent } from "@/components/ContentComponent";
import { getRunningEntry } from "@/timekeep/queries";
import { assert } from "@/utils/assert";
import { TimesheetRunningEntryEditing } from "./TimesheetRunningEntryEditing";
import { TimesheetRunningEntryViewing } from "./TimesheetRunningEntryViewing";
import { ContentComponent } from "@/components/ContentComponent";
import { getRunningEntry } from "@/timekeep/queries";
import type { Timekeep } from "@/timekeep/schema";
export class TimesheetRunningEntry extends ContentComponent<
TimesheetRunningEntryViewing | TimesheetRunningEntryEditing
> {

View file

@ -6,7 +6,6 @@ import { beforeEach, it, describe, vi, expect } from "vitest";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings } from "@/settings";
@ -14,6 +13,8 @@ import { createStore } from "@/store";
import { TimesheetRunningEntryEditing } from "./TimesheetRunningEntryEditing";
import type { Timekeep } from "@/timekeep/schema";
describe("TimesheetRunningEntryEditing", () => {
let containerEl: HTMLElement;
let timekeep: Store<Timekeep>;

View file

@ -1,12 +1,14 @@
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { DomComponent } from "@/components/DomComponent";
import { createObsidianIcon } from "@/components/obsidianIcon";
import { getRunningEntry } from "@/timekeep/queries";
import type { Timekeep } from "@/timekeep/schema";
import { updateEntry } from "@/timekeep/update";
import { assert } from "@/utils/assert";
/**
* The editing section for editing the currently

View file

@ -4,14 +4,14 @@ import moment from "moment";
import { v4 } from "uuid";
import { describe, it, vi, beforeEach, afterEach, expect } from "vitest";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings, type TimekeepSettings } from "@/settings";
import { createStore, type Store } from "@/store";
import { TimesheetRunningEntryViewing } from "./TimesheetRunningEntryViewing";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
describe("TimesheetRunningEntry", () => {
let containerEl: HTMLElement;
let timekeep: Store<Timekeep>;

View file

@ -2,14 +2,16 @@ import moment from "moment";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { formatTimestamp } from "@/utils/time";
import { DomComponent } from "@/components/DomComponent";
import { createObsidianIcon } from "@/components/obsidianIcon";
import { getPathToEntry } from "@/timekeep/queries";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { stopTimekeep } from "@/timekeep/update";
import { assert } from "@/utils/assert";
import { formatTimestamp } from "@/utils/time";
/**
* The "Running" timer section of the timesheet start are

View file

@ -4,10 +4,11 @@ import { describe, it, expect, vi, beforeEach, Mock } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import { createStore, Store } from "@/store";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
import { TimesheetSaveError } from "./TimesheetSaveError";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
describe("TimesheetSaveError", () => {
let container: HTMLElement;
let timekeepStore: Store<Timekeep>;

View file

@ -1,6 +1,7 @@
import type { Store } from "@/store";
import { DomComponent } from "@/components/DomComponent";
import { stripTimekeepRuntimeData, type Timekeep } from "@/timekeep/schema";
type HandleSaveTimekeep = (value: Timekeep) => Promise<void>;

View file

@ -5,16 +5,18 @@ import { beforeEach, it, describe, afterEach, vi, expect } from "vitest";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { createMockContainer, MockVault } from "@/__mocks__/obsidian";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
import { defaultSettings } from "@/settings";
import { createStore } from "@/store";
import { TimesheetStartForm } from "./TimesheetStartForm";
import type { Timekeep } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
vi.mock(import("uuid"), async (importOriginal) => {
return {
...(await importOriginal()),

View file

@ -2,15 +2,18 @@ import moment from "moment";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { DomComponent } from "@/components/DomComponent";
import { createObsidianIcon } from "@/components/obsidianIcon";
import { TimesheetNameInput } from "@/components/TimesheetNameInput";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { getRunningEntry } from "@/timekeep/queries";
import type { Timekeep } from "@/timekeep/schema";
import { startNewEntry } from "@/timekeep/start";
import { assert } from "@/utils/assert";
import { TimekeepAutocomplete } from "@/service/autocomplete";
/**
* The start section above the timesheet table

View file

@ -5,12 +5,13 @@ import type { App } from "obsidian";
import { beforeEach, describe, expect, it } from "vitest";
import { createMockContainer, MockVault } from "@/__mocks__/obsidian";
import { TimekeepRegistry } from "@/service/registry";
import { defaultSettings, type TimekeepSettings } from "@/settings";
import { createStore, type Store } from "@/store";
import { TimesheetStatusBar } from "./TimesheetStatusBar";
import { TimekeepRegistry } from "@/service/registry";
describe("TimesheetStatusBar", () => {
let containerEl: HTMLElement;
let vault: MockVault;

View file

@ -1,15 +1,16 @@
import { type App } from "obsidian";
import { Component } from "obsidian";
import { TimesheetStatusBarItem } from "./TimesheetStatusBarItem";
import { getRunningEntry } from "@/timekeep/queries";
import { Timekeep } from "@/timekeep/schema";
import {
TimekeepEntryItemType,
TimekeepRegistry,
TimekeepRegistryItemRef,
} from "@/service/registry";
import { getRunningEntry } from "@/timekeep/queries";
import { Timekeep } from "@/timekeep/schema";
import { TimesheetStatusBarItem } from "./TimesheetStatusBarItem";
export class TimesheetStatusBar extends Component {
/** Parent container element */

View file

@ -5,10 +5,11 @@ import { v4 } from "uuid";
import { describe, beforeEach, it, expect, vi, afterEach } from "vitest";
import { createMockContainer } from "@/__mocks__/obsidian";
import { TimeEntry } from "@/timekeep/schema";
import { TimesheetStatusBarItem } from "./TimesheetStatusBarItem";
import { TimeEntry } from "@/timekeep/schema";
describe("TimesheetStatusBarItem", () => {
const start = moment();
const oneHourLater = start.add(1, "hour");

View file

@ -1,6 +1,7 @@
import { DomComponent } from "@/components/DomComponent";
import { createObsidianIcon } from "@/components/obsidianIcon";
import { TimesheetEntryDuration } from "@/components/TimesheetEntryDuration";
import { TimeEntry } from "@/timekeep/schema";
export class TimesheetStatusBarItem extends DomComponent {

View file

@ -5,8 +5,6 @@ import { type App } from "obsidian";
import { v4 } from "uuid";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { Timekeep } from "@/timekeep/schema";
import { createMockContainer } from "@/__mocks__/obsidian";
import { defaultSettings, type TimekeepSettings } from "@/settings";
import { createStore, type Store } from "@/store";
@ -14,6 +12,8 @@ import { assert } from "@/utils/assert";
import { TimesheetTable } from "./TimesheetTable";
import type { Timekeep } from "@/timekeep/schema";
describe("TimesheetTable", () => {
let containerEl: HTMLElement;
let app: App;

View file

@ -2,12 +2,14 @@ import type { App } from "obsidian";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import type { Timekeep } from "@/timekeep/schema";
import { assert } from "@/utils/assert";
import { DomComponent } from "@/components/DomComponent";
import { TimesheetRow } from "@/components/TimesheetRow";
import type { Timekeep } from "@/timekeep/schema";
import { getEntriesSorted } from "@/timekeep/sort";
import { assert } from "@/utils/assert";
/**
* Table component for rendering the contents of the timekeep

View file

@ -2,6 +2,7 @@ import type { Moment } from "moment";
import { RawTableRow, createRawTable } from "@/export";
import { TimekeepSettings } from "@/settings";
import { Timekeep } from "@/timekeep/schema";
/**

View file

@ -1,10 +1,11 @@
import type { Moment } from "moment";
import { TimekeepSettings } from "@/settings";
import { formatDuration, formatTimestamp } from "@/utils/time";
import { getEntryDuration } from "@/timekeep/queries";
import { TimeEntry } from "@/timekeep/schema";
import { getEntriesSorted } from "@/timekeep/sort";
import { formatDuration, formatTimestamp } from "@/utils/time";
export { createCSV } from "./csv";
export { createMarkdownTable } from "./markdown-table";

View file

@ -2,9 +2,10 @@ import type { Moment } from "moment";
import { RawTableRow, TOTAL_COLUMNS, createRawTable } from "@/export";
import { DurationFormat, TimekeepSettings } from "@/settings";
import { formatDuration } from "@/utils/time";
import { getTotalDuration } from "@/timekeep/queries";
import { Timekeep, TimeEntry } from "@/timekeep/schema";
import { formatDuration } from "@/utils/time";
/**
* Creates the table header row

View file

@ -11,11 +11,8 @@ import { App, Notice, Platform } from "obsidian";
import pdfMake from "pdfmake";
import type { TimekeepSettings } from "@/settings";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
import { FileNamePromptModal } from "@/modals/FileNamePromptModal";
import { PdfExportBehavior } from "@/settings";
import { getEntryDuration, getTotalDuration } from "@/timekeep/queries";
import {
formatDurationLong,
formatDurationShort,
@ -23,6 +20,11 @@ import {
formatPdfRowDate,
} from "@/utils/time";
import { FileNamePromptModal } from "@/modals/FileNamePromptModal";
import { getEntryDuration, getTotalDuration } from "@/timekeep/queries";
import type { TimeEntry, Timekeep } from "@/timekeep/schema";
// Embedded fonts
import RobotoBold from "@/fonts/Roboto-Bold.ttf";
import RobotoRegular from "@/fonts/Roboto-Regular.ttf";

View file

@ -5,21 +5,18 @@ import { Plugin, TFolder } from "obsidian";
import type { CustomOutputFormat } from "@/output";
import type { Store } from "@/store";
import type { Timekeep, TimeEntry } from "@/timekeep/schema";
import createMerged from "@/commands/createMerged";
import exportMergedPdf from "@/commands/exportMergedPdf";
import findRunningTrackers from "@/commands/findRunningTrackers";
import insertTracker from "@/commands/insertTracker";
import newTimekeepFile from "@/commands/newTimekeepFile";
import stopAllTimekeepsCommand from "@/commands/stopAllTimekeeps";
import stopFileTimekeepsCommand from "@/commands/stopFileTimekeeps";
import { TimesheetStatusBar } from "@/components/TimesheetStatusBar";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
import { defaultSettings, TimekeepSettings, legacySettingsCompatibility } from "@/settings";
import { TimekeepSettingsTab } from "@/settings-tab";
import { createStore } from "@/store";
import { createNewTimekeepFile } from "./timekeep/createNewTimekeepFile";
import { TimesheetStatusBar } from "@/components/TimesheetStatusBar";
import TimekeepFileView from "@/views/TimekeepFileView";
import TimekeepMarkdownView from "@/views/TimekeepMarkdownView";
import { replaceTimekeepCodeblock, extractTimekeepCodeblocks } from "@/timekeep/parser";
import {
isKeepRunning,
@ -28,12 +25,20 @@ import {
getEntryDuration,
getTotalDuration,
} from "@/timekeep/queries";
import type { Timekeep, TimeEntry } from "@/timekeep/schema";
import { stopAllTimekeeps } from "@/timekeep/stopAllTimekeeps";
import { stopFileTimekeeps } from "@/timekeep/stopFileTimekeeps";
import TimekeepFileView from "@/views/TimekeepFileView";
import TimekeepMarkdownView from "@/views/TimekeepMarkdownView";
import { createNewTimekeepFile } from "./timekeep/createNewTimekeepFile";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepRegistry } from "@/service/registry";
import createMerged from "@/commands/createMerged";
import exportMergedPdf from "@/commands/exportMergedPdf";
import findRunningTrackers from "@/commands/findRunningTrackers";
import insertTracker from "@/commands/insertTracker";
import newTimekeepFile from "@/commands/newTimekeepFile";
import stopAllTimekeepsCommand from "@/commands/stopAllTimekeeps";
import stopFileTimekeepsCommand from "@/commands/stopFileTimekeeps";
export default class TimekeepPlugin extends Plugin {
/** Store containing the plugin settings */

View file

@ -4,6 +4,8 @@ import { SuggestModal } from "obsidian";
import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import { getRunningEntry } from "@/timekeep/queries";
import type { TimeEntry } from "@/timekeep/schema";
import {
@ -12,7 +14,6 @@ import {
TimekeepRegistryEntry,
TimekeepRegistryItemRef,
} from "@/service/registry";
import { getRunningEntry } from "@/timekeep/queries";
interface TimekeepResult {
ref: TimekeepRegistryItemRef;

View file

@ -2,11 +2,13 @@ import { App, TFile, Modal, TextComponent, ButtonComponent } from "obsidian";
import { v4 as uuid } from "uuid";
import { exportPdf } from "@/export/pdf";
import { TimekeepEntryItemType, TimekeepRegistry, TimekeepRegistryEntry } from "@/service/registry";
import { TimekeepSettings } from "@/settings";
import { Store } from "@/store";
import { Timekeep, stripTimekeepRuntimeData } from "@/timekeep/schema";
import { TimekeepEntryItemType, TimekeepRegistry, TimekeepRegistryEntry } from "@/service/registry";
interface TimekeepResult {
timekeep: Timekeep;
file: TFile;

View file

@ -5,12 +5,13 @@ import { describe, expect, it, vi } from "vitest";
import { MockVault } from "@/__mocks__/obsidian";
import { defaultSettings } from "@/settings";
import { createStore } from "@/store";
import { Timekeep } from "@/timekeep/schema";
import { createCodeBlock } from "@/utils/codeblock";
import { TimekeepAutocomplete } from "./autocomplete";
import { TimekeepRegistry } from "./registry";
import { Timekeep } from "@/timekeep/schema";
describe("TimekeepAutocomplete", () => {
describe("autocomplete enabled", () => {
it("empty vault should have no names", async () => {

View file

@ -2,11 +2,12 @@ import { Component } from "obsidian";
import { TimekeepSettings } from "@/settings";
import { createStore, Store } from "@/store";
import { getEntriesNames } from "@/timekeep/queries";
import { isNumberText } from "@/utils/number";
import { TimekeepEntryItemType, TimekeepRegistry } from "./registry";
import { getEntriesNames } from "@/timekeep/queries";
/**
* Autocomplete registry to provide entry name autocomplete based
* on all the existing tasks within the vault

View file

@ -7,7 +7,6 @@ import { describe, vi, it, expect } from "vitest";
import { MockMarkdownView, MockVault } from "@/__mocks__/obsidian";
import { defaultSettings } from "@/settings";
import { createStore } from "@/store";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
import { createCodeBlock } from "@/utils/codeblock";
import {
@ -17,6 +16,8 @@ import {
TimekeepRegistryItemRef,
} from "./registry";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
describe("TimekeepRegistry", () => {
describe("getFileRegistryEntry", () => {
it("returns null for markdown without timekeeps", async () => {

View file

@ -8,6 +8,7 @@ import type { TimekeepSettings } from "@/settings";
import type { Store } from "@/store";
import { createStore } from "@/store";
import {
extractTimekeepCodeblocksWithPosition,
load,

View file

@ -1,8 +1,9 @@
import moment from "moment";
import { Timekeep } from "@/timekeep/schema";
import { createCodeBlock } from "@/utils/codeblock";
import { Timekeep } from "@/timekeep/schema";
// Input data to find
export const input1 = createCodeBlock(
`{"entries":[{"name":"Block 1","startTime":"2024-03-17T01:33:51.630Z","endTime":"2024-03-17T01:33:55.151Z","subEntries":null}]}`,

View file

@ -1,8 +1,9 @@
import moment from "moment";
import { Timekeep } from "@/timekeep/schema";
import { createCodeBlock } from "@/utils/codeblock";
import { Timekeep } from "@/timekeep/schema";
// Input data to find
export const input1 = createCodeBlock(
`{"entries":[{"name":"Block 1","startTime":"2024-03-17T01:33:51.630Z","endTime":"2024-03-17T01:33:55.151Z","subEntries":null}]}`,

View file

@ -2,9 +2,10 @@ import type { Moment } from "moment";
import { v4 as uuid } from "uuid";
import { TimeEntry, TimeEntryGroup } from "@/timekeep/schema";
import { isEmptyString } from "@/utils/text";
import { TimeEntry, TimeEntryGroup } from "@/timekeep/schema";
/**
* Creates a new entry that has just started
*

View file

@ -1,6 +1,7 @@
import { TIMEKEEP, Timekeep, stripTimekeepRuntimeData } from "@/timekeep/schema";
import { isEmptyString } from "@/utils/text";
import { TIMEKEEP, Timekeep, stripTimekeepRuntimeData } from "@/timekeep/schema";
export type LoadResult = LoadSuccess | LoadError;
export type LoadSuccess = { success: true; timekeep: Timekeep };

View file

@ -1,8 +1,9 @@
import { SortOrder, UnstartedOrder, TimekeepSettings } from "@/settings";
import { TimeEntry } from "@/timekeep/schema";
import { getStartTime } from "./queries";
import { TimeEntry } from "@/timekeep/schema";
type TimeEntryWithIndex = TimeEntry & { index: number };
type EntriesComparator = (a: TimeEntryWithIndex, b: TimeEntryWithIndex) => number;

View file

@ -1,11 +1,11 @@
import type { Moment } from "moment";
import { TimeEntry } from "@/timekeep/schema";
import { withEntry, createEntry, withSubEntry } from "./create";
import { getEntryById } from "./queries";
import { updateEntry, stopRunningEntries } from "./update";
import { TimeEntry } from "@/timekeep/schema";
/**
* Start a new entry in the provided set of entries
*

View file

@ -1,10 +1,9 @@
import type { Moment } from "moment";
import type { TFile, Vault } from "obsidian";
import type { Timekeep } from "@/timekeep/schema";
import { replaceTimekeepCodeblock, extractTimekeepCodeblocksWithPosition } from "@/timekeep/parser";
import { getRunningEntry } from "@/timekeep/queries";
import type { Timekeep } from "@/timekeep/schema";
import { stopTimekeep } from "@/timekeep/update";
/**

View file

@ -1,15 +1,18 @@
import moment from "moment";
import { EditableFileView, TFile, WorkspaceLeaf } from "obsidian";
import { Timesheet } from "@/components/Timesheet";
import { TimesheetLoadError } from "@/components/TimesheetLoadError";
import { CustomOutputFormat } from "@/output";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { TimekeepSettings } from "@/settings";
import { createStore, Store } from "@/store";
import { Timesheet } from "@/components/Timesheet";
import { TimesheetLoadError } from "@/components/TimesheetLoadError";
import { load, LoadResult } from "@/timekeep/parser";
import { stripTimekeepRuntimeData, Timekeep } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
export default class TimekeepFileView extends EditableFileView {
/** Access to the timekeep settings */
settings: Store<TimekeepSettings>;

View file

@ -7,13 +7,16 @@ import { TFile, MarkdownRenderChild } from "obsidian";
import type { CustomOutputFormat } from "@/output";
import type { TimekeepSettings } from "@/settings";
import { type Store, createStore } from "@/store";
import { Timesheet } from "@/components/Timesheet";
import { TimesheetLoadError } from "@/components/TimesheetLoadError";
import { TimekeepAutocomplete } from "@/service/autocomplete";
import { type Store, createStore } from "@/store";
import { type LoadResult, load, replaceTimekeepCodeblock } from "@/timekeep/parser";
import { type Timekeep, stripTimekeepRuntimeData } from "@/timekeep/schema";
import { TimekeepAutocomplete } from "@/service/autocomplete";
export default class TimekeepMarkdownView extends MarkdownRenderChild {
// Obsidian app instance
app: App;