GithubHelp home page GithubHelp logo

tagip / forest-guard Goto Github PK

View Code? Open in Web Editor NEW
26.0 6.0 6.0 412 KB

Forest Guard is a [Taiga](https://taiga.io/) dashboard for managers to see who is doing what on their different Taiga projects.

HTML 4.59% CSS 2.30% JavaScript 93.11%
taiga dashboard react admin-on-rest

forest-guard's Introduction

Forest Guard is a Taiga dashboard where managers (and any logged user) can see what their teammates are working on (tasks and issues). It is built using the great admin-on-rest framework.

The main view is a grid list of users and their assigned tasks and issues that are not closed yet.

ScreenShot

Start the project

Using yarn

You need to have yarn installed on your computer. First, install dependencies with

$ yarn install

Then you are ready to run the project using

$ yarn start

If you have a custom Taiga instance, set REACT_APP_API_URL and REACT_APP_API_URL variables as you start the project or place them in a .env file:

$ REACT_APP_BASE_URL=http://taiga.tag-ip.com REACT_APP_API_URL=http://taiga.tag-ip.com/api/v1 yarn start

Using docker

Build the docker image with

$ docker build -t forest-guard .

You can set the REACT_APP_API_URL and REACT_APP_API_URL variables if needed using

$ docker build --build-arg REACT_APP_API_URL=http://taiga.tag-ip.com/api/v1 --build-arg REACT_APP_BASE_URL=http://taiga.tag-ip.com -t forest-guard .

Then you run the image (here on port 8056) with

$ docker run -p 8056:80 --name forest-guard --rm forest-guard

Finally, you can push the image in a registry (either docker hub or a private registry) so it can be used from anywhere else :

$ docker tag forest-guard registry.example.org/forest-guard:latest
$ docker push registry.example.org/forest-guard:latest

Environment variables

Environment variables car be inserted in the .env file

REACT_APP_API_URL: The URL for the API root (default to https://api.taiga.io/api/v1)

REACT_APP_BASE_URL: The URL of Taiga front-end (default to http://tree.taiga.io/)

REACT_APP_DUE_DATE_CUSTOM_ATTRIBUTES: A JSON object that describes custom attributes used as due date field. The structure of the object is like so:

{
  PROJECT_X_ID: {
    'issue': CUSTOM_FIELD_X_ID,
    'task': ANOTHER_CUSTOM_FIELD_X_ID
  },
  PROJECT_Y_ID: {
    'issue': CUSTOM_FIELD_X_ID,
    'task': ANOTHER_CUSTOM_FIELD_X_ID
  },
  // ...
}

REACT_APP_ISSUE_STATUS_FILTER: A comma separated list of issue status ID used as filter.

REACT_APP_TASK_STATUS_FILTER: A comma separated list of task status ID used as filter.

REACT_APP_IGNORE_USERS: A comma separated list of user ID that shouldn't be displayed.

forest-guard's People

Contributors

mikaoelitiana avatar sirhexalot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

forest-guard's Issues

User Dashboard

Would it be possible to have a personal user dashboard?

List of my projects

List of my issues
List of my tasks

We want to use taiga as a multi project management solution. But the taiga dashboard is not very usefull for us.

Your project is absolut fantastic! If you like we can also help on adding new features.

Add watchers to Issue and Tasks

Hi,

would it be possible to expand the filter to have also the watchers:

<List {...props} perPage={30} filter={{ status__is_closed: false, assigned_to: localStorage.getItem('user_id') }}>

German Translation

Hi there,

I would like to provide a german translation. How can I help?

Create taiga link

Is it possible to create a taiga link like:

https://tree.taiga.com/project/[project name]/issue/38

export const TaskList = (props) => (
  <List {...props} perPage={30} filter={{ status__is_closed: false }}>
    <Datagrid>
      <TextField source="id" />
      <TextField source="project_extra_info.name" label="Project" />
      <TextField source="subject"/>
      <TextField source="status_extra_info.name" label="Status"/>
      <TextField source="assigned_to_extra_info.full_name_display" label="Assignee"/>
    </Datagrid>
  </List>
);
export const UserList = (props) => (
  <List {...props} perPage={30} title="fg.work_in_progress">
    <Datagrid>
      <TextField source="id" sortable={false} />
      <TextField source="full_name" sortable={false} />
      <WorkInProgressField source="tasks_issues" sortable={false} {...props} />
    </Datagrid>
  </List>
);

Update german translation for new routes

`import moment from 'moment';
import { resolveBrowserLocale } from 'admin-on-rest';

const messages = {
// FRENCH
fr: {
fg: {
created_on: 'Créé le',
due_date: 'Echéance',
work_in_progress: 'Travaux en cours',
},
resources: {
users: {
name: 'Travaux en cours',
fields: {
full_name: 'Nom',
tasks_issues: 'Tâches/Tickets',
}
},
issues: {
name: 'Tickets assignés'
},
tasks: {
name: 'Tâches assignées'
}
}
},

// ENGLISH
en: {
fg: {
created_on: 'Created on',
due_date: 'Due date',
work_in_progress: 'Work in progress',
todo_list: 'Todo',
},
resources: {
users: {
name: 'Work in progress',
fields: {
full_name: 'Name',
tasks_issues: 'Tasks/Issues',
}
},
issues: {
name: 'Assigned Issues'
},
tasks: {
name: 'Assigned Tasks'
}
}
},

// GERMAN
de: {
fg: {
created_on: 'Erstellt am',
due_date: 'Fällig am',
work_in_progress: 'In Arbeit',
todo_list: 'Todo'
},
resources: {
users: {
name: 'In Arbeit',
fields: {
full_name: 'Name',
tasks_issues: 'Aufgabe/Problem',
}
}
}
}
}

export default messages;

moment.locale('fr', {
months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct.nov.déc.'.split(''),
monthsParseExact: true,
weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('
'),
weekdaysShort: 'dim._lun._mar._mer._jeu.ven.sam.'.split(''),
weekdaysMin: 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('
'),
weekdaysParseExact: true,
longDateFormat: {
LT: 'HH:mm',
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
LLL: 'D MMMM YYYY HH:mm',
LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[Aujourd’hui à] LT',
nextDay: '[Demain à] LT',
nextWeek: 'dddd [à] LT',
lastDay: '[Hier à] LT',
lastWeek: 'dddd [dernier à] LT',
sameElse: 'L'
},
relativeTime: {
future: 'dans %s',
past: 'il y a %s',
s: 'quelques secondes',
m: 'une minute',
mm: '%d minutes',
h: 'une heure',
hh: '%d heures',
d: 'un jour',
dd: '%d jours',
M: 'un mois',
MM: '%d mois',
y: 'un an',
yy: '%d ans'
},
dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
ordinal: function (number) {
return number + (number === 1 ? 'er' : 'e');
},
meridiemParse: /PD|MD/,
isPM: function (input) {
return input.charAt(0) === 'M';
},
// In case the meridiem units are not separated around 12, then implement
// this function (look at locale/id.js for an example).
// meridiemHour : function (hour, meridiem) {
// return /* 0-23 hour, given meridiem token and hour 1-12 */ ;
// },
meridiem: function (hours, minutes, isLower) {
return hours < 12 ? 'PD' : 'MD';
},
week: {
dow: 1, // Monday is the first day of the week.
doy: 4 // The week that contains Jan 4th is the first week of the year.
}
});

moment.locale('de', {
months: 'Jaunar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sept._Okt.Nov.Dez.'.split(''),
monthsParseExact: true,
weekdays: 'Sonntag_Montag_Dientag_Mittwoch_Donnerstag_Freitag_Samstag'.split('
'),
weekdaysShort: 'So._Mo._Di._Mi._Do.Fr.Sa.'.split(''),
weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('
'),
weekdaysParseExact: true,
longDateFormat: {
LT: 'HH:mm',
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
LLL: 'D MMMM YYYY HH:mm',
LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[heute um}] LT',
nextDay: '[morgen um] LT',
nextWeek: 'dddd [in] LT',
lastDay: '[Gestern um] LT',
lastWeek: 'dddd [vor dem] LT',
sameElse: 'L'
},
relativeTime: {
future: 'in %s',
past: 'vor %s',
s: 'einigen Sekunden',
m: 'eine Minute',
mm: '%d Minuten',
h: 'eine Stunde',
hh: '%d Stunden',
d: 'eine Woche',
dd: '%d Wochen',
M: 'ein Monat',
MM: '%d Monate',
y: 'ein Jahr',
yy: '%d Jahre'
},
dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
ordinal: function (number) {
return number + (number === 1 ? 'er' : 'e');
},
meridiemParse: /PD|MD/,
isPM: function (input) {
return input.charAt(0) === 'M';
},
// In case the meridiem units are not separated around 12, then implement
// this function (look at locale/id.js for an example).
// meridiemHour : function (hour, meridiem) {
// return /* 0-23 hour, given meridiem token and hour 1-12 */ ;
// },
meridiem: function (hours, minutes, isLower) {
return hours < 12 ? 'PD' : 'MD';
},
week: {
dow: 1, // Monday is the first day of the week.
doy: 4 // The week that contains Jan 4th is the first week of the year.
}
});

export const momentLocale = () => {
const available = moment.locales();
const browser = resolveBrowserLocale();
if (available.indexOf(browser) > 0) {
return browser;
}
return 'en';
}
`

Users Overview

Is it possible to have the field this.props.record.project_extra_info.name in the users overview?

It would be great if it is poosible to have a view which is group by this.props.record.project_extra_info.name

Best
Adrian

/#/issues Filter

Hi,

is it possible to have a filter for issues and tasks.

It would be nice to have default a filter "my issues" or "my tasks". And even have the possibity to remove that default filter to view all issues an all tasks.

That would be great.

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.