diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2bfa80d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +- Add support for starting/stopping a timer +- Show hours as HH:MM or decimal in the Bubble, depending on setting in MOCO + + +## [1.0.18] - 2019-03-23 +### Added +- First release of version 1 + +## [1.0.19] - 2019-03-26 +### Changed +- Position Bubble in the bottom right by default + +### Fixed +- Set default value of subdomain to `__unset__` to prevent network error if it is empty + +## [1.0.20] - 2019-03-26 +### Added +- Add support for tags in description + +### Changed +- Update README with example configuration and instructions for local installation + diff --git a/README.md b/README.md index 69045fb..db8067a 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,6 @@ -mocoapp-browser-extension -========================= +# MOCO Browser Extension -Documentation -------------- - -* https://checklyhq.com/blog/2018/08/creating-a-chrome-extension-in-2018-the-good-the-bad-and-the-meh/ -* https://developer.chrome.com/extensions -* https://developer.chrome.com/extensions/api_index - -Development ------------ +## Development * run `yarn` * run `yarn start:chrome` or `yarn start:firefox` (`yarn start` is an alias for `yarn start:chrome`) @@ -18,9 +9,106 @@ Development * Firefox: visit `about:debugging` and load temporary Add-on from `build/firefox` * reload browser extension after change -Release -------- +## Production Build * bump version in `package.json` * run `yarn build` -* upload Chrome and Firefox extensions in `build/chrome` and `build/firefox` respectively +* The Chrome and Firefox extensions are available as ZIP-files in `build/chrome` and `build/firefox` respectively + +## Install Local Builds + +### Chrome + +1. `yarn build:chrome` +1. Visit `chrome://extensions` +2. Enable `Developer mode` +3. `Load unpacked` and select the `build/chrome` folder. + +### Firefox + +1. `yarn build:firefox` +1. Visit `about:debugging` +2. Click on `Load temporary Add-on` and select the ZIP-file in `build/firefox` + +Only signed extensions can be permantly installed in Firefox (unless you are using Firefox Developer Edition). To sign the build, proceed as described in [Getting started with web-ext](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext). + +You can keep the extension settings between builds by providing a stable `APPLICATION_ID` between builds. You can set an `APPLICATION_ID` in a file named `.env` or at build time as follows: + +`APPLICATION_ID=my-custom-moco-extension@mycompany.com yarn build:firefox` + +## Remote Service Configuration + +Remote services are configured in `src/remoteServices.js`. + +A remote service is configured as follows: + +```javascript +{ + service_key: { + name: "service_name", + urlPatterns: [ + "https:\\://:subdomain.example.com/card/:id", + [/^https:\/\/(\w+).example.com\/card\/(\d+), ["subdomain", "id"]], + ], + queryParams: { + projectId: "currentList" + }, + description: (document, service, { subdomain, id, projectId }) => { + const title = document + .querySelector('.title') + ?.textContent + ?.trim() + return `#${id} ${service.key} ${title || ""}` + }, + projectId: (document, service, { subdomain, id, projectId }) => { + return projectId + }, + position: { left: "50%", transform: "translate(-50%)" } + } +} +``` + +| Parameter | Description | +|--------------|:-------------| +| service_key | `string` — Unique identifier for the service | +| service_name | `string` — Must be one of the registered services `trello`, `jira`, `asana`, `wunderlist`, `github` or `youtrack` | +| urlPatterns | `string` \| `RegEx` — A valid URL pattern or regular expression, as described in the [url-pattern](https://www.npmjs.com/package/url-pattern) package. | +| queryParams | `Object` — The object value is the name of the query parameter and the key the property it will available on, e.g. the value of the query parameter `currentList` will be available under `projectId`. Matches in `urlPatterns` have precedence over matches in `queryParams`. | +| description | `undefined` \| `string` \| `function` — The default description of the service. If it is a function, it will receive `window.document`, the current `service` and an object with the URL `matches` as arguments, and the return value set as the default description. | +| projectId | `undefined` \| `string` \| `function` — The pre-selected project of the service matching the MOCO project identifier. If it is a function, it will receive `window.document`, the current `service` and an object with the URL `matches` as arguments, and must return the MOCO project identifier or `undefined`. | +| position | `Object` — CSS properties as object styles for position the bubble. Defaults to `{ right: calc(4rem + 5px)` | + +## Adding a Custom Service + +1. Fork and clone this repository +2. Add your service to `src/removeServices.js`, e.g. for self-hosted Jira copy the entry with the key `jira` and update the `urlPatterns`: + +```javascript + "self-hosted-jira": { + name: "jira", + urlPatterns: [ + "https\\://jira.my-company.com/secure/RapidBoard.jspa", + "https\\://jira.my-company.net/browse/:id", + "https\\://jira.my-company.net/jira/software/projects/:projectId/boards/:board", + "https\\://jira.my-company.net/jira/software/projects/:projectId/boards/:board/backlog" + ], + queryParams: { + id: "selectedIssue", + projectId: "projectKey" + }, + description: (document, service, { id }) => { + const title = + document + .querySelector('[aria-label="Edit Summary"]') + ?.parentNode?.querySelector("h1") + ?.textContent?.trim() || + document + .querySelector(".ghx-selected .ghx-summary") + ?.textContent?.trim() + return `#${id} ${title || ""}` + } + }, +``` + +3. Build the extension (see [Production Build](#production-build)). +4. Install the extension locally (see [Install Local Builds](#install-local-builds)).