ui-soxo-bootstrap-core 2.4.24 → 2.4.25-dev.7

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.
Files changed (33) hide show
  1. package/.github/workflows/npm-publish.yml +37 -15
  2. package/README.md +260 -0
  3. package/core/components/extra-info/extra-info-details.js +109 -126
  4. package/core/components/landing-api/landing-api.js +22 -30
  5. package/core/lib/Store.js +20 -18
  6. package/core/lib/components/index.js +4 -1
  7. package/core/lib/components/sidemenu/sidemenu.js +153 -256
  8. package/core/lib/components/sidemenu/sidemenu.scss +39 -26
  9. package/core/lib/hooks/index.js +2 -12
  10. package/core/lib/hooks/use-otp-timer.js +99 -0
  11. package/core/lib/pages/login/login.js +255 -139
  12. package/core/lib/pages/login/login.scss +140 -32
  13. package/core/models/dashboard/dashboard.js +14 -0
  14. package/core/models/doctor/components/doctor-add/doctor-add.js +403 -0
  15. package/core/models/doctor/components/doctor-add/doctor-add.scss +32 -0
  16. package/core/models/menus/components/menu-add/menu-add.js +230 -268
  17. package/core/models/menus/components/menu-lists/menu-lists.js +126 -89
  18. package/core/models/menus/components/menu-lists/menu-lists.scss +9 -0
  19. package/core/models/menus/menus.js +247 -267
  20. package/core/models/roles/components/role-add/role-add.js +269 -227
  21. package/core/models/roles/components/role-list/role-list.js +8 -6
  22. package/core/models/roles/roles.js +182 -174
  23. package/core/models/users/components/user-add/user-add.js +619 -365
  24. package/core/models/users/components/user-add/user-edit.js +90 -0
  25. package/core/models/users/users.js +261 -165
  26. package/core/modules/index.js +5 -8
  27. package/core/modules/reporting/components/index.js +5 -0
  28. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +65 -2
  29. package/core/modules/steps/action-buttons.js +79 -0
  30. package/core/modules/steps/steps.js +553 -0
  31. package/core/modules/steps/steps.scss +158 -0
  32. package/core/modules/steps/timeline.js +49 -0
  33. package/package.json +2 -2
@@ -11,23 +11,45 @@ jobs:
11
11
  build:
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
- - uses: actions/checkout@v3
15
- - uses: actions/setup-node@v3
16
- with:
17
- node-version: 16
18
- - run: npm i
19
- # - run: npm test
14
+ # 1. Checkout the repository
15
+ - name: Checkout Code
16
+ uses: actions/checkout@v3
20
17
 
21
- publish-npm:
22
- needs: build
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v3
26
- - uses: actions/setup-node@v3
18
+ # 2. Setup Node.js and npm registry
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v3
27
21
  with:
28
22
  node-version: 16
29
23
  registry-url: https://registry.npmjs.org/
30
- - run: npm i
31
- - run: npm publish
24
+
25
+ # 3. Install dependencies using ci for reproducibility
26
+ - name: Install Dependencies
27
+ run: npm ci
28
+
29
+ # 4. Verify tag matches package.json version
30
+ - name: Verify Tag Matches Version
31
+ run: |
32
+ TAG=${GITHUB_REF#refs/tags/}
33
+ PACKAGE_VERSION=$(node -p "require('./package.json').version")
34
+ echo "Release Tag: $TAG"
35
+ echo "Package Version: $PACKAGE_VERSION"
36
+
37
+ if [[ "$TAG" != "v$PACKAGE_VERSION"* ]]; then
38
+ echo "Error: Tag does not match package.json version"
39
+ exit 1
40
+ fi
41
+
42
+ # 5. Publish the package
43
+ - name: Publish Package
44
+ run: |
45
+ TAG_NAME=${GITHUB_REF#refs/tags/}
46
+
47
+ if [[ "$TAG_NAME" == *"dev"* ]]; then
48
+ echo "Publishing development package with 'dev' tag"
49
+ npm publish --tag dev
50
+ else
51
+ echo "Publishing stable package"
52
+ npm publish
53
+ fi
32
54
  env:
33
- NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
55
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # 📦 NPM Release Workflow — Task-Based Development → Develop → Master
2
+
3
+ This guide describes the complete workflow for publishing **task-based development builds** and **stable releases** using GitHub Actions, Git tags, and npm versioning.
4
+
5
+ Incorrect versioning or incorrect tags will break the publish pipeline — follow the process exactly.
6
+
7
+ ---
8
+
9
+ # 📘 Table of Contents
10
+ - Overview
11
+ - Branch Strategy
12
+ - Task Branch Workflow
13
+ - Versioning Rules
14
+ - Development Release Workflow (`develop`)
15
+ - Promotion Workflow (Dev → Master)
16
+ - Publishing via GitHub Release UI
17
+ - How GitHub Action Detects Release Type
18
+ - Summary Table
19
+ - Common Mistakes & Fixes
20
+
21
+ ---
22
+
23
+ # 🧩 Overview
24
+
25
+ We maintain two release channels:
26
+
27
+ | Channel | Branch | Tag | Purpose |
28
+ |---------------------|----------|------------------|-----------------------|
29
+ | Stable (`latest`) | master | `vX.Y.Z` | Production release |
30
+ | Development (`dev`) | develop | `vX.Y.Z-dev.N` | QA/internal testing |
31
+
32
+ Releases are triggered using Git tags:
33
+
34
+ ```
35
+ npm version
36
+ ```
37
+
38
+ ---
39
+
40
+ # 🌿 Branch Strategy
41
+
42
+ ## `master`
43
+ - Production-ready code
44
+ - Publishes **stable** builds
45
+ - Versions never include a `dev` suffix
46
+
47
+ ## `develop`
48
+ - Used for QA/internal testing
49
+ - Publishes **development** builds
50
+ - Versions always include `-dev.N`
51
+
52
+ ## Task Branches
53
+ - Create from `master`
54
+ - Naming: `task/<JIRA-ID>-<description>`
55
+ - After completing work, merge into `develop`
56
+
57
+ ---
58
+
59
+ # 🏗️ Task Branch Workflow
60
+
61
+ ### 1. Create a task branch
62
+ ```bash
63
+ git checkout master
64
+ git pull origin master
65
+ git checkout -b task/<JIRA-ID>-<description>
66
+ ```
67
+
68
+ ### 2. Work on the task
69
+ ```bash
70
+ git add .
71
+ git commit -m "TASK-123: Implement XYZ"
72
+ ```
73
+
74
+ ### 3. Merge into develop
75
+ ```bash
76
+ git checkout develop
77
+ git pull origin develop
78
+ git merge task/<JIRA-ID>-<description>
79
+ ```
80
+
81
+ ---
82
+
83
+ # 🔧 Versioning Rules
84
+
85
+ ## Development Versions
86
+ ```
87
+ X.Y.Z-dev.N
88
+ ```
89
+ Example:
90
+ ```
91
+ 2.4.30-dev.0
92
+ ```
93
+
94
+ ## Stable Versions
95
+ ```
96
+ X.Y.Z
97
+ ```
98
+
99
+ ## Rules
100
+ - Each version must be unique
101
+ - Dev versions do **not** convert into stable versions
102
+ - Git tag must exactly match `package.json` version
103
+
104
+ ---
105
+
106
+ # 🟦 Development Release Workflow (`develop`)
107
+
108
+ ### 1. Switch to develop
109
+ ```bash
110
+ git checkout develop
111
+ git pull origin develop
112
+ ```
113
+
114
+ ### 2. Create a new development version
115
+ ```bash
116
+ npm version prerelease --preid=dev
117
+ ```
118
+
119
+ ### 3. Push commit + tag
120
+ ```bash
121
+ git push --follow-tags
122
+ ```
123
+
124
+ ### 4. GitHub Action publishes dev build
125
+ ```
126
+ npm publish --tag dev
127
+ ```
128
+
129
+ ### 5. Install the dev build
130
+ ```bash
131
+ npm install soxo-bootstrap-core@dev
132
+ ```
133
+
134
+ ---
135
+
136
+ # 🟩 Promotion Workflow (Dev → Master)
137
+
138
+ ### 1. Switch to master
139
+ ```bash
140
+ git checkout master
141
+ git pull origin master
142
+ ```
143
+
144
+ ### 2. Merge develop into master
145
+ ```bash
146
+ git merge develop
147
+ ```
148
+
149
+ ### 3. Bump the stable version
150
+ ```bash
151
+ npm version patch
152
+ # or
153
+ npm version minor
154
+ # or
155
+ npm version major
156
+ ```
157
+
158
+ ### 4. Push with tags
159
+ ```bash
160
+ git push --follow-tags
161
+ ```
162
+
163
+ ### 5. GitHub Action publishes stable build
164
+ ```
165
+ npm publish
166
+ ```
167
+
168
+ ### 6. Install stable version
169
+ ```bash
170
+ npm install soxo-bootstrap-core
171
+ # or
172
+ npm install soxo-bootstrap-core@<version>
173
+ ```
174
+
175
+ ---
176
+
177
+ # 🟧 Publishing via GitHub Release UI
178
+
179
+ ### Important
180
+ **The tag must match the `package.json` version exactly**, including the `v` prefix.
181
+
182
+ Example:
183
+ ```
184
+ package.json: "version": "2.4.31-dev.0"
185
+ GitHub Tag: v2.4.31-dev.0
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Steps
191
+
192
+ ### 1. Ensure `develop` branch is up to date
193
+ Push your changes.
194
+
195
+ ### 2. Ensure version contains a dev suffix
196
+ If not:
197
+ ```bash
198
+ npm version prerelease --preid=dev
199
+ git push --follow-tags
200
+ ```
201
+
202
+ ### 3. Open GitHub → Releases → Draft a new release
203
+
204
+ ### 4. Create tag matching the version
205
+ Example:
206
+ ```
207
+ v2.4.31-dev.0
208
+ ```
209
+
210
+ ### 5. Select target branch = `develop`
211
+
212
+ ### 6. Title = tag version
213
+ Description is optional.
214
+
215
+ ### 7. Publish the release
216
+ Triggers:
217
+ ```
218
+ npm publish --tag dev
219
+ ```
220
+
221
+ ---
222
+
223
+ # ⚙️ How GitHub Action Detects Release Type
224
+
225
+ If version contains `dev`:
226
+ ```
227
+ npm publish --tag dev
228
+ ```
229
+
230
+ Otherwise:
231
+ ```
232
+ npm publish
233
+ ```
234
+
235
+ ---
236
+
237
+ # 📊 Summary Table
238
+
239
+ | Step | Branch | Command | Tag | Publish Type |
240
+ |--------------------------|----------|------------------------------------------|------------------|--------------|
241
+ | Create task branch | master | `git checkout -b task/<ID>` | — | — |
242
+ | Merge task → develop | develop | `git merge task/<ID>` | — | — |
243
+ | Dev version | develop | `npm version prerelease --preid=dev` | `vX.Y.Z-dev.N` | dev |
244
+ | Publish dev build | develop | `git push --follow-tags` | — | dev |
245
+ | Merge develop → master | master | `git merge develop` | — | — |
246
+ | Stable version | master | `npm version patch/minor/major` | `vX.Y.Z` | latest |
247
+ | Publish stable build | master | `git push --follow-tags` | — | latest |
248
+
249
+ ---
250
+
251
+ # ⚠️ Common Mistakes & Fixes
252
+
253
+ | Mistake | Issue | Fix |
254
+ |-------------------------------|----------------------|---------------------------------|
255
+ | Tag doesn't match version | Publish fails | Always use `npm version` |
256
+ | Manual tag creation | Version mismatch | Avoid manual tagging |
257
+ | Dev publish from master | Wrong channel | Verify branch before tagging |
258
+ | Not pushing tags | Workflow won’t run | Use `git push --follow-tags` |
259
+ | Merging incomplete tasks | Breaks dev builds | Test before merging |
260
+
@@ -1,7 +1,7 @@
1
1
  /**
2
- * ExtraInfoDetail component contains the button and the data for corresponding to script mode and will open extrainfo
2
+ * ExtraInfoDetail component contains the button and the data for corresponding to script mode and will open extrainfo
3
3
  *
4
- * @description
4
+ * @description
5
5
  * @author Sneha T
6
6
  */
7
7
 
@@ -21,152 +21,135 @@ import ExtraInfo from './extra-info';
21
21
 
22
22
  const { TabPane } = Tabs;
23
23
 
24
- export default function ExtraInfoDetail({ modeValue, icon, title, tabPosition='left',showDrawerData,dbPtr,callback,...record}) {
25
- // State to control drawer
26
- const [open, setOpen] = useState(false);
24
+ export default function ExtraInfoDetail({ modeValue, icon, title, tabPosition = 'left', showDrawerData, dbPtr, callback, ...record }) {
25
+ // State to control drawer
26
+ const [open, setOpen] = useState(false);
27
27
 
28
- // To set extra info data
29
- const [info, setInfo] = useState([]);
30
- //Setting active key for tabs
31
- const [activeKey, setActiveKey] = useState(null);
28
+ // To set extra info data
29
+ const [info, setInfo] = useState([]);
30
+ //Setting active key for tabs
31
+ const [activeKey, setActiveKey] = useState(null);
32
32
 
33
- // To strore selected item
34
- const [selectedItem, setSelectedItem] = useState(null);
33
+ // To strore selected item
34
+ const [selectedItem, setSelectedItem] = useState(null);
35
35
 
36
- const [loading, setLoading] = useState(true);
36
+ const [loading, setLoading] = useState(true);
37
37
 
38
- /**
39
- * Show Drawer
40
- */
41
- const showDrawer = () => {
42
-
43
- setActiveKey(null); // Reset activeKey before fetching new info
44
-
45
- getExtraInfo();
38
+ /**
39
+ * Show Drawer
40
+ */
41
+ const showDrawer = () => {
42
+ setActiveKey(null); // Reset activeKey before fetching new info
46
43
 
47
- setOpen(true);
44
+ getExtraInfo();
48
45
 
49
- };
46
+ setOpen(true);
47
+ };
50
48
 
51
- /**
52
- * Function to close
53
- */
54
- const onClose = () => {
55
- if (typeof callback === 'function') {
56
- // Only call if it exists
57
- callback(false);
58
- }
59
- setOpen(false);
60
- };
49
+ /**
50
+ * Function to close
51
+ */
52
+ const onClose = () => {
53
+ if (typeof callback === 'function') {
54
+ // Only call if it exists
55
+ callback(false);
56
+ }
57
+ setOpen(false);
58
+ };
61
59
 
62
- /**
63
- * Function to get Info
64
- */
65
- async function getExtraInfo() {
60
+ /**
61
+ * Function to get Info
62
+ */
63
+ async function getExtraInfo() {
64
+ setSelectedItem();
66
65
 
67
- setSelectedItem()
66
+ setLoading(true);
68
67
 
69
- setLoading(true);
68
+ let mode = modeValue;
70
69
 
71
- let mode = modeValue
70
+ const result = await Dashboard.getExtraInfo(mode);
72
71
 
73
- const result = await Dashboard.getExtraInfo(mode);
72
+ setInfo(result);
74
73
 
75
- setInfo(result);
74
+ setSelectedItem(result[0]);
76
75
 
77
- setSelectedItem(result[0])
76
+ setActiveKey(result[0].id.toString()); // Set activeKey to the first item's id
78
77
 
79
- setActiveKey(result[0].id.toString()); // Set activeKey to the first item's id
78
+ setLoading(false);
79
+ }
80
80
 
81
- setLoading(false);
81
+ useEffect(() => {
82
+ // If showDrawerData is true then call showDrawer function
83
+ if (showDrawerData) {
84
+ showDrawer();
82
85
  }
86
+ }, [showDrawerData]);
83
87
 
84
- useEffect(() => {
85
- // If showDrawerData is true then call showDrawer function
86
- if (showDrawerData) {
87
- showDrawer();
88
- }
89
- }, [showDrawerData]);
90
-
91
- /**
88
+ /**
92
89
  * Function to render icon or button
93
90
  */
94
- const renderIconOrButton = () => {
95
- switch (icon) {
96
- case 'InfoCircleFilled':
97
- return <InfoCircleFilled onClick={showDrawer} />;
98
- case 'Button':
99
- return <Button size="small" onClick={showDrawer}>Show Info</Button>;
100
- default:
101
- return null;
102
- }
103
- };
104
-
105
-
106
-
107
- return (
108
- <>
109
- {/* {loading ? (
91
+ const renderIconOrButton = () => {
92
+ switch (icon) {
93
+ case 'InfoCircleFilled':
94
+ return <InfoCircleFilled onClick={showDrawer} />;
95
+ case 'Button':
96
+ return (
97
+ <Button size="small" onClick={showDrawer}>
98
+ Show Info
99
+ </Button>
100
+ );
101
+ default:
102
+ return null;
103
+ }
104
+ };
105
+
106
+ return (
107
+ <>
108
+ {/* {loading ? (
110
109
  <>
111
110
  <Skeleton active />
112
111
  </>
113
112
  ) : ( */}
114
- <>
115
- {/* */}
116
- {/* <Button onClick={showDrawer}> */}
117
-
118
- {/* <InfoCircleFilled onMouseEnter={showDrawer} /> */}
119
-
120
- {renderIconOrButton()}
121
- {/* </Button> */}
122
- {/* */}
123
-
124
- {/* */}
125
- <Drawer
126
-
127
- width={'85%'}
128
-
129
- title={title} onClose={onClose} open={open}>
130
-
131
- <div className="main-drawer-content">
132
-
133
- <div className="drawer-container">
134
-
135
- <div className="drawer-click"> {/* Flexbox approach */}
136
- <Tabs
137
- tabPosition={tabPosition}
138
-
139
- activeKey={activeKey} // Set activeKey to control the active tab
140
-
141
- onChange={(key) => {
142
-
143
- const selectedItem = info.find(item => item.id.toString() === key);
144
-
145
- setSelectedItem(selectedItem);
146
-
147
- setActiveKey(key);
148
- }}
149
- >
150
- {info.map(item => (
151
- <TabPane tab={item.caption} key={item.id.toString()} />
152
- ))}
153
- </Tabs>
154
- </div>
155
-
156
- <div className="right-drawer">
157
-
158
- {selectedItem && !loading ? <ExtraInfo item={selectedItem} record={record} dbPtr={dbPtr}/> : null}
159
-
160
- </div>
161
-
162
- </div>
163
-
164
- </div>
165
-
166
- </Drawer>
167
-
168
- </>
169
- {/* )} */}
170
- </>
171
- );
113
+ <>
114
+ {/* */}
115
+ {/* <Button onClick={showDrawer}> */}
116
+
117
+ {/* <InfoCircleFilled onMouseEnter={showDrawer} /> */}
118
+
119
+ {renderIconOrButton()}
120
+ {/* </Button> */}
121
+ {/* */}
122
+
123
+ {/* */}
124
+ <Drawer width={'35%'} title={title} onClose={onClose} open={open}>
125
+ <div className="main-drawer-content">
126
+ <div className="drawer-container">
127
+ <div className="drawer-click">
128
+ {' '}
129
+ {/* Flexbox approach */}
130
+ <Tabs
131
+ tabPosition={tabPosition}
132
+ activeKey={activeKey} // Set activeKey to control the active tab
133
+ onChange={(key) => {
134
+ const selectedItem = info.find((item) => item.id.toString() === key);
135
+
136
+ setSelectedItem(selectedItem);
137
+
138
+ setActiveKey(key);
139
+ }}
140
+ >
141
+ {info.map((item) => (
142
+ <TabPane tab={item.caption} key={item.id.toString()} />
143
+ ))}
144
+ </Tabs>
145
+ </div>
146
+
147
+ <div className="right-drawer">{selectedItem && !loading ? <ExtraInfo item={selectedItem} record={record} dbPtr={dbPtr} /> : null}</div>
148
+ </div>
149
+ </div>
150
+ </Drawer>
151
+ </>
152
+ {/* )} */}
153
+ </>
154
+ );
172
155
  }
@@ -96,7 +96,6 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
96
96
  * @param reports
97
97
  */
98
98
  async function loadMenus(reports) {
99
-
100
99
  setLoader(true);
101
100
 
102
101
  // setReports(report)
@@ -106,16 +105,12 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
106
105
  // console.log(result);
107
106
 
108
107
  if (result && Array.isArray(result.result) && result.result.length) {
109
-
110
108
  // setModules(result.result);
111
-
112
109
  // result.result.map((ele) => {
113
110
  // let languageString = JSON.parse(ele.attributes)
114
111
  // console.log('language_string', languageString);
115
112
  // if (languageString && languageString.languages) {
116
-
117
113
  // const language = i18n.language;
118
-
119
114
  // i18n.addResourceBundle(language, 'translation', languageString.languages[i18n.language]);
120
115
  // }
121
116
  // })
@@ -126,7 +121,6 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
126
121
  dispatch({ type: 'settings', payload: result.result.settings });
127
122
  }
128
123
 
129
-
130
124
  // Reports length
131
125
  if (reports.length) {
132
126
  reportMenus = [
@@ -153,30 +147,25 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
153
147
 
154
148
  /**If there is roles assigned to the user */
155
149
  // for matria
156
- const useCoreMenus= process.env.REACT_APP_USE_CORE_MENUS === 'true';
157
- if(useCoreMenus){
158
- if (result && result.result && reportMenus) {
159
- setAllModules([...result.result, ...reportMenus, ...coreModules]);
160
- } else {
161
- //If there is no roles assigned to the user
162
- setAllModules([...coreModules]);
163
- }
164
-
165
- } else{
166
- // for nura
167
- if (result && result.result.menus && reportMenus) {
168
- setAllModules([...result.result.menus, ...reportMenus, ...coreModules]);
150
+ const useCoreMenus = process.env.REACT_APP_USE_CORE_MENUS === 'true';
151
+ if (useCoreMenus) {
152
+ if (result && result.result && reportMenus) {
153
+ setAllModules([...result.result, ...reportMenus, ...coreModules]);
154
+ } else {
155
+ //If there is no roles assigned to the user
156
+ setAllModules([...coreModules]);
157
+ }
169
158
  } else {
170
- //If there is no roles assigned to the user
171
- setAllModules([...coreModules]);
159
+ // for nura
160
+ if (result && result.result.menus && reportMenus) {
161
+ setAllModules([...result.result.menus, ...reportMenus, ...coreModules]);
162
+ } else {
163
+ //If there is no roles assigned to the user
164
+ setAllModules([...coreModules]);
165
+ }
172
166
  }
173
-
174
-
167
+ setLoader(false);
175
168
  }
176
- setLoader(false);
177
-
178
- }
179
-
180
169
 
181
170
  /**
182
171
  * Load the scripts
@@ -257,6 +246,12 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
257
246
 
258
247
  <Route exact key={'profile'} path={'/profile'} render={(props) => <Profile {...props} />} />
259
248
 
249
+ {/* More specific routes should come before general/dynamic routes */}
250
+
251
+
252
+ <Route path={'/reports/:id'} render={(props) => <ReportingDashboard CustomComponents={CustomComponents} {...props} />} />
253
+
254
+
260
255
  <Route path={'/menus/:id'} render={() => <ModuleRoutes model={MenusAPI} />} />
261
256
 
262
257
  {/* <Switch> */}
@@ -273,9 +268,6 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
273
268
  }}
274
269
  />
275
270
 
276
- {/* <Route path={'/users'} render={() => <ModuleRoutes model={UsersAPI} />} /> */}
277
-
278
- <Route path={'/reports/:id'} render={(props) => <ReportingDashboard CustomComponents={CustomComponents} {...props} />} />
279
271
 
280
272
  <Route exact key={'change-password'} path={'/change-password'} render={(props) => <ChangePassword {...props} />} />
281
273