mirror of
https://github.com/cse110-fa22-group29/cse110-fa22-group29.git
synced 2024-12-26 17:09:09 +00:00
Merge branch 'main' of https://github.com/cse110-fa22-group29/cse110-fa22-group29
This commit is contained in:
commit
7cac0bc0a8
10
.github/workflows/deploy-githubpages.yml
vendored
10
.github/workflows/deploy-githubpages.yml
vendored
@ -29,8 +29,18 @@ jobs:
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install apt updates
|
||||
run: sudo apt -y update; sudo apt -y upgrade;
|
||||
- name: Install prerequisites
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo npm install
|
||||
- name: Run tests
|
||||
run: sudo npm run js-doc
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v2
|
||||
- name: Upload artifact
|
||||
|
29
.github/workflows/prettier.yml
vendored
Normal file
29
.github/workflows/prettier.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: Prettier
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install apt updates
|
||||
run: sudo apt -y update; sudo apt -y upgrade;
|
||||
- name: Install prerequisites
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo npm install
|
||||
- name: Start local http server
|
||||
run: sudo npm run http-server &
|
||||
- name: Run tests
|
||||
run: sudo npm lint-prettier
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
**/.devcontainer/*
|
||||
**/node_modules/*
|
||||
**/package-lock.json
|
||||
**/package-lock.json
|
||||
**/*.vscode/*
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
||||
{
|
||||
"liveServer.settings.port": 5501
|
||||
}
|
BIN
admin/cipipeline/phase2.drawio.png
Normal file
BIN
admin/cipipeline/phase2.drawio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
47
admin/cipipeline/phase2.md
Normal file
47
admin/cipipeline/phase2.md
Normal file
@ -0,0 +1,47 @@
|
||||
# CI/CD Phase 2
|
||||
|
||||
## Overall Pipeline Architecture
|
||||
|
||||
Rather than create one large pipeline with many steps which increases complexity, we decided to create many small independent pipelines which work in parallel to conduct code quality checking. Using this strategy, if any one pipeline has issues, we can still continue development without delay, and the quality of code is likely to remain high.
|
||||
|
||||
## Overview of Pipeline Features
|
||||
|
||||
We've identified 5 major features which we definitely want to implement in the CI/CD pipeline.
|
||||
|
||||
- Deployment
|
||||
- Unit Testing
|
||||
- Linting
|
||||
- End To End Validation
|
||||
- Manual Validation
|
||||
|
||||
We also identified some features which are nice to have:
|
||||
- Automatic documentation publishing
|
||||
- Minification
|
||||
- HTML Validation and accessibility scoring
|
||||
|
||||
We created this diagram to demonstrate our strategy of multiple simple pipelines.
|
||||
|
||||
![Pipeline Diagram](phase2.drawio.png)
|
||||
|
||||
## Finished Features and Implementation
|
||||
|
||||
So far the features listed below have been completed to some degree:
|
||||
|
||||
- Deployment
|
||||
- Implemented: action triggered on any push to main, uses the github pages action to publish the app
|
||||
- Implemented: uses JSDoc to generate documentation on the same site at [docs](https://cse110-fa22-group29.github.io/cse110-fa22-group29/docs/)
|
||||
- ToDo: Add minification step between trigger and github pages action
|
||||
- Unit Testing
|
||||
- Implemented: action triggers on PR to main, uses mocha to perform unit testing on core components
|
||||
- End to end testing
|
||||
- Implemented: action triggers on PR to main, uses mocha and puppeteer to perform end to end testing
|
||||
- Linting (JS)
|
||||
- Implemented: action triggers on PR to main, uses eslint to perform style enforcement on all JS components
|
||||
- Linting (HTML)
|
||||
- Implemented: action triggers on PR to main, uses HTMLhint to perform style enforcement on all HTML components
|
||||
- Linting (CSS)
|
||||
- Implemented: action triggers on PR to main, uses Stylelint to perform style enforcement on all CSS components
|
||||
- Linting (general)
|
||||
- Implemented: action triggers on PR to main, uses Prettier to perform style checking on all file types
|
||||
|
||||
## Planned Features and Timeline
|
BIN
admin/cipipeline/phase2.mp4
Normal file
BIN
admin/cipipeline/phase2.mp4
Normal file
Binary file not shown.
@ -68,4 +68,4 @@ A few members got sick over the break and with midterms picking up for other cla
|
||||
* Fix image sizing issues by focusing on supporting 300x300 pixel images with sizes of around 2-5 megabytes
|
||||
|
||||
## End Time
|
||||
- 11/14/2022 at 5:00PM
|
||||
- 11/14/2022 at 5:00PM
|
@ -9,16 +9,21 @@
|
||||
"lint-html": "htmlhint **/*.html",
|
||||
"lint-css": "stylelint **/*.css",
|
||||
"fix-css": "stylelint --fix **/*.css",
|
||||
"http-server": "http-server source"
|
||||
"http-server": "http-server source",
|
||||
"js-doc": "jsdoc -d source/docs/ -r source/",
|
||||
"lint-prettier": "prettier --check .",
|
||||
"fix-prettier": "prettier --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.27.0",
|
||||
"htmlhint": "1.1.4",
|
||||
"http-server": "",
|
||||
"jsdoc": "^4.0.0",
|
||||
"mocha": "10",
|
||||
"mock-local-storage": "^1.1.23",
|
||||
"puppeteer": "^18.2.1",
|
||||
"stylelint": "14.14.1",
|
||||
"stylelint-config-standard": "^29.0.0"
|
||||
"stylelint-config-standard": "^29.0.0",
|
||||
"prettier": "2.8.0"
|
||||
}
|
||||
}
|
||||
|
@ -10,19 +10,18 @@
|
||||
<!--Add Favicon-->
|
||||
<link rel="icon" type="image/x-icon" href="./assets/images/favicon.ico">
|
||||
|
||||
<!-- Recipe Card Custom Element -->
|
||||
<!-- Review Card Custom Element -->
|
||||
<script src="assets/scripts/ReviewCard.js" type="module"></script>
|
||||
|
||||
|
||||
<!-- Main Stylesheets & Scripts -->
|
||||
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
|
||||
<!-- <link rel="stylesheet" href="/static/reset.css" /> -->
|
||||
<!-- Create Page Stylesheets & Scripts -->
|
||||
<link rel="stylesheet" href="./static/CreatePage.css" />
|
||||
<link rel="stylesheet" href="./static/Form.css" />
|
||||
<script src="./assets/scripts/CreatePage.js" type="module"></script>
|
||||
</head>
|
||||
|
||||
<header>
|
||||
<!-- Setting up logo and site name at the top of the website -->
|
||||
<div class="top-bar">
|
||||
<img src ="./assets/images/Logo.png" alt="logo" />
|
||||
<h1> Food Journal </h1>
|
||||
@ -85,6 +84,8 @@
|
||||
</fieldset>
|
||||
|
||||
<button type="submit" id="save-btn" value="Submit">Save</button>
|
||||
|
||||
<!-- Button that allows user to go back to the homepage -->
|
||||
<input type="button" value="Cancel" id="home-btn" onclick="window.location.assign('./index.html')">
|
||||
</form>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<!--Add Favicon-->
|
||||
<link rel="icon" type="image/x-icon" href="./assets/images/icons/favicon.ico">
|
||||
|
||||
<!-- Recipe Card Custom Element -->
|
||||
<!-- Review Card Custom Element -->
|
||||
<script src="assets/scripts/ReviewCard.js" type="module"></script>
|
||||
|
||||
<!-- Main Stylesheets & Scripts -->
|
||||
|
@ -2,35 +2,38 @@ import { newReviewToStorage } from "./localStorage.js";
|
||||
|
||||
window.addEventListener("DOMContentLoaded", init);
|
||||
|
||||
/**
|
||||
* Delegates the functionality for creating review cards.
|
||||
*/
|
||||
function init() {
|
||||
// get next id
|
||||
|
||||
// creates the key
|
||||
|
||||
initFormHandler();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a form and associates a new ID with the new review card.
|
||||
*/
|
||||
function initFormHandler() {
|
||||
|
||||
//accessing form components
|
||||
// Accesses form components
|
||||
let tagContainer = document.getElementById("tag-container-form");
|
||||
let form = document.querySelector("form");
|
||||
|
||||
/*
|
||||
* change the input source of the image between local file and URL
|
||||
* depending on user's selection
|
||||
*/
|
||||
// Event listener for reading form data
|
||||
let select = document.getElementById("select");
|
||||
select.addEventListener("change", function() {
|
||||
const input = document.getElementById("source");
|
||||
|
||||
// Select a photo with HTML file selector
|
||||
if (select.value == "file") {
|
||||
input.innerHTML = `
|
||||
Source:
|
||||
<input type="file" accept="image/*" id="mealImg" name="mealImg">
|
||||
`;
|
||||
}
|
||||
//TODO: change to photo taking for sprint 3
|
||||
|
||||
// Upload text URL input
|
||||
else {
|
||||
input.innerHTML = `
|
||||
Source:
|
||||
@ -39,28 +42,28 @@ function initFormHandler() {
|
||||
}
|
||||
});
|
||||
|
||||
//addressing sourcing image from local file
|
||||
// Addresses sourcing image from local file
|
||||
let imgDataURL = "";
|
||||
document.getElementById("mealImg").addEventListener("change", function() {
|
||||
const reader = new FileReader();
|
||||
|
||||
//store image data URL after successful image load
|
||||
// Store image data URL after successful image load
|
||||
reader.addEventListener("load", ()=>{
|
||||
imgDataURL = reader.result;
|
||||
}, false);
|
||||
|
||||
//convert image file into data URL for local storage
|
||||
// Convert image file into data URL for local storage
|
||||
reader.readAsDataURL(document.getElementById("mealImg").files[0]);
|
||||
});
|
||||
|
||||
form.addEventListener("submit", function(e){
|
||||
/*
|
||||
* User submits the form for their review.
|
||||
* We create reviewCard and put in storage
|
||||
*/
|
||||
|
||||
// Create reviewObject and put in storage
|
||||
e.preventDefault();
|
||||
let formData = new FormData(form);
|
||||
let reviewObject = {};
|
||||
|
||||
// Adds data to the reviewObject from form data
|
||||
for (let [key, value] of formData) {
|
||||
console.log(`${key}`);
|
||||
console.log(`${value}`);
|
||||
@ -71,36 +74,51 @@ function initFormHandler() {
|
||||
reviewObject["mealImg"] = imgDataURL;
|
||||
}
|
||||
}
|
||||
|
||||
// Makes sure that ratings is filled
|
||||
if(reviewObject["rating"] != null){
|
||||
|
||||
//Adds rags separately as an array
|
||||
reviewObject["tags"] = [];
|
||||
|
||||
// Grabs tags
|
||||
let tags = document.querySelectorAll(".tag");
|
||||
for(let i = 0; i < tags.length; i ++) {
|
||||
reviewObject["tags"].push(tags[i].innerHTML);
|
||||
tagContainer.removeChild(tags[i]);
|
||||
}
|
||||
|
||||
// Assigns the new review with a new ID
|
||||
let nextReviewId = newReviewToStorage(reviewObject);
|
||||
sessionStorage.setItem("currID", JSON.stringify(nextReviewId));
|
||||
|
||||
|
||||
// Redirects to a page that shows the newly created review
|
||||
window.location.assign("./ReviewDetails.html");
|
||||
} else{
|
||||
}
|
||||
// Does not let user proceed if rating is not complete
|
||||
else{
|
||||
window.alert("NO! FILL IN STARS");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Event listener for tag functionality
|
||||
let tagAddBtn = document.getElementById("tag-add-btn");
|
||||
tagAddBtn.addEventListener("click", ()=> {
|
||||
let tagField = document.getElementById("tag-form");
|
||||
|
||||
// If there is a tag, it'll display the tag
|
||||
if (tagField.value.length > 0) {
|
||||
let tagLabel = document.createElement("label");
|
||||
tagLabel.innerHTML = tagField.value;
|
||||
tagLabel.setAttribute("class","tag");
|
||||
|
||||
// Allows for user to delete the tag
|
||||
tagLabel.addEventListener("click",()=> {
|
||||
tagContainer.removeChild(tagLabel);
|
||||
});
|
||||
|
||||
|
||||
// Adds the tag
|
||||
tagContainer.append(tagLabel);
|
||||
tagField.value = "";
|
||||
|
||||
|
@ -102,45 +102,37 @@ class ReviewCard extends HTMLElement {
|
||||
articleEl.append(styleEl);
|
||||
shadowEl.append(articleEl);
|
||||
this.shadowEl = shadowEl;
|
||||
//attach event listener to each recipe-card
|
||||
|
||||
// Attach event listener to each review-card
|
||||
this.addEventListener("click", (event) => {
|
||||
console.log(event.target);
|
||||
console.log(event.target.reviewId);
|
||||
//Option 1: sending current data to second html page using localStorage (could also just store index)
|
||||
// Saves the ID for corresponding review on new page (for data retrieval)
|
||||
sessionStorage.setItem("currID", JSON.stringify(event.target.data.reviewID));
|
||||
// Goes to the new page for the review
|
||||
window.location.assign("./ReviewDetails.html");
|
||||
/*
|
||||
//Option 2: sending current data to second html page using string query w/ url (currently not storing value)
|
||||
let reviewFields = window.location.search.slice(1).split("&");
|
||||
for(let i = 0; i < reviewFields.length; i++) {
|
||||
let kv = reviewFields[i].split("=");
|
||||
let key = kv[0];
|
||||
let value = kv[1];
|
||||
console.log(key);
|
||||
console.log(value);
|
||||
// What you want to do with name and value...
|
||||
}*/
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the .data property is set on this element.
|
||||
*
|
||||
* For Example:
|
||||
* let reviewCard = document.createElement('review-card');
|
||||
* reviewCard.data = { foo: 'bar' }
|
||||
*
|
||||
* @param {Object} data - The data to pass into the <review-card>, must be of the
|
||||
* following format:
|
||||
* {
|
||||
* "mealImg": "string",
|
||||
* "mealName": "string",
|
||||
* "comments": "string",
|
||||
* "rating": number,
|
||||
* "restaurant": "string",
|
||||
* "tags": string array
|
||||
* }
|
||||
*/
|
||||
* Called when the .data property is set on this element.
|
||||
*
|
||||
* For Example:
|
||||
* let reviewCard = document.createElement('review-card');
|
||||
* reviewCard.data = { foo: 'bar' }
|
||||
*
|
||||
* @param {Object} data - The data to pass into the <review-card>, must be of the
|
||||
* following format:
|
||||
* {
|
||||
* "mealImg": string,
|
||||
* "mealName": string,
|
||||
* "comments": string,
|
||||
* "rating": number,
|
||||
* "restaurant": string,
|
||||
* "reviewID": number,
|
||||
* "tags": string array
|
||||
* }
|
||||
*/
|
||||
set data(data) {
|
||||
// If nothing was passed in, return
|
||||
if (!data) return;
|
||||
@ -148,10 +140,10 @@ class ReviewCard extends HTMLElement {
|
||||
// Select the <article> we added to the Shadow DOM in the constructor
|
||||
let articleEl = this.shadowEl.querySelector("article");
|
||||
|
||||
// setting the article elements for the review card
|
||||
// Setting the article elements for the review card
|
||||
this.reviewID = data["reviewID"];
|
||||
|
||||
//image setup
|
||||
// Image setup
|
||||
let mealImg = document.createElement("img");
|
||||
mealImg.setAttribute("id", "a-mealImg");
|
||||
mealImg.setAttribute("alt","Meal Photo Corrupted");
|
||||
@ -161,25 +153,25 @@ class ReviewCard extends HTMLElement {
|
||||
e.onerror = null;
|
||||
});
|
||||
|
||||
//meal name setup
|
||||
// Meal name setup
|
||||
let mealLabel = document.createElement("label");
|
||||
mealLabel.setAttribute("id", "a-mealName");
|
||||
mealLabel.setAttribute("class","meal-name");
|
||||
mealLabel.innerHTML = data["mealName"];
|
||||
|
||||
//restaurant name setup
|
||||
// Restaurant name setup
|
||||
let restaurantLabel = document.createElement("label");
|
||||
restaurantLabel.setAttribute("id", "a-restaurant");
|
||||
restaurantLabel.setAttribute("class","restaurant-name");
|
||||
restaurantLabel.innerHTML = data["restaurant"];
|
||||
|
||||
//comment section setup (display set to none)
|
||||
// Comment section setup (display set to none)
|
||||
let comments = document.createElement("p");
|
||||
comments.setAttribute("id", "a-comments");
|
||||
comments.style.display = "none";
|
||||
comments.innerText = data["comments"];
|
||||
|
||||
//other info: rating
|
||||
// Rating setup
|
||||
let ratingDiv = document.createElement("div");
|
||||
ratingDiv.setAttribute("class", "rating");
|
||||
let starsImg = document.createElement("img");
|
||||
@ -189,11 +181,13 @@ class ReviewCard extends HTMLElement {
|
||||
starsImg.setAttribute("num", data["rating"]);
|
||||
ratingDiv.append(starsImg);
|
||||
|
||||
//added tags
|
||||
// Tags setup
|
||||
let tagContainer = document.createElement("div");
|
||||
tagContainer.setAttribute("class", "tag-container");
|
||||
tagContainer.setAttribute("id", "a-tags");
|
||||
tagContainer.setAttribute("list", data["tags"]);
|
||||
|
||||
// Checks if user gave tags, if so added to review card
|
||||
if(data["tags"]){
|
||||
for (let i = 0; i < data["tags"].length; i++) {
|
||||
let newTag = document.createElement("label");
|
||||
@ -203,8 +197,7 @@ class ReviewCard extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
//adding final ID to data!
|
||||
|
||||
// Setting all the data to the review card
|
||||
articleEl.append(mealImg);
|
||||
articleEl.append(mealLabel);
|
||||
articleEl.append(restaurantLabel);
|
||||
@ -216,52 +209,53 @@ class ReviewCard extends HTMLElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when getting the .data property of this element.
|
||||
*
|
||||
* For Example:
|
||||
* let reviewCard = document.createElement('review-card');
|
||||
* reviewCard.data = { foo: 'bar' }
|
||||
*
|
||||
* @return {Object} data - The data from the <review-card>, of the
|
||||
* following format:
|
||||
* {
|
||||
* "mealImg": "string",
|
||||
* "mealName": "string",
|
||||
* "comments": "string",
|
||||
* "rating": number,
|
||||
* "restaurant": "string",
|
||||
* "tags": string array
|
||||
* }
|
||||
*/
|
||||
* Called when getting the .data property of this element.
|
||||
*
|
||||
* For Example:
|
||||
* let reviewCard = document.createElement('review-card');
|
||||
* reviewCard.data = { foo: 'bar' }
|
||||
*
|
||||
* @return {Object} data - The data from the <review-card>, of the
|
||||
* following format:
|
||||
* {
|
||||
* "mealImg": string,
|
||||
* "mealName": string,
|
||||
* "comments": string,
|
||||
* "rating": number,
|
||||
* "restaurant": string,
|
||||
* "reviewID": number,
|
||||
* "tags": string array
|
||||
* }
|
||||
*/
|
||||
get data() {
|
||||
|
||||
let dataContainer = {};
|
||||
|
||||
// getting the article elements for the review card
|
||||
// Getting the article elements for the review card
|
||||
dataContainer["reviewID"] = this.reviewID;
|
||||
|
||||
//get image
|
||||
// Get image
|
||||
let mealImg = this.shadowEl.getElementById("a-mealImg");
|
||||
dataContainer["mealImg"] = mealImg.getAttribute("src");
|
||||
|
||||
//get meal name
|
||||
// Get meal name
|
||||
let mealLabel = this.shadowEl.getElementById("a-mealName");
|
||||
dataContainer["mealName"] = mealLabel.innerHTML;
|
||||
|
||||
//get comment section
|
||||
// Get comment section
|
||||
let comments = this.shadowEl.getElementById("a-comments");
|
||||
console.log(comments);
|
||||
dataContainer["comments"] = comments.innerText;
|
||||
|
||||
//get other info: rating
|
||||
// Get rating
|
||||
let starsImg = this.shadowEl.getElementById("a-rating");
|
||||
dataContainer["rating"] = starsImg.getAttribute("num");
|
||||
|
||||
//get restaurant name
|
||||
//Get restaurant name
|
||||
let restaurantLabel = this.shadowEl.getElementById("a-restaurant");
|
||||
dataContainer["restaurant"] = restaurantLabel.innerHTML;
|
||||
|
||||
//get tags
|
||||
// Get tags
|
||||
let tagContainer = this.shadowEl.getElementById("a-tags");
|
||||
dataContainer["tags"] = tagContainer.getAttribute("list").split(",");
|
||||
|
||||
|
@ -4,6 +4,9 @@ import {deleteReviewFromStorage, getReviewFromStorage, updateReviewToStorage} fr
|
||||
// Run the init() function when the page has loaded
|
||||
window.addEventListener("DOMContentLoaded", init);
|
||||
|
||||
/**
|
||||
* Populates the relevant data to the details from local storage review.
|
||||
*/
|
||||
function init(){
|
||||
setupInfo();
|
||||
setupDelete();
|
||||
@ -51,6 +54,9 @@ function setupInfo(){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up delete button to delete reveiw from storage and switch to homepage.
|
||||
*/
|
||||
function setupDelete(){
|
||||
let deleteBtn = document.getElementById("delete-btn");
|
||||
let currID = JSON.parse(sessionStorage.getItem("currID"));
|
||||
@ -63,6 +69,9 @@ function setupDelete(){
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up update button to reveal form and update info in storage and the current page.
|
||||
*/
|
||||
function setupUpdate(){
|
||||
let updateBtn = document.getElementById("update-btn");
|
||||
let currID = JSON.parse(sessionStorage.getItem("currID"));
|
||||
@ -139,19 +148,18 @@ function setupUpdate(){
|
||||
|
||||
//Take formdata values as newData when submit
|
||||
form.addEventListener("submit", function(){
|
||||
/*
|
||||
* User submits the form for their review.
|
||||
* We create reviewCard and put in storage
|
||||
*/
|
||||
//We create reviewCard datea, replace it in in storage, and update tags
|
||||
let formData = new FormData(form);
|
||||
let newData = {};
|
||||
|
||||
// Iterate through formData an add to newData
|
||||
for (let [key, value] of formData) {
|
||||
console.log(`${key}`);
|
||||
console.log(`${value}`);
|
||||
if (`${key}` !== "tag-form") {
|
||||
newData[`${key}`] = `${value}`;
|
||||
}
|
||||
//Account for the case where image is not updated
|
||||
// Account for the case where image is not updated
|
||||
if (`${key}` === "mealImg" && document.getElementById("mealImg").value === "") {
|
||||
newData["mealImg"] = currReview["mealImg"];
|
||||
}
|
||||
@ -175,6 +183,7 @@ function setupUpdate(){
|
||||
|
||||
});
|
||||
|
||||
// Adding tag to form functionality
|
||||
let tagAddBtn = document.getElementById("tag-add-btn");
|
||||
tagAddBtn.addEventListener("click", ()=> {
|
||||
let tagField = document.getElementById("tag-form");
|
||||
|
@ -10,12 +10,10 @@
|
||||
<!--Add Favicon-->
|
||||
<link rel="icon" type="image/x-icon" href="./assets/images/favicon.ico">
|
||||
|
||||
<!-- Recipe Card Custom Element -->
|
||||
<!-- Review Card Custom Element -->
|
||||
<script src="assets/scripts/ReviewCard.js" type="module"></script>
|
||||
|
||||
<!-- Main Stylesheets & Scripts -->
|
||||
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
|
||||
<!-- <link rel="stylesheet" href="/static/reset.css" /> -->
|
||||
<!-- Homepage Stylesheets & Scripts -->
|
||||
<link rel="stylesheet" href="./static/homepage.css" />
|
||||
<script src="assets/scripts/main.js" type="module"></script>
|
||||
</head>
|
||||
|
17
specs/adrs/112922-documentation-jsdoc.md
Normal file
17
specs/adrs/112922-documentation-jsdoc.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Use JSDoc for JS documentation
|
||||
|
||||
- Status: accept
|
||||
- Deciders: Arthur Lu, Marc Reta
|
||||
- Date: 11 / 29 / 22
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
- Need simple way to publish documentation for code
|
||||
- Already documentating infile using JSDoc style
|
||||
|
||||
## Considered Options
|
||||
- JSDoc
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen Option: JSDoc. Will run by generating docs in /source/docs/ before publishing /source/ so users can enter the URI /docs/ to see documentation.
|
17
specs/adrs/112922-prettier.md
Normal file
17
specs/adrs/112922-prettier.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Use Prettier for generic style enforcement
|
||||
|
||||
- Status: accept
|
||||
- Deciders: Arthur Lu, Marc Reta
|
||||
- Date: 11 / 29 / 22
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
- Other linters (HTML, CSS, JS) are sometimes too permissive
|
||||
- Need to enforce style on other files like markdown, json
|
||||
|
||||
## Considered Options
|
||||
- Prettier
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen Option: Prettier
|
16
specs/adrs/112922-review-storage.md
Normal file
16
specs/adrs/112922-review-storage.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Backend Storage Structure
|
||||
- Status: Accept
|
||||
- Deciders: Rhea Bhutada, Kara Hoagland, Gavyn Ezell, George Dubinin, Henry Feng
|
||||
- Date: 11/29/2022
|
||||
|
||||
## Decision Drivers
|
||||
- Needed more efficient way of storing reviews that are created, for more efficient testing, updating, accessing, and deleting.
|
||||
|
||||
## Considered Options
|
||||
- localStorage
|
||||
|
||||
## Decision Outcome
|
||||
Using local storage to maintain the "local first" requirement.
|
||||
Moved away from array of objects for storing reviews, reviews are stored individually as keys in localStorage, under the "review{id}" format. Each key
|
||||
corresponds to object containing review data. We also have an array stored in local storage, named "activeIDs" which keeps track of id numbers that are attached
|
||||
to created reviews.
|
15
specs/adrs/112922-reviewpage-session.md
Normal file
15
specs/adrs/112922-reviewpage-session.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Opening Specific Reviews
|
||||
- Status: Accept
|
||||
- Deciders: Rhea Bhutada, Kara Hoagland, Gavyn Ezell, George Dubinin, Henry Feng
|
||||
- Date: 11/29/2022
|
||||
|
||||
## Decision Drivers
|
||||
- When opening up a review, browser needs to know what review ID to use for loading the review page data
|
||||
|
||||
## Considered Options
|
||||
- sessionStorage
|
||||
|
||||
## Decision Outcome
|
||||
Review cards have event listeners that will add their associated review ID number to session storage so
|
||||
when the review loads, the browser will use the id stored to pull exact data corresponding to the review.
|
||||
|
13
specs/adrs/112922-tag-review-collision-fix.md
Normal file
13
specs/adrs/112922-tag-review-collision-fix.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Organizing Review Under Tags
|
||||
- Status: Accept
|
||||
- Deciders: Rhea Bhutada, Kara Hoagland, Gavyn Ezell, George Dubinin, Henry Feng
|
||||
- Date: 11/29/2022
|
||||
|
||||
## Decision Drivers
|
||||
- Needed to keep track of reviews under certain given tags for filtering feature.
|
||||
|
||||
## Considered Options
|
||||
- localStorage
|
||||
|
||||
## Decision Outcome
|
||||
For every tag create a key under that tag name in localStorage. They will store an array of IDs that correspond to reviews that contain that tag.
|
Loading…
Reference in New Issue
Block a user