@snsw/var-rebates-ui-lib
v3.0.11
Published
Service New South Wales - UI library for rebates in Angular
Downloads
20
Maintainers
Keywords
Readme
#Vouchers and Rebates common UI Angular library (var-rebates-ui-lib) This library and storybook is to serve as a common place for different VAR applications, to standardise styling and lessen code duplication.
Some of the components could be used in quite general manner in SNSW, but mainly the architecture decisions are kept in mind of the VAR team not the entire SNSW.
##Pages and content:
(links don't work in Storybook)
##Add to project
npm install @snsw/var-rebates-ui-lib --save
npm install @snsw/biz-js-client --save
npm install normalize-text --save
npm install @ng-idle/core --save
npm install html2canvas --save
yarn add @snsw/var-rebates-ui-lib
yarn add @snsw/biz-js-client
yarn add normalize-text
yarn add @ng-idle/core
yarn add html2canvas
##Library structure The library is set into 4 main parts:
components - stand alone specific functionality ex. address entry, quickfeed, valdiation-summary
core - are central place for universal services, data models and anything common between pages and components
- interceptors - Angular common interceptors
- models - all interfaces that are global
- resolvers - Angular common resolvers
- services - all services that should be accessible on all applications
- styles - our main global style files
- testing - our static test builders and other utils
- utils - string, date or other static util methods
- validators - our static validators that can be used in FormGroup
dialogs - place where all the models should exist as they are very specific business use cases
pages - are business logic set of components that serve a specific goal ex. personal details page, review application page etc.
##Logic how to use We use a general Angular Material kind of feel to using these sets of common ui parts. There are groupings of business logic sets of modules or are very specific functionality module. To use something then you need to import the module that is providing it.
We use the .forRoot
pattern on module import, to give in specific configurations, or the environment file.
Examples:
* To use `<snsw-phone>` you need to import the `SnswFormElementsModule`.
* To use `<snsw-address-entry-v2>` you need to import the `SnswAddressEntryModule.forRoot(addressConfig)`.
* To use `<snsw-personal-details-page>` you need to import the `SnswPersonalDetailsPageModule.forRoot(environment, personalDetaildPageConfig)`.
##Adding new component / page Make sure the feature you are developing is unique and not just a different state of a same component. If it's a state change then you should make the original component configurable.
To all a new feature development and improvements or bug fixes definitely do your development in a branch! Let the code be checked over by the main maintainers, before merging it in!
If the feature has a interface
that is only specific to it and it will be only used when you import that
feature module, then keep it tied together with that specific feature and don't add the interface to core.
If the feature is complex enough make sure you have tests
that cover it's main business logic!!
Always update or add a stories.ts
and a README file. You can check beforehand if the group of
components have a general README file. Read more about Storybook in Instructions/Writing a new Story
Add the shorthands to the correct index.ts files as the feature has to be accessible
from the '@snsw/var-rebates-ui-lib'
level
If you added a new component don't forget to run and update the automated visual tests base line using 'test-visual:update-base'.
Be extra careful when doing changes and improving something! These components are used by multiple applications so when you need one thing to do a specific thing for your application then don't just change the original implementation, without knowing all apps will be OK with the change!
####Recap
- Don't duplicate code
- Develop on branches and let maintainers look over the changes
- Write tests
- Update/add a story
- Update/add to correct index.ts files
- When new component or change appearance of component run
test-visual:update-base
- Be extra vigilant on changes, this is used by multiple applications
##Our used storybook standard Storybook’s Component Story Format (CSF) is the recommended way to write stories since Storybook 5.2.
In CSF, stories and component metadata are defined as ES Modules. Every component story file consists of a required default export and one or more named exports.
CSF is supported in all frameworks except React Native, where you should use the storiesOf API instead.
##Our story structure We standardise our story files to all have the same pattern. This is in our opinion the best for functionality wise, easy of use and to get an code working example.
All of our stories have a Wrapper component, this gives us more control over the Angular component and also it's automatically a real example of what needs to be imported, provided, etc.
@Component({
selector: 'story-wrapper',
template: `
<p>Docs in Notes section</p>
`
})
class StoryWrapperComponent implements OnInit {
constructor() {}
ngOnInit() {}
}
And our stories are defined like this:
export default {
title: 'Components | README',
decorators: [
moduleMetadata({
imports: [],
providers:[]
}),
],
};
export const Documentation = () => ({
component: StoryWrapperComponent,
props: {},
});
Documentation.story = {
parameters: {
notes: { README },
}
};
##Other storybook material
If you have not written stories before, then please read and look through:
- Storybook CSF documentation
- Angular Storybook Example
Additional reading if you want to understand what problem we are solving:
- Design systems for developers
Longer tutorial:
- Intro to storybook
##Our used automated visual testing
For our common library automated visual testing required technology is:
- Storybook
- Puppeteer
- Jest
- Jest Image Snapshot
###How it works
- All tested components are gathered with jest and written in a unit testing style
- All components get rendered in storybook iframe URL, meaning it will only show given component.
- We navigate to that iframe page in headless chrome, using puppeteer which also does any prep work needed for the test and takes the screenshot.
- After that the image comparison is done using Jest image snapshot, which uses pixelmatch under the hood.
###How to run it
npm run test-visual
yarn test-visual
###How to update base images
npm run test-visual:update-base
yarn test-visual:update-base