Skip to content

Commit

Permalink
feature: add edit command
Browse files Browse the repository at this point in the history
  • Loading branch information
f3rno64 committed Nov 29, 2023
1 parent 21d4802 commit 4263d3c
Show file tree
Hide file tree
Showing 20 changed files with 262 additions and 283 deletions.
6 changes: 5 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node

import yArgs from 'yargs'
import * as C from './color'
import commands from './commands'
import { loadDB, initDB, dbExists } from './db'

Expand All @@ -15,7 +16,10 @@ const y = yArgs

argv.db = await loadDB()
})
.showHelpOnFail(false, 'Specify --help for available options')
.fail((_, err: Error): void => {
console.log(`${C.clHighlight('Error:')} ${C.clError(err.message)}`)
process.exit(1)
})
.help()
.version()
.recommendCommands()
Expand Down
99 changes: 99 additions & 0 deletions src/commands/edit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import _isEmpty from 'lodash/isEmpty'
import _isFinite from 'lodash/isFinite'

import * as U from '../utils'
import { type TimeTrackerDB } from '../types'
import { findSheet, findSheetEntry, saveDB } from '../db'

const COMMAND_CONFIG = {
command: 'edit',
describe: 'View, modify, or delete a time sheet entry',
builder: {
sheet: {
describe: 'Name of time sheet to edit'
},

name: {
describe: 'New name to apply to specified time sheet'
},

entry: {
describe: 'ID of entry to edit'
},

description: {
describe: 'New description for the specified entry'
},

delete: {
describe: 'Delete the specified time sheet or time sheet entry'
}
}
}

interface EntryCommandArguments {
db: TimeTrackerDB
sheet: string
name: string
entry: string
description: string
delete: boolean
}

const handler = async (args: EntryCommandArguments): Promise<void> => {
const {
db,
sheet: inputSheet,
name: inputName,
entry: inputEntry,
description,
delete: del
} = args

if (_isEmpty(inputSheet) && _isEmpty(inputEntry)) {
throw new Error('No sheet or entry specified')
}

if (!_isEmpty(inputSheet)) {
const sheet = findSheet(db, inputSheet)

if (typeof sheet === 'undefined') {
throw new Error(`Sheet ${inputSheet} not found`)
}

if (_isFinite(+inputEntry)) {
const entry = findSheetEntry(db, inputSheet, +inputEntry)

if (typeof entry === 'undefined') {
throw new Error(`Entry ${inputEntry} not found in sheet ${inputSheet}`)
}

if (del) {
sheet.entries = sheet.entries.filter((e) => e.id !== entry.id)
console.log(`Deleted entry ${inputEntry} from sheet ${inputSheet}`)
} else {
entry.description = description
console.log(`Updated entry ${inputEntry} in sheet ${inputSheet}`)
}
} else {
if (_isEmpty(inputName)) {
throw new Error('No new name specified')
}

if (del) {
db.sheets = db.sheets.filter((s) => s.name !== inputSheet)
console.log(`Deleted sheet ${inputSheet}`)
} else {
sheet.name = inputName
console.log(`Renamed sheet ${inputSheet} to ${inputName}`)
}
}

await saveDB(db)
}
}

export default {
...COMMAND_CONFIG,
handler: U.cmdHandler(handler)
}
90 changes: 0 additions & 90 deletions src/commands/entry.ts

This file was deleted.

21 changes: 4 additions & 17 deletions src/commands/in.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import parseDate from 'time-speak'
import _isEmpty from 'lodash/isEmpty'
import _isUndefined from 'lodash/isUndefined'

import * as C from '../color'
import * as P from '../print'
import * as U from '../utils'
import { genEntry } from '../sheets'
Expand Down Expand Up @@ -43,32 +41,21 @@ const handler = async (args: InCommandArgs) => {
const sheet = findSheet(db, activeSheetName)

if (typeof sheet === 'undefined') {
console.log(C.clError('No active sheet'))
return
throw new Error('No active sheet')
}

const { name, entries, activeEntryID } = sheet

if (activeEntryID !== null) {
const entry = findSheetEntry(db, name, activeEntryID)

if (_isUndefined(entry)) {
throw new Error(
`${C.clText('Sheet')} ${C.clSheet(name)} ${C.clText(
'has no active entry with id'
)} ${C.clID(activeEntryID)}`
)
if (typeof entry === 'undefined') {
throw new Error(`Sheet ${name} has no entry with ID ${activeEntryID}`)
}

const { id, description: entryDescription } = entry

console.log(
`${C.clHighlight('An entry is already active:')} [${C.clID(
`${id}`
)}] ${C.clText(entryDescription)}`
)

return
throw new Error(`An entry is already active (${id}): ${entryDescription}`)
}

const startDate = _isEmpty(at) ? new Date() : parseDate(at)
Expand Down
4 changes: 2 additions & 2 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import sheetsCommand from './sheets'
import resumeCommand from './resume'
import entryCommand from './entry'
import sheetCommand from './sheet'
import todayCommand from './today'
import listCommand from './list'
import editCommand from './edit'
import nowCommand from './now'
import outCommand from './out'
import inCommand from './in'
Expand All @@ -13,9 +13,9 @@ export default [
nowCommand,
outCommand,
listCommand,
editCommand,
todayCommand,
sheetCommand,
entryCommand,
sheetsCommand,
resumeCommand
]
16 changes: 3 additions & 13 deletions src/commands/list.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import _isEmpty from 'lodash/isEmpty'

import * as C from '../color'
import * as P from '../print'
import * as U from '../utils'
import { findSheet } from '../db'
Expand Down Expand Up @@ -30,20 +29,11 @@ const handler = (args: ListCommandArgs) => {
: sheets.map((name: string): TimeSheet => findSheet(db, name))

if (_isEmpty(sheetsToList)) {
console.error(C.clError('No available sheets'))
return
throw new Error('No sheets')
}

sheetsToList.forEach((sheet: TimeSheet, i: number): void => {
P.printSheet(sheet, sheet.name === activeSheetName)

if (i < sheetsToList.length - 1) {
console.log('')
}
})

console.log('')
P.printSummary(sheetsToList)
P.printSummary(sheetsToList, true)
P.printSheets(sheetsToList, activeSheetName)
}

export default {
Expand Down
40 changes: 16 additions & 24 deletions src/commands/now.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as C from '../color'
import _max from 'lodash/max'

import * as P from '../print'
import * as U from '../utils'
import { type TimeSheetEntry, type TimeTrackerDB } from '../types'
import { type TimeTrackerDB } from '../types'

const COMMAND_CONFIG = {
command: ['now', '$0'],
Expand All @@ -15,34 +16,25 @@ interface NowCommandArguments {

const handler = (args: NowCommandArguments) => {
const { db } = args
const { activeSheetName, sheets } = db
const sheetsWithActiveEntries = sheets
.map(({ name, entries }) => ({
sheetName: name,
entries: entries.filter(({ end }) => end === null)
}))
.filter(({ entries }) => entries.length > 0)
const { sheets } = db
const sheetsWithActiveEntries = sheets.filter(
({ entries }) => entries.filter(({ end }) => end === null).length > 0
)

if (sheetsWithActiveEntries.length === 0) {
console.log(
`[${C.clText('Active sheet')} ${C.clSheet(
activeSheetName ?? 'No active sheet'
)}] ${C.clText('No active entries')}`
)
return
throw new Error('No sheets with active entries')
}

sheetsWithActiveEntries.forEach(({ sheetName, entries }, i: number) => {
console.log(`${C.clText('- Sheet')} ${C.clSheet(sheetName)}`)
sheetsWithActiveEntries.sort(
({ entries: a }, { entries: b }) =>
+_max(a.map(({ start }) => start)) - +_max(b.map(({ start }) => start))
)

entries.map((entry: TimeSheetEntry): void => {
P.printSheetEntry(entry, true)
})
const [sheet] = sheetsWithActiveEntries
const { activeEntryID, entries } = sheet
const entry = entries.find(({ id }) => id === activeEntryID)

if (i < sheetsWithActiveEntries.length - 1) {
console.log('')
}
})
P.printSheetEntry(entry, true)
}

export default {
Expand Down
Loading

0 comments on commit 4263d3c

Please sign in to comment.