winget install --id=WalkoverTechnologies.giddh -e
Accounting Software from Giddh.
Clone https://github.com/Walkover-Web-Solution/Giddh-New-Angular4-App.git.
This project requires Node version 14+, install Node from here.
Go inside the cloned directory Giddh-New-Angular4-App
in any terminal and run these following commands in the terminal to install dependency and start local serve.
Run npm i
for installation of dependencies.
You need to add a .env
file at the root of the project (similar to .env.example
already present at the root) which is used to store credentials related to Google, Razorpay, LinkedIn, Twitter. You can get the .env
file from any of the contributors of this project.
Run npm run start
to local serve the project.
Before contributing it is required that you should have a proper knowledge of Git. If you're unfamiliar with Git you should first visit the recommended Udacity Git course.
Giddh has 4 environments TEST
, STAGE
, BETA
and PROD
. Any feature/bug needs to be deployed first on TEST
env. for testing, once the feature/bug is ready for production it needs to be deployed on rest of the higher environments. Below is the flow that any new feature/bug needs to cover in order for it to be marked as complete:
feature/bug
--> giddh-2.0
--> beta-stage
--> beta-branch
--> production
Branch beta-stage
is considered to be the parent branch of all the new branches. This is the clean branch for development. Every contributor is required to check out their new branch from this branch only for both feature & bug.
Feature F1 deployment cycle:
<card-id>-stage
(where <card-id>
needs to be replaced by Clickup card ID) from beta-stage
. For eg: dtqvbd-stage
dtqvbd-stage
dtqvbd-stage
to giddh-2.0
(TEST env.)dtqvbd-stage
-> giddh-2.0
has conflict -> Checkout a new branch dtqvbd-test
from giddh-2.0
and take a pull from dtqvbd-stage
and resolve conflicts in branch dtqvbd-test
; raise PR from dtqvbd-test
to giddh-2.0
dtqvbd-stage
-> beta-stage
has conflict -> Take a pull from beta-stage
to branch dtqvbd-stage
and resolve conflicts in it; raise PR from dtqvbd-stage
-> beta-stage
beta-stage
-> beta-branch
has conflict -> Checkout a new branch dtqvbd-beta
from beta-branch
and take a pull from beta-stage
; raise PR from dtqvbd-beta
to beta-branch
beta-branch
-> production
has conflict -> Checkout a new branch dtqvbd-prod
from production
and take a pull from beta-branch
; raise PR from dtqvbd-prod
to production
dtqvbd-stage
SHOULD TAKE A PULL FROM giddh-2.0
dtqvbd-stage
by developer:
if branch dtqvbd-stage
has conflict with giddh-2.0
-> follow Step 4.1 abovedtqvbd-stage
-> beta-stage
dtqvbd-stage
is merged to beta-stage
, raise PR from beta-stage
to beta-branch
(follow Step 4 above in case of merge conflicts)beta-stage
is merged to beta-branch
, raise PR from beta-branch
to production
(follow Step 4 above in case of merge conflicts)All of the changes must be present on a single branch <card-id>-stage
which will act as a single source of truth for that feature/bug for other branches
dtqvbd-stage
-> beta-stage
-> beta-branch
-> production
If you face any issues in the understanding of contributing guideline then please reach out to other contributors first than trying it out for yourself. If you have any suggestions for the improvement of this guideline then also you're welcome! :smiley:
package-lock.json
conflicts:It has been observed that developers over the time of development face merge conflicts issue in package-lock.json
file. This happens when two developers run npm install
command on their respective machines and commit the code. Resolving merge conflict of lock file could be tiresome and is not guaranteed to work always and therefore, as of npm@5.7.0
, NPM has provided an automated way of doing the same.
As of
npm@5.7.0
, these conflicts can be resolved by manually fixing anypackage.json
conflicts, and then runningnpm install --package-lock-only
again. npm will automatically resolve any conflicts for you and write a merged package lock that includes all the dependencies from both branches in a reasonable tree. If --package-lock-only is provided, it will do this without also modifying your local node_modules/.
So, now you just need to resolve the conflicts of package.json
file and run the command npm install --package-lock-only
to resolve the merge conflicts of package-lock.json
file.
This is a guide to Angular syntax, conventions, and application structure. This style guide presents preferred conventions to write scalable Angular Apps with syntax that is easy to read, understand, and navigate through.
NOTE: Most of it is inherited from Angular-Style Guide.
Use consistent names for all files/symbols is a must.
Name your files/symbols following the convention of feature.type.extension.
File names must be separated with dots and dashes.
Feature and Folder Name must describe the feature it is made for. It must be hyphenate/dash-case. For eg. if I had a Component named StyleGuide
, my feature name would be style-guide
and the folder in which this file resides would also be named style-guide
.
File Type must tell about the contents of the file. It can be any of the following:
module
| component
| directive
| pipe
| service
| model
| class
| interface
| const
| config
| spec
| e2e-spec
ts
| js
| css
| scss
| json
| map
| ico
| hbs
| rules
| md
End to End test case files should be named like app.e2e-spec.ts
Class names must be in PascalCase/UpperCamelCase. So app.component.ts
should have a file named AppComponent
.
Consts should be declared in UPPER_SNAKE_CASE. So a const that contains configuration for your project may be named FIREBASE_CONFIG for eg.
Interfaces must be declared in PascalCase/UpperCamelCase. Interface names should not be prepended with an I as TypeScript guidelines discourage the I prefix. If there's an interface for machine, then it should be named as Machine
for instance.
Observables should have a $ sign appended after their names so that they could be useful when scanning through code and looking for observable values. A variable named stopwatchValue that may contain an observable value may be named stopwatchValue$
for instance.
Property and method names should be in camelCase.
Don't use _ before private property or method names.
File Grouping - Create a folder for a feature when it has multiple accompanying files (.ts
, .html
, .scss
and .spec
). Any entity or building block, that has multiple files for it, should reside in a folder of its own. For eg. if a Component named StyleGuide
has a component class file(component), a template file(html), a style file(scss), and a test case file(spec), then all these 4 files must reside under the folder named style-guide
.
Create a folder for an entity/feature if it has more than one files associated with it.
Create folders named for the feature area they represent.
Always use Angular CLI for all the file creation. This helps create files with the best and recommended conventions possible.
Name the feature module symbol reflecting the name of the feature area, folder, and file; for example, app/cart/cart.module.ts
defines CartModule
.
Apply the Single Responsibility Principle(SRP) to all components, services, and other symbols. This helps make the app cleaner, easier to read and maintain, and more testable. In order to do just that, keep the following points in mind:
Define just one thing per file. Thing here can either be class, style, tests, template etc. For eg. if a Component named StyleGuide needs to have a component class, a template file(html), some styles and tests, 4 different files should be created for each of the code type.
Files must not be more than 400 lines of code. If a file exceeds 400 lines, break it into two separate blocks, thus creating two separate files.
A file must have a single responsibility. If you need to bootstrap an Angular App, define a model object, create a component and load data from the server for eg., create 4 files: a main.ts
file to bootstrap the App, a data.model.ts
file to define the model object, a component-name.component.ts
file for defining the component, and a data.service.ts
file to fetch data from the server. And it goes without saying that it will again follow the File Grouping rule.
Platform and Bootstrapping logic should be a part of main.ts
file.
Application logic should reside in a Component or a Service.
Just like files, functions also follow the single responsibility princinple. Define small functions. A function should be no more than 75 lines.
Variable declarations that aren't reassigned must be declared as const.
Interfaces should be used for Data Models instead of classes.
Leave one empty line between third party imports and application imports.
Import lines must always be listed in alphabetical order.
Destructured symbols must be arranged alphabetically.
Import symbols from their closest locations instead of importing everything from their parent module.
All of the app's code goes in a folder named src
.
Keep related files near each other in an intuitive location. For eg. if you're building an e-commerce App, keep all files related to cart in a folder named cart.
Psychologists believe that humans start to struggle when the number of adjacent interesting things exceeds nine. So when a folder has ten or more files, it may be time to create subfolders. Create sub-folders when a folder reaches seven or more files.
Configure the IDE to hide distracting, irrelevant files such as generated .js
and .js.map
files.
Keep a flat folder structure as long as possible.
Try to be DRY (Don't Repeat Yourself). But avoid being so DRY that you sacrifice readability. For example, it's redundant to name a template cart-view.component.html
because with the .html
extension, it is obviously a view. But if something is not obvious or departs from a convention, then spell it out.
Create an NgModule for each feature area.
All feature areas should be in their own folder, with their own NgModule.
Name the module the same as the folder it is placed in.
Create dedicated modules for cases like routing, using third party packages like Angular Material, Firebase etc.
Create a feature module named SharedModule
in a shared
folder; for example, app/shared/shared.module.ts
defines SharedModule
.
Declare components, directives, and pipes in a shared module when those items will be re-used and referenced by the components declared in other feature modules.
Use the name SharedModule when the contents of a shared module are referenced across the entire application.
Don't provide services in shared modules. Services are usually singletons that are provided once for the entire application or in a particular feature module. There are exceptions, however. A service that is stateless; that is, the consumers of the service aren't impacted by new instances can be declared in it.
Import all modules required by the assets in the SharedModule
; for example, CommonModule
and FormsModule
.
Don't specify app-wide singleton providers in a SharedModule
. Intentional singletons are OK. Take care.
Collect numerous, auxiliary, single-use classes inside a core module to simplify the apparent structure of a feature module.
Call the application-wide core module, CoreModule
. Importing CoreModule
into the root AppModule
reduces its complexity and emphasizes its role as orchestrator of the application as a whole.
Create a feature module named CoreModule
in a core
folder (e.g. app/core/core.module.ts
defines CoreModule
).
Put a singleton service whose instance will be shared throughout the application in the CoreModule
(e.g. ExceptionService
and LoggerService
).
Import all modules required by the assets in the CoreModule
(e.g. CommonModule
and FormsModule
).
Gather application-wide, single use components in the CoreModule
. Import it once (in the AppModule
) when the app starts and never import it anywhere else. (e.g. NavComponent
and SpinnerComponent
).
Don't import the CoreModule
anywhere except in the AppModule
.
Export all symbols from the CoreModule
that the AppModule
will import and make available for other feature modules to use.
AppModule
is a little smaller because many app/root classes have moved to other modules. AppModule
is stable because you will add future components and providers to other modules, not this one. AppModule
delegates to imported modules rather than doing work. AppModule
is focused on its main task, orchestrating the app as a whole.
Only the root AppModule
should import the CoreModule
. Guard against reimporting of CoreModule
and fail fast by adding guard logic.
Put the contents of lazy loaded features in separate modules, in lazy loaded folders. A typical lazy loaded folder contains a routing component, its child components, and their related assets and modules.
Don't allow modules in sibling and parent folders to directly import a module in a lazy loaded feature. Directly importing and using a module will load it immediately when the intention is to load it on demand.
Give components an element selector, as opposed to attribute or class selectors.
Extract templates and styles into their own files especially when the content of the files is more than 3 lines.
Always name the template file [component-name].component.html
,
Always name the style file [component-name].component.scss
Specify component-relative URLs, prefixed with ./
.
Use the @Input
and @Output
class decorators instead of the inputs
and outputs
properties of the @Directive
and @Component
metadata.
Place @Input
or @Output
on the same line as the property it decorates.
Don't use input and output aliases except when it serves an important purpose.
Put presentation logic in the component class, and not in the template.
Don't prefix output properties
Name events without the prefix on
.
Name event handler methods with the prefix on
followed by the event name.
Limit logic in a component to only that required for the view. All other logic should be delegated to services.
Component element selectors should be in dashed-case or kebab-case. They should always be in lowercase. admin-users
for eg.
Always use a custom prefix for a component selector. This can preferably be the module name itself. For example, the prefix pb
represents Pizza Builder module and the prefix cart
represents cart module. For eg. the preview component inside a cart module would have a selector of cart-preview
.
Place properties up top followed by methods.
Place private members after public members, alphabetized.
Use the @Input
and @Output
class decorators instead of the inputs
and outputs
properties of the @Directive
metadata.
Use an alias only when the directive name is also an input property, and the directive name doesn't describe the property.
Use attribute directives when you have presentation logic without a template.
Use the @HostListener
and @HostBinding
to the host
property of the @Directive
and @Component
decorators.
Use Renderer2 instead of ElementRef's NativeElement for DOM Manipulations.
Always use lowerCamelCase for naming the selectors of directives.
Just like components, always use a custom prefix for the selector of directives. For eg. the form-validate directive in the cart module will have a selector of cartFormValidate
.
Delegate complex component logic to services
Move reusable logic to services and keep components simple and focused on their intended purpose.
Use services as singletons within the same injector. Use them for sharing data and functionality.
Create services with a single responsibility that is encapsulated by its context.
Create a new service once the service begins to exceed that singular purpose.
Provide a service with the app root injector in the @Injectable
decorator of the service.
When two different components need different instances of a service provide the service at the component level.
Use the @Injectable
class decorator instead of the @Inject parameter decorator when using types as tokens for the dependencies of a service.
Logic for making data operations and interacting with data must reside inside a service.
Make data services responsible for XHR calls, local storage, stashing in memory, or any other data operations.