Skip to content

Commit

Permalink
Add Package Versions Page (#1799)
Browse files Browse the repository at this point in the history
* initial package_versions.eml

* styling

* move styles

* padding on smaller screens

* improved collapsing on smaller screens

* unformat styles

* include publication date with version, simplify template, render publication dates

* fmt

---------

Co-authored-by: Kate Bagenzo <[email protected]>
Co-authored-by: kate-bagenzo <[email protected]>
  • Loading branch information
3 people authored Jan 12, 2024
1 parent 79bc800 commit ffbbb8b
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/global/url.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ let packages_autocomplete_fragment = "/packages/autocomplete"

module Package : sig
val overview : ?hash:string -> ?version:string -> string -> string
val versions : ?hash:string -> ?version:string -> string -> string

val documentation :
?hash:string -> ?version:string -> ?page:string -> string -> string
Expand All @@ -22,6 +23,7 @@ end = struct
with_hash hash ^ "/" ^ name ^ with_version version ^ page

let overview ?hash ?version = base ?hash ?version ""
let versions ?hash ?version = base ?hash ?version "/versions"

let documentation ?hash ?version ?(page = "index.html") =
base ?hash ?version ("/doc/" ^ page)
Expand Down
5 changes: 5 additions & 0 deletions src/ocamlorg_frontend/components/icons.eml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ let arrow_top_right_on_square class_ =
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
</svg>

let bars_3 class_ =
<svg xmlns="http://www.w3.org/2000/svg" class="<%s class_ %>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>

let beaker class_ =
<svg xmlns="http://www.w3.org/2000/svg" class="<%s class_ %>" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" />
Expand Down
8 changes: 4 additions & 4 deletions src/ocamlorg_frontend/components/package_breadcrumbs.eml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ let render_package_and_version
| Overview _ -> Url.Package.overview package.name ?version
| Documentation _ -> Url.Package.documentation package.name ?version ?hash ?page
in
let version_options v =
<% if v = package.latest_version then ( %>
let version_options (v: Package.version_with_publication_date) =
<% if v.version = package.latest_version then ( %>
<option value="<%s url None %>" <%s if package.version = Latest then "selected" else "" %>>
<%s "latest (" ^ package.latest_version ^ ")" %>
</option>
<% ); %>
<option value="<%s url (Some v) %>" <%s if package.version = Specific v then "selected" else "" %>>
<%s v %>
<option value="<%s url (Some v.version) %>" <%s if package.version = Specific v.version then "selected" else "" %>>
<%s v.version %>
</option>
in
<div class="flex gap-4">
Expand Down
4 changes: 4 additions & 0 deletions src/ocamlorg_frontend/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ body {
word-wrap: break-word;
}

.prose {
word-wrap: break-word;
}

.prose [id] {
scroll-margin-top: 2rem;
}
Expand Down
8 changes: 8 additions & 0 deletions src/ocamlorg_frontend/dune
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@
%{dep:package_documentation.eml}
--workspace
%{workspace_root})))
(rule
(target package_versions.ml)
(action
(run
%{bin:dream_eml}
%{dep:package_versions.eml}
--workspace
%{workspace_root})))
(rule
(target packages.ml)
(action
Expand Down
1 change: 1 addition & 0 deletions src/ocamlorg_frontend/ocamlorg_frontend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ let package_overview_file = Package_overview.render_file
let packages_autocomplete_fragment = Packages_autocomplete_fragment.render
let packages = Packages.render
let packages_search = Packages_search.render
let package_versions = Package_versions.render
let page = Page.render
let papers = Papers.render
let platform = Platform.render
Expand Down
3 changes: 2 additions & 1 deletion src/ocamlorg_frontend/package.ml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
type version = Latest | Specific of string
type documentation_status = Success | Failure | Unknown
type version_with_publication_date = { version : string; publication : float }

type package = {
name : string;
synopsis : string;
description : string;
license : string;
version : version;
versions : string list;
versions : version_with_publication_date list;
latest_version : string;
tags : string list;
rev_deps : string list;
Expand Down
1 change: 1 addition & 0 deletions src/ocamlorg_frontend/pages/package_overview.eml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ in
<%s! side_box_link ~icon_html:(Icons.license "h-4 w-4 mr-2 inline-block") ~href:(Url.Package.file package.name ?version ~filepath:(license_filename ^ ".html")) ~title:( package.license ^ " License") %>
<% | _ -> ()); %>
<%s! side_box_link ~icon_html:(Icons.edit "h-4 w-4 mr-2 inline-block") ~href:(Url.github_opam_file package.name specific_version) ~title:"Edit opam file" %>
<%s! side_box_link ~icon_html:(Icons.tag "h-4 w-4 mr-2 inline-block") ~href:(Url.Package.file package.name ~filepath:("versions")) ~title: ( "Versions (" ^ string_of_int (List.length package.versions) ^ ")") %>
</div>

<h2 class="mt-8 font-semibold text-base text-legacy-lighter">Authors</h2>
Expand Down
50 changes: 50 additions & 0 deletions src/ocamlorg_frontend/pages/package_versions.eml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
let render
(package : Package.package)
=
Layout.render
~title:(Printf.sprintf "%s Versions" package.name)
~description:"Package Versions" @@
let version = Package.specific_version package in
<div class="bg-default dark:bg-dark-default py-8">
<div class="container-fluid flex items-center gap-2">
<a href="/p/<%s package.name %>" class="h-11 w-11 m-5 border-primary border-2 rounded-full flex items-center justify-center"><%s! Icons.arrow_left "h-6 w-6 text-primary"; %></a>
<h1 class="text-2xl font-medium"><%s package.name %> Versions (<%i List.length package.versions %>) </h1>
</div>
<div class="container-fluid flex justify-center">
<table class="table-auto border-separate border-spacing-y-6">
<thead class="container-fluid text-md text-lighter text-left">
<tr class="py-4">
<th class="hidden sm:table-cell text-left font-normal border-b-2 border-gray-200 py-4 pl-3 md:pr-14"><%s! Icons.bars_3 "h-5 w-5"; %></th>
<th class="text-left font-normal border-b-2 border-gray-200 px-5 md:pr-12">Version</th>
<th class="text-left font-normal border-b-2 border-gray-200 md:pr-14">Release Date</th>
<th class="text-left font-normal border-b-2 border-gray-200 px-5 md:pr-14">Links</th>
</tr>
</thead>
<tbody>
<% package.versions |> List.iter (fun (item: Package.version_with_publication_date) -> %>
<tr class="tr-selected">
<td class="hidden sm:table-cell text-left font-normal py-5 px-4 <%s if version = item.version then "bg-primary-200 rounded-l" else "" %>">
<% if version = item.version then ( %><div class="bg-primary h-3 w-3 rounded-full"></div><% ) else ( %><div class="bg-gray-200 h-2 w-2 rounded-full ml-0.5"></div><% ); %>
<div class="absolute h-[4.5rem] pl-1">
<% if List.nth package.versions (List.length package.versions -1) <> item then ( %>
<div class="-ml-px w-1 border-solid border-r-2 border-gray-200 h-full"></div>
<% ); %>
</div>
</td>
<td class="text-left bg-primary-200">
<a href="/p/<%s package.name %>/<%s item.version %>" class="p-5 hover:no-underline hover:text-primary focus:text-primary focus:no-underline <%s if version = item.version then "font-bold focus:font-bold" else "" %> text-base md:mr-10">
<%s item.version %>
</a>
</td>
<td class="pr-4 text-left text-sm bg-primary-200">
<%s Utils.human_date_of_timestamp item.publication %>
</td>
<td class="text-left text-sm bg-primary-200 rounded-r">
<a href="/p/<%s package.name %>/<%s item.version %>/doc/index.html" class="text-primary flex items-center p-2 font-medium sm:p-4"><%s! Icons.document "h-5 w-5"; %> Documentation</a>
</td>
</tr>
<% ); %>
</tbody>
</table>
</div>
</div>
16 changes: 13 additions & 3 deletions src/ocamlorg_package/lib/ocamlorg_package.ml
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,19 @@ let get_by_name t name =
|> Option.map Version.Map.bindings
|> Option.map (List.map (fun (version, info) -> { name; version; info }))

type version_with_publication_date = {
version : Version.t;
publication : float;
}

let get_versions t name =
t.packages |> Name.Map.find_opt name
|> Option.map (fun p -> p |> Version.Map.bindings |> List.rev_map fst)
|> Option.map (fun p ->
p |> Version.Map.bindings
|> List.map (fun (version, info) ->
{ version; publication = info.Info.publication }))
|> Option.value ~default:[]
|> List.sort (fun v1 v2 -> Version.compare v2.version v1.version)

let get_latest t name = get_latest' t.packages name

Expand Down Expand Up @@ -404,8 +414,8 @@ let latest_documented_version t name =
| None -> aux (List.tl vlist))
in
match get_versions t name with
| None -> Lwt.return None
| Some vlist -> aux vlist
| [] -> Lwt.return None
| vlist -> aux (vlist |> List.map (fun v -> v.version))

let is_latest_version t name version =
match get_latest t name with
Expand Down
7 changes: 6 additions & 1 deletion src/ocamlorg_package/lib/ocamlorg_package.mli
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,12 @@ val stats : state -> Statistics.t option
val get_by_name : state -> Name.t -> t list option
(** Get the list of packages with the given name. *)

val get_versions : state -> Name.t -> Version.t list option
type version_with_publication_date = {
version : Version.t;
publication : float;
}

val get_versions : state -> Name.t -> version_with_publication_date list
(** Get the list of versions for a package name, newest coming first. *)

val get_latest : state -> Name.t -> t option
Expand Down
18 changes: 14 additions & 4 deletions src/ocamlorg_web/lib/handler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ let changelog req =
Data.Changelog.all
|> List.concat_map (fun (change : Data.Changelog.t) -> change.tags)
|> List.sort_uniq String.compare
|> List.sort_uniq String.compare
in
let changes =
match current_tag with
Expand Down Expand Up @@ -472,9 +471,12 @@ module Package_helper = struct
(** Query all the versions of a package. *)
let versions state name =
Ocamlorg_package.get_versions state name
|> Option.value ~default:[]
|> List.sort (Fun.flip Ocamlorg_package.Version.compare)
|> List.map Ocamlorg_package.Version.to_string
|> List.map (fun (v : Ocamlorg_package.version_with_publication_date) ->
Ocamlorg_frontend.Package.
{
version = Ocamlorg_package.Version.to_string v.version;
publication = v.publication;
})

let frontend_package ?on_latest_url state (package : Ocamlorg_package.t) :
Ocamlorg_frontend.Package.package =
Expand Down Expand Up @@ -788,6 +790,14 @@ let package_overview t kind req =
(Ocamlorg_frontend.package_overview ~sidebar_data ~readme
~search_index_digest ~toc ~deps_and_conflicts frontend_package)

let package_versions t _kind req =
let name = Ocamlorg_package.Name.of_string @@ Dream.param req "name" in
let version_from_url = Dream.param req "version" in
let</>? _package, frontend_package =
Package_helper.of_name_version t name version_from_url
in
Dream.html (Ocamlorg_frontend.package_versions frontend_package)

let package_documentation t kind req =
let name = Ocamlorg_package.Name.of_string @@ Dream.param req "name" in
let version_from_url = Dream.param req "version" in
Expand Down
6 changes: 6 additions & 0 deletions src/ocamlorg_web/lib/router.ml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ let package_route t =
Dream.get
(Url.Package.overview ~hash:":hash" ":name" ~version:":version")
((Handler.package_overview t) Handler.Universe);
Dream.get
(Url.Package.versions ":name" ~version:":version")
((Handler.package_versions t) Handler.Universe);
Dream.get
(Url.Package.versions ~hash:":hash" ":name" ~version:":version")
((Handler.package_versions t) Handler.Universe);
Dream.get
(Url.Package.documentation ":name" ~version:":version" ~page:"**")
((Handler.package_documentation t) Handler.Package);
Expand Down

0 comments on commit ffbbb8b

Please sign in to comment.