From 5cee038743e1e149226d5b0b1a68a782182a4e33 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 24 Dec 2018 23:05:35 +0300 Subject: Add filter to Build Configurations page --- mod/build-config-module.cxx | 26 +++++++++++ mod/build-config-module.hxx | 12 ++--- mod/mod-build-configs.cxx | 110 +++++++++++++++++++++++++++++++++++--------- mod/options.cli | 5 ++ www/build-configs-body.css | 19 +++++++- 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& 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 +#include // replace() + #include #include @@ -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& 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. */ -- cgit v1.1