From 613c147ee7f348938f87339a7faf5e5eb924d54b Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 27 Nov 2017 10:58:44 -0500 Subject: [PATCH 1/2] [#275] Fixed next page shows on last page --- docs/2-tutorials/3-stockpile/stockpile-app/9.12-testing.html.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/2-tutorials/3-stockpile/stockpile-app/9.12-testing.html.md b/docs/2-tutorials/3-stockpile/stockpile-app/9.12-testing.html.md index 117f69b36..72f0121b5 100644 --- a/docs/2-tutorials/3-stockpile/stockpile-app/9.12-testing.html.md +++ b/docs/2-tutorials/3-stockpile/stockpile-app/9.12-testing.html.md @@ -2,7 +2,6 @@ title: Lesson 12 - Testing url: tutorials/stockpile/912-testing layout: subpage -next: 2-tutorials/3-stockpile/stockpile-app/9.12-testing.html.md --- The Stockpile app comes bundled with a few different libraries that can be used together for automated tests and reporting. From 31298970245f61e83497b71265882d4b360e37ea Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 28 Nov 2017 17:29:28 -0500 Subject: [PATCH 2/2] [Fixes #272 and Fixes #274], also removes old referenced files. --- .../stockpile-app/4-stock-api.html.md | 6 +- .../stockpile-app/5-results-part1.html.md | 14 +- .../stockpile-app/0-index.html.md | 38 -- .../stockpile-app/01-project-overview.html.md | 98 ----- .../stockpile-app/1-project-creation.html.md | 94 ----- .../stockpile-app/2-search-page.html.md | 304 --------------- .../stockpile-app/3-data-store.html.md | 33 -- .../stockpile-app/4-stock-api.html.md | 133 ------- .../stockpile-app/5-results-part1.html.md | 199 ---------- .../stockpile-app/6-results-part2.html.md | 315 ---------------- .../stockpile-app/7-details-page.html.md | 352 ------------------ .../stockpile-app/8-favorites-api.html.md | 122 ------ .../stockpile-app/81-favorites-page.html.md | 213 ----------- .../9.10-details-add-favorites.html.md | 139 ------- .../stockpile-app/9.11-pwa-features.html.md | 50 --- .../stockpile-app/9.12-testing.html.md | 59 --- public/images/stockpile/route-params.png | Bin 0 -> 74784 bytes 17 files changed, 15 insertions(+), 2154 deletions(-) delete mode 100644 docs/3-references/stockpile-app/0-index.html.md delete mode 100644 docs/3-references/stockpile-app/01-project-overview.html.md delete mode 100644 docs/3-references/stockpile-app/1-project-creation.html.md delete mode 100644 docs/3-references/stockpile-app/2-search-page.html.md delete mode 100644 docs/3-references/stockpile-app/3-data-store.html.md delete mode 100644 docs/3-references/stockpile-app/4-stock-api.html.md delete mode 100644 docs/3-references/stockpile-app/5-results-part1.html.md delete mode 100644 docs/3-references/stockpile-app/6-results-part2.html.md delete mode 100644 docs/3-references/stockpile-app/7-details-page.html.md delete mode 100644 docs/3-references/stockpile-app/8-favorites-api.html.md delete mode 100644 docs/3-references/stockpile-app/81-favorites-page.html.md delete mode 100644 docs/3-references/stockpile-app/9.10-details-add-favorites.html.md delete mode 100644 docs/3-references/stockpile-app/9.11-pwa-features.html.md delete mode 100644 docs/3-references/stockpile-app/9.12-testing.html.md create mode 100644 public/images/stockpile/route-params.png diff --git a/docs/2-tutorials/3-stockpile/stockpile-app/4-stock-api.html.md b/docs/2-tutorials/3-stockpile/stockpile-app/4-stock-api.html.md index 07643daf5..d7fe3a2a7 100644 --- a/docs/2-tutorials/3-stockpile/stockpile-app/4-stock-api.html.md +++ b/docs/2-tutorials/3-stockpile/stockpile-app/4-stock-api.html.md @@ -77,14 +77,16 @@ then import it for use by opening `main.js` and adding the following at the top, ## Content Security Policy Updates -You'll also need to update the Content Security Policy for the app to allow content to come from Adobe Stock API by including its URL `https://stock.adobe.io` in the meta tag. +You'll also need to update the [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) for the app to allow content to come from Adobe Stock API by including its URL `https://stock.adobe.io` in the meta tag. Open the `index.html` file and replace the `` tag with the current CSP to: ```html - + ``` +
**IMPORTANT:** This CSP should be used for example purposes only and should **NEVER** be used in a production app as it is extremely insecure and provides wide open access. It's important to understand the meaning of the different attributes to ensure you're using the most secure one for your app. Please refer to [the documentation here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) for more details. You can also check out the [CSP is Awesome tool](http://cspisawesome.com/) to help you generate your own CSP's.
+ ## Add JavaScript handling To keep things more readable and maintainable for this app, it's better to code the functions for interacting with the Stock API in a separate JavaScript file. diff --git a/docs/2-tutorials/3-stockpile/stockpile-app/5-results-part1.html.md b/docs/2-tutorials/3-stockpile/stockpile-app/5-results-part1.html.md index 7f72afb99..7dc177809 100644 --- a/docs/2-tutorials/3-stockpile/stockpile-app/5-results-part1.html.md +++ b/docs/2-tutorials/3-stockpile/stockpile-app/5-results-part1.html.md @@ -36,7 +36,7 @@ An example of what will be returned by clicking these links is shown in this ani component: Results }, -
This path uses [dynamic route matching by pattern](http://framework7.io/vue/navigation-router.html), so when this pattern is found in a URL, it will load the `Results` component and match the 4 variables passed in dynamically for `filter`, `limit`, `q` and `referrer` respectively. For example: `http://localhost:8080/#!//results/words/60/cat/search` would be a matching URL. Once you complete the next lesson you will see how the browser URL dynamically changes each time based upon the search criteria when this page is loaded.
+
**Dynamic Routing:** This path uses the [dynamic route matching by pattern in Framework7]( http://framework7.io/vue/navigation-router.html#dynamic-route-matching), so when the above path pattern is found in a URL, the router will load the `Results` component and pass the 4 dynamic variables (`filter`, `limit`, `q` and `referrer`) with their actual values in the URL. For example: `http://localhost:8080/#!//results/words/60/cat/search` could be a resulting URL, where *words* is the `filter`, *60* is the `limit`, *cat* is the `q` (query) and *search* is the `referrer`. Once you complete the next lesson you will see how the browser URL is dynamically changed with new values each time a new search is executed.
1. You will also need to update the side menu for this step to remove the `About` list item completely, since this results page will be loaded dynamically based on search results and never from the side menu. @@ -60,7 +60,7 @@ An example of what will be returned by clicking these links is shown in this ani ``` -1. Replace the entire `` block with the following navbar. This new navbar binds the `back-link` to a computed property that determines which title to show based on which page the results came from. You will code this `backLink` property shortly: +1. Replace the entire `` block with the following navbar. This new navbar binds the [`back-link`]( http://framework7.io/vue/navigation-router.html#dynamic-route-matching) attribute to a computed property returning a label that was dynamically set based on where the results page was routed from. You'll see this label next to the back arrow icon on the results page. You will code this `backLink` computed property shortly: ```html @@ -122,7 +122,7 @@ Now locate the the `` tag, add this ` -``` - -## Run it - -![](/images/stockpile/7-details.png) diff --git a/docs/3-references/stockpile-app/8-favorites-api.html.md b/docs/3-references/stockpile-app/8-favorites-api.html.md deleted file mode 100644 index 133f4acf2..000000000 --- a/docs/3-references/stockpile-app/8-favorites-api.html.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Lesson 8 - Favorites API -url: references/stockpile-app/8-favorites-api -layout: subpage ---- - -The **Favorites** view manages a list of images that have been *favorited* in the app and relies on [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage) to persist favorites across sessions. An example of the favorites view is shown below for reference. However in this first part you're going to code a Favorites JavaScript API of sorts to allow the app to manage them more easily. - -Stockpile Favorites Screen - -## Favorites API - -1. In the `utils` folder, create a new file named `favorites.js` -1. Add an [eslint exception](https://eslint.org/docs/rules/no-undef) for the global `store` and `localStorage` variables at the top. - -```javascript - /* global store localStorage */ -``` - -1. Add a local function called `updateFavoritesById()` to take the array of `favorites` and store them as an object keyed by their id (resulting in the `favoritesById` being indexed by id): - -```javascript - function updateFavoritesById () { - store.favoritesById = store.favorites.reduce((a, b) => { - const c = a; - c[b.id] = b; - return c; - }, {}); - } -``` - -1. Next, code the `addFavorite()` and `removeFavorite()` local functions to manage adding and removing favorites with the global `store` object. The `updateFavoritesById` function is called each time to ensure the `favoritesById` array is updated with the change as well. - -```javascript - function addFavorite (favorite) { - store.favorites.push(favorite); - updateFavoritesById(); - } - - function removeFavorite (id) { - store.favorites = store.favorites.filter(favorite => favorite.id !== id); - updateFavoritesById(); - } -``` - -1. Add a local function to save the `favorites` array as a JSON string to `localStorage`: - -```javascript - function saveFavoritesToLocalStorage () { - localStorage.setItem('favorites', JSON.stringify(store.favorites)); - } -``` - -1. Add an export function to fetch the `favorites` JSON object from `localStorage`: - -```javascript - export function fetchFavoritesFromLocalStorage () { - return JSON.parse(localStorage.getItem('favorites')) || []; - } -``` - -1. Next add an export function called `toggleFavorite` which will be called to toggle the status of an item by adding or removing it from the favorites array depending on if it's already been favorited or not. Once the change is made to the array, a call to save to `localStorage` is necessary to keep it in sync: - -```javascript - export function toggleFavorite (favorite) { - const alreadyAFavorite = store.favorites.filter(fave => fave.id === favorite.id); - if (alreadyAFavorite.length > 0) { - removeFavorite(favorite.id); - } else { - addFavorite(favorite); - } - saveFavoritesToLocalStorage(); - } -``` - -### Managing Favorites Data - -The `favorites` should be populated from local storage initially when the app is run to load any items that have already been favorited. You initially created the data objects for the `favorites` in the global store as an empty array but in this step you will call the new `fetchFavoritesFromLocalStorage` method and index them by `id` when the app starts up. - -1. Open `main.js` and add an import for the `fetchFavoritesFromLocalStorage` function after the other imports: - -```javascript - import { fetchFavoritesFromLocalStorage } from './utils/favorites'; -``` - -1. Then, replace the `const favorites = [];` line you added earlier with a call to the new `fetchFavoritesFromLocalStorage` to actually populate it with the `favorites` from local storage when the app is run: - -```javascript - const favorites = fetchFavoritesFromLocalStorage(); -``` - -1. Next, replace the `const favoritesById = [];` with the following snippet, to index `favorites` by `id`: - -```javascript - const favoritesById = favorites.reduce((a, b) => { - const c = a; - c[b.id] = b; - return c; - }, {}); -``` - - In the end your global store handling data should look like the following: - -```javascript - // Set up a global store - const favorites = fetchFavoritesFromLocalStorage(); - const favoritesById = favorites.reduce((a, b) => { - const c = a; - c[b.id] = b; - return c; - }, {}); - - // Global store defaults - window.store = { - images: [], - imagesById: {}, - favorites, - favoritesById - }; -``` - -In the next lesson you will implement the UI and associated JavaScript needed to show the **Favorites** list view. diff --git a/docs/3-references/stockpile-app/81-favorites-page.html.md b/docs/3-references/stockpile-app/81-favorites-page.html.md deleted file mode 100644 index 4ed10ec36..000000000 --- a/docs/3-references/stockpile-app/81-favorites-page.html.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: Lesson 9 - Favorites View -url: references/stockpile-app/81-favorites-page -layout: subpage ---- - -In this part 2 you will implement the **Favorites** view UI specifically and it's associated handling. The **Favorites** view show a list of items containing the images the user has favorited along with the title, category and creation date for each, and a [swipeout](http://framework7.io/vue/swipeout-list.html) button to allow it to be deleted. Each of the list items links to the **Details** page when clicked. - -![](/images/stockpile/favorites-phone.png) - -## Renaming & Routing Updates - -1. Rename the existing `~src/components/pages/Services.vue` to `Favorites.vue` -1. Next update the routing for this app to load the `Favorites` component instead of the `Services` component. - - Open `~src/routes.js` and replace the import for `Services` with `Favorites`: - -```javascript - import Favorites from './components/pages/Favorites'; -``` - -1. Then replace the route for the `'/services/'` path to `'/favorites/'` and specify the `Favorites` component: - -```javascript - { - path: '/favorites/', - component: Favorites - }, -``` - -1. Lastly, you'll want to be able to access the **Favorites** page from the side menu. Open `~src/components/LeftPanel.vue` and replace the `` element for `"/services/"` with the following: - -```html - -``` - -## Implement the UI - -In `Favorites.vue`, change the page name from "services" to "favorites": - -```html - -``` - -### Navigation Bar - -Replace the current `` component with the following: - -```html - - - - - - Favorites - - -``` - -### Content Updates - -1. Completely replace the `` and `` elements with the following list and content block code: - -```html - - - - Delete - - - - -

- You have no favorites saved. Search for something then use the - star icon to save a favorite -

-
-``` - - This code will create a list of items using the `[Framework7 media-list](http://framework7.io/vue/list.html)` modifier if there are currently any items favorited (the `hasFavorites` will be added in the JavaScript handling below). If there are none, a UI block is shown to notify the user to use the star icon. It will bind all of the item data to the UI components of the list item for display, and also set a click handler to open the details of the item, and a delete handler to call when the swipeout delete button is clicked. These functions will be added in the JavaScript section below. The animated image below shows how the favorites list appears after this code is rendered and and what the swipeout delete looks like: - - Stockpile Delete Fave - -## Add JavaScript Handling - -In this section you will need to scroll down to the bottom of the page where the JavaScript default export block is defined to make some changes and additions. - -1. Rename this component by changing the `name: Services` to `name: Favorites` - -```javascript - export default { - name: 'Favorites', - ... - } -``` - -1. At the top of the `