-
Notifications
You must be signed in to change notification settings - Fork 570
Adding new integrations
This is a by example type of tutorial about how to add integration of a new tool to Toggl Button Chrome extension.
We'll go through the process of adding an integration for a service named "SuperCoolTool" (with url https://www.supercooltool.com
) to Toggl Button.
Whenever contributing to the project, please remember to follow the Contributing Guidelines.
git clone [email protected]:toggl/toggl-button.git
Please follow set up instructions found in the README.
We need to add a reference to origins.json
file located in src/scripts
. This reference will be picked up by the extension and used when requesting permissions to run inside the tool's webpage.
Add a new entry. Try to keep the alphabetical order. It should look something like this:
'supercooltool.com': {
'url': '*://*.supercooltool.com/*',
'name': 'Supercooltool'
},
If your tool does not have public url that people use it with, please leave the url parameter empty.
Note that the name
property is used to fetch the file we'll create in next step.
- If
name
is "Super Cool Tool" it will translate tosuper-cool-tool.js
. - If
name
is "SuperCoolTool" it will translate tosupercooltool.js
.
and so on ...
Create a file in 'src/scripts/content/'. In our case it is named supercooltool.js
This is the script that determines where the Toggl Button is displayed on the page and how it functions.
The script should look something like this:
'use strict';
/* global togglbutton, $ */
togglbutton.render(
'#task-view:not(.toggl)',
{ observe: true },
$container => {
const descriptionSelector = () => {
const $description = $('#task-title', $container);
return $description.textContent.trim();
}
const projectSelector = () => {
const $project = $('#task-project span', $container);
return $project.textContent.trim();
}
const tagsSelector = () => {
const $tags = $('.tag-list', $container);
return ($tags.textContent || '').split(',').map(tag => tag.trim());
}
const link = togglbutton.createTimerLink({
className: 'super-cool-tool',
description: descriptionSelector,
projectName: projectSelector,
tags: tagsSelector
});
$('.toolbar').appendChild(link);
}
);
#task-view(.toggl)
- This is the selector of the container that must be visible when adding Toggl Button link. Note the :not(.toggl)
, this prevents the extension adding a button multiple times to the page.
If the Toggl Button is shown inside of a popup view, this should be the selector of this popup view. From this part of the page, all relevant information will be fetched.
{observe: true}
- This can be one of two values {} or {observe: true}.
Observe true means that the extension observes the page for dynamic data loading. This means that if the tool loads some parts of the page with ajax or renders dynamically, the Toggl Button extension waits until all loading is done before inserting a button into the page. This is usually essential for single page applications.
It's good practice to retrieve the data we need using functions that are passed to Toggl Button, rather than providing static string values. In our example, these are the functions named descriptionSelector
, etc.
This allows the extension to retrieve the data at the moment the user clicks the button, rather than only once on page load. (Again, especially important for single page applications).
$('#task-title', $container)
- We find the element that contains the description we want to use for our time entry, inside the "container" we chose in the first parameter of togglbutton.render()
. It's usually best to include the reference to the container, but in some cases the layout of the page may prevent this.
We do the same in our projectSelector
and tagsSelector
. The tags selector does some transformation of the value, as toggl button expects an array of tags rather than a comma-delimited string.
You'll probably need to tweak these selectors according to the service you are integrating with. Some services won't have any concept of tags or labels, in which case it can be ignored.
-
className
- this should be same as the name of the tool -
description
- this is the function to find the description value that was set in the previous section -
project
- this is the function to find the project value that was set in the previous section -
tags
- this is the function to find the array of tags we found in the previous section
const link = togglbutton.createTimerLink({
className: 'super-cool-tool',
description: descriptionSelector,
projectName: projectSelector,
tags: tagsSelector
});
There is a buttonStyle
option you can use. If you pass 'minimal'
to this option, only the button icon will be displayed, the text 'Start Timer' will not be included.
The .toolbar
class is a container to which we append the Toggl Button link.
$('.toolbar').appendChild(link);
Try to respect the layout around the button, and avoid interfering with features of the service.
If you want to add some custom styles to your Start timer
link you can add it to style.css
.
Just create new style rule with selector:
/********* SUPERCOOLTOOL *********/
.toggl-button.super-cool-tool {
}
and add all needed styles in it.
Add your integration to the list of compatible services.
- [SuperCoolTool](https://www.supercooltool.com/)
If you have done all that you are ready to submit a pull request.
Please don't forget to refer to the Contributing Guidelines.
It would be great if you would add a screenshot and description of where in the tool the toggl button link should be visible. This simplifies the review progress for Toggl Button maintainers. If all is good, it will be merged shortly.
Please squash all your commits into one commit. This keeps the git log more compact and clear.