From 2536bf0589efdaf21a2e3ff48503db12884da339 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Wed, 11 Sep 2024 11:50:07 +0530 Subject: [PATCH 1/9] Improved: facility display logic on Admin/Super user details page(#173) --- src/locales/en.json | 1 + src/services/UserService.ts | 29 +++++++++++++++++++++++++++++ src/views/UserDetails.vue | 12 ++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index da0d94a..0c80f72 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -204,6 +204,7 @@ "The timezone you select is used to ensure automations you schedule are always accurate to the time you select.": "The timezone you select is used to ensure automations you schedule are always accurate to the time you select.", "This is the name of the OMS you are connected to right now. Make sure that you are connected to the right instance before proceeding.": "This is the name of the OMS you are connected to right now. Make sure that you are connected to the right instance before proceeding.", "This user was disabled due to repeated failed password attempts": "This user was disabled due to repeated failed password attempts", + "This user has 'STOREFULFILLMENT_ADMIN' permission, enabling access to all facilities.": "This user has 'STOREFULFILLMENT_ADMIN' permission, enabling access to all facilities.", "Unblock user login": "Unblock user login", "Unblocking a user will allow them to login to the OMS again with their credentials.": "Unblocking a user will allow them to login to the OMS again with their credentials.", "Update product store role": "Update product store role", diff --git a/src/services/UserService.ts b/src/services/UserService.ts index bdcc657..83af520 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -326,6 +326,34 @@ const getUserSecurityGroup = async (userLoginId: string): Promise => { return userSecurityGroup } +const isUserAdminAndSuper = async (userLoginId: string): Promise => { + const payload = { + inputFields: { + userLoginId, + permissionId: ['STOREFULFILLMENT_ADMIN'] + }, + entityName: "UserLoginSecurityGroupAndPermission", + filterByDate: "Y", + viewSize: 10, + }; + + try { + const resp: any = await api({ + url: "performFind", + method: "POST", + data: payload, + }); + + if (!hasError(resp)) { + return resp.data.docs; + } else { + throw resp.data; + } + } catch (error) { + logger.error(error); + return []; + } +}; const removeUserSecurityGroup = async (payload: any): Promise => { return api({ @@ -783,6 +811,7 @@ export const UserService = { getUserFacilities, getUserProductStores, getUserSecurityGroup, + isUserAdminAndSuper, isUserLoginIdAlreadyExists, isRoleTypeExists, login, diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index 4ada04f..349d6ab 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -322,8 +322,11 @@ {{ translate("Show as picker") }} - - {{ getUserFacilities().length === 1 ? translate('Added to 1 facility') : translate('Added to facilities', { count: getUserFacilities().length }) }} + + {{ translate("This user has 'STOREFULFILLMENT_ADMIN' permission, enabling access to all facilities.") }} + + + {{ getUserFacilities().length === 1 ? translate('Added to 1 facility') : translate('Added to facilities', { count: getUserFacilities().length }) }} @@ -518,7 +521,8 @@ export default defineComponent({ imageUrl: "", isUserFetched: false, showPassword: false, - shopifyShopsForProductStore: [] as any + shopifyShopsForProductStore: [] as any, + isUserAdmin: [] } }, @@ -532,7 +536,7 @@ export default defineComponent({ if (productStoreId) { this.getShopifyShops(productStoreId); } - + this.isUserAdmin = await UserService.isUserAdminAndSuper(this.selectedUser.userLoginId) this.isUserFetched = true this.username = this.selectedUser.groupName ? (this.selectedUser.groupName)?.toLowerCase() : (`${this.selectedUser.firstName}.${this.selectedUser.lastName}`?.toLowerCase()) }, From 38240b577fc8041dee40beeff0e67f4217666cc4 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Wed, 11 Sep 2024 12:02:12 +0530 Subject: [PATCH 2/9] Improved: changed the service and variable name(#173) --- src/services/UserService.ts | 4 ++-- src/views/UserDetails.vue | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 83af520..66838a9 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -326,7 +326,7 @@ const getUserSecurityGroup = async (userLoginId: string): Promise => { return userSecurityGroup } -const isUserAdminAndSuper = async (userLoginId: string): Promise => { +const isUserFulfillmentAdmin = async (userLoginId: string): Promise => { const payload = { inputFields: { userLoginId, @@ -811,7 +811,7 @@ export const UserService = { getUserFacilities, getUserProductStores, getUserSecurityGroup, - isUserAdminAndSuper, + isUserFulfillmentAdmin, isUserLoginIdAlreadyExists, isRoleTypeExists, login, diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index 349d6ab..f65157a 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -322,7 +322,7 @@ {{ translate("Show as picker") }} - + {{ translate("This user has 'STOREFULFILLMENT_ADMIN' permission, enabling access to all facilities.") }} @@ -522,7 +522,7 @@ export default defineComponent({ isUserFetched: false, showPassword: false, shopifyShopsForProductStore: [] as any, - isUserAdmin: [] + isUserFulfillmentAdmin: [] } }, @@ -536,7 +536,7 @@ export default defineComponent({ if (productStoreId) { this.getShopifyShops(productStoreId); } - this.isUserAdmin = await UserService.isUserAdminAndSuper(this.selectedUser.userLoginId) + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.userLoginId) this.isUserFetched = true this.username = this.selectedUser.groupName ? (this.selectedUser.groupName)?.toLowerCase() : (`${this.selectedUser.firstName}.${this.selectedUser.lastName}`?.toLowerCase()) }, From 2319e0344d6c33916a416982962a53e82c2b3760 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Mon, 16 Sep 2024 14:18:30 +0530 Subject: [PATCH 3/9] Improved: Update to use 'SecurityGroupPermission' entity to check the user permissions(#173) --- src/services/UserService.ts | 27 +++++++++++++-------------- src/views/UserDetails.vue | 9 ++++++--- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 6b5cdac..687e5ff 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -326,15 +326,17 @@ const getUserSecurityGroup = async (userLoginId: string): Promise => { return userSecurityGroup } -const isUserFulfillmentAdmin = async (userLoginId: string): Promise => { + +const isUserFulfillmentAdmin = async (groupId: string): Promise => { const payload = { inputFields: { - userLoginId, - permissionId: ['STOREFULFILLMENT_ADMIN'] + groupId, + permissionId: "STOREFULFILLMENT_ADMIN" }, - entityName: "UserLoginSecurityGroupAndPermission", + entityName: "SecurityGroupPermission", filterByDate: "Y", - viewSize: 10, + viewSize: 1, + fieldList: ["groupId", "permissionId", "fromDate"] }; try { @@ -343,17 +345,14 @@ const isUserFulfillmentAdmin = async (userLoginId: string): Promise => { method: "POST", data: payload, }); - - if (!hasError(resp)) { - return resp.data.docs; - } else { - throw resp.data; + if(!hasError(resp) && resp.data.docs.length) { + return true } - } catch (error) { - logger.error(error); - return []; + return false + } catch(err) { + return false } -}; +} const removeUserSecurityGroup = async (payload: any): Promise => { return api({ diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index 7bdb6ca..880008e 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -322,7 +322,7 @@ {{ translate("Show as picker") }} - + {{ translate("This user has 'STOREFULFILLMENT_ADMIN' permission, enabling access to all facilities.") }} @@ -523,7 +523,7 @@ export default defineComponent({ isUserFetched: false, showPassword: false, shopifyShopsForProductStore: [] as any, - isUserFulfillmentAdmin: [] + isUserFulfillmentAdmin: false } }, @@ -537,7 +537,7 @@ export default defineComponent({ if (productStoreId) { this.getShopifyShops(productStoreId); } - this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.userLoginId) + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.securityGroup?.groupId) this.isUserFetched = true this.username = this.selectedUser.groupName ? (this.selectedUser.groupName)?.toLowerCase() : (`${this.selectedUser.firstName}.${this.selectedUser.lastName}`?.toLowerCase()) }, @@ -951,6 +951,7 @@ export default defineComponent({ if (!hasError(resp)) { showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) + this.isUserFulfillmentAdmin = false this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { throw resp.data @@ -964,6 +965,7 @@ export default defineComponent({ if (hasError(resp)) throw resp.data showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.securityGroup?.groupId) this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { @@ -975,6 +977,7 @@ export default defineComponent({ if (!hasError(resp)) { showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.securityGroup?.groupId) this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { throw resp.data From 076ca8fdee7335ff216406c355cdea386d255877 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Mon, 16 Sep 2024 14:23:37 +0530 Subject: [PATCH 4/9] Update UserDetails.vue --- src/views/UserDetails.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index 880008e..c92bc88 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -325,7 +325,7 @@ {{ translate("This user has 'STOREFULFILLMENT_ADMIN' permission, enabling access to all facilities.") }} - + {{ getUserFacilities().length === 1 ? translate('Added to 1 facility') : translate('Added to facilities', { count: getUserFacilities().length }) }} From 576597eead5baa9afb186ce00a67faa6d5c21509 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Mon, 16 Sep 2024 14:32:27 +0530 Subject: [PATCH 5/9] Improved: update to pass the selected groupId from the event(#173) --- src/views/UserDetails.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index c92bc88..a898933 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -965,7 +965,7 @@ export default defineComponent({ if (hasError(resp)) throw resp.data showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) - this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.securityGroup?.groupId) + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(groupId) this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { @@ -977,7 +977,7 @@ export default defineComponent({ if (!hasError(resp)) { showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) - this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(this.selectedUser.securityGroup?.groupId) + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(groupId) this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { throw resp.data From 5c6b86f7a687162f99a1c810a4a9922042ca0486 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Tue, 17 Sep 2024 11:04:16 +0530 Subject: [PATCH 6/9] Improved: updated the api call and add conditional payload(#173) --- src/services/UserService.ts | 2 +- src/views/UserDetails.vue | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 687e5ff..a710d83 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -331,7 +331,7 @@ const isUserFulfillmentAdmin = async (groupId: string): Promise => { const payload = { inputFields: { groupId, - permissionId: "STOREFULFILLMENT_ADMIN" + permissionId: groupId ? "STOREFULFILLMENT_ADMIN" : "" }, entityName: "SecurityGroupPermission", filterByDate: "Y", diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index a898933..37cbadc 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -951,7 +951,6 @@ export default defineComponent({ if (!hasError(resp)) { showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) - this.isUserFulfillmentAdmin = false this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { throw resp.data @@ -965,7 +964,6 @@ export default defineComponent({ if (hasError(resp)) throw resp.data showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) - this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(groupId) this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { @@ -977,12 +975,12 @@ export default defineComponent({ if (!hasError(resp)) { showToast(translate('Security group updated successfully.')) const userSecurityGroup = await UserService.getUserSecurityGroup(this.selectedUser.userLoginId) - this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(groupId) this.store.dispatch('user/updateSelectedUser', { ...this.selectedUser, securityGroup: userSecurityGroup }) } else { throw resp.data } } + this.isUserFulfillmentAdmin = await UserService.isUserFulfillmentAdmin(groupId) } catch (error: any) { const errorMessage = error?.response?.data?.error.message; if (errorMessage && errorMessage?.startsWith('Security Error:')) { From a3bcc82ec791037f1313319313d6332d72cc9666 Mon Sep 17 00:00:00 2001 From: R-Sourabh Date: Tue, 17 Sep 2024 15:18:20 +0530 Subject: [PATCH 7/9] Improved: added support to get permissons for multiple `groupIds`(#173) --- src/components/SelectSecurityGroupModal.vue | 6 +++++- src/locales/en.json | 2 ++ src/services/UserService.ts | 6 +++--- src/views/UserDetails.vue | 5 +++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/SelectSecurityGroupModal.vue b/src/components/SelectSecurityGroupModal.vue index 2027901..9100030 100644 --- a/src/components/SelectSecurityGroupModal.vue +++ b/src/components/SelectSecurityGroupModal.vue @@ -121,4 +121,8 @@ }, }); - \ No newline at end of file + \ No newline at end of file diff --git a/src/locales/en.json b/src/locales/en.json index d237ef1..8d11d3b 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -12,6 +12,7 @@ "Add phone number": "Add phone number", "Add profile picture": "Add profile picture", "added to product store": "added to product store", + "Add to security group": "Add to security group", "Add to a product store": "Add to a product store", "All": "All", "App": "App", @@ -178,6 +179,7 @@ "Security group created successfully.": "Security group created successfully.", "Security group name is required.": "Security group name is required.", "Security group permission association successfully updated.": "Security group permission association successfully updated.", + "Select security groups": "Select security groups", "Select a security group to view its details": "Select a security group to view its details", "Select facility": "Select facility", "Select facilities": "Select facilities", diff --git a/src/services/UserService.ts b/src/services/UserService.ts index de0a3b8..9a1dd12 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -324,11 +324,11 @@ const getUserSecurityGroups = async (userLoginId: string): Promise => { return userSecurityGroups } -const isUserFulfillmentAdmin = async (groupId: string): Promise => { +const isUserFulfillmentAdmin = async (groupIds: string): Promise => { const payload = { inputFields: { - groupId, - permissionId: groupId ? "STOREFULFILLMENT_ADMIN" : "" + groupId: groupIds, + permissionId: groupIds.length ? "STOREFULFILLMENT_ADMIN" : "" }, entityName: "SecurityGroupPermission", filterByDate: "Y", diff --git a/src/views/UserDetails.vue b/src/views/UserDetails.vue index 49d1b20..b189ae4 100644 --- a/src/views/UserDetails.vue +++ b/src/views/UserDetails.vue @@ -275,7 +275,7 @@