From f071e5872475dfe950beb69d21b535bfc4384840 Mon Sep 17 00:00:00 2001 From: Eike Cochu <eike@cochu.com> Date: Fri, 10 Jun 2016 16:18:57 +0200 Subject: [PATCH] updated excerpt to details, fixed ellipsis, updated other things --- .../main/java/de/vipra/cmd/lda/Analyzer.java | 8 ++--- .../de/vipra/cmd/option/ImportCommand.java | 6 ++-- .../app/html/directives/article-link.html | 9 +++-- vipra-ui/app/html/index.html | 2 +- .../app/html/partials/topicmodel-popover.html | 30 ++++++++++++++++ vipra-ui/app/index.html | 15 +++++--- vipra-ui/app/js/app.js | 34 ++++++++++++++++++ vipra-ui/app/js/directives.js | 18 +++++----- vipra-ui/app/js/helpers.js | 3 +- vipra-ui/app/less/app.less | 23 +++++++++++- .../de/vipra/util/model/TopicModelFull.java | 36 ++++++++++++------- .../de/vipra/util/model/TopicModelState.java | 7 ++++ 12 files changed, 152 insertions(+), 39 deletions(-) create mode 100644 vipra-ui/app/html/partials/topicmodel-popover.html create mode 100644 vipra-util/src/main/java/de/vipra/util/model/TopicModelState.java diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java b/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java index 6bad2608..1e04b318 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java @@ -208,10 +208,10 @@ public class Analyzer { final List<SequenceFull> newSequences = new ArrayList<>(topicCount * windowCount); final List<TopicFull> newTopics = new ArrayList<>(topicCount); - topicModel.setWordCount(wordCount); - topicModel.setWindowCount(windowCount); - topicModel.setArticleCount(articleCount); - topicModel.setTopicCount(topicCount); + topicModel.setWordCount((long) wordCount); + topicModel.setWindowCount((long) windowCount); + topicModel.setArticleCount((long) articleCount); + topicModel.setTopicCount((long) topicCount); final boolean seqRelativeCutoff = modelConfig.getMinRelativeProbability() > 0; diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java index 0859d490..c3ca6cbe 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java @@ -300,8 +300,10 @@ public class ImportCommand implements Command { * update topic model */ topicModelFull.setWindows(filebase.getWindowIndex().getWindows()); - topicModelFull.setArticleCount(filebase.getIdDateIndex().size()); - topicModelFull.setWordCount(filebase.getWordIndex().size()); + topicModelFull.setArticleCount((long) filebase.getIdDateIndex().size()); + topicModelFull.setWordCount((long) filebase.getWordIndex().size()); + final long entityCount = dbEntities.count(QueryBuilder.builder().eq("topicModel", topicModel)); + topicModelFull.setEntityCount(entityCount); dbTopicModels.replaceSingle(topicModelFull); /* diff --git a/vipra-ui/app/html/directives/article-link.html b/vipra-ui/app/html/directives/article-link.html index ddd58cc3..1e7d04ab 100644 --- a/vipra-ui/app/html/directives/article-link.html +++ b/vipra-ui/app/html/directives/article-link.html @@ -1,7 +1,7 @@ <div class="link-wrapper"> <span class="menu-padding ellipsis"> <div class="pull-right article-dropdown"> - <i class="fa text-muted pointer" ng-class="{'fa-chevron-down':!excerptShown,'fa-chevron-up':excerptShown}" ng-click="toggleExcerpt()" ng-if="::showExcerpt" analytics-on analytics-event="Article excerpt" analytics-category="Article actions"></i> + <i class="fa text-muted pointer" ng-class="{'fa-chevron-down':!detailsShown,'fa-chevron-up':detailsShown}" ng-click="toggleDetails()" ng-if="::showDetails" analytics-on analytics-event="Article details" analytics-category="Article actions"></i> <span class="badge" ng-bind="::article.topicsCount" ng-attr-title="{{::article.topicsCount}} topic(s)" ng-if="::showBadge"></span> </div> <a class="article-link" ui-sref="articles.show({id:article.id})" ng-attr-title="{{::article.title}}"> @@ -10,5 +10,10 @@ </a> </span> <article-menu class="menu-button" article="article" ng-if="::showMenu" /> - <div ng-bind="excerpt" ng-if="excerptShown" class="excerpt"></div> + <div ng-if="detailsShown" class="details"> + <span ng-bind="::articleDetails.text"></span> + <div> + <a ui-sref="topics.show({id:topic.topic.id})" class="badge" ng-bind="::topic.topic.name" ng-attr-title="::topic.topic.name" ng-repeat="topic in articleDetails.topics"></a> + </div> + </div> </div> \ No newline at end of file diff --git a/vipra-ui/app/html/index.html b/vipra-ui/app/html/index.html index bae0a628..fac08c01 100644 --- a/vipra-ui/app/html/index.html +++ b/vipra-ui/app/html/index.html @@ -45,7 +45,7 @@ <div class="col-md-8 text-center"> <h4>Latest articles</h4> <ul class="list-unstyled"> - <article-link article="::article" badge="false" menu="false" excerpt="false" ng-repeat="article in latestArticles"/> + <article-link article="::article" badge="false" menu="false" details="false" ng-repeat="article in latestArticles"/> </ul> <p class="text-center" ng-if="!latestArticles">Loading...</p> <p class="text-center" ng-if="latestArticles&&!latestArticles.length">No Articles</p> diff --git a/vipra-ui/app/html/partials/topicmodel-popover.html b/vipra-ui/app/html/partials/topicmodel-popover.html new file mode 100644 index 00000000..ab7142f1 --- /dev/null +++ b/vipra-ui/app/html/partials/topicmodel-popover.html @@ -0,0 +1,30 @@ +<table class="td-padded"> + <tr> + <th>Articles</th> + <td ng-bind="::topicModel.articleCount"></td> + </tr> + <tr> + <th>Topics</th> + <td ng-bind="::topicModel.topicCount"></td> + </tr> + <tr> + <th>Words</th> + <td ng-bind="::topicModel.wordCount"></td> + </tr> + <tr> + <th>Entities</th> + <td ng-bind="::topicModel.entityCount"></td> + </tr> + <tr> + <th>Windows</th> + <td ng-bind="::topicModel.windowCount"></td> + </tr> + <tr> + <th>Last generated</th> + <td ng-bind-template="{{::Vipra.formatDateTime(topicModel.lastGenerated)}}"></td> + </tr> + <tr> + <th>Last indexed</th> + <td ng-bind-template="{{::Vipra.formatDateTime(topicModel.lastIndexed)}}"></td> + </tr> +</table> \ No newline at end of file diff --git a/vipra-ui/app/index.html b/vipra-ui/app/index.html index e8452361..4cbc1dc8 100644 --- a/vipra-ui/app/index.html +++ b/vipra-ui/app/index.html @@ -86,12 +86,17 @@ <div class="modal-body"> <ul class="list-group nomargin" ng-show="topicModels.length" ng-cloak> <button type="button" class="list-group-item topic-model" ng-repeat="topicModel in topicModels" ng-click="changeTopicModel(topicModel)" ng-class="{'active selected-model':rootModels.topicModel.id===topicModel.id}" analytics-on analytics-event="Topic model" analytics-category="Topic model actions"> - <span class="badge" ng-bind="topicModel.articleCount" ng-show="topicModel.articleCount" ng-attr-title="{{topicModel.articleCount + ' article(s)'}}" ng-cloak></span> - <span class="badge" ng-bind="topicModel.topicCount" ng-show="topicModel.topicCount" ng-attr-title="{{topicModel.topicCount + ' topic(s)'}}" ng-cloak></span> - <span class="badge" ng-if="!topicModel.lastGenerated" title="Model was never generated">Non-generated</span> - <span ng-bind="topicModel.name"></span> + <span class="badge" bs-popover popover-title="{{::topicModel.name}}" popover-template="partials/topicmodel-popover.html" popover-placement="left"> + <i class="fa fa-info"></i> + </span> + <span class="badge badge-group"> + <span class="badge-part" ng-if="!topicModel.lastGenerated" title="Model was never generated">Non-generated</span> + <span class="badge-part" ng-bind="::topicModel.articleCount" ng-show="topicModel.articleCount" ng-attr-title="{{::topicModel.articleCount + ' article(s)'}}" ng-cloak></span> + <span class="badge-part" ng-bind="::topicModel.topicCount" ng-show="topicModel.topicCount" ng-attr-title="{{::topicModel.topicCount + ' topic(s)'}}" ng-cloak></span> + </span> + <span ng-bind="::topicModel.name"></span> <br ng-show="topicModel.modelConfig.description" ng-cloak> - <small ng-bind="topicModel.modelConfig.description"></small> + <small ng-bind="::topicModel.modelConfig.description"></small> </button> </ul> <p class="text-center" ng-show="loading.any" ng-cloak> diff --git a/vipra-ui/app/js/app.js b/vipra-ui/app/js/app.js index 1913324c..d0d60338 100644 --- a/vipra-ui/app/js/app.js +++ b/vipra-ui/app/js/app.js @@ -260,6 +260,40 @@ } }); + // hold onto the drop down menu + var dropdownMenu; + + // and when you show it, move it to the body + $(window).on('show.bs.dropdown', function (e) { + + // grab the menu + dropdownMenu = $(e.target).find('.dropdown-menu'); + + // detach it and append it to the body + $('body').append(dropdownMenu.detach()); + + // grab the new offset position + var eOffset = $(e.target).offset(); + + // make sure to place it where it would normally go (this could be improved) + dropdownMenu.css({ + 'display': 'block', + 'top': eOffset.top + $(e.target).outerHeight(), + 'left': eOffset.left + }); + }); + + // and when you hide it, reattach the drop down, and hide it normally + $(window).on('hide.bs.dropdown', function (e) { + $(e.target).append(dropdownMenu.detach()); + dropdownMenu.hide(); + }); + + $(window).on('resize', function() { + if(dropdownMenu) + dropdownMenu.hide(); + }); + $(document).ready(function() { $('.btn-file :file').on('fileselect', function(event, numFiles, label) { var input = $(this).parents('.input-group').find(':text'), diff --git a/vipra-ui/app/js/directives.js b/vipra-ui/app/js/directives.js index 7d0db883..b3b06651 100644 --- a/vipra-ui/app/js/directives.js +++ b/vipra-ui/app/js/directives.js @@ -50,7 +50,7 @@ return { scope: { article: '=', - excerpt: '@', + details: '@', badge: '@', menu: '@' }, @@ -59,24 +59,24 @@ transclude: true, templateUrl: 'html/directives/article-link.html', link: function($scope) { - $scope.showExcerpt = $scope.excerpt !== 'false'; + $scope.showDetails = $scope.details !== 'false'; $scope.showBadge = $scope.badge !== 'false'; $scope.showMenu = $scope.menu !== 'false'; - $scope.toggleExcerpt = function() { - if (!$scope.excerptShown) { - if ($scope.excerpt) { - $scope.excerptShown = true; + $scope.toggleDetails = function() { + if (!$scope.detailsShown) { + if ($scope.details) { + $scope.detailsShown = true; } else { ArticleFactory.get({ id: $scope.article.id, excerpt: true }, function(data) { - $scope.excerpt = data.text; - $scope.excerptShown = true; + $scope.articleDetails = data; + $scope.detailsShown = true; }); } } else { - $scope.excerptShown = false; + $scope.detailsShown = false; } }; } diff --git a/vipra-ui/app/js/helpers.js b/vipra-ui/app/js/helpers.js index 63dfc88a..a3df6c4e 100644 --- a/vipra-ui/app/js/helpers.js +++ b/vipra-ui/app/js/helpers.js @@ -18,8 +18,7 @@ }; Vipra.formatDateTime = function(date) { - date = new Date(date); - return date.toLocaleDateString() + " " + date.toLocaleTimeString(); + return new Date(date).toLocaleString(); }; Vipra.toPercent = function(input, nums) { diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less index 754b620a..abe10319 100644 --- a/vipra-ui/app/less/app.less +++ b/vipra-ui/app/less/app.less @@ -703,7 +703,7 @@ entity-menu { } } -.excerpt { +.details { padding-top: 10px; color: #555; } @@ -943,6 +943,27 @@ entity-menu { padding: 0 !important; } +.td-padded th + td { + padding-left: 5px; +} + +.badge-group { + font-size: 0; + + .badge-part { + font-size: 12px; + padding: 0 5px; + } + + .badge-part + .badge-part { + border-left: 1px solid #ddd; + } +} + +.article-dropdown { + position: relative; +} + @keyframes spin { 100% { -webkit-transform: rotateY(360deg); diff --git a/vipra-util/src/main/java/de/vipra/util/model/TopicModelFull.java b/vipra-util/src/main/java/de/vipra/util/model/TopicModelFull.java index ac0615c9..8ae0afae 100644 --- a/vipra-util/src/main/java/de/vipra/util/model/TopicModelFull.java +++ b/vipra-util/src/main/java/de/vipra/util/model/TopicModelFull.java @@ -25,13 +25,15 @@ public class TopicModelFull implements Model<ObjectId>, Comparable<TopicModelFul private String name; - private Integer topicCount; + private Long topicCount; - private Integer articleCount; + private Long articleCount; - private Integer wordCount; + private Long wordCount; - private Integer windowCount; + private Long entityCount; + + private Long windowCount; private Date lastGenerated; @@ -80,35 +82,43 @@ public class TopicModelFull implements Model<ObjectId>, Comparable<TopicModelFul this.name = name; } - public Integer getTopicCount() { + public Long getTopicCount() { return topicCount; } - public void setTopicCount(final Integer topicCount) { + public void setTopicCount(final Long topicCount) { this.topicCount = topicCount; } - public Integer getArticleCount() { + public Long getArticleCount() { return articleCount; } - public void setArticleCount(final Integer articleCount) { + public void setArticleCount(final Long articleCount) { this.articleCount = articleCount; } - public Integer getWordCount() { + public Long getWordCount() { return wordCount; } - public void setWordCount(final Integer wordCount) { + public void setWordCount(final Long wordCount) { this.wordCount = wordCount; } - public Integer getWindowCount() { + public Long getEntityCount() { + return entityCount; + } + + public void setEntityCount(Long entityCount) { + this.entityCount = entityCount; + } + + public Long getWindowCount() { return windowCount; } - public void setWindowCount(final Integer windowCount) { + public void setWindowCount(final Long windowCount) { this.windowCount = windowCount; } @@ -142,7 +152,7 @@ public class TopicModelFull implements Model<ObjectId>, Comparable<TopicModelFul public void setWindows(final List<Window> windows) { this.windows = windows; - windowCount = windows != null ? windows.size() : 0; + windowCount = (long) (windows != null ? windows.size() : 0); } public Date getCreated() { diff --git a/vipra-util/src/main/java/de/vipra/util/model/TopicModelState.java b/vipra-util/src/main/java/de/vipra/util/model/TopicModelState.java new file mode 100644 index 00000000..68f4f7f8 --- /dev/null +++ b/vipra-util/src/main/java/de/vipra/util/model/TopicModelState.java @@ -0,0 +1,7 @@ +package de.vipra.util.model; + +public enum TopicModelState { + NONE, + MODELING, + INDEXING +} -- GitLab