WooliesX Webapp
How it works
####To see the storybooks for Stencil :
1- Go inside `Stencil>wooliesx-design-system`
2- run `npm install`
3- run `npm run storybook`
4- go to http://localhost:49839/
5- I made two stories, one of `w-btn` which demonstrates all the different props, including the `variant` etc, and one for `w-product`.
####To run the Angular Web App :
1- Go inside `Angular>wooliesx-webapp`
2- run `npm install`
3- run `npm start` and go to `http://localhost:4200/`
4- Click on `ADD TO SHOPPING LIST`
5- No need to fill out the form in the `LoginDialog`, just hit `Login`. The idea is that users need to login/signup to be able to retrieve/add new shopping list items
6- Notice the state of the Product component will change, and the button is replaced by a "REMOVE FROM SHOPPING LIST".
7- Notice also that in the navigation bar, `My Shopping List` will show a badge with the newly added shopping item inside it.
8- Click on the "REMOVE FROM SHOPPING LIST" button and see above side effects to be reversed.
That's it :)
Assumptions
1- My Stencil components
I have created 5 components in my Stencil project, and these components are published to a public NPM
registry.
Due to the time constraints, I decided to publish all the components as a single library, but this is not ideal.
Ideally we should publish these components separately using their own NPM
package under a bigger umbrella.
Something like @WooliesX/w-btn@0.0.1
.
Moreover, although I would encourage to open-source our design system, sometimes due to the restrictions of the company this is not possible, in those cases we will have our very own private NPM
( or others like Microsoft etc) registry.
Currently, my Stencil packages are deployed here https://www.npmjs.com/package/wooliesx-design-system
2 - Usage of Material Components
I decided to use a couple of Material Components in my Angular
project, along with my Stencil
components, both to show case that we can easily use other component libraries and design systems if needed and also save time.
From Angular Material, I used their Dialog
and Text Input
Note that choosing Angular Material
was by no means a thoroughly researched choice, it was rather the first option I thought of, just for demonstration purposes.
If I wanted to choose a third-party design system in a real example, I would definitely investigate more and consider different options and provide more documents and rational around my decision.
###The cool parts
I've tried to demonstrate a couple of different technical ideas in my Stencil components that are worth mentioning.
1- In w-btn
component benefits from attribute customisation.
A consumer can change the look and feel and behaviour of the button by providing below attributes :
- variant: outlined | contained | text
- color: primary | secondary | default
- size: small | large | medium
2- I used BEM
, or Block Element Modifier in the styles, but depending on the size of the project, Atomic
design is also a perfect choice
3- In w-typography
I have demonstrated how to load dynamic DOM
elements based on Props
. This is a very powerful concept, and it can be hardly achieved in the Angular realm, but JSX
make this very easy.
4- I've also set up path
in the tsconfig
to prevent from hard-coding absolute path when importing other components
5- I tried to demonstrate the usage of Storybooks
for our Stencil components, which is again an overkill for just two components, but I thought why not :)
This will help to achieve below :
Before : `../../../store/product/product.actions`
After : `@Store/product/product.actions`
5- I used NGRX
to demonstrate the integration of a Store
and I also offloaded all my API calls to the @Effects
.
Although this was an overkill for this little project, but I thought I would demonstrate my knowledge.
Note that none of the components are fully coded and ready, they all are for demonstration purposes.
Note also that all the API services are returning mock data using BehaviourSubject
To be continued
There are so many things that I could improve if I had more time, and I was more involved, but here are some of them :
1- Some of the interfaces/types
are being duplicated between my Angular and Stencil project. There are so many ways to rectify this issue, but at the very least a shared repo for the common interfaces would be decent.
2- The level of testing should definitely be improved, but considering the time, I had to limit my test cases to only a function in product-page.component.spec.ts
(Although this is still a good idea to separate logics into separate reusable and testable functions. This helps reducing usage of Angular's TestBed which has been always notoriously slow)
3- Loading fonts from Google directly in HTML isn't the best idea, because this might create different flashes ( more on that here https://css-tricks.com/fout-foit-foft/)
4- The visual design of the elements is by no means idea, but I think considering the time it's ok.
5- Inside the product-page
, there's a shopping-list
class that should not be there, this is just a placeholder for a proper ShoppingList
component that will come from our design system
6- Login/Signup functionality is completely outside of the scope of this task, this is why I'm not storing user's credential and the LoginBoxDialog
is just a placeholder.
This project was generated with Angular CLI version 10.1.0.
Development server
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The app will automatically reload if you change any of the source files.