Giter Site home page Giter Site logo

davidackroyd99 / harvest-dashboard Goto Github PK

View Code? Open in Web Editor NEW

This project forked from vincentrohde/harvest-dashboard

0.0 1.0 0.0 975 KB

An open-source, third-party React client for the Harvest API V2 (time-tracking) ⏰

JavaScript 16.95% HTML 0.35% TypeScript 78.69% Shell 0.17% Dockerfile 0.53% SCSS 3.17% Makefile 0.13%

harvest-dashboard's Introduction

Harvest Dashboard

GitHub release (latest by date) GitHub tag (latest SemVer) Deployment CodeQL

A third-party React.js client for the Harvest API V2, that helps you to manage the time-trackings of your Harvest Account, while also giving you statistical feedback on how you spend your time.

Contents

  1. Getting Started
    1. Prerequisites
    2. Installation
    3. Access to Harvest
    4. Start the Project
  2. Features
    1. Semantic UI
    2. Chart.js
    3. Components
    4. Services
  3. Development
    1. Branches
    2. Types files
    3. Workflows
  4. Production
    1. Automatic Deploy (fork)
    2. Manual Deploy (no fork)

Getting Started

Prerequisites

First of all, you will need a Harvest account to fully use this project. The free version will do fine. To run the client, you need to have Node.js and its package manager npm installed on your environment.

Installation

Clone repository

git clone https://github.com/vincentrohde/harvest-dashboard.git
cd ./harvest-dashboard

Install Server dependencies

cd ./server
npm install

Install Client dependencies

cd ./client
npm install

Access to Harvest

Add an .env file

Start by creating your own .env file in the /server directory. You can use the .env.example file and just create a copy of it, with the filename .env like so:

cp ./server/.env.example ./server/.env

Harvest v2 Personal Access Token

If you have your Harvest account ready. It's time to setup your own Personal Access Token. To do so, jump over to the Developers section of your account.

Under the tab Personal Access Tokens you will find the option Create New Personal Access Token

First of all start by setting the name for your token.

Setup Access to your Harvest Account

Now that you have your Personal Access Token. It's time to add its data to your .env file in ./server. The fields marked in red (see below) are required in your .env file.

This should be your version of ./server/.env :

HARVEST_API_URL=https://api.harvestapp.com
ACCESS_TOKEN={{ Insert "Your Token" here }}
ACCOUNT_ID={{ Insert "Account ID" here }}
READ_ONLY=false

Start the Project

Now that you have everything in place you can start the servers.

Backend

To start the backend server, simply go to the ./server directory and run the following command:

npm run start

The backend will be available under:

http://localhost:8080

Client

To start the client's dev-server, go to the ./client directory and run:

npm run start

The dev-server will be available under:

http://localhost:3000

Now both servers are running and will automatically reload on file changes.

Features

Semantic UI

When implementing templates, the project makes use of Semantic UI through semantic-ui-react.

Chart.js

When implementing data visualization, the project makes use of chart.js.

Components

DatePicker

With the DatePicker component you are able, to either select a certain date, a date range or a preset date range. On default, the today preset is selected.

Presets
Preset Output Format
today [currentDay] <'DD-MM-YYYY'>[]
one-week [6 days ago, currentDay] <'DD-MM-YYYY'>[]
one-month [29 days ago, currentDay] <'DD-MM-YYYY'>[]
one-year [364 days ago, currentDay] <'DD-MM-YYYY'>[]
all 1 number

Once a date value (either a single date, a date-range or 1) is set, the applications redux store (store.filters.dateRange) will be updated. When the dateRange property is updated, the application will request new time-entries from the backend.

EditForm

The EditForm component allows you to add new time-entries as well as updating existing ones.

Props

The following props can be passed to the EditForm component, but are not required.

Prop Information Default
data data of the time-entry *
onSuccess callback when submit succeeds () => {}
onCancel callback when submit was cancelled () => {}

*) If no data is provided, the component will fall back on its defaultData which can be found in EditForm/defaultData.ts. This will be then handled as a isNewEntry.

onChange

Whenever the user makes updates to the data, the component will update its lastInputChange state (latest field that was updated).

useErrorCheck

The EditForm component comes with its own hook called useErrorCheck. It passes lastInputChange and entry as props to the hook.

The entry prop is debounced (using useDebounce) and is compared with its prevDebouncedEntry prop. This is supposed to prevent error-checking while the user is still typing and unecessary error-checking if the content did not change.

The fields that are checked, are hours and spent_date. If the hook finds any errors it will return the list of field-names, that are not matching the format.

onSubmit

When a new entry is submitted by the user, the component will reset itself to default with resetStateToDefault(). In both cases (create or update an entry) the onSuccess callback method is executed.

DataOverview

The DataOverview component gives the user a data-visualisation of his/ her time-entries.

It's possible to filter by tasks or projects and sort by time-unit (day, week, month or year).

Services

Services are classes that bundle various utility functions, that belong to a certain topic (ex. time-formatting). Server and client each have their own services.

Each service is written in the same pattern:

class ExampleService {
    ...
}

const exampleService = new ExampleService();
export default exampleService;

BackendService

Communication (create, read, update, delete) to the backend by the client using axios.

ApiService (Server)

Communication (create, read, update, delete) to the Harvest API by the server using axios.

TimeService

Time utility functions (ex. comparing or formatting dates) using moment.js.

Development

Branches

master

The master branch is used as the project's release branch. No development should happen here.

develop

The develop branch is used as a collection for changes that will end up as a new release. In general, new pushes should only come through merging feature/ or bug/ branches into develop.

feature/

A feature/** branch should be used for the development of a new feature. When the feature is ready, a Pull Request into develop should be opened.

bug/

A bug/** branch should be used when fixing bug-issues. When the bug is fixed, a Pull Request into develop should be opened.

Types files

To prevent cluttering regular files with Typescript declarations (ex. interfaces, types, etc.). they should be moved into a separate file using the .types naming. The regular file will then import the .types file declarations.

Example

This is an example for a React component:

+ MyComponent
|   + MyComponent.tsx
|   + MyComponent.types.ts
// MyComponent.types.ts
export interface MyComponentProps {
    title: string;
}
// MyComponent.tsx

// Types
import { MyComponentProps } from './MyComponent.types';

const MyComponent = ({ title }: MyComponentProps) => <h2>{ title }</h2>;

export default MyComponent;

Workflows

Github Release Action

The Github Release Action workflow is triggered once a new push on master happens. This will generate a new minor tag of the project, which will automatically be released.

Github Patch Action

The Github Patch Action workflow is triggered once a new push on develop happens. This will generate a new patch tag of the project. This patch tag is not released.

Deployment

The Deployment workflow can be triggered manually or with push to master. It will deploy a production-ready version of the project to the server.

Production

There are two ways you can deploy the project. In case you have forked the repository see the next section. If you didn't fork the repository, please follow the manual deployment guide.

Automatic Deploy (fork)

If you have forked this repository you can automatically deploy the project using the Deployment workflow.

Adding Secrets

To do this, you will need to add a few new GitHub secrets to your repo (the fork)

Go to your forked repository on Github and open the Settings tab. Now navigate to Secrets and click on New Repository Secret. Add the following secrets to your repository.

Secret Name Information
SSH_KEY Your SSH key, with access to your server
SSH_HOST Your server's IP address
SSH_USER The server's user you log into with when using ssh
SSH_LOCATION The directory on your server, where the repo should be deployed to (remote directory)

Deploying

Now you can deploy either through pushing new commits to your master branch or through the Actions tab of your repository.

Here you will find a workflow called Deployment. If you click on Run Workflow, you will be able to deploy with any of your repository's branches.

Manual Deploy (no fork)

If you have not created a fork of the repository, this is the guide to deploying the code. The guide assumes you have Docker and Docker Compose installed.

Copy to server

For the deploy you can either clone the project on your server (if you have git installed) or use ssh (scp or rsync) to copy it.

scp

If you have rsync installed you can skip copying with scp.

scp -r /path/to/local/copy user@your-server-ip:/path/to/remote/copy
rsync (alternative, recommended)

If you already copied using scp, you can skip this part.

rsync -avz -e 'ssh' /path/to/local/copy user@your-server-ip:/path/to/remote/copy

Start containers

The rest is fairly simple. Run the following command in the root of the project's directory.

docker-compose up -d

If you have Make installed this command will also do the same.

make prod

Containers

api-server

This Node.js container will provide an Express.js api for your client server. It will be available under:

http://localhost:8080
dashboard

This container runs two services. First, it builds a production version (/dist) of the client (build-service). This version will then be served by ngnix (nginx-server). The container will be available under:

http://localhost

Stop containers

In case you want to stop the containers you can either run

docker-compose down

or

make down

Back To Top

harvest-dashboard's People

Contributors

vincentrohde avatar dependabot[bot] avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.