aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-12-24 23:05:35 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-01-10 13:35:28 +0300
commit5cee038743e1e149226d5b0b1a68a782182a4e33 (patch)
treed9d4d96074c67184c6cbf1bfbb398af88067b2c9
parent080c6778e89029560a6daf00605ec212ef9f39ee (diff)
Add filter to Build Configurations page
-rw-r--r--mod/build-config-module.cxx26
-rw-r--r--mod/build-config-module.hxx12
-rw-r--r--mod/mod-build-configs.cxx110
-rw-r--r--mod/options.cli5
-rw-r--r--www/build-configs-body.css19
5 files changed, 142 insertions, 30 deletions
diff --git a/mod/build-config-module.cxx b/mod/build-config-module.cxx
index 57c035f..b6b5072 100644
--- a/mod/build-config-module.cxx
+++ b/mod/build-config-module.cxx
@@ -335,6 +335,32 @@ namespace brep
return false;
}
+ bool build_config_module::
+ belongs (const bbot::build_config& cfg, const char* cls) const
+ {
+ const map<string, string>& im (build_conf_->class_inheritance_map);
+
+ for (const string& c: cfg.classes)
+ {
+ if (c == cls)
+ return true;
+
+ // Go through base classes.
+ //
+ for (auto i (im.find (c)); i != im.end (); )
+ {
+ const string& base (i->second);
+
+ if (base == cls)
+ return true;
+
+ i = im.find (base);
+ }
+ }
+
+ return false;
+ }
+
path build_config_module::
dash_components_to_path (const string& s)
{
diff --git a/mod/build-config-module.hxx b/mod/build-config-module.hxx
index bd6e0b0..97cfe28 100644
--- a/mod/build-config-module.hxx
+++ b/mod/build-config-module.hxx
@@ -54,13 +54,13 @@ namespace brep
// Check if the configuration belongs to the specified class.
//
- // Note that the configuration base classes are not checked.
- //
- static bool
- belongs (const bbot::build_config& cfg, const char* cls)
+ bool
+ belongs (const bbot::build_config&, const char*) const;
+
+ bool
+ belongs (const bbot::build_config& cfg, const string& cls) const
{
- const strings& cs (cfg.classes);
- return std::find (cs.begin (), cs.end (), cls) != cs.end ();
+ return belongs (cfg, cls.c_str ());
}
// Convert dash-separated components (target, build configuration name,
diff --git a/mod/mod-build-configs.cxx b/mod/mod-build-configs.cxx
index 826bb87..d1cf520 100644
--- a/mod/mod-build-configs.cxx
+++ b/mod/mod-build-configs.cxx
@@ -4,6 +4,8 @@
#include <mod/mod-build-configs.hxx>
+#include <algorithm> // replace()
+
#include <libstudxml/serializer.hxx>
#include <web/xhtml.hxx>
@@ -59,6 +61,14 @@ handle (request& rq, response& rs)
{
name_value_scanner s (rq.parameters (1024));
params = params::build_configs (s, unknown_mode::fail, unknown_mode::fail);
+
+ // We accept the non-url-encoded class name. Note that the parameter is
+ // already url-decoded by the web server, so we just restore the space
+ // character (that is otherwise forbidden in a class name) to the plus
+ // character.
+ //
+ string& cn (params.class_name ());
+ replace (cn.begin (), cn.end (), ' ', '+');
}
catch (const cli::exception& e)
{
@@ -79,7 +89,65 @@ handle (request& rq, response& rs)
<< DIV_HEADER (options_->logo (), options_->menu (), root, tenant)
<< DIV(ID="content");
- // Print build configurations that belong to the 'all' class.
+ auto url = [&root] (const string& cls)
+ {
+ string r (root.string () + "?build-configs");
+
+ if (cls != "all")
+ {
+ r += '=';
+
+ // Note that '+' is the only class name character that potentially needs
+ // to be url-encoded, and only in the query part of the URL. However, we
+ // embed the class name into the URL query part, where it is not encoded
+ // by design (see above).
+ //
+ r += cls;
+ }
+
+ return r;
+ };
+
+ auto print_class_name = [&s, &url] (const string& c, bool sel = false)
+ {
+ if (sel)
+ s << SPAN(ID="selected-class", CLASS="class-name") << c << ~SPAN;
+ else
+ s << A(CLASS="class-name") << HREF << url (c) << ~HREF << c << ~A;
+ };
+
+ // Print the configuration filter on the first page only.
+ //
+ if (params.page () == 0)
+ {
+ const strings& cls (build_conf_->classes);
+ const map<string, string>& im (build_conf_->class_inheritance_map);
+
+ s << DIV(ID="filter-heading") << "Build Configuration Classes" << ~DIV
+ << P(ID="filter");
+
+ for (auto b (cls.begin ()), i (b), e (cls.end ()); i != e; ++i)
+ {
+ if (i != b)
+ s << ' ';
+
+ const string& c (*i);
+ print_class_name (c, c == params.class_name ());
+
+ // Append the base class, if present.
+ //
+ auto j (im.find (c));
+ if (j != im.end ())
+ {
+ s << ':';
+ print_class_name (j->second);
+ }
+ }
+
+ s << ~P;
+ }
+
+ // Print build configurations that belong to the selected class.
//
// We will calculate the total configuration count and cache configurations
// for printing (skipping an appropriate number of them for page number
@@ -94,7 +162,7 @@ handle (request& rq, response& rs)
size_t print (page_configs);
for (const build_config& c: *build_conf_)
{
- if (belongs (c, "all"))
+ if (belongs (c, params.class_name ()))
{
if (skip != 0)
--skip;
@@ -119,29 +187,27 @@ handle (request& rq, response& rs)
s << DIV;
for (const build_config* c: configs)
{
- string classes;
- for (const string& cls: c->classes)
- {
- if (!classes.empty ())
- classes += ' ';
-
- classes += cls;
-
- // Append the base class, if present.
- //
- auto i (build_conf_->class_inheritance_map.find (cls));
- if (i != build_conf_->class_inheritance_map.end ())
- {
- classes += ':';
- classes += i->second;
- }
- }
-
s << TABLE(CLASS="proplist config")
<< TBODY
<< TR_VALUE ("name", c->name)
<< TR_VALUE ("target", c->target.string ())
- << TR_VALUE ("classes", classes)
+ << TR(CLASS="classes")
+ << TH << "classes" << ~TH
+ << TD
+ << SPAN(CLASS="value");
+
+ const strings& cls (c->classes);
+ for (auto b (cls.begin ()), i (b), e (cls.end ()); i != e; ++i)
+ {
+ if (i != b)
+ s << ' ';
+
+ print_class_name (*i);
+ }
+
+ s << ~SPAN
+ << ~TD
+ << ~TR
<< ~TBODY
<< ~TABLE;
}
@@ -151,7 +217,7 @@ handle (request& rq, response& rs)
count,
page_configs,
options_->build_config_pages (),
- root.string () + "?build-configs")
+ url (params.class_name ()))
<< ~DIV
<< ~BODY
<< ~HTML;
diff --git a/mod/options.cli b/mod/options.cli
index 93f2ead..8191674 100644
--- a/mod/options.cli
+++ b/mod/options.cli
@@ -738,6 +738,11 @@ namespace brep
class build_configs
{
+ // Note that the build-configs parameter is renamed to '_' by the root
+ // handler (see the request_proxy class for details).
+ //
+ string class_name | _ = "all";
+
// Display build configurations list starting from this page.
//
uint16_t page | p;
diff --git a/www/build-configs-body.css b/www/build-configs-body.css
index 83bdf6e..af931bd 100644
--- a/www/build-configs-body.css
+++ b/www/build-configs-body.css
@@ -1,7 +1,12 @@
/*
- * Config count.
+ * Class name.
*/
-#count
+.class-name {white-space: nowrap;}
+
+/*
+ * Config filter and count.
+ */
+#filter-heading, #count
{
font-size: 1.32em;
line-height: 1.4em;
@@ -10,6 +15,16 @@
margin: 1.2em 0 0 0;
}
+#filter
+{
+ font-family: monospace;
+ font-size: 0.94em;
+
+ text-align: left;
+}
+
+#selected-class {font-weight: bold;}
+
/*
* Config table.
*/