* configurable host overrides * base host overrides on name of service instead of key and hide the options by default * added unit tests * review changes * Refactor options * Refactor * Update Readme * Pump version and update Changelog Co-authored-by: Tobias Jacksteit <me@xtj7.de>
122 lines
3.2 KiB
JavaScript
122 lines
3.2 KiB
JavaScript
import {
|
|
groupBy,
|
|
compose,
|
|
map,
|
|
mapValues,
|
|
toPairs,
|
|
flatMap,
|
|
pathEq,
|
|
get,
|
|
find,
|
|
curry,
|
|
pick,
|
|
head,
|
|
defaultTo,
|
|
padCharsStart,
|
|
} from "lodash/fp"
|
|
import { startOfWeek, endOfWeek } from "date-fns"
|
|
import { format } from "date-fns"
|
|
|
|
const nilToArray = (input) => input || []
|
|
|
|
export const ERROR_UNAUTHORIZED = "unauthorized"
|
|
export const ERROR_UPGRADE_REQUIRED = "upgrade-required"
|
|
export const ERROR_UNKNOWN = "unknown"
|
|
|
|
export const noop = () => null
|
|
export const asArray = (input) => (Array.isArray(input) ? input : [input])
|
|
|
|
export const findProjectBy = (prop) => (val) => (projects) => {
|
|
if (!val) {
|
|
return undefined
|
|
}
|
|
|
|
return compose(find(pathEq(prop, val)), flatMap(get("options")))(projects)
|
|
}
|
|
|
|
export const findProjectByIdentifier = findProjectBy("identifier")
|
|
export const findProjectByValue = findProjectBy("value")
|
|
|
|
export const findTask = (id) => compose(find(pathEq("value", Number(id))), get("tasks"))
|
|
|
|
export const defaultTask = (tasks) =>
|
|
compose(defaultTo(head(tasks)), find(pathEq("isDefault", true)), nilToArray)(tasks)
|
|
|
|
function taskOptions(tasks) {
|
|
return tasks.map(({ id, name, billable, default: isDefault }) => ({
|
|
label: billable ? name : `(${name})`,
|
|
value: id,
|
|
billable,
|
|
isDefault,
|
|
}))
|
|
}
|
|
|
|
export function projectOptions(projects) {
|
|
return projects.map((project) => ({
|
|
value: project.id,
|
|
label: project.intern ? `(${project.name})` : project.name,
|
|
identifier: project.identifier,
|
|
customerName: project.customer_name,
|
|
tasks: taskOptions(project.tasks),
|
|
}))
|
|
}
|
|
|
|
export const groupedProjectOptions = compose(
|
|
map(([customerName, projects]) => ({
|
|
label: customerName,
|
|
options: projectOptions(projects),
|
|
})),
|
|
toPairs,
|
|
groupBy("customer_name"),
|
|
nilToArray,
|
|
)
|
|
|
|
export const serializeProps = (attrs) => compose(mapValues(JSON.stringify), pick(attrs))
|
|
|
|
export const parseProps = (attrs) => compose(mapValues(JSON.parse), pick(attrs))
|
|
|
|
export const trace = curry((tag, value) => {
|
|
// eslint-disable-next-line no-console
|
|
console.log(tag, value)
|
|
return value
|
|
})
|
|
|
|
export const weekStartsOn = 1
|
|
export const formatDate = (date) => format(date, "yyyy-MM-dd")
|
|
export const getStartOfWeek = () => startOfWeek(new Date(), { weekStartsOn })
|
|
export const getEndOfWeek = () => endOfWeek(new Date(), { weekStartsOn })
|
|
|
|
export const extensionSettingsUrl = () => `chrome://extensions/?id=${chrome.runtime.id}`
|
|
|
|
export const extractAndSetTag = (changeset) => {
|
|
let { description } = changeset
|
|
const match = description.match(/^#(\S+)/)
|
|
if (!match) {
|
|
return changeset
|
|
}
|
|
return {
|
|
...changeset,
|
|
description: description.replace(/^#\S+\s/, ""),
|
|
tag: match[1],
|
|
}
|
|
}
|
|
|
|
export const formatDuration = (
|
|
durationInSeconds,
|
|
{ settingTimeTrackingHHMM = true, showSeconds = true } = {},
|
|
) => {
|
|
if (settingTimeTrackingHHMM) {
|
|
const hours = Math.floor(durationInSeconds / 3600)
|
|
const minutes = Math.floor((durationInSeconds % 3600) / 60)
|
|
const result = `${hours}:${padCharsStart("0", 2, minutes)}`
|
|
if (!showSeconds) {
|
|
return result
|
|
} else {
|
|
const seconds = durationInSeconds % 60
|
|
return result + `:${padCharsStart("0", 2, seconds)}`
|
|
}
|
|
} else {
|
|
return (durationInSeconds / 3600).toFixed(2)
|
|
}
|
|
}
|