ui-soxo-bootstrap-core 2.4.25-dev.48 → 2.4.25-dev.49
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/.github/workflows/npm-publish.yml +39 -28
- package/core/models/staff/components/staff-add/staff-add.js +28 -29
- package/core/models/user-roles/user-roles.js +14 -0
- package/core/models/users/components/assign-role/assign-role.js +37 -19
- package/core/models/users/users.js +1 -1
- package/package.json +1 -1
- package/core/models/staff/components/staff-add/staff-add.scss +0 -0
|
@@ -1,52 +1,63 @@
|
|
|
1
1
|
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
|
2
2
|
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
3
|
|
|
4
|
-
name: Node
|
|
4
|
+
name: Publish Node Package (OIDC)
|
|
5
5
|
|
|
6
6
|
on:
|
|
7
7
|
release:
|
|
8
8
|
types: [created]
|
|
9
9
|
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
id-token: write # REQUIRED for OIDC
|
|
13
|
+
|
|
10
14
|
jobs:
|
|
11
|
-
|
|
15
|
+
publish:
|
|
12
16
|
runs-on: ubuntu-latest
|
|
17
|
+
|
|
13
18
|
steps:
|
|
14
|
-
# 1. Checkout the
|
|
15
|
-
- name: Checkout
|
|
16
|
-
uses: actions/checkout@
|
|
19
|
+
# 1. Checkout the exact commit the release was created from
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
17
22
|
|
|
18
|
-
# 2. Setup Node.js
|
|
23
|
+
# 2. Setup Node.js
|
|
24
|
+
# Node 22 = current LTS
|
|
19
25
|
- name: Setup Node.js
|
|
20
|
-
uses: actions/setup-node@
|
|
26
|
+
uses: actions/setup-node@v4
|
|
21
27
|
with:
|
|
22
|
-
node-version:
|
|
28
|
+
node-version: 22
|
|
23
29
|
registry-url: https://registry.npmjs.org/
|
|
30
|
+
cache: npm
|
|
24
31
|
|
|
25
|
-
# 3. Install dependencies
|
|
26
|
-
- name: Install
|
|
32
|
+
# 3. Install dependencies deterministically
|
|
33
|
+
- name: Install dependencies
|
|
27
34
|
run: npm ci
|
|
28
35
|
|
|
29
|
-
# 4. Verify tag matches package.json version
|
|
30
|
-
|
|
36
|
+
# 4. Verify git tag matches package.json version
|
|
37
|
+
# This prevents publishing the wrong version
|
|
38
|
+
- name: Verify tag matches package.json version
|
|
31
39
|
run: |
|
|
32
|
-
TAG
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
echo "
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
TAG="${{ github.event.release.tag_name }}"
|
|
41
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
42
|
+
|
|
43
|
+
echo "Release tag: $TAG"
|
|
44
|
+
echo "Package version: $VERSION"
|
|
45
|
+
|
|
46
|
+
if [[ "$TAG" != "v$VERSION"* ]]; then
|
|
47
|
+
echo "::error::Release tag does not match package.json version"
|
|
38
48
|
exit 1
|
|
39
49
|
fi
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
|
|
51
|
+
# 5. Publish using OIDC (NO TOKEN)
|
|
52
|
+
# --provenance triggers GitHub → npm identity verification
|
|
53
|
+
- name: Publish to npm (OIDC)
|
|
42
54
|
run: |
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
TAG="${{ github.event.release.tag_name }}"
|
|
56
|
+
|
|
57
|
+
if [[ "$TAG" == *"dev"* ]]; then
|
|
58
|
+
echo "Publishing dev release"
|
|
59
|
+
npm publish --tag dev --provenance
|
|
47
60
|
else
|
|
48
|
-
echo "Publishing stable
|
|
49
|
-
npm publish
|
|
61
|
+
echo "Publishing stable release"
|
|
62
|
+
npm publish --provenance
|
|
50
63
|
fi
|
|
51
|
-
env:
|
|
52
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef } from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import { Modal, Tabs, Input, Form, Row, Col, message, Checkbox, Select } from 'antd';
|
|
4
4
|
import { useTranslation, Button } from './../../../../lib/';
|
|
5
5
|
import { UsersAPI } from '../../..';
|
|
@@ -163,20 +163,20 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
163
163
|
return Promise.resolve();
|
|
164
164
|
};
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
const validateSerial = (_, value) => {
|
|
167
|
+
if (!value) {
|
|
168
|
+
return Promise.resolve();
|
|
169
|
+
}
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
// Allow same serial number for the same staff in edit mode
|
|
172
|
+
if (editMode && String(value) === String(staffData?.slNo)) {
|
|
173
|
+
return Promise.resolve();
|
|
174
|
+
}
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
const exists = staffList.some((staff) => String(staff.slNo) === String(value));
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
return exists ? Promise.reject('Serial Number already exists') : Promise.resolve();
|
|
179
|
+
};
|
|
180
180
|
|
|
181
181
|
/** -------------------------------
|
|
182
182
|
* UTIL – Enter Key Navigation
|
|
@@ -215,6 +215,8 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
215
215
|
});
|
|
216
216
|
};
|
|
217
217
|
|
|
218
|
+
const existing = staffData || {};
|
|
219
|
+
|
|
218
220
|
/** -------------------------------
|
|
219
221
|
* SUBMIT HANDLER
|
|
220
222
|
* ------------------------------- */
|
|
@@ -225,19 +227,19 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
225
227
|
id: values.id,
|
|
226
228
|
shortName: values.shortName,
|
|
227
229
|
description: values.description,
|
|
228
|
-
designationPtr: values.designation
|
|
229
|
-
phone: values.phone1
|
|
230
|
-
mobile: values.phone1
|
|
231
|
-
alternateMobile: values.phone2
|
|
232
|
-
email: values.email1
|
|
233
|
-
alternateEmail: values.email2
|
|
234
|
-
remarks: values.remarks
|
|
235
|
-
slNo: values.slno
|
|
230
|
+
designationPtr: values.designation ?? existing.designationPtr ?? null,
|
|
231
|
+
phone: values.phone1 ?? existing.phone ?? null,
|
|
232
|
+
mobile: values.phone1 ?? existing.mobile ?? null,
|
|
233
|
+
alternateMobile: values.phone2 ?? existing.alternateMobile ?? null,
|
|
234
|
+
email: values.email1 ?? existing.email ?? null,
|
|
235
|
+
alternateEmail: values.email2 ?? existing.alternateEmail ?? null,
|
|
236
|
+
remarks: values.remarks ?? existing.remarks ?? null,
|
|
237
|
+
slNo: values.slno ?? existing.slNo ?? null,
|
|
236
238
|
active: values.active === 'Y' ? 'Y' : 'N',
|
|
237
|
-
address1: values.address1
|
|
238
|
-
address2: values.address2
|
|
239
|
-
place: values.place
|
|
240
|
-
zip: values.zip
|
|
239
|
+
address1: values.address1 ?? existing.address1 ?? null,
|
|
240
|
+
address2: values.address2 ?? existing.address2 ?? null,
|
|
241
|
+
place: values.place ?? existing.place ?? null,
|
|
242
|
+
zip: values.zip ?? existing.zip ?? null,
|
|
241
243
|
};
|
|
242
244
|
|
|
243
245
|
try {
|
|
@@ -279,10 +281,7 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
279
281
|
name="id"
|
|
280
282
|
validateTrigger="onChange"
|
|
281
283
|
hasFeedback={!editMode}
|
|
282
|
-
rules={[
|
|
283
|
-
{ required: true, message: 'Code is required' },
|
|
284
|
-
{ validator: validateInput },
|
|
285
|
-
]}
|
|
284
|
+
rules={[{ required: true, message: 'Code is required' }, { validator: validateInput }]}
|
|
286
285
|
>
|
|
287
286
|
<Input placeholder="Enter Code" autoComplete="off" maxLength={10} ref={nameInputRef} onKeyDown={handleEnterKey} disabled={editMode} />
|
|
288
287
|
</Form.Item>
|
|
@@ -383,7 +382,7 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
|
|
|
383
382
|
name="slno"
|
|
384
383
|
rules={[{ message: 'only numbers are allowed', pattern: /^\d*$/ }, { validator: validateSerial }]}
|
|
385
384
|
>
|
|
386
|
-
<Input autoComplete="off" maxLength={5} placeholder="Enter Serial Number" onKeyDown={handleEnterKey}
|
|
385
|
+
<Input autoComplete="off" maxLength={5} placeholder="Enter Serial Number" onKeyDown={handleEnterKey} />
|
|
387
386
|
</Form.Item>
|
|
388
387
|
</Col>
|
|
389
388
|
|
|
@@ -73,6 +73,7 @@ class UserRole extends Base {
|
|
|
73
73
|
return false;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
|
|
76
77
|
/**
|
|
77
78
|
*
|
|
78
79
|
* @param {*} formBody
|
|
@@ -86,6 +87,19 @@ class UserRole extends Base {
|
|
|
86
87
|
})
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
* @param {*} formBody
|
|
93
|
+
* @returns
|
|
94
|
+
*/
|
|
95
|
+
addUserRoleSave = (values) => {
|
|
96
|
+
|
|
97
|
+
return this.post({
|
|
98
|
+
url: 'core-user-roles/save-core-user-roles',
|
|
99
|
+
formBody: values
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
89
103
|
/**
|
|
90
104
|
*
|
|
91
105
|
*
|
|
@@ -51,6 +51,9 @@ export default function AssignRole() {
|
|
|
51
51
|
const [selectedMenus, setSelectedMenus] = useState([]);
|
|
52
52
|
const [search, setSearch] = useState('');
|
|
53
53
|
|
|
54
|
+
// for initial roles
|
|
55
|
+
const [initialRoles, setInitialRoles] = useState([]);
|
|
56
|
+
|
|
54
57
|
/**
|
|
55
58
|
* Load user details and assigned roles when user ID changes
|
|
56
59
|
*/
|
|
@@ -89,13 +92,14 @@ export default function AssignRole() {
|
|
|
89
92
|
/* ---------- USER ROLES ---------- */
|
|
90
93
|
const roleList = Array.isArray(roleRes?.result) ? roleRes.result : [];
|
|
91
94
|
|
|
92
|
-
//
|
|
93
|
-
const roleIds = [...new Set(
|
|
95
|
+
// Extract VALID role IDs (ignore nulls & duplicates)
|
|
96
|
+
const roleIds = [...new Set(list.filter((item) => item.role_id && item.active === 'Y').map((item) => Number(item.role_id)))];
|
|
94
97
|
|
|
95
98
|
setSelectedRoles(roleIds);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
setInitialRoles(roleIds);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
console.error(e);
|
|
102
|
+
message.error('Unable to load user details');
|
|
99
103
|
} finally {
|
|
100
104
|
setLoadingUser(false);
|
|
101
105
|
}
|
|
@@ -202,25 +206,39 @@ export default function AssignRole() {
|
|
|
202
206
|
* @returns {Promise<void>}
|
|
203
207
|
*/
|
|
204
208
|
const handleSaveUserRole = async () => {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
if (!id) {
|
|
210
|
+
message.error('Invalid user');
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
209
213
|
// start button spinner
|
|
210
214
|
setSaving(true);
|
|
211
215
|
|
|
212
216
|
try {
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
// roles to ADD
|
|
218
|
+
const role_ids = selectedRoles.filter((rid) => !initialRoles.includes(rid));
|
|
219
|
+
|
|
220
|
+
// roles to REMOVE
|
|
221
|
+
const update_ids = initialRoles.filter((rid) => !selectedRoles.includes(rid));
|
|
222
|
+
|
|
223
|
+
if (!role_ids.length && !update_ids.length) {
|
|
224
|
+
message.info('No changes to save');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const payload = {
|
|
229
|
+
user_id: id,
|
|
230
|
+
role_ids,
|
|
231
|
+
update_ids,
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
await UserRolesAPI.addUserRoleSave(payload);
|
|
221
235
|
|
|
222
236
|
// Only show success AFTER all saves
|
|
223
|
-
|
|
237
|
+
|
|
238
|
+
message.success('User roles updated successfully');
|
|
239
|
+
|
|
240
|
+
await loadUser();
|
|
241
|
+
|
|
224
242
|
} catch (err) {
|
|
225
243
|
console.error(err);
|
|
226
244
|
message.error('Failed to save user roles');
|
|
@@ -290,7 +308,7 @@ export default function AssignRole() {
|
|
|
290
308
|
</div>
|
|
291
309
|
|
|
292
310
|
<div className="footer-actions">
|
|
293
|
-
<Button type="primary" onClick={handleSaveUserRole} loading={saving}>
|
|
311
|
+
<Button type="primary" onClick={handleSaveUserRole} loading={saving} disabled={!selectedRoles.length}>
|
|
294
312
|
Save
|
|
295
313
|
</Button>
|
|
296
314
|
</div>
|
|
@@ -288,7 +288,7 @@ class Users extends Base {
|
|
|
288
288
|
roles associated with a specific user from the API. */
|
|
289
289
|
|
|
290
290
|
getUserRole = ({ id }) => {
|
|
291
|
-
return ApiUtils.get({ url: `core-user-roles?user_id=${id}` });
|
|
291
|
+
return ApiUtils.get({ url: `core-user-roles?user_id=${id}&active=Y` });
|
|
292
292
|
|
|
293
293
|
};
|
|
294
294
|
|
package/package.json
CHANGED
|
File without changes
|