Worm Counter


Clarification (Meneely sections only)
We are doing Worm Counter and Worm Counter for our client projects.

Overview

For this project, you will build a web applications using HTML, CSS, Javascript, and React.js for tracking genetics experiments. The microscopic nematode, Caenorhabditis Elegans is one of the most important multicellular organisms in the field of genetics because they have short lifespans (about two weeks), and are able to survive lab conditions maintained by modern college students.

When scientists conduct their experiments, they look through a microscope and count worms according to various atrributes. For example, if you’re studying sex determination genes in meiosis, you might want to track the ratio of males to hermaphrodites. When looking through the microscope, the scientists would lose their count if they had to write down the count, so they need a “tally counter” they can operate with just their fingers (sorta like one of these devices, but with more buttons). Let’s make a web app that simulates that so they can use their phone.

You’ll have a counter with mulitple buttons according to various attributes, and you’ll track results per petri dish, and by experiment.

Client 0: Initial Setup

Client Setup: Your first web page

Overview

Please use the branch client-0-dev and the tag client-0 for submission.

This initial assignment will introduce you to the basics of HTML and CSS. In this initial assignment, you will not need a CSS file (though you will, and if you want to start one now go head). Instead, use a <style> tag in your <head> section to specify style.

Setup

Locate your project in your group (Named client-group-x) in gitlab, and clone the project Once you clone this project, create a folder named public. All your code for this assignment will go in this folder. Inside public/, do the following: Create a file, and name it index.html - Your web markup (html) will go in this file (You can use the template below to get started)

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web Assignment 0</title>
  <meta name="description" content="First web assignment">
  <meta name="author" content="student name">
</head>
<body>
</body>
</html>

In the root directory, create a .gitlab-ci.yml file with this content:

image:
  name: node:18 #No special docker image.  Standard nodejs image from dockerhub
cache:
  paths:
  - node_modules/
before_script:
  - yarn install
  - node --version
pages:
  stage: deploy
  script:
    - ls -lFa public
  artifacts:
    paths:
    - public

This CI file will publish your webpage (index.html) to the gitlab web server.

You can find the URL (to check your webpage) on the Deploy > Pages link in your gitlab settings

Requirements

You will implement the following controls and behaviour for your webpage (index.html) Set the default font to ‘Segoe UI’ Add a title using the <h1> tag to the top of the page with the following text ‘SWEN-344 Web Assignment 0’

  • Set the font to Bold, Verdana, with a size of 36px (Use the style property) and centre the title.

Add a sub-heading with the <h2> tag.

  • The text content should be ‘Section xx’, where ‘xx’ is your section number. Set the font to “Impact”
  • Center the text.

Add a dropdown list control with the following values:

  • Lorem
  • Ipsum
  • Dolor

Use the <select> tag with those options. There should also be a default selection with an empty value (blank).

Using the ul and li elements, make a horizontal list of six rectangles.

  • Each rectangle should be least 5em high.
  • Each rectangle will have a number in large font, with smaller text below it explaining what it is.
  • Use a flex to make these spread evenly across one line.
  • No bullets should be shown
  • Make every other item in your list of number have a different background color.
  • Two of your rectangles should also have a button that stretches to the full size of the rectangle. The number and subtitle should still be in the button too.

Here’s an example of a solution:

../meneely-example-0.png

Sample Page-0

Grading

Grading: 10 points total Correct implemention for each of the controls and styles Web Page and Actions:

  • Lab day: 2 points
  • CI working: 2 points
  • Title & Headings: 2 points
  • Dropdown list: 2 points
  • Layout & Alignment: 2

Worm Counter Specifics

No project specifics for this iteration.

Client 1: Initial HTML+CSS+JS

Your branch name should be client1-dev. When you have merged, the tag should be client1.

In this iteration, we want to make a minimal version of our UI with some basic dynamic functionality.

A few things that everyone needs to pay attention to:

  • Keep your app usable on both mobile and desktop situations. Use the Dev Tools to simulate this as shown in class.
  • Avoid using style attributes; favor using CSS wherever possible

Grading

Points: 50 points

  • (10 points) Works on the CI and deployed to GitLab Pages
  • (10 points) UI displays every part requested
  • (20 points) Dynamic functionality works as expected
  • (10 points) Refactored to use CSS instead of embedded styles

Worm Counter Specifics

Your worm counter should include the following:

  • Two buttons should be large enough that someone can tap them regularly without looking
    • Every time you tap one of the buttons, the count for that category is incremented
  • A dropdown menu for the attribute you’re currently counting. Options are: maturity, sex, coordination, mutant.
    • When the dropdown is changed, the two buttons should change their names based on the attribute:
      • Maturity: Adult and Juvenile
      • Sex: Male and Hermaphrodite
      • Coordination: Coordinated and Uncoordinated
      • Mutant: Nominal and Mutant
    • Note: there will always be exactly two button counters in this project.
  • There should be text that prominently display that the current experiment is called “Blister Mutation” (this will be expanded upon in future iterations)
  • There should be text that prominently displays that we’re on Petri Dish 1 (this will be expanded upon in future iterations)
  • A “Reset Counts” button that sets the current counts to zero.
  • A “Done” button that puts the two counts into a list of experiments, grouped by experiment and petri dish. Then, sets the counts to zero.
  • A “Results” area that shows:
    • Entries of the counts, including experiment, petri dish, and both counts
    • A visual for conveying the proportion of each count. This could be something like a pie-chart (look up online on how to do CSS-only pie charts), or something similar. For example, if we have 3 Adult and 7 Juvenile, then the chart would show a 30/70 split.

Client 2: Refactor to React

Your branch name should be client2-dev. When you have merged, the tag should be client2.

Now you have seen what it looks like to have a tiny bit of dynamic functionality on a webpage, let’s start thinking bigger. Modern websites that have a lot of client-side functionality use component-based frameworks. We’ll be using React.js, which is one of the most popular ones out there today.

Our goal with this iteration is to achieve feature parity, perhaps with some improvements along the way. Your app will hopefully look and act nearly exactly as before, but will be easier to build upon for future features.

Getting Started with React

Everyone must do this part, even if you think you are familiar with React.js.

  1. Do our React Setup instructions. Be sure to review the walkthrough explanation of all the files.
  2. Review the resources available to you on the Getting Started with React. We have found these resources to be very well-written and helpful.
  3. Do ONE of these:
  • The Step-by-Step Guide. It’s longer, but highly useful. Go through these chapters: Describing the UI, Adding Interactivity, and Managing State (especially the concept of “Lifting State Up”). The last chapter, Escape Hatches isn’t critical to what we’re doing, but worth a skim. OR
  • The Tic Tac Toe tutorial that shows everything together. Feel free to do this tutorial instead, and commit your code if you do (again, into a separate folder). Note: we have found that this tutorial, while more “hands on”, is a bit more difficult. Everyone’s learning style is different, but we have found students end up less confused when they do the other tutorial.

Commit your tutorial code to your repository, to the branch client2-dev into a separate folder.

  • i.e. create a sub-folder in your repo called ‘react-guide’, and place your files for the tutorial you used in there.

Porting to React

Once you’ve gotten set up and done the tutorials, let’s do the following, in this order:

  1. Decide what your app’s state will look like. This is the minimum amount of data that needs to be maintained to represent what the app tracks at any given time. Define your intitial state in your top-level component (e.g. App, or whatever you want to rename yours to). Consider which other components need their own state. Minimize the complexity of state management, but make sure you make components as independent as possible so you don’t always rely on a single ‘master’ object. This is the basics of good O-O design.
  2. Create component classes (or functions) to represent elements of your UI. Put each component in a separate file.
  3. Next, make the render method for each component. Hard-code all your numbers first. Just get the JSX working so the site looks the same.
  4. Next, pass the state from your top-level component to the properties of the child components. Make the hard-coded aspects of your UI dynamic based on the state/properties of the component. Again, aim for the UI to look the same way as you do this.
  5. Finally, figure out your event listeners. The tic-tac-toe tutorial mentioned earlier is a useful reference on the proper way to pass around event listeners.

Grading Client2

Points: 50 points

  • (10 points) Completed the setup instructions and the React tutorials.
  • (10 points) Works on the CI and deployed to GitLab Pages
  • (20 points) Refactored to React components
  • (5 points) Proper use of props for passing data to components
  • (5 points) Proper use of state for updating dynamic elements

Worm Tracker Specifics

No project specifics this time around. Reaching feature parity is challenging enough!

Client 3: Feature Iteration

In this iteration, we’re looking for new features that involve more interconnected components.

Worm Counter Specifics

  • Add the ability to add and delete Petri dishes to an experiment
  • Revise your results area to provide “accordion”-like functionality. This can mean many things and done many ways, but here’s what we mean:
    • Place Experiments in a list (i.e. <ul> and <li>), and petri dish counts in a sub-list (i.e. a <ul> inside of an <li>). Remember, Every petri dish “belongs to” an Experiment.
    • By default, all Experiments are collapsed, i.e. you do not see the sublists
      • When you click on an Experiment, it toggles showing the Petri dish sublist beneath it.
    • A fancier, more feature-rich version of this is the Bootstrap Accordion. Note: we are not expecting animations or other toggle effects that the Accordion does - just the above functionality.
  • Add the following live-updated statistics to each <li> element of the above accordian:
    • Average worms per petri dish
    • Total worms in this experiment, across all petri dishes

Grading

  • (20) Show/hide functionality
  • (10) Statistics
  • (10) Add/delete petri dishes
  • (10) Maintainable use of state, props and other React mechanisms.
  • (10) Builds and deploy on CI and submitted properly

Client 4: Full stack

It’s time to become a full-stack web engineer! In this iteration, we’re going to integrate everything from the class together. Using the setup instructions for the RESTful project, add a Flask server that also connects to a PostgreSQL database. Our goal here is to do a minimal feature - to show how everything fits together.

A few notes:

  • Your client should still be functional in the absence of the server
  • We covered the fetch() Javascript method in an earlier lecture. Be sure to review how to use that for GET and POST requests, to your RESTful endpoint
  • Also note: we will be unable to use GitLab pages for this feature, so we will be grading this locally.

Worm Counter Specifics

We want to persist the “current” count, the current petri dish, and current experiment. This can be stored as a single entity of “count”.

  • Store the current count in a database table.
  • Have DB methods to get and put the count from the database
  • Have a RESTful endpoint for to get and put the count
  • When the app starts, make a fetch() to the RESTful API for the current count. If it’s empty, then start as usual without a current count.
  • When you change the current count, update it to the database. You do not need to store historical records in the database, just the current count.

The ultimate test: start a count, then close the browser, close the React server, close the Flask server. Then, start the Flask and React servers again, and open the browser - and counter can continue without missing anything!

Note For the purposes of this assignment, you can have a hard-coded primary key of your current count, since you’ll only ever have one count. The goal is to keep it simple!