diff --git a/src/css/content.scss b/src/css/content.scss index 5ef29a0..06945c1 100644 --- a/src/css/content.scss +++ b/src/css/content.scss @@ -14,8 +14,7 @@ width: 60px; background-color: white; border-radius: 50%; - box-shadow: -1px -1px 15px 4px rgba(0, 0, 0, 0.05), - 2px 2px 15px 4px rgba(0, 0, 0, 0.05); + box-shadow: -1px -1px 15px 4px rgba(0, 0, 0, 0.05), 2px 2px 15px 4px rgba(0, 0, 0, 0.05); padding: 5px; z-index: 9999; diff --git a/src/js/background.js b/src/js/background.js index 66378ea..3eb9617 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -1,17 +1,8 @@ import "@babel/polyfill" import ApiClient from "api/Client" -import { - isChrome, - getCurrentTab, - getSettings, - isBrowserTab -} from "utils/browser" +import { isChrome, getCurrentTab, getSettings, isBrowserTab } from "utils/browser" import { BackgroundMessenger } from "utils/messaging" -import { - tabUpdated, - settingsChanged, - togglePopup -} from "utils/messageHandlers" +import { tabUpdated, settingsChanged, togglePopup } from "utils/messageHandlers" const messenger = new BackgroundMessenger() @@ -47,8 +38,8 @@ chrome.runtime.onMessage.addListener(action => { type: "showBubble", payload: { bookedHours: parseFloat(data[0]?.hours) || 0, - service - } + service, + }, }) }) }) @@ -56,7 +47,7 @@ chrome.runtime.onMessage.addListener(action => { if (error.response?.status === 422) { chrome.runtime.sendMessage({ type: "setFormErrors", - payload: error.response.data + payload: error.response.data, }) } }) diff --git a/src/js/utils/index.js b/src/js/utils/index.js index d0d0379..256408d 100644 --- a/src/js/utils/index.js +++ b/src/js/utils/index.js @@ -9,7 +9,7 @@ import { get, find, curry, - pick + pick, } from "lodash/fp" import { format } from "date-fns" @@ -28,7 +28,7 @@ export const findProjectBy = prop => val => projects => { return compose( find(pathEq(prop, val)), - flatMap(get("options")) + flatMap(get("options")), )(projects) } @@ -38,14 +38,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 +55,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 +90,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 +101,6 @@ export const extractAndSetTag = changeset => { return { ...changeset, description: description.replace(/^#\S+\s/, ""), - tag: match[1] + tag: match[1], } } diff --git a/src/js/utils/messageHandlers.js b/src/js/utils/messageHandlers.js index 6a8bc13..026d184 100644 --- a/src/js/utils/messageHandlers.js +++ b/src/js/utils/messageHandlers.js @@ -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 }, }) } } diff --git a/src/js/utils/urlMatcher.js b/src/js/utils/urlMatcher.js index dadf007..2695bd6 100644 --- a/src/js/utils/urlMatcher.js +++ b/src/js/utils/urlMatcher.js @@ -1,12 +1,5 @@ import UrlPattern from "url-pattern" -import { - isFunction, - isUndefined, - compose, - toPairs, - map, - pipe -} from "lodash/fp" +import { isFunction, isUndefined, compose, toPairs, map, pipe } from "lodash/fp" import queryString from "query-string" const extractQueryParams = (queryParams, query) => { @@ -37,9 +30,9 @@ const parseServices = compose( return new UrlPattern(...pattern) } return new UrlPattern(pattern) - }) + }), })), - toPairs + toPairs, ) export const createEnhancer = document => service => { @@ -57,19 +50,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 +68,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 +76,7 @@ export const createMatcher = remoteServices => { ...match, ...service, url: tabUrl, - match + match, } } } @@ -99,6 +86,6 @@ export const createServiceFinder = remoteServices => document => { const enhancer = createEnhancer(document) return pipe( matcher, - enhancer + enhancer, ) } diff --git a/test/utils/urlMatcher.test.js b/test/utils/urlMatcher.test.js index 2402a30..cc0c78e 100644 --- a/test/utils/urlMatcher.test.js +++ b/test/utils/urlMatcher.test.js @@ -11,16 +11,14 @@ describe("utils", () => { describe("createMatcher", () => { it("matches host and path", () => { - const service = matcher( - "https://github.com/hundertzehn/mocoapp/pull/123" - ) + const service = matcher("https://github.com/hundertzehn/mocoapp/pull/123") expect(service.key).toEqual("github-pr") expect(service.name).toEqual("github") }) it("matches query string", () => { let service = matcher( - "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&projectKey=TEST1&modal=detail&selectedIssue=TEST1-1" + "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&projectKey=TEST1&modal=detail&selectedIssue=TEST1-1", ) expect(service.key).toEqual("jira") expect(service.name).toEqual("jira") @@ -32,7 +30,7 @@ describe("utils", () => { expect(service.match.id).toEqual("TEST1-1") service = matcher( - "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&projectKey=TEST1&modal=detail" + "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&projectKey=TEST1&modal=detail", ) expect(service.key).toEqual("jira") expect(service.name).toEqual("jira") @@ -44,7 +42,7 @@ describe("utils", () => { expect(service.match.id).toBeUndefined() service = matcher( - "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&projectKey=TEST1&modal=detail&selectedIssue=" + "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&projectKey=TEST1&modal=detail&selectedIssue=", ) expect(service.key).toEqual("jira") expect(service.name).toEqual("jira") @@ -55,9 +53,7 @@ describe("utils", () => { expect(service.match.projectId).toEqual("TEST1") expect(service.match.id).toEqual("") - service = matcher( - "https://moco-bx.atlassian.net/secure/RapidBoard.jspa" - ) + service = matcher("https://moco-bx.atlassian.net/secure/RapidBoard.jspa") expect(service.key).toEqual("jira") expect(service.name).toEqual("jira") expect(service.match.org).toEqual("moco-bx") @@ -65,7 +61,7 @@ describe("utils", () => { expect(service.match.id).toBeUndefined() service = matcher( - "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&modal=detail&selectedIssue=TEST2-1" + "https://moco-bx.atlassian.net/secure/RapidBoard.jspa?rapidView=2&modal=detail&selectedIssue=TEST2-1", ) expect(service.key).toEqual("jira") expect(service.name).toEqual("jira") @@ -78,18 +74,14 @@ describe("utils", () => { }) it("matches url with hash", () => { - let service = matcher( - "https://www.wunderlist.com/webapp#/tasks/4771178545" - ) + let service = matcher("https://www.wunderlist.com/webapp#/tasks/4771178545") expect(service.key).toEqual("wunderlist") expect(service.name).toEqual("wunderlist") expect(service.match.id).toEqual("4771178545") }) it("does not match different host", () => { - const service = matcher( - "https://trello.com/hundertzehn/mocoapp/pull/123" - ) + const service = matcher("https://trello.com/hundertzehn/mocoapp/pull/123") expect(service).toBeFalsy() }) }) @@ -98,9 +90,7 @@ describe("utils", () => { it("enhances a services", () => { const url = "https://github.com/hundertzehn/mocoapp/pull/123" const document = { - querySelector: jest - .fn() - .mockReturnValue({ textContent: "[4321] Foo" }) + querySelector: jest.fn().mockReturnValue({ textContent: "[4321] Foo" }), } const service = matcher(url) const enhancedService = createEnhancer(document)(service)