@bigbinary/neeto-commons-frontend 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # neeto-commons-frontend
2
+
3
+ The commons frontend library for Neeto Applications.
4
+
5
+ ## Installation Instructions
6
+
7
+ Install from npm:
8
+
9
+ ```bash
10
+ yarn add "@bigbinary/neeto-commons-frontend@0.0.1"
11
+ ```
12
+
13
+ This package relies on the host project's tailwind configuration. So add
14
+ neeto-commons-frontend to your project's tailwind.config.js file:
15
+
16
+ ```js
17
+ module.exports = {
18
+ purge: {
19
+ content: [
20
+ // ... other content directories
21
+ "./node_modules/@bigbinary/neeto-commons-frontend/**/*.js",
22
+ ],
23
+ },
24
+ // ... other tailwind config options
25
+ };
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ This package exports four different sets of functions and components. Click on
31
+ them to read more:
32
+
33
+ 1. [Initializers](./docs/initializers/README.md)
34
+ 2. [React utilities](./docs/react/README.md)
35
+ 3. [General utility functions](./docs/utils/README.md)
36
+
37
+ ## Development instructions
38
+
39
+ 1. Clone this repository.
40
+ 2. Run `yarn install` to download the dependencies and setup the development
41
+ environment.
42
+ 3. Have a host application ready.
43
+ 4. Run `yarn build --watch` to automatically transpile code as you save the
44
+ file. You can omit the `--watch` flag if you want to run the build only once.
45
+ 5. In a different terminal, run `yalc publish` to publish the
46
+ neeto-commons-frontend to the local yalc store.
47
+ 6. Run `yalc install` to install the neeto-commons-frontend to the host
48
+ application.
49
+ 7. After making all changes to `neeto-commons-frontend`, run `yal push` to push
50
+ the changes to the host application.
51
+ 8. Video explanation on how to use yalc: https://vimeo.com/722958162/9e931b640c
52
+
53
+ ## Building and releasing.
54
+
55
+ This is how releases are managed in this repo.
56
+
57
+ - We will create a branch with the next release version as its name (`1.0.x`)
58
+ from master branch.
59
+ - Version in
60
+ [README.md](https://github.com/bigbinary/neeto-commons-frontend/blob/master/README.md#L10)
61
+ and
62
+ [package.json](https://github.com/bigbinary/neeto-commons-frontend/blob/master/package.json#L3)
63
+ will be updated to the current branch name.
64
+ - From now on, we can install the package to neeto-applications using the
65
+ version `1.X.Y`.
66
+ - We will create a draft PR of this branch targeting master. This keeps the
67
+ branch in sync with master branch (bot-bigbinary will auto-merge the changes).
68
+ - When all features have been built, we will deploy it to all neeto-applications
69
+ locally using `yalc` package manager. We won't raise PR until the deployment
70
+ and verification is successfully done locally for all neeto-applications. The
71
+ usage of yalc is explained in this video:
72
+ https://vimeo.com/722958162/9e931b640c
73
+ - In case if we notice any problem during verification, like any missed edge
74
+ cases, we will fix the problem in this repo and re-run `yalc push` to install
75
+ the latest changes.
76
+ - Once everything is fine and the verification is complete, we will create a
77
+ [new github release](https://github.com/bigbinary/neeto-commons-frontend/releases/new)
78
+ from `1.X.Y` branch with the exact same name for the tag (`1.X.Y`). The target
79
+ branch will be kept as `1.X.Y`. This will create a tag from the latest `1.X.Y`
80
+ branch and this ensures that the latest commit on that branch will remain
81
+ intact even if that branch gets deleted.
82
+ - Whenever a new release is created with a new version number, the github
83
+ actions will automatically publish the built package to npm.
84
+ - Now we will squash and merge the PR `1.X.Y` to master and delete its source
85
+ branch. This will delete all commits except the top one (since we have created
86
+ a tag with it).
87
+ - Immediately, we will open another branch with the next version (`1.X.Y`) and
88
+ the cycle will continue.
89
+ - Now we can run `yalc remove neeto-commons-frontend` to remove yalc based
90
+ package and run `yarn add neeto-commons-frontend@1.X.Y` to fetch the latest
91
+ changes from npm in all repos and raise PR. You might be able to slightly
92
+ tweak this script to get the job done:
93
+ https://gist.github.com/jagannathBhat/42a584748d97fe134f0abadb191ef29a
@@ -0,0 +1,195 @@
1
+ 'use strict';
2
+
3
+ var objects = require('pure/objects');
4
+ var axios = require('axios');
5
+ var ramda = require('ramda');
6
+ var mixpanel = require('mixpanel-browser');
7
+ var i18n = require('i18next');
8
+ var reactI18next = require('react-i18next');
9
+
10
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
+
12
+ var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
13
+ var mixpanel__default = /*#__PURE__*/_interopDefaultLegacy(mixpanel);
14
+ var i18n__default = /*#__PURE__*/_interopDefaultLegacy(i18n);
15
+
16
+ var _document$getElements, _document$getElements2;
17
+ window.globalProps = objects.keysToCamelCase(JSON.parse(((_document$getElements = document.getElementsByClassName("root-container")[0]) === null || _document$getElements === void 0 ? void 0 : (_document$getElements2 = _document$getElements.dataset) === null || _document$getElements2 === void 0 ? void 0 : _document$getElements2.reactProps) || "{}"));
18
+ objects.deepFreezeObject(window.globalProps);
19
+
20
+ function _defineProperty(obj, key, value) {
21
+ if (key in obj) {
22
+ Object.defineProperty(obj, key, {
23
+ value: value,
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true
27
+ });
28
+ } else {
29
+ obj[key] = value;
30
+ }
31
+
32
+ return obj;
33
+ }
34
+
35
+ var HEADERS_KEYS = {
36
+ xAuthEmail: "X-Auth-Email",
37
+ xAuthToken: "X-Auth-Token",
38
+ xCsrfToken: "X-CSRF-TOKEN"
39
+ };
40
+
41
+ var resetAuthTokens = function resetAuthTokens() {
42
+ ramda.values(HEADERS_KEYS).forEach(function (header) {
43
+ delete axios__default["default"].defaults.headers[header];
44
+ });
45
+ };
46
+
47
+ var setAxiosDefaults = function setAxiosDefaults() {
48
+ axios__default["default"].defaults.baseURL = "/";
49
+ setAuthHeaders();
50
+ registerIntercepts();
51
+ };
52
+
53
+ var setAuthHeaders = function setAuthHeaders() {
54
+ var _globalProps$user, _globalProps$user2;
55
+
56
+ axios__default["default"].defaults.headers = _defineProperty({
57
+ Accept: "application/json",
58
+ "Content-Type": "application/json"
59
+ }, HEADERS_KEYS.xCsrfToken, document.querySelector('[name="csrf-token"]').getAttribute("content"));
60
+ var token = (_globalProps$user = globalProps.user) === null || _globalProps$user === void 0 ? void 0 : _globalProps$user.authenticationToken;
61
+ var email = (_globalProps$user2 = globalProps.user) === null || _globalProps$user2 === void 0 ? void 0 : _globalProps$user2.email;
62
+
63
+ if (token && email) {
64
+ axios__default["default"].defaults.headers[HEADERS_KEYS.xAuthEmail] = email;
65
+ axios__default["default"].defaults.headers[HEADERS_KEYS.xAuthToken] = token;
66
+ }
67
+ };
68
+
69
+ var handleSuccessResponse = function handleSuccessResponse(response) {
70
+ var _response$config = response.config,
71
+ _response$config$tran = _response$config.transformResponseCase,
72
+ transformResponseCase = _response$config$tran === void 0 ? true : _response$config$tran,
73
+ _response$config$incl = _response$config.includeMetadataInResponse,
74
+ includeMetadataInResponse = _response$config$incl === void 0 ? false : _response$config$incl;
75
+
76
+ if (transformResponseCase && response.data) {
77
+ response.data = objects.keysToCamelCase(response.data);
78
+ }
79
+
80
+ return includeMetadataInResponse ? response : response.data;
81
+ };
82
+
83
+ var handleErrorResponse = function handleErrorResponse(error) {
84
+ var _error$response, _error$response2;
85
+
86
+ if (((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) === 404) {
87
+ window.location.href = "/page-not-found";
88
+ } else if (((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.status) === 401) {
89
+ resetAuthTokens();
90
+ setTimeout(function () {
91
+ var redirectTo = window.location.pathname === "/login" ? "/login" : "/login?redirect_uri=".concat(encodeURIComponent(window.location.href));
92
+ window.location.href = redirectTo;
93
+ }, 300);
94
+ }
95
+
96
+ return Promise.reject(error);
97
+ };
98
+
99
+ var cleanupCredentialsForCrossOrigin = function cleanupCredentialsForCrossOrigin(request) {
100
+ if (!request.url.includes("://")) return request;
101
+ if (request.url.includes(window.location.hostname)) return request;
102
+ return ramda.evolve({
103
+ headers: ramda.omit(ramda.values(HEADERS_KEYS))
104
+ })(request);
105
+ };
106
+
107
+ var transformDataToSnakeCase = function transformDataToSnakeCase(request) {
108
+ var _request$transformReq = request.transformRequestCase,
109
+ transformRequestCase = _request$transformReq === void 0 ? true : _request$transformReq;
110
+ if (!transformRequestCase || !request.data) return request;
111
+ return ramda.evolve({
112
+ data: objects.keysToSnakeCase
113
+ })(request);
114
+ };
115
+
116
+ var registerIntercepts = function registerIntercepts() {
117
+ axios__default["default"].interceptors.request.use(ramda.pipe(cleanupCredentialsForCrossOrigin, transformDataToSnakeCase));
118
+ axios__default["default"].interceptors.response.use(handleSuccessResponse, handleErrorResponse);
119
+ };
120
+
121
+ setAxiosDefaults();
122
+
123
+ var isProduction = process.env.NODE_ENV === "production";
124
+ var isTokenPresent = !!process.env.MIXPANEL_TOKEN;
125
+ var isUserLoggedIn = !ramda.either(ramda.isEmpty, ramda.isNil)(globalProps.user);
126
+
127
+ if (isProduction && isTokenPresent && isUserLoggedIn) {
128
+ mixpanel__default["default"].init(process.env.MIXPANEL_TOKEN);
129
+ mixpanel__default["default"].people.set({
130
+ $email: globalProps.user.email,
131
+ $fist_name: globalProps.user.firstName,
132
+ $last_name: globalProps.user.lastName
133
+ });
134
+ mixpanel__default["default"].identify(globalProps.user.email);
135
+ } else {
136
+ /*
137
+ We need to initialize mixpanel with a bogus token in development and test environment to
138
+ prevent mixpanel library from throwing an error when we use mixpanel.track() method in react components.
139
+ */
140
+ mixpanel__default["default"].init("TEST_TOKEN");
141
+ }
142
+
143
+ var neetoCommons = {
144
+ errorPage: {
145
+ pageDoesNotExist: "Page does not exist.",
146
+ goToHome: "Go home"
147
+ },
148
+ sidebar: {
149
+ profile: "Profile",
150
+ orgSettings: "Organization Settings",
151
+ logout: "Logout",
152
+ help: "Help"
153
+ },
154
+ common: {
155
+ actions: {
156
+ cancel: "Cancel",
157
+ save: "Save"
158
+ }
159
+ },
160
+ toastr: {
161
+ success: {
162
+ copiedToClipboard: "Copied to clipboard!"
163
+ }
164
+ },
165
+ notice: {
166
+ errorOccurred: "Some error occurred."
167
+ }
168
+ };
169
+ var en = {
170
+ neetoCommons: neetoCommons
171
+ };
172
+
173
+ var initializeI18n = function initializeI18n(resources) {
174
+ i18n__default["default"].use(reactI18next.initReactI18next).init({
175
+ resources: ramda.mergeDeepLeft({
176
+ en: {
177
+ translation: en
178
+ }
179
+ }, resources),
180
+ lng: "en",
181
+ fallbackLng: "en",
182
+ interpolation: {
183
+ escapeValue: false,
184
+ skipOnVariables: false
185
+ }
186
+ });
187
+ };
188
+
189
+ /* eslint-disable import/order */
190
+ function initializeApplication(_ref) {
191
+ var translationResources = _ref.translationResources;
192
+ initializeI18n(translationResources);
193
+ }
194
+
195
+ module.exports = initializeApplication;
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@bigbinary/neeto-commons-frontend",
3
+ "version": "0.0.1",
4
+ "description": "A package encapsulating common code across neeto projects including initializers, utility functions, common components and hooks and so on.",
5
+ "repository": "git@github.com:bigbinary/neeto-commons-frontend.git",
6
+ "author": "Amaljith K <amaljith.k@bigbinary.com>",
7
+ "license": "apache-2.0",
8
+ "scripts": {
9
+ "prepare": "husky install",
10
+ "sync_with_wheel": "./.scripts/sync_with_wheel.sh",
11
+ "test": "TZ=UTC jest",
12
+ "build": "NODE_ENV=production rollup -c rollup.config.js",
13
+ "watch": "rollup -c rollup.config.js --watch"
14
+ },
15
+ "files": [
16
+ "initializers*.js",
17
+ "react*.js",
18
+ "utils*.js",
19
+ "pure*.js"
20
+ ],
21
+ "lint-staged": {
22
+ "**/*.{js,jsx,json}": [
23
+ ".scripts/fix-lints.sh"
24
+ ]
25
+ },
26
+ "devDependencies": {
27
+ "@babel/eslint-parser": "^7.18.2",
28
+ "@babel/plugin-transform-runtime": "^7.18.5",
29
+ "@babel/preset-env": "^7.17.10",
30
+ "@babel/preset-react": "^7.16.7",
31
+ "@bigbinary/neeto-icons": "^1.8.35",
32
+ "@bigbinary/neetoui": "^3.5.11",
33
+ "@honeybadger-io/react": "2.0.1",
34
+ "@rollup/plugin-alias": "^3.1.9",
35
+ "@rollup/plugin-babel": "^5.3.1",
36
+ "@rollup/plugin-commonjs": "^22.0.0",
37
+ "@rollup/plugin-json": "^4.1.0",
38
+ "@rollup/plugin-node-resolve": "^13.3.0",
39
+ "@svgr/rollup": "^6.2.1",
40
+ "@testing-library/jest-dom": "5.16.2",
41
+ "@testing-library/react": "12.1.3",
42
+ "@testing-library/react-hooks": "^8.0.0",
43
+ "@testing-library/user-event": "13.5.0",
44
+ "autoprefixer": "^10.4.7",
45
+ "axios": "^0.27.2",
46
+ "babel-jest": "27.0.6",
47
+ "dayjs": "1.11.1",
48
+ "eslint": "^8.15.0",
49
+ "eslint-config-prettier": "^8.5.0",
50
+ "eslint-plugin-import": "^2.26.0",
51
+ "eslint-plugin-jam3": "^0.2.3",
52
+ "eslint-plugin-json": "^3.1.0",
53
+ "eslint-plugin-neeto": "^1.0.8",
54
+ "eslint-plugin-prettier": "^4.0.0",
55
+ "eslint-plugin-promise": "^6.0.0",
56
+ "eslint-plugin-react": "^7.29.4",
57
+ "eslint-plugin-react-hooks": "4.2.1-alpha-13455d26d-20211104",
58
+ "eslint-plugin-unused-imports": "^2.0.0",
59
+ "formik": "^2.2.9",
60
+ "husky": "^7.0.4",
61
+ "i18next": "21.7.0",
62
+ "jest": "27.5.1",
63
+ "lint-staged": "^12.3.7",
64
+ "mixpanel-browser": "^2.45.0",
65
+ "prettier": "^2.6.2",
66
+ "ramda": "^0.28.0",
67
+ "react": "^17.0.2",
68
+ "react-dom": "17.0.2",
69
+ "react-i18next": "11.16.8",
70
+ "react-router-dom": "^5.2.0",
71
+ "rollup": "^2.76.0",
72
+ "rollup-plugin-analyzer": "^4.0.0",
73
+ "rollup-plugin-cleaner": "^1.0.0",
74
+ "rollup-plugin-peer-deps-external": "^2.2.4",
75
+ "yup": "^0.32.11"
76
+ },
77
+ "dependencies": {},
78
+ "peerDependencies": {
79
+ "@bigbinary/neeto-icons": "^1.8.35",
80
+ "@bigbinary/neetoui": "^3.5.11",
81
+ "@honeybadger-io/react": "2.0.1",
82
+ "axios": "^0.27.2",
83
+ "dayjs": "1.11.1",
84
+ "formik": "^2.2.9",
85
+ "i18next": "21.7.0",
86
+ "mixpanel-browser": "^2.45.0",
87
+ "ramda": "^0.28.0",
88
+ "react": "^17.0.2",
89
+ "react-i18next": "11.16.8",
90
+ "react-router-dom": "^5.2.0",
91
+ "yup": "^0.32.11"
92
+ }
93
+ }