Skip to content
This repository was archived by the owner on Jan 14, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3c28d36
Bugfix in Routes when setting the component.
rNoz Dec 22, 2019
d6d7b00
Added Login mode to the LoginView (User+Password as default, API Key …
rNoz Dec 22, 2019
3a18481
Gitignore without .idea dir.
rNoz Dec 22, 2019
03d2fc5
LoginView tests repaired and added one for the apiKey. Added enzyme-t…
rNoz Dec 23, 2019
08b3bcd
Bugfix: className rendered false instead of empty string.
rNoz Dec 23, 2019
363e174
Bugfix: IssuesTable with Date rendered without date.
rNoz Dec 23, 2019
3c9e9fe
Bugfixes in IssuesTable: tr or td cannot appear as a child of div, ta…
rNoz Dec 23, 2019
7231c7c
Bugfix in InfiniteScroll: window is not PropTypes.element.
rNoz Dec 23, 2019
43d0b49
Bugfix in CommentsSection: p child of p.
rNoz Dec 23, 2019
5ae9944
Bugfix: pause and save state of Timer when unload/exit, preserve stat…
rNoz Dec 24, 2019
3f9bc99
Time tracking is editable (duration and date) when we stop the Timer.
rNoz Dec 24, 2019
2a0b17d
Tray feature: app can hide in tray.
rNoz Dec 25, 2019
40231d5
Modal: close button with cursor pointer.
rNoz Dec 26, 2019
572ef5f
Feature: duration (humanized string, eg. 1m, 2hours 3minutes, 1d 39 s…
rNoz Dec 26, 2019
42c4273
Feature: TimeEntryModal requests confirmation when contents are modif…
rNoz Dec 26, 2019
9df8e04
Time interval optimized when window is hidden (datetime diffs). New f…
rNoz Dec 29, 2019
56f66c2
Added electron mock for ipcRenderer.
rNoz Dec 29, 2019
ff71f5e
Electron updated to latest stable version with support for Tray icon.…
rNoz Jan 3, 2020
1ffba0a
Developed advanced timer controls, settings menu in window, automatic…
rNoz Jan 3, 2020
ea04d28
Bugfix: styles in advanced controls. Bugfix: jest and electron now sh…
rNoz Jan 4, 2020
56a7c36
Added 2 custom icons (1 minute rewind and fastforward) for the advanc…
rNoz Jan 4, 2020
ea8e4b7
README.md with new features (docs, images). Version updated to 1.1.0 …
rNoz Jan 4, 2020
73e7907
AUR PKGBUILD with redshape.desktop bugfixed to support the hicolor/0x…
rNoz Jan 4, 2020
a37199c
Bugfix: correctly save the state of the timer (duration and comments)…
rNoz Jan 5, 2020
8f51616
Bugfix: DatePicker is not updated properly (onDayChange instead of on…
rNoz Jan 10, 2020
d38331a
Updated PKGBUILD with new version. Releases updated.
rNoz Jan 10, 2020
9e6dd89
Bugfix: TimeEntryModal spent_on date is casted to ISO string, instead…
rNoz Jan 13, 2020
5c8c533
Feature: progress bars with two modes: progress-gradient (5 colors be…
rNoz Jan 13, 2020
d45083a
Custom fields are shown in IssueDetailsPage (if available).
rNoz Jan 14, 2020
f7f7d70
New feature: added IssueModal in IssueDetailsPage to be able to updat…
rNoz Jan 14, 2020
491dd85
Progress of issue can be edited using an input range instead of an in…
rNoz Jan 15, 2020
9dd17b2
Show errors from requests if available in response.data.errors.
rNoz Jan 16, 2020
3cd2673
IssuesTable: estimated time is fixed to 2 decimals.
rNoz Jan 16, 2020
6f8fe6c
New features: editable estimated time and due date in issue, omitted …
rNoz Jan 16, 2020
26fd88b
Added setting issue progress slider with two steps mode: 10% (default…
rNoz Jan 16, 2020
f351995
Merge pull request #14 from rNoz/master
Spring3 Jan 23, 2020
463c383
[rnoz] Follow up (#17)
Spring3 Feb 29, 2020
c2c1383
Update readme
Spring3 Feb 29, 2020
253b09c
Merge branch 'develop' into feature/rnoz-contributions
Spring3 Feb 29, 2020
63f3e51
cert fix
Spring3 Mar 1, 2020
186aab5
Merge branch 'feature/rnoz-contributions' of https://github.com/Sprin…
Spring3 Mar 1, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
version: 2
jobs:
build:
lint:
working_directory: ~/redshape
docker:
- image: circleci/node:10.15.3
steps:
- checkout
- restore_cache:
key: dependency-cache-{{ .Branch }}-{{ checksum "package.json" }}
- run: 'sudo apt install libxss-dev pkg-config'
- run:
name: Install Dependencies
command: 'npm install'
- save_cache:
key: dependency-cache-{{ .Branch }}-{{ checksum "package.json" }}
paths:
- ./node_modules
- run:
name: 'Linting'
command: 'npm run lint'

test:
working_directory: ~/redshape
docker:
- image: circleci/node:10.15.3
steps:
- checkout
- restore_cache:
key: dependency-cache-{{ .Branch }}-{{ checksum "package.json" }}
- run: 'sudo apt install libxss-dev libxext-dev libxtst6 libnss3 libgtk-3-0 libgtkextra-dev libasound2'
- run:
name: Install Dependencies
command: 'npm install'
Expand All @@ -18,4 +39,10 @@ jobs:
- run:
name: Coverage
command: 'npm test'


workflows:
version: 2
test:
jobs:
- lint
- test
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
42 changes: 41 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"parser": "babel-eslint",
"env": {
"browser": true,
"es6": true,
Expand Down Expand Up @@ -27,9 +28,48 @@
"no-underscore-dangle": [ "error", {
"allow": ["__initialize", "__reset"]
}],
"max-len": ["error", { "code": 120, "ignoreComments": true }],
"no-restricted-syntax": "off",
"camelcase": [ "error", {
"allow": ["api_key"]
"allow": [
"api_key",
"time_entry",
"spent_on",
"issue_id",
"activity_id",
"user_id",
"spent_hours",
"total_spent_hours",
"time_entries",
"project_id",
"tracker_id",
"status_id",
"assigned_to_id",
"author_id",
"due_date",
"created_on",
"priority_id",
"private_notes",
"total_count",
"estimated_duration",
"estimated_hours",
"done_ratio",
"assigned_to",
"start_date",
"custom_fields",
"closed_on",
"progress_info"
]
}],
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/anchor-is-valid": "off",
"react/no-array-index-key": "off",
"no-mixed-operators": "off",
"react/forbid-prop-types": "off",
"react/require-default-props": "off",
"react/jsx-props-no-spreading": "off",
"max-classes-per-file": "off",
"no-use-before-define": "off",
"jsx-a11y/label-has-for": [ 2, {
"required": {
"every": [ "nesting", "id" ]
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ coverage/
dist/
build/
.env
.idea
support/package-aur/*
!support/package-aur/manager.sh
!support/package-aur/PKGBUILD
64 changes: 58 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,43 @@ Re-designs the way tasks, task info, tracked time and communication is done on r

The project was originally developed for a MVP portfolio showcase, but there is some roadmap planned with new features that might be added once I find enough of free time.

Thanks for using, or considering to use this project. I would love to hear some feedback as well as your suggestions and thoughts about what could be improved. If you have something to say, don't hesitate to [send me an email](mailto:redshape.app@gmail.com).
Thanks for using, or considering to use this project.

![Redshape Screenshot](https://user-images.githubusercontent.com/4171202/58926139-bbd6df00-8752-11e9-92bb-ddfdb5bce33d.png)

## Installation

### macOS

Download the latest [Redshape release](https://github.com/Spring3/redshape/releases/latest).

The application will automatically update when a new release is available.

### Windows

Download the latest [Redshape installer](https://github.com/Spring3/redshape/releases).

You can download the .exe installer or the web installer. Both automatically detect the system architecture and set up the correct version.

The application will automatically update when a new release is available.


### Linux

Download the latest [Redshape release](https://github.com/Spring3/redshape/releases/latest).

The application will automatically update when a new release is available.

## License
[GPL-3.0](https://github.com/Spring3/redshape/blob/master/LICENSE.md)
## Development

Created by [Daniyil Vasylenko](https://github.com/Spring3)
If you don't have access to a deployed instance of redmine, you can now run it in docker

Unfortuantely, you will have to configure it then yourself

```
docker-compose -f docker-compose.yml up
```

Then after you run the project with `npm run dev`, use `http://localhost` as redmine endpoint on the login form and provide the credentials or the API token

## FAQ

Expand All @@ -48,6 +55,51 @@ Created by [Daniyil Vasylenko](https://github.com/Spring3)
#### - Markdown is displayed incorrectly
Please ask your Redmine admin user to check if it's enabled in `Administration -> General -> Text Formatting` menu. This path may change with the upcoming redmine releases, so please refer to Redmine documentation to find out exactly where this switch is located for your version of Redmine

#### - My antivirus / Defender / Mac OS warns that it's not safe to run this app
#### - My antivirus / Defender / Mac OS warns that it's not safe to run this app
Mac OS build was signed by a **self-signed certificate**, while Windows and Linux builds **were not signed at all**. In such case, you will see this warnings upon download or running the application / installation, saying that this app is not safe to run or that it was provided by an unknown developer and is not safe to run.

#### - How to use timer controls

Timer controls allow to manually modify the time for the timer by (1 or 5 minutes back and forth) as well as write temporary comments. Using these, we can directly modify the time after the pause in the task. To enable it, toggle the "Use advanced timer controls" item in the Settings menu

#### - Idle behavior

Redshape can pause the timer if it detects the system is idle for a range of times (5, 10 o 15 minutes). It will warn with notifications (15s. warning time before pausing).

Optionally, it can automatically discard the idle time from the current timer when it is paused.

#### - More accurate progressbar

Issue progress slider can be changed with 1% step if configured (by default is 10%).
Enable this if you have support in the server side (ruby, redmine) to use every percentage (33%, 81%, etc).

### AUR package

Electron-builder does not offer aur packages. Therefore, in the directory `support/package-aur` we can build those for ArchLinux/Manjaro distributions. It is "optimized" and just installs around 50MiB, using the system electron, as it is exposed here [issue 4059](https://github.com/electron-userland/electron-builder/issues/4059).

```sh
bash support/package-aur/manager.sh pack # can be omitted if using the archive from the repo
bash support/package-aur/manager.sh makepkg
```

Before publishing a release, you have to update the PKGBUILD:

```sh
# using npm script:
npm run release:aur

# alternatively, with the shell:
bash support/package-aur/manager.sh pack pkgbuild
```

The second target (`pkgbuild`) will update the version and md5sums of the PKGBUILD.


## License
[GPL-3.0](https://github.com/Spring3/redshape/blob/master/LICENSE.md)

Created by [Daniyil Vasylenko](https://github.com/Spring3)

## Contributors

[rNoz](https://github.com/rnoz) from [Group4Layers](https://www.group4layers.com)
5 changes: 4 additions & 1 deletion __mocks__/electron-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,24 @@ class Store {
}

get = (key) => {
// eslint-disable-next-line
console.log('[electron-store] Using mocked get function');
return values[key];
}

has = (key) => {
// eslint-disable-next-line
console.log('[electron-store] Using mocked has function');
return Object.hasOwnProperty.call(values, key);
}

set = (key, value) => {
// eslint-disable-next-line
console.log('[electron-store] Using mocked set function');
values[key] = value;
}

delete = (key) => delete values[key];
delete = (key) => delete values[key];

clear = () => Store.__reset();
}
Expand Down
16 changes: 15 additions & 1 deletion __mocks__/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const shell = {
openExternal: () => {}
};

const powerMonitor = {
getSystemIdleTime: jest.fn()
};

const remote = {
shell,
process: {
Expand All @@ -17,10 +21,20 @@ const remote = {
if (path.includes('/common/request')) {
return require('../common/request'); // eslint-disable-line
}
if (path.includes('electron')) {
return { powerMonitor };
}
return undefined;
}
};

const ipcRenderer = {
on: jest.fn(),
send: jest.fn(),
removeListener: jest.fn()
};

module.exports = {
remote
remote,
ipcRenderer
};
3 changes: 3 additions & 0 deletions __mocks__/image-mock.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
import React from 'react';

// eslint-disable-next-line react/jsx-filename-extension
export default () => (<div className="image" />);
4 changes: 4 additions & 0 deletions __mocks__/ipc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
send: jest.fn(),
setupTimer: jest.fn(),
};
Binary file added assets/icon-pause-tray-macTemplate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-pause.ico
Binary file not shown.
Binary file added assets/icon-pause.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-play-tray-macTemplate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-play.ico
Binary file not shown.
Binary file added assets/icon-play.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-tray-macTemplate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/icon.icns
Binary file not shown.
5 changes: 3 additions & 2 deletions common/env.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// eslint-disable-next-line
const { remote } = require('electron');
const _pick = require('lodash/pick');
const pick = require('lodash/pick');

let config;

// main process
const mainProcess = process && process.type !== 'renderer' ? process : remote.process;

if (!config) {
config = _pick(mainProcess.env, 'PORT', 'ENCRYPTION_KEY', 'NODE_ENV');
config = pick(mainProcess.env, 'PORT', 'ENCRYPTION_KEY', 'NODE_ENV');
config.platform = mainProcess.platform;
}

Expand Down
3 changes: 2 additions & 1 deletion common/reporter.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const { openNewGitHubIssue, debugInfo } = require('electron-util');

module.exports = {
report: error => openNewGitHubIssue({
report: (error) => openNewGitHubIssue({
user: 'Spring3',
repo: 'redshape',
body: error && error instanceof Error
// eslint-disable-next-line max-len
? `Please describe the issue as detailed as you can\n\n---\n### Error Stack:\n \`\`\`\n${error.stack}\n\`\`\`\n### Debug Info:\n \`\`\`\n${debugInfo()}\n\`\`\``
: `Please describe the issue as detailed as you can\n\n---\n### Debug Info:\n \`\`\`\n${debugInfo()}\n\`\`\``
})
Expand Down
11 changes: 10 additions & 1 deletion common/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,16 @@ const handleReject = (error) => {
// if this request was not cancelled
if (!axios.isCancel(error)) {
let errorMessage = 'Error';
if (error.status) {
const { response } = error;
const data = response && response.data;
const errors = data && data.errors;
if (errors) {
if (errors.length > 1) {
errorMessage = `${errorMessage}s - ${errors.join(' - ')}`;
} else {
errorMessage = `${errorMessage} ${errors[0]}`;
}
} else if (error.status) {
errorMessage = `${errorMessage} ${error.status}`;
}
errorMessage = `${errorMessage} (${error.statusText || error.message})`;
Expand Down
8 changes: 5 additions & 3 deletions common/utils.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
const xss = require('xss');
// eslint-disable-next-line import/no-extraneous-dependencies
const { shell } = require('electron').remote;

const openExternalUrl = url => new Promise((resolve, reject) => { // eslint-disable-line
return (url && (url.startsWith('http') || url.startsWith('mailto:')))
? resolve(url)
: reject(new Error('Intercepted suspicious url', url));
})
.then(link => shell.openExternal(link))
.catch(error => console.error('Error when opening external url', url, error.message));
.then((link) => shell.openExternal(link))
// eslint-disable-next-line
.catch((error) => console.error('Error when opening external url', url, error.message));

const xssFilter = input => xss(input);
const xssFilter = (input) => xss(input);

module.exports = {
openExternalUrl,
Expand Down
23 changes: 23 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: '3.1'

services:
redmine:
image: redmine:4.1
restart: always
ports:
- 80:3000
environment:
REDMINE_DB_MYSQL: db
REDMINE_DB_PASSWORD: example

db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: redmine
volumes:
- db-data:/var/lib/mysql/data

volumes:
db-data:
4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ module.exports = {
clearMocks: true,
collectCoverage: true,
setupFilesAfterEnv: ['./setupJest.js'],
snapshotSerializers: ['enzyme-to-json/serializer'],
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/style-mock.js',
'\\.(png)$': '<rootDir>/__mocks__/image-mock.js'
'\\.(png)$': '<rootDir>/__mocks__/image-mock.js',
ipc$: '<rootDir>/__mocks__/ipc.js'
}
};
Loading