Make filters really work

This commit is contained in:
emeric
2018-02-05 13:39:45 +01:00
parent 1e470a34b1
commit cea01d06b7
14 changed files with 187 additions and 18 deletions
+5
View File
@@ -10,4 +10,9 @@
<message id="msg-filter-add">Add filter</message> <message id="msg-filter-add">Add filter</message>
<message id="msg-search-placeholder">Search...</message> <message id="msg-search-placeholder">Search...</message>
<message id="msg-add">Add</message>
<message id="msg-cancel">Cancel</message>
<message id="msg-filter-type">Type</message>
<message id="msg-filter-value">Value</message>
</messages> </messages>
+26
View File
@@ -22,4 +22,30 @@
</div> </div>
</message> </message>
<message id="template-filter-add">
<div class="form-horizontal">
<div class="form-group">
<label class="control-label col-sm-2" for="${id:type}">
${tr:msg-filter-type}
</label>
<div class="col-sm-10">
${type}
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="${id:value}">
${tr:msg-filter-value}
</label>
<div class="col-sm-10">
${value}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
${add class="btn-primary"} ${cancel}
</div>
</div>
</div>
</message>
</messages> </messages>
+3 -3
View File
@@ -91,7 +91,7 @@ Artist::getAllOrphans(Wt::Dbo::Session& session)
static static
Wt::Dbo::Query<Artist::pointer> Wt::Dbo::Query<Artist::pointer>
getQuery(Wt::Dbo::Session& session, getQuery(Wt::Dbo::Session& session,
const std::vector<id_type>& clusterIds, const std::set<id_type>& clusterIds,
const std::vector<std::string>& keywords) const std::vector<std::string>& keywords)
{ {
WhereClause where; WhereClause where;
@@ -132,7 +132,7 @@ getQuery(Wt::Dbo::Session& session,
std::vector<Artist::pointer> std::vector<Artist::pointer>
Artist::getByFilter(Wt::Dbo::Session& session, Artist::getByFilter(Wt::Dbo::Session& session,
const std::vector<id_type>& clusters, const std::set<id_type>& clusters,
const std::vector<std::string> keywords, const std::vector<std::string> keywords,
int offset, int size, bool& moreResults) int offset, int size, bool& moreResults)
{ {
@@ -152,7 +152,7 @@ Artist::getByFilter(Wt::Dbo::Session& session,
} }
std::vector<Wt::Dbo::ptr<Release> > std::vector<Wt::Dbo::ptr<Release> >
Artist::getReleases(const std::vector<id_type>& clusterIds) const Artist::getReleases(const std::set<id_type>& clusterIds) const
{ {
assert(self()); assert(self());
assert(self()->id() != Wt::Dbo::dbo_traits<Artist>::invalidId() ); assert(self()->id() != Wt::Dbo::dbo_traits<Artist>::invalidId() );
+2 -2
View File
@@ -51,7 +51,7 @@ class Artist : public Wt::Dbo::Dbo<Artist>
static pointer getNone(Wt::Dbo::Session& session); // Special entry static pointer getNone(Wt::Dbo::Session& session); // Special entry
static std::vector<pointer> getByName(Wt::Dbo::Session& session, const std::string& name); static std::vector<pointer> getByName(Wt::Dbo::Session& session, const std::string& name);
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, static std::vector<pointer> getByFilter(Wt::Dbo::Session& session,
const std::vector<id_type>& clusters, // at least one track that belongs to these clusters const std::set<id_type>& clusters, // at least one track that belongs to these clusters
const std::vector<std::string> keywords, // name must match all of these keywords const std::vector<std::string> keywords, // name must match all of these keywords
int offset, int offset,
int size, int size,
@@ -65,7 +65,7 @@ class Artist : public Wt::Dbo::Dbo<Artist>
std::string getMBID(void) const { return _MBID; } std::string getMBID(void) const { return _MBID; }
// Get the releases that have at least one track for this artist + belongs to optonal cluster filters // Get the releases that have at least one track for this artist + belongs to optonal cluster filters
std::vector<Wt::Dbo::ptr<Release>> getReleases(const std::vector<id_type>& clusterIds = std::vector<id_type>()) const; std::vector<Wt::Dbo::ptr<Release>> getReleases(const std::set<id_type>& clusterIds = std::set<id_type>()) const;
void setMBID(std::string mbid) { _MBID = mbid; } void setMBID(std::string mbid) { _MBID = mbid; }
+3 -3
View File
@@ -90,7 +90,7 @@ Release::getAllOrphans(Wt::Dbo::Session& session)
static static
Wt::Dbo::Query<Release::pointer> Wt::Dbo::Query<Release::pointer>
getQuery(Wt::Dbo::Session& session, getQuery(Wt::Dbo::Session& session,
const std::vector<id_type>& clusterIds, const std::set<id_type>& clusterIds,
const std::vector<std::string> keywords) const std::vector<std::string> keywords)
{ {
WhereClause where; WhereClause where;
@@ -130,7 +130,7 @@ getQuery(Wt::Dbo::Session& session,
std::vector<Release::pointer> std::vector<Release::pointer>
Release::getByFilter(Wt::Dbo::Session& session, Release::getByFilter(Wt::Dbo::Session& session,
const std::vector<id_type>& clusterIds, const std::set<id_type>& clusterIds,
const std::vector<std::string> keywords, const std::vector<std::string> keywords,
int offset, int size, bool& moreResults) int offset, int size, bool& moreResults)
{ {
@@ -195,7 +195,7 @@ Release::hasVariousArtists() const
} }
std::vector<Wt::Dbo::ptr<Track>> std::vector<Wt::Dbo::ptr<Track>>
Release::getTracks(const std::vector<id_type>& clusterIds) const Release::getTracks(const std::set<id_type>& clusterIds) const
{ {
assert(self()); assert(self());
assert(self()->id() != Wt::Dbo::dbo_traits<Release>::invalidId() ); assert(self()->id() != Wt::Dbo::dbo_traits<Release>::invalidId() );
+2 -2
View File
@@ -51,13 +51,13 @@ class Release : public Wt::Dbo::Dbo<Release>
static std::vector<pointer> getAll(Wt::Dbo::Session& session, int offset, int size); static std::vector<pointer> getAll(Wt::Dbo::Session& session, int offset, int size);
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, static std::vector<pointer> getByFilter(Wt::Dbo::Session& session,
const std::vector<id_type>& clusters, // at least one track that belongs to these clusters const std::set<id_type>& clusters, // at least one track that belongs to these clusters
const std::vector<std::string> keywords, // name must match all of these keywords const std::vector<std::string> keywords, // name must match all of these keywords
int offset, int offset,
int size, int size,
bool& moreExpected); bool& moreExpected);
std::vector<Wt::Dbo::ptr<Track>> getTracks(const std::vector<id_type>& clusters = std::vector<id_type>()) const; std::vector<Wt::Dbo::ptr<Track>> getTracks(const std::set<id_type>& clusters = std::set<id_type>()) const;
// Create // Create
static pointer create(Wt::Dbo::Session& session, const std::string& name, const std::string& MBID = ""); static pointer create(Wt::Dbo::Session& session, const std::string& name, const std::string& MBID = "");
+11 -2
View File
@@ -111,7 +111,7 @@ Track::getClusters(void) const
static static
Wt::Dbo::Query< Track::pointer > Wt::Dbo::Query< Track::pointer >
getQuery(Wt::Dbo::Session& session, getQuery(Wt::Dbo::Session& session,
const std::vector<id_type>& clusterIds, const std::set<id_type>& clusterIds,
const std::vector<std::string> keywords) const std::vector<std::string> keywords)
{ {
WhereClause where; WhereClause where;
@@ -165,7 +165,7 @@ Track::getStats(Wt::Dbo::Session& session, SearchFilter filter)
std::vector<Track::pointer> std::vector<Track::pointer>
Track::getByFilter(Wt::Dbo::Session& session, Track::getByFilter(Wt::Dbo::Session& session,
const std::vector<id_type>& clusterIds, const std::set<id_type>& clusterIds,
const std::vector<std::string> keywords, const std::vector<std::string> keywords,
int offset, int size, bool& moreResults) int offset, int size, bool& moreResults)
{ {
@@ -282,6 +282,15 @@ Cluster::getQuery(Wt::Dbo::Session& session, SearchFilter filter)
return query; return query;
} }
std::vector<std::string>
Cluster::getAllTypes(Wt::Dbo::Session& session)
{
Wt::Dbo::collection<std::string> res
= session.query<std::string>("SELECT type from cluster").groupBy("type").orderBy("type");
return std::vector<std::string>(res.begin(), res.end());
}
std::vector<Cluster::pointer> std::vector<Cluster::pointer>
Cluster::getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size) Cluster::getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size)
{ {
+2 -1
View File
@@ -62,6 +62,7 @@ class Cluster
static pointer getNone(Wt::Dbo::Session& session); static pointer getNone(Wt::Dbo::Session& session);
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1);
static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session); static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session);
static std::vector<std::string> getAllTypes(Wt::Dbo::Session& session);
static std::vector<pointer> getByType(Wt::Dbo::Session& session, std::string type); static std::vector<pointer> getByType(Wt::Dbo::Session& session, std::string type);
// Create utility // Create utility
@@ -120,7 +121,7 @@ class Track
static pointer getById(Wt::Dbo::Session& session, id_type id); static pointer getById(Wt::Dbo::Session& session, id_type id);
static pointer getByMBID(Wt::Dbo::Session& session, const std::string& MBID); static pointer getByMBID(Wt::Dbo::Session& session, const std::string& MBID);
static std::vector<pointer> getByFilter(Wt::Dbo::Session& session, static std::vector<pointer> getByFilter(Wt::Dbo::Session& session,
const std::vector<id_type>& clusters, // tracks that belong to these clusters const std::set<id_type>& clusters, // tracks that belong to these clusters
const std::vector<std::string> keywords, // name must match all of these keywords const std::vector<std::string> keywords, // name must match all of these keywords
int offset, int offset,
int size, int size,
+4
View File
@@ -43,6 +43,10 @@ Artist::Artist(Filters* filters, Wt::WContainerWidget* parent)
})); }));
refresh(); refresh();
filters->updated().connect(std::bind([=] {
refresh();
}));
} }
void void
+4 -1
View File
@@ -54,8 +54,11 @@ Artists::Artists(Filters* filters, Wt::WContainerWidget* parent)
artists->bindWidget("artists", _artistsContainer); artists->bindWidget("artists", _artistsContainer);
refresh(); refresh();
}
filters->updated().connect(std::bind([=] {
refresh();
}));
}
void void
Artists::refresh(std::vector<std::string> searchKeywords) Artists::refresh(std::vector<std::string> searchKeywords)
+109 -2
View File
@@ -17,13 +17,116 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>. * along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <Wt/WTemplate> #include <Wt/WComboBox>
#include <Wt/WDialog>
#include <Wt/WPushButton> #include <Wt/WPushButton>
#include <Wt/WTemplate>
#include "Filters.hpp" #include "Filters.hpp"
#include "LmsApplication.hpp"
namespace UserInterface { namespace UserInterface {
void
Filters::showDialog()
{
auto dialog = new Wt::WDialog("Go to cell");
auto container = new Wt::WTemplate(Wt::WString::tr("template-filter-add"));
container->addFunction("tr", &Wt::WTemplate::Functions::tr);
dialog->contents()->addWidget(container);
auto typeCombo = new Wt::WComboBox();
container->bindWidget("type", typeCombo);
auto valueCombo = new Wt::WComboBox();
container->bindWidget("value", valueCombo);
auto addBtn = new Wt::WPushButton(Wt::WString::tr("msg-add"));
container->bindWidget("add", addBtn);
addBtn->clicked().connect(dialog, &Wt::WDialog::accept);
auto cancelBtn = new Wt::WPushButton(Wt::WString::tr("msg-cancel"));
container->bindWidget("cancel", cancelBtn);
cancelBtn->clicked().connect(dialog, &Wt::WDialog::reject);
// Populate data
{
Wt::Dbo::Transaction transaction(DboSession());
auto types = Database::Cluster::getAllTypes(DboSession());
for (auto type : types)
typeCombo->addItem(Wt::WString::fromUTF8(type));
if (!types.empty())
{
auto values = Database::Cluster::getByType(DboSession(), types.front());
for (auto value : values)
{
if (_filterIds.find(value.id()) == _filterIds.end())
valueCombo->addItem(Wt::WString::fromUTF8(value->getName()));
}
}
}
typeCombo->changed().connect(std::bind([=]
{
auto type = typeCombo->valueText().toUTF8();
valueCombo->clear();
Wt::Dbo::Transaction transaction(DboSession());
auto values = Database::Cluster::getByType(DboSession(), type);
for (auto value : values)
{
if (_filterIds.find(value.id()) == _filterIds.end())
valueCombo->addItem(Wt::WString::fromUTF8(value->getName()));
}
}));
dialog->setModal(true);
dialog->setMovable(false);
dialog->setResizable(false);
dialog->setClosable(false);
dialog->finished().connect(std::bind([=]
{
if (dialog->result() != Wt::WDialog::Accepted)
return;
auto type = typeCombo->valueText().toUTF8();
auto value = valueCombo->valueText().toUTF8();
Wt::Dbo::Transaction transaction(DboSession());
auto cluster = Database::Cluster::get(DboSession(), type, value);
if (!cluster)
return;
auto clusterId = cluster.id();
_filterIds.insert(clusterId);
_sigUpdated.emit();
auto filterBtn = new Wt::WPushButton(Wt::WString::fromUTF8(value));
_filters->addWidget(filterBtn);
filterBtn->clicked().connect(std::bind([=]
{
_filters->removeWidget(filterBtn);
_filterIds.erase(clusterId);
_sigUpdated.emit();
}));
}));
dialog->show();
}
Filters::Filters(Wt::WContainerWidget *parent) Filters::Filters(Wt::WContainerWidget *parent)
: Wt::WContainerWidget(parent) : Wt::WContainerWidget(parent)
{ {
@@ -36,7 +139,11 @@ Filters::Filters(Wt::WContainerWidget *parent)
_filters = new Wt::WContainerWidget(); _filters = new Wt::WContainerWidget();
container->bindWidget("filters", _filters); container->bindWidget("filters", _filters);
// _filterIds = {108, 419}; addFilterBtn->clicked().connect(std::bind([this]
{
showDialog();
}));
} }
+8 -2
View File
@@ -20,6 +20,7 @@
#pragma once #pragma once
#include <Wt/WContainerWidget> #include <Wt/WContainerWidget>
#include <Wt/WSignal>
#include "database/Types.hpp" #include "database/Types.hpp"
@@ -32,12 +33,17 @@ class Filters : public Wt::WContainerWidget
public: public:
Filters(Wt::WContainerWidget *parent = 0); Filters(Wt::WContainerWidget *parent = 0);
std::vector<Database::Cluster::id_type> getClusterIds() const { return _filterIds; } std::set<Database::Cluster::id_type> getClusterIds() const { return _filterIds; }
Wt::Signal<void>& updated() { return _sigUpdated; }
private: private:
void showDialog();
Wt::WContainerWidget *_filters; Wt::WContainerWidget *_filters;
std::vector<Database::Cluster::id_type> _filterIds; Wt::Signal<void> _sigUpdated;
std::set<Database::Cluster::id_type> _filterIds;
}; };
} // namespace UserInterface } // namespace UserInterface
+4
View File
@@ -56,6 +56,10 @@ Releases::Releases(Filters* filters, Wt::WContainerWidget* parent)
releases->bindWidget("releases", _releasesContainer); releases->bindWidget("releases", _releasesContainer);
refresh(); refresh();
filters->updated().connect(std::bind([=] {
refresh();
}));
} }
+4
View File
@@ -55,6 +55,10 @@ Tracks::Tracks(Filters* filters, Wt::WContainerWidget* parent)
tracks->bindWidget("tracks", _tracksContainer); tracks->bindWidget("tracks", _tracksContainer);
refresh(); refresh();
filters->updated().connect(std::bind([=] {
refresh();
}));
} }