@dropins/storefront-company-management 1.0.0-alpha2000 → 1.0.0-alpha2001
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/chunks/getCompanyUsers.js +2 -2
- package/chunks/getCompanyUsers.js.map +1 -1
- package/containers/CompanyUsers.js +1 -1
- package/containers/CompanyUsers.js.map +1 -1
- package/containers/CustomerCompanyInfo.js +1 -1
- package/containers/CustomerCompanyInfo.js.map +1 -1
- package/hooks/containers/index.d.ts +1 -0
- package/hooks/containers/useCompanyUsers.d.ts +33 -0
- package/package.json +1 -1
- package/types/api/companyUsers.types.d.ts +1 -1
- package/types/api/updateCompanyUserStatus.types.d.ts +1 -1
- package/api/deleteCompanyUser/graphql/index.d.ts +0 -18
- package/api/getCompanyUsers/graphql/index.d.ts +0 -18
- package/api/updateCompanyUserStatus/graphql/index.d.ts +0 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*! Copyright 2025 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{f as p,c as d,h as m}from"./fetch-error.js";const f=e=>{try{return btoa(e)}catch(t){throw new Error(`Failed to encode base64: ${t}`)}},
|
|
3
|
+
import{f as p,c as d,h as m}from"./fetch-error.js";const f=e=>{try{return btoa(e)}catch(t){throw new Error(`Failed to encode base64: ${t}`)}},g=e=>{try{return atob(e)}catch{return e}},l=e=>{if(!e||typeof e!="string")throw new Error("User ID must be a non-empty string");return f(e)},y=e=>!e||typeof e!="string"?e:g(e),h=`
|
|
4
4
|
mutation DELETE_COMPANY_USER($id: ID!) {
|
|
5
5
|
deleteCompanyUserV2(id: $id) {
|
|
6
6
|
success
|
|
@@ -41,5 +41,5 @@ import{f as p,c as d,h as m}from"./fetch-error.js";const f=e=>{try{return btoa(e
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
`,I=async(e={})=>{var n,a,i,o;const{pageSize:t=20,currentPage:r=1,filter:u}=e;try{const s=await p(E,{method:"GET",cache:"no-cache",variables:{pageSize:t,currentPage:r,filter:u}}).catch(d);return(n=s.errors)!=null&&n.length&&m(s.errors),(o=(i=(a=s.data)==null?void 0:a.company)==null?void 0:i.users)!=null&&o.items?{users:s.data.company.users.items.map(c=>({id:
|
|
44
|
+
`,I=async(e={})=>{var n,a,i,o;const{pageSize:t=20,currentPage:r=1,filter:u}=e;try{const s=await p(E,{method:"GET",cache:"no-cache",variables:{pageSize:t,currentPage:r,filter:u}}).catch(d);return(n=s.errors)!=null&&n.length&&m(s.errors),(o=(i=(a=s.data)==null?void 0:a.company)==null?void 0:i.users)!=null&&o.items?{users:s.data.company.users.items.map(c=>({id:y(c.id),firstName:c.firstname,lastName:c.lastname,email:c.email,role:c.role.name,status:c.status,...c.team&&{team:c.team.name}})),pageInfo:{pageSize:s.data.company.users.page_info.page_size,currentPage:s.data.company.users.page_info.current_page,totalPages:s.data.company.users.page_info.total_pages},totalCount:s.data.company.users.total_count}:{users:[],pageInfo:{pageSize:t,currentPage:r,totalPages:1}}}catch{return{users:[],pageInfo:{pageSize:t,currentPage:r,totalPages:1}}}};export{S as d,I as g,T as u};
|
|
45
45
|
//# sourceMappingURL=getCompanyUsers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCompanyUsers.js","sources":["/@dropins/storefront-company-management/src/lib/encoding.ts","/@dropins/storefront-company-management/src/api/deleteCompanyUser/graphql/deleteCompanyUser.graphql.ts","/@dropins/storefront-company-management/src/api/deleteCompanyUser/deleteCompanyUser.ts","/@dropins/storefront-company-management/src/api/updateCompanyUserStatus/graphql/updateCompanyUserStatus.graphql.ts","/@dropins/storefront-company-management/src/api/updateCompanyUserStatus/updateCompanyUserStatus.ts","/@dropins/storefront-company-management/src/api/getCompanyUsers/graphql/companyUsers.graphql.ts","/@dropins/storefront-company-management/src/api/getCompanyUsers/getCompanyUsers.ts"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Encodes a string to base64\n * @param value - The string to encode\n * @returns The base64 encoded string\n * @throws Error if encoding fails\n */\nexport const encodeBase64 = (value: string): string => {\n try {\n return btoa(value);\n } catch (error) {\n throw new Error(`Failed to encode base64: ${error}`);\n }\n};\n\n/**\n * Decodes a base64 encoded string\n * @param encoded - The base64 encoded string to decode\n * @returns The decoded string, or the original string if decoding fails\n */\nexport const decodeBase64 = (encoded: string): string => {\n try {\n return atob(encoded);\n } catch {\n // Return original if decoding fails (graceful fallback)\n return encoded;\n }\n};\n\n/**\n * Safely encodes a user ID to base64 for API transmission\n * @param userId - The user ID to encode\n * @returns The base64 encoded user ID\n * @throws Error if userId is empty or encoding fails\n */\nexport const encodeUserId = (userId: string): string => {\n if (!userId || typeof userId !== 'string') {\n throw new Error('User ID must be a non-empty string');\n }\n \n return encodeBase64(userId);\n};\n\n/**\n * Safely decodes a base64 encoded user ID from API response\n * @param encodedUserId - The base64 encoded user ID\n * @returns The decoded user ID, or the original string if decoding fails\n */\nexport const decodeUserId = (encodedUserId: string): string => {\n if (!encodedUserId || typeof encodedUserId !== 'string') {\n return encodedUserId;\n }\n \n return decodeBase64(encodedUserId);\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nexport const DELETE_COMPANY_USER_MUTATION = /* GraphQL */ `\n mutation DELETE_COMPANY_USER($id: ID!) {\n deleteCompanyUserV2(id: $id) {\n success\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { fetchGraphQl } from '../fetch-graphql';\nimport { handleNetworkError } from '../../lib/network-error';\nimport { handleFetchError } from '../../lib/fetch-error';\nimport { encodeUserId } from '../../lib';\nimport { DELETE_COMPANY_USER_MUTATION } from './graphql';\nimport { DeleteCompanyUserMutation, DeleteCompanyUserParams, DeleteCompanyUserResponse } from '../../types';\n\n/**\n * Deletes a company user by their ID\n * @param params - The parameters containing user ID\n * @param params.id - The ID of the user to delete (will be base64 encoded)\n * @returns Promise<DeleteCompanyUserResponse> - Object containing success status\n */\nexport const deleteCompanyUser = async (params: DeleteCompanyUserParams): Promise<DeleteCompanyUserResponse> => {\n const { id } = params;\n \n if (!id) {\n throw new Error('User ID is required to delete a company user');\n }\n\n try {\n const encodedId = encodeUserId(id);\n \n const response = await fetchGraphQl<DeleteCompanyUserMutation>(\n DELETE_COMPANY_USER_MUTATION,\n {\n method: 'POST',\n cache: 'no-cache',\n variables: {\n id: encodedId\n }\n }\n ).catch(handleNetworkError);\n\n if (response.errors?.length) {\n handleFetchError(response.errors);\n }\n\n if (!response.data?.deleteCompanyUserV2) {\n return {\n success: false\n };\n }\n\n return {\n success: response.data.deleteCompanyUserV2.success\n };\n } catch (error) {\n // Both handleNetworkError and handleFetchError throw errors\n // We return failure status as fallback\n return {\n success: false\n };\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nexport const UPDATE_COMPANY_USER_STATUS_MUTATION = /* GraphQL */ `\n mutation UPDATE_COMPANY_USER_STATUS($input: CompanyUserUpdateInput!) {\n updateCompanyUser(input: $input) {\n user {\n id\n status\n }\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { fetchGraphQl } from '../fetch-graphql';\nimport { handleNetworkError } from '../../lib/network-error';\nimport { handleFetchError } from '../../lib/fetch-error';\nimport { encodeUserId } from '../../lib';\nimport { UPDATE_COMPANY_USER_STATUS_MUTATION } from './graphql';\nimport { UpdateCompanyUserStatusMutation, UpdateCompanyUserStatusParams, UpdateCompanyUserStatusResponse } from '../../types';\n\n/**\n * Updates a company user's status (Active/Inactive)\n * @param params - The parameters containing user ID and new status\n * @param params.id - The ID of the user to update (will be base64 encoded)\n * @param params.status - The new status for the user (ACTIVE or INACTIVE)\n * @returns Promise<UpdateCompanyUserStatusResponse> - Object containing success status and updated user data\n */\nexport const updateCompanyUserStatus = async (params: UpdateCompanyUserStatusParams): Promise<UpdateCompanyUserStatusResponse> => {\n const { id, status } = params;\n \n if (!id) {\n throw new Error('User ID is required to update company user status');\n }\n \n if (!status || (status !== 'ACTIVE' && status !== 'INACTIVE')) {\n throw new Error('Valid status (ACTIVE or INACTIVE) is required to update company user status');\n }\n\n try {\n const encodedId = encodeUserId(id);\n \n const response = await fetchGraphQl<UpdateCompanyUserStatusMutation>(\n UPDATE_COMPANY_USER_STATUS_MUTATION,\n {\n method: 'POST',\n cache: 'no-cache',\n variables: {\n input: {\n id: encodedId,\n status\n }\n }\n }\n ).catch(handleNetworkError);\n\n if (response.errors?.length) {\n handleFetchError(response.errors);\n }\n\n if (!response.data?.updateCompanyUser?.user) {\n return {\n success: false\n };\n }\n\n return {\n success: true,\n user: {\n id: response.data.updateCompanyUser.user.id,\n status: response.data.updateCompanyUser.user.status\n }\n };\n } catch (error) {\n // Both handleNetworkError and handleFetchError throw errors\n // We return failure status as fallback\n return {\n success: false\n };\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nexport const COMPANY_USERS_QUERY = /* GraphQL */ `\n query COMPANY_USERS($pageSize: Int!, $currentPage: Int!, $filter: CompanyUsersFilterInput) {\n company {\n users(pageSize: $pageSize, currentPage: $currentPage, filter: $filter) {\n items {\n id\n firstname\n lastname\n email\n role {\n name\n }\n status\n team {\n name\n }\n }\n page_info {\n page_size\n current_page\n total_pages\n }\n total_count\n }\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { fetchGraphQl } from '../fetch-graphql';\nimport { handleNetworkError } from '../../lib/network-error';\nimport { handleFetchError } from '../../lib/fetch-error';\nimport { decodeUserId } from '../../lib';\nimport { COMPANY_USERS_QUERY } from './graphql';\nimport { CompanyUsersQuery, CompanyUser, CompanyUsersParams, CompanyUsersResponse } from '../../types';\n\n/**\n * Fetches the list of company users with pagination and optional filtering\n * @param params - Query parameters\n * @param params.pageSize - Number of items per page (default: 20)\n * @param params.currentPage - Current page number (default: 1)\n * @param params.filter - Optional filter to apply (e.g., { status: 'ACTIVE' })\n * @returns Promise<CompanyUsersResponse> - Object containing array of company users and pagination info\n */\nexport const getCompanyUsers = async (params: CompanyUsersParams = {}): Promise<CompanyUsersResponse> => {\n const { pageSize = 20, currentPage = 1, filter } = params;\n\n try {\n const response = await fetchGraphQl<CompanyUsersQuery>(\n COMPANY_USERS_QUERY,\n {\n method: 'GET',\n cache: 'no-cache',\n variables: {\n pageSize,\n currentPage,\n filter\n }\n }\n ).catch(handleNetworkError);\n\n if (response.errors?.length) {\n handleFetchError(response.errors);\n }\n\n if (!response.data?.company?.users?.items) {\n return {\n users: [],\n pageInfo: {\n pageSize,\n currentPage\n }\n };\n }\n\n // Transform the GraphQL response to CompanyUser interface\n const users: CompanyUser[] = response.data.company.users.items.map((item) => {\n return {\n id: decodeUserId(item.id),\n firstName: item.firstname,\n lastName: item.lastname,\n email: item.email,\n role: item.role.name,\n status: item.status,\n ...(item.team && { team: item.team.name })\n };\n });\n\n return {\n users,\n pageInfo: {\n pageSize: response.data.company.users.page_info.page_size,\n currentPage: response.data.company.users.page_info.current_page,\n totalPages: response.data.company.users.page_info.total_pages\n },\n totalCount: response.data.company.users.total_count\n };\n } catch (error) {\n // Both handleNetworkError and handleFetchError throw errors\n // We return empty users array with default page info as fallback\n return {\n users: [],\n pageInfo: {\n pageSize,\n currentPage\n }\n };\n }\n};\n"],"names":["encodeBase64","value","error","decodeBase64","encoded","encodeUserId","userId","decodeUserId","encodedUserId","DELETE_COMPANY_USER_MUTATION","deleteCompanyUser","params","id","encodedId","response","fetchGraphQl","handleNetworkError","_a","handleFetchError","_b","UPDATE_COMPANY_USER_STATUS_MUTATION","updateCompanyUserStatus","status","_c","COMPANY_USERS_QUERY","getCompanyUsers","pageSize","currentPage","filter","_d","item"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"getCompanyUsers.js","sources":["/@dropins/storefront-company-management/src/lib/encoding.ts","/@dropins/storefront-company-management/src/api/deleteCompanyUser/graphql/deleteCompanyUser.graphql.ts","/@dropins/storefront-company-management/src/api/deleteCompanyUser/deleteCompanyUser.ts","/@dropins/storefront-company-management/src/api/updateCompanyUserStatus/graphql/updateCompanyUserStatus.graphql.ts","/@dropins/storefront-company-management/src/api/updateCompanyUserStatus/updateCompanyUserStatus.ts","/@dropins/storefront-company-management/src/api/getCompanyUsers/graphql/companyUsers.graphql.ts","/@dropins/storefront-company-management/src/api/getCompanyUsers/getCompanyUsers.ts"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Encodes a string to base64\n * @param value - The string to encode\n * @returns The base64 encoded string\n * @throws Error if encoding fails\n */\nexport const encodeBase64 = (value: string): string => {\n try {\n return btoa(value);\n } catch (error) {\n throw new Error(`Failed to encode base64: ${error}`);\n }\n};\n\n/**\n * Decodes a base64 encoded string\n * @param encoded - The base64 encoded string to decode\n * @returns The decoded string, or the original string if decoding fails\n */\nexport const decodeBase64 = (encoded: string): string => {\n try {\n return atob(encoded);\n } catch {\n // Return original if decoding fails (graceful fallback)\n return encoded;\n }\n};\n\n/**\n * Safely encodes a user ID to base64 for API transmission\n * @param userId - The user ID to encode\n * @returns The base64 encoded user ID\n * @throws Error if userId is empty or encoding fails\n */\nexport const encodeUserId = (userId: string): string => {\n if (!userId || typeof userId !== 'string') {\n throw new Error('User ID must be a non-empty string');\n }\n \n return encodeBase64(userId);\n};\n\n/**\n * Safely decodes a base64 encoded user ID from API response\n * @param encodedUserId - The base64 encoded user ID\n * @returns The decoded user ID, or the original string if decoding fails\n */\nexport const decodeUserId = (encodedUserId: string): string => {\n if (!encodedUserId || typeof encodedUserId !== 'string') {\n return encodedUserId;\n }\n \n return decodeBase64(encodedUserId);\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nexport const DELETE_COMPANY_USER_MUTATION = /* GraphQL */ `\n mutation DELETE_COMPANY_USER($id: ID!) {\n deleteCompanyUserV2(id: $id) {\n success\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { fetchGraphQl } from '@/company-management/api';\nimport { handleNetworkError, handleFetchError, encodeUserId } from '@/company-management/lib';\nimport { DELETE_COMPANY_USER_MUTATION } from './graphql/deleteCompanyUser.graphql';\nimport { DeleteCompanyUserMutation, DeleteCompanyUserParams, DeleteCompanyUserResponse } from '@/company-management/types';\n\n/**\n * Deletes a company user by their ID\n * @param params - The parameters containing user ID\n * @param params.id - The ID of the user to delete (will be base64 encoded)\n * @returns Promise<DeleteCompanyUserResponse> - Object containing success status\n */\nexport const deleteCompanyUser = async (params: DeleteCompanyUserParams): Promise<DeleteCompanyUserResponse> => {\n const { id } = params;\n \n if (!id) {\n throw new Error('User ID is required to delete a company user');\n }\n\n try {\n const encodedId = encodeUserId(id);\n \n const response = await fetchGraphQl<DeleteCompanyUserMutation>(\n DELETE_COMPANY_USER_MUTATION,\n {\n method: 'POST',\n cache: 'no-cache',\n variables: {\n id: encodedId\n }\n }\n ).catch(handleNetworkError);\n\n if (response.errors?.length) {\n handleFetchError(response.errors);\n }\n\n if (!response.data?.deleteCompanyUserV2) {\n return {\n success: false\n };\n }\n\n return {\n success: response.data.deleteCompanyUserV2.success\n };\n } catch (error) {\n // Both handleNetworkError and handleFetchError throw errors\n // We return failure status as fallback\n return {\n success: false\n };\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nexport const UPDATE_COMPANY_USER_STATUS_MUTATION = /* GraphQL */ `\n mutation UPDATE_COMPANY_USER_STATUS($input: CompanyUserUpdateInput!) {\n updateCompanyUser(input: $input) {\n user {\n id\n status\n }\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { fetchGraphQl } from '@/company-management/api';\nimport { handleNetworkError, handleFetchError, encodeUserId } from '@/company-management/lib';\nimport { UPDATE_COMPANY_USER_STATUS_MUTATION } from './graphql/updateCompanyUserStatus.graphql';\nimport {\n UpdateCompanyUserStatusMutation,\n UpdateCompanyUserStatusParams,\n UpdateCompanyUserStatusResponse,\n} from '@/company-management/types';\n\n/**\n * Updates a company user's status (Active/Inactive)\n * @param params - The parameters containing user ID and new status\n * @param params.id - The ID of the user to update (will be base64 encoded)\n * @param params.status - The new status for the user (ACTIVE or INACTIVE)\n * @returns Promise<UpdateCompanyUserStatusResponse> - Object containing success status and updated user data\n */\nexport const updateCompanyUserStatus = async (params: UpdateCompanyUserStatusParams): Promise<UpdateCompanyUserStatusResponse> => {\n const { id, status } = params;\n \n if (!id) {\n throw new Error('User ID is required to update company user status');\n }\n \n if (!status || (status !== 'ACTIVE' && status !== 'INACTIVE')) {\n throw new Error('Valid status (ACTIVE or INACTIVE) is required to update company user status');\n }\n\n try {\n const encodedId = encodeUserId(id);\n \n const response = await fetchGraphQl<UpdateCompanyUserStatusMutation>(\n UPDATE_COMPANY_USER_STATUS_MUTATION,\n {\n method: 'POST',\n cache: 'no-cache',\n variables: {\n input: {\n id: encodedId,\n status\n }\n }\n }\n ).catch(handleNetworkError);\n\n if (response.errors?.length) {\n handleFetchError(response.errors);\n }\n\n if (!response.data?.updateCompanyUser?.user) {\n return {\n success: false\n };\n }\n\n return {\n success: true,\n user: {\n id: response.data.updateCompanyUser.user.id,\n status: response.data.updateCompanyUser.user.status\n }\n };\n } catch (error) {\n // Both handleNetworkError and handleFetchError throw errors\n // We return failure status as fallback\n return {\n success: false\n };\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nexport const COMPANY_USERS_QUERY = /* GraphQL */ `\n query COMPANY_USERS($pageSize: Int!, $currentPage: Int!, $filter: CompanyUsersFilterInput) {\n company {\n users(pageSize: $pageSize, currentPage: $currentPage, filter: $filter) {\n items {\n id\n firstname\n lastname\n email\n role {\n name\n }\n status\n team {\n name\n }\n }\n page_info {\n page_size\n current_page\n total_pages\n }\n total_count\n }\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { fetchGraphQl } from '@/company-management/api';\nimport { handleNetworkError, handleFetchError, decodeUserId } from '@/company-management/lib';\nimport { COMPANY_USERS_QUERY } from './graphql/companyUsers.graphql';\nimport { CompanyUsersQuery, CompanyUser, CompanyUsersParams, CompanyUsersResponse } from '@/company-management/types';\n\n/**\n * Fetches the list of company users with pagination and optional filtering\n * @param params - Query parameters\n * @param params.pageSize - Number of items per page (default: 20)\n * @param params.currentPage - Current page number (default: 1)\n * @param params.filter - Optional filter to apply (e.g., { status: 'ACTIVE' })\n * @returns Promise<CompanyUsersResponse> - Object containing array of company users and pagination info\n */\nexport const getCompanyUsers = async (params: CompanyUsersParams = {}): Promise<CompanyUsersResponse> => {\n const { pageSize = 20, currentPage = 1, filter } = params;\n\n try {\n const response = await fetchGraphQl<CompanyUsersQuery>(\n COMPANY_USERS_QUERY,\n {\n method: 'GET',\n cache: 'no-cache',\n variables: {\n pageSize,\n currentPage,\n filter\n }\n }\n ).catch(handleNetworkError);\n\n if (response.errors?.length) {\n handleFetchError(response.errors);\n }\n\n if (!response.data?.company?.users?.items) {\n return {\n users: [],\n pageInfo: {\n pageSize,\n currentPage,\n totalPages: 1\n }\n };\n }\n\n // Transform the GraphQL response to CompanyUser interface\n const users: CompanyUser[] = response.data.company.users.items.map((item) => {\n return {\n id: decodeUserId(item.id),\n firstName: item.firstname,\n lastName: item.lastname,\n email: item.email,\n role: item.role.name,\n status: item.status,\n ...(item.team && { team: item.team.name })\n };\n });\n\n return {\n users,\n pageInfo: {\n pageSize: response.data.company.users.page_info.page_size,\n currentPage: response.data.company.users.page_info.current_page,\n totalPages: response.data.company.users.page_info.total_pages\n },\n totalCount: response.data.company.users.total_count\n };\n } catch (error) {\n // Both handleNetworkError and handleFetchError throw errors\n // We return empty users array with default page info as fallback\n return {\n users: [],\n pageInfo: {\n pageSize,\n currentPage,\n totalPages: 1\n }\n };\n }\n};\n"],"names":["encodeBase64","value","error","decodeBase64","encoded","encodeUserId","userId","decodeUserId","encodedUserId","DELETE_COMPANY_USER_MUTATION","deleteCompanyUser","params","id","encodedId","response","fetchGraphQl","handleNetworkError","_a","handleFetchError","_b","UPDATE_COMPANY_USER_STATUS_MUTATION","updateCompanyUserStatus","status","_c","COMPANY_USERS_QUERY","getCompanyUsers","pageSize","currentPage","filter","_d","item"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2025 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsx as a,jsxs as h}from"@dropins/tools/preact-jsx-runtime.js";import{useState as b,useRef as F,useCallback as y,useEffect as G,useMemo as R}from"@dropins/tools/preact-hooks.js";import{InLineAlert as se,Button as P,Icon as oe,Skeleton as ie,SkeletonRow as le,Picker as ce}from"@dropins/tools/components.js";import{Fragment as me}from"@dropins/tools/preact.js";import{classes as j,VComponent as Q}from"@dropins/tools/lib.js";import{useText as q}from"@dropins/tools/i18n.js";import{u as de}from"../chunks/useCompanyContextListener.js";import{u as pe,d as ye,g as ue}from"../chunks/getCompanyUsers.js";import{f as ge}from"../chunks/fetchUserPermissions.js";import{u as Ce,C as be}from"../chunks/useInLineAlert.js";import"@dropins/tools/event-bus.js";import"../chunks/fetch-error.js";import"@dropins/tools/fetch-graphql.js";import"@dropins/tools/preact-compat.js";const he=(d,l)=>!d||typeof d!="string"?"":d==="ACTIVE"&&l.statusActive?l.statusActive:d==="INACTIVE"&&l.statusInactive?l.statusInactive:d.charAt(0).toUpperCase()+d.slice(1).toLowerCase(),ve=(d,l)=>{const u=(d==null?void 0:d.trim())||"",r=(l==null?void 0:l.trim())||"";return`${u} ${r}`.trim()},fe=({className:d,userId:l,userStatus:u,onClose:r,isOpen:w=!1,...I})=>{const[S,i]=b(!1),[v,U]=b(!1),{inLineAlertProps:T,showError:m,clearAlert:p}=Ce(),x=F(null),B=F(null),_=`modal-title-${l}`,k=`modal-desc-${l}`,e=q({title:"Company.CompanyUsers.managementModal.title",setActiveText:"Company.CompanyUsers.managementModal.setActiveText",setInactiveText:"Company.CompanyUsers.managementModal.setInactiveText",deleteText:"Company.CompanyUsers.managementModal.deleteText",setActiveButton:"Company.CompanyUsers.managementModal.setActiveButton",setInactiveButton:"Company.CompanyUsers.managementModal.setInactiveButton",settingActiveButton:"Company.CompanyUsers.managementModal.settingActiveButton",settingInactiveButton:"Company.CompanyUsers.managementModal.settingInactiveButton",deleteButton:"Company.CompanyUsers.managementModal.deleteButton",deletingButton:"Company.CompanyUsers.managementModal.deletingButton",cancelButton:"Company.CompanyUsers.managementModal.cancelButton",setActiveErrorGeneric:"Company.CompanyUsers.managementModal.setActiveErrorGeneric",setActiveErrorSpecific:"Company.CompanyUsers.managementModal.setActiveErrorSpecific",setInactiveErrorGeneric:"Company.CompanyUsers.managementModal.setInactiveErrorGeneric",setInactiveErrorSpecific:"Company.CompanyUsers.managementModal.setInactiveErrorSpecific",deleteErrorGeneric:"Company.CompanyUsers.managementModal.deleteErrorGeneric",deleteErrorSpecific:"Company.CompanyUsers.managementModal.deleteErrorSpecific",ariaCloseModal:"Company.CompanyUsers.managementModal.ariaLabels.closeModal",ariaModalDescription:"Company.CompanyUsers.managementModal.ariaLabels.modalDescription"}),s=y(async()=>{if(v)return;const o=u==="ACTIVE"?"INACTIVE":"ACTIVE",f=o==="ACTIVE";U(!0),p();try{(await pe({id:l,status:o})).success?r():m(f?e.setActiveErrorSpecific:e.setInactiveErrorSpecific)}catch{m(f?e.setActiveErrorGeneric:e.setInactiveErrorGeneric)}finally{U(!1)}},[l,u,r,v,p,m,e.setActiveErrorSpecific,e.setInactiveErrorSpecific,e.setActiveErrorGeneric,e.setInactiveErrorGeneric]),g=y(async()=>{if(!S){i(!0),p();try{(await ye({id:l})).success?r():m(e.deleteErrorSpecific)}catch{m(e.deleteErrorGeneric)}finally{i(!1)}}},[l,r,S,p,m,e.deleteErrorSpecific,e.deleteErrorGeneric]),L=y(()=>{p(),r()},[r,p]),C=y(o=>{if(o.key==="Escape"&&(p(),r()),o.key==="Tab"){const f=x.current;if(!f)return;const n=f.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'),M=n[0],A=n[n.length-1];o.shiftKey?document.activeElement===M&&(A.focus(),o.preventDefault()):document.activeElement===A&&(M.focus(),o.preventDefault())}},[r,p]),N=y(o=>{o.target===o.currentTarget&&(p(),r())},[r,p]),D=y(()=>{p(),r()},[r,p]);return G(()=>{if(w)return B.current=document.activeElement,document.addEventListener("keydown",C),setTimeout(()=>{const o=x.current;if(o){const f=o.querySelector("button");f?f.focus():o.focus()}},100),()=>{document.removeEventListener("keydown",C)};B.current&&B.current.focus()},[w,C]),w?a("div",{className:j(["company-management-company-users-management-modal-overlay",d]),onClick:N,...I,children:h("div",{ref:x,className:"company-management-company-users-management-modal",role:"dialog","aria-modal":"true","aria-labelledby":_,"aria-describedby":k,tabIndex:-1,children:[h("div",{className:"company-management-company-users-management-modal__header",children:[a("h2",{id:_,className:"company-management-company-users-management-modal__title",children:e.title}),a("button",{className:"company-management-company-users-management-modal__close",onClick:D,"aria-label":e.ariaCloseModal,children:"×"})]}),h("div",{id:k,className:"company-management-company-users-management-modal__content",children:[a("p",{className:"company-management-company-users-management-modal__text",children:u==="ACTIVE"?e.setInactiveText:e.setActiveText}),a("p",{className:"company-management-company-users-management-modal__text",children:e.deleteText})]}),(T==null?void 0:T.text)&&a("div",{className:"company-management-company-users-management-modal__alert",role:"alert","aria-live":"assertive",children:a(se,{type:"error",heading:T.text,icon:T.icon,"data-testid":"companyUsersManagementModalAlert"})}),h("div",{className:"company-management-company-users-management-modal__actions",children:[a(P,{variant:"primary",onClick:s,disabled:v,className:"company-management-company-users-management-modal__button-primary",children:v?u==="ACTIVE"?e.settingInactiveButton:e.settingActiveButton:u==="ACTIVE"?e.setInactiveButton:e.setActiveButton}),a("button",{type:"button",onClick:g,disabled:S,className:"company-management-company-users-management-modal__button-delete",children:S?e.deletingButton:e.deleteButton}),a(P,{variant:"secondary",onClick:L,className:"company-management-company-users-management-modal__button-cancel",children:e.cancelButton})]})]})}):null},Ue=({className:d,children:l,columns:u=[],rowData:r=[],mobileLayout:w="none",caption:I,expandedRows:S=new Set,loading:i=!1,skeletonRowCount:v=10,onSortChange:U,...T})=>{const m=q({sortedAscending:"Dropin.Table.sortedAscending",sortedDescending:"Dropin.Table.sortedDescending",sortBy:"Dropin.Table.sortBy"}),p=e=>{if(!U)return;let s;e.sortBy===!0?s="asc":e.sortBy==="asc"?s="desc":s=!0,U(e.key,s)},x=e=>{if(e.sortBy===void 0)return null;let s,g;return e.sortBy==="asc"?(s="ChevronUp",g=m.sortedAscending.replace("{label}",e.label)):e.sortBy==="desc"?(s="ChevronDown",g=m.sortedDescending.replace("{label}",e.label)):(s="Sort",g=m.sortBy.replace("{label}",e.label)),a(P,{variant:"tertiary",size:"medium",className:"dropin-table__header__sort-button",icon:a(oe,{source:s}),"aria-label":g,onClick:()=>p(e)})},B=()=>Array.from({length:v},(e,s)=>a("tr",{className:"dropin-table__body__row",children:u.map(g=>a("td",{className:"dropin-table__body__cell","data-label":g.label,children:a(ie,{children:a(le,{variant:"row",size:"small",fullWidth:!0})})},g.key))},`skeleton-${s}`)),_=()=>r.map((e,s)=>{const g=e._rowDetails!==void 0,L=S.has(s);return h(me,{children:[a("tr",{className:"dropin-table__body__row",children:u.map(C=>{const N=e[C.key];return typeof N=="string"||typeof N=="number"?a("td",{className:"dropin-table__body__cell","data-label":C.label,children:N},C.key):a("td",{className:"dropin-table__body__cell","data-label":C.label,children:a(Q,{node:N})},C.key)})}),g&&L&&a("tr",{className:"dropin-table__row-details dropin-table__row-details--expanded",id:`row-${s}-details`,children:a("td",{className:"dropin-table__row-details__cell",colSpan:u.length,role:"region","aria-labelledby":`row-${s}-details`,children:typeof e._rowDetails=="string"?e._rowDetails:a(Q,{node:e._rowDetails})})},`${s}-details`)]},s)}),k=e=>{if(e.sortBy===!0)return"none";if(e.sortBy==="asc")return"ascending";if(e.sortBy==="desc")return"descending"};return a("div",{className:j(["dropin-table",`dropin-table--mobile-layout-${w}`,d]),children:h("table",{...T,className:"dropin-table__table",children:[I&&a("caption",{className:"dropin-table__caption",children:I}),a("thead",{className:"dropin-table__header",children:a("tr",{className:"dropin-table__header__row",children:u.map(e=>h("th",{className:j(["dropin-table__header__cell",["dropin-table__header__cell--sorted",e.sortBy==="asc"||e.sortBy==="desc"],["dropin-table__header__cell--sortable",e.sortBy!==void 0]]),"aria-sort":k(e),children:[e.label,x(e)]},e.key))})}),a("tbody",{className:"dropin-table__body",children:i?B():_()})]})})},_e=20,z=1,Ae=[{text:"20",value:"20"},{text:"30",value:"30"},{text:"50",value:"50"},{text:"100",value:"100"},{text:"200",value:"200"}],ze=({children:d,className:l,...u})=>{var H;const[r,w]=b([]),[I,S]=b(!1),[i,v]=b(z),[U,T]=b(_e),[m,p]=b("all"),[x,B]=b(0),[_,k]=b(1),[e,s]=b(""),[g,L]=b(!1),[C,N]=b(""),[D,o]=b(null),f=F(null),n=q({showAllUsers:"Company.CompanyUsers.filters.showAll",showActiveUsers:"Company.CompanyUsers.filters.showActive",showInactiveUsers:"Company.CompanyUsers.filters.showInactive",idColumn:"Company.CompanyUsers.columns.id",nameColumn:"Company.CompanyUsers.columns.name",emailColumn:"Company.CompanyUsers.columns.email",roleColumn:"Company.CompanyUsers.columns.role",teamColumn:"Company.CompanyUsers.columns.team",statusColumn:"Company.CompanyUsers.columns.status",actionsColumn:"Company.CompanyUsers.columns.actions",statusActive:"Company.CompanyUsers.status.active",statusInactive:"Company.CompanyUsers.status.inactive",emptyTeam:"Company.CompanyUsers.emptyTeam",emptyActions:"Company.CompanyUsers.emptyActions",itemsText:"Company.CompanyUsers.pagination.itemsCount",itemsPerPageLabel:"Company.CompanyUsers.pagination.itemsPerPage",showLabel:"Company.CompanyUsers.pagination.show",perPageLabel:"Company.CompanyUsers.pagination.perPage",previousPage:"Company.CompanyUsers.pagination.previous",nextPage:"Company.CompanyUsers.pagination.next",pageInfo:"Company.CompanyUsers.pagination.pageInfo",ariaLoadingUsers:"Company.CompanyUsers.ariaLabels.loadingUsers",ariaUsersTable:"Company.CompanyUsers.ariaLabels.usersTable",ariaFilterOptions:"Company.CompanyUsers.ariaLabels.filterOptions",ariaPaginationNav:"Company.CompanyUsers.ariaLabels.paginationNav",ariaPageSizeSelector:"Company.CompanyUsers.ariaLabels.pageSizeSelector",ariaPreviousPageFull:"Company.CompanyUsers.ariaLabels.previousPageFull",ariaNextPageFull:"Company.CompanyUsers.ariaLabels.nextPageFull",ariaCurrentPage:"Company.CompanyUsers.ariaLabels.currentPage",ariaShowingUsers:"Company.CompanyUsers.ariaLabels.showingUsers",ariaDataLoaded:"Company.CompanyUsers.ariaLabels.dataLoaded",ariaDataError:"Company.CompanyUsers.ariaLabels.dataError",ariaPageNavigation:"Company.CompanyUsers.ariaLabels.pageNavigation",manageUser:"Company.CompanyUsers.actions.manage",ariaManageUser:"Company.CompanyUsers.ariaLabels.manageUser"}),M=F(n);M.current=n;const A=F(null),K=R(()=>{switch(m){case"active":return{status:"ACTIVE"};case"inactive":return{status:"INACTIVE"};default:return}},[m]),V=y(async()=>{var t;S(!0);try{const c=await ue({pageSize:U,currentPage:i,filter:K});if(w(c.users),B(c.totalCount||c.users.length),s(M.current.ariaDataLoaded.replace("{count}",c.users.length.toString())),(t=c.pageInfo)!=null&&t.totalPages)k(c.pageInfo.totalPages);else{const E=Math.ceil((c.totalCount||c.users.length)/U);k(E||1)}}catch(c){console.error("Failed to fetch company users:",c),w([]),B(0),k(1),s(M.current.ariaDataError)}finally{S(!1)}},[U,i,K]);A.current=V;const Z=y(async()=>{try{const{allowedIds:t}=await ge();o(t)}catch(t){console.error("Failed to fetch user permissions:",t),o(new Set)}},[]);G(()=>{V()},[V]),G(()=>{Z()},[Z]),G(()=>{!I&&f.current&&r.length>0&&f.current.setAttribute("aria-busy","false")},[I,i,m,r.length]);const X=y(()=>{var t;v(z),(t=A.current)==null||t.call(A)},[]);de(X);const $=y(t=>{p(t),v(z)},[]),Y=y(t=>{let c;if(typeof t=="string")c=t;else if("target"in t&&t.target&&"value"in t.target)c=t.target.value;else return;const E=parseInt(c,10);isNaN(E)||(T(E),v(z))},[]),ee=y(()=>{i>1&&v(i-1)},[i]),ae=y(()=>{i<_&&v(i+1)},[i,_]),W=y(t=>{N(t),L(!0)},[]),te=y(()=>{var t;L(!1),N(""),(t=A.current)==null||t.call(A)},[]),ne=R(()=>{const t=M.current;return[{key:"id",label:t.idColumn},{key:"name",label:t.nameColumn},{key:"email",label:t.emailColumn},{key:"role",label:t.roleColumn},{key:"team",label:t.teamColumn},{key:"status",label:t.statusColumn},{key:"actions",label:t.actionsColumn}]},[]),O=(D==null?void 0:D.has("Magento_Company::users_edit"))||!1,re=R(()=>r.map(t=>{var J;const c=ve(t.firstName,t.lastName),E=M.current;return{id:t.id,name:c,email:t.email,role:t.role,team:t.team||E.emptyTeam,status:he(t.status,E),actions:O?a(P,{variant:"tertiary",onClick:()=>W(t.id),"aria-label":((J=E.ariaManageUser)==null?void 0:J.replace("{name}",c))||`Manage user ${c}`,className:"manage-user-button",children:E.manageUser||"Manage"}):a("span",{className:"no-actions",children:E.emptyActions})}}),[r,W,O]);return h("section",{className:l,...u,children:[a("div",{className:"sr-only",role:"status","aria-live":"polite","aria-atomic":"true",children:e}),h("div",{className:"filterButtons",role:"group","aria-label":n.ariaFilterOptions,children:[m!=="all"&&a(P,{variant:"tertiary",onClick:()=>$("all"),"aria-label":n.showAllUsers,children:n.showAllUsers}),m!=="active"&&a(P,{variant:"tertiary",onClick:()=>$("active"),"aria-label":n.showActiveUsers,children:n.showActiveUsers}),m!=="inactive"&&a(P,{variant:"tertiary",onClick:()=>$("inactive"),"aria-label":n.showInactiveUsers,children:n.showInactiveUsers})]}),a("div",{ref:f,"aria-busy":I,children:I?h("div",{className:"loadingContainer",role:"status","aria-live":"polite",children:[a(be,{testId:"companyUsersTableLoader"}),a("span",{className:"sr-only",children:n.ariaLoadingUsers})]}):a(Ue,{columns:ne,rowData:re,mobileLayout:"stacked","aria-label":n.ariaUsersTable,summary:n.ariaShowingUsers.replace("{count}",r.length.toString())})}),h("nav",{"aria-label":n.ariaPaginationNav,className:"paginationContainer",children:[a("div",{"aria-live":"polite","aria-atomic":"true",children:n.itemsText.replace("{count}",x.toString())}),_>1&&h("div",{className:"paginationButtons",role:"group","aria-label":n.ariaPageNavigation,children:[a(P,{variant:"secondary",onClick:ee,disabled:i===1,"aria-label":n.ariaPreviousPageFull.replace("{current}",i.toString()),children:n.previousPage}),a("span",{"aria-current":"page","aria-live":"polite",children:n.pageInfo.replace("{current}",i.toString()).replace("{total}",_.toString())}),a(P,{variant:"secondary",onClick:ae,disabled:i===_,"aria-label":n.ariaNextPageFull.replace("{current}",i.toString()),children:n.nextPage})]}),h("div",{className:"pageSizeSelector",children:[a("label",{htmlFor:"page-size-select",id:"page-size-label",children:a("span",{children:n.showLabel})}),a(ce,{id:"page-size-select",name:"pageSize",value:U.toString(),options:Ae,onChange:Y,"aria-labelledby":"page-size-label","aria-describedby":"page-size-description"}),a("span",{id:"page-size-description",children:n.perPageLabel})]})]}),d,C&&O&&a(fe,{isOpen:g,userId:C,userStatus:((H=r.find(t=>t.id===C))==null?void 0:H.status)||"ACTIVE",onClose:te})]})};export{ze as CompanyUsers,ze as default};
|
|
3
|
+
import{jsx as a,jsxs as A}from"@dropins/tools/preact-jsx-runtime.js";import{useState as E,useRef as F,useMemo as R,useCallback as h,useEffect as G}from"@dropins/tools/preact-hooks.js";import{InLineAlert as K,Button as P,Icon as Z,Skeleton as W,SkeletonRow as H,Picker as J}from"@dropins/tools/components.js";import{Fragment as Q}from"@dropins/tools/preact.js";import{classes as $,VComponent as q}from"@dropins/tools/lib.js";import{useText as O}from"@dropins/tools/i18n.js";import{u as X,C as Y}from"../chunks/useInLineAlert.js";import{g as ee,u as ae,d as te}from"../chunks/getCompanyUsers.js";import{u as ne}from"../chunks/useCompanyContextListener.js";import{f as re}from"../chunks/fetchUserPermissions.js";import"@dropins/tools/preact-compat.js";import"../chunks/fetch-error.js";import"@dropins/tools/fetch-graphql.js";import"@dropins/tools/event-bus.js";const se=(c,i)=>!c||typeof c!="string"?"":c==="ACTIVE"&&i.statusActive?i.statusActive:c==="INACTIVE"&&i.statusInactive?i.statusInactive:c.charAt(0).toUpperCase()+c.slice(1).toLowerCase(),oe=(c,i)=>{const y=(c==null?void 0:c.trim())||"",l=(i==null?void 0:i.trim())||"";return`${y} ${l}`.trim()},ie=20,V=1,le=({translations:c})=>{const[i,y]=E([]),[l,S]=E(!1),[p,b]=E(V),[I,t]=E(ie),[g,f]=E("all"),[m,d]=E(0),[v,T]=E(1),[N,w]=E(""),[e,n]=E(null),u=F(c);u.current=c;const B=R(()=>{switch(g){case"active":return{status:"ACTIVE"};case"inactive":return{status:"INACTIVE"};default:return}},[g]),C=h(async()=>{S(!0);try{const o=await ee({pageSize:I,currentPage:p,filter:B});y(o.users),d(o.totalCount||o.users.length),T(o.pageInfo.totalPages),w(u.current.ariaDataLoaded.replace("{count}",o.users.length.toString()))}catch{y([]),d(0),T(1),w(u.current.ariaDataError)}finally{S(!1)}},[I,p,B]),U=h(async()=>{try{const{allowedIds:o}=await re();n(o)}catch{n(new Set)}},[]);G(()=>{C()},[C]),G(()=>{U()},[U]);const L=h(o=>{f(o),b(V)},[]),s=h(o=>{let r;if(typeof o=="string")r=o;else if("target"in o&&o.target&&"value"in o.target)r=o.target.value;else return;const D=parseInt(r,10);isNaN(D)||(t(D),b(V))},[]),_=h(()=>{p>1&&b(p-1)},[p]),k=h(()=>{p<v&&b(p+1)},[p,v]),x=(e==null?void 0:e.has("Magento_Company::users_edit"))||!1,M=h(async()=>{await C()},[C]);return{users:i,userPermissions:e,currentPage:p,pageSize:I,totalItems:m,totalPages:v,filterType:g,filter:B,loading:l,announcement:N,canEditUsers:x,handleFilterChange:L,handlePageSizeChange:s,handlePreviousPage:_,handleNextPage:k,refreshUsers:M}},ce=({className:c,userId:i,userStatus:y,onClose:l,isOpen:S=!1,...p})=>{const[b,I]=E(!1),[t,g]=E(!1),{inLineAlertProps:f,showError:m,clearAlert:d}=X(),v=F(null),T=F(null),N=`modal-title-${i}`,w=`modal-desc-${i}`,e=O({title:"Company.CompanyUsers.managementModal.title",setActiveText:"Company.CompanyUsers.managementModal.setActiveText",setInactiveText:"Company.CompanyUsers.managementModal.setInactiveText",deleteText:"Company.CompanyUsers.managementModal.deleteText",setActiveButton:"Company.CompanyUsers.managementModal.setActiveButton",setInactiveButton:"Company.CompanyUsers.managementModal.setInactiveButton",settingActiveButton:"Company.CompanyUsers.managementModal.settingActiveButton",settingInactiveButton:"Company.CompanyUsers.managementModal.settingInactiveButton",deleteButton:"Company.CompanyUsers.managementModal.deleteButton",deletingButton:"Company.CompanyUsers.managementModal.deletingButton",cancelButton:"Company.CompanyUsers.managementModal.cancelButton",setActiveErrorGeneric:"Company.CompanyUsers.managementModal.setActiveErrorGeneric",setActiveErrorSpecific:"Company.CompanyUsers.managementModal.setActiveErrorSpecific",setInactiveErrorGeneric:"Company.CompanyUsers.managementModal.setInactiveErrorGeneric",setInactiveErrorSpecific:"Company.CompanyUsers.managementModal.setInactiveErrorSpecific",deleteErrorGeneric:"Company.CompanyUsers.managementModal.deleteErrorGeneric",deleteErrorSpecific:"Company.CompanyUsers.managementModal.deleteErrorSpecific",ariaCloseModal:"Company.CompanyUsers.managementModal.ariaLabels.closeModal",ariaModalDescription:"Company.CompanyUsers.managementModal.ariaLabels.modalDescription"}),n=h(async()=>{if(t)return;const s=y==="ACTIVE"?"INACTIVE":"ACTIVE",_=s==="ACTIVE";g(!0),d();try{(await ae({id:i,status:s})).success?l():m(_?e.setActiveErrorSpecific:e.setInactiveErrorSpecific)}catch{m(_?e.setActiveErrorGeneric:e.setInactiveErrorGeneric)}finally{g(!1)}},[i,y,l,t,d,m,e.setActiveErrorSpecific,e.setInactiveErrorSpecific,e.setActiveErrorGeneric,e.setInactiveErrorGeneric]),u=h(async()=>{if(!b){I(!0),d();try{(await te({id:i})).success?l():m(e.deleteErrorSpecific)}catch{m(e.deleteErrorGeneric)}finally{I(!1)}}},[i,l,b,d,m,e.deleteErrorSpecific,e.deleteErrorGeneric]),B=h(()=>{d(),l()},[l,d]),C=h(s=>{if(s.key==="Escape"&&(d(),l()),s.key==="Tab"){const _=v.current;if(!_)return;const k=_.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'),x=k[0],M=k[k.length-1];s.shiftKey?document.activeElement===x&&(M.focus(),s.preventDefault()):document.activeElement===M&&(x.focus(),s.preventDefault())}},[l,d]),U=h(s=>{s.target===s.currentTarget&&(d(),l())},[l,d]),L=h(()=>{d(),l()},[l,d]);return G(()=>{if(S)return T.current=document.activeElement,document.addEventListener("keydown",C),setTimeout(()=>{const s=v.current;if(s){const _=s.querySelector("button");_?_.focus():s.focus()}},100),()=>{document.removeEventListener("keydown",C)};T.current&&T.current.focus()},[S,C]),S?a("div",{className:$(["company-management-company-users-management-modal-overlay",c]),onClick:U,...p,children:A("div",{ref:v,className:"company-management-company-users-management-modal",role:"dialog","aria-modal":"true","aria-labelledby":N,"aria-describedby":w,tabIndex:-1,children:[A("div",{className:"company-management-company-users-management-modal__header",children:[a("h2",{id:N,className:"company-management-company-users-management-modal__title",children:e.title}),a("button",{className:"company-management-company-users-management-modal__close",onClick:L,"aria-label":e.ariaCloseModal,children:"×"})]}),A("div",{id:w,className:"company-management-company-users-management-modal__content",children:[a("p",{className:"company-management-company-users-management-modal__text",children:y==="ACTIVE"?e.setInactiveText:e.setActiveText}),a("p",{className:"company-management-company-users-management-modal__text",children:e.deleteText})]}),(f==null?void 0:f.text)&&a("div",{className:"company-management-company-users-management-modal__alert",role:"alert","aria-live":"assertive",children:a(K,{type:"error",heading:f.text,icon:f.icon,"data-testid":"companyUsersManagementModalAlert"})}),A("div",{className:"company-management-company-users-management-modal__actions",children:[a(P,{variant:"primary",onClick:n,disabled:t,className:"company-management-company-users-management-modal__button-primary",children:t?y==="ACTIVE"?e.settingInactiveButton:e.settingActiveButton:y==="ACTIVE"?e.setInactiveButton:e.setActiveButton}),a(P,{variant:"tertiary",onClick:u,disabled:b,className:"company-management-company-users-management-modal__button-delete",children:b?e.deletingButton:e.deleteButton}),a(P,{variant:"secondary",onClick:B,className:"company-management-company-users-management-modal__button-cancel",children:e.cancelButton})]})]})}):null},me=({className:c,children:i,columns:y=[],rowData:l=[],mobileLayout:S="none",caption:p,expandedRows:b=new Set,loading:I=!1,skeletonRowCount:t=10,onSortChange:g,...f})=>{const m=O({sortedAscending:"Dropin.Table.sortedAscending",sortedDescending:"Dropin.Table.sortedDescending",sortBy:"Dropin.Table.sortBy"}),d=e=>{if(!g)return;let n;e.sortBy===!0?n="asc":e.sortBy==="asc"?n="desc":n=!0,g(e.key,n)},v=e=>{if(e.sortBy===void 0)return null;let n,u;return e.sortBy==="asc"?(n="ChevronUp",u=m.sortedAscending.replace("{label}",e.label)):e.sortBy==="desc"?(n="ChevronDown",u=m.sortedDescending.replace("{label}",e.label)):(n="Sort",u=m.sortBy.replace("{label}",e.label)),a(P,{variant:"tertiary",size:"medium",className:"dropin-table__header__sort-button",icon:a(Z,{source:n}),"aria-label":u,onClick:()=>d(e)})},T=()=>Array.from({length:t},(e,n)=>a("tr",{className:"dropin-table__body__row",children:y.map(u=>a("td",{className:"dropin-table__body__cell","data-label":u.label,children:a(W,{children:a(H,{variant:"row",size:"small",fullWidth:!0})})},u.key))},`skeleton-${n}`)),N=()=>l.map((e,n)=>{const u=e._rowDetails!==void 0,B=b.has(n);return A(Q,{children:[a("tr",{className:"dropin-table__body__row",children:y.map(C=>{const U=e[C.key];return typeof U=="string"||typeof U=="number"?a("td",{className:"dropin-table__body__cell","data-label":C.label,children:U},C.key):a("td",{className:"dropin-table__body__cell","data-label":C.label,children:a(q,{node:U})},C.key)})}),u&&B&&a("tr",{className:"dropin-table__row-details dropin-table__row-details--expanded",id:`row-${n}-details`,children:a("td",{className:"dropin-table__row-details__cell",colSpan:y.length,role:"region","aria-labelledby":`row-${n}-details`,children:typeof e._rowDetails=="string"?e._rowDetails:a(q,{node:e._rowDetails})})},`${n}-details`)]},n)}),w=e=>{if(e.sortBy===!0)return"none";if(e.sortBy==="asc")return"ascending";if(e.sortBy==="desc")return"descending"};return a("div",{className:$(["dropin-table",`dropin-table--mobile-layout-${S}`,c]),children:A("table",{...f,className:"dropin-table__table",children:[p&&a("caption",{className:"dropin-table__caption",children:p}),a("thead",{className:"dropin-table__header",children:a("tr",{className:"dropin-table__header__row",children:y.map(e=>A("th",{className:$(["dropin-table__header__cell",["dropin-table__header__cell--sorted",e.sortBy==="asc"||e.sortBy==="desc"],["dropin-table__header__cell--sortable",e.sortBy!==void 0]]),"aria-sort":w(e),children:[e.label,v(e)]},e.key))})}),a("tbody",{className:"dropin-table__body",children:I?T():N()})]})})},de=[{text:"20",value:"20"},{text:"30",value:"30"},{text:"50",value:"50"},{text:"100",value:"100"},{text:"200",value:"200"}],Se=({children:c,className:i,...y})=>{var o;const[l,S]=E(!1),[p,b]=E(""),I=F(null),t=O({showAllUsers:"Company.CompanyUsers.filters.showAll",showActiveUsers:"Company.CompanyUsers.filters.showActive",showInactiveUsers:"Company.CompanyUsers.filters.showInactive",idColumn:"Company.CompanyUsers.columns.id",nameColumn:"Company.CompanyUsers.columns.name",emailColumn:"Company.CompanyUsers.columns.email",roleColumn:"Company.CompanyUsers.columns.role",teamColumn:"Company.CompanyUsers.columns.team",statusColumn:"Company.CompanyUsers.columns.status",actionsColumn:"Company.CompanyUsers.columns.actions",statusActive:"Company.CompanyUsers.status.active",statusInactive:"Company.CompanyUsers.status.inactive",emptyTeam:"Company.CompanyUsers.emptyTeam",emptyActions:"Company.CompanyUsers.emptyActions",itemsText:"Company.CompanyUsers.pagination.itemsCount",itemsPerPageLabel:"Company.CompanyUsers.pagination.itemsPerPage",showLabel:"Company.CompanyUsers.pagination.show",perPageLabel:"Company.CompanyUsers.pagination.perPage",previousPage:"Company.CompanyUsers.pagination.previous",nextPage:"Company.CompanyUsers.pagination.next",pageInfo:"Company.CompanyUsers.pagination.pageInfo",ariaLoadingUsers:"Company.CompanyUsers.ariaLabels.loadingUsers",ariaUsersTable:"Company.CompanyUsers.ariaLabels.usersTable",ariaFilterOptions:"Company.CompanyUsers.ariaLabels.filterOptions",ariaPaginationNav:"Company.CompanyUsers.ariaLabels.paginationNav",ariaPageSizeSelector:"Company.CompanyUsers.ariaLabels.pageSizeSelector",ariaPreviousPageFull:"Company.CompanyUsers.ariaLabels.previousPageFull",ariaNextPageFull:"Company.CompanyUsers.ariaLabels.nextPageFull",ariaCurrentPage:"Company.CompanyUsers.ariaLabels.currentPage",ariaShowingUsers:"Company.CompanyUsers.ariaLabels.showingUsers",ariaDataLoaded:"Company.CompanyUsers.ariaLabels.dataLoaded",ariaDataError:"Company.CompanyUsers.ariaLabels.dataError",ariaPageNavigation:"Company.CompanyUsers.ariaLabels.pageNavigation",manageUser:"Company.CompanyUsers.actions.manage",ariaManageUser:"Company.CompanyUsers.ariaLabels.manageUser"}),{users:g,loading:f,currentPage:m,pageSize:d,filterType:v,totalItems:T,totalPages:N,announcement:w,canEditUsers:e,handleFilterChange:n,handlePageSizeChange:u,handlePreviousPage:B,handleNextPage:C,refreshUsers:U}=le({translations:{ariaDataLoaded:t.ariaDataLoaded,ariaDataError:t.ariaDataError}}),L=F(t);L.current=t,G(()=>{!f&&I.current&&g.length>0&&I.current.setAttribute("aria-busy","false")},[f,m,v,g.length]);const s=h(()=>{U()},[U]);ne(s);const _=h(r=>{b(r),S(!0)},[]),k=h(()=>{S(!1),b(""),U()},[U]),x=R(()=>{const r=L.current;return[{key:"id",label:r.idColumn},{key:"name",label:r.nameColumn},{key:"email",label:r.emailColumn},{key:"role",label:r.roleColumn},{key:"team",label:r.teamColumn},{key:"status",label:r.statusColumn},{key:"actions",label:r.actionsColumn}]},[]),M=R(()=>g.map(r=>{var j;const D=oe(r.firstName,r.lastName),z=L.current;return{id:r.id,name:D,email:r.email,role:r.role,team:r.team||z.emptyTeam,status:se(r.status,z),actions:e?a(P,{variant:"tertiary",onClick:()=>_(r.id),"aria-label":((j=z.ariaManageUser)==null?void 0:j.replace("{name}",D))||`Manage user ${D}`,className:"manage-user-button",children:z.manageUser||"Manage"}):a("span",{className:"no-actions",children:z.emptyActions})}}),[g,_,e]);return A("section",{className:i,...y,children:[a("div",{className:"sr-only",role:"status","aria-live":"polite","aria-atomic":"true",children:w}),A("div",{className:"filterButtons",role:"group","aria-label":t.ariaFilterOptions,children:[v!=="all"&&a(P,{variant:"tertiary",onClick:()=>n("all"),"aria-label":t.showAllUsers,children:t.showAllUsers}),v!=="active"&&a(P,{variant:"tertiary",onClick:()=>n("active"),"aria-label":t.showActiveUsers,children:t.showActiveUsers}),v!=="inactive"&&a(P,{variant:"tertiary",onClick:()=>n("inactive"),"aria-label":t.showInactiveUsers,children:t.showInactiveUsers})]}),a("div",{ref:I,"aria-busy":f,children:f?A("div",{className:"loadingContainer",role:"status","aria-live":"polite",children:[a(Y,{testId:"companyUsersTableLoader"}),a("span",{className:"sr-only",children:t.ariaLoadingUsers})]}):a(me,{columns:x,rowData:M,mobileLayout:"stacked","aria-label":t.ariaUsersTable,summary:t.ariaShowingUsers.replace("{count}",g.length.toString())})}),A("nav",{"aria-label":t.ariaPaginationNav,className:"paginationContainer",children:[a("div",{"aria-live":"polite","aria-atomic":"true",children:t.itemsText.replace("{count}",T.toString())}),N>1&&A("div",{className:"paginationButtons",role:"group","aria-label":t.ariaPageNavigation,children:[a(P,{variant:"secondary",onClick:B,disabled:m===1,"aria-label":t.ariaPreviousPageFull.replace("{current}",m.toString()),children:t.previousPage}),a("span",{"aria-current":"page","aria-live":"polite",children:t.pageInfo.replace("{current}",m.toString()).replace("{total}",N.toString())}),a(P,{variant:"secondary",onClick:C,disabled:m===N,"aria-label":t.ariaNextPageFull.replace("{current}",m.toString()),children:t.nextPage})]}),A("div",{className:"pageSizeSelector",children:[a("label",{htmlFor:"page-size-select",id:"page-size-label",children:a("span",{children:t.showLabel})}),a(J,{id:"page-size-select",name:"pageSize",value:d.toString(),options:de,onChange:u,"aria-labelledby":"page-size-label","aria-describedby":"page-size-description"}),a("span",{id:"page-size-description",children:t.perPageLabel})]})]}),c,p&&e&&a(ce,{isOpen:l,userId:p,userStatus:((o=g.find(r=>r.id===p))==null?void 0:o.status)||"ACTIVE",onClose:k})]})};export{Se as CompanyUsers,Se as default};
|
|
4
4
|
//# sourceMappingURL=CompanyUsers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyUsers.js","sources":["/@dropins/storefront-company-management/src/lib/userHelpers.ts","/@dropins/storefront-company-management/src/components/CompanyUsersManagementModal/CompanyUsersManagementModal.tsx","../../node_modules/@adobe-commerce/elsie/src/components/Table/Table.tsx","/@dropins/storefront-company-management/src/containers/CompanyUsers/CompanyUsers.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Formats a user status string for display\n * @param status - The raw status string (e.g., 'ACTIVE', 'INACTIVE')\n * @param translations - Translation object containing statusActive and statusInactive keys\n * @returns The formatted status string for display\n */\nexport const formatUserStatus = (status: string, translations: { statusActive?: string; statusInactive?: string }): string => {\n if (!status || typeof status !== 'string') {\n return '';\n }\n\n // Use translations for known statuses\n if (status === 'ACTIVE' && translations.statusActive) {\n return translations.statusActive;\n }\n \n if (status === 'INACTIVE' && translations.statusInactive) {\n return translations.statusInactive;\n }\n\n // Fallback to formatted string if status is unknown or no translation available\n return status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();\n};\n\n/**\n * Formats a user's full name by combining first and last name\n * @param firstName - The user's first name\n * @param lastName - The user's last name\n * @returns The formatted full name, trimmed of extra spaces\n */\nexport const formatUserName = (firstName: string, lastName: string): string => {\n const first = firstName?.trim() || '';\n const last = lastName?.trim() || '';\n \n return `${first} ${last}`.trim();\n};\n\n/**\n * Checks if a user has a specific status\n * @param userStatus - The user's current status\n * @param expectedStatus - The status to check against\n * @returns true if the user has the expected status\n */\nexport const hasUserStatus = (userStatus: string, expectedStatus: string): boolean => {\n return userStatus?.toUpperCase() === expectedStatus?.toUpperCase();\n};\n\n/**\n * Gets the opposite status for toggling (ACTIVE <-> INACTIVE)\n * @param currentStatus - The current user status\n * @returns The opposite status, or the current status if not recognized\n */\nexport const getToggleStatus = (currentStatus: string): string => {\n const status = currentStatus?.toUpperCase();\n \n switch (status) {\n case 'ACTIVE':\n return 'INACTIVE';\n case 'INACTIVE':\n return 'ACTIVE';\n default:\n return currentStatus;\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FunctionComponent } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { useState, useCallback, useEffect, useRef } from 'preact/hooks';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { Button, InLineAlert } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { deleteCompanyUser, updateCompanyUserStatus } from '../../api';\nimport type { CompanyUserStatus } from '../../types';\nimport { useInLineAlert } from '../../hooks/useInLineAlert';\nimport '@/company-management/components/CompanyUsersManagementModal/CompanyUsersManagementModal.css';\n\nexport interface CompanyUsersManagementModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onClose'> {\n /** The ID of the user to manage */\n userId: string;\n /** The current status of the user */\n userStatus: CompanyUserStatus;\n /** Callback function called when the modal should be closed */\n onClose: () => void;\n /** Whether the modal is currently open */\n isOpen?: boolean;\n}\n\nexport const CompanyUsersManagementModal: FunctionComponent<CompanyUsersManagementModalProps> = ({\n className,\n userId,\n userStatus,\n onClose,\n isOpen = false,\n ...props\n}) => {\n const [isDeleting, setIsDeleting] = useState(false);\n const [isTogglingStatus, setIsTogglingStatus] = useState(false);\n const { inLineAlertProps, showError, clearAlert } = useInLineAlert();\n \n // Refs for accessibility\n const modalRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const titleId = `modal-title-${userId}`;\n const descriptionId = `modal-desc-${userId}`;\n\n // Text translations\n const translations = useText({\n title: 'Company.CompanyUsers.managementModal.title',\n setActiveText: 'Company.CompanyUsers.managementModal.setActiveText',\n setInactiveText: 'Company.CompanyUsers.managementModal.setInactiveText',\n deleteText: 'Company.CompanyUsers.managementModal.deleteText',\n setActiveButton: 'Company.CompanyUsers.managementModal.setActiveButton',\n setInactiveButton: 'Company.CompanyUsers.managementModal.setInactiveButton',\n settingActiveButton: 'Company.CompanyUsers.managementModal.settingActiveButton',\n settingInactiveButton: 'Company.CompanyUsers.managementModal.settingInactiveButton',\n deleteButton: 'Company.CompanyUsers.managementModal.deleteButton',\n deletingButton: 'Company.CompanyUsers.managementModal.deletingButton',\n cancelButton: 'Company.CompanyUsers.managementModal.cancelButton',\n setActiveErrorGeneric: 'Company.CompanyUsers.managementModal.setActiveErrorGeneric',\n setActiveErrorSpecific: 'Company.CompanyUsers.managementModal.setActiveErrorSpecific',\n setInactiveErrorGeneric: 'Company.CompanyUsers.managementModal.setInactiveErrorGeneric',\n setInactiveErrorSpecific: 'Company.CompanyUsers.managementModal.setInactiveErrorSpecific',\n deleteErrorGeneric: 'Company.CompanyUsers.managementModal.deleteErrorGeneric',\n deleteErrorSpecific: 'Company.CompanyUsers.managementModal.deleteErrorSpecific',\n ariaCloseModal: 'Company.CompanyUsers.managementModal.ariaLabels.closeModal',\n ariaModalDescription: 'Company.CompanyUsers.managementModal.ariaLabels.modalDescription',\n });\n\n const handleToggleStatus = useCallback(async () => {\n if (isTogglingStatus) return;\n \n const newStatus = userStatus === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE';\n const isActivating = newStatus === 'ACTIVE';\n \n setIsTogglingStatus(true);\n clearAlert();\n try {\n const result = await updateCompanyUserStatus({ id: userId, status: newStatus });\n if (result.success) {\n onClose();\n } else {\n showError(isActivating ? translations.setActiveErrorSpecific : translations.setInactiveErrorSpecific);\n }\n } catch (error) {\n showError(isActivating ? translations.setActiveErrorGeneric : translations.setInactiveErrorGeneric);\n } finally {\n setIsTogglingStatus(false);\n }\n }, [userId, userStatus, onClose, isTogglingStatus, clearAlert, showError, translations.setActiveErrorSpecific, translations.setInactiveErrorSpecific, translations.setActiveErrorGeneric, translations.setInactiveErrorGeneric]);\n\n const handleDelete = useCallback(async () => {\n if (isDeleting) return;\n \n setIsDeleting(true);\n clearAlert();\n try {\n const result = await deleteCompanyUser({ id: userId });\n if (result.success) {\n onClose();\n } else {\n showError(translations.deleteErrorSpecific);\n }\n } catch (error) {\n showError(translations.deleteErrorGeneric);\n } finally {\n setIsDeleting(false);\n }\n }, [userId, onClose, isDeleting, clearAlert, showError, translations.deleteErrorSpecific, translations.deleteErrorGeneric]);\n\n const handleCancel = useCallback(() => {\n clearAlert();\n onClose();\n }, [onClose, clearAlert]);\n\n // Handle Escape key\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n clearAlert();\n onClose();\n }\n \n // Focus trapping\n if (event.key === 'Tab') {\n const modal = modalRef.current;\n if (!modal) return;\n \n const focusableElements = modal.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n \n if (event.shiftKey) {\n // Shift + Tab\n if (document.activeElement === firstElement) {\n lastElement.focus();\n event.preventDefault();\n }\n } else if (document.activeElement === lastElement) {\n // Tab\n firstElement.focus();\n event.preventDefault();\n }\n }\n }, [onClose, clearAlert]);\n\n const handleOverlayClick = useCallback((event: MouseEvent) => {\n if (event.target === event.currentTarget) {\n clearAlert();\n onClose();\n }\n }, [onClose, clearAlert]);\n\n const handleCloseClick = useCallback(() => {\n clearAlert();\n onClose();\n }, [onClose, clearAlert]);\n\n // Focus management and event listeners\n useEffect(() => {\n if (isOpen) {\n // Store current focus\n previousFocusRef.current = document.activeElement as HTMLElement;\n \n // Add keyboard event listener\n document.addEventListener('keydown', handleKeyDown);\n \n // Focus the modal after a brief delay to ensure it's rendered\n setTimeout(() => {\n const modal = modalRef.current;\n if (modal) {\n const firstButton = modal.querySelector('button') as HTMLElement;\n if (firstButton) {\n firstButton.focus();\n } else {\n modal.focus();\n }\n }\n }, 100);\n \n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }\n \n // Restore focus when modal closes\n if (previousFocusRef.current) {\n previousFocusRef.current.focus();\n }\n }, [isOpen, handleKeyDown]);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div \n className={classes(['company-management-company-users-management-modal-overlay', className])}\n onClick={handleOverlayClick}\n {...props}\n >\n <div \n ref={modalRef}\n className=\"company-management-company-users-management-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n tabIndex={-1}\n >\n <div className=\"company-management-company-users-management-modal__header\">\n <h2 \n id={titleId}\n className=\"company-management-company-users-management-modal__title\"\n >\n {translations.title}\n </h2>\n <button\n className=\"company-management-company-users-management-modal__close\"\n onClick={handleCloseClick}\n aria-label={translations.ariaCloseModal}\n >\n ×\n </button>\n </div>\n \n <div \n id={descriptionId}\n className=\"company-management-company-users-management-modal__content\"\n >\n <p className=\"company-management-company-users-management-modal__text\">\n {userStatus === 'ACTIVE' ? translations.setInactiveText : translations.setActiveText}\n </p>\n <p className=\"company-management-company-users-management-modal__text\">\n {translations.deleteText}\n </p>\n </div>\n\n {inLineAlertProps?.text && (\n <div \n className=\"company-management-company-users-management-modal__alert\"\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <InLineAlert\n type=\"error\"\n heading={inLineAlertProps.text}\n icon={inLineAlertProps.icon}\n data-testid=\"companyUsersManagementModalAlert\"\n />\n </div>\n )}\n\n <div className=\"company-management-company-users-management-modal__actions\">\n <Button\n variant=\"primary\"\n onClick={handleToggleStatus}\n disabled={isTogglingStatus}\n className=\"company-management-company-users-management-modal__button-primary\"\n >\n {isTogglingStatus \n ? (userStatus === 'ACTIVE' ? translations.settingInactiveButton : translations.settingActiveButton)\n : (userStatus === 'ACTIVE' ? translations.setInactiveButton : translations.setActiveButton)\n }\n </Button>\n \n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"company-management-company-users-management-modal__button-delete\"\n >\n {isDeleting ? translations.deletingButton : translations.deleteButton}\n </button>\n \n <Button\n variant=\"secondary\"\n onClick={handleCancel}\n className=\"company-management-company-users-management-modal__button-cancel\"\n >\n {translations.cancelButton}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { FunctionComponent, VNode, Fragment } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport { Icon, Button, Skeleton, SkeletonRow } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport '@adobe-commerce/elsie/components/Table/Table.css';\n\ntype Sortable = 'asc' | 'desc' | true;\n\ntype Column = {\n key: string;\n label: string;\n sortBy?: Sortable;\n};\n\ntype RowData = {\n [key: string]: VNode | string | number | undefined;\n _rowDetails?: VNode | string; // Special property for expandable row content\n};\n\nexport interface TableProps extends Omit<HTMLAttributes<HTMLTableElement>, 'loading'> {\n columns: Column[];\n rowData: RowData[];\n mobileLayout?: 'stacked' | 'none';\n caption?: string;\n expandedRows?: Set<number>;\n loading?: boolean;\n skeletonRowCount?: number;\n onSortChange?: (columnKey: string, direction: Sortable) => void;\n}\n\nexport const Table: FunctionComponent<TableProps> = ({\n className,\n children,\n columns = [],\n rowData = [],\n mobileLayout = 'none',\n caption,\n expandedRows = new Set(),\n loading = false,\n skeletonRowCount = 10,\n onSortChange,\n ...props\n}) => {\n const translations = useText({\n sortedAscending: 'Dropin.Table.sortedAscending',\n sortedDescending: 'Dropin.Table.sortedDescending',\n sortBy: 'Dropin.Table.sortBy',\n });\n\n const handleSort = (column: Column) => {\n if (!onSortChange) return;\n\n // Determine next sort direction\n let nextDirection: Sortable;\n if (column.sortBy === true) {\n nextDirection = 'asc';\n } else if (column.sortBy === 'asc') {\n nextDirection = 'desc';\n } else {\n nextDirection = true;\n }\n\n onSortChange(column.key, nextDirection);\n };\n\n const renderSortButton = (column: Column) => {\n if (column.sortBy === undefined) return null;\n\n let iconSource: string;\n let ariaLabel: string;\n\n if (column.sortBy === 'asc') {\n iconSource = 'ChevronUp';\n ariaLabel = translations.sortedAscending.replace('{label}', column.label);\n } else if (column.sortBy === 'desc') {\n iconSource = 'ChevronDown';\n ariaLabel = translations.sortedDescending.replace('{label}', column.label);\n } else {\n iconSource = 'Sort';\n ariaLabel = translations.sortBy.replace('{label}', column.label);\n }\n\n return (\n <Button\n variant=\"tertiary\"\n size=\"medium\"\n className=\"dropin-table__header__sort-button\"\n icon={<Icon source={iconSource} />}\n aria-label={ariaLabel}\n onClick={() => handleSort(column)}\n />\n );\n };\n\n const renderSkeletonRows = () => {\n return Array.from({ length: skeletonRowCount }, (_, rowIndex) => (\n <tr key={`skeleton-${rowIndex}`} className=\"dropin-table__body__row\">\n {columns.map((column) => (\n <td key={column.key} className=\"dropin-table__body__cell\" data-label={column.label}>\n <Skeleton>\n <SkeletonRow variant=\"row\" size=\"small\" fullWidth />\n </Skeleton>\n </td>\n ))}\n </tr>\n ));\n };\n\n const renderDataRows = () => {\n return rowData.map((row, rowIndex) => {\n const hasDetails = row._rowDetails !== undefined;\n const isExpanded = expandedRows.has(rowIndex);\n\n return (\n <Fragment key={rowIndex}>\n <tr className=\"dropin-table__body__row\">\n {columns.map((column) => {\n const cell = row[column.key];\n\n if (typeof cell === 'string' || typeof cell === 'number') {\n return (\n <td key={column.key} className=\"dropin-table__body__cell\" data-label={column.label}>\n {cell}\n </td>\n );\n }\n\n return (\n <td key={column.key} className=\"dropin-table__body__cell\" data-label={column.label}>\n <VComponent node={cell!} />\n </td>\n );\n })}\n </tr>\n {hasDetails && isExpanded && (\n <tr\n key={`${rowIndex}-details`}\n className=\"dropin-table__row-details dropin-table__row-details--expanded\"\n id={`row-${rowIndex}-details`}\n >\n <td\n className=\"dropin-table__row-details__cell\"\n colSpan={columns.length}\n role=\"region\"\n aria-labelledby={`row-${rowIndex}-details`}\n >\n {typeof row._rowDetails === 'string' ? row._rowDetails : <VComponent node={row._rowDetails!} />}\n </td>\n </tr>\n )}\n </Fragment>\n );\n });\n };\n\n const getAriaSort = (column: Column): 'none' | 'ascending' | 'descending' | 'other' | undefined => {\n if (column.sortBy === true) return 'none';\n if (column.sortBy === 'asc') return 'ascending';\n if (column.sortBy === 'desc') return 'descending';\n return undefined;\n };\n\n return (\n <div className={classes(['dropin-table', `dropin-table--mobile-layout-${mobileLayout}`, className])}>\n <table {...props} className=\"dropin-table__table\">\n {caption && <caption className=\"dropin-table__caption\">{caption}</caption>}\n <thead className=\"dropin-table__header\">\n <tr className=\"dropin-table__header__row\">\n {columns.map((column) => (\n <th\n key={column.key}\n className={classes([\n 'dropin-table__header__cell',\n ['dropin-table__header__cell--sorted', column.sortBy === 'asc' || column.sortBy === 'desc'],\n ['dropin-table__header__cell--sortable', column.sortBy !== undefined]\n ])}\n aria-sort={getAriaSort(column)}\n >\n {column.label}\n {renderSortButton(column)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"dropin-table__body\">\n {loading ? (\n // Render skeleton rows when loading\n renderSkeletonRows()\n ) : (\n // Render actual data when not loading\n renderDataRows()\n )}\n </tbody>\n </table>\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { HTMLAttributes } from 'preact/compat';\nimport { useEffect, useState, useCallback, useRef, useMemo } from 'preact/hooks';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { \n Button, \n Picker \n} from '@adobe-commerce/elsie/components';\nimport { Table } from '@adobe-commerce/elsie/components/Table/Table';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { getCompanyUsers, fetchUserPermissions } from '../../api';\nimport { formatUserStatus, formatUserName } from '../../lib';\nimport { \n CompanyUser, \n CompanyUsersFilter, \n CompanyUserStatus \n} from '../../types';\nimport { CompanyUsersManagementModal } from '../../components/CompanyUsersManagementModal';\nimport { CompanyUsersTableLoader } from '../../components/CompanyLoaders';\nimport { useCompanyContextListener } from './hooks';\nimport './CompanyUsers.css';\n\nexport interface CompanyUsersProps extends HTMLAttributes<HTMLElement> {}\n\ntype FilterType = 'all' | 'active' | 'inactive';\n\n// Constants\nconst DEFAULT_PAGE_SIZE = 20;\nconst FIRST_PAGE = 1;\nconst PAGE_SIZE_OPTIONS = [\n { text: '20', value: '20' },\n { text: '30', value: '30' },\n { text: '50', value: '50' },\n { text: '100', value: '100' },\n { text: '200', value: '200' }\n];\n\n\nexport const CompanyUsers: Container<CompanyUsersProps> = ({ children, className, ...props }) => {\n const [users, setUsers] = useState<CompanyUser[]>([]);\n const [loading, setLoading] = useState(false);\n const [currentPage, setCurrentPage] = useState(FIRST_PAGE);\n const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);\n const [filterType, setFilterType] = useState<FilterType>('all');\n const [totalItems, setTotalItems] = useState(0);\n const [totalPages, setTotalPages] = useState(1);\n const [announcement, setAnnouncement] = useState('');\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [selectedUserId, setSelectedUserId] = useState('');\n const [userPermissions, setUserPermissions] = useState<Set<string> | null>(null);\n const tableRef = useRef<HTMLDivElement>(null);\n\n // Text translations using proper useText pattern\n const translations = useText({\n showAllUsers: 'Company.CompanyUsers.filters.showAll',\n showActiveUsers: 'Company.CompanyUsers.filters.showActive',\n showInactiveUsers: 'Company.CompanyUsers.filters.showInactive',\n idColumn: 'Company.CompanyUsers.columns.id',\n nameColumn: 'Company.CompanyUsers.columns.name',\n emailColumn: 'Company.CompanyUsers.columns.email',\n roleColumn: 'Company.CompanyUsers.columns.role',\n teamColumn: 'Company.CompanyUsers.columns.team',\n statusColumn: 'Company.CompanyUsers.columns.status',\n actionsColumn: 'Company.CompanyUsers.columns.actions',\n statusActive: 'Company.CompanyUsers.status.active',\n statusInactive: 'Company.CompanyUsers.status.inactive',\n emptyTeam: 'Company.CompanyUsers.emptyTeam',\n emptyActions: 'Company.CompanyUsers.emptyActions',\n itemsText: 'Company.CompanyUsers.pagination.itemsCount',\n itemsPerPageLabel: 'Company.CompanyUsers.pagination.itemsPerPage',\n showLabel: 'Company.CompanyUsers.pagination.show',\n perPageLabel: 'Company.CompanyUsers.pagination.perPage',\n previousPage: 'Company.CompanyUsers.pagination.previous',\n nextPage: 'Company.CompanyUsers.pagination.next',\n pageInfo: 'Company.CompanyUsers.pagination.pageInfo',\n // Accessibility labels\n ariaLoadingUsers: 'Company.CompanyUsers.ariaLabels.loadingUsers',\n ariaUsersTable: 'Company.CompanyUsers.ariaLabels.usersTable',\n ariaFilterOptions: 'Company.CompanyUsers.ariaLabels.filterOptions',\n ariaPaginationNav: 'Company.CompanyUsers.ariaLabels.paginationNav',\n ariaPageSizeSelector: 'Company.CompanyUsers.ariaLabels.pageSizeSelector',\n ariaPreviousPageFull: 'Company.CompanyUsers.ariaLabels.previousPageFull',\n ariaNextPageFull: 'Company.CompanyUsers.ariaLabels.nextPageFull',\n ariaCurrentPage: 'Company.CompanyUsers.ariaLabels.currentPage',\n ariaShowingUsers: 'Company.CompanyUsers.ariaLabels.showingUsers',\n ariaDataLoaded: 'Company.CompanyUsers.ariaLabels.dataLoaded',\n ariaDataError: 'Company.CompanyUsers.ariaLabels.dataError',\n ariaPageNavigation: 'Company.CompanyUsers.ariaLabels.pageNavigation',\n manageUser: 'Company.CompanyUsers.actions.manage',\n ariaManageUser: 'Company.CompanyUsers.ariaLabels.manageUser'\n });\n\n // Stable reference to translations to prevent unnecessary re-renders\n const translationsRef = useRef(translations);\n translationsRef.current = translations;\n\n // Stable reference to fetchUsers for event handling optimization (will be set after fetchUsers is defined)\n const fetchUsersRef = useRef<(() => Promise<void>) | null>(null);\n\n // Memoized filter based on current filter type (performance optimization)\n const filter = useMemo((): CompanyUsersFilter | undefined => {\n switch (filterType) {\n case 'active':\n return { status: 'ACTIVE' as CompanyUserStatus };\n case 'inactive':\n return { status: 'INACTIVE' as CompanyUserStatus };\n default:\n return undefined;\n }\n }, [filterType]);\n\n // Fetch users data\n const fetchUsers = useCallback(async () => {\n setLoading(true);\n try {\n const response = await getCompanyUsers({\n pageSize,\n currentPage,\n filter\n });\n \n // Batch state updates for better performance\n setUsers(response.users);\n setTotalItems(response.totalCount || response.users.length);\n setAnnouncement(translationsRef.current.ariaDataLoaded.replace('{count}', response.users.length.toString()));\n \n // Use totalPages from API if available, otherwise calculate from users array\n if (response.pageInfo?.totalPages) {\n setTotalPages(response.pageInfo.totalPages);\n } else {\n // Fallback calculation if API doesn't provide totalPages\n const calculatedTotalPages = Math.ceil((response.totalCount || response.users.length) / pageSize);\n setTotalPages(calculatedTotalPages || 1);\n }\n } catch (error) {\n console.error('Failed to fetch company users:', error);\n // Batch error state updates\n setUsers([]);\n setTotalItems(0);\n setTotalPages(1);\n setAnnouncement(translationsRef.current.ariaDataError);\n } finally {\n setLoading(false);\n }\n }, [pageSize, currentPage, filter]);\n\n // Assign stable reference after fetchUsers is defined\n fetchUsersRef.current = fetchUsers;\n\n // Fetch user permissions\n const fetchPermissions = useCallback(async () => {\n try {\n const { allowedIds } = await fetchUserPermissions();\n setUserPermissions(allowedIds);\n } catch (error) {\n console.error('Failed to fetch user permissions:', error);\n setUserPermissions(new Set()); // Empty set on error\n }\n }, []);\n\n // Fetch users when dependencies change\n useEffect(() => {\n fetchUsers();\n }, [fetchUsers]);\n\n // Fetch permissions on component mount\n useEffect(() => {\n fetchPermissions();\n }, [fetchPermissions]);\n\n // Focus management after data updates\n useEffect(() => {\n if (!loading && tableRef.current && users.length > 0) {\n // Announce change to screen readers but don't steal focus\n tableRef.current.setAttribute('aria-busy', 'false');\n }\n }, [loading, currentPage, filterType, users.length]);\n\n // Handle company context changes using reusable hook\n const handleCompanyContextChange = useCallback(() => {\n // Reset to first page but keep filter settings\n setCurrentPage(FIRST_PAGE);\n fetchUsersRef.current?.();\n }, []);\n\n useCompanyContextListener(handleCompanyContextChange);\n\n // Handle filter changes\n const handleFilterChange = useCallback((newFilter: FilterType) => {\n setFilterType(newFilter);\n setCurrentPage(FIRST_PAGE); // Reset to first page when filter changes\n }, []);\n\n // Handle page size change\n const handlePageSizeChange = useCallback((event: Event | { target?: { value: string } } | string) => {\n let value: string;\n if (typeof event === 'string') {\n value = event;\n } else if ('target' in event && event.target && 'value' in event.target) {\n value = event.target.value;\n } else {\n return;\n }\n const newSize = parseInt(value, 10);\n if (!isNaN(newSize)) {\n setPageSize(newSize);\n setCurrentPage(FIRST_PAGE); // Reset to first page when page size changes\n }\n }, []);\n\n // Handle page navigation\n const handlePreviousPage = useCallback(() => {\n if (currentPage > 1) {\n setCurrentPage(currentPage - 1);\n }\n }, [currentPage]);\n\n const handleNextPage = useCallback(() => {\n if (currentPage < totalPages) {\n setCurrentPage(currentPage + 1);\n }\n }, [currentPage, totalPages]);\n\n // Handle modal operations\n const handleOpenModal = useCallback((userId: string) => {\n setSelectedUserId(userId);\n setIsModalOpen(true);\n }, []);\n\n const handleCloseModal = useCallback(() => {\n setIsModalOpen(false);\n setSelectedUserId('');\n // Refresh the user list after modal closes (in case user was deleted)\n fetchUsersRef.current?.();\n }, []);\n\n // Prepare table columns - memoized to prevent unnecessary re-renders (optimized)\n const columns = useMemo(() => {\n const currentTranslations = translationsRef.current;\n return [\n { key: 'id', label: currentTranslations.idColumn },\n { key: 'name', label: currentTranslations.nameColumn },\n { key: 'email', label: currentTranslations.emailColumn },\n { key: 'role', label: currentTranslations.roleColumn },\n { key: 'team', label: currentTranslations.teamColumn },\n { key: 'status', label: currentTranslations.statusColumn },\n { key: 'actions', label: currentTranslations.actionsColumn }\n ];\n }, []); // No dependencies - only recompute when component mounts\n\n\n // Check if user has permission to edit company users\n const canEditUsers = userPermissions?.has('Magento_Company::users_edit') || false;\n\n // Prepare table row data - memoized for performance (optimized)\n const rowData = useMemo(() => users.map((user) => {\n const fullName = formatUserName(user.firstName, user.lastName);\n const currentTranslations = translationsRef.current;\n \n return {\n id: user.id,\n name: fullName,\n email: user.email,\n role: user.role,\n team: user.team || currentTranslations.emptyTeam,\n status: formatUserStatus(user.status, currentTranslations),\n actions: canEditUsers ? (\n <Button\n variant=\"tertiary\"\n onClick={() => handleOpenModal(user.id)}\n aria-label={currentTranslations.ariaManageUser?.replace('{name}', fullName) || `Manage user ${fullName}`}\n className=\"manage-user-button\"\n >\n {currentTranslations.manageUser || 'Manage'}\n </Button>\n ) : (\n <span className=\"no-actions\">{currentTranslations.emptyActions}</span>\n )\n };\n }), [users, handleOpenModal, canEditUsers]);\n\n\n return (\n <section className={className} {...props}>\n {/* Screen reader announcements */}\n <div className=\"sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcement}\n </div>\n\n {/* Filter buttons */}\n <div className=\"filterButtons\" role=\"group\" aria-label={translations.ariaFilterOptions}>\n {filterType !== 'all' && (\n <Button\n variant=\"tertiary\"\n onClick={() => handleFilterChange('all')}\n aria-label={translations.showAllUsers}\n >\n {translations.showAllUsers}\n </Button>\n )}\n {filterType !== 'active' && (\n <Button\n variant=\"tertiary\"\n onClick={() => handleFilterChange('active')}\n aria-label={translations.showActiveUsers}\n >\n {translations.showActiveUsers}\n </Button>\n )}\n {filterType !== 'inactive' && (\n <Button\n variant=\"tertiary\"\n onClick={() => handleFilterChange('inactive')}\n aria-label={translations.showInactiveUsers}\n >\n {translations.showInactiveUsers}\n </Button>\n )}\n </div>\n\n {/* Table with loading state */}\n <div ref={tableRef} aria-busy={loading}>\n {loading ? (\n <div className=\"loadingContainer\" role=\"status\" aria-live=\"polite\">\n <CompanyUsersTableLoader testId=\"companyUsersTableLoader\" />\n <span className=\"sr-only\">{translations.ariaLoadingUsers}</span>\n </div>\n ) : (\n <Table\n columns={columns}\n rowData={rowData}\n mobileLayout=\"stacked\"\n aria-label={translations.ariaUsersTable}\n summary={translations.ariaShowingUsers.replace('{count}', users.length.toString())}\n />\n )}\n </div>\n\n {/* Pagination controls */}\n <nav aria-label={translations.ariaPaginationNav} className=\"paginationContainer\">\n {/* Items count on the left */}\n <div aria-live=\"polite\" aria-atomic=\"true\">\n {translations.itemsText.replace('{count}', totalItems.toString())}\n </div>\n\n {/* Pagination buttons in the center (only show when multiple pages) */}\n {totalPages > 1 && (\n <div className=\"paginationButtons\" role=\"group\" aria-label={translations.ariaPageNavigation}>\n <Button\n variant=\"secondary\"\n onClick={handlePreviousPage}\n disabled={currentPage === 1}\n aria-label={translations.ariaPreviousPageFull.replace('{current}', currentPage.toString())}\n >\n {translations.previousPage}\n </Button>\n <span aria-current=\"page\" aria-live=\"polite\">\n {translations.pageInfo.replace('{current}', currentPage.toString()).replace('{total}', totalPages.toString())}\n </span>\n <Button\n variant=\"secondary\"\n onClick={handleNextPage}\n disabled={currentPage === totalPages}\n aria-label={translations.ariaNextPageFull.replace('{current}', currentPage.toString())}\n >\n {translations.nextPage}\n </Button>\n </div>\n )}\n\n {/* Page size picker on the right */}\n <div className=\"pageSizeSelector\">\n <label htmlFor=\"page-size-select\" id=\"page-size-label\">\n <span>{translations.showLabel}</span>\n </label>\n <Picker\n id=\"page-size-select\"\n name=\"pageSize\"\n value={pageSize.toString()}\n options={PAGE_SIZE_OPTIONS}\n onChange={handlePageSizeChange}\n aria-labelledby=\"page-size-label\"\n aria-describedby=\"page-size-description\"\n />\n <span id=\"page-size-description\">{translations.perPageLabel}</span>\n </div>\n </nav>\n\n {children}\n\n {/* User Management Modal */}\n {selectedUserId && canEditUsers && (\n <CompanyUsersManagementModal\n isOpen={isModalOpen}\n userId={selectedUserId}\n userStatus={(users.find(user => user.id === selectedUserId)?.status as CompanyUserStatus) || 'ACTIVE'}\n onClose={handleCloseModal}\n />\n )}\n </section>\n );\n};\n"],"names":["formatUserStatus","status","translations","formatUserName","firstName","lastName","first","last","CompanyUsersManagementModal","className","userId","userStatus","onClose","isOpen","props","isDeleting","setIsDeleting","useState","isTogglingStatus","setIsTogglingStatus","inLineAlertProps","showError","clearAlert","useInLineAlert","modalRef","useRef","previousFocusRef","titleId","descriptionId","useText","handleToggleStatus","useCallback","newStatus","isActivating","updateCompanyUserStatus","handleDelete","deleteCompanyUser","handleCancel","handleKeyDown","event","modal","focusableElements","firstElement","lastElement","handleOverlayClick","handleCloseClick","useEffect","firstButton","jsx","classes","jsxs","InLineAlert","Button","Table","children","columns","rowData","mobileLayout","caption","expandedRows","loading","skeletonRowCount","onSortChange","handleSort","column","nextDirection","renderSortButton","iconSource","ariaLabel","Icon","renderSkeletonRows","_","rowIndex","Skeleton","SkeletonRow","renderDataRows","row","hasDetails","isExpanded","Fragment","cell","VComponent","getAriaSort","DEFAULT_PAGE_SIZE","FIRST_PAGE","PAGE_SIZE_OPTIONS","CompanyUsers","users","setUsers","setLoading","currentPage","setCurrentPage","pageSize","setPageSize","filterType","setFilterType","totalItems","setTotalItems","totalPages","setTotalPages","announcement","setAnnouncement","isModalOpen","setIsModalOpen","selectedUserId","setSelectedUserId","userPermissions","setUserPermissions","tableRef","translationsRef","fetchUsersRef","filter","useMemo","fetchUsers","response","getCompanyUsers","_a","calculatedTotalPages","error","fetchPermissions","allowedIds","fetchUserPermissions","handleCompanyContextChange","useCompanyContextListener","handleFilterChange","newFilter","handlePageSizeChange","value","newSize","handlePreviousPage","handleNextPage","handleOpenModal","handleCloseModal","currentTranslations","canEditUsers","user","fullName","CompanyUsersTableLoader","Picker"],"mappings":"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","x_google_ignoreList":[2]}
|
|
1
|
+
{"version":3,"file":"CompanyUsers.js","sources":["/@dropins/storefront-company-management/src/lib/userHelpers.ts","/@dropins/storefront-company-management/src/hooks/containers/useCompanyUsers.tsx","/@dropins/storefront-company-management/src/components/CompanyUsersManagementModal/CompanyUsersManagementModal.tsx","../../node_modules/@adobe-commerce/elsie/src/components/Table/Table.tsx","/@dropins/storefront-company-management/src/containers/CompanyUsers/CompanyUsers.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Formats a user status string for display\n * @param status - The raw status string (e.g., 'ACTIVE', 'INACTIVE')\n * @param translations - Translation object containing statusActive and statusInactive keys\n * @returns The formatted status string for display\n */\nexport const formatUserStatus = (status: string, translations: { statusActive?: string; statusInactive?: string }): string => {\n if (!status || typeof status !== 'string') {\n return '';\n }\n\n // Use translations for known statuses\n if (status === 'ACTIVE' && translations.statusActive) {\n return translations.statusActive;\n }\n \n if (status === 'INACTIVE' && translations.statusInactive) {\n return translations.statusInactive;\n }\n\n // Fallback to formatted string if status is unknown or no translation available\n return status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();\n};\n\n/**\n * Formats a user's full name by combining first and last name\n * @param firstName - The user's first name\n * @param lastName - The user's last name\n * @returns The formatted full name, trimmed of extra spaces\n */\nexport const formatUserName = (firstName: string, lastName: string): string => {\n const first = firstName?.trim() || '';\n const last = lastName?.trim() || '';\n \n return `${first} ${last}`.trim();\n};\n\n/**\n * Checks if a user has a specific status\n * @param userStatus - The user's current status\n * @param expectedStatus - The status to check against\n * @returns true if the user has the expected status\n */\nexport const hasUserStatus = (userStatus: string, expectedStatus: string): boolean => {\n return userStatus?.toUpperCase() === expectedStatus?.toUpperCase();\n};\n\n/**\n * Gets the opposite status for toggling (ACTIVE <-> INACTIVE)\n * @param currentStatus - The current user status\n * @returns The opposite status, or the current status if not recognized\n */\nexport const getToggleStatus = (currentStatus: string): string => {\n const status = currentStatus?.toUpperCase();\n \n switch (status) {\n case 'ACTIVE':\n return 'INACTIVE';\n case 'INACTIVE':\n return 'ACTIVE';\n default:\n return currentStatus;\n }\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { useEffect, useState, useCallback, useRef, useMemo } from 'preact/hooks';\nimport { getCompanyUsers, fetchUserPermissions } from '@/company-management/api';\nimport { \n CompanyUser, \n CompanyUsersFilter, \n CompanyUserStatus \n} from '@/company-management/types';\n\nexport type FilterType = 'all' | 'active' | 'inactive';\n\n// Constants\nconst DEFAULT_PAGE_SIZE = 20;\nconst FIRST_PAGE = 1;\n\nexport interface UseCompanyUsersProps {\n translations: {\n ariaDataLoaded: string;\n ariaDataError: string;\n };\n}\n\nexport interface UseCompanyUsersReturn {\n // Core data\n users: CompanyUser[];\n userPermissions: Set<string> | null;\n \n // Pagination state\n currentPage: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n \n // Filter state\n filterType: FilterType;\n filter: CompanyUsersFilter | undefined;\n \n // Loading states\n loading: boolean;\n \n // UI state\n announcement: string;\n \n // Computed values\n canEditUsers: boolean;\n \n // Actions\n handleFilterChange: (newFilter: FilterType) => void;\n handlePageSizeChange: (event: Event | { target?: { value: string } } | string) => void;\n handlePreviousPage: () => void;\n handleNextPage: () => void;\n refreshUsers: () => Promise<void>;\n}\n\nexport const useCompanyUsers = ({ translations }: UseCompanyUsersProps): UseCompanyUsersReturn => {\n const [users, setUsers] = useState<CompanyUser[]>([]);\n const [loading, setLoading] = useState(false);\n const [currentPage, setCurrentPage] = useState(FIRST_PAGE);\n const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);\n const [filterType, setFilterType] = useState<FilterType>('all');\n const [totalItems, setTotalItems] = useState(0);\n const [totalPages, setTotalPages] = useState(1);\n const [announcement, setAnnouncement] = useState('');\n const [userPermissions, setUserPermissions] = useState<Set<string> | null>(null);\n\n // Stable reference to translations to prevent unnecessary re-renders\n const translationsRef = useRef(translations);\n translationsRef.current = translations;\n\n // Memoized filter based on current filter type\n const filter = useMemo((): CompanyUsersFilter | undefined => {\n switch (filterType) {\n case 'active':\n return { status: 'ACTIVE' as CompanyUserStatus };\n case 'inactive':\n return { status: 'INACTIVE' as CompanyUserStatus };\n default:\n return undefined;\n }\n }, [filterType]);\n\n // Fetch users data\n const fetchUsers = useCallback(async () => {\n setLoading(true);\n try {\n const response = await getCompanyUsers({\n pageSize,\n currentPage,\n filter\n });\n \n // Batch state updates for better performance\n setUsers(response.users);\n setTotalItems(response.totalCount || response.users.length);\n setTotalPages(response.pageInfo.totalPages);\n setAnnouncement(translationsRef.current.ariaDataLoaded.replace('{count}', response.users.length.toString()));\n } catch (error) {\n // Batch error state updates\n setUsers([]);\n setTotalItems(0);\n setTotalPages(1);\n setAnnouncement(translationsRef.current.ariaDataError);\n } finally {\n setLoading(false);\n }\n }, [pageSize, currentPage, filter]);\n\n // Fetch user permissions\n const fetchPermissions = useCallback(async () => {\n try {\n const { allowedIds } = await fetchUserPermissions();\n setUserPermissions(allowedIds);\n } catch (error) {\n setUserPermissions(new Set()); // Empty set on error\n }\n }, []);\n\n // Fetch users when dependencies change\n useEffect(() => {\n fetchUsers();\n }, [fetchUsers]);\n\n // Fetch permissions on component mount\n useEffect(() => {\n fetchPermissions();\n }, [fetchPermissions]);\n\n // Handle filter changes\n const handleFilterChange = useCallback((newFilter: FilterType) => {\n setFilterType(newFilter);\n setCurrentPage(FIRST_PAGE); // Reset to first page when filter changes\n }, []);\n\n // Handle page size change\n const handlePageSizeChange = useCallback((event: Event | { target?: { value: string } } | string) => {\n let value: string;\n if (typeof event === 'string') {\n value = event;\n } else if ('target' in event && event.target && 'value' in event.target) {\n value = event.target.value;\n } else {\n return;\n }\n const newSize = parseInt(value, 10);\n if (!isNaN(newSize)) {\n setPageSize(newSize);\n setCurrentPage(FIRST_PAGE); // Reset to first page when page size changes\n }\n }, []);\n\n // Handle page navigation\n const handlePreviousPage = useCallback(() => {\n if (currentPage > 1) {\n setCurrentPage(currentPage - 1);\n }\n }, [currentPage]);\n\n const handleNextPage = useCallback(() => {\n if (currentPage < totalPages) {\n setCurrentPage(currentPage + 1);\n }\n }, [currentPage, totalPages]);\n\n // Check if user has permission to edit company users\n const canEditUsers = userPermissions?.has('Magento_Company::users_edit') || false;\n\n // Expose refresh function for external use (e.g., after modal operations)\n const refreshUsers = useCallback(async () => {\n await fetchUsers();\n }, [fetchUsers]);\n\n return {\n // Core data\n users,\n userPermissions,\n \n // Pagination state\n currentPage,\n pageSize,\n totalItems,\n totalPages,\n \n // Filter state\n filterType,\n filter,\n \n // Loading states\n loading,\n \n // UI state\n announcement,\n \n // Computed values\n canEditUsers,\n \n // Actions\n handleFilterChange,\n handlePageSizeChange,\n handlePreviousPage,\n handleNextPage,\n refreshUsers,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FunctionComponent } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { useState, useCallback, useEffect, useRef } from 'preact/hooks';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { Button, InLineAlert } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { deleteCompanyUser, updateCompanyUserStatus } from '@/company-management/api';\nimport type { CompanyUserStatus } from '@/company-management/types';\nimport { useInLineAlert } from '@/company-management/hooks';\nimport '@/company-management/components/CompanyUsersManagementModal/CompanyUsersManagementModal.css';\n\nexport interface CompanyUsersManagementModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onClose'> {\n /** The ID of the user to manage */\n userId: string;\n /** The current status of the user */\n userStatus: CompanyUserStatus;\n /** Callback function called when the modal should be closed */\n onClose: () => void;\n /** Whether the modal is currently open */\n isOpen?: boolean;\n}\n\nexport const CompanyUsersManagementModal: FunctionComponent<CompanyUsersManagementModalProps> = ({\n className,\n userId,\n userStatus,\n onClose,\n isOpen = false,\n ...props\n}) => {\n const [isDeleting, setIsDeleting] = useState(false);\n const [isTogglingStatus, setIsTogglingStatus] = useState(false);\n const { inLineAlertProps, showError, clearAlert } = useInLineAlert();\n \n // Refs for accessibility\n const modalRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const titleId = `modal-title-${userId}`;\n const descriptionId = `modal-desc-${userId}`;\n\n // Text translations\n const translations = useText({\n title: 'Company.CompanyUsers.managementModal.title',\n setActiveText: 'Company.CompanyUsers.managementModal.setActiveText',\n setInactiveText: 'Company.CompanyUsers.managementModal.setInactiveText',\n deleteText: 'Company.CompanyUsers.managementModal.deleteText',\n setActiveButton: 'Company.CompanyUsers.managementModal.setActiveButton',\n setInactiveButton: 'Company.CompanyUsers.managementModal.setInactiveButton',\n settingActiveButton: 'Company.CompanyUsers.managementModal.settingActiveButton',\n settingInactiveButton: 'Company.CompanyUsers.managementModal.settingInactiveButton',\n deleteButton: 'Company.CompanyUsers.managementModal.deleteButton',\n deletingButton: 'Company.CompanyUsers.managementModal.deletingButton',\n cancelButton: 'Company.CompanyUsers.managementModal.cancelButton',\n setActiveErrorGeneric: 'Company.CompanyUsers.managementModal.setActiveErrorGeneric',\n setActiveErrorSpecific: 'Company.CompanyUsers.managementModal.setActiveErrorSpecific',\n setInactiveErrorGeneric: 'Company.CompanyUsers.managementModal.setInactiveErrorGeneric',\n setInactiveErrorSpecific: 'Company.CompanyUsers.managementModal.setInactiveErrorSpecific',\n deleteErrorGeneric: 'Company.CompanyUsers.managementModal.deleteErrorGeneric',\n deleteErrorSpecific: 'Company.CompanyUsers.managementModal.deleteErrorSpecific',\n ariaCloseModal: 'Company.CompanyUsers.managementModal.ariaLabels.closeModal',\n ariaModalDescription: 'Company.CompanyUsers.managementModal.ariaLabels.modalDescription',\n });\n\n const handleToggleStatus = useCallback(async () => {\n if (isTogglingStatus) return;\n \n const newStatus = userStatus === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE';\n const isActivating = newStatus === 'ACTIVE';\n \n setIsTogglingStatus(true);\n clearAlert();\n try {\n const result = await updateCompanyUserStatus({ id: userId, status: newStatus });\n if (result.success) {\n onClose();\n } else {\n showError(isActivating ? translations.setActiveErrorSpecific : translations.setInactiveErrorSpecific);\n }\n } catch (error) {\n showError(isActivating ? translations.setActiveErrorGeneric : translations.setInactiveErrorGeneric);\n } finally {\n setIsTogglingStatus(false);\n }\n }, [userId, userStatus, onClose, isTogglingStatus, clearAlert, showError, translations.setActiveErrorSpecific, translations.setInactiveErrorSpecific, translations.setActiveErrorGeneric, translations.setInactiveErrorGeneric]);\n\n const handleDelete = useCallback(async () => {\n if (isDeleting) return;\n \n setIsDeleting(true);\n clearAlert();\n try {\n const result = await deleteCompanyUser({ id: userId });\n if (result.success) {\n onClose();\n } else {\n showError(translations.deleteErrorSpecific);\n }\n } catch (error) {\n showError(translations.deleteErrorGeneric);\n } finally {\n setIsDeleting(false);\n }\n }, [userId, onClose, isDeleting, clearAlert, showError, translations.deleteErrorSpecific, translations.deleteErrorGeneric]);\n\n const handleCancel = useCallback(() => {\n clearAlert();\n onClose();\n }, [onClose, clearAlert]);\n\n // Handle Escape key\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n clearAlert();\n onClose();\n }\n \n // Focus trapping\n if (event.key === 'Tab') {\n const modal = modalRef.current;\n if (!modal) return;\n \n const focusableElements = modal.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n \n if (event.shiftKey) {\n // Shift + Tab\n if (document.activeElement === firstElement) {\n lastElement.focus();\n event.preventDefault();\n }\n } else if (document.activeElement === lastElement) {\n // Tab\n firstElement.focus();\n event.preventDefault();\n }\n }\n }, [onClose, clearAlert]);\n\n const handleOverlayClick = useCallback((event: MouseEvent) => {\n if (event.target === event.currentTarget) {\n clearAlert();\n onClose();\n }\n }, [onClose, clearAlert]);\n\n const handleCloseClick = useCallback(() => {\n clearAlert();\n onClose();\n }, [onClose, clearAlert]);\n\n // Focus management and event listeners\n useEffect(() => {\n if (isOpen) {\n // Store current focus\n previousFocusRef.current = document.activeElement as HTMLElement;\n \n // Add keyboard event listener\n document.addEventListener('keydown', handleKeyDown);\n \n // Focus the modal after a brief delay to ensure it's rendered\n setTimeout(() => {\n const modal = modalRef.current;\n if (modal) {\n const firstButton = modal.querySelector('button') as HTMLElement;\n if (firstButton) {\n firstButton.focus();\n } else {\n modal.focus();\n }\n }\n }, 100);\n \n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }\n \n // Restore focus when modal closes\n if (previousFocusRef.current) {\n previousFocusRef.current.focus();\n }\n }, [isOpen, handleKeyDown]);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div \n className={classes(['company-management-company-users-management-modal-overlay', className])}\n onClick={handleOverlayClick}\n {...props}\n >\n <div \n ref={modalRef}\n className=\"company-management-company-users-management-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n tabIndex={-1}\n >\n <div className=\"company-management-company-users-management-modal__header\">\n <h2 \n id={titleId}\n className=\"company-management-company-users-management-modal__title\"\n >\n {translations.title}\n </h2>\n <button\n className=\"company-management-company-users-management-modal__close\"\n onClick={handleCloseClick}\n aria-label={translations.ariaCloseModal}\n >\n ×\n </button>\n </div>\n \n <div \n id={descriptionId}\n className=\"company-management-company-users-management-modal__content\"\n >\n <p className=\"company-management-company-users-management-modal__text\">\n {userStatus === 'ACTIVE' ? translations.setInactiveText : translations.setActiveText}\n </p>\n <p className=\"company-management-company-users-management-modal__text\">\n {translations.deleteText}\n </p>\n </div>\n\n {inLineAlertProps?.text && (\n <div \n className=\"company-management-company-users-management-modal__alert\"\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <InLineAlert\n type=\"error\"\n heading={inLineAlertProps.text}\n icon={inLineAlertProps.icon}\n data-testid=\"companyUsersManagementModalAlert\"\n />\n </div>\n )}\n\n <div className=\"company-management-company-users-management-modal__actions\">\n <Button\n variant=\"primary\"\n onClick={handleToggleStatus}\n disabled={isTogglingStatus}\n className=\"company-management-company-users-management-modal__button-primary\"\n >\n {isTogglingStatus \n ? (userStatus === 'ACTIVE' ? translations.settingInactiveButton : translations.settingActiveButton)\n : (userStatus === 'ACTIVE' ? translations.setInactiveButton : translations.setActiveButton)\n }\n </Button>\n \n <Button\n variant=\"tertiary\"\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"company-management-company-users-management-modal__button-delete\"\n >\n {isDeleting ? translations.deletingButton : translations.deleteButton}\n </Button>\n \n <Button\n variant=\"secondary\"\n onClick={handleCancel}\n className=\"company-management-company-users-management-modal__button-cancel\"\n >\n {translations.cancelButton}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { FunctionComponent, VNode, Fragment } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport { Icon, Button, Skeleton, SkeletonRow } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport '@adobe-commerce/elsie/components/Table/Table.css';\n\ntype Sortable = 'asc' | 'desc' | true;\n\ntype Column = {\n key: string;\n label: string;\n sortBy?: Sortable;\n};\n\ntype RowData = {\n [key: string]: VNode | string | number | undefined;\n _rowDetails?: VNode | string; // Special property for expandable row content\n};\n\nexport interface TableProps extends Omit<HTMLAttributes<HTMLTableElement>, 'loading'> {\n columns: Column[];\n rowData: RowData[];\n mobileLayout?: 'stacked' | 'none';\n caption?: string;\n expandedRows?: Set<number>;\n loading?: boolean;\n skeletonRowCount?: number;\n onSortChange?: (columnKey: string, direction: Sortable) => void;\n}\n\nexport const Table: FunctionComponent<TableProps> = ({\n className,\n children,\n columns = [],\n rowData = [],\n mobileLayout = 'none',\n caption,\n expandedRows = new Set(),\n loading = false,\n skeletonRowCount = 10,\n onSortChange,\n ...props\n}) => {\n const translations = useText({\n sortedAscending: 'Dropin.Table.sortedAscending',\n sortedDescending: 'Dropin.Table.sortedDescending',\n sortBy: 'Dropin.Table.sortBy',\n });\n\n const handleSort = (column: Column) => {\n if (!onSortChange) return;\n\n // Determine next sort direction\n let nextDirection: Sortable;\n if (column.sortBy === true) {\n nextDirection = 'asc';\n } else if (column.sortBy === 'asc') {\n nextDirection = 'desc';\n } else {\n nextDirection = true;\n }\n\n onSortChange(column.key, nextDirection);\n };\n\n const renderSortButton = (column: Column) => {\n if (column.sortBy === undefined) return null;\n\n let iconSource: string;\n let ariaLabel: string;\n\n if (column.sortBy === 'asc') {\n iconSource = 'ChevronUp';\n ariaLabel = translations.sortedAscending.replace('{label}', column.label);\n } else if (column.sortBy === 'desc') {\n iconSource = 'ChevronDown';\n ariaLabel = translations.sortedDescending.replace('{label}', column.label);\n } else {\n iconSource = 'Sort';\n ariaLabel = translations.sortBy.replace('{label}', column.label);\n }\n\n return (\n <Button\n variant=\"tertiary\"\n size=\"medium\"\n className=\"dropin-table__header__sort-button\"\n icon={<Icon source={iconSource} />}\n aria-label={ariaLabel}\n onClick={() => handleSort(column)}\n />\n );\n };\n\n const renderSkeletonRows = () => {\n return Array.from({ length: skeletonRowCount }, (_, rowIndex) => (\n <tr key={`skeleton-${rowIndex}`} className=\"dropin-table__body__row\">\n {columns.map((column) => (\n <td key={column.key} className=\"dropin-table__body__cell\" data-label={column.label}>\n <Skeleton>\n <SkeletonRow variant=\"row\" size=\"small\" fullWidth />\n </Skeleton>\n </td>\n ))}\n </tr>\n ));\n };\n\n const renderDataRows = () => {\n return rowData.map((row, rowIndex) => {\n const hasDetails = row._rowDetails !== undefined;\n const isExpanded = expandedRows.has(rowIndex);\n\n return (\n <Fragment key={rowIndex}>\n <tr className=\"dropin-table__body__row\">\n {columns.map((column) => {\n const cell = row[column.key];\n\n if (typeof cell === 'string' || typeof cell === 'number') {\n return (\n <td key={column.key} className=\"dropin-table__body__cell\" data-label={column.label}>\n {cell}\n </td>\n );\n }\n\n return (\n <td key={column.key} className=\"dropin-table__body__cell\" data-label={column.label}>\n <VComponent node={cell!} />\n </td>\n );\n })}\n </tr>\n {hasDetails && isExpanded && (\n <tr\n key={`${rowIndex}-details`}\n className=\"dropin-table__row-details dropin-table__row-details--expanded\"\n id={`row-${rowIndex}-details`}\n >\n <td\n className=\"dropin-table__row-details__cell\"\n colSpan={columns.length}\n role=\"region\"\n aria-labelledby={`row-${rowIndex}-details`}\n >\n {typeof row._rowDetails === 'string' ? row._rowDetails : <VComponent node={row._rowDetails!} />}\n </td>\n </tr>\n )}\n </Fragment>\n );\n });\n };\n\n const getAriaSort = (column: Column): 'none' | 'ascending' | 'descending' | 'other' | undefined => {\n if (column.sortBy === true) return 'none';\n if (column.sortBy === 'asc') return 'ascending';\n if (column.sortBy === 'desc') return 'descending';\n return undefined;\n };\n\n return (\n <div className={classes(['dropin-table', `dropin-table--mobile-layout-${mobileLayout}`, className])}>\n <table {...props} className=\"dropin-table__table\">\n {caption && <caption className=\"dropin-table__caption\">{caption}</caption>}\n <thead className=\"dropin-table__header\">\n <tr className=\"dropin-table__header__row\">\n {columns.map((column) => (\n <th\n key={column.key}\n className={classes([\n 'dropin-table__header__cell',\n ['dropin-table__header__cell--sorted', column.sortBy === 'asc' || column.sortBy === 'desc'],\n ['dropin-table__header__cell--sortable', column.sortBy !== undefined]\n ])}\n aria-sort={getAriaSort(column)}\n >\n {column.label}\n {renderSortButton(column)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"dropin-table__body\">\n {loading ? (\n // Render skeleton rows when loading\n renderSkeletonRows()\n ) : (\n // Render actual data when not loading\n renderDataRows()\n )}\n </tbody>\n </table>\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { HTMLAttributes } from 'preact/compat';\nimport { useEffect, useState, useCallback, useRef, useMemo } from 'preact/hooks';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { \n Button, \n Picker \n} from '@adobe-commerce/elsie/components';\nimport { Table } from '@adobe-commerce/elsie/components/Table/Table';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { formatUserStatus, formatUserName } from '@/company-management/lib';\nimport { CompanyUserStatus } from '@/company-management/types';\nimport { CompanyUsersManagementModal } from '@/company-management/components/CompanyUsersManagementModal';\nimport { CompanyUsersTableLoader } from '@/company-management/components/CompanyLoaders';\nimport { useCompanyContextListener } from './hooks';\nimport { useCompanyUsers } from '@/company-management/hooks';\nimport './CompanyUsers.css';\n\nexport interface CompanyUsersProps extends HTMLAttributes<HTMLElement> {}\n\n// Constants\nconst PAGE_SIZE_OPTIONS = [\n { text: '20', value: '20' },\n { text: '30', value: '30' },\n { text: '50', value: '50' },\n { text: '100', value: '100' },\n { text: '200', value: '200' }\n];\n\nexport const CompanyUsers: Container<CompanyUsersProps> = ({ children, className, ...props }) => {\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [selectedUserId, setSelectedUserId] = useState('');\n const tableRef = useRef<HTMLDivElement>(null);\n\n // Text translations using proper useText pattern\n const translations = useText({\n showAllUsers: 'Company.CompanyUsers.filters.showAll',\n showActiveUsers: 'Company.CompanyUsers.filters.showActive',\n showInactiveUsers: 'Company.CompanyUsers.filters.showInactive',\n idColumn: 'Company.CompanyUsers.columns.id',\n nameColumn: 'Company.CompanyUsers.columns.name',\n emailColumn: 'Company.CompanyUsers.columns.email',\n roleColumn: 'Company.CompanyUsers.columns.role',\n teamColumn: 'Company.CompanyUsers.columns.team',\n statusColumn: 'Company.CompanyUsers.columns.status',\n actionsColumn: 'Company.CompanyUsers.columns.actions',\n statusActive: 'Company.CompanyUsers.status.active',\n statusInactive: 'Company.CompanyUsers.status.inactive',\n emptyTeam: 'Company.CompanyUsers.emptyTeam',\n emptyActions: 'Company.CompanyUsers.emptyActions',\n itemsText: 'Company.CompanyUsers.pagination.itemsCount',\n itemsPerPageLabel: 'Company.CompanyUsers.pagination.itemsPerPage',\n showLabel: 'Company.CompanyUsers.pagination.show',\n perPageLabel: 'Company.CompanyUsers.pagination.perPage',\n previousPage: 'Company.CompanyUsers.pagination.previous',\n nextPage: 'Company.CompanyUsers.pagination.next',\n pageInfo: 'Company.CompanyUsers.pagination.pageInfo',\n // Accessibility labels\n ariaLoadingUsers: 'Company.CompanyUsers.ariaLabels.loadingUsers',\n ariaUsersTable: 'Company.CompanyUsers.ariaLabels.usersTable',\n ariaFilterOptions: 'Company.CompanyUsers.ariaLabels.filterOptions',\n ariaPaginationNav: 'Company.CompanyUsers.ariaLabels.paginationNav',\n ariaPageSizeSelector: 'Company.CompanyUsers.ariaLabels.pageSizeSelector',\n ariaPreviousPageFull: 'Company.CompanyUsers.ariaLabels.previousPageFull',\n ariaNextPageFull: 'Company.CompanyUsers.ariaLabels.nextPageFull',\n ariaCurrentPage: 'Company.CompanyUsers.ariaLabels.currentPage',\n ariaShowingUsers: 'Company.CompanyUsers.ariaLabels.showingUsers',\n ariaDataLoaded: 'Company.CompanyUsers.ariaLabels.dataLoaded',\n ariaDataError: 'Company.CompanyUsers.ariaLabels.dataError',\n ariaPageNavigation: 'Company.CompanyUsers.ariaLabels.pageNavigation',\n manageUser: 'Company.CompanyUsers.actions.manage',\n ariaManageUser: 'Company.CompanyUsers.ariaLabels.manageUser'\n });\n\n // Use the company users hook to manage all user data and pagination\n const {\n users,\n loading,\n currentPage,\n pageSize,\n filterType,\n totalItems,\n totalPages,\n announcement,\n canEditUsers,\n handleFilterChange,\n handlePageSizeChange,\n handlePreviousPage,\n handleNextPage,\n refreshUsers\n } = useCompanyUsers({\n translations: {\n ariaDataLoaded: translations.ariaDataLoaded,\n ariaDataError: translations.ariaDataError\n }\n });\n\n // Stable reference to translations to prevent unnecessary re-renders\n const translationsRef = useRef(translations);\n translationsRef.current = translations;\n\n // Focus management after data updates\n useEffect(() => {\n if (!loading && tableRef.current && users.length > 0) {\n // Announce change to screen readers but don't steal focus\n tableRef.current.setAttribute('aria-busy', 'false');\n }\n }, [loading, currentPage, filterType, users.length]);\n\n // Handle company context changes using reusable hook\n const handleCompanyContextChange = useCallback(() => {\n refreshUsers();\n }, [refreshUsers]);\n\n useCompanyContextListener(handleCompanyContextChange);\n\n // Handle modal operations\n const handleOpenModal = useCallback((userId: string) => {\n setSelectedUserId(userId);\n setIsModalOpen(true);\n }, []);\n\n const handleCloseModal = useCallback(() => {\n setIsModalOpen(false);\n setSelectedUserId('');\n // Refresh the user list after modal closes (in case user was deleted)\n refreshUsers();\n }, [refreshUsers]);\n\n // Prepare table columns - memoized to prevent unnecessary re-renders (optimized)\n const columns = useMemo(() => {\n const currentTranslations = translationsRef.current;\n return [\n { key: 'id', label: currentTranslations.idColumn },\n { key: 'name', label: currentTranslations.nameColumn },\n { key: 'email', label: currentTranslations.emailColumn },\n { key: 'role', label: currentTranslations.roleColumn },\n { key: 'team', label: currentTranslations.teamColumn },\n { key: 'status', label: currentTranslations.statusColumn },\n { key: 'actions', label: currentTranslations.actionsColumn }\n ];\n }, []); // No dependencies - only recompute when component mounts\n\n\n // Prepare table row data - memoized for performance (optimized)\n const rowData = useMemo(() => users.map((user) => {\n const fullName = formatUserName(user.firstName, user.lastName);\n const currentTranslations = translationsRef.current;\n \n return {\n id: user.id,\n name: fullName,\n email: user.email,\n role: user.role,\n team: user.team || currentTranslations.emptyTeam,\n status: formatUserStatus(user.status, currentTranslations),\n actions: canEditUsers ? (\n <Button\n variant=\"tertiary\"\n onClick={() => handleOpenModal(user.id)}\n aria-label={currentTranslations.ariaManageUser?.replace('{name}', fullName) || `Manage user ${fullName}`}\n className=\"manage-user-button\"\n >\n {currentTranslations.manageUser || 'Manage'}\n </Button>\n ) : (\n <span className=\"no-actions\">{currentTranslations.emptyActions}</span>\n )\n };\n }), [users, handleOpenModal, canEditUsers]);\n\n\n return (\n <section className={className} {...props}>\n {/* Screen reader announcements */}\n <div className=\"sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcement}\n </div>\n\n {/* Filter buttons */}\n <div className=\"filterButtons\" role=\"group\" aria-label={translations.ariaFilterOptions}>\n {filterType !== 'all' && (\n <Button\n variant=\"tertiary\"\n onClick={() => handleFilterChange('all')}\n aria-label={translations.showAllUsers}\n >\n {translations.showAllUsers}\n </Button>\n )}\n {filterType !== 'active' && (\n <Button\n variant=\"tertiary\"\n onClick={() => handleFilterChange('active')}\n aria-label={translations.showActiveUsers}\n >\n {translations.showActiveUsers}\n </Button>\n )}\n {filterType !== 'inactive' && (\n <Button\n variant=\"tertiary\"\n onClick={() => handleFilterChange('inactive')}\n aria-label={translations.showInactiveUsers}\n >\n {translations.showInactiveUsers}\n </Button>\n )}\n </div>\n\n {/* Table with loading state */}\n <div ref={tableRef} aria-busy={loading}>\n {loading ? (\n <div className=\"loadingContainer\" role=\"status\" aria-live=\"polite\">\n <CompanyUsersTableLoader testId=\"companyUsersTableLoader\" />\n <span className=\"sr-only\">{translations.ariaLoadingUsers}</span>\n </div>\n ) : (\n <Table\n columns={columns}\n rowData={rowData}\n mobileLayout=\"stacked\"\n aria-label={translations.ariaUsersTable}\n summary={translations.ariaShowingUsers.replace('{count}', users.length.toString())}\n />\n )}\n </div>\n\n {/* Pagination controls */}\n <nav aria-label={translations.ariaPaginationNav} className=\"paginationContainer\">\n {/* Items count on the left */}\n <div aria-live=\"polite\" aria-atomic=\"true\">\n {translations.itemsText.replace('{count}', totalItems.toString())}\n </div>\n\n {/* Pagination buttons in the center (only show when multiple pages) */}\n {totalPages > 1 && (\n <div className=\"paginationButtons\" role=\"group\" aria-label={translations.ariaPageNavigation}>\n <Button\n variant=\"secondary\"\n onClick={handlePreviousPage}\n disabled={currentPage === 1}\n aria-label={translations.ariaPreviousPageFull.replace('{current}', currentPage.toString())}\n >\n {translations.previousPage}\n </Button>\n <span aria-current=\"page\" aria-live=\"polite\">\n {translations.pageInfo.replace('{current}', currentPage.toString()).replace('{total}', totalPages.toString())}\n </span>\n <Button\n variant=\"secondary\"\n onClick={handleNextPage}\n disabled={currentPage === totalPages}\n aria-label={translations.ariaNextPageFull.replace('{current}', currentPage.toString())}\n >\n {translations.nextPage}\n </Button>\n </div>\n )}\n\n {/* Page size picker on the right */}\n <div className=\"pageSizeSelector\">\n <label htmlFor=\"page-size-select\" id=\"page-size-label\">\n <span>{translations.showLabel}</span>\n </label>\n <Picker\n id=\"page-size-select\"\n name=\"pageSize\"\n value={pageSize.toString()}\n options={PAGE_SIZE_OPTIONS}\n onChange={handlePageSizeChange}\n aria-labelledby=\"page-size-label\"\n aria-describedby=\"page-size-description\"\n />\n <span id=\"page-size-description\">{translations.perPageLabel}</span>\n </div>\n </nav>\n\n {children}\n\n {/* User Management Modal */}\n {selectedUserId && canEditUsers && (\n <CompanyUsersManagementModal\n isOpen={isModalOpen}\n userId={selectedUserId}\n userStatus={(users.find(user => user.id === selectedUserId)?.status as CompanyUserStatus) || 'ACTIVE'}\n onClose={handleCloseModal}\n />\n )}\n </section>\n );\n};\n"],"names":["formatUserStatus","status","translations","formatUserName","firstName","lastName","first","last","DEFAULT_PAGE_SIZE","FIRST_PAGE","useCompanyUsers","users","setUsers","useState","loading","setLoading","currentPage","setCurrentPage","pageSize","setPageSize","filterType","setFilterType","totalItems","setTotalItems","totalPages","setTotalPages","announcement","setAnnouncement","userPermissions","setUserPermissions","translationsRef","useRef","filter","useMemo","fetchUsers","useCallback","response","getCompanyUsers","fetchPermissions","allowedIds","fetchUserPermissions","useEffect","handleFilterChange","newFilter","handlePageSizeChange","event","value","newSize","handlePreviousPage","handleNextPage","canEditUsers","refreshUsers","CompanyUsersManagementModal","className","userId","userStatus","onClose","isOpen","props","isDeleting","setIsDeleting","isTogglingStatus","setIsTogglingStatus","inLineAlertProps","showError","clearAlert","useInLineAlert","modalRef","previousFocusRef","titleId","descriptionId","useText","handleToggleStatus","newStatus","isActivating","updateCompanyUserStatus","handleDelete","deleteCompanyUser","handleCancel","handleKeyDown","modal","focusableElements","firstElement","lastElement","handleOverlayClick","handleCloseClick","firstButton","jsx","classes","jsxs","InLineAlert","Button","Table","children","columns","rowData","mobileLayout","caption","expandedRows","skeletonRowCount","onSortChange","handleSort","column","nextDirection","renderSortButton","iconSource","ariaLabel","Icon","renderSkeletonRows","_","rowIndex","Skeleton","SkeletonRow","renderDataRows","row","hasDetails","isExpanded","Fragment","cell","VComponent","getAriaSort","PAGE_SIZE_OPTIONS","CompanyUsers","isModalOpen","setIsModalOpen","selectedUserId","setSelectedUserId","tableRef","handleCompanyContextChange","useCompanyContextListener","handleOpenModal","handleCloseModal","currentTranslations","user","fullName","_a","CompanyUsersTableLoader","Picker"],"mappings":"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","x_google_ignoreList":[3]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2025 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsx as o,jsxs as i}from"@dropins/tools/preact-jsx-runtime.js";import{useState as c,useEffect as m}from"@dropins/tools/preact-hooks.js";import{events as f}from"@dropins/tools/event-bus.js";import{g as p}from"../chunks/getCustomerCompany.js";import{Card as d,Skeleton as h,SkeletonRow as s}from"@dropins/tools/components.js";import{classes as u}from"@dropins/tools/lib.js";import{useText as y}from"@dropins/tools/i18n.js";import"../chunks/fetch-error.js";import"@dropins/tools/fetch-graphql.js";import"../chunks/validateCompanyEmail.js";const g=({customerCompanyInfo:e,loading:a,className:t})=>{const r=y({companyName:"Company.shared.fields.companyName",jobTitle:"Company.shared.fields.jobTitle",workPhoneNumber:"Company.shared.fields.workPhoneNumber",userRole:"Company.shared.fields.userRole"});return a?o(d,{variant:"secondary",className:u(["customer-company-info-card",t]),children:o("div",{className:"customer-company-info-card__content",children:i(h,{"data-testid":"customerCompanyInfoSkeletonLoader",children:[o(s,{variant:"heading",size:"xlarge",fullWidth:!1,lines:1}),o(s,{variant:"heading",size:"xlarge",fullWidth:!0,lines:1}),o(s,{variant:"heading",size:"xlarge",fullWidth:!0,lines:1}),o(s,{variant:"heading",size:"xlarge",fullWidth:!0,lines:1})]})})}):e?o(d,{variant:"secondary",className:u(["customer-company-info-card",t]),children:i("div",{className:"customer-company-info-card__content",children:[i("p",{children:[r.companyName,": ",e.companyName]}),e.jobTitle&&i("p",{children:[r.jobTitle,": ",e.jobTitle]}),e.workPhoneNumber&&i("p",{children:[r.workPhoneNumber,": ",e.workPhoneNumber]}),e.userRole&&i("p",{children:[r.userRole,": ",e.userRole]})]})}):null},
|
|
3
|
+
import{jsx as o,jsxs as i}from"@dropins/tools/preact-jsx-runtime.js";import{useState as c,useEffect as m}from"@dropins/tools/preact-hooks.js";import{events as f}from"@dropins/tools/event-bus.js";import{g as p}from"../chunks/getCustomerCompany.js";import{Card as d,Skeleton as h,SkeletonRow as s}from"@dropins/tools/components.js";import{classes as u}from"@dropins/tools/lib.js";import{useText as y}from"@dropins/tools/i18n.js";import"../chunks/fetch-error.js";import"@dropins/tools/fetch-graphql.js";import"../chunks/validateCompanyEmail.js";const g=()=>{const[e,a]=c(null),[t,r]=c(!0),l=async()=>{try{r(!0);const n=await p();a(n)}catch(n){console.error("Failed to fetch customer company info:",n),a(null)}finally{r(!1)}};return m(()=>{l()},[]),m(()=>{const n=f.on("companyContext/changed",l,{eager:!0});return()=>{n==null||n.off()}},[]),{companyInfo:e,loading:t}},N=({customerCompanyInfo:e,loading:a,className:t})=>{const r=y({companyName:"Company.shared.fields.companyName",jobTitle:"Company.shared.fields.jobTitle",workPhoneNumber:"Company.shared.fields.workPhoneNumber",userRole:"Company.shared.fields.userRole"});return a?o(d,{variant:"secondary",className:u(["customer-company-info-card",t]),children:o("div",{className:"customer-company-info-card__content",children:i(h,{"data-testid":"customerCompanyInfoSkeletonLoader",children:[o(s,{variant:"heading",size:"xlarge",fullWidth:!1,lines:1}),o(s,{variant:"heading",size:"xlarge",fullWidth:!0,lines:1}),o(s,{variant:"heading",size:"xlarge",fullWidth:!0,lines:1}),o(s,{variant:"heading",size:"xlarge",fullWidth:!0,lines:1})]})})}):e?o(d,{variant:"secondary",className:u(["customer-company-info-card",t]),children:i("div",{className:"customer-company-info-card__content",children:[i("p",{children:[r.companyName,": ",e.companyName]}),e.jobTitle&&i("p",{children:[r.jobTitle,": ",e.jobTitle]}),e.workPhoneNumber&&i("p",{children:[r.workPhoneNumber,": ",e.workPhoneNumber]}),e.userRole&&i("p",{children:[r.userRole,": ",e.userRole]})]})}):null},z=({className:e})=>{const{companyInfo:a,loading:t}=g();return o(N,{customerCompanyInfo:a,loading:t,className:e})};export{z as CustomerCompanyInfo};
|
|
4
4
|
//# sourceMappingURL=CustomerCompanyInfo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomerCompanyInfo.js","sources":["/@dropins/storefront-company-management/src/
|
|
1
|
+
{"version":3,"file":"CustomerCompanyInfo.js","sources":["/@dropins/storefront-company-management/src/hooks/containers/useCustomerCompanyInfo.ts","/@dropins/storefront-company-management/src/components/CustomerCompanyInfoCard/CustomerCompanyInfoCard.tsx","/@dropins/storefront-company-management/src/containers/CustomerCompanyInfo/CustomerCompanyInfo.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { useState, useEffect } from 'preact/hooks';\nimport { events } from '@adobe-commerce/event-bus';\nimport { getCustomerCompany } from '@/company-management/api/getCustomerCompany';\nimport { CustomerCompanyInfo } from '@/company-management/data/models/customer-company-info';\n\n/**\n * Custom hook for fetching and managing customer company information\n * Listens to companyContext/changed events to refetch data when company context changes\n * @returns Object containing company info and loading state\n */\nexport const useCustomerCompanyInfo = () => {\n const [companyInfo, setCompanyInfo] = useState<CustomerCompanyInfo | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n\n const fetchCompanyInfo = async () => {\n try {\n setLoading(true);\n const data = await getCustomerCompany();\n setCompanyInfo(data);\n } catch (error) {\n console.error('Failed to fetch customer company info:', error);\n setCompanyInfo(null);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchCompanyInfo();\n }, []);\n\n // Re-fetch customer company info when company context changes (e.g., user switches company)\n useEffect(() => {\n const subChanged = events.on('companyContext/changed', fetchCompanyInfo, { eager: true });\n\n return () => {\n subChanged?.off();\n };\n }, []);\n\n return {\n companyInfo,\n loading,\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { FunctionComponent } from 'preact';\nimport { Card, Skeleton, SkeletonRow } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { CustomerCompanyInfoCardProps } from '@/company-management/types';\nimport './CustomerCompanyInfoCard.css';\n\n/**\n * Component for displaying customer company information in a card format\n * Shows company name, job title, and work phone number with loading states\n */\nexport const CustomerCompanyInfoCard: FunctionComponent<CustomerCompanyInfoCardProps> = ({\n customerCompanyInfo,\n loading,\n className,\n}) => {\n const translations = useText({\n companyName: 'Company.shared.fields.companyName',\n jobTitle: 'Company.shared.fields.jobTitle',\n workPhoneNumber: 'Company.shared.fields.workPhoneNumber',\n userRole: 'Company.shared.fields.userRole',\n });\n\n // Return loader card OR data card\n if (loading) {\n return (\n <Card variant=\"secondary\" className={classes(['customer-company-info-card', className])}>\n <div className=\"customer-company-info-card__content\">\n <Skeleton data-testid=\"customerCompanyInfoSkeletonLoader\">\n <SkeletonRow variant=\"heading\" size=\"xlarge\" fullWidth={false} lines={1} />\n <SkeletonRow variant=\"heading\" size=\"xlarge\" fullWidth={true} lines={1} />\n <SkeletonRow variant=\"heading\" size=\"xlarge\" fullWidth={true} lines={1} />\n <SkeletonRow variant=\"heading\" size=\"xlarge\" fullWidth={true} lines={1} />\n </Skeleton>\n </div>\n </Card>\n );\n }\n\n if (!customerCompanyInfo) {\n return null;\n }\n\n return (\n <Card variant=\"secondary\" className={classes(['customer-company-info-card', className])}>\n <div className=\"customer-company-info-card__content\">\n <p>{translations.companyName}: {customerCompanyInfo.companyName}</p>\n \n {customerCompanyInfo.jobTitle && (\n <p>{translations.jobTitle}: {customerCompanyInfo.jobTitle}</p>\n )}\n \n {customerCompanyInfo.workPhoneNumber && (\n <p>{translations.workPhoneNumber}: {customerCompanyInfo.workPhoneNumber}</p>\n )}\n \n {customerCompanyInfo.userRole && (\n <p>{translations.userRole}: {customerCompanyInfo.userRole}</p>\n )}\n </div>\n </Card>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { CustomerCompanyInfoCard } from '@/company-management/components';\nimport { useCustomerCompanyInfo } from '@/company-management/hooks/containers';\nimport { CustomerCompanyInfoProps } from '@/company-management/types';\n\n/**\n * Container component for customer company information\n * Manages data fetching and passes props to CustomerCompanyInfoCard\n */\nexport const CustomerCompanyInfo: Container<CustomerCompanyInfoProps> = ({\n className,\n}) => {\n const { companyInfo: customerCompanyInfo, loading } = useCustomerCompanyInfo();\n\n return <CustomerCompanyInfoCard customerCompanyInfo={customerCompanyInfo} loading={loading} className={className} />;\n};\n"],"names":["useCustomerCompanyInfo","companyInfo","setCompanyInfo","useState","loading","setLoading","fetchCompanyInfo","data","getCustomerCompany","error","useEffect","subChanged","events","CustomerCompanyInfoCard","customerCompanyInfo","className","translations","useText","Card","classes","jsxs","Skeleton","jsx","SkeletonRow","CustomerCompanyInfo"],"mappings":"8hBA0BO,MAAMA,EAAyB,IAAM,CAC1C,KAAM,CAACC,EAAaC,CAAc,EAAIC,EAAqC,IAAI,EACzE,CAACC,EAASC,CAAU,EAAIF,EAAkB,EAAI,EAE9CG,EAAmB,SAAY,CAC/B,GAAA,CACFD,EAAW,EAAI,EACT,MAAAE,EAAO,MAAMC,EAAmB,EACtCN,EAAeK,CAAI,QACZE,EAAO,CACN,QAAA,MAAM,yCAA0CA,CAAK,EAC7DP,EAAe,IAAI,CAAA,QACnB,CACAG,EAAW,EAAK,CAAA,CAEpB,EAEA,OAAAK,EAAU,IAAM,CACGJ,EAAA,CACnB,EAAG,EAAE,EAGLI,EAAU,IAAM,CACR,MAAAC,EAAaC,EAAO,GAAG,yBAA0BN,EAAkB,CAAE,MAAO,GAAM,EAExF,MAAO,IAAM,CACXK,GAAA,MAAAA,EAAY,KACd,CACF,EAAG,EAAE,EAEE,CACL,YAAAV,EACA,QAAAG,CACF,CACF,ECjCaS,EAA2E,CAAC,CACvF,oBAAAC,EACA,QAAAV,EACA,UAAAW,CACF,IAAM,CACJ,MAAMC,EAAeC,EAAQ,CAC3B,YAAa,oCACb,SAAU,iCACV,gBAAiB,wCACjB,SAAU,gCAAA,CACX,EAGD,OAAIb,IAECc,EAAK,CAAA,QAAQ,YAAY,UAAWC,EAAQ,CAAC,6BAA8BJ,CAAS,CAAC,EACpF,WAAC,MAAI,CAAA,UAAU,sCACb,SAACK,EAAAC,EAAA,CAAS,cAAY,oCACpB,SAAA,CAACC,EAAAC,EAAA,CAAY,QAAQ,UAAU,KAAK,SAAS,UAAW,GAAO,MAAO,CAAG,CAAA,EACzED,EAACC,GAAY,QAAQ,UAAU,KAAK,SAAS,UAAW,GAAM,MAAO,CAAG,CAAA,EACxED,EAACC,GAAY,QAAQ,UAAU,KAAK,SAAS,UAAW,GAAM,MAAO,CAAG,CAAA,EACxED,EAACC,GAAY,QAAQ,UAAU,KAAK,SAAS,UAAW,GAAM,MAAO,CAAG,CAAA,CAAA,CAC1E,CAAA,CACF,CAAA,EACF,EAICT,EAKFQ,EAAAJ,EAAA,CAAK,QAAQ,YAAY,UAAWC,EAAQ,CAAC,6BAA8BJ,CAAS,CAAC,EACpF,SAACK,EAAA,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAA,EAAC,IAAG,CAAA,SAAA,CAAaJ,EAAA,YAAY,KAAGF,EAAoB,WAAA,EAAY,EAE/DA,EAAoB,UACnBM,EAAC,IAAG,CAAA,SAAA,CAAaJ,EAAA,SAAS,KAAGF,EAAoB,QAAA,EAAS,EAG3DA,EAAoB,iBACnBM,EAAC,IAAG,CAAA,SAAA,CAAaJ,EAAA,gBAAgB,KAAGF,EAAoB,eAAA,EAAgB,EAGzEA,EAAoB,UACnBM,EAAC,IAAG,CAAA,SAAA,CAAaJ,EAAA,SAAS,KAAGF,EAAoB,QAAA,CAAS,CAAA,CAAA,CAAA,CAE9D,CACF,CAAA,EApBO,IAsBX,ECrDaU,EAA2D,CAAC,CACvE,UAAAT,CACF,IAAM,CACJ,KAAM,CAAE,YAAaD,EAAqB,QAAAV,CAAA,EAAYJ,EAAuB,EAE7E,OAAQsB,EAAAT,EAAA,CAAwB,oBAAAC,EAA0C,QAAAV,EAAkB,UAAAW,CAAsB,CAAA,CACpH"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CompanyUser, CompanyUsersFilter } from '../../types';
|
|
2
|
+
|
|
3
|
+
export type FilterType = 'all' | 'active' | 'inactive';
|
|
4
|
+
export interface UseCompanyUsersProps {
|
|
5
|
+
translations: {
|
|
6
|
+
ariaDataLoaded: string;
|
|
7
|
+
ariaDataError: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface UseCompanyUsersReturn {
|
|
11
|
+
users: CompanyUser[];
|
|
12
|
+
userPermissions: Set<string> | null;
|
|
13
|
+
currentPage: number;
|
|
14
|
+
pageSize: number;
|
|
15
|
+
totalItems: number;
|
|
16
|
+
totalPages: number;
|
|
17
|
+
filterType: FilterType;
|
|
18
|
+
filter: CompanyUsersFilter | undefined;
|
|
19
|
+
loading: boolean;
|
|
20
|
+
announcement: string;
|
|
21
|
+
canEditUsers: boolean;
|
|
22
|
+
handleFilterChange: (newFilter: FilterType) => void;
|
|
23
|
+
handlePageSizeChange: (event: Event | {
|
|
24
|
+
target?: {
|
|
25
|
+
value: string;
|
|
26
|
+
};
|
|
27
|
+
} | string) => void;
|
|
28
|
+
handlePreviousPage: () => void;
|
|
29
|
+
handleNextPage: () => void;
|
|
30
|
+
refreshUsers: () => Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare const useCompanyUsers: ({ translations }: UseCompanyUsersProps) => UseCompanyUsersReturn;
|
|
33
|
+
//# sourceMappingURL=useCompanyUsers.d.ts.map
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "@dropins/storefront-company-management", "version": "1.0.0-
|
|
1
|
+
{"name": "@dropins/storefront-company-management", "version": "1.0.0-alpha2001", "@dropins/tools": "^1.5.0-beta4", "license": "SEE LICENSE IN LICENSE.md"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/********************************************************************
|
|
2
|
-
* ADOBE CONFIDENTIAL
|
|
3
|
-
* __________________
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2025 Adobe
|
|
6
|
-
* All Rights Reserved.
|
|
7
|
-
*
|
|
8
|
-
* NOTICE: All information contained herein is, and remains
|
|
9
|
-
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
-
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
-
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
-
* property laws, including trade secret and copyright laws.
|
|
13
|
-
* Dissemination of this information or reproduction of this material
|
|
14
|
-
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
-
* from Adobe.
|
|
16
|
-
*******************************************************************/
|
|
17
|
-
export { DELETE_COMPANY_USER_MUTATION } from './deleteCompanyUser.graphql';
|
|
18
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/********************************************************************
|
|
2
|
-
* ADOBE CONFIDENTIAL
|
|
3
|
-
* __________________
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2025 Adobe
|
|
6
|
-
* All Rights Reserved.
|
|
7
|
-
*
|
|
8
|
-
* NOTICE: All information contained herein is, and remains
|
|
9
|
-
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
-
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
-
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
-
* property laws, including trade secret and copyright laws.
|
|
13
|
-
* Dissemination of this information or reproduction of this material
|
|
14
|
-
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
-
* from Adobe.
|
|
16
|
-
*******************************************************************/
|
|
17
|
-
export { COMPANY_USERS_QUERY } from './companyUsers.graphql';
|
|
18
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/********************************************************************
|
|
2
|
-
* ADOBE CONFIDENTIAL
|
|
3
|
-
* __________________
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2025 Adobe
|
|
6
|
-
* All Rights Reserved.
|
|
7
|
-
*
|
|
8
|
-
* NOTICE: All information contained herein is, and remains
|
|
9
|
-
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
-
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
-
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
-
* property laws, including trade secret and copyright laws.
|
|
13
|
-
* Dissemination of this information or reproduction of this material
|
|
14
|
-
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
-
* from Adobe.
|
|
16
|
-
*******************************************************************/
|
|
17
|
-
export { UPDATE_COMPANY_USER_STATUS_MUTATION } from './updateCompanyUserStatus.graphql';
|
|
18
|
-
//# sourceMappingURL=index.d.ts.map
|