jbgoldman1104 / ml-bose-memorial

ML Bose Memorial Template

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Kleeen Logo

Kleeen Software / Template

HTML5 CSS3 SASS Material UI NodeJS Express TypeScript ReactJS GraphQL Redux NPM Babel Git GitHub

🧰 1. Prerequisites

You need to have a basic understanding of JavaScript, Node.js, and NPM to continue.

1.1 Install Node Version Manager

We recommend to use NVM.

  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash

Check GitHub repository to verify any change in the installation process.

1.2 Setup your .nvmrc file

This project has a .nvmrc file containing the node version number supported and tested. Check the repository to configure your terminal.

Calling nvm use automatically in a directory with a .nvmrc file. If it finds it, it will switch to that version; if not, it will use the default version.

1.3 Install Node
  nvm install <NODE_VERSION_ON_NVMRC_FILE>
  nvm use <NODE_VERSION_ON_NVMRC_FILE>
🧭 2. Understand your workspace Run:
  npm run dep-graph

to see a diagram of the dependencies of your projects.

⏳ 3. Setup
3.1 Install packages
  npm install | bash
🏎 4. Run project

You can run this template using the following commands in a different console.

To run both frontend and backend:

  npm run start

Client only

  npm run start:client

API only

  npm run start:api
🚜 5. Build
5.1 Build
  nx build cloud

to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

πŸš€ 6. Deploy
6.1 Deploy with Serverless Framework
  npm install -g serverless@<CHECK_VERSION_AT_buildspec.yml_FILE>
πŸ§ͺ 7. Testing
7.1 Unit tests
  nx test cloud

to execute the unit tests via Jest.

  npm run affected:test

to execute the unit tests affected by a change.

7.2 E2E (end-to-end) tests

By default, Nx uses Cypress to run E2E tests.

Start Cypress with

  nx e2e {appName}-e2e --watch

to execute the end-to-end tests in Interactive Watch Mode.

Run e2e tests for the applications affected by changes.

  npm run affected:e2e

Run the respective .spec Change files in your app, Cypress should re-run its tests.

πŸ” 8. Authentication
8.1 How to add custom integrations

Kleeen Software provides the option to extend the default authentication or implements new ones.

To support custom workflows, @kleeen/auth library exposes a set of types and interfaces.

import { Integrations, KSAuth } from '@kleeen/auth';
KSAuth.configure({
  authenticationHandler: new Integrations.CognitoAuthenticationHandler(),
});
8.2 IAuthenticationHandler base definition

IAuthenticationHandler interface is the blueprint to implement different workflows.

Here is an example of a custom implementation:

import 'firebase/auth';
import firebase from 'firebase/app';
import { Integrations } from '@kleeen/auth';

/* Your web app's Firebase configuration */
const firebaseConfig = {
  apiKey: '',
  authDomain: '',
  databaseURL: '',
  projectId: '',
  storageBucket: '',
  messagingSenderId: '',
  appId: '',
};

export class FirebaseAuthenticationHandler extends Integrations.AuthenticationHandler {
  constructor(config: typeof firebaseConfig = firebaseConfig) {
    super();
    /* Initialize Firebase */
    firebase.initializeApp(firebaseConfig);
  }

  /* Sign in a register user using username and password */
  async signIn(options: SignInOptions): Promise<IUser> {
    const { password, username } = options;
    const response = await firebase.auth().signInWithEmailAndPassword(username, password);
    return {
      ...response,
      email: response?.user?.email,
      getUsername: () => response?.user?.displayName,
      role: null, // Set here the default for the current user
      roles: [], // set here the list of roles assigned for the current user
    };
  }

  /**
   A function that takes a new context object and update it if needed
  @param {Record<string, any>} context is an existing context
  @return {Record<string, any>} with an updated context
  **/

  setContext(context: Record<string, any>): Record<string, any> {
    return {
      ...context,
      headers: {
        ...context.headers,
        MY_CUSTOM_HEADER: 'GOING HERE',
      },
    };
  }
}
8.3 Update the authentication handler

Following is the example of configuring the KSAuth class to use the custom implementation.

import { FirebaseAuthenticationHandler } from './google-firebase';
import firebaseConfiguration from './custom-implementations/firebase.json';

KSAuth.configure({
  authenticationHandler: new FirebaseAuthenticationHandler(firebaseConfiguration),
});
8.4 Running unit tests

Run

  nx test auth

to execute the unit tests via Jest.

8.5 Login Role and UI Access Manager Integration

To connect a login to the FE app, it's needed to implement an AuthenticationHandler like libs/auth/src/lib/integrations/aws-cognito/aws-cognito.ts, that is the one used in our own prototypes.

When implementing this 'authenticator,' the currentAuthenticatedUser function needs to return a shape like { ...anyUserInfoNeeded, role: 'ADMIN' }, role its required, but if it's not provided, the access-control did not interfere with anything.

NOTES
  • the role values depend on what the apps/cloud/src/app/settings/role-access-keys.json have on the permissions and can be any string.
  • The role-access-keys.json is created for our generated UI proposes grouping each page into NAVIGATION key and next each page have WIDGETS, VIEWS and can have more specific components also can be extended but to also reflect access on the UI, the AccessControl component is needed.
  • the UI implementation follows the rules and uses the access-manager module from the ks-ui-react.
🎫 9. Onboarding integration
9.1 Relate paths

onboarding settings = apps/cloud/src/app/modules/generated/components/on-boarding/on-boarding.settings.ts

9.2 How onboarding decides when to show

The condition used to decide if the onBoarding shows is a combination between the onboarding settings (because the feature itself can be off) and the onboarding preferences redux state, the path in the redux state used for getting if the onBoarding should show is endUserPreference.onBoardingPreferences.showOnBoarding. That onBoardingPreferences is one of the props receive in the component below and can be manipulated with the response of the query getOnboardingPreferences (needs to be implemented in custom API).

9.2 Queries called by onboarding

getOnboardingPreferences: is called at the start of onboarding, it filled the onBoardingPreferences state with the response so can be used to inject data to this custom component or disable the onboarding for certain users or cases.

setOnBoardingPreference: is call with the action preferencesActions.setOnBoardingPreference and it can be used to store some data related to onBoarding or set info related to user like turn off next onboarding for the same user.

9.2 PreferencesActions actions injected

With the action preferencesActions.setOnBoardingPreference you can change the onBoardingPreferences state and it also calls a BE query setOnBoardingPreference (needs to be implemented in custom API) to save preferences for the onboarding (for example setting the flag in real BE to false so the user does not get the onboarding a second time).

9.2 Implemented in custom API

Some of the queries that the onboarding throws does not have a BE query the catch it, all the firm and shape is defined on the FE but it needs to be added to the custom API schema and resolvers y order to getting it on the GraphQL middleware.

example on apps/api/src/graphql/custom/operations/custom-schema.ts

export const customSchema = gql`
  extend type Query {
    getOnboardingPreferences: OnboardingPreferences
    setOnboardingPreferences(input: PreferencesInput): OnboardingPreferences
  }
`;

on apps/api/src/graphql/custom/operations/custom-resolvers.ts

export const customResolvers: IResolvers = {
  Query: {
    getOnboardingPreferences: () => ({ showOnBoarding: true }),
    setOnboardingPreferences: (input) => ({ success: true }),
  },
};

Please refer to the official documentation about how to add your custom schema.

For more information please visit Apollo GraphQL Documentation

All in these files can change except the shape and name of the export component.

πŸ›ƒ 10. Custom provider integration
10.1 Create a new custom provider

As End-Developers, it is quite common that you need to share some data, and that data needs to be accessible by many components at different nesting levels inside your application. Also, you might need to integrate third party tools which should be enabled at application level, and not at workflow level.

In the path apps/cloud/src/app/modules/custom/providers/ you can add any custom global provider you need, for example you can use a higher order component pattern to wrap the whole application with your custom global provider; In this case, let's integrate a third-party tool like Intercom, using the react-use-intercom module:

Add a new file called intercom-provider.ts, then add the following higher order component:

import { IntercomProvider } from 'react-use-intercom';
import { environment } from '../../../../environments/environment';

const intercomAppId = 'your-intercom-app-id';

interface IntercomProviderProps {
  children: JSX.Element; // This represents the whole application
}

// This is the way to wrap the whole application with your Custom Global Provider
export function CustomIntercomProvider({ children }: IntercomProviderProps) {
  return <IntercomProvider appId={intercomAppId}>{children}</IntercomProvider>;
}
10.2 Add our new custom provider

For those reasons, Kleeen provides an easy way to add Custom Global Providers to your application, so you can fulfill those requirements, and more simply going to apps/cloud/src/app/modules/custom/providers/index.ts file, there you have this custom barrel:

export const CustomProviders = [];

Import and add the new Custom Global Provider that we just did to the Custom Providers catalog:

import { CustomIntercomProvider } from './intercom-provider';

export const CustomProviders = [CustomIntercomProvider];
πŸ›ƒ 11. Initialize third party libraries
11.1 Add third party libraries to initialize

As End-Developers, it is common that you need to call or initialize third-party libraries on top of the react chain.

In the path apps/cloud/src/app/modules/custom/third-parties/third-party-initialize.ts you can add any function or hook to the thirdPartyInitialize array, so we can initialize Intercom as a custom third party as it is in the example below:

import { useIntercom } from 'react-use-intercom';

export const thirdPartyInitialize = [useIntercom];
πŸ”— 12. Quick Links
12.1 Links to the project files

As End-Developers, it is common that you need to have direct links to important source files so that you don't have to hunt for those files.

You can find your project files:

12.2 Links to documentation files
🏁 13. Quick Start
13.1 Running the project

As an End Developer you may need to have a quick start guide on how to run the Kleeen Project, please follow the next steps:

The first step is to have the latest version of dependencies run:
  npm install

After the dependencies have been installed it is needed to have the Backend and the Frontend running in separate terminals

Client only

  npm run start:client

In the package.json file you can specify the port the Front End is going to run for this script, by adding the option --port=<PORT_NUMBER> for example --port=4201.

API only

API will run by default in port 3002

  npm run start:api

If needed you can also have the Backend and Frontend running in the same terminal

Backend and Frontend

  npm run start

In your browser go to localhost:4200 (or your default port number) Congratulations!
At this point your Kleeen project should be up and running.

πŸ—ΊοΈ 14. System Architecture

Inside these folders are both the visualization code and the api code. The structures where the elements of both the front-end and the back-end are located are presented below.

14.1 Back-End

14.1.1 Filters

Here are the jsons with the construction of the filter references for each of the views.

14.1.2 Graphql Custom

Here is the logic of the requests to the back-end. Inside this folder there are several folders, which have the request scripts.

14.1.3 Graphql Generated

Here are the queries and mapping of the api to which they are going to be consumed.

14.2 Front-End

14.2.1 Modules Kleeen-managed

Inside here is part of the research interaction. This code is static and is not modified by the user, it is part of the kleeen implementation.

14.2.2 Modules Custom

Here are the code generation for custom views. These are divided by folders which have the name of your workflow. Inside each of the folders there are files of type js. Which have unique names. In order to know which custom each file corresponds to, you must visit the "Generated" files and within this folder there must be a workflow with the same name. In there, there is a settings file and look for the document called 'widgets.ts', in there look for the custom widget whose code you want to change. When it is found, see the name and later look for it inside the custom folder and inside the folder with the same name in the workflow. In this section a standard code is created, which must be manipulated by the developer, to include their own code.

14.2.3 Modules Generated

Here all the views that a user can access are generated. For each of the views a folder is generated with the name of the workflow, which is the name of the url to which we are going to access. Inside each folder there is a file index.jsx, which has auto-generated code and there is also a folder with the name of settings which can have different files. These files internally have a configuration json which tells our end-product what to display.

14.2.4 Settings

In this part of the code there are global settings, such as the 'translate', which is auto-generated and has the texts to be displayed depending on the selected language. Also the roles or accesses that a group of users can have.

Made with ❀️ by Kleeen Software 2022

About

ML Bose Memorial Template


Languages

Language:TypeScript 87.0%Language:JavaScript 7.1%Language:SCSS 5.7%Language:Shell 0.2%Language:HTML 0.0%Language:CSS 0.0%