feature/wrike (#17)

* Fix code styles

* Add support for WRIKE

* Add tests
This commit is contained in:
Manuel Bouza
2019-04-26 13:05:14 +02:00
committed by Tobias Miesel
parent 25773cc661
commit a9d1726707
9 changed files with 118 additions and 83 deletions

View File

@@ -9,7 +9,7 @@ import {
get,
find,
curry,
pick
pick,
} from "lodash/fp"
import { format } from "date-fns"
@@ -20,6 +20,7 @@ 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) {
@@ -28,7 +29,7 @@ export const findProjectBy = prop => val => projects => {
return compose(
find(pathEq(prop, val)),
flatMap(get("options"))
flatMap(get("options")),
)(projects)
}
@@ -38,14 +39,14 @@ export const findProjectByValue = findProjectBy("value")
export const findTask = id =>
compose(
find(pathEq("value", Number(id))),
get("tasks")
get("tasks"),
)
function taskOptions(tasks) {
return tasks.map(({ id, name, billable }) => ({
label: billable ? name : `(${name})`,
value: id,
billable
billable,
}))
}
@@ -55,30 +56,30 @@ export function projectOptions(projects) {
label: project.intern ? `(${project.name})` : project.name,
identifier: project.identifier,
customerName: project.customer_name,
tasks: taskOptions(project.tasks)
tasks: taskOptions(project.tasks),
}))
}
export const groupedProjectOptions = compose(
map(([customerName, projects]) => ({
label: customerName,
options: projectOptions(projects)
options: projectOptions(projects),
})),
toPairs,
groupBy("customer_name"),
nilToArray
nilToArray,
)
export const serializeProps = attrs =>
compose(
mapValues(JSON.stringify),
pick(attrs)
pick(attrs),
)
export const parseProps = attrs =>
compose(
mapValues(JSON.parse),
pick(attrs)
pick(attrs),
)
export const trace = curry((tag, value) => {
@@ -90,8 +91,7 @@ export const trace = curry((tag, value) => {
export const weekStartsOn = 1
export const formatDate = date => format(date, "YYYY-MM-DD")
export const extensionSettingsUrl = () =>
`chrome://extensions/?id=${chrome.runtime.id}`
export const extensionSettingsUrl = () => `chrome://extensions/?id=${chrome.runtime.id}`
export const extractAndSetTag = changeset => {
let { description } = changeset
@@ -102,6 +102,6 @@ export const extractAndSetTag = changeset => {
return {
...changeset,
description: description.replace(/^#\S+\s/, ""),
tag: match[1]
tag: match[1],
}
}

View File

@@ -4,7 +4,7 @@ import {
ERROR_UPGRADE_REQUIRED,
ERROR_UNKNOWN,
groupedProjectOptions,
weekStartsOn
weekStartsOn,
} from "utils"
import { get, forEach, reject, isNil } from "lodash/fp"
import { startOfWeek, endOfWeek } from "date-fns"
@@ -32,8 +32,8 @@ export function tabUpdated(tab, { messenger, settings }) {
type: "showBubble",
payload: {
bookedHours: parseFloat(data[0]?.hours) || 0,
service
}
service,
},
})
})
.catch(() => {
@@ -41,8 +41,8 @@ export function tabUpdated(tab, { messenger, settings }) {
type: "showBubble",
payload: {
bookedHours: 0,
service
}
service,
},
})
})
})
@@ -58,7 +58,7 @@ export function settingsChanged(settings, { messenger }) {
forEach(tab => {
messenger.postMessage(tab, { type: "closePopup" })
tabUpdated(tab, { settings, messenger })
})
}),
)
}
@@ -88,7 +88,7 @@ async function openPopup(tab, { service, messenger }) {
apiClient.login(service),
apiClient.projects(),
apiClient.activities(fromDate, toDate),
apiClient.schedules(fromDate, toDate)
apiClient.schedules(fromDate, toDate),
])
const action = {
type: "openPopup",
@@ -103,8 +103,8 @@ async function openPopup(tab, { service, messenger }) {
schedules: get("[3].data", responses),
fromDate,
toDate,
loading: false
}
loading: false,
},
}
messenger.postMessage(tab, action)
} catch (error) {
@@ -119,7 +119,7 @@ async function openPopup(tab, { service, messenger }) {
}
messenger.postMessage(tab, {
type: "openPopup",
payload: { errorType, errorMessage }
payload: { errorType, errorMessage },
})
}
}

View File

@@ -1,17 +1,28 @@
import UrlPattern from "url-pattern"
import {
isFunction,
isUndefined,
compose,
toPairs,
map,
pipe
} from "lodash/fp"
import { isFunction, isUndefined, compose, toPairs, map, pipe, isNil } from "lodash/fp"
import { asArray } from "./index"
import queryString from "query-string"
const extractQueryParams = (queryParams, query) => {
return toPairs(queryParams).reduce((acc, [key, param]) => {
acc[key] = query[param]
function parseUrl(url) {
const urlObject = new URL(url)
const { origin, pathname, search } = urlObject
let { hash } = urlObject
const query = {
...queryString.parse(search),
...queryString.parse(hash),
}
if (hash) {
hash = hash.match(/#[^&]+/)[0]
}
return { origin, pathname, hash, query }
}
function extractQueryParams(queryParams, query) {
return toPairs(queryParams).reduce((acc, [key, params]) => {
const param = asArray(params).find(param => !isNil(query[param]))
if (param) {
acc[key] = query[param]
}
return acc
}, {})
}
@@ -37,9 +48,9 @@ const parseServices = compose(
return new UrlPattern(...pattern)
}
return new UrlPattern(pattern)
})
}),
})),
toPairs
toPairs,
)
export const createEnhancer = document => service => {
@@ -57,19 +68,16 @@ export const createEnhancer = document => service => {
description: evaluate(service.description),
projectId: evaluate(service.projectId),
taskId: evaluate(service.taskId),
position: service.position || { right: "calc(2rem + 5px)" }
position: service.position || { right: "calc(2rem + 5px)" },
}
}
export const createMatcher = remoteServices => {
const services = parseServices(remoteServices)
return tabUrl => {
const { origin, pathname, hash, search } = new URL(tabUrl)
const { origin, pathname, hash, query } = parseUrl(tabUrl)
const url = `${origin}${pathname}${hash}`
const query = queryString.parse(search)
const service = services.find(service =>
service.patterns.some(pattern => pattern.match(url))
)
const service = services.find(service => service.patterns.some(pattern => pattern.match(url)))
if (!service) {
return
@@ -78,10 +86,7 @@ export const createMatcher = remoteServices => {
const pattern = service.patterns.find(pattern => pattern.match(url))
let match = pattern.match(url)
if (service.queryParams) {
const extractedQueryParams = extractQueryParams(
service.queryParams,
query
)
const extractedQueryParams = extractQueryParams(service.queryParams, query)
match = { ...extractedQueryParams, ...match }
}
@@ -89,7 +94,7 @@ export const createMatcher = remoteServices => {
...match,
...service,
url: tabUrl,
match
match,
}
}
}
@@ -99,6 +104,6 @@ export const createServiceFinder = remoteServices => document => {
const enhancer = createEnhancer(document)
return pipe(
matcher,
enhancer
enhancer,
)
}