Skip to content

Commit 2f9a4ee

Browse files
authored
Solves #1029 - Adds paging to recent packages and recent revisions (#1055)
paging on recent packages and uploads
1 parent 0a2ffe8 commit 2f9a4ee

File tree

9 files changed

+382
-166
lines changed

9 files changed

+382
-166
lines changed

datafiles/static/browse.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,17 @@ const createPageLink = (num) => {
253253
return a;
254254
};
255255

256-
const createPrevNext = (prevNextNum, cond, txt) => {
257-
const el = d.createElement(cond ? "span" : "a");
258-
el.setAttribute("href", "#");
259-
el.addEventListener('click', (evt) => {
260-
evt.preventDefault();
261-
changePage(prevNextNum);
262-
});
263-
if (cond) el.classList.add("disabled");
256+
const createPrevNext = (prevNextNum, hasLink, txt) => {
257+
const el = d.createElement("a");
258+
259+
if(hasLink) {
260+
el.setAttribute("href", "#");
261+
el.addEventListener('click', (evt) => {
262+
evt.preventDefault();
263+
changePage(prevNextNum);
264+
});
265+
}
266+
264267
el.appendChild(d.createTextNode(txt));
265268
return el;
266269
};
@@ -276,7 +279,7 @@ const createPaginator = () => {
276279

277280
const pag = d.createElement("div");
278281
pag.classList.add("paginator");
279-
pag.appendChild(createPrevNext(state.page - 1, state.page === 0, "Previous"));
282+
pag.appendChild(createPrevNext(state.page - 1, state.page !== 0, "Previous"));
280283
// note that page is zero-indexed
281284
if (maxPage <= 4) {
282285
// No ellipsis
@@ -308,7 +311,8 @@ const createPaginator = () => {
308311
pag.appendChild(createPageLink(maxPage));
309312
}
310313
const isNowOnLastPage = state.page === maxPage;
311-
pag.appendChild(createPrevNext(state.page + 1, isNowOnLastPage, "Next"));
314+
315+
pag.appendChild(createPrevNext(state.page + 1, !isNowOnLastPage, "Next"));
312316

313317
return pag;
314318
};

datafiles/static/hackage.css

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,3 +1044,55 @@ a.deprecated[href]:visited {
10441044
.versions a.normal[href]:visited {
10451045
color: #61B01E;
10461046
}
1047+
1048+
/* Paginator */
1049+
#paginatorContainer {
1050+
display: flex;
1051+
align-items: center;
1052+
flex-wrap: wrap;
1053+
justify-content: space-between;
1054+
}
1055+
1056+
#paginatorContainer > div {
1057+
padding: 1em 0;
1058+
}
1059+
1060+
.paginator {
1061+
display: flex;
1062+
flex-wrap: wrap;
1063+
}
1064+
1065+
/* Styles Next/Prev when they have no href */
1066+
.paginator a {
1067+
color: #666;
1068+
cursor: default;
1069+
background: none;
1070+
border: none;
1071+
padding: 0.5em 1em;
1072+
text-decoration: none;
1073+
}
1074+
1075+
.paginator span {
1076+
color: #333;
1077+
padding: 0.5em 1em;
1078+
}
1079+
1080+
.paginator a:link, .paginator a:visited {
1081+
color: #333;
1082+
border: 1px solid transparent;
1083+
border-radius: 2px;
1084+
}
1085+
1086+
.paginator a:link:hover, .paginator a:visited:hover {
1087+
color: white;
1088+
border: 1px solid #111;
1089+
background: linear-gradient(to bottom, #585858 0%, #111 100%);
1090+
text-decoration: none;
1091+
}
1092+
1093+
.paginator .current,
1094+
.paginator .current:hover {
1095+
color: #333;
1096+
border: 1px solid #979797;
1097+
background: linear-gradient(to bottom, #fff 0%, #dcdcdc 100%);
1098+
}

datafiles/templates/Html/browse.html.st

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -51,38 +51,6 @@
5151
#browseTable th.descending {
5252
background-image: url(/static/images/sort_desc.png);
5353
}
54-
.paginator {
55-
margin-left: auto;
56-
}
57-
.paginator a {
58-
box-sizing: border-box;
59-
display: inline-block;
60-
min-width: 1.5em;
61-
padding: 0.5em 1em;
62-
margin-left: 2px;
63-
text-align: center;
64-
text-decoration: none !important;
65-
color: #333 !important;
66-
border: 1px solid transparent;
67-
border-radius: 2px;
68-
}
69-
.paginator .current, .paginator .current:hover {
70-
color: #333 !important;
71-
border: 1px solid #979797;
72-
background: linear-gradient(to bottom, #fff 0%, #dcdcdc 100%);
73-
}
74-
.paginator a:hover {
75-
color: white !important;
76-
border: 1px solid #111;
77-
background: linear-gradient(to bottom, #585858 0%, #111 100%);
78-
}
79-
.paginator span {
80-
padding: 0 1em;
81-
cursor: default;
82-
}
83-
.paginator .disabled {
84-
color: #666;
85-
}
8654
.filterSuggestion {
8755
display: flex;
8856
align-items: center;
@@ -102,11 +70,6 @@
10270
.filterSuggestion > div > input {
10371
margin: 0;
10472
}
105-
#paginatorContainer {
106-
display: flex;
107-
align-items: center;
108-
flex-wrap: wrap;
109-
}
11073
#fatalError {
11174
display: none;
11275
color: red;

hackage-server.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ library lib-server
266266
Distribution.Server.Util.Merge
267267
Distribution.Server.Util.ParseSpecVer
268268
Distribution.Server.Util.Markdown
269+
Distribution.Server.Util.Paging
269270

270271
Distribution.Server.Features
271272
Distribution.Server.Features.Browse

src/Distribution/Server/Features.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ initHackageFeatures env@ServerEnv{serverVerbosity = verbosity} = do
193193
tarIndexCacheFeature
194194
usersFeature
195195

196-
packagesFeature <- mkRecentPackagesFeature
196+
recentPackagesFeature <- mkRecentPackagesFeature
197197
usersFeature
198198
coreFeature
199199

@@ -313,6 +313,8 @@ initHackageFeatures env@ServerEnv{serverVerbosity = verbosity} = do
313313
tarIndexCacheFeature
314314
reportsCoreFeature
315315
userDetailsFeature
316+
recentPackagesFeature
317+
316318

317319
editCabalFeature <- mkEditCabalFilesFeature
318320
usersFeature
@@ -371,7 +373,7 @@ initHackageFeatures env@ServerEnv{serverVerbosity = verbosity} = do
371373
#ifndef MINIMAL
372374
, getFeatureInterface tarIndexCacheFeature
373375
, getFeatureInterface packageContentsFeature
374-
, getFeatureInterface packagesFeature
376+
, getFeatureInterface recentPackagesFeature
375377
, getFeatureInterface userDetailsFeature
376378
, getFeatureInterface userSignupFeature
377379
, getFeatureInterface legacyPasswdsFeature

src/Distribution/Server/Features/Html.hs

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ import qualified Text.XHtml.Strict as XHtml
7676
import Text.XHtml.Table (simpleTable)
7777
import Distribution.PackageDescription (hasLibs)
7878
import Distribution.PackageDescription.Configuration (flattenPackageDescription)
79+
import qualified Distribution.Server.Pages.Recent as Pages
80+
import qualified Distribution.Server.Util.Paging as Paging
81+
import Distribution.Server.Features.RecentPackages (RecentPackagesFeature (RecentPackagesFeature, getRecentRevisions, getRecentPackages))
82+
import Data.Time (getCurrentTime)
83+
import Text.Read (readMaybe)
7984
import Distribution.Server.Pages.Group (listGroupCompact)
8085

8186

@@ -115,6 +120,7 @@ initHtmlFeature :: ServerEnv
115120
-> TarIndexCacheFeature
116121
-> ReportsFeature
117122
-> UserDetailsFeature
123+
-> RecentPackagesFeature
118124
-> IO HtmlFeature)
119125

120126
initHtmlFeature env@ServerEnv{serverTemplatesDir, serverTemplatesMode,
@@ -153,7 +159,8 @@ initHtmlFeature env@ServerEnv{serverTemplatesDir, serverTemplatesMode,
153159
docsCore docsCandidates
154160
tarIndexCache
155161
reportsCore
156-
usersdetails -> do
162+
usersdetails
163+
recentPackagesFeature -> do
157164
-- do rec, tie the knot
158165
rec let (feature, packageIndex, packagesPage) =
159166
htmlFeature env user core
@@ -172,6 +179,7 @@ initHtmlFeature env@ServerEnv{serverTemplatesDir, serverTemplatesMode,
172179
(reverseHtmlUtil reversef)
173180
mainCache namesCache
174181
templates
182+
recentPackagesFeature
175183

176184
-- Index page caches
177185
mainCache <- newAsyncCacheNF packageIndex
@@ -224,6 +232,7 @@ htmlFeature :: ServerEnv
224232
-> AsyncCache Response
225233
-> AsyncCache Response
226234
-> Templates
235+
-> RecentPackagesFeature
227236
-> (HtmlFeature, IO Response, IO Response)
228237

229238
htmlFeature env@ServerEnv{..}
@@ -245,6 +254,7 @@ htmlFeature env@ServerEnv{..}
245254
reverseH@ReverseHtmlUtil{..}
246255
cachePackagesPage cacheNamesPage
247256
templates
257+
recentPackagesFeature
248258
= (HtmlFeature{..}, packageIndex, packagesPage)
249259
where
250260
htmlFeatureInterface = (emptyHackageFeature "html") {
@@ -288,6 +298,7 @@ htmlFeature env@ServerEnv{..}
288298
templates
289299
names
290300
candidates
301+
recentPackagesFeature
291302
htmlUsers = mkHtmlUsers user usersdetails
292303
htmlUploads = mkHtmlUploads utilities upload
293304
htmlDocUploads = mkHtmlDocUploads utilities core docsCore templates
@@ -419,6 +430,7 @@ mkHtmlCore :: ServerEnv
419430
-> Templates
420431
-> SearchFeature
421432
-> PackageCandidatesFeature
433+
-> RecentPackagesFeature
422434
-> HtmlCore
423435
mkHtmlCore ServerEnv{serverBaseURI, serverBlobStore}
424436
utilities@HtmlUtilities{..}
@@ -448,10 +460,11 @@ mkHtmlCore ServerEnv{serverBaseURI, serverBlobStore}
448460
templates
449461
SearchFeature{..}
450462
PackageCandidatesFeature{..}
463+
RecentPackagesFeature{getRecentPackages, getRecentRevisions}
451464
= HtmlCore{..}
452465
where
453466
candidatesCore = candidatesCoreResource
454-
cores@CoreResource{packageInPath, lookupPackageName, lookupPackageId} = coreResource
467+
cores@CoreResource {packageInPath, lookupPackageName, lookupPackageId} = coreResource
455468
versions = versionsResource
456469
docs = documentationResource
457470

@@ -505,8 +518,76 @@ mkHtmlCore ServerEnv{serverBaseURI, serverBlobStore}
505518
, (resourceAt "/package/:package/revisions/.:format") {
506519
resourceGet = [("html", serveCabalRevisionsPage)]
507520
}
521+
, (resourceAt "/packages/recent.:format") {
522+
resourceGet = [("html", serveRecentPage),("rss", serveRecentRSS)]
523+
}
524+
, (resourceAt "/packages/recent/revisions.:format") {
525+
resourceGet = [("html", serveRevisionPage), ("rss", serveRevisionRSS)]
526+
}
508527
]
509528

529+
readParamWithDefaultAndValid :: (Read a, HasRqData m, Monad m, Functor m, Alternative m) =>
530+
a -> (a -> Bool) -> String -> m a
531+
readParamWithDefaultAndValid n f queryParam = do
532+
m <- optional (look queryParam)
533+
let parsed = m >>= readMaybe >>= (\x -> if f x then Just x else Nothing)
534+
535+
return $ fromMaybe n parsed
536+
537+
lookupPageSize :: (HasRqData m, Monad m, Functor m, Alternative m) => Int -> m Int
538+
lookupPageSize def = readParamWithDefaultAndValid def validPageSize "pageSize"
539+
where validPageSize x = x > 1 && x <= 200
540+
541+
lookupPage :: (HasRqData m, Monad m, Functor m, Alternative m) => Int -> m Int
542+
lookupPage def = readParamWithDefaultAndValid def validPage "page"
543+
where validPage = (>= 1)
544+
545+
serveRecentPage :: DynamicPath -> ServerPartE Response
546+
serveRecentPage _ = do
547+
recentPackages <- getRecentPackages
548+
users <- queryGetUserDb
549+
page <- lookupPage 1
550+
pageSize <- lookupPageSize 20
551+
552+
let conf = Paging.createConf page pageSize recentPackages
553+
554+
return . toResponse $ Pages.recentPage conf users recentPackages
555+
556+
serveRecentRSS :: DynamicPath -> ServerPartE Response
557+
serveRecentRSS _ = do
558+
recentPackages <- getRecentPackages
559+
users <- queryGetUserDb
560+
page <- lookupPage 1
561+
pageSize <- lookupPageSize 20
562+
now <- liftIO getCurrentTime
563+
564+
let conf = Paging.createConf page pageSize recentPackages
565+
566+
return . toResponse $ Pages.recentFeed conf users serverBaseURI now recentPackages
567+
568+
serveRevisionPage :: DynamicPath -> ServerPartE Response
569+
serveRevisionPage _ = do
570+
revisions <- getRecentRevisions
571+
users <- queryGetUserDb
572+
page <- lookupPage 1
573+
pageSize <- lookupPageSize 40
574+
575+
let conf = Paging.createConf page pageSize revisions
576+
577+
return . toResponse $ Pages.revisionsPage conf users revisions
578+
579+
serveRevisionRSS :: DynamicPath -> ServerPartE Response
580+
serveRevisionRSS _ = do
581+
revisions <- getRecentRevisions
582+
users <- queryGetUserDb
583+
page <- lookupPage 1
584+
pageSize <- lookupPageSize 40
585+
now <- liftIO getCurrentTime
586+
587+
let conf = Paging.createConf page pageSize revisions
588+
589+
return . toResponse $ Pages.recentRevisionsFeed conf users serverBaseURI now revisions
590+
510591
serveBrowsePage :: DynamicPath -> ServerPartE Response
511592
serveBrowsePage _dpath = do
512593
template <- getTemplate templates "browse.html"

0 commit comments

Comments
 (0)