diff --git a/vipra-cmd/runcfg/CMD.launch b/vipra-cmd/runcfg/CMD.launch index 2684d5379e17d2688b8b6be10bfd0a026892f0fa..bee7078bfab75ad04d237aa2164895de91ae036e 100644 --- a/vipra-cmd/runcfg/CMD.launch +++ b/vipra-cmd/runcfg/CMD.launch @@ -11,7 +11,7 @@ </listAttribute> <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="de.vipra.cmd.Main"/> -<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-S test -dcI /home/eike/repos/master/ma-impl/docker/data/test-1.json"/> +<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-S test2 -dcI /home/eike/repos/master/ma-impl/docker/data/test-1.json"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="vipra-cmd"/> <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/> 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 2409ea023cf53bd54a56be0b2c9b7dab24f5fa69..92fb40b5a56db54f9b2e0cb05ecdf3c4dc4c9e6c 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 @@ -237,7 +237,7 @@ public class Analyzer { final double[][] probabilities = new double[wordCount][windowCount]; for (int idxWord = 0; idxWord < wordCount; idxWord++) { for (int idxSeq = 0; idxSeq < windowCount; idxSeq++) { - probabilities[idxWord][idxSeq] = Double.parseDouble(in.readLine()); + probabilities[idxWord][idxSeq] = Math.exp(Double.parseDouble(in.readLine())); } } diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java index 14df7a19542cedd76f590774ee1757e7efd361db..bfa74d5867a211d1c9092e698bda8bae07511046 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java @@ -1,18 +1,13 @@ package de.vipra.cmd.option; import java.io.File; -import java.io.IOException; import java.util.Random; import org.bson.types.ObjectId; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.JsonMappingException; - import de.vipra.cmd.Main; import de.vipra.util.Config; import de.vipra.util.ConsoleUtils; -import de.vipra.util.ex.DatabaseException; import de.vipra.util.model.TopicModelConfig; import de.vipra.util.model.TopicModelFull; import de.vipra.util.service.MongoService; @@ -28,15 +23,21 @@ public class CreateModelCommand implements Command { this.names = names; } - private TopicModelFull createModel(final String name, final TopicModelConfig modelConfig, final File modelDir) - throws JsonGenerationException, JsonMappingException, IOException, DatabaseException { + private TopicModelFull createModel(final String name, final TopicModelConfig modelConfig) throws Exception { final TopicModelFull topicModel = new TopicModelFull(name, modelConfig); topicModel.setColorSeed(random.nextLong()); + dbTopicModels.createSingle(topicModel); + config.getTopicModelConfigs().put(topicModel.getName(), modelConfig); + + final File modelDir = new File(config.getDataDirectory(), topicModel.getName()); + + if (!modelDir.mkdirs()) + throw new Exception("could not create model directory: " + modelDir.getAbsolutePath()); + modelConfig.setName(topicModel.getName()); modelConfig.setGroup(topicModel.getGroup()); modelConfig.saveToFile(modelDir); - dbTopicModels.createSingle(topicModel); - config.getTopicModelConfigs().put(topicModel.getName(), modelConfig); + return topicModel; } @@ -63,12 +64,7 @@ public class CreateModelCommand implements Command { if (msg != null) throw new Exception(msg); - final File modelDir = new File(config.getDataDirectory(), name); - - if (!modelDir.mkdirs()) - throw new Exception("could not create model directory: " + modelDir.getAbsolutePath()); - - final TopicModelFull topicModel = createModel(name, modelConfig, modelDir); + final TopicModelFull topicModel = createModel(name, modelConfig); ConsoleUtils .info("model created: " + topicModel.getName() + (topicModel.getGroup() == null ? "" : " in group: " + topicModel.getGroup())); Main.stats.stop("create." + name); 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 427a830610a7b097ffb4a9a539a5a2627426f3d3..dc6885da292f6f58e078cec4e4167aee31aa2808 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 @@ -6,6 +6,7 @@ import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -182,11 +183,12 @@ public class ImportCommand implements Command { if (spotlightAnalyzer != null) { final SpotlightResponse spotlightResponse = spotlightAnalyzer.analyze(article.getText()); - final List<TextEntityCount> textEntitiesCounts = spotlightResponse.getEntities(); + List<TextEntityCount> textEntitiesCounts = spotlightResponse.getEntities(); if (textEntitiesCounts != null) { // replace entities with hypernyms if (modelConfig.isProcessorUseHypernyms()) { final HypernymAnalyzer hypernymAnalyzer = HypernymAnalyzer.getInstance(); + final Map<String, TextEntityCount> replacedTextEntities = new HashMap<>(textEntitiesCounts.size()); for (final TextEntityCount textEntityCount : textEntitiesCounts) { final TextEntity textEntity = textEntityCount.getEntity(); final String hypernym = hypernymAnalyzer.getHypernym(textEntity.realEntity()); @@ -194,7 +196,13 @@ public class ImportCommand implements Command { textEntity.setUrl(hypernymAnalyzer.getURL(hypernym)); textEntity.setIsHypernym(true); } + final TextEntityCount replacedTextEntity = replacedTextEntities.get(textEntity.getUrl()); + if (replacedTextEntity != null) + replacedTextEntity.setCount(replacedTextEntity.getCount() + textEntityCount.getCount()); + else + replacedTextEntities.put(textEntity.getUrl(), textEntityCount); } + textEntitiesCounts = new ArrayList<>(replacedTextEntities.values()); } blockedWords = new HashSet<>(textEntitiesCounts.size()); diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/ListModelsCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/ListModelsCommand.java index c899a979326d816daff6b3eba6a76486cdabecdc..0959b78d4cd8840945ffdac9aec0a32c09e70908 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/option/ListModelsCommand.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/ListModelsCommand.java @@ -20,7 +20,7 @@ public class ListModelsCommand implements Command { longestModelName = Math.max(longestModelName, entry.getValue().getName().length()); for (final Entry<String, TopicModelConfig> entry : config.getTopicModelConfigs().entrySet()) ConsoleUtils.info(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(StringUtils.pad(entry.getValue().getName(), longestModelName)).reset() - + " " + entry.getValue().toString()); + + " " + entry.getValue().toString() + " " + entry.getValue().getGroup()); } @Override diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/text/StopwordsAnnotator.java b/vipra-cmd/src/main/java/de/vipra/cmd/text/StopwordsAnnotator.java index 2a4c19856e5bc291688548246e6bdd659753aa25..04aefe2ec642fb78db1f2dd2e60f3b976b1a6e7b 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/text/StopwordsAnnotator.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/text/StopwordsAnnotator.java @@ -21,7 +21,7 @@ public class StopwordsAnnotator implements Annotator, CoreAnnotation<Boolean> { public StopwordsAnnotator(final String input, final Properties props) { stopWords = new HashSet<>(Arrays.asList(props.getProperty(NAME).split(" "))); - stopWords.addAll(Arrays.asList("-LRB-", "-RRB-", "-LSB-", "-RSB-", "-LCB-", "-RCB-")); + stopWords.addAll(Arrays.asList("-lrb-", "-rrb-", "-lsb-", "-rsb-", "-lcb-", "-rcb-")); } @Override diff --git a/vipra-ui/app/html/articles/entities.html b/vipra-ui/app/html/articles/entities.html index 493746dfc6bb01612d96b6c7dbc512d5869e2f3d..13de7b7631fd7705813f0196e5ab8e3f52428b54 100644 --- a/vipra-ui/app/html/articles/entities.html +++ b/vipra-ui/app/html/articles/entities.html @@ -41,7 +41,7 @@ </tr> </thead> <tbody> - <tr ng-repeat="entity in entities | orderBy:articlesShowModels.entitiesSort"> + <tr ng-repeat="entity in entities | orderBy:articlesShowModels.entitiesSort track by entity.entity.entity"> <td> <entity-link entity="::entity.entity" /> </td> diff --git a/vipra-ui/app/html/articles/index.html b/vipra-ui/app/html/articles/index.html index 24518891e9f283cbd192b3128038d2dee63f7286..fa42a19b59d91fbb8da3026f10b991c06b13f317 100644 --- a/vipra-ui/app/html/articles/index.html +++ b/vipra-ui/app/html/articles/index.html @@ -14,13 +14,10 @@ <div class="panel-heading clearfix"> Found <ng-pluralize count="articlesTotal||0" when="{0:'no articles',1:'1 article',other:'{} articles'}"></ng-pluralize> in the database. - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="article in articles"> + <tr ng-repeat="article in articles track by article.id"> <td> <article-link article="::article"/> </td> @@ -33,10 +30,8 @@ </tr> </tbody> </table> - <div class="panel-footer clearfix"> - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> + <div class="panel-footer"> + <sub-pagination total="articlesTotal" page="articlesIndexModels.page" limit="articlesIndexModels.limit" /> </div> </div> </div> diff --git a/vipra-ui/app/html/articles/show.html b/vipra-ui/app/html/articles/show.html index 9fe9273f91f06152a84935dd5de7596af16927d8..b95e11333563c858cacb5d0facf3b9e9d0d44521 100644 --- a/vipra-ui/app/html/articles/show.html +++ b/vipra-ui/app/html/articles/show.html @@ -30,7 +30,7 @@ <tbody> <tr> <th class="infocol">Date</th> - <td ng-bind-template="{{$root.Vipra.formatDateTime(article.date)}}"></td> + <td ng-bind-template="{{Vipra.formatDateTime(article.date)}}"></td> </tr> <tr ng-if="article.url"> <th>URL</th> @@ -58,18 +58,14 @@ <tr> <th class="infocol" ng-model="articlesShowModels.topicsSort" sort-by="share">Share</th> <th ng-model="articlesShowModels.topicsSort" sort-by="topic.name">Name</th> - <th class="colorcol"></th> </tr> </thead> <tbody> - <tr ng-repeat="topic in article.topics | orderBy:articlesShowModels.topicsSort" ng-mouseenter="highlightSlice(topic.topic.id, true)" ng-mouseleave="highlightSlice(topic.topic.id, false)"> - <td class="text-right" ng-bind-template="{{(topic.share*100).toFixed(0)}}%"></td> + <tr ng-repeat="topic in article.topics | orderBy:articlesShowModels.topicsSort track by topic.topic.id" ng-mouseenter="highlightSlice(topic.topic.id, true)" ng-mouseleave="highlightSlice(topic.topic.id, false)"> + <td class="text-right" ng-bind-template="{{::(topic.share*100).toFixed(0)}}%"></td> <td> <topic-link topic="::topic.topic" /> </td> - <td> - <span class="colorbox shown plain" style="background:{{::topic.color}}"></span> - </td> </tr> </tbody> </table> @@ -89,7 +85,7 @@ </tr> </thead> <tbody> - <tr ng-repeat="simArticle in article.similarArticles | orderBy:articlesShowModels.similarSort"> + <tr ng-repeat="simArticle in article.similarArticles | orderBy:articlesShowModels.similarSort track by simArticle.article.id"> <td class="text-right" ng-bind-template="{{::simArticle.share}}%"></td> <td> <article-link article="::simArticle.article" /> diff --git a/vipra-ui/app/html/articles/words.html b/vipra-ui/app/html/articles/words.html index 7c9a87ba6b44d2822828dd5839efa5fb72c59fd9..ccdf7b9beade0a6250cc1df34e7ff3814bad7b9e 100644 --- a/vipra-ui/app/html/articles/words.html +++ b/vipra-ui/app/html/articles/words.html @@ -44,7 +44,7 @@ </tr> </thead> <tbody> - <tr ng-repeat="word in words | orderBy:articlesShowModels.wordsSort"> + <tr ng-repeat="word in words | orderBy:articlesShowModels.wordsSort track by word.word"> <td> <word-link word="::word" /> </td> diff --git a/vipra-ui/app/html/directives/alert.html b/vipra-ui/app/html/directives/alert.html index c703f74d9eb64413bc240f21ab2d2bb34ca6793d..c565a37e4d813a997e8cd9ad1017113ecd508a39 100644 --- a/vipra-ui/app/html/directives/alert.html +++ b/vipra-ui/app/html/directives/alert.html @@ -1,4 +1,4 @@ -<div ng-attr-class="{{classes}}" role="alert"> +<div ng-attr-class="{{::classes}}" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-if="dismissible"><span aria-hidden="true">×</span></button> - <strong ng-bind="ngModel.title"></strong> <span ng-bind="ngModel.detail"></span> + <strong ng-bind="::ngModel.title"></strong> <span ng-bind="::ngModel.detail"></span> </div> \ No newline at end of file diff --git a/vipra-ui/app/html/directives/article-link.html b/vipra-ui/app/html/directives/article-link.html index 952d2991b5e61401bdb68726e4220a81956b1758..e4e93c8fd219761cf7fc2cd531e2a25e2a021b55 100644 --- a/vipra-ui/app/html/directives/article-link.html +++ b/vipra-ui/app/html/directives/article-link.html @@ -9,7 +9,7 @@ <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> </div> <a class="article-link" ui-sref="articles.show({id:article.id})" ng-attr-title="{{::article.title}}"> - <span class="title" ng-bind="article.title"></span> + <span class="title" ng-bind="::article.title"></span> <ng-transclude/> </a> </span> @@ -17,7 +17,7 @@ <div ng-if="detailsShown" class="details"> <span ng-bind="::articleDetails.text"></span> <div> - <a class="badge topic-badge text-outline" ng-style="{'background':topic.topic.color}" ng-repeat="topic in articleDetails.topics"> + <a class="badge topic-badge text-outline" ng-style="{'background':topic.topic.color}" ng-repeat="topic in articleDetails.topics track by topic.topic.id"> <topic-link topic="::topic.topic" badge="false" /> </a> </div> diff --git a/vipra-ui/app/html/directives/article-menu.html b/vipra-ui/app/html/directives/article-menu.html index 09815f09a46b98ed3d312bb0bf6001545029f853..4ae1d1143eba6caf251f6659f95ac3f00d25e246 100644 --- a/vipra-ui/app/html/directives/article-menu.html +++ b/vipra-ui/app/html/directives/article-menu.html @@ -4,7 +4,8 @@ </a> <ul class="dropdown-menu" ng-class="{'dropdown-menu-right':dropdownRight}"> <li><a ui-sref="articles.show({id:article.id})">Show</a></li> - <li role="separator" class="divider"></li> + <li><a ui-sref="articles.show.entities({id:article.id})">Entities</a></li> + <li><a ui-sref="articles.show.words({id:article.id})">Words</a></li> <li><a ui-sref="network({type:'articles',id:article.id})">Network</a></li> </ul> </div> \ No newline at end of file diff --git a/vipra-ui/app/html/directives/entity-link.html b/vipra-ui/app/html/directives/entity-link.html index 5fb9e2fdbca25ea8b202ecd08de14f5d36cfa975..2abd24c2f03477e60c21625142fec7cd0cba9692 100644 --- a/vipra-ui/app/html/directives/entity-link.html +++ b/vipra-ui/app/html/directives/entity-link.html @@ -1,7 +1,7 @@ <div class="link-wrapper"> <span class="menu-padding ellipsis"> <a class="entity-link" ui-sref="entities.show({id:entity.entity})" ng-attr-title="{{::entity.entity}}"> - <span class="title" ng-bind="entity.entity"></span> + <span class="title" ng-bind="::entity.entity"></span> <ng-transclude/> </a> </span> diff --git a/vipra-ui/app/html/directives/entity-menu.html b/vipra-ui/app/html/directives/entity-menu.html index 1e1c965f9a5b4776ce98e182240d3c9f6e9b758c..1d205f726fd44be870cb1a86b550bc802450a95c 100644 --- a/vipra-ui/app/html/directives/entity-menu.html +++ b/vipra-ui/app/html/directives/entity-menu.html @@ -5,7 +5,6 @@ <ul class="dropdown-menu" ng-class="{'dropdown-menu-right':dropdownRight}"> <li><a ui-sref="entities.show({id:entity.entity})">Show</a></li> <li ng-if="entity.isWord"><a ui-sref="words.show({id:entity.entity})">Show word</a></li> - <li role="separator" class="divider"></li> <li><a ui-sref="entities.show.articles({id:entity.entity})">Articles</a></li> <li role="separator" class="divider"></li> <li><a ng-href="{{entity.url}}" target="_blank"><span class="dbpedia-logo"></span> DBPedia</a></li> diff --git a/vipra-ui/app/html/directives/pagination-full.html b/vipra-ui/app/html/directives/pagination-full.html index 7564a87c025a491eaf2e554a3a882ba83cd4b220..30e2564110e7da1b3f64aed57a87eecc89dc7aae 100644 --- a/vipra-ui/app/html/directives/pagination-full.html +++ b/vipra-ui/app/html/directives/pagination-full.html @@ -28,7 +28,7 @@ </div> <div class="btn-group btn-group-justified button-pagination"> - <div class="btn-group" ng-repeat="p in pages"> + <div class="btn-group" ng-repeat="p in pages track by p"> <button class="btn btn-default" ng-class="{current:page==p}" ng-attr-title="{{'Page ' + p}}" ng-click="changePage(p)" analytics-on analytics-event="Paginator (i)" analytics-category="Filter actions" ng-bind="p"></button> </div> </div> diff --git a/vipra-ui/app/html/directives/pagination.html b/vipra-ui/app/html/directives/pagination.html index 069d579dadc6fbd51f327639947d9b82b65fa83a..b5f42ab659c944eca192c8b2b81bd92e7de3813e 100644 --- a/vipra-ui/app/html/directives/pagination.html +++ b/vipra-ui/app/html/directives/pagination.html @@ -8,7 +8,7 @@ <a ui-sref="{page:page==2?null:page-1}" ng-show="page>1" ng-click="changePage(page-1)" analytics-on analytics-event="Paginator (-1)" analytics-category="Filter actions" ng-cloak>‹</a> <span ng-hide="page>1">‹</span> </li> - <li ng-class="{active:p==page}" ng-repeat="p in pages"> + <li ng-class="{active:p==page}" ng-repeat="p in pages track by p"> <a ui-sref="{page:p===1?null:p}" ng-bind="p" ng-click="changePage(p)" analytics-on analytics-event="Paginator (i)" analytics-category="Filter actions"></a> </li> <li title="Next" ng-class="{disabled:page>=maxPage}"> diff --git a/vipra-ui/app/html/directives/sequence-dropdown.html b/vipra-ui/app/html/directives/sequence-dropdown.html index cd86d8ffc3b24c4105460572d55a4a9ab62debd1..5c4bb1cc0122098b3ced7d4d14052b344c4d3a5d 100644 --- a/vipra-ui/app/html/directives/sequence-dropdown.html +++ b/vipra-ui/app/html/directives/sequence-dropdown.html @@ -1 +1,3 @@ -<select class="form-control inline" ng-model="ngModel" ng-disabled="!sequences" ng-options="sequence as sequence.label for sequence in sequences track by sequence.id"></select> \ No newline at end of file +<select class="form-control inline" ng-model="ngModel" ng-disabled="!sequences" ng-options="sequence as sequence.label for sequence in sequences track by sequence.id"> + <option value="" style="display:none" disabled selected>None</option> +</select> \ No newline at end of file diff --git a/vipra-ui/app/html/directives/sub-pagination.html b/vipra-ui/app/html/directives/sub-pagination.html new file mode 100644 index 0000000000000000000000000000000000000000..0c3ccc0cb0df498d7c50e896ac6ec9040ee18764 --- /dev/null +++ b/vipra-ui/app/html/directives/sub-pagination.html @@ -0,0 +1,15 @@ +<ul class="pager"> + <li class="previous" ng-class="{disabled:page===1}"> + <a ng-click="changePage(page-1)" analytics-on analytics-event="Paginator (-1)" analytics-category="Filter actions"> + <i class="fa fa-angle-left"></i> Prev + </a> + </li> + <li class="current"> + Page <span ng-bind="page||1"></span> of <span ng-bind="maxPage||1"></span> + </li> + <li class="next" ng-class="{disabled:page>=maxPage}"> + <a ng-click="changePage(page+1)" analytics-on analytics-event="Paginator (i+1)" analytics-category="Filter actions"> + Next <i class="fa fa-angle-right"></i> + </a> + </li> +</ul> \ No newline at end of file diff --git a/vipra-ui/app/html/directives/topic-link.html b/vipra-ui/app/html/directives/topic-link.html index 0bb40417ab7f2f19a3dc0dc7eed0c8a1d18b8b5c..cee3218d639ca45574b38dc4b73a6cf616d62cb2 100644 --- a/vipra-ui/app/html/directives/topic-link.html +++ b/vipra-ui/app/html/directives/topic-link.html @@ -1,7 +1,10 @@ <div class="link-wrapper"> <span class="menu-padding ellipsis"> - <a ui-sref="topics.show.articles({id:topic.id})" class="badge pull-right" ng-bind="::topic.articlesCount" ng-attr-title="{{::topic.articlesCount}} article(s)" ng-if="::showBadge"></a> - <a class="topic-link" ui-sref="topics.show({id:topic.id})" ng-attr-title="{{::topic.name}}"> + <div class="pull-right"> + <a ui-sref="topics.show.articles({id:topic.id})" class="badge" ng-bind="::topic.articlesCount" ng-attr-title="{{::topic.articlesCount}} article(s)" ng-if="::showBadge"></a> + <span class="colorbox plain shown" style="background:{{::topic.color}}"></span> + </div> + <a class="topic-link" ui-sref="topics.show({id:topic.id})" ng-attr-title="{{topic.name}}"> <span class="title" ng-bind="topic.name"></span> <ng-transclude/> </a> diff --git a/vipra-ui/app/html/directives/topic-menu.html b/vipra-ui/app/html/directives/topic-menu.html index b533279a237575113b041630b9ea5d81bd363261..e6984e1fb0eadb9b993d4b0ce8ec059595383954 100644 --- a/vipra-ui/app/html/directives/topic-menu.html +++ b/vipra-ui/app/html/directives/topic-menu.html @@ -4,9 +4,10 @@ </a> <ul class="dropdown-menu" ng-class="{'dropdown-menu-right':dropdownRight}"> <li><a ui-sref="topics.show({id:topic.id})">Show</a></li> - <li><a ng-click="renameTopic()" analytics-on analytics-event="Rename topic" analytics-category="Topic actions">Rename...</a></li> - <li role="separator" class="divider"></li> - <li><a ui-sref="network({type:'topics',id:topic.id})">Network</a></li> + <li><a ui-sref="topics.show.sequences({id:topic.id})">Sequences</a></li> <li><a ui-sref="topics.show.articles({id:topic.id})">Articles</a></li> + <li><a ui-sref="network({type:'topics',id:topic.id})">Network</a></li> + <li role="separator" class="divider"></li> + <li><a ng-click="renameTopic()" analytics-on analytics-event="Rename topic" analytics-category="Topic actions">Rename...</a></li> </ul> </div> diff --git a/vipra-ui/app/html/directives/topicmodel-button.html b/vipra-ui/app/html/directives/topicmodel-button.html index 9e45cceb1cd49b22b12ebd0df7525dbfbda246f5..83c08462fb335df68ffd5ab834e649a1ee66a9a5 100644 --- a/vipra-ui/app/html/directives/topicmodel-button.html +++ b/vipra-ui/app/html/directives/topicmodel-button.html @@ -1,8 +1,8 @@ <button type="button" class="list-group-item topic-model" 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 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 class="badge-part" ng-bind="::topicModel.articleCount" ng-show="topicModel.articleCount" ng-attr-title="{{::topicModel.articleCount + ' article(s)'}}" ng-cloak></span> </span> <span ng-bind="::topicModel.name"></span> <br ng-show="topicModel.modelConfig.description" ng-cloak> diff --git a/vipra-ui/app/html/directives/word-evolution.html b/vipra-ui/app/html/directives/word-evolution.html index 471079ba7fa6d7214d2a801b5195e1ce49f44815..3796949addaa92a94fa50de3cd48b7d0f8e76ce9 100644 --- a/vipra-ui/app/html/directives/word-evolution.html +++ b/vipra-ui/app/html/directives/word-evolution.html @@ -18,12 +18,12 @@ <div class="panel-body"> <div class="topic-list sidebar"> <ul class="list-unstyled item-choice"> - <li ng-repeat="word in topic.words" ng-mouseenter="highlightSeries(word.word, true)" ng-mouseleave="highlightSeries(word.word, false)"> + <li ng-repeat="word in topic.words track by word.word" ng-mouseenter="highlightSeries(word.word, true)" ng-mouseleave="highlightSeries(word.word, false)"> <div class="checkbox checkbox-condensed" ng-class="{selected:word.selected}"> <input tabindex="0" type="checkbox" ng-model="word.selected" ng-attr-id="{{::word.word}}" ng-change="redrawWordEvolutionChart()"> <label class="check" ng-attr-for="{{::word.word}}" analytics-on analytics-event="Word Evolution Word" analytics-category="Chart actions"> <span class="ellipsis menu-padding" ng-attr-title="{{::word.word}}"> - <span ng-bind="word.word"></span> + <span ng-bind="::word.word"></span> </span> <word-menu word="word" class="menu-button" /> </label> @@ -34,7 +34,7 @@ </div> <div class="center message-container"> <div class="wrapper"> - <div class="chart area-chart" ng-attr-id="{{chartId}}" highcharts="wordEvolution"></div> + <div class="chart area-chart" ng-attr-id="{{::chartId}}" highcharts="wordEvolution"></div> </div> </div> </div> diff --git a/vipra-ui/app/html/directives/word-menu.html b/vipra-ui/app/html/directives/word-menu.html index 97c31b2712070037b30c2b0e95ffbf6d4174c507..d6f17117fae0b682dbaf8082228ee55225974b1e 100644 --- a/vipra-ui/app/html/directives/word-menu.html +++ b/vipra-ui/app/html/directives/word-menu.html @@ -4,7 +4,6 @@ </a> <ul class="dropdown-menu" ng-class="{'dropdown-menu-right':dropdownRight}"> <li><a ui-sref="words.show({id:id})">Show</a></li> - <li role="separator" class="divider"></li> <li><a ui-sref="words.show.topics({id:id})">Topics</a></li> <li><a ui-sref="words.show.articles({id:id})">Articles</a></li> </ul> diff --git a/vipra-ui/app/html/entities/articles.html b/vipra-ui/app/html/entities/articles.html index dec71c1de08231a21d032dae254d0a2d732999cb..65ae82528392b015dbd3acb3968d838a13bfaea1 100644 --- a/vipra-ui/app/html/entities/articles.html +++ b/vipra-ui/app/html/entities/articles.html @@ -41,7 +41,7 @@ </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="article in articles"> + <tr ng-repeat="article in articles track by article.id"> <td> <article-link article="::article"/> </td> diff --git a/vipra-ui/app/html/entities/index.html b/vipra-ui/app/html/entities/index.html index 8cc34a7ffd31ab55fbf7986e95e4f301084b98d8..a8d5d2ab0f78670c896d200f884f9f0c076a5330 100644 --- a/vipra-ui/app/html/entities/index.html +++ b/vipra-ui/app/html/entities/index.html @@ -14,13 +14,10 @@ <div class="panel-heading clearfix"> Found <ng-pluralize count="entitiesTotal||0" when="{0:'no entities',1:'1 entity',other:'{} entities'}"></ng-pluralize> in the database. - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="entity in entities"> + <tr ng-repeat="entity in entities track by entity.entity"> <td> <entity-link entity="::entity" /> </td> @@ -33,10 +30,8 @@ </tr> </tbody> </table> - <div class="panel-footer clearfix"> - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> + <div class="panel-footer"> + <sub-pagination total="entitiesTotal" page="entitiesIndexModels.page" limit="entitiesIndexModels.limit" /> </div> </div> </div> diff --git a/vipra-ui/app/html/explorer.html b/vipra-ui/app/html/explorer.html index b888481bdc234cdb167811e4d82e15c4d65a56ac..87657d31358c6443908702998f110b788b449388 100644 --- a/vipra-ui/app/html/explorer.html +++ b/vipra-ui/app/html/explorer.html @@ -22,12 +22,12 @@ <span class="glyphicon glyphicon-remove-circle searchclear" ng-click="search=''" analytics-on analytics-event="Explorer Filter Topics (clear)" analytics-category="Filter actions"></span> </div> <ul class="list-unstyled item-choice topic-choice"> - <li ng-repeat="topic in topics | orderBy:explorerModels.sorttopics:explorerModels.sortdir | filter:search" ng-mouseenter="highlightTopic(topic.id, true)" ng-mouseleave="highlightTopic(topic.id, false)" ng-class="{selected:topic.selected}" class="text-muted topic" ng-attr-data-id="{{::topic.id}}"> + <li ng-repeat="topic in topics | orderBy:explorerModels.sorttopics:explorerModels.sortdir | filter:search track by topic.id" ng-mouseenter="highlightTopic(topic.id, true)" ng-mouseleave="highlightTopic(topic.id, false)" ng-class="{selected:topic.selected}" class="text-muted topic" ng-attr-data-id="{{::topic.id}}"> <div class="checkbox checkbox-condensed"> <span class="valuebar" ng-style="{width:topic.topicCurrValue}"></span> <input tabindex="0" type="checkbox" ng-model="topic.selected" ng-attr-id="relevance-{{::topic.id}}" ng-change="changeSelectedTopics()"> <label class="check" ng-attr-for="relevance-{{::topic.id}}" analytics-on analytics-event="Explorer Topic Relevance Choice" analytics-category="Explorer actions"> - <span class="ellipsis menu-padding" ng-attr-title="{{::topic.name}}"> + <span class="ellipsis menu-padding" ng-attr-title="{{topic.name}}"> <span class="title" ng-bind="topic.name"></span> </span> <topic-menu topic="topic" class="menu-button" /> @@ -73,12 +73,12 @@ <div class="ui-layout-south no-padding no-border" id="lower"> <div class="ui-layout-west explorer-sidebar no-border"> <ul class="list-unstyled item-choice no-offset"> - <li ng-repeat="topic in selectedTopics = (topics | filter:{selected: true} | filter:search | orderBy:explorerModels.sorttopics:explorerModels.sortdir)" ng-mouseenter="highlightTopic(topic.id, true)" ng-mouseleave="highlightTopic(topic.id, false)" ng-class="{active:explorerModels.activeTopic.id===topic.id}" class="pointer text-muted topic" ng-attr-data-id="{{::topic.id}}"> + <li ng-repeat="topic in selectedTopics = (topics | filter:{selected: true} | filter:search | orderBy:explorerModels.sorttopics:explorerModels.sortdir) track by topic.id" ng-mouseenter="highlightTopic(topic.id, true)" ng-mouseleave="highlightTopic(topic.id, false)" ng-class="{active:explorerModels.activeTopic.id===topic.id}" class="pointer text-muted topic" ng-attr-data-id="{{::topic.id}}"> <div class="radio radio-condensed"> <span class="valuebar" ng-style="{width:topic.topicCurrValue}"></span> <input tabindex="0" type="radio" ng-model="explorerModels.activeTopic" ng-attr-id="detail-{{::topic.id}}" name="topic-active" ng-value="topic"> <label class="radio" ng-attr-for="detail-{{::topic.id}}" analytics-on analytics-event="Explorer Topic Detail Choice" analytics-category="Explorer actions"> - <span class="ellipsis menu-padding" ng-attr-title="{{::topic.name}}"> + <span class="ellipsis menu-padding" ng-attr-title="{{topic.name}}"> <span class="title" ng-bind="topic.name"></span> </span> <topic-menu topic="topic" class="menu-button" /> @@ -120,7 +120,7 @@ </tr> </thead> <tbody> - <tr ng-repeat="article in articles | orderBy:explorerModels.articlesSort"> + <tr ng-repeat="article in articles | orderBy:explorerModels.articlesSort track by article.id"> <td> <article-link article="::article" /> </td> diff --git a/vipra-ui/app/html/index.html b/vipra-ui/app/html/index.html index ba7ee29fbbd988fa468d7d1cea2ed405aabe1545..a9a87355a852b6a78acd20f20b4d0fc874a75b58 100644 --- a/vipra-ui/app/html/index.html +++ b/vipra-ui/app/html/index.html @@ -78,7 +78,7 @@ <div class="col-md-12" ng-show="searchResults.length > 0" ng-cloak> <h4>Results</h4> <ul class="list-unstyled search-results"> - <li class="search-result" ng-repeat="article in searchResults"> + <li class="search-result" ng-repeat="article in searchResults track by article.id"> <a ui-sref="articles.show({id:article.id})" ng-bind="article.title"></a> <p> <span class="text" ng-bind="article.text"></span> diff --git a/vipra-ui/app/html/partials/topicmodel-popover.html b/vipra-ui/app/html/partials/topicmodel-popover.html deleted file mode 100644 index eef9175423d8b39b3c974fef4c41ee4771f43241..0000000000000000000000000000000000000000 --- a/vipra-ui/app/html/partials/topicmodel-popover.html +++ /dev/null @@ -1,34 +0,0 @@ -<table class="popover-table"> - <tr> - <th>Article count</th> - <td ng-bind="rootModels.topicModel.articleCount || 0"></td> - </tr> - <tr> - <th>Topic count</th> - <td ng-bind="rootModels.topicModel.topicCount || 0"></td> - </tr> - <tr> - <th>Entity count</th> - <td ng-bind="rootModels.topicModel.entityCount || 0"></td> - </tr> - <tr> - <th>Word count</th> - <td ng-bind="rootModels.topicModel.wordCount || 0"></td> - </tr> - <tr> - <th>Window count</th> - <td ng-bind="rootModels.topicModel.windowCount || 0"></td> - </tr> - <tr> - <th>Last generated</th> - <td ng-bind-template="{{$root.Vipra.formatDateTime(rootModels.topicModel.lastGenerated) || 'never'}}"></td> - </tr> - <tr> - <th>Last indexed</th> - <td ng-bind-template="{{$root.Vipra.formatDateTime(rootModels.topicModel.lastIndexed) || 'never'}}"></td> - </tr> - <tr> - <th>Last modified</th> - <td ng-bind-template="{{$root.Vipra.formatDateTime(rootModels.topicModel.modified) || 'never'}}"></td> - </tr> -</table> \ No newline at end of file diff --git a/vipra-ui/app/html/topics/articles.html b/vipra-ui/app/html/topics/articles.html index d0232f29adf269e8f1df97f5dc64e687271f4235..a5d41b22e23d327d7abf1df984760f38343423aa 100644 --- a/vipra-ui/app/html/topics/articles.html +++ b/vipra-ui/app/html/topics/articles.html @@ -2,7 +2,7 @@ <div class="container" ng-cloak ng-hide="!rootModels.topicModel || state.name !== 'topics.show.articles'"> <div class="page-header no-border"> <span class="label label-default">Topic</span> - <h1 ng-bind="::topic.name"></h1> + <h1 ng-bind="topic.name"></h1> </div> <div> <ul class="nav nav-tabs" role="tablist"> @@ -37,6 +37,7 @@ <option value="title">Title</option> <option value="date">Date</option> <option value="created">Added</option> + <option value="topicsCount"># of topics</option> </select> <span class="input-group-btn"> <sort-dir ng-model="topicsArticlesModels.sortdir" /> @@ -46,7 +47,7 @@ </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="article in articles"> + <tr ng-repeat="article in articles track by article.id"> <td> <article-link article="::article"/> </td> diff --git a/vipra-ui/app/html/topics/index.html b/vipra-ui/app/html/topics/index.html index aa50877e2ea3eca00c4110fde8fc9442aec49d48..10412713aa45ba1f7b1a8d6c4717964c9c9171c3 100644 --- a/vipra-ui/app/html/topics/index.html +++ b/vipra-ui/app/html/topics/index.html @@ -14,13 +14,10 @@ <div class="panel-heading clearfix"> Found <ng-pluralize count="topicsTotal||0" when="{0:'no topics',1:'1 topic',other:'{} topics'}"></ng-pluralize> in the database. - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="topic in topics"> + <tr ng-repeat="topic in topics track by topic.id"> <td> <topic-link topic="::topic" /> </td> @@ -33,10 +30,8 @@ </tr> </tbody> </table> - <div class="panel-footer clearfix"> - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> + <div class="panel-footer"> + <sub-pagination total="topicsTotal" page="topicsIndexModels.page" limit="topicsIndexModels.limit" /> </div> </div> </div> diff --git a/vipra-ui/app/html/topics/sequences.html b/vipra-ui/app/html/topics/sequences.html index 78ec3f0f2f542947979c8c958d2cea147934e987..38c772fbe728a0a9b3bbecff9bfc65df10d01ac8 100644 --- a/vipra-ui/app/html/topics/sequences.html +++ b/vipra-ui/app/html/topics/sequences.html @@ -2,7 +2,7 @@ <div class="container" ng-cloak ng-hide="!rootModels.topicModel || state.name !== 'topics.show.sequences'"> <div class="page-header no-border"> <span class="label label-default">Topic</span> - <h1 ng-bind="::topic.name"></h1> + <h1 ng-bind="topic.name"></h1> </div> <div> <ul class="nav nav-tabs" role="tablist"> @@ -43,7 +43,7 @@ </tr> </thead> <tbody> - <tr class="compare-row" ng-repeat="word in sequence.words | orderBy:topicsShowModels.seqSortWords" ng-attr-word="{{::word.word}}"> + <tr class="compare-row" ng-repeat="word in sequence.words | orderBy:topicsShowModels.seqSortWords track by word.word" ng-attr-word="{{::word.word}}"> <td> <word-link word="::word" /> </td> @@ -66,7 +66,7 @@ </tr> </thead> <tbody> - <tr class="compare-row" ng-repeat="word in sequence.words | orderBy:topicsShowModels.seqSortWords" ng-attr-word="{{::word.word}}"> + <tr class="compare-row" ng-repeat="word in sequence.words | orderBy:topicsShowModels.seqSortWords track by word.word" ng-attr-word="{{::word.word}}"> <td class="text-center"> <change-pos change="word.change"/> </td> @@ -91,7 +91,7 @@ </tr> </thead> <tbody> - <tr class="compare-row" ng-repeat="word in sequenceCompare.words | orderBy:topicsShowModels.seqSortWords" ng-attr-word="{{::word.word}}"> + <tr class="compare-row" ng-repeat="word in sequenceCompare.words | orderBy:topicsShowModels.seqSortWords track by word.word" ng-attr-word="{{::word.word}}"> <td> <word-link word="::word" /> </td> diff --git a/vipra-ui/app/html/words/articles.html b/vipra-ui/app/html/words/articles.html index 23f7abef39013694282d3103970148c55966e0c0..17b8e78a7c895d4ee329366d122a4ab2a218f3bc 100644 --- a/vipra-ui/app/html/words/articles.html +++ b/vipra-ui/app/html/words/articles.html @@ -45,7 +45,7 @@ </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="article in articles"> + <tr ng-repeat="article in articles track by article.id"> <td> <article-link article="::article"/> </td> diff --git a/vipra-ui/app/html/words/index.html b/vipra-ui/app/html/words/index.html index 8f3cb8d7aa08698f3119b22e7fb24be4b83376c4..13f25ab27306d835f5c979e8661ad116ff488ae0 100644 --- a/vipra-ui/app/html/words/index.html +++ b/vipra-ui/app/html/words/index.html @@ -14,13 +14,10 @@ <div class="panel-heading clearfix"> Found <ng-pluralize count="wordsTotal||0" when="{0:'no words',1:'1 word',other:'{} words'}"></ng-pluralize> in the database. - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="word in words"> + <tr ng-repeat="word in words track by word.word"> <td> <word-link word="::word" /> </td> @@ -34,9 +31,7 @@ </tbody> </table> <div class="panel-footer clearfix"> - <div class="pull-right"> - Page <span ng-bind="wordsIndexModels.page||1"></span> of <span ng-bind="maxPage||1"></span> - </div> + <sub-pagination total="wordsTotal" page="wordsIndexModels.page" limit="wordsIndexModels.limit" /> </div> </div> </div> diff --git a/vipra-ui/app/html/words/topics.html b/vipra-ui/app/html/words/topics.html index 26b6adf16a568076259edc0cd1c254b1bb011f57..96c0fa297a47c8ac4ad01349681881345b5fb694 100644 --- a/vipra-ui/app/html/words/topics.html +++ b/vipra-ui/app/html/words/topics.html @@ -44,7 +44,7 @@ </div> <table class="table table-hover table-condensed table-fixed"> <tbody> - <tr ng-repeat="topic in topics"> + <tr ng-repeat="topic in topics track by topic.id"> <td> <topic-link topic="::topic" /> </td> diff --git a/vipra-ui/app/index.html b/vipra-ui/app/index.html index a303f682e29b099d25c2f3b398d221d3c5b15c14..443134fe416756d8d92e8aece2692982f708c07a 100644 --- a/vipra-ui/app/index.html +++ b/vipra-ui/app/index.html @@ -48,30 +48,30 @@ </ul> <form class="navbar-form navbar-left search-form" role="search" ng-hide="state.name === 'index'" ng-cloak> <div class="form-group has-feedback"> - <input tabindex="0" type="text" class="form-control" placeholder="Search..." ng-model="rootModels.search" ng-enter="menubarSearch(rootModels.search)" id="menuSearchBox"> + <input tabindex="0" type="text" class="form-control search-collapsed" placeholder="Search..." ng-model="rootModels.search" ng-enter="menubarSearch(rootModels.search)" id="quicksearch"> <i class="form-control-feedback glyphicon glyphicon-search text-muted"></i> </div> </form> <ul class="nav navbar-nav navbar-right"> - <li ng-class="{'text-italic active':rootModels.topicModel}" bs-popover popover-template="partials/topicmodel-popover.html" popover-delay="500" popover-placement="bottom"> + <li ng-class="{'text-italic active':rootModels.topicModel}"> <a class="active-topicmodel" tabindex="0" ng-click="chooseTopicModel()" ng-bind-template="{{rootModels.topicModel ? rootModels.topicModel.name : 'Models'}}" analytics-on analytics-event="Menu Item (Topic Models)" analytics-category="Menu actions"></a> </li> - <li ng-class="{disabled:!rootModels.helpEnabled}" ng-attr-title="{{ rootModels.helpEnabled ? 'Help' : 'No help available' }}"> + <li class="menu-icon" ng-class="{disabled:!rootModels.helpEnabled}" ng-attr-title="{{ rootModels.helpEnabled ? 'Help' : 'No help available' }}"> <a ng-click="showHelp()"> <i class="fa fa-question-circle"></i> </a> </li> - <li title="Keyboard cheatsheet"> + <li class="menu-icon" title="Keyboard cheatsheet"> <a tabindex="0" ng-click="showCheatSheet()" analytics-on analytics-event="Menu Item (Cheatsheet)" analytics-category="Menu actions"> <i class="fa fa-keyboard-o"></i> </a> </li> - <li ui-sref-active="active" title="About"> + <li class="menu-icon" ui-sref-active="active" title="About"> <a tabindex="0" ui-sref="about"> <i class="fa fa-info-circle"></i> </a> </li> - <li title="Feedback"> + <li class="menu-icon" title="Feedback"> <a tabindex="0" ng-click="showFeedbackModal()" analytics-on analytics-event="Menu Item (Feedback)" analytics-category="Menu actions"> <i class="fa fa-comment-o"></i> </a> @@ -81,7 +81,7 @@ </div> </nav> <div class="main" ui-view ng-cloak></div> - <div id="topicModelModal" class="modal" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false" ng-show="!fatal"> + <div id="topicModelModal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false" ng-if="!fatal"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> @@ -93,7 +93,7 @@ <input tabindex="0" type="text" class="form-control" placeholder="Filter..." ng-model="rootModels.topicModelFilter"> <i class="form-control-feedback glyphicon glyphicon-search text-muted"></i> </div> - <div class="panel panel-default" ng-repeat="(groupName, group) in groups" ng-show="filtered.length"> + <div class="panel panel-default topic-group" ng-repeat="(groupName, group) in groups track by groupName" ng-show="filtered.length"> <div class="panel-heading pointer" ng-click="group.collapsed=!group.collapsed"> <i class="fa folder-icon" ng-class="{'fa-folder-open-o':!group.collapsed,'fa-folder-o':group.collapsed}"></i> <span ng-bind="::groupName"></span> @@ -103,11 +103,11 @@ </div> </div> <div ng-attr-id="{{::groupName}}" class="list-group nomargin collapse in" ng-show="topicModelsCount && !group.collapsed" ng-cloak> - <topicmodel-button ng-repeat="topicModel in filtered = (group | filter:{name:rootModels.topicModelFilter})"></topicmodel-button> + <topicmodel-button ng-repeat="topicModel in filtered = (group | filter:{name:rootModels.topicModelFilter}) track by topicModel.id"></topicmodel-button> </div> </div> <div class="list-group nomargin" ng-show="topicModelsCount" ng-cloak> - <topicmodel-button ng-repeat="topicModel in topicModels | filter:{name:rootModels.topicModelFilter}"></topicmodel-button> + <topicmodel-button ng-repeat="topicModel in topicModels | filter:{name:rootModels.topicModelFilter} track by topicModel.id"></topicmodel-button> </div> <p class="text-center" ng-show="loading.any" ng-cloak> Loading... @@ -136,7 +136,7 @@ </div> </div> </div> - <div id="feedbackModal" class="modal" tabindex="-1" role="dialog" data-backdrop="static"> + <div id="feedbackModal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> @@ -149,7 +149,7 @@ </div> </div> </div> - <div id="helpModal" class="modal" tabindex="-1" role="dialog" data-backdrop="static"> + <div id="helpModal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> diff --git a/vipra-ui/app/js/app.js b/vipra-ui/app/js/app.js index 4cc3fa117564f91bfc8f3797ef4a20ff22fe07b3..cadb228563fc63c3a7854eb35f6be0c3c484b5e5 100644 --- a/vipra-ui/app/js/app.js +++ b/vipra-ui/app/js/app.js @@ -234,7 +234,7 @@ } ]); - app.run(['$rootScope', '$state', function($rootScope, $state) { + app.run(['$rootScope', '$state', '$interval', function($rootScope, $state, $interval) { $rootScope.loading = {}; @@ -262,6 +262,15 @@ $rootScope.$on('$stateChangeStart', function() { $rootScope.alerts = []; }); + + // http://www.mograblog.com/2015/10/angular-improve-website-performance.html + // this cancels intervals on scope destroy + var ScopeProt = Object.getPrototypeOf($rootScope); + ScopeProt.$interval = function(func, time){ + var timer = $interval(func,time); + this.on('$destroy', function(){ $timeout.cancel(timer); }); + return timer; + }; }]); $(document).on('change', '.btn-file :file', function() { @@ -277,6 +286,17 @@ } }); + $(document).on('click', '#quicksearch', function() { + if($(this).hasClass('search-collapsed')) + $(this).removeClass('search-collapsed'); + }); + + $(document).on('blur', '#quicksearch', function(e) { + if(!this.value) { + $(this).addClass('search-collapsed'); + } + }); + // hold onto the drop down menu var dropdownMenu; diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js index 372fae3248284d971ea90f42fc991e9f9bc098c6..9877f182d8ccce527c1d8a0d72372a6a1b350702 100644 --- a/vipra-ui/app/js/controllers.js +++ b/vipra-ui/app/js/controllers.js @@ -19,25 +19,21 @@ helpEnabled: false }; - var prevTopicModelLoading = false; var prevTopicModelDefer = $q.defer(); $scope.rootModels.tmLoading = prevTopicModelDefer.promise; if (localStorage.tm) { - prevTopicModelLoading = true; $rootScope.loadingScreen = true; TopicModelFactory.get({ id: localStorage.tm }, function(data) { $scope.rootModels.topicModel = data; - prevTopicModelLoading = false; $scope.loadingScreen = false; prevTopicModelDefer.resolve(); }, function() { delete localStorage.tm; - prevTopicModelLoading = false; $scope.loadingScreen = false; $scope.chooseTopicModel(); prevTopicModelDefer.reject(); @@ -71,15 +67,15 @@ }; $scope.chooseTopicModel = function() { - if (prevTopicModelLoading) - return; - $scope.queryTopicModels(); - $scope.rootModels.topicModelModalOpen = true; - $('#topicModelModal').modal(); - if ($scope.rootModels.topicModel) - $('.selected-model').focus(); - else - $('.topic-model').first().focus(); + $scope.rootModels.tmLoading.finally(function() { + $scope.queryTopicModels(); + $scope.rootModels.topicModelModalOpen = true; + $('#topicModelModal').modal(); + if ($scope.rootModels.topicModel) + $('.selected-model').focus(); + else + $('.topic-model').first().focus(); + }); }; $scope.changeTopicModel = function(topicModel) { @@ -212,6 +208,10 @@ $('#helpModal').modal(); } }; + + $scope.showSearch = function() { + $scope.searchExpanded = true; + }; } ]); @@ -1721,7 +1721,7 @@ $scope.checkTopicModel('entities.show.articles', function() { $scope.id = $stateParams.id; - $scope.rootModels.title = $scope.entity; + $scope.rootModels.title = $scope.id; $scope.entitiesArticlesModels = { sortkey: 'date', @@ -1950,8 +1950,8 @@ var pages = [], max = Math.ceil($scope.total / $scope.limit * 1.0), pad = 2, - start = Math.max($scope.page - pad, 1), - end = Math.min(Math.max($scope.page + pad, start + pad * 2), max); + end = Math.min(Math.max($scope.page + pad, Math.max($scope.page - pad, 1) + pad * 2), max), + start = Math.max(Math.min($scope.page - pad, end - pad * 2), 1); for (var i = start; i <= end; i++) { pages.push(i); } @@ -1968,7 +1968,8 @@ $scope.calculatePages(); $scope.changePage = function(page) { - $scope.page = parseInt(page, 10); + if(page < 1 || page > $scope.maxPage) return; + $scope.page = page; window.scrollTo(0,0); }; diff --git a/vipra-ui/app/js/directives.js b/vipra-ui/app/js/directives.js index 9370e889bfc8a14f891c9991d7759a46a2f14ba4..e70ab740e5f7b1aec9d7a48e584591fece871722 100644 --- a/vipra-ui/app/js/directives.js +++ b/vipra-ui/app/js/directives.js @@ -130,6 +130,21 @@ }; }]); + app.directive('subPagination', [function() { + return { + restrict: 'E', + replace: true, + scope: { + total: '=', + page: '=', + limit: '=', + change: '&' + }, + controller: 'PaginationController', + templateUrl: 'html/directives/sub-pagination.html' + } + }]); + app.directive('highcharts', [function() { return { scope: { diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less index f0a7e501664adede8e92f5d80f3188d65b689e0c..069ef4c4ad3f690a49ab952c69fab4583fd87930 100644 --- a/vipra-ui/app/less/app.less +++ b/vipra-ui/app/less/app.less @@ -12,7 +12,7 @@ html { body { padding-top: @topbarSpace; - padding-bottom: 20px; + padding-bottom: @topbarSpace; } html, body { @@ -252,6 +252,7 @@ td { } } +.navbar a, .vis-network { outline: none; } @@ -564,10 +565,6 @@ entity-menu { width: 100px; } -.colorcol { - width: 21px; -} - .page-header.no-border { border-color: transparent; } @@ -976,11 +973,21 @@ entity-menu { position: fixed; } -.active-topicmodel { - max-width: 120px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; +.navbar-collapse { + &:not(.in) { + .active-topicmodel { + max-width: 120px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + &.in { + .menu-icon { + float: left; + } + } } .stats-badges { @@ -1006,6 +1013,10 @@ entity-menu { color: #fff; cursor: default; } + .btn { + padding-left: 0; + padding-right: 0; + } } .date-compact { @@ -1088,8 +1099,31 @@ entity-menu { } } -.article-text { - padding-bottom: 40px; +.topic-group { + margin-bottom: 8px; +} + +.badge + .colorbox { + margin-left: 5px; +} + +.search-collapsed { + width: 1px !important; + padding-right: 20px !important; + background: transparent; + border: none !important; + -webkit-box-shadow: none !important; + -moz-box-shadow: none !important; + box-shadow: none !important; + cursor: pointer; +} + +#quicksearch { + transition: all .5s; +} + +.pager { + margin: 0; } [ng\:cloak], [ng-cloak], .ng-cloak { @@ -1186,9 +1220,7 @@ entity-menu { overflow: hidden!important; } .date-compact { - small { - display: block; - } + display: none; } }