Step in page merge. Added color indicator. Added Chartjs.

This commit is contained in:
Christian P. MOMON 2020-01-18 09:55:56 +01:00
parent 3f2a667040
commit 879a006c6d
18 changed files with 826 additions and 248 deletions

View file

@ -187,7 +187,7 @@ public final class AgiStatoolCLI
AgirStatoolConfigFile config = new AgirStatoolConfigFile(configurationFile); AgirStatoolConfigFile config = new AgirStatoolConfigFile(configurationFile);
Connection connection = SQLUtils.getConnexion(config.getDabataseUrl(), config.getDabataseName(), config.getDabataseLogin(), config.getDabatasePassword()); Connection connection = SQLUtils.getConnexion(config.getDabataseUrl(), config.getDabataseName(), config.getDabataseLogin(), config.getDabatasePassword());
AgirStatool statool = new AgirStatool(connection, new File(config.getTargetDirectory())); AgirStatool statool = new AgirStatool(connection, new File(config.getTargetDirectory()));
statool.doRefresh(); statool.doRefreshPages();
} }
break; break;
@ -226,6 +226,8 @@ public final class AgiStatoolCLI
throw new AgirStatoolException("Bad parameter count."); throw new AgirStatoolException("Bad parameter count.");
} }
} }
logger.info("Finished.");
} }
catch (AgirStatoolException exception) catch (AgirStatoolException exception)
{ {

View file

@ -20,7 +20,7 @@ package org.april.agirstatool.core;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -28,8 +28,7 @@ import java.sql.SQLException;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.april.agirstatool.cli.SQLUtils; import org.april.agirstatool.cli.SQLUtils;
import org.april.agirstatool.core.pages.ProjectsGroupedPageBuilder; import org.april.agirstatool.core.pages.ProjectPage;
import org.april.agirstatool.core.pages.ProjectsRawPageBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -165,6 +164,7 @@ public class AgirStatool
{ {
try try
{ {
// TODO: add filter on .xhtml and .css file.
for (File file : this.targetDirectory.listFiles()) for (File file : this.targetDirectory.listFiles())
{ {
FileUtils.forceDelete(file); FileUtils.forceDelete(file);
@ -179,34 +179,33 @@ public class AgirStatool
/** /**
* Refresh all. * Refresh all.
*/ */
public void doRefresh() throws AgirStatoolException public void doRefreshPages() throws AgirStatoolException
{ {
try try
{ {
// Copy CSS file. // Copy CSS file.
FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/agirstatool.css"), new File(this.targetDirectory, "agirstatool.css")); FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/agirstatool.css"), new File(this.targetDirectory, "agirstatool.css"));
FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/Chart.bundle.min.js"), new File(this.targetDirectory, "Chart.bundle.min.js"));
// //
Projects projects = listProjectsFullFull(); Project root = listProjectsAsTree();
// Create welcome page. // Create welcome page.
String lines = ProjectsRawPageBuilder.build(projects); refreshWelcomePage(root);
// System.out.println(lines);
FileUtils.write(new File(this.targetDirectory, "index.xhtml"), lines, Charset.defaultCharset());
// Create welcome grouped page.
lines = ProjectsGroupedPageBuilder.build(projects);
// System.out.println(lines);
FileUtils.write(new File(this.targetDirectory, "index2.xhtml"), lines, Charset.defaultCharset());
// Create one page per project. // Create one page per project.
File projectDirectory = new File(this.targetDirectory, "projects"); for (Project project : root.subProjects())
FileUtils.deleteQuietly(projectDirectory);
projectDirectory.mkdir();
for (Project project : projects)
{ {
// refresh(project, projects.get); refreshPage(project);
for (Project subProject : project.subProjects())
{
if (!subProject.getName().startsWith("#"))
{
refreshPage(subProject);
}
}
} }
} }
catch (IOException exception) catch (IOException exception)
{ {
@ -242,7 +241,7 @@ public class AgirStatool
StringList sql = new StringList(); StringList sql = new StringList();
sql.append("SELECT"); sql.append("SELECT");
sql.append(" 0,"); sql.append(" 0,");
sql.append(" '*',"); sql.append(" 'all',");
sql.append(" '*',"); sql.append(" '*',");
sql.append(" null,"); sql.append(" null,");
sql.append(" (select count(*) from projects where status = 1 and is_public = 1) as child_count, "); sql.append(" (select count(*) from projects where status = 1 and is_public = 1) as child_count, ");
@ -371,11 +370,12 @@ public class AgirStatool
return result; return result;
} }
public Projects listProjectsFullFull() throws AgirStatoolException public Project listProjectsAsTree() throws AgirStatoolException
{ {
Projects result; Project result;
result = new Projects(); // Create a root project.
result = getRootProject();
// //
Projects projects = listProjectsWithSubStats(); Projects projects = listProjectsWithSubStats();
@ -392,16 +392,12 @@ public class AgirStatool
} }
} }
// Create a root project.
Project all = getRootProject();
projects.add(all);
// Transform as tree. // Transform as tree.
for (Project project : projects) for (Project project : projects)
{ {
if ((project.hasChild()) || (project.getId() == 0)) if ((project.getParentId() == null) || (project.getId() == 0))
{ {
result.add(project); result.subProjects().add(project);
Projects subProjects = projects.getByParent(project.getId()); Projects subProjects = projects.getByParent(project.getId());
subProjects.sortByName(); subProjects.sortByName();
@ -409,7 +405,7 @@ public class AgirStatool
} }
} }
result.sortByName(); result.subProjects().sortByName();
// //
return result; return result;
@ -605,4 +601,52 @@ public class AgirStatool
{ {
} }
/**
* Refresh page.
*
* @param project
* the project
* @throws AgirStatoolException
* the agir statool exception
*/
public void refreshPage(final Project project) throws AgirStatoolException
{
try
{
if (project != null)
{
String page = ProjectPage.build(project);
FileUtils.write(new File(this.targetDirectory, project.getIdentifier() + ".xhtml"), page, StandardCharsets.UTF_8);
}
}
catch (IOException exception)
{
throw new AgirStatoolException("Error refreshing page: " + exception.getMessage(), exception);
}
}
/**
* Refresh welcomme page.
*
* @param project
* the project
* @throws AgirStatoolException
* the agir statool exception
*/
public void refreshWelcomePage(final Project root) throws AgirStatoolException
{
try
{
if (root != null)
{
String page = ProjectPage.build(root);
FileUtils.write(new File(this.targetDirectory, "index.xhtml"), page, StandardCharsets.UTF_8);
}
}
catch (IOException exception)
{
throw new AgirStatoolException("Error refreshing welcome page: " + exception.getMessage(), exception);
}
}
} }

View file

@ -43,6 +43,62 @@ public class AgirStatoolUtils
return new Date().getTime(); return new Date().getTime();
} }
/**
* Select stat indicator.
*
* @param value
* the value
* @return the string
*/
public static String selectStatIndicator(final long value)
{
String result;
if (value < 10)
{
result = null;
}
else if (value < 20)
{
result = " caution";
}
else if (value < 50)
{
result = " warning";
}
else
{
result = " alert";
}
//
return result;
}
/**
* Select unassigned indicator.
*
* @param value
* the value
* @return the string
*/
public static String selectUnassignedIndicator(final long value)
{
String result;
if (value == 0)
{
result = null;
}
else
{
result = " alert";
}
//
return result;
}
/** /**
* To human long. * To human long.
* *

View file

@ -43,7 +43,7 @@ public class Project
this.id = id; this.id = id;
this.identifier = identifier; this.identifier = identifier;
this.name = name; this.name = name;
this.path = "projects/" + identifier + ".xhtml"; this.path = identifier + ".xhtml";
this.parentId = parentId; this.parentId = parentId;
this.subProjects = new Projects(); this.subProjects = new Projects();
this.childCount = 0; this.childCount = 0;

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,76 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian.momon@devinsy.fr>
*
* This file is part of AgirStatool, simple key value database.
*
* AgirStatool is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* AgirStatool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with AgirStatool. If not, see <http://www.gnu.org/licenses/>.
*/
package org.april.agirstatool.core.pages;
import org.april.agirstatool.core.AgirStatoolException;
import org.april.agirstatool.core.Project;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.xidyn.XidynException;
import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.presenters.PresenterUtils;
/**
* The class AgirStatool.
*
* @author Christian Pierre MOMON
*/
public class ProjectPage
{
private static Logger logger = LoggerFactory.getLogger(ProjectPage.class);
/**
* Builds the.
*
* @param projects
* the projects
* @return the string
* @throws AgirStatoolException
* the agir statool exception
*/
public static String build(final Project project) throws AgirStatoolException
{
String result;
try
{
logger.info("Building project page " + project.getName() + "");
TagDataManager data = new TagDataManager();
data.setContent("projectName", project.getName());
String projectsRawView = ProjectsRawView.build(project);
data.setContent("projectsRawView", projectsRawView);
String projectsGroupedView = ProjectsGroupedView.build(project);
data.setContent("projectsGroupedView", projectsGroupedView);
result = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/project.xhtml", data).toString();
}
catch (XidynException exception)
{
throw new AgirStatoolException("Error building project page: " + exception.getMessage(), exception);
}
//
return result;
}
}

View file

@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringEscapeUtils;
import org.april.agirstatool.core.AgirStatoolException; import org.april.agirstatool.core.AgirStatoolException;
import org.april.agirstatool.core.AgirStatoolUtils; import org.april.agirstatool.core.AgirStatoolUtils;
import org.april.agirstatool.core.Project; import org.april.agirstatool.core.Project;
import org.april.agirstatool.core.Projects;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -35,9 +34,9 @@ import fr.devinsy.xidyn.presenters.PresenterUtils;
* *
* @author Christian Pierre MOMON * @author Christian Pierre MOMON
*/ */
public class ProjectsGroupedPageBuilder public class ProjectsGroupedPage
{ {
private static Logger logger = LoggerFactory.getLogger(ProjectsGroupedPageBuilder.class); private static Logger logger = LoggerFactory.getLogger(ProjectsGroupedPage.class);
/** /**
* Builds the. * Builds the.
@ -48,7 +47,7 @@ public class ProjectsGroupedPageBuilder
* @throws AgirStatoolException * @throws AgirStatoolException
* the agir statool exception * the agir statool exception
*/ */
public static String build(final Projects projects) throws AgirStatoolException public static String build(final Project root) throws AgirStatoolException
{ {
String result; String result;
@ -57,26 +56,10 @@ public class ProjectsGroupedPageBuilder
System.out.println("Building ProjectsGrouped page…"); System.out.println("Building ProjectsGrouped page…");
TagDataManager data = new TagDataManager(); TagDataManager data = new TagDataManager();
int index = 0; String projectsView = ProjectsGroupedView.build(root);
for (Project project : projects) data.setContent("projectsView", projectsView);
{
if (project.getParentId() == null)
{
fillLine(data, index, project);
index += 1;
}
if (project.hasChild()) result = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/projectsGroupedPage.xhtml", data).toString();
{
for (Project subProject : project.subProjects())
{
fillLine(data, index, subProject);
index += 1;
}
}
}
result = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/projectsGrouped.xhtml", data).toString();
} }
catch (XidynException exception) catch (XidynException exception)
{ {
@ -97,7 +80,7 @@ public class ProjectsGroupedPageBuilder
* @param project * @param project
* the project * the project
*/ */
private static void fillLine(final TagDataManager data, final int index, final Project project) public static void fillLine(final TagDataManager data, final int index, final Project project)
{ {
data.setContent("projectLine", index, "projectId", project.getId()); data.setContent("projectLine", index, "projectId", project.getId());
if (project.getParentId() != null) if (project.getParentId() != null)

View file

@ -0,0 +1,126 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian.momon@devinsy.fr>
*
* This file is part of AgirStatool, simple key value database.
*
* AgirStatool is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* AgirStatool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with AgirStatool. If not, see <http://www.gnu.org/licenses/>.
*/
package org.april.agirstatool.core.pages;
import org.apache.commons.lang3.StringEscapeUtils;
import org.april.agirstatool.core.AgirStatoolException;
import org.april.agirstatool.core.AgirStatoolUtils;
import org.april.agirstatool.core.Project;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.xidyn.XidynException;
import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.presenters.PresenterUtils;
import fr.devinsy.xidyn.utils.XidynUtils;
/**
* The class AgirStatool.
*
* @author Christian Pierre MOMON
*/
public class ProjectsGroupedView
{
private static Logger logger = LoggerFactory.getLogger(ProjectsGroupedView.class);
/**
* Builds the.
*
* @param projects
* the projects
* @return the string
* @throws AgirStatoolException
* the agir statool exception
*/
public static String build(final Project project) throws AgirStatoolException
{
String result;
try
{
logger.info("Building ProjectsGrouped view…");
TagDataManager data = new TagDataManager();
fillLine(data, 0, project);
int index = 1;
for (Project subProject : project.subProjects())
{
fillLine(data, index, subProject);
index += 1;
for (Project subSubProject : subProject.subProjects())
{
fillLine(data, index, subSubProject);
index += 1;
}
}
CharSequence page = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/projectsGroupedView.xhtml", data);
result = XidynUtils.extractBodyContent(page);
}
catch (XidynException exception)
{
throw new AgirStatoolException("Error building ProjectsGrouped view: " + exception.getMessage(), exception);
}
//
return result;
}
/**
* Fill line.
*
* @param data
* the data
* @param index
* the index
* @param project
* the project
*/
public static void fillLine(final TagDataManager data, final int index, final Project project)
{
data.setContent("projectGroupedLine", index, "pgl_projectId", project.getId());
if (project.getParentId() != null)
{
data.setAttribute("projectGroupedLine", index, "pgl_projectName", "style", "padding-left: 25px;");
}
data.setAttribute("projectGroupedLine", index, "pgl_projectNameLink", "href", project.getPath());
data.setContent("projectGroupedLine", index, "pgl_projectNameLink", StringEscapeUtils.escapeXml(project.getName()));
data.setContent("projectGroupedLine", index, "pgl_childCount", project.getChildCount());
data.setContent("projectGroupedLine", index, "pgl_issueCount", project.issueStats().getCount());
data.setContent("projectGroupedLine", index, "pgl_activeIssueCount", project.issueStats().getActiveCount());
data.setAttribute("projectGroupedLine", index, "pgl_activeIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getActiveCount()));
data.setContent("projectGroupedLine", index, "pgl_maybeIssueCount", project.issueStats().getMaybeCount());
data.setContent("projectGroupedLine", index, "pgl_resolvedIssueCount", project.issueStats().getResolvedCount());
data.setAttribute("projectGroupedLine", index, "pgl_resolvedIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getResolvedCount()));
data.setContent("projectGroupedLine", index, "pgl_concludedIssueCount", project.issueStats().getConcludedCount());
data.setContent("projectGroupedLine", index, "pgl_unassignedIssueCount", project.issueStats().getUnassignedCount());
data.setContent("projectGroupedLine", index, "pgl_unassignedNewIssueCount", project.issueStats().getUnassignedNewCount());
data.setContent("projectGroupedLine", index, "pgl_unassignedStartedIssueCount", project.issueStats().getUnassignedStartedCount());
data.setAttribute("projectGroupedLine", index, "pgl_unassignedStartedIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getUnassignedStartedCount()));
data.setContent("projectGroupedLine", index, "pgl_unassignedResolvedIssueCount", project.issueStats().getUnassignedResolvedCount());
data.setAttribute("projectGroupedLine", index, "pgl_unassignedResolvedIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getUnassignedResolvedCount()));
data.setContent("projectGroupedLine", index, "pgl_unassignedConcludedIssueCount", project.issueStats().getUnassignedConcludedCount());
data.setAttribute("projectGroupedLine", index, "pgl_unassignedConcludedIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getUnassignedConcludedCount()));
data.setContent("projectGroupedLine", index, "pgl_lastUpdate", AgirStatoolUtils.toHumanShort(project.issueStats().getLastUpdate(), "n/a"));
data.setAttribute("projectGroupedLine", index, "pgl_lastUpdate", "title", AgirStatoolUtils.toHumanLong(project.issueStats().getLastUpdate(), "n/a"));
}
}

View file

@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringEscapeUtils;
import org.april.agirstatool.core.AgirStatoolException; import org.april.agirstatool.core.AgirStatoolException;
import org.april.agirstatool.core.AgirStatoolUtils; import org.april.agirstatool.core.AgirStatoolUtils;
import org.april.agirstatool.core.Project; import org.april.agirstatool.core.Project;
import org.april.agirstatool.core.Projects;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -33,9 +32,9 @@ import fr.devinsy.xidyn.presenters.PresenterUtils;
/** /**
* The Class projectsRawPageBuilder. * The Class projectsRawPageBuilder.
*/ */
public class ProjectsRawPageBuilder public class ProjectsRawPage
{ {
private static Logger logger = LoggerFactory.getLogger(ProjectsRawPageBuilder.class); private static Logger logger = LoggerFactory.getLogger(ProjectsRawPage.class);
/** /**
* Builds the. * Builds the.
@ -46,7 +45,7 @@ public class ProjectsRawPageBuilder
* @throws AgirStatoolException * @throws AgirStatoolException
* the agir statool exception * the agir statool exception
*/ */
public static String build(final Projects projects) throws AgirStatoolException public static String build(final Project root) throws AgirStatoolException
{ {
String result; String result;
@ -55,26 +54,11 @@ public class ProjectsRawPageBuilder
System.out.println("Building ProjectsRaw page…"); System.out.println("Building ProjectsRaw page…");
TagDataManager data = new TagDataManager(); TagDataManager data = new TagDataManager();
int index = 0;
for (Project project : projects)
{
if (project.getParentId() == null)
{
fillLine(data, index, project);
index += 1;
}
if (project.hasChild()) String projectsView = ProjectsRawView.build(root);
{ data.setContent("projectsView", projectsView);
for (Project subProject : project.subProjects())
{
fillLine(data, index, subProject);
index += 1;
}
}
}
result = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/projectsRaw.xhtml", data).toString(); result = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/projectsRawPage.xhtml", data).toString();
} }
catch (XidynException exception) catch (XidynException exception)
{ {

View file

@ -0,0 +1,136 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian.momon@devinsy.fr>
*
* This file is part of AgirStatool, simple key value database.
*
* AgirStatool is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* AgirStatool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with AgirStatool. If not, see <http://www.gnu.org/licenses/>.
*/
package org.april.agirstatool.core.pages;
import org.apache.commons.lang3.StringEscapeUtils;
import org.april.agirstatool.core.AgirStatoolException;
import org.april.agirstatool.core.AgirStatoolUtils;
import org.april.agirstatool.core.Project;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.xidyn.XidynException;
import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.presenters.PresenterUtils;
import fr.devinsy.xidyn.utils.XidynUtils;
/**
* The Class projectsRawPageBuilder.
*/
public class ProjectsRawView
{
private static Logger logger = LoggerFactory.getLogger(ProjectsRawView.class);
/**
* Builds the.
*
* @param projects
* the projects
* @return the string
* @throws AgirStatoolException
* the agir statool exception
*/
public static String build(final Project project) throws AgirStatoolException
{
String result;
try
{
logger.info("Building ProjectsRaw view…");
TagDataManager data = new TagDataManager();
fillLine(data, 0, project);
int index = 1;
for (Project subProject : project.subProjects())
{
fillLine(data, index, subProject);
index += 1;
for (Project subSubProject : subProject.subProjects())
{
fillLine(data, index, subSubProject);
index += 1;
}
}
CharSequence page = PresenterUtils.dynamize("/org/april/agirstatool/core/pages/projectsRawView.xhtml", data);
result = XidynUtils.extractBodyContent(page);
}
catch (XidynException exception)
{
throw new AgirStatoolException("Error building ProjectsRaw view: " + exception.getMessage(), exception);
}
//
return result;
}
/**
* Fill line.
*
* @param data
* the data
* @param index
* the index
* @param project
* the project
*/
private static void fillLine(final TagDataManager data, final int index, final Project project)
{
data.setContent("projectRawLine", index, "prl_projectId", project.getId());
if (project.getParentId() != null)
{
data.setAttribute("projectRawLine", index, "prl_projectName", "style", "padding-left: 25px;");
}
data.setAttribute("projectRawLine", index, "prl_projectNameLink", "href", project.getPath());
data.setContent("projectRawLine", index, "prl_projectNameLink", StringEscapeUtils.escapeXml(project.getName()));
data.setContent("projectRawLine", index, "prl_childCount", project.getChildCount());
data.setContent("projectRawLine", index, "prl_issueCount", project.issueStats().getCount());
data.setContent("projectRawLine", index, "prl_newIssueCount", project.issueStats().getNewCount());
data.setAttribute("projectRawLine", index, "prl_newIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getNewCount()));
data.setContent("projectRawLine", index, "prl_confirmedIssueCount", project.issueStats().getConfirmedCount());
data.setAttribute("projectRawLine", index, "prl_confirmedIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getConfirmedCount()));
data.setContent("projectRawLine", index, "prl_ongoingIssueCount", project.issueStats().getOngoingCount());
data.setAttribute("projectRawLine", index, "prl_ongoingIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getOngoingCount()));
data.setContent("projectRawLine", index, "prl_waitingIssueCount", project.issueStats().getWaitingCount());
data.setContent("projectRawLine", index, "prl_maybeIssueCount", project.issueStats().getMaybeCount());
data.setContent("projectRawLine", index, "prl_resolvedIssueCount", project.issueStats().getResolvedCount());
data.setAttribute("projectRawLine", index, "prl_resolvedIssueCount", "class", AgirStatoolUtils.selectStatIndicator(project.issueStats().getResolvedCount()));
data.setContent("projectRawLine", index, "prl_rejectedIssueCount", project.issueStats().getRejectedCount());
data.setContent("projectRawLine", index, "prl_closedIssueCount", project.issueStats().getClosedCount());
data.setContent("projectRawLine", index, "prl_unassignedIssueCount", project.issueStats().getUnassignedCount());
data.setContent("projectRawLine", index, "prl_unassignedNewIssueCount", project.issueStats().getUnassignedNewCount());
data.setContent("projectRawLine", index, "prl_unassignedConfirmedIssueCount", project.issueStats().getUnassignedConfirmedCount());
data.setContent("projectRawLine", index, "prl_unassignedOngoingIssueCount", project.issueStats().getUnassignedOngoingCount());
data.setAttribute("projectRawLine", index, "prl_unassignedOngoingIssueCount", "class", AgirStatoolUtils.selectUnassignedIndicator(project.issueStats().getUnassignedOngoingCount()));
data.setContent("projectRawLine", index, "prl_unassignedWaitingIssueCount", project.issueStats().getUnassignedWaitingCount());
data.setAttribute("projectRawLine", index, "prl_unassignedWaitingIssueCount", "class", AgirStatoolUtils.selectUnassignedIndicator(project.issueStats().getUnassignedWaitingCount()));
data.setContent("projectRawLine", index, "prl_unassignedMaybeIssueCount", project.issueStats().getUnassignedMaybeCount());
data.setContent("projectRawLine", index, "prl_unassignedResolvedIssueCount", project.issueStats().getUnassignedResolvedCount());
data.setAttribute("projectRawLine", index, "prl_unassignedResolvedIssueCount", "class", AgirStatoolUtils.selectUnassignedIndicator(project.issueStats().getUnassignedResolvedCount()));
data.setContent("projectRawLine", index, "prl_unassignedRejectedIssueCount", project.issueStats().getUnassignedRejectedCount());
data.setAttribute("projectRawLine", index, "prl_unassignedRejectedIssueCount", "class", AgirStatoolUtils.selectUnassignedIndicator(project.issueStats().getUnassignedRejectedCount()));
data.setContent("projectRawLine", index, "prl_unassignedClosedIssueCount", project.issueStats().getUnassignedClosedCount());
data.setAttribute("projectRawLine", index, "prl_unassignedClosedIssueCount", "class", AgirStatoolUtils.selectUnassignedIndicator(project.issueStats().getUnassignedClosedCount()));
data.setContent("projectRawLine", index, "prl_lastUpdate", AgirStatoolUtils.toHumanShort(project.issueStats().getLastUpdate(), "n/a"));
data.setAttribute("projectRawLine", index, "prl_lastUpdate", "title", AgirStatoolUtils.toHumanLong(project.issueStats().getLastUpdate(), "n/a"));
}
}

View file

@ -18,9 +18,6 @@ table
font-size: 0.8em; font-size: 0.8em;
} }
/**************** GENERAL SETTINGS ****************/ /**************** GENERAL SETTINGS ****************/
* *
@ -176,6 +173,11 @@ h3 span
background-color: #dff0d8; background-color: #dff0d8;
} }
.background_yellow
{
background-color: #fffbbb;
}
.background_orange .background_orange
{ {
background-color: #FFCBA4; background-color: #FFCBA4;
@ -187,6 +189,22 @@ h3 span
} }
.caution
{
background-color: #fffbbb;
}
.warning
{
background-color: #f58e1c;
}
.alert,
.redalert
{
background-color: red;
}
/***** GENERIC COLUMNS *****/ /***** GENERIC COLUMNS *****/
.row .row
@ -230,6 +248,71 @@ a.button:hover
background-color:#5f5d63; background-color:#5f5d63;
} }
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
/***** GENERIC TABLES *****/ /***** GENERIC TABLES *****/
table a table a
@ -308,6 +391,24 @@ table > tfoot > tr > th.success
background-color: #dff0d8; background-color: #dff0d8;
} }
table > thead > tr.caution > td,
table > thead > tr.caution > th,
table > thead > tr > td.caution,
table > thead > tr > th.caution,
table > tbody > tr.caution > td,
table > tbody > tr.caution > th,
table > tbody > tr > td.caution,
table > tr > td.caution,
table > tbody > tr > th.caution,
table > tr > th.caution,
table > tfoot > tr.caution > td,
table > tfoot > tr.caution > th,
table > tfoot > tr > td.caution,
table > tfoot > tr > th.caution
{
background-color: #fffbbb;
}
table > thead > tr.warning > td, table > thead > tr.warning > td,
table > thead > tr.warning > th, table > thead > tr.warning > th,
table > thead > tr > td.warning, table > thead > tr > td.warning,
@ -323,7 +424,7 @@ table > tfoot > tr.warning > th,
table > tfoot > tr > td.warning, table > tfoot > tr > td.warning,
table > tfoot > tr > th.warning table > tfoot > tr > th.warning
{ {
background-color: #faf5e3; background-color: ##f58e1c;
} }
table > thead > tr.alert > td, table > thead > tr.alert > td,
@ -341,7 +442,7 @@ table > tfoot > tr.alert > th,
table > tfoot > tr > td.alert, table > tfoot > tr > td.alert,
table > tfoot > tr > th.alert table > tfoot > tr > th.alert
{ {
background-color: #ffcba4; background-color: red;
} }
table > thead > tr.danger > td, table > thead > tr.danger > td,

View file

@ -8,73 +8,96 @@
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="agirstatool.css" /> <link rel="stylesheet" type="text/css" href="agirstatool.css" />
<script src="/commons/sorttable.js" /> <script src="/commons/sorttable.js" />
<script src="Chart.bundle.min.js"></script>
</head> </head>
<body> <body>
<div style="margin: 10px;"> <div style="margin: 10px;">
<h1>Agir Statool</h1> <h1><a href="index.xhtml">Agir Statool</a> Project <span id="projectName">n/a</span></h1>
<div style="width: 400px; height: 200px; text-align: center; margin: 0 0; border: 1px solid red;">
<h2>Project <span id="projectTitle">n/a</span></h2> <canvas id="myChart" width="100%" height="100%"></canvas>
<script>
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['New', 'Started', 'Waiting', 'Maybe', 'Resolved', 'Closed'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options:
{
maintainAspectRatio: false,
scales:
{
xAxes:
[{
ticks:
{
beginAtZero: true
}
}],
yAxes:
[{
ticks:
{
beginAtZero: true
}
}]
}
}
});
</script>
</div>
<br/>
<div> <div>
<span class="italic">Raw stats</span> <a href="index2.xhtml">Grouped stats</a> <div style="margin: 4px;">
<span style="display: inline-block; padding-top: 6px; vertical-align: text-top;">Grouped</span>
<label class="switch">
<input type="checkbox" onclick="javascript:projectsViewFlip();" />
<span class="slider round"></span>
</label>
</div>
<div id="projectsRawView">RAW VIEW PLACE</div>
<div id="projectsGroupedView" style="display: none;" >GROUPED VIEW PLACE</div>
</div> </div>
<hr />
<table class="table_classic">
<tr>
<th rowspan="2">ID</th>
<th rowspan="2">Name</th>
<th rowspan="2">Child</th>
<th colspan="9">Issues count</th>
<th colspan="9">Unassigned issues count</th>
</tr>
<tr>
<th class="tablesubtitle">Total</th>
<th class="tablesubtitle">New</th>
<th class="tablesubtitle">Confirmed</th>
<th class="tablesubtitle">Ongoing</th>
<th class="tablesubtitle">Waiting</th>
<th class="tablesubtitle">Maybe</th>
<th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Rejected</th>
<th class="tablesubtitle">Closed</th>
<th class="tablesubtitle">Total</th>
<th class="tablesubtitle">New</th>
<th class="tablesubtitle">Confirmed</th>
<th class="tablesubtitle">Ongoing</th>
<th class="tablesubtitle">Waiting</th>
<th class="tablesubtitle">Maybe</th>
<th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Rejected</th>
<th class="tablesubtitle">Closed</th>
</tr>
<tr id="projectLine">
<td id="projectId" class="center">n/a</td>
<td id="projectName"><a href="#" id="projectNameLink">foo</a></td>
<td id="childCount" class="td_number">n/a</td>
<td id="issueCount" class="td_number">n/a</td>
<td id="newIssueCount" class="td_number">n/a</td>
<td id="confirmedIssueCount" class="td_number">n/a</td>
<td id="ongoingIssueCount" class="td_number">n/a</td>
<td id="waitingIssueCount" class="td_number">n/a</td>
<td id="maybeIssueCount" class="td_number">n/a</td>
<td id="resolvedIssueCount" class="td_number">n/a</td>
<td id="rejectedIssueCount" class="td_number">n/a</td>
<td id="closedIssueCount" class="td_number">n/a</td>
<td id="unassignedIssueCount" class="td_number">n/a</td>
<td id="unassignedNewIssueCount" class="td_number">n/a</td>
<td id="unassignedConfirmedIssueCount" class="td_number">n/a</td>
<td id="unassignedOngoingIssueCount" class="td_number">n/a</td>
<td id="unassignedWaitingIssueCount" class="td_number">n/a</td>
<td id="unassignedMaybeIssueCount" class="td_number">n/a</td>
<td id="unassignedResolvedIssueCount" class="td_number">n/a</td>
<td id="unassignedRejectedIssueCount" class="td_number">n/a</td>
<td id="unassignedClosedIssueCount" class="td_number">n/a</td>
</tr>
</table>
</div> </div>
<script type="text/javascript">
var showRawView = true;
function projectsViewFlip ()
{
if (showRawView == true)
{
document.getElementById ('projectsRawView').style.display = 'none';
document.getElementById ('projectsGroupedView').style.display = 'inline';
showRawView = false;
}
else
{
document.getElementById ('projectsRawView').style.display = 'block';
document.getElementById ('projectsGroupedView').style.display = 'none';
showRawView = true;
}
}
</script>
</body> </body>
</html> </html>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Agir Statool</title>
<meta charset="UTF-8" />
<meta content="April" name="keywords" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="agirstatool.css" />
<script src="/commons/sorttable.js" />
</head>
<body>
<div style="margin: 10px;">
<h1><a href="index.xhtml">Agir Statool</a> Project list</h1>
<div>
<a href="index.xhtml">Raw stats</a> <span class="italic">Grouped stats</span>
</div>
<div id="projectsView">VIEW PLACE</div>
</div>
</body>
</html>

View file

@ -10,14 +10,6 @@
<script src="/commons/sorttable.js" /> <script src="/commons/sorttable.js" />
</head> </head>
<body> <body>
<div style="margin: 10px;">
<h1>Agir Statool</h1>
<h2>Project list</h2>
<div>
<a href="index.xhtml">Raw stats</a> <span class="italic">Grouped stats</span>
</div>
<table class="table_classic"> <table class="table_classic">
<tr> <tr>
<th rowspan="2">ID</th> <th rowspan="2">ID</th>
@ -39,26 +31,25 @@
<th class="tablesubtitle">Resolved</th> <th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Concluded</th> <th class="tablesubtitle">Concluded</th>
</tr> </tr>
<tr id="projectLine"> <tr id="projectGroupedLine">
<td id="projectId" class="center">n/a</td> <td id="pgl_projectId" class="center">n/a</td>
<td id="projectName"><a href="#" id="projectNameLink">foo</a></td> <td id="pgl_projectName"><a href="#" id="pgl_projectNameLink">foo</a></td>
<td id="childCount" class="td_number">n/a</td> <td id="pgl_childCount" class="td_number">n/a</td>
<td id="issueCount" class="td_number">n/a</td> <td id="pgl_issueCount" class="td_number">n/a</td>
<td id="activeIssueCount" class="td_number">n/a</td> <td id="pgl_activeIssueCount" class="td_number">n/a</td>
<td id="maybeIssueCount" class="td_number">n/a</td> <td id="pgl_maybeIssueCount" class="td_number">n/a</td>
<td id="resolvedIssueCount" class="td_number">n/a</td> <td id="pgl_resolvedIssueCount" class="td_number">n/a</td>
<td id="concludedIssueCount" class="td_number">n/a</td> <td id="pgl_concludedIssueCount" class="td_number">n/a</td>
<td id="unassignedIssueCount" class="td_number">n/a</td> <td id="pgl_unassignedIssueCount" class="td_number">n/a</td>
<td id="unassignedNewIssueCount" class="td_number">n/a</td> <td id="pgl_unassignedNewIssueCount" class="td_number">n/a</td>
<td id="unassignedStartedIssueCount" class="td_number">n/a</td> <td id="pgl_unassignedStartedIssueCount" class="td_number">n/a</td>
<td id="unassignedResolvedIssueCount" class="td_number">n/a</td> <td id="pgl_unassignedResolvedIssueCount" class="td_number">n/a</td>
<td id="unassignedConcludedIssueCount" class="td_number">n/a</td> <td id="pgl_unassignedConcludedIssueCount" class="td_number">n/a</td>
<td id="lastUpdate" class="center">n/a</td> <td id="pgl_lastUpdate" class="center">n/a</td>
</tr> </tr>
</table> </table>
</div>
</body> </body>
</html> </html>

View file

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Agir Statool</title>
<meta charset="UTF-8" />
<meta content="April" name="keywords" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="agirstatool.css" />
<script src="/commons/sorttable.js" />
</head>
<body>
<div style="margin: 10px;">
<h1>Agir Statool</h1>
<h2>Project list</h2>
<div>
<span class="italic">Raw stats</span> <a href="index2.xhtml">Grouped stats</a>
</div>
<table class="table_classic">
<tr>
<th rowspan="2">ID</th>
<th rowspan="2">Name</th>
<th rowspan="2">Child</th>
<th colspan="9">Issues count</th>
<th colspan="9">Unassigned issues count</th>
<th rowspan="2">Last<br/>update</th>
</tr>
<tr>
<th class="tablesubtitle">Total</th>
<th class="tablesubtitle">New</th>
<th class="tablesubtitle">Confirmed</th>
<th class="tablesubtitle">Ongoing</th>
<th class="tablesubtitle">Waiting</th>
<th class="tablesubtitle">Maybe</th>
<th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Rejected</th>
<th class="tablesubtitle">Closed</th>
<th class="tablesubtitle">Total</th>
<th class="tablesubtitle">New</th>
<th class="tablesubtitle">Confirmed</th>
<th class="tablesubtitle">Ongoing</th>
<th class="tablesubtitle">Waiting</th>
<th class="tablesubtitle">Maybe</th>
<th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Rejected</th>
<th class="tablesubtitle">Closed</th>
</tr>
<tr id="projectLine">
<td id="projectId" class="center">n/a</td>
<td id="projectName"><a href="#" id="projectNameLink">foo</a></td>
<td id="childCount" class="td_number">n/a</td>
<td id="issueCount" class="td_number">n/a</td>
<td id="newIssueCount" class="td_number">n/a</td>
<td id="confirmedIssueCount" class="td_number">n/a</td>
<td id="ongoingIssueCount" class="td_number">n/a</td>
<td id="waitingIssueCount" class="td_number">n/a</td>
<td id="maybeIssueCount" class="td_number">n/a</td>
<td id="resolvedIssueCount" class="td_number">n/a</td>
<td id="rejectedIssueCount" class="td_number">n/a</td>
<td id="closedIssueCount" class="td_number">n/a</td>
<td id="unassignedIssueCount" class="td_number">n/a</td>
<td id="unassignedNewIssueCount" class="td_number">n/a</td>
<td id="unassignedConfirmedIssueCount" class="td_number">n/a</td>
<td id="unassignedOngoingIssueCount" class="td_number">n/a</td>
<td id="unassignedWaitingIssueCount" class="td_number">n/a</td>
<td id="unassignedMaybeIssueCount" class="td_number">n/a</td>
<td id="unassignedResolvedIssueCount" class="td_number">n/a</td>
<td id="unassignedRejectedIssueCount" class="td_number">n/a</td>
<td id="unassignedClosedIssueCount" class="td_number">n/a</td>
<td id="lastUpdate" class="center">n/a</td>
</tr>
</table>
</div>
</body>
</html>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Agir Statool</title>
<meta charset="UTF-8" />
<meta content="April" name="keywords" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="agirstatool.css" />
<script src="/commons/sorttable.js" />
</head>
<body>
<div style="margin: 10px;">
<h1><a href="index.xhtml">Agir Statool</a> Project list</h1>
<div>
<span class="italic">Raw stats</span> <a href="index2.xhtml">Grouped stats</a>
</div>
<div id="projectsView">VIEW PLACE</div>
</div>
</body>
</html>

View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Agir Statool</title>
<meta charset="UTF-8" />
<meta content="April" name="keywords" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="agirstatool.css" />
<script src="/commons/sorttable.js" />
</head>
<body>
<table class="table_classic">
<tr>
<th rowspan="2">ID</th>
<th rowspan="2">Name</th>
<th rowspan="2">Child</th>
<th colspan="9">Issues count</th>
<th colspan="9">Unassigned issues count</th>
<th rowspan="2">Last<br/>update</th>
</tr>
<tr>
<th class="tablesubtitle">Total</th>
<th class="tablesubtitle">New</th>
<th class="tablesubtitle">Confirmed</th>
<th class="tablesubtitle">Ongoing</th>
<th class="tablesubtitle">Waiting</th>
<th class="tablesubtitle">Maybe</th>
<th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Rejected</th>
<th class="tablesubtitle">Closed</th>
<th class="tablesubtitle">Total</th>
<th class="tablesubtitle">New</th>
<th class="tablesubtitle">Confirmed</th>
<th class="tablesubtitle">Ongoing</th>
<th class="tablesubtitle">Waiting</th>
<th class="tablesubtitle">Maybe</th>
<th class="tablesubtitle">Resolved</th>
<th class="tablesubtitle">Rejected</th>
<th class="tablesubtitle">Closed</th>
</tr>
<tr id="projectRawLine">
<td id="prl_projectId" class="center">n/a</td>
<td id="prl_projectName"><a href="#" id="prl_projectNameLink">foo</a></td>
<td id="prl_childCount" class="td_number">n/a</td>
<td id="prl_issueCount" class="td_number">n/a</td>
<td id="prl_newIssueCount" class="td_number">n/a</td>
<td id="prl_confirmedIssueCount" class="td_number">n/a</td>
<td id="prl_ongoingIssueCount" class="td_number">n/a</td>
<td id="prl_waitingIssueCount" class="td_number">n/a</td>
<td id="prl_maybeIssueCount" class="td_number">n/a</td>
<td id="prl_resolvedIssueCount" class="td_number">n/a</td>
<td id="prl_rejectedIssueCount" class="td_number">n/a</td>
<td id="prl_closedIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedNewIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedConfirmedIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedOngoingIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedWaitingIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedMaybeIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedResolvedIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedRejectedIssueCount" class="td_number">n/a</td>
<td id="prl_unassignedClosedIssueCount" class="td_number">n/a</td>
<td id="prl_lastUpdate" class="center">n/a</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Redirection</title>
<meta charset="UTF-8" />
<meta http-equiv="Refresh" content="0;URL=/project-all.xhtml">
</head>
<body>
</body>
</html>