Prerequisite reference study materials
Development and implementation team
JavaScript ES6, ES7, ES8: Learn to Code on the Bleeding Edge (Full Course)
Full React Course 2020 - Learn Fundamentals, Hooks, Context API, React Router, Custom Hooks
Development team
Frontend Components
Broadly, the frontend components can be categorized as followings:
CLI Tool
Templates
CSS Library
Component Libraries
UI Modules
The CSS Library, Component Libraries, and UI modules are based on templates created by CLI Tool.
Nomenclature
The first line contains the Architecture Component name or info, the second line has npm-package and in the bracket, we have a template based on which the component will be created.
CLI Tool
This tool will be used to bootstrap libraries and micro frontend frameworks for the DIGIT platform. It contains a “template” folder, which will have several starter apps.
The following will be in the template:
Default (WIP) - A default pure js template.
React-component (Done) - Starter template to make the component library based on React.
Module (React based) - Micro frontend framework, which will act as a base for different modules we will create.
… more to come
Features
Easy-to-use CLI
Handles all modern JS features
Bundles
commonjs
andes
module formatscreate-react-app for example usage and local dev for React-based libraries
Rollup for bundling
Babel for transpiling
Supports complicated peer-dependencies
Supports CSS modules
Example
Answer some basic prompts about your module, and then the CLI will perform the following steps:
copy over the template
install dependencies via yarn or npm
link packages together for local development
initialize local git repo
Templates
The templates have the following folder structure:
The components related to the template are inside the src
folder of the template and an example is created to use and showcase the app created by the template.
Architecture
We have two repos:
digit-ui-internals
- https://github.com/egovernments/digit-ui-internalsMeant for eGov development team to build components and default modules.
Contains following modules:
CSS Library
UI Components (presently
react-components
)Utils Library: Contains Services, Localization handling and React Hooks.
UI Modules
Core - containing login, routing and global state.
PGR
FSM
PT
Payment
digit-ui
- https://github.com/egovernments/digit-uiMeant for state team to manage, make changes and deploy
Import
digit-ui-internals
modules.Customizations
View
Services
Build and deploy scripts
Dockerfile & nginx.conf
build-config.yaml
CSS Library
The CSS Library will have all the classes both in the module and compiled form.
Can be imported like
import "@egovernments/digit-ui.css/Button"
or like this for full CSS import
import "@egovernments/digit-ui.css"
Component Libraries
Component Library will have the set of all the required components defined in them.
# Atoms <egov-button text action /> <egov-checkbox name value /> <egov-textarea placeholder /> # Molecules <egov-list data> <egov-list-item /> </egov-list> <egov-searchbox placeholder action /> <egov-list-filter> <egov-input /> <egov-list data /> </egov-list-filter>
Utils Library
This will have the followings:
Workflows
API handling - API caching and handling strategies will be here, imported, and shared by all modules. Published as a function, can be used by anyone.
import { fetchAPI } from '@egovernments/digit-utils' async function searchProperty() { const { data, error } = await fetchAPI("/api/searchProperty"); if (error) return ""; return data; }
Internationalization (i18n)
<egov-textarea placeholder="i18n.PGR_NEW_COMMENTS" />
getConfig
This will be like MDMS config service
The default and state configs will be stored on GitHub.
getConfig will fetch the latest config on runtime and initiate the module.
default config:
{ "name": "create_complaint", "action": "createComplaint", "init": "newComplaintInit", "saveUrl": "/rainmaker-pgr/v1/requests/_create", "redirectionRoute":"/complaint-submitted", "fields": [{ "id": "city", "name": "city", "type": "dropdown", "labelText": "{{i18n.CORE_COMMON_CITY}}", "hintText": "{{i18n.CS_CREATECOMPLAINT_SELECT_PLACEHOLDER}}", "errMessage": "{{i18n.CS_ADDCOMPLAINT_COMPLAINT_TYPE_PLACEHOLDER}}", "required": true, "action": "createComplaint.updateDependentFields" }, { "id": "address", "name": "address", "type": "input-textarea", "labelText": "{{i18n.CS_ADDCOMPLAINT_LOCATION}}", "hintText": "{{i18n.CS_COMPLAINT_DETAILS_LOCATION}}", "errMessage": "", "action": "" }, { "id": "media", "name": "media", "type": "input-file", "errMessage": "{{i18n.CS_FILE_UPLOAD_FAILED}}", "action": "" }], "buttons": [{ "id": "addComplaint-submit-complaint", "name": "submit", "labelText": "{{i18n.CS_ADDCOMPLAINT_ADDITIONAL_DETAILS_SUBMIT_COMPLAINT}}", "action": "createComplaint.submit" }] }
state config:
{ "name": "create_complaint", "redirectionRoute":"__delete__", "saveUrl": "__delete__", "fields": [{ "__action__": "insert_after", "__property__": "address", "id": "landmark", "name": "landmark", "type": "input-text", "labelText": "{{i18n.CS_ADDCOMPLAINT_LANDMARK}}", "hintText": "{{i18n.CS_ADDCOMPLAINT_LANDMARK_PLACEHOLDER}}", "errMessage": "{{i18n.PT_LANDMARK_ERROR_MESSAGE}}", "action": "", }, { "__action__": "update", "id": "address", "labelText": "{{i18n.CS_ADDCOMPLAINT_LOCATION}}", "hintText": "{{i18n.CS_COMPLAINT_DETAILS_LOCATION}}", }] }
getConfig:
# @egovernments/digit-utils exports.getConfig = async (state, module = "", screen = "") => { let path = state; if (module) { path = `${path}.${module}`; if (screen) { path = `${path}.${screen}` } } const { data, error } = await fetchAPI(`/api/_get?config=${path}`) if (error) return {}; return data; } # Module import { getConfig } from '@egovernments/digit-utils' const compaintConfig = getConfig("pb", "pgr", "create_complaint");
Modules
The module will be a black box for the states, they will only access throw node_modules
or CDN
. Any state-specific components can be passed during the initialization of the module inside the state’s employee or citizen app.
The modules structure will look like:
The module code is in src
and an example
is created to show how it will be imported in the core app and can be modified at the state level.
The components passed to the module from the core app are:
components (optional): Any custom component that is created outside of module scope.
onRouteChange: This is a callback function that will be called by the module itself to alert the core app about the route changes so the sidebar handler can change the active item.
theme (optional): This is a set of CSS variables which states can modify to change the theme of the module.
Eg, PGRModule:
import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-rdux'; import { getConfig } from '@egovernments/digit-utils'; import configureStore from './store'; import applyTheme from "./utils/theme"; import PGRApp from './App'; const PGRModule = ({ config, components, onRouteChange, theme }) => { applyTheme(theme); return <Provider store={configureStore(config)}> <PGRApp components={components} onRouteChange={onRouteChange} /> </Provider> } function initPGR = ({ state, element, components, onRouteChange, theme = {} }) => { getConfig(state, "pgr").then(config => { ReactDOM.render( <PGRModule config={config} components={PGRComponents} onRouteChange={onRouteChange} theme={theme} />, document.getElementById(element)); }) } export default initPGR
Modules will have the followings inbuilt
Theme - this may change if we later decide to use any
css-in-js
library, likestyled-components
.Components
Routes
State management
Business logic
API integrations
Employee / Citizen App
The app will import the developed module.
import './index.css' import { initPGR } from '@egovernments/pgr-module'; import punjabLogo from './assets/logo.png' const theme = { "--primary-color": "#3f51b5", "--text-color": "#212121" } const PGRComponents = { "logo": punjabLogo } const initPunjabPGR = (onRouteChange) => initPGR({ state: "pb", element: "#appWrapper", components: PGRComponents, onRouteChange, theme }); export default initPunjabPGR;
Another method will be importing from CDN
:
import './index.css' import punjabLogo from './assets/logo.png' const theme = { "--primary-color": "#3f51b5", "--text-color": "#212121" } const PGRComponents = { "logo": punjabLogo } const initPunjabPGR = (onRouteChange) => { import("https://unpkg.com/@egovernments/pgr-module").then(({ initPGR }) => { initPGR({ state: "pb", element: "#appWrapper", components: PGRComponents, onRouteChange, theme }) }) } export default initPunjabPGR;
At the next phase, the Employee and Citizen app can be rewritten to be a single app with role and permissions based rendering.