Skip to content

Commit 14aa08d

Browse files
Add sort by deadline and sort by event date buttons (#15)
* Add sort by deadline and sort by event date buttons - Add two toggle buttons (Deadline / Event Date) next to Clear Filters - Deadline sort is the default and mirrors existing behaviour - Event date sort parses the free-text date field with moment.js and reorders events by conference start date; TBA entries sort last - Refactor inline sort logic into reorderConfs(sortMode) for reuse - Add Gemfile (jekyll + webrick) for local Docker preview and CI - Add GitHub Actions workflows: deploy to gh-pages on main push, PR preview at /preview/pr-N/ with auto-comment, cleanup on close - Update .gitignore to exclude _site/, .bundle/, .jekyll-cache/ * Fix Gemfile.lock platform for GitHub Actions (add x86_64-linux)
1 parent 834f144 commit 14aa08d

9 files changed

Lines changed: 277 additions & 32 deletions

File tree

.github/workflows/cleanup.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Cleanup Preview
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
cleanup:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
with:
16+
ref: gh-pages
17+
18+
- name: Remove preview directory
19+
run: |
20+
if [ -d "preview/pr-${{ github.event.number }}" ]; then
21+
git config user.name "github-actions[bot]"
22+
git config user.email "github-actions[bot]@users.noreply.github.com"
23+
git rm -rf "preview/pr-${{ github.event.number }}"
24+
git commit -m "Remove preview for PR #${{ github.event.number }}"
25+
git push
26+
else
27+
echo "No preview directory found, skipping."
28+
fi

.github/workflows/deploy.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
deploy:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- uses: ruby/setup-ruby@v1
17+
with:
18+
ruby-version: '3.1'
19+
bundler-cache: true
20+
21+
- name: Build site
22+
run: bundle exec jekyll build
23+
24+
- name: Deploy to gh-pages
25+
uses: peaceiris/actions-gh-pages@v4
26+
with:
27+
github_token: ${{ secrets.GITHUB_TOKEN }}
28+
publish_dir: ./_site

.github/workflows/preview.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: PR Preview
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
preview:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: ruby/setup-ruby@v1
18+
with:
19+
ruby-version: '3.1'
20+
bundler-cache: true
21+
22+
- name: Build preview
23+
run: bundle exec jekyll build --baseurl "/preview/pr-${{ github.event.number }}"
24+
25+
- name: Deploy preview to gh-pages
26+
uses: peaceiris/actions-gh-pages@v4
27+
with:
28+
github_token: ${{ secrets.GITHUB_TOKEN }}
29+
publish_dir: ./_site
30+
destination_dir: preview/pr-${{ github.event.number }}
31+
32+
- name: Post preview comment
33+
uses: actions/github-script@v7
34+
with:
35+
script: |
36+
const url = `https://mpc-deadlines.github.io/preview/pr-${{ github.event.number }}/`;
37+
const body = `## Preview deployed\n\n🔍 **${url}**\n\n_Updates automatically on each push to this PR._`;
38+
39+
const { data: comments } = await github.rest.issues.listComments({
40+
owner: context.repo.owner,
41+
repo: context.repo.repo,
42+
issue_number: context.issue.number,
43+
});
44+
45+
const existing = comments.find(c =>
46+
c.user.type === 'Bot' && c.body.includes('Preview deployed')
47+
);
48+
49+
if (existing) {
50+
await github.rest.issues.updateComment({
51+
owner: context.repo.owner,
52+
repo: context.repo.repo,
53+
comment_id: existing.id,
54+
body,
55+
});
56+
} else {
57+
await github.rest.issues.createComment({
58+
owner: context.repo.owner,
59+
repo: context.repo.repo,
60+
issue_number: context.issue.number,
61+
body,
62+
});
63+
}

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11

22
.DS_Store
33
static/.DS_Store
4-
static/.DS_Store
54
.phcode.json
5+
_site/
6+
.bundle/
7+
.jekyll-cache/

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
source "https://rubygems.org"
2+
gem "jekyll", "~> 4.2"
3+
gem "webrick"

Gemfile.lock

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
addressable (2.9.0)
5+
public_suffix (>= 2.0.2, < 8.0)
6+
base64 (0.3.0)
7+
bigdecimal (4.1.2)
8+
colorator (1.1.0)
9+
concurrent-ruby (1.3.6)
10+
csv (3.3.5)
11+
em-websocket (0.5.3)
12+
eventmachine (>= 0.12.9)
13+
http_parser.rb (~> 0)
14+
eventmachine (1.2.7)
15+
ffi (1.17.4-x86_64-linux-musl)
16+
forwardable-extended (2.6.0)
17+
google-protobuf (4.34.1-x86_64-linux-musl)
18+
bigdecimal
19+
rake (~> 13.3)
20+
http_parser.rb (0.8.1)
21+
i18n (1.14.8)
22+
concurrent-ruby (~> 1.0)
23+
jekyll (4.4.1)
24+
addressable (~> 2.4)
25+
base64 (~> 0.2)
26+
colorator (~> 1.0)
27+
csv (~> 3.0)
28+
em-websocket (~> 0.5)
29+
i18n (~> 1.0)
30+
jekyll-sass-converter (>= 2.0, < 4.0)
31+
jekyll-watch (~> 2.0)
32+
json (~> 2.6)
33+
kramdown (~> 2.3, >= 2.3.1)
34+
kramdown-parser-gfm (~> 1.0)
35+
liquid (~> 4.0)
36+
mercenary (~> 0.3, >= 0.3.6)
37+
pathutil (~> 0.9)
38+
rouge (>= 3.0, < 5.0)
39+
safe_yaml (~> 1.0)
40+
terminal-table (>= 1.8, < 4.0)
41+
webrick (~> 1.7)
42+
jekyll-sass-converter (3.1.0)
43+
sass-embedded (~> 1.75)
44+
jekyll-watch (2.2.1)
45+
listen (~> 3.0)
46+
json (2.19.5)
47+
kramdown (2.5.2)
48+
rexml (>= 3.4.4)
49+
kramdown-parser-gfm (1.1.0)
50+
kramdown (~> 2.0)
51+
liquid (4.0.4)
52+
listen (3.10.0)
53+
logger
54+
rb-fsevent (~> 0.10, >= 0.10.3)
55+
rb-inotify (~> 0.9, >= 0.9.10)
56+
logger (1.7.0)
57+
mercenary (0.4.0)
58+
pathutil (0.16.2)
59+
forwardable-extended (~> 2.6)
60+
public_suffix (6.0.2)
61+
rake (13.4.2)
62+
rb-fsevent (0.11.2)
63+
rb-inotify (0.11.1)
64+
ffi (~> 1.0)
65+
rexml (3.4.4)
66+
rouge (4.7.0)
67+
safe_yaml (1.0.5)
68+
sass-embedded (1.99.0)
69+
google-protobuf (~> 4.31)
70+
rake (>= 13)
71+
terminal-table (3.0.2)
72+
unicode-display_width (>= 1.1.1, < 3)
73+
unicode-display_width (2.6.0)
74+
webrick (1.9.2)
75+
76+
PLATFORMS
77+
x86_64-linux
78+
x86_64-linux-musl
79+
80+
DEPENDENCIES
81+
jekyll (~> 4.2)
82+
webrick
83+
84+
BUNDLED WITH
85+
2.3.25

index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ <h1>
9494

9595
<div class="col-xs-12">
9696
<button id="clear-filters" class="btn btn-primary">Clear Filters</button>
97+
&nbsp;&nbsp;
98+
<span class="sort-label"><b>Sort by:</b></span>
99+
<button class="btn btn-default btn-sm sort-btn active-sort" data-sort="deadline">Deadline</button>
100+
<button class="btn btn-default btn-sm sort-btn" data-sort="event-date">Event Date</button>
97101
</div>
98102

99103
</div>
@@ -110,7 +114,7 @@ <h1>
110114
<!--{% assign conf_id = conf.name | append: conf.year | append: '-' | append: i | slugify %}-->
111115
{% assign conf_type = conf.tags | join: "-" | slugify %}
112116
{% assign conf_id = conf.name | append: conf.year | append: '-' | append: conf_type | append: '-' | append: i | slugify %}
113-
<div id="{{ conf_id }}" class="conf {% for tag in conf.tags %} {{tag}} {% endfor %}">
117+
<div id="{{ conf_id }}" class="conf {% for tag in conf.tags %} {{tag}} {% endfor %}" data-conf-date="{{ conf.date }}" data-conf-year="{{ conf.year }}">
114118
<div class="row">
115119
<div class="col-xs-12 col-sm-6">
116120
<a class="conf-title" href="{{conf.link}}" target="_blank">{{conf.name}} {{conf.year}}</a>

static/css/styles.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,16 @@ h2 .evtname {
99

1010
.past {
1111
opacity: 0.5;
12+
}
13+
14+
.sort-label {
15+
margin-left: 10px;
16+
margin-right: 5px;
17+
vertical-align: middle;
18+
}
19+
20+
.sort-btn.active-sort {
21+
background-color: #337ab7;
22+
color: #fff;
23+
border-color: #2e6da4;
1224
}

static/js/main.js

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -82,39 +82,59 @@ $(function() {
8282

8383
// Reorder list
8484
var today = moment();
85-
var confs = $('.conf').detach();
86-
87-
confs.sort(function(a, b) {
88-
var aDeadline = deadlineByConf[a.id];
89-
var bDeadline = deadlineByConf[b.id];
90-
var aDiff = today.diff(aDeadline);
91-
var bDiff = today.diff(bDeadline);
92-
if (aDiff < 0 && bDiff > 0) {
93-
return -1;
94-
}
95-
if (aDiff > 0 && bDiff < 0) {
96-
return 1;
97-
}
98-
return bDiff - aDiff;
99-
});
100-
101-
var pastConfs = [];
102-
var upcomingConfs = [];
103-
104-
confs.each(function() {
105-
var conf = $(this);
10685

107-
if (conf.hasClass("past")) {
108-
pastConfs.push(conf);
86+
function getEventStartDate(confEl) {
87+
var dateStr = $(confEl).data('conf-date');
88+
var year = $(confEl).data('conf-year');
89+
if (!dateStr || String(dateStr).toLowerCase().indexOf('tba') === 0) return null;
90+
// Handle "June 29 - July 03" → "June 29"; handle "November 15-19" → "November 15"
91+
var firstPart = String(dateStr).split(' - ')[0].replace(/-\d+$/, '').trim();
92+
var parsed = moment(firstPart + ' ' + year, 'MMMM D YYYY');
93+
return parsed.isValid() ? parsed : null;
94+
}
95+
96+
function renderConfs(sortMode) {
97+
var confs = $('.conf-container .conf, #past-events-list .conf').detach();
98+
99+
if (sortMode === 'event-date') {
100+
confs.sort(function(a, b) {
101+
var aDate = getEventStartDate(a);
102+
var bDate = getEventStartDate(b);
103+
if (!aDate && !bDate) return 0;
104+
if (!aDate) return 1;
105+
if (!bDate) return -1;
106+
return aDate.diff(bDate);
107+
});
109108
} else {
110-
upcomingConfs.push(conf);
109+
confs.sort(function(a, b) {
110+
var aDeadline = deadlineByConf[a.id];
111+
var bDeadline = deadlineByConf[b.id];
112+
var aDiff = today.diff(aDeadline);
113+
var bDiff = today.diff(bDeadline);
114+
if (aDiff < 0 && bDiff > 0) return -1;
115+
if (aDiff > 0 && bDiff < 0) return 1;
116+
return bDiff - aDiff;
117+
});
111118
}
112-
});
113-
114-
//$('.conf-container').append(confs);
115-
$('.conf-container').append(upcomingConfs);
116-
$('#past-events-list').append(pastConfs);
117-
119+
120+
var pastConfs = [];
121+
var upcomingConfs = [];
122+
confs.each(function() {
123+
($(this).hasClass('past') ? pastConfs : upcomingConfs).push(this);
124+
});
125+
126+
$('.conf-container').append(upcomingConfs);
127+
$('#past-events-list').append(pastConfs);
128+
}
129+
130+
renderConfs('deadline');
131+
132+
$('.sort-btn').click(function() {
133+
$('.sort-btn').removeClass('active-sort');
134+
$(this).addClass('active-sort');
135+
renderConfs($(this).data('sort'));
136+
});
137+
118138
// Toggle past events visibility
119139
$(".past-deadlines").click(function() {
120140
$("#past-events-list").slideToggle();

0 commit comments

Comments
 (0)