Skip to content

Commit

Permalink
Feature/investigate plain js solutions (#6)
Browse files Browse the repository at this point in the history
* initial thoughts

* minor cleanup

* trying to figure out initial file structure

* initial pass on a timeline

* chaser

* initial copies from the odin-recipe repo

* fixing missing choices when choice is not a dictionary

* cleaning up some annoying UI bugs

* cleaning up some kerning issues

* initial pass at a landing page stub - TBD if it works

* cut/paste/edit error

* recording the vote progress - plurality works TBD

* more work on plurality and RCV vote recording

* more UI debugging - at least one more RCV to go

* regardless of selected node, always use the li node for selection

* figuring out a direction for the checkout page

* the checkout page has a heartbeat; UI not done yet

* initial second-pass at a selection flexbox

* checkpoint on better progressBar color handling

* more layout cleanup

* like programming in assembly with toggle switches ...

* restoring plurality contests seems to work

* getting RCV to restore selection

* fixing next button text

* cleaning up more checkout text

* progress regarding back navigation

* adding progress bar navigation

* random checkpoint - still need to add vote buttons

* adding vote buttons (for milestone 2 functionality only)

* chaser
  • Loading branch information
windoverwater authored Mar 7, 2024
1 parent 6df98cf commit 867fcf1
Show file tree
Hide file tree
Showing 8 changed files with 1,324 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Emacs
*~
.#*
\#*\#
TAGS

# Mac
.DS_Store

# pytest
__pycache__
.pytest_cache

# Ignore python local install build symlinks et al
.venv
poetry.lock
38 changes: 38 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Ancient Makefile implicit rule disabler
(%): %
%:: %,v
%:: RCS/%,v
%:: s.%
%:: SCCS/s.%
%.out: %
%.c: %.w %.ch
%.tex: %.w %.ch
%.mk:

# Variables
DOC_DIR := docs
SRC_DIR := .
TEST_DIR := tests

# Use colors for errors and warnings when in an interactive terminal
INTERACTIVE := $(shell test -t 0 && echo 1)
ifdef INTERACTIVE
RED := \033[0;31m
END := \033[0m
else
RED :=
END :=
endif

# Let there be no default target
.PHONY: default
default:
@echo "${RED}There is no default make target.${END} Specify one of:"
@echo "etags - constructs an emacs tags table"
@echo ""
@echo "See ${BUILD_DIR}/README.md for more details and info"

# emacs tags (for javascript need GNU's universal-ctag package)
.PHONY: etags
etags:
/opt/homebrew/bin/ctags -e -R --language-force=javascript
75 changes: 75 additions & 0 deletions docs/DesignNotes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# VoteTracker+ Client Side UI/UX Design Notes

## User Story 1 - landing page

#### What happens when a client (smart device browser of choice) initially connects to the VTP demo?

Displays a short welcome and help message that briefly explains the standard contest buttons. There is only one active button on the page, __CONTINUE__. Activating that continues to step 2.

## User Story 2 - voting

#### What happens when the voter starts to mark the ballot (votes)?

Displays the first contest. At the moment two types of contests are supported, plurality and IRV (RCV).

If plurality:
- can select up to the number of open positions by tapping the choice of interest in the vertical list
- individual choices can be de-selected by tapping again
- if more than the allowable number of choices are selected, a dialog abort window appears

If IRV/RCV:
- the vertical list of candidates is displayed below an (initially empty) vertical list of ranked/selected candidates above
- clicking an candidate from the below list adds the candidate to the bottom of the upper list and removes the candidate from the below list
- swiping a candidate left or right in the upper list will remove the candidate from the upper list and re-appear the candidate in the original order in the below list
- the upper list is draggable - the upper list can be reordered at will

Common buttons/actions/UI:

- there is a __DE-SELECT ALL__ button somewhere in the lower left portion of the page
- there is a __CONTINUE__ button somewhere in the lower right portion of the page
- if the continue button is activated and there is an undervote situation, a warning window appears that allows the user to go to the next contest or stay with the current contest
- across the top is a horizontal progress bar divided into equal width sections by contest
- each contest is clickable and takes the user to that contest
- if there is an undervote in the current contest, a proceed-able warning window appears
- in the completion bar, completed contests are solid bright green, undervote contests are solid somewhat dimm yellow, and no-vote or undervote contests that are to the left of any green or yellow contest are red outlined boxes.
- immediately below the progress bar in the left corner is a __PREVIOUS CONTEST__ button
- immediately below the progress bar in the right corner is a __NEXT CONTEST__ button
- when the last contest in focus, the upper right button says __CHECKOUT__
- when the __CHECKOUT__ box is clicked, all the contests are displayed with only two buttons: __GO BACK__ and __THIS IS MY VOTE__
- __GO BACK__ goes to the previous page with the checkout box in the upper right
- __THIS IS MY VOTE__ submits the ballot

Note that the backend python server side will re-validate the incoming ballot CVR. The __THIS IS MY VOTE__ entrypoint can return various errors to the user:

- a non compliant contest selection was found
- there was a problem on the server side

If there is no error, the endpoint returns:

- the voter's ballot check as if it were paper (no links) but with the QR code being a valid link (into the voter's backend server's still active git workspace)
- the voter's row offset into the ballot check is temporarily displayed
- in addition there is, for demo purposes only, two additional buttons on this page
- a __VERIFY BALLOT RECEIPT__ button
- a __TALLY CONTESTS__ button

## User Story 3 - inspecting the ballot check/QR code

#### What happens when the user clicks the QR code (or takes a photo of the QR code)?

Displays the git repo copy of the contents of the ballot check. All the digests are active links to the actual git digests for a specific vote for a specific contest.

## User Story 4 - verifying the ballot check

#### What happens when the user wants to verify their ballot check?

The user clicks the __VERIFY BALLOT RECEIPT__ (end of User Story 1) and a new page displays the 'console log' output of that function with digests hyperlinked. The output page contains a few by default blank fields that the user can optionally fill in. One of them is a row offset.

The page contains a __RE-VERIFY__ button that re-verifies the receipt honoring the new values in the various fields.

## User Story 5 - tallying the election

#### What happens when the user wants to tally the election?

The user clicks the __TALLY CONTESTS__ button (end of User Story 1) and a new page displays the 'console log' output of that function with digests hyperlinked. The output page contains a few by default blank fields that the user can optionally fill in. One of them is a row offset.

The page contains a __RE-TALLY CONTESTS__ button that re-tallies the election honoring the new values in the various fields.
74 changes: 74 additions & 0 deletions docs/ProjectPlan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# VoteTracker+ Client Side UI/UX Project Plan

#### 1. Background

The current design target is to create a usable client/voter frontend in a few weeks for a June 8th live demo. The date and available skill level are driving the client UI side design and implementation.

The current tech choice to achieve this is a plain html, css, and javascript implementation. The current development environment is Google's devtools, Microsoft's Visual Studio Code, and emacs :-).

See the VoteTracker+ [project page](https://github.com/orgs/TrustTheVote-Project/projects/2/views/1) for status.

#### 2. Overall VTP Git Repo Context

Summary of the VTP git repo's:

The [VTP-dev-end](https://github.com/TrustTheVote-Project/VTP-dev-env) holds/defines the development/run-time environment. Contained within VTP-dev-end as submodules are three repos:
- [VTP-mock-election.US.15](https://github.com/TrustTheVote-Project/VTP-mock-election.US.15) - contains the election configuration and data
- [VTP-web-api](https://github.com/TrustTheVote-Project/VTP-web-api) - contains the FASTapi rest interface
- [VoteTrackerPlus](https://github.com/TrustTheVote-Project/VoteTrackerPlus) - contains the python backend code

This repo, [VTP-web-client](https://github.com/TrustTheVote-Project/VTP-web-client) contains the client frontend a.k.a. the voter's /UI/UX

See [DesignNotes.md](DesignNotes.md) in this repo for details on the end user (voter) user stories

#### 3. Basic Project Plan

The basic project plan is to stub out static versions of the various pages and write the javascript to support that. Then incrementally add support for deeper integrations with the restful web-api. The web-api hopefully will not require major work at this point.

The four major milestones are:

1. Create just the controls and UI without dealing with any JSON data - just get the basic html/css/JS UI controls for the five web pages (see below) working.

2. Add JSON decoding support and integrate with static JSON data. This includes reading and sending (static) JSON to a stubbed out backend.

3. Plug in the web-api and use actual live JSON data from the web-api

4. Full end-to-end testing of the demo

#### 4. Timeline

To achieve the demo all four of the above major milestones need to be completed by end of may. Project completion means that the live demo is running without significant issues on a standalong router disconnected from any WAN. Thus:

- Completion of milestone 1: 02/21 (1 week)
- Completion of milestone 2: 03/21 (4 weeks)
- Completion of milestone 3: 04/17 (4 weeks)
- Completion of milestone 4: 05/01 (2 weeks)

which leaves 3 weeks of buffer

#### 5. File layout (this git repo <-> end user web server)

Given the decomposition into [5 user stories](./DesingNotes.md), out-of-the-gate associate different html pages with each user story.

1. index.html
- the landing page
- one js button that jumps to the (next) voting.html page
2. voting.html
- handles a single contest
- provides navigation to previous, next, other contests (same page), and to the checkout.html page
- provides progress status
3. checkout.html
- allows the voter to double check their ballot prior to casting
- does not support editing the ballot
- provides three options: spoil ballot (exit), edit ballot (back to voting.html), and submit/cast ballot
4. ballot check displaying
- either create the JS to retrieve the data from the web-api (new endpoint), creating an explicit ballot-check.html
- or standup a http server running somewhere that is pointing to the repo of interest for the demo. This would probably require changing the upstream remote git repo URI to the demo LAN local git server, which would be ok as it would completely isolate the demo.
5. verify-ballot-check.html
- handles the output of the ballot check function (basically console log output)
- supplies various end user functions associated with verify their ballot check - a UX TBD
6. tally-election.html
- handles the output of tallying the election (basically console log output)
- initial UX target is to supply a few buttons for enabling switches and converting digests to links (back to the local LAN git server or the upstream remote - see 3 above)

Regarding css and javascript, created as needed in standard locations.
33 changes: 33 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landing Page - User Story 1</title>
<style>
/* box debugging
* {
border-style: solid;
border-color: red;
}
*/
</style>
</head>
<body>
<h2>Welcome to a VoteTrackr+ Demo</h2>
<p>This is a simulated conceptual demo of what voting in an election that is
integrated with the VoteTrackr+ technology</p>
<p>You may vote as many times as you would like</p>
<p>Please click the continue button to start voting</p>
<p></p>
<p></p>
<p></p>
<button id="vote" >Vote</button>

<script>
document.getElementById("vote").onclick = function () {
window.location.href = "voting.html";
};
</script>
</body>
</html>
127 changes: 127 additions & 0 deletions javascript/blank-ballot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
const blankBallotJSON = `{
"active_ggos": [
".",
"GGOs/states/Massachusetts",
"GGOs/states/Massachusetts/GGOs/counties/Middlesex",
"GGOs/states/Massachusetts/GGOs/towns/Concord"
],
"ballot_filename": "000,001,002,003,ballot.json",
"ballot_node": "GGOs/states/Massachusetts/GGOs/towns/Concord",
"ballot_subdir": "GGOs/states/Massachusetts/GGOs/towns/Concord",
"contests": {
"GGOs/states/Massachusetts": [
{
"U.S. President": {
"choices": [
{
"name": "Circle Party Ticket",
"ticket_names": [
"Rey Skywalker",
"Obi-Wan Kenobi"
]
},
{
"name": "Square Party Ticket",
"ticket_names": [
"Atticus Finch",
"Hermione Granger"
]
},
{
"name": "Triangle Party Ticket",
"ticket_names": [
"Evelyn Quan Wang",
"Waymond Wang"
]
}
],
"contest_type": "ticket",
"max": 1,
"tally": "plurality",
"ticket_offices": [
"President",
"Vice President"
],
"uid": "0000"
}
},
{
"U.S. Senate": {
"choices": [
{
"name": "Anthony Alpha",
"party": "Circle Party"
},
{
"name": "Betty Beta",
"party": "Dyad Party"
},
{
"name": "Gloria Gamma",
"party": "Triangle Party"
},
{
"name": "David Delta",
"party": "Square Party"
},
{
"name": "Emily Echo",
"party": "Pentagon Party"
},
{
"name": "Francis Foxtrot",
"party": "Hexagon Party"
}
],
"tally": "rcv",
"uid": "0001"
}
},
{
"Governor": {
"choices": [
{
"name": "Spencer Cogswell",
"party": "Circle Party"
},
{
"name": "Cosmo Spacely",
"party": "Triangle Party"
}
],
"max": 1,
"tally": "plurality",
"uid": "0002"
}
}
],
"GGOs/states/Massachusetts/GGOs/counties/Middlesex": [
{
"County Clerk": {
"choices": [
"Jean-Luc Picard",
"Katniss Everdeen",
"James T. Kirk"
],
"max": 1,
"tally": "plurality",
"uid": "0003"
}
}
],
"GGOs/states/Massachusetts/GGOs/towns/Concord": [
{
"Question 1 - should the starting time of the annual town meeting be moved to 6:30 PM?": {
"choices": [
"yes",
"no"
],
"description": "Should the Town of Concord start the annual Town Meeting at 6:30 PM instead of 7:00 PM?",
"max": 1,
"tally": "plurality",
"uid": "0004"
}
}
]
}
}`;
Loading

0 comments on commit 867fcf1

Please sign in to comment.