@openedx/frontend-app-admin-console 1.0.0-alpha.7 → 1.0.0-alpha.9
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/dist/authz-module/audit-user/index.js +1 -1
- package/dist/authz-module/audit-user/index.js.map +1 -1
- package/dist/authz-module/authz-home/index.js +1 -1
- package/dist/authz-module/authz-home/index.js.map +1 -1
- package/dist/authz-module/components/AuthZLayout.js +1 -1
- package/dist/authz-module/components/AuthZLayout.js.map +1 -1
- package/dist/authz-module/components/AuthZTitle.d.ts +2 -1
- package/dist/authz-module/components/AuthZTitle.js +2 -2
- package/dist/authz-module/components/AuthZTitle.js.map +1 -1
- package/dist/authz-module/components/PermissionTable.js +1 -1
- package/dist/authz-module/components/PermissionTable.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.d.ts +1 -1
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js +4 -3
- package/dist/authz-module/components/TableControlBar/MultipleChoiceFilter.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/SearchFilter.d.ts +2 -1
- package/dist/authz-module/components/TableControlBar/SearchFilter.js +2 -1
- package/dist/authz-module/components/TableControlBar/SearchFilter.js.map +1 -1
- package/dist/authz-module/components/TableControlBar/types.d.ts +1 -0
- package/dist/authz-module/components/TableControlBar/types.js.map +1 -1
- package/dist/authz-module/index.scss +28 -2
- package/dist/authz-module/roles-permissions/RolesPermissions.js +2 -2
- package/dist/authz-module/roles-permissions/RolesPermissions.js.map +1 -1
- package/dist/authz-module/utils.d.ts +1 -0
- package/dist/authz-module/utils.js +2 -0
- package/dist/authz-module/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -181,7 +181,7 @@ const AuditUserPage = () => {
|
|
|
181
181
|
rolesCount: count || 0,
|
|
182
182
|
} }), _jsx(AuthZLayout, { navLinks: navLinks, activeLabel: (user === null || user === void 0 ? void 0 : user.username) || '', pageTitle: (user === null || user === void 0 ? void 0 : user.username) || '', pageSubtitle: (user === null || user === void 0 ? void 0 : user.email) || '', actions: [
|
|
183
183
|
_jsx(AddRoleButton, { presetUsername: user === null || user === void 0 ? void 0 : user.username }, "add-role-button"),
|
|
184
|
-
], children: _jsx("div", { className: "page-band py-
|
|
184
|
+
], showDivider: true, children: _jsx("div", { className: "page-band py-3", children: _jsxs(DataTable, { isPaginated: true, isFilterable: true, isSortable: true, manualPagination: true, data: rowsWithPermissions, manualFilters: true, manualSortBy: true, fetchData: fetchData, itemCount: count, pageCount: pageCount, initialState: { pageSize: TABLE_DEFAULT_PAGE_SIZE }, additionalColumns: additionalColumns, columns: columns, isLoading: isLoadingUserAssignments, isExpandable: true, renderRowSubComponent: ({ row }) => (_jsx(UserPermissions, { row: row })), children: [_jsx(TableControlBar, { onFilterChange: setColumnsWithFiltersApplied }), _jsx(DataTable.Table, {}), _jsx(TableFooter, {})] }) }) })] }));
|
|
185
185
|
};
|
|
186
186
|
export default AuditUserPage;
|
|
187
187
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/audit-user/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useContext, useEffect, useMemo, useState,\n} from 'react';\nimport { SiteContext, useIntl } from '@openedx/frontend-base';\nimport { DataTable } from '@openedx/paragon';\nimport TableFooter from '@src/authz-module/components/TableFooter/TableFooter';\nimport {\n AUTHZ_HOME_PATH, TABLE_DEFAULT_PAGE_SIZE,\n} from '@src/authz-module/constants';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useUserAccount, useValidateUserPermissionsNonSuspense } from '@src/data/hooks';\nimport { LIBRARY_ROLE_KEYS } from '@src/authz-module/roles-permissions';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { getHttpErrorStatus } from '@src/data/utils';\nimport baseMessages from '@src/authz-module/messages';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport {\n OrgCell, RoleCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell,\n createActionsCell,\n} from '@src/authz-module/components/TableCells';\nimport { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { useRevokeUserRoles, useUserAssignedRoles } from '@src/authz-module/data/hooks';\nimport type { RevokeUserRolesRequest } from '@src/authz-module/data/api';\nimport { RoleToDelete } from '@src/types';\nimport { useToastManager } from '@src/components/ToastManager/ToastManagerContext';\nimport UserPermissions from '@src/authz-module/components/UserPermissions';\nimport OrgFilter from '@src/authz-module/components/TableControlBar/OrgFilter';\nimport RolesFilter from '@src/authz-module/components/TableControlBar/RolesFilter';\nimport TableControlBar from '@src/authz-module/components/TableControlBar/TableControlBar';\nimport messages from './messages';\nimport ConfirmDeletionModal from '@src/authz-module/components/ConfirmDeletionModal';\nimport { getCellHeader, getScopeManageActionPermission } from '@src/authz-module/utils';\n\nconst AuditUserPage = () => {\n const { formatMessage } = useIntl();\n const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState<string[]>([]);\n const { username } = useParams();\n const { authenticatedUser } = useContext(SiteContext);\n const navigate = useNavigate();\n const {\n isLoading: isLoadingUser, data: user, isError: isErrorUser, error: errorUser,\n } = useUserAccount(username);\n const { querySettings, handleTableFetch } = useQuerySettings();\n\n const { isCourseViewAllowed } = useViewTeamPermissions();\n const { isCourseEnabled } = useCourseAuthoringFlag();\n\n const effectiveQuerySettings = useMemo(() => {\n if (isCourseViewAllowed || querySettings.roles) return querySettings;\n return { ...querySettings, roles: LIBRARY_ROLE_KEYS };\n }, [isCourseViewAllowed, querySettings]);\n\n const {\n isLoading: isLoadingUserAssignments, data: { results: userAssignments, count } = { results: [], count: 0 },\n } = useUserAssignedRoles(username, effectiveQuerySettings);\n const [roleToDelete, setRoleToDelete] = useState<RoleToDelete | null>(null);\n const [showConfirmDeletionModal, setShowConfirmDeletionModal] = useState(false);\n const {\n showToast, showErrorToast, Bold, Br,\n } = useToastManager();\n const { mutate: revokeUserRoles, isPending: isRevokingUserRolePending } = useRevokeUserRoles();\n\n const deletePermissions = useMemo(() => {\n const uniqueScopes = [...new Set(userAssignments.map(assignment => assignment.scope))];\n return uniqueScopes.map(scope => getScopeManageActionPermission(scope));\n }, [userAssignments]);\n\n const {\n data: permissionsToManageScope,\n } = useValidateUserPermissionsNonSuspense(deletePermissions);\n\n const rowsWithPermissions = useMemo(() => {\n if (!permissionsToManageScope) return userAssignments;\n\n return userAssignments.map(assignment => {\n const canManageScope = permissionsToManageScope.some(\n permission => permission.scope === assignment.scope && permission.allowed,\n );\n return {\n ...assignment,\n canManageScope,\n };\n });\n }, [userAssignments, permissionsToManageScope]);\n\n const fetchData = useMemo(() => handleTableFetch, [handleTableFetch]);\n\n useEffect(() => {\n if (!user && !isLoadingUser) {\n if (!isErrorUser || getHttpErrorStatus(errorUser) === 404) {\n navigate(AUTHZ_HOME_PATH);\n }\n }\n }, [user, isLoadingUser, navigate, isErrorUser, errorUser]);\n\n const handleShowConfirmDeletionModal = useCallback((role: RoleToDelete) => {\n if (isRevokingUserRolePending) return;\n\n setRoleToDelete(role);\n setShowConfirmDeletionModal(true);\n }, [isRevokingUserRolePending]);\n\n const navLinks = useMemo(() => [\n {\n label: formatMessage(baseMessages['authz.management.home.nav.link']),\n to: AUTHZ_HOME_PATH,\n },\n ], [formatMessage]);\n\n const additionalColumns = useMemo(() => [\n {\n id: 'view_permissions',\n Header: '',\n Cell: ViewAllPermissionsCell,\n },\n {\n id: 'action',\n Header: formatMessage(messages['authz.user.table.action.column.header']),\n Cell: createActionsCell({\n onClickDeleteButton: handleShowConfirmDeletionModal,\n isUserAuthenticatedPage: username === authenticatedUser?.username,\n isCourseEnabled,\n }),\n },\n ], [authenticatedUser?.username, formatMessage, handleShowConfirmDeletionModal, username, isCourseEnabled]);\n\n const columns = useMemo(() => [\n {\n Header: getCellHeader('role', formatMessage(messages['authz.user.table.role.column.header']), columnsWithFiltersApplied),\n accessor: 'role',\n Cell: RoleCell,\n filter: 'includesValue',\n Filter: RolesFilter,\n filterButtonText: formatMessage(messages['authz.user.table.role.column.header']),\n filterOrder: 2,\n },\n {\n Header: getCellHeader('org', formatMessage(messages['authz.user.table.organization.column.header']), columnsWithFiltersApplied),\n accessor: 'org',\n Cell: OrgCell,\n filter: 'includesValue',\n Filter: OrgFilter,\n filterButtonText: formatMessage(messages['authz.user.table.organization.column.header']),\n filterOrder: 1,\n },\n {\n Header: getCellHeader('scope', formatMessage(messages['authz.user.table.scope.column.header']), columnsWithFiltersApplied),\n accessor: 'scope',\n Cell: ScopeCell,\n disableFilters: true,\n\n },\n {\n Header: formatMessage(messages['authz.user.table.permissions.column.header']),\n Cell: PermissionsCell,\n disableFilters: true,\n disableSortBy: true,\n },\n ], [formatMessage, columnsWithFiltersApplied]);\n\n const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);\n\n const handleCloseConfirmDeletionModal = () => {\n setRoleToDelete(null);\n setShowConfirmDeletionModal(false);\n };\n\n const handleRevokeUserRole = () => {\n if (!user || !roleToDelete) return;\n\n const data = {\n users: user.username,\n role: roleToDelete.role,\n scope: roleToDelete.scope,\n };\n\n const runRevokeRole = (variables: { data: RevokeUserRolesRequest }) => {\n const variablesData = {\n data: {\n ...variables.data,\n querySettings,\n },\n\n };\n revokeUserRoles(variablesData, {\n onSuccess: (response) => {\n const { errors } = response;\n\n if (errors.length) {\n showToast({\n type: 'error',\n message: formatMessage(\n baseMessages['authz.team.toast.default.error.message'],\n { Bold, Br },\n ),\n });\n return;\n }\n\n const remainingRolesCount = count ? count - 1 : 0;\n showToast({\n message: formatMessage(\n baseMessages['authz.team.remove.user.toast.success.description'],\n {\n role: roleToDelete.name ?? roleToDelete.role,\n rolesCount: remainingRolesCount,\n },\n ),\n type: 'success',\n });\n handleCloseConfirmDeletionModal();\n if (remainingRolesCount === 0) {\n navigate(AUTHZ_HOME_PATH);\n }\n },\n onError: (error, retryVariables) => {\n showErrorToast(error, () => runRevokeRole(retryVariables));\n },\n });\n };\n\n runRevokeRole({ data });\n };\n\n return (\n <>\n <ConfirmDeletionModal\n isOpen={showConfirmDeletionModal}\n close={handleCloseConfirmDeletionModal}\n onSave={handleRevokeUserRole}\n isDeleting={isRevokingUserRolePending}\n context={{\n userName: user?.username || '',\n scope: roleToDelete?.scope || '',\n role: roleToDelete?.role || '',\n name: roleToDelete?.name || '',\n rolesCount: count || 0,\n }}\n />\n <AuthZLayout\n navLinks={navLinks}\n activeLabel={user?.username || ''}\n pageTitle={user?.username || ''}\n pageSubtitle={user?.email || ''}\n actions={\n [\n <AddRoleButton presetUsername={user?.username} key=\"add-role-button\" />,\n ]\n }\n >\n <div className=\"page-band py-5\">\n <DataTable\n isPaginated\n isFilterable\n isSortable\n manualPagination\n data={rowsWithPermissions}\n manualFilters\n manualSortBy\n fetchData={fetchData}\n itemCount={count}\n pageCount={pageCount}\n initialState={{ pageSize: TABLE_DEFAULT_PAGE_SIZE }}\n additionalColumns={additionalColumns}\n columns={columns}\n isLoading={isLoadingUserAssignments}\n isExpandable\n renderRowSubComponent={({ row }) => (\n <UserPermissions row={row} />\n )}\n >\n <TableControlBar onFilterChange={setColumnsWithFiltersApplied} />\n <DataTable.Table />\n <TableFooter />\n </DataTable>\n </div>\n </AuthZLayout>\n </>\n );\n};\n\nexport default AuditUserPage;\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/audit-user/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useContext, useEffect, useMemo, useState,\n} from 'react';\nimport { SiteContext, useIntl } from '@openedx/frontend-base';\nimport { DataTable } from '@openedx/paragon';\nimport TableFooter from '@src/authz-module/components/TableFooter/TableFooter';\nimport {\n AUTHZ_HOME_PATH, TABLE_DEFAULT_PAGE_SIZE,\n} from '@src/authz-module/constants';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useUserAccount, useValidateUserPermissionsNonSuspense } from '@src/data/hooks';\nimport { LIBRARY_ROLE_KEYS } from '@src/authz-module/roles-permissions';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { getHttpErrorStatus } from '@src/data/utils';\nimport baseMessages from '@src/authz-module/messages';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport {\n OrgCell, RoleCell, ScopeCell, PermissionsCell, ViewAllPermissionsCell,\n createActionsCell,\n} from '@src/authz-module/components/TableCells';\nimport { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';\nimport { useCourseAuthoringFlag } from '@src/authz-module/hooks/useCourseAuthoringFlag';\nimport { useRevokeUserRoles, useUserAssignedRoles } from '@src/authz-module/data/hooks';\nimport type { RevokeUserRolesRequest } from '@src/authz-module/data/api';\nimport { RoleToDelete } from '@src/types';\nimport { useToastManager } from '@src/components/ToastManager/ToastManagerContext';\nimport UserPermissions from '@src/authz-module/components/UserPermissions';\nimport OrgFilter from '@src/authz-module/components/TableControlBar/OrgFilter';\nimport RolesFilter from '@src/authz-module/components/TableControlBar/RolesFilter';\nimport TableControlBar from '@src/authz-module/components/TableControlBar/TableControlBar';\nimport messages from './messages';\nimport ConfirmDeletionModal from '@src/authz-module/components/ConfirmDeletionModal';\nimport { getCellHeader, getScopeManageActionPermission } from '@src/authz-module/utils';\n\nconst AuditUserPage = () => {\n const { formatMessage } = useIntl();\n const [columnsWithFiltersApplied, setColumnsWithFiltersApplied] = useState<string[]>([]);\n const { username } = useParams();\n const { authenticatedUser } = useContext(SiteContext);\n const navigate = useNavigate();\n const {\n isLoading: isLoadingUser, data: user, isError: isErrorUser, error: errorUser,\n } = useUserAccount(username);\n const { querySettings, handleTableFetch } = useQuerySettings();\n\n const { isCourseViewAllowed } = useViewTeamPermissions();\n const { isCourseEnabled } = useCourseAuthoringFlag();\n\n const effectiveQuerySettings = useMemo(() => {\n if (isCourseViewAllowed || querySettings.roles) return querySettings;\n return { ...querySettings, roles: LIBRARY_ROLE_KEYS };\n }, [isCourseViewAllowed, querySettings]);\n\n const {\n isLoading: isLoadingUserAssignments, data: { results: userAssignments, count } = { results: [], count: 0 },\n } = useUserAssignedRoles(username, effectiveQuerySettings);\n const [roleToDelete, setRoleToDelete] = useState<RoleToDelete | null>(null);\n const [showConfirmDeletionModal, setShowConfirmDeletionModal] = useState(false);\n const {\n showToast, showErrorToast, Bold, Br,\n } = useToastManager();\n const { mutate: revokeUserRoles, isPending: isRevokingUserRolePending } = useRevokeUserRoles();\n\n const deletePermissions = useMemo(() => {\n const uniqueScopes = [...new Set(userAssignments.map(assignment => assignment.scope))];\n return uniqueScopes.map(scope => getScopeManageActionPermission(scope));\n }, [userAssignments]);\n\n const {\n data: permissionsToManageScope,\n } = useValidateUserPermissionsNonSuspense(deletePermissions);\n\n const rowsWithPermissions = useMemo(() => {\n if (!permissionsToManageScope) return userAssignments;\n\n return userAssignments.map(assignment => {\n const canManageScope = permissionsToManageScope.some(\n permission => permission.scope === assignment.scope && permission.allowed,\n );\n return {\n ...assignment,\n canManageScope,\n };\n });\n }, [userAssignments, permissionsToManageScope]);\n\n const fetchData = useMemo(() => handleTableFetch, [handleTableFetch]);\n\n useEffect(() => {\n if (!user && !isLoadingUser) {\n if (!isErrorUser || getHttpErrorStatus(errorUser) === 404) {\n navigate(AUTHZ_HOME_PATH);\n }\n }\n }, [user, isLoadingUser, navigate, isErrorUser, errorUser]);\n\n const handleShowConfirmDeletionModal = useCallback((role: RoleToDelete) => {\n if (isRevokingUserRolePending) return;\n\n setRoleToDelete(role);\n setShowConfirmDeletionModal(true);\n }, [isRevokingUserRolePending]);\n\n const navLinks = useMemo(() => [\n {\n label: formatMessage(baseMessages['authz.management.home.nav.link']),\n to: AUTHZ_HOME_PATH,\n },\n ], [formatMessage]);\n\n const additionalColumns = useMemo(() => [\n {\n id: 'view_permissions',\n Header: '',\n Cell: ViewAllPermissionsCell,\n },\n {\n id: 'action',\n Header: formatMessage(messages['authz.user.table.action.column.header']),\n Cell: createActionsCell({\n onClickDeleteButton: handleShowConfirmDeletionModal,\n isUserAuthenticatedPage: username === authenticatedUser?.username,\n isCourseEnabled,\n }),\n },\n ], [authenticatedUser?.username, formatMessage, handleShowConfirmDeletionModal, username, isCourseEnabled]);\n\n const columns = useMemo(() => [\n {\n Header: getCellHeader('role', formatMessage(messages['authz.user.table.role.column.header']), columnsWithFiltersApplied),\n accessor: 'role',\n Cell: RoleCell,\n filter: 'includesValue',\n Filter: RolesFilter,\n filterButtonText: formatMessage(messages['authz.user.table.role.column.header']),\n filterOrder: 2,\n },\n {\n Header: getCellHeader('org', formatMessage(messages['authz.user.table.organization.column.header']), columnsWithFiltersApplied),\n accessor: 'org',\n Cell: OrgCell,\n filter: 'includesValue',\n Filter: OrgFilter,\n filterButtonText: formatMessage(messages['authz.user.table.organization.column.header']),\n filterOrder: 1,\n },\n {\n Header: getCellHeader('scope', formatMessage(messages['authz.user.table.scope.column.header']), columnsWithFiltersApplied),\n accessor: 'scope',\n Cell: ScopeCell,\n disableFilters: true,\n\n },\n {\n Header: formatMessage(messages['authz.user.table.permissions.column.header']),\n Cell: PermissionsCell,\n disableFilters: true,\n disableSortBy: true,\n },\n ], [formatMessage, columnsWithFiltersApplied]);\n\n const pageCount = Math.ceil(count / TABLE_DEFAULT_PAGE_SIZE);\n\n const handleCloseConfirmDeletionModal = () => {\n setRoleToDelete(null);\n setShowConfirmDeletionModal(false);\n };\n\n const handleRevokeUserRole = () => {\n if (!user || !roleToDelete) return;\n\n const data = {\n users: user.username,\n role: roleToDelete.role,\n scope: roleToDelete.scope,\n };\n\n const runRevokeRole = (variables: { data: RevokeUserRolesRequest }) => {\n const variablesData = {\n data: {\n ...variables.data,\n querySettings,\n },\n\n };\n revokeUserRoles(variablesData, {\n onSuccess: (response) => {\n const { errors } = response;\n\n if (errors.length) {\n showToast({\n type: 'error',\n message: formatMessage(\n baseMessages['authz.team.toast.default.error.message'],\n { Bold, Br },\n ),\n });\n return;\n }\n\n const remainingRolesCount = count ? count - 1 : 0;\n showToast({\n message: formatMessage(\n baseMessages['authz.team.remove.user.toast.success.description'],\n {\n role: roleToDelete.name ?? roleToDelete.role,\n rolesCount: remainingRolesCount,\n },\n ),\n type: 'success',\n });\n handleCloseConfirmDeletionModal();\n if (remainingRolesCount === 0) {\n navigate(AUTHZ_HOME_PATH);\n }\n },\n onError: (error, retryVariables) => {\n showErrorToast(error, () => runRevokeRole(retryVariables));\n },\n });\n };\n\n runRevokeRole({ data });\n };\n\n return (\n <>\n <ConfirmDeletionModal\n isOpen={showConfirmDeletionModal}\n close={handleCloseConfirmDeletionModal}\n onSave={handleRevokeUserRole}\n isDeleting={isRevokingUserRolePending}\n context={{\n userName: user?.username || '',\n scope: roleToDelete?.scope || '',\n role: roleToDelete?.role || '',\n name: roleToDelete?.name || '',\n rolesCount: count || 0,\n }}\n />\n <AuthZLayout\n navLinks={navLinks}\n activeLabel={user?.username || ''}\n pageTitle={user?.username || ''}\n pageSubtitle={user?.email || ''}\n actions={\n [\n <AddRoleButton presetUsername={user?.username} key=\"add-role-button\" />,\n ]\n }\n showDivider\n >\n <div className=\"page-band py-3\">\n <DataTable\n isPaginated\n isFilterable\n isSortable\n manualPagination\n data={rowsWithPermissions}\n manualFilters\n manualSortBy\n fetchData={fetchData}\n itemCount={count}\n pageCount={pageCount}\n initialState={{ pageSize: TABLE_DEFAULT_PAGE_SIZE }}\n additionalColumns={additionalColumns}\n columns={columns}\n isLoading={isLoadingUserAssignments}\n isExpandable\n renderRowSubComponent={({ row }) => (\n <UserPermissions row={row} />\n )}\n >\n <TableControlBar onFilterChange={setColumnsWithFiltersApplied} />\n <DataTable.Table />\n <TableFooter />\n </DataTable>\n </div>\n </AuthZLayout>\n </>\n );\n};\n\nexport default AuditUserPage;\n"]}
|
|
@@ -36,7 +36,7 @@ const AuthzHome = () => {
|
|
|
36
36
|
if (!isCourseViewAllowed && !isLibraryViewAllowed) {
|
|
37
37
|
throw new Error(CustomErrors.NO_ACCESS);
|
|
38
38
|
}
|
|
39
|
-
return (_jsx(AuthZLayout, { pageTitle: pageTitle, actions: [_jsx(AddRoleButton, {}, "add-role-button")], children: _jsxs(Tabs, { variant: "tabs", defaultActiveKey: hash ? 'permissionsRoles' : 'team', className: "page-band bg-light-100", children: [_jsx(Tab, { eventKey: "team", title: intl.formatMessage(messages['authz.tabs.team']), className: "page-band py-
|
|
39
|
+
return (_jsx(AuthZLayout, { pageTitle: pageTitle, actions: [_jsx(AddRoleButton, {}, "add-role-button")], children: _jsxs(Tabs, { variant: "tabs", defaultActiveKey: hash ? 'permissionsRoles' : 'team', className: "page-band bg-light-100", children: [_jsx(Tab, { eventKey: "team", title: intl.formatMessage(messages['authz.tabs.team']), className: "page-band py-3", children: _jsx(TeamMembersTable, { presetScope: presetScope }) }), _jsx(Tab, { id: "libraries-permissions-roles-tab", eventKey: "permissionsRoles", title: intl.formatMessage(messages['authz.tabs.permissionsRoles']), className: "page-band py-3", children: _jsx(RolesPermissions, {}) })] }) }));
|
|
40
40
|
};
|
|
41
41
|
export default AuthzHome;
|
|
42
42
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/authz-home/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,aAAa,MAAM,4CAA4C,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,gBAAgB,MAAM,sDAAsD,CAAC;AACpF,OAAO,WAAW,MAAM,0CAA0C,CAAC;AAEnE,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,SAAS,GAAG,GAAG,EAAE;;IACrB,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,YAAY,CAAC,GAAG,eAAe,EAAE,CAAC;IAEzC;;MAEE;IACF,MAAM,WAAW,GAAG,CAAA,MAAA,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,0CAAE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,KAAI,SAAS,CAAC;IAEhF,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAE1E,MAAM,EACJ,mBAAmB,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,GAC3E,GAAG,sBAAsB,EAAE,CAAC;IAE7B;;;;;;;;OAQG;IACH,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO,KAAC,WAAW,KAAG,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,mBAAmB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CACL,KAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,OAAO,EACL,CAAC,KAAC,aAAa,MAAK,iBAAiB,CAAG,CAAC,YAG3C,MAAC,IAAI,IACH,OAAO,EAAC,MAAM,EACd,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,EACpD,SAAS,EAAC,wBAAwB,aAElC,KAAC,GAAG,IAAC,QAAQ,EAAC,MAAM,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAC,gBAAgB,YACrG,KAAC,gBAAgB,IAAC,WAAW,EAAE,WAAW,GAAI,GAC1C,EACN,KAAC,GAAG,IAAC,EAAE,EAAC,iCAAiC,EAAC,QAAQ,EAAC,kBAAkB,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC,EAAE,SAAS,EAAC,gBAAgB,YAClK,KAAC,gBAAgB,KAAG,GAChB,IACD,GACK,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Tab, Tabs } from '@openedx/paragon';\nimport { useLocation, useSearchParams } from 'react-router-dom';\nimport { TeamMembersTable } from '@src/authz-module/team-members';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { CustomErrors } from '@src/constants';\nimport LoadingPage from '@src/components/LoadingPage';\nimport RolesPermissions from '@src/authz-module/roles-permissions/RolesPermissions';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\n\nimport messages from './messages';\n\nconst AuthzHome = () => {\n const { hash } = useLocation();\n const intl = useIntl();\n const [searchParams] = useSearchParams();\n\n /* In the authoring repository the scope is encoded but this is to Replace spaces with '+'\n to match URL encoding format in case the 'scope' parameter is provided with spaces instead of '+'\n */\n const presetScope = searchParams.get('scope')?.replace(/\\s/g, '+') || undefined;\n\n const pageTitle = intl.formatMessage(messages['authz.manage.page.title']);\n\n const {\n isCourseViewAllowed, isLibraryViewAllowed, isLoading: isLoadingPermissions,\n } = useViewTeamPermissions();\n\n /**\n * It gates the whole page whether the user is allowed to view the team members. If\n * the user is not allowed, an error is thrown to display the access denied message.\n *\n * Rendering is held until the check settles rather than started optimistically, so a\n * user who turns out to be denied never fires the listing and filter requests behind\n * the page. Both flags read false while it is in flight, which would otherwise deny\n * everyone for a frame.\n */\n if (isLoadingPermissions) {\n return <LoadingPage />;\n }\n\n if (!isCourseViewAllowed && !isLibraryViewAllowed) {\n throw new Error(CustomErrors.NO_ACCESS);\n }\n\n return (\n <AuthZLayout\n pageTitle={pageTitle}\n actions={\n [<AddRoleButton key=\"add-role-button\" />]\n }\n >\n <Tabs\n variant=\"tabs\"\n defaultActiveKey={hash ? 'permissionsRoles' : 'team'}\n className=\"page-band bg-light-100\"\n >\n <Tab eventKey=\"team\" title={intl.formatMessage(messages['authz.tabs.team'])} className=\"page-band py-
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz-module/authz-home/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,aAAa,MAAM,4CAA4C,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,gBAAgB,MAAM,sDAAsD,CAAC;AACpF,OAAO,WAAW,MAAM,0CAA0C,CAAC;AAEnE,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,SAAS,GAAG,GAAG,EAAE;;IACrB,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,YAAY,CAAC,GAAG,eAAe,EAAE,CAAC;IAEzC;;MAEE;IACF,MAAM,WAAW,GAAG,CAAA,MAAA,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,0CAAE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,KAAI,SAAS,CAAC;IAEhF,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAE1E,MAAM,EACJ,mBAAmB,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,GAC3E,GAAG,sBAAsB,EAAE,CAAC;IAE7B;;;;;;;;OAQG;IACH,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO,KAAC,WAAW,KAAG,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,mBAAmB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CACL,KAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,OAAO,EACL,CAAC,KAAC,aAAa,MAAK,iBAAiB,CAAG,CAAC,YAG3C,MAAC,IAAI,IACH,OAAO,EAAC,MAAM,EACd,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,EACpD,SAAS,EAAC,wBAAwB,aAElC,KAAC,GAAG,IAAC,QAAQ,EAAC,MAAM,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAC,gBAAgB,YACrG,KAAC,gBAAgB,IAAC,WAAW,EAAE,WAAW,GAAI,GAC1C,EACN,KAAC,GAAG,IAAC,EAAE,EAAC,iCAAiC,EAAC,QAAQ,EAAC,kBAAkB,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC,EAAE,SAAS,EAAC,gBAAgB,YAClK,KAAC,gBAAgB,KAAG,GAChB,IACD,GACK,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Tab, Tabs } from '@openedx/paragon';\nimport { useLocation, useSearchParams } from 'react-router-dom';\nimport { TeamMembersTable } from '@src/authz-module/team-members';\nimport AddRoleButton from '@src/authz-module/components/AddRoleButton';\nimport { useViewTeamPermissions } from '@src/authz-module/hooks/useViewTeamPermissions';\nimport { CustomErrors } from '@src/constants';\nimport LoadingPage from '@src/components/LoadingPage';\nimport RolesPermissions from '@src/authz-module/roles-permissions/RolesPermissions';\nimport AuthZLayout from '@src/authz-module/components/AuthZLayout';\n\nimport messages from './messages';\n\nconst AuthzHome = () => {\n const { hash } = useLocation();\n const intl = useIntl();\n const [searchParams] = useSearchParams();\n\n /* In the authoring repository the scope is encoded but this is to Replace spaces with '+'\n to match URL encoding format in case the 'scope' parameter is provided with spaces instead of '+'\n */\n const presetScope = searchParams.get('scope')?.replace(/\\s/g, '+') || undefined;\n\n const pageTitle = intl.formatMessage(messages['authz.manage.page.title']);\n\n const {\n isCourseViewAllowed, isLibraryViewAllowed, isLoading: isLoadingPermissions,\n } = useViewTeamPermissions();\n\n /**\n * It gates the whole page whether the user is allowed to view the team members. If\n * the user is not allowed, an error is thrown to display the access denied message.\n *\n * Rendering is held until the check settles rather than started optimistically, so a\n * user who turns out to be denied never fires the listing and filter requests behind\n * the page. Both flags read false while it is in flight, which would otherwise deny\n * everyone for a frame.\n */\n if (isLoadingPermissions) {\n return <LoadingPage />;\n }\n\n if (!isCourseViewAllowed && !isLibraryViewAllowed) {\n throw new Error(CustomErrors.NO_ACCESS);\n }\n\n return (\n <AuthZLayout\n pageTitle={pageTitle}\n actions={\n [<AddRoleButton key=\"add-role-button\" />]\n }\n >\n <Tabs\n variant=\"tabs\"\n defaultActiveKey={hash ? 'permissionsRoles' : 'team'}\n className=\"page-band bg-light-100\"\n >\n <Tab eventKey=\"team\" title={intl.formatMessage(messages['authz.tabs.team'])} className=\"page-band py-3\">\n <TeamMembersTable presetScope={presetScope} />\n </Tab>\n <Tab id=\"libraries-permissions-roles-tab\" eventKey=\"permissionsRoles\" title={intl.formatMessage(messages['authz.tabs.permissionsRoles'])} className=\"page-band py-3\">\n <RolesPermissions />\n </Tab>\n </Tabs>\n </AuthZLayout>\n );\n};\n\nexport default AuthzHome;\n"]}
|
|
@@ -19,7 +19,7 @@ import AuthZTitle from './AuthZTitle';
|
|
|
19
19
|
*/
|
|
20
20
|
const AuthZLayout = (_a) => {
|
|
21
21
|
var { children } = _a, titleProps = __rest(_a, ["children"]);
|
|
22
|
-
return (_jsxs("div", { className: "authz-module", children: [_jsx(AuthZTitle, Object.assign({}, titleProps)),
|
|
22
|
+
return (_jsxs("div", { className: "authz-module", children: [_jsx(AuthZTitle, Object.assign({}, titleProps)), children] }));
|
|
23
23
|
};
|
|
24
24
|
export default AuthZLayout;
|
|
25
25
|
//# sourceMappingURL=AuthZLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthZLayout.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZLayout.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,UAA+B,MAAM,cAAc,CAAC;AAM3D;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,EAA6C,EAAE,EAAE;QAAjD,EAAE,QAAQ,OAAmC,EAA9B,UAAU,cAAzB,YAA2B,CAAF;IAAyB,OAAA,CACrE,eAAK,SAAS,EAAC,cAAc,aAC3B,KAAC,UAAU,oBAAK,UAAU,EAAI,
|
|
1
|
+
{"version":3,"file":"AuthZLayout.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZLayout.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,UAA+B,MAAM,cAAc,CAAC;AAM3D;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,EAA6C,EAAE,EAAE;QAAjD,EAAE,QAAQ,OAAmC,EAA9B,UAAU,cAAzB,YAA2B,CAAF;IAAyB,OAAA,CACrE,eAAK,SAAS,EAAC,cAAc,aAC3B,KAAC,UAAU,oBAAK,UAAU,EAAI,EAC7B,QAAQ,IACL,CACP,CAAA;CAAA,CAAC;AAEF,eAAe,WAAW,CAAC","sourcesContent":["import { ReactNode } from 'react';\nimport AuthZTitle, { AuthZTitleProps } from './AuthZTitle';\n\ninterface AuthZLayoutProps extends AuthZTitleProps {\n children: ReactNode;\n}\n\n/**\n * Page chrome for the authz module: the title band, then the body below it.\n * The body only paints its colour, edge to edge. Each page marks the parts of its\n * content that should line up with the header using `page-band`, so anything meant\n * to bleed across the full width -- a stepper header, a toolbar -- simply omits it.\n */\nconst AuthZLayout = ({ children, ...titleProps }: AuthZLayoutProps) => (\n <div className=\"authz-module\">\n <AuthZTitle {...titleProps} />\n {children}\n </div>\n);\n\nexport default AuthZLayout;\n"]}
|
|
@@ -14,7 +14,8 @@ export interface AuthZTitleProps {
|
|
|
14
14
|
pageSubtitle?: string | ReactNode;
|
|
15
15
|
navLinks?: BreadcrumbLink[];
|
|
16
16
|
actions?: (Action | ReactNode)[];
|
|
17
|
+
showDivider?: boolean;
|
|
17
18
|
}
|
|
18
19
|
export declare const ActionButton: ({ label, icon, onClick }: Action) => import("react").JSX.Element;
|
|
19
|
-
declare const AuthZTitle: ({ activeLabel, navLinks, pageTitle, pageSubtitle, actions, }: AuthZTitleProps) => import("react").JSX.Element;
|
|
20
|
+
declare const AuthZTitle: ({ activeLabel, navLinks, pageTitle, pageSubtitle, actions, showDivider, }: AuthZTitleProps) => import("react").JSX.Element;
|
|
20
21
|
export default AuthZTitle;
|
|
@@ -3,10 +3,10 @@ import { isValidElement, Fragment, } from 'react';
|
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
4
|
import { Breadcrumb, Col, Row, Button, Stack, useMediaQuery, breakpoints, } from '@openedx/paragon';
|
|
5
5
|
export const ActionButton = ({ label, icon, onClick }) => (_jsx(Button, { size: "sm", iconBefore: icon, onClick: onClick, children: label }));
|
|
6
|
-
const AuthZTitle = ({ activeLabel, navLinks = [], pageTitle, pageSubtitle, actions = [], }) => {
|
|
6
|
+
const AuthZTitle = ({ activeLabel, navLinks = [], pageTitle, pageSubtitle, actions = [], showDivider = false, }) => {
|
|
7
7
|
const shouldRenderBreadcrumb = activeLabel || (navLinks === null || navLinks === void 0 ? void 0 : navLinks.length) > 0;
|
|
8
8
|
const isDesktop = useMediaQuery({ minWidth: breakpoints.large.minWidth });
|
|
9
|
-
return (_jsxs("div", { className:
|
|
9
|
+
return (_jsxs("div", { className: `page-band py-4 bg-light-100${showDivider ? ' title-border-bottom' : ''}`, children: [shouldRenderBreadcrumb
|
|
10
10
|
&& (_jsx(Breadcrumb, { linkAs: Link, links: navLinks, activeLabel: activeLabel })), _jsxs(Row, { children: [_jsx(Col, { xs: 12, md: 7, children: _jsxs("div", { className: "d-flex align-items-center flex-column-sm mb-3 mb-md-0", children: [_jsx("h2", { className: "text-primary mb-0", children: pageTitle }), pageSubtitle && (_jsxs(_Fragment, { children: [_jsx("hr", { className: "authz-action-divider mx-lg-3 my-md-0 mx-md-3" }), typeof pageSubtitle === 'string'
|
|
11
11
|
? _jsx("h3", { className: "mb-0 font-weight-light text-gray-700", children: pageSubtitle })
|
|
12
12
|
: _jsx("div", { className: "mb-0", children: pageSubtitle })] }))] }) }), _jsx(Col, { xs: 12, md: 5, children: _jsx(Stack, { className: "justify-content-end", direction: isDesktop ? 'horizontal' : 'vertical', children: actions.map((action, index) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthZTitle.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZTitle.tsx"],"names":[],"mappings":";AAAA,OAAO,EACU,cAAc,EAAa,QAAQ,GACnD,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EACL,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAC5B,KAAK,EACL,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthZTitle.js","sourceRoot":"","sources":["../../../src/authz-module/components/AuthZTitle.tsx"],"names":[],"mappings":";AAAA,OAAO,EACU,cAAc,EAAa,QAAQ,GACnD,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EACL,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAC5B,KAAK,EACL,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAsB1B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAU,EAAE,EAAE,CAAC,CAChE,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,OAAO,YAEf,KAAK,GACC,CACV,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAClB,WAAW,EAAE,QAAQ,GAAG,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,GAAG,EAAE,EAAE,WAAW,GAAG,KAAK,GACtE,EAAE,EAAE;IACpB,MAAM,sBAAsB,GAAG,WAAW,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,IAAG,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1E,OAAO,CACL,eAAK,SAAS,EAAE,8BAA8B,WAAW,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,EAAE,aACrF,sBAAsB;mBACrB,CACD,KAAC,UAAU,IACT,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,WAAW,GACxB,CACH,EACD,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,eAAK,SAAS,EAAC,uDAAuD,aACpE,aAAI,SAAS,EAAC,mBAAmB,YAAE,SAAS,GAAM,EACjD,YAAY,IAAI,CACf,8BACE,aAAI,SAAS,EAAC,8CAA8C,GAAG,EAC9D,OAAO,YAAY,KAAK,QAAQ;4CAC/B,CAAC,CAAC,aAAI,SAAS,EAAC,sCAAsC,YAAE,YAAY,GAAM;4CAC1E,CAAC,CAAC,cAAK,SAAS,EAAC,MAAM,YAAE,YAAY,GAAO,IAC7C,CACJ,IAEG,GACF,EACN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,KAAC,KAAK,IAAC,SAAS,EAAC,qBAAqB,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,YAEnF,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gCAC5B,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC;oCACpC,CAAC,CAAC,MAAM;oCACR,CAAC,CAAC,KAAC,YAAY,oBAAK,MAAgB,EAAI,CAAC;gCAC3C,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC;oCAChC,CAAC,CAAC,MAAM,CAAC,GAAG;oCACZ,CAAC,CAAE,MAAiB,CAAC,KAAK,CAAC;gCAC7B,OAAO,CACL,MAAC,QAAQ,eACN,OAAO,EACP,CAAC,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;4CACpC,CAAC,CAAC,CAAC,aAAI,SAAS,EAAC,8BAA8B,GAAG,CAAC,KAHxC,uBAAuB,GAAG,EAAE,CAIhC,CACZ,CAAC;4BACJ,CAAC,CAAC,GAEE,GACJ,IACF,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import {\n ComponentType, isValidElement, ReactNode, Fragment,\n} from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n Breadcrumb, Col, Row, Button,\n Stack,\n useMediaQuery,\n breakpoints,\n} from '@openedx/paragon';\n\ninterface BreadcrumbLink {\n label: string;\n to?: string;\n}\n\ninterface Action {\n label: string;\n icon?: ComponentType;\n onClick: () => void;\n}\n\nexport interface AuthZTitleProps {\n activeLabel?: string;\n pageTitle: string;\n pageSubtitle?: string | ReactNode;\n navLinks?: BreadcrumbLink[];\n actions?: (Action | ReactNode)[];\n showDivider?: boolean;\n}\n\nexport const ActionButton = ({ label, icon, onClick }: Action) => (\n <Button\n size=\"sm\"\n iconBefore={icon}\n onClick={onClick}\n >\n {label}\n </Button>\n);\n\nconst AuthZTitle = ({\n activeLabel, navLinks = [], pageTitle, pageSubtitle, actions = [], showDivider = false,\n}: AuthZTitleProps) => {\n const shouldRenderBreadcrumb = activeLabel || navLinks?.length > 0;\n const isDesktop = useMediaQuery({ minWidth: breakpoints.large.minWidth });\n return (\n <div className={`page-band py-4 bg-light-100${showDivider ? ' title-border-bottom' : ''}`}>\n { shouldRenderBreadcrumb\n && (\n <Breadcrumb\n linkAs={Link}\n links={navLinks}\n activeLabel={activeLabel}\n />\n )}\n <Row>\n <Col xs={12} md={7}>\n <div className=\"d-flex align-items-center flex-column-sm mb-3 mb-md-0\">\n <h2 className=\"text-primary mb-0\">{pageTitle}</h2>\n {pageSubtitle && (\n <>\n <hr className=\"authz-action-divider mx-lg-3 my-md-0 mx-md-3\" />\n {typeof pageSubtitle === 'string'\n ? <h3 className=\"mb-0 font-weight-light text-gray-700\">{pageSubtitle}</h3>\n : <div className=\"mb-0\">{pageSubtitle}</div>}\n </>\n )}\n\n </div>\n </Col>\n <Col xs={12} md={5}>\n <Stack className=\"justify-content-end\" direction={isDesktop ? 'horizontal' : 'vertical'}>\n {\n actions.map((action, index) => {\n const content = isValidElement(action)\n ? action\n : <ActionButton {...action as Action} />;\n const key = isValidElement(action)\n ? action.key\n : (action as Action).label;\n return (\n <Fragment key={`authz-header-action-${key}`}>\n {content}\n {(index === actions.length - 1) ? null\n : (<hr className=\"authz-action-divider mx-lg-5\" />)}\n </Fragment>\n );\n })\n }\n </Stack>\n </Col>\n </Row>\n </div>\n );\n};\n\nexport default AuthZTitle;\n"]}
|
|
@@ -12,7 +12,7 @@ const PermissionTable = ({ permissionsTable, roles, title }) => {
|
|
|
12
12
|
// Only the narrowest viewports are too small for the matrix, so the card scrolls there
|
|
13
13
|
// (see `.permission-table-scroll`). Above that it is not a scroll container, which is
|
|
14
14
|
// what lets the header row stick to the viewport as the page scrolls.
|
|
15
|
-
_jsx(Card, { className: "permission-table-scroll", children: _jsxs("table", { className: "permission-table w-100", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "sticky-top bg-white px-4 py-3", children: title }), roles.map(role => (_jsx("th", { className: `text-center py-3 sticky-top bg-white ${role.disabled ? 'text-gray-200' : ''}`, children: role.disabled ? (_jsx(OverlayTrigger, { placement: "top", overlay: (_jsx(Tooltip, { id: `tooltip-${role.name}`, variant: "light", children: formatMessage(messages['authz.role.card.permission.for.role.status.disabled']) })), children: _jsx("span", { style: { cursor: 'help' }, children: role.name }) })) : (role.name) }, role.name)))] }) }), _jsx("tbody", { children: permissionsTable.map(resourceGroup => (_jsxs(React.Fragment, { children: [_jsx("tr", { className: "bg-info-100 text-primary", children: _jsx("td", { colSpan: roles.length + 1, className: "text-start py-3 px-4", children: _jsxs("div", { className: "d-flex align-items-center", children: [resourceGroup.icon && _jsx(Icon, { className: "d-inline-block mr-2", size: "xs", src: resourceGroup.icon }), _jsx("strong", { children: resourceGroup.label }), _jsx(ResourceTooltip, { resourceGroup: resourceGroup })] }) }) }), resourceGroup.permissions.map(permission => (_jsxs("tr", { className: "border-top", children: [_jsxs("td", { className: "text-start d-flex align-items-center small px-4 py-3", children: [_jsx(Icon, { className: "d-inline-block mr-2", size: "sm", src: actionsDictionary[permission.actionKey] }), permission.label] }), roles.map(role => (_jsx("td", { className: `text-center ${role.disabled ? 'text-gray-200' : ''}`, children: permission.roles[role.name]
|
|
15
|
+
_jsx(Card, { className: "permission-table-scroll", children: _jsxs("table", { className: "permission-table w-100", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "sticky-top bg-white px-4 py-3", children: title }), roles.map(role => (_jsx("th", { className: `text-center py-3 sticky-top bg-white ${role.disabled ? 'text-gray-200' : ''}`, children: role.disabled ? (_jsx(OverlayTrigger, { placement: "top", overlay: (_jsx(Tooltip, { id: `tooltip-${role.name}`, variant: "light", children: formatMessage(messages['authz.role.card.permission.for.role.status.disabled']) })), children: _jsx("span", { style: { cursor: 'help' }, children: role.name }) })) : (role.name) }, role.name)))] }) }), _jsx("tbody", { children: permissionsTable.map(resourceGroup => (_jsxs(React.Fragment, { children: [_jsx("tr", { className: "bg-info-100 text-primary", children: _jsx("td", { colSpan: roles.length + 1, className: "text-start py-3 px-4", children: _jsxs("div", { className: "d-flex align-items-center", children: [resourceGroup.icon && _jsx(Icon, { className: "d-inline-block mr-2", size: "xs", src: resourceGroup.icon }), _jsxs("span", { className: "small", children: [" ", _jsx("strong", { children: resourceGroup.label })] }), _jsx(ResourceTooltip, { resourceGroup: resourceGroup })] }) }) }), resourceGroup.permissions.map(permission => (_jsxs("tr", { className: "border-top", children: [_jsxs("td", { className: "text-start d-flex align-items-center small px-4 py-3", children: [_jsx(Icon, { className: "d-inline-block mr-2", size: "sm", src: actionsDictionary[permission.actionKey] }), permission.label] }), roles.map(role => (_jsx("td", { className: `text-center ${role.disabled ? 'text-gray-200' : ''}`, children: permission.roles[role.name]
|
|
16
16
|
? (_jsx(Icon, { className: `d-inline-block ${role.disabled ? 'text-gray-200' : 'text-success'}`, src: Check, "aria-label": formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {
|
|
17
17
|
roleName: role.name,
|
|
18
18
|
}), screenReaderText: formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionTable.js","sourceRoot":"","sources":["../../../src/authz-module/components/PermissionTable.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,GACpC,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAQlC,MAAM,eAAe,GAAG,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAwB,EAAE,EAAE;IACnF,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO;IACL,uFAAuF;IACvF,sFAAsF;IACtF,sEAAsE;IACtE,KAAC,IAAI,IAAC,SAAS,EAAC,yBAAyB,YACvC,iBAAO,SAAS,EAAC,wBAAwB,aACvC,0BACE,yBACE,aAAI,SAAS,EAAC,+BAA+B,YAC1C,KAAK,GACH,EACJ,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CACjB,aAEE,SAAS,EAAE,wCAAwC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,YAExF,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CACf,KAAC,cAAc,IACb,SAAS,EAAC,KAAK,EACf,OAAO,EAAE,CACP,KAAC,OAAO,IACN,EAAE,EAAE,WAAW,IAAI,CAAC,IAAI,EAAE,EAC1B,OAAO,EAAC,OAAO,YAEd,aAAa,CAAC,QAAQ,CAAC,qDAAqD,CAAC,CAAC,GACvE,CACX,YAED,eAAM,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAG,IAAI,CAAC,IAAI,GAAQ,GACpC,CAClB,CAAC,CAAC,CAAC,CACF,IAAI,CAAC,IAAI,CACV,IAnBI,IAAI,CAAC,IAAI,CAoBX,CACN,CAAC,IACC,GACC,EACR,0BACG,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,CACrC,MAAC,KAAK,CAAC,QAAQ,eACb,aAAI,SAAS,EAAC,0BAA0B,YACtC,aAAI,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,SAAS,EAAC,sBAAsB,YAC7D,eAAK,SAAS,EAAC,2BAA2B,aACvC,aAAa,CAAC,IAAI,IAAI,KAAC,IAAI,IAAC,SAAS,EAAC,qBAAqB,EAAC,IAAI,EAAC,IAAI,EAAC,GAAG,EAAE,aAAa,CAAC,IAAI,GAAI,EAClG,2BAAS,aAAa,CAAC,KAAK,GAAU,
|
|
1
|
+
{"version":3,"file":"PermissionTable.js","sourceRoot":"","sources":["../../../src/authz-module/components/PermissionTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Check, Close } from '@openedx/paragon/icons';\nimport {\n Card, Icon, OverlayTrigger, Tooltip,\n} from '@openedx/paragon';\nimport { PermissionsResourceGrouped, Role } from '@src/types';\nimport { actionsDictionary } from './RoleCard/constants';\nimport ResourceTooltip from './ResourceTooltip';\nimport messages from './messages';\n\ninterface PermissionTableProps {\n roles: Role[];\n permissionsTable: PermissionsResourceGrouped[];\n title?: string;\n}\n\nconst PermissionTable = ({ permissionsTable, roles, title }: PermissionTableProps) => {\n const { formatMessage } = useIntl();\n return (\n // Only the narrowest viewports are too small for the matrix, so the card scrolls there\n // (see `.permission-table-scroll`). Above that it is not a scroll container, which is\n // what lets the header row stick to the viewport as the page scrolls.\n <Card className=\"permission-table-scroll\">\n <table className=\"permission-table w-100\">\n <thead>\n <tr>\n <th className=\"sticky-top bg-white px-4 py-3\">\n {title}\n </th>\n {roles.map(role => (\n <th\n key={role.name}\n className={`text-center py-3 sticky-top bg-white ${role.disabled ? 'text-gray-200' : ''}`}\n >\n {role.disabled ? (\n <OverlayTrigger\n placement=\"top\"\n overlay={(\n <Tooltip\n id={`tooltip-${role.name}`}\n variant=\"light\"\n >\n {formatMessage(messages['authz.role.card.permission.for.role.status.disabled'])}\n </Tooltip>\n )}\n >\n <span style={{ cursor: 'help' }}>{role.name}</span>\n </OverlayTrigger>\n ) : (\n role.name\n )}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {permissionsTable.map(resourceGroup => (\n <React.Fragment key={resourceGroup.key}>\n <tr className=\"bg-info-100 text-primary\">\n <td colSpan={roles.length + 1} className=\"text-start py-3 px-4\">\n <div className=\"d-flex align-items-center\">\n {resourceGroup.icon && <Icon className=\"d-inline-block mr-2\" size=\"xs\" src={resourceGroup.icon} />}\n <span className=\"small\"> <strong>{resourceGroup.label}</strong></span>\n <ResourceTooltip resourceGroup={resourceGroup} />\n </div>\n </td>\n </tr>\n {resourceGroup.permissions.map(permission => (\n <tr key={permission.key} className=\"border-top\">\n <td className=\"text-start d-flex align-items-center small px-4 py-3\">\n <Icon className=\"d-inline-block mr-2\" size=\"sm\" src={actionsDictionary[permission.actionKey]} />\n {permission.label}\n </td>\n {roles.map(role => (\n <td key={role.name} className={`text-center ${role.disabled ? 'text-gray-200' : ''}`}>\n {\n permission.roles[role.name]\n ? (\n <Icon\n className={`d-inline-block ${role.disabled ? 'text-gray-200' : 'text-success'}`}\n src={Check}\n aria-label={formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {\n roleName: role.name,\n })}\n screenReaderText={formatMessage(messages['authz.role.card.permission.for.role.status.granted'], {\n roleName: role.name,\n })}\n />\n )\n : (\n <Icon\n className={`d-inline-block ${role.disabled ? 'text-gray-200' : 'text-danger'}`}\n src={Close}\n aria-label={formatMessage(messages['authz.role.card.permission.for.role.status.not.granted'], {\n roleName: role.name,\n })}\n screenReaderText={formatMessage(messages['authz.role.card.permission.for.role.status.not.granted'], {\n roleName: role.name,\n })}\n />\n )\n }\n </td>\n ))}\n </tr>\n ))}\n </React.Fragment>\n ))}\n </tbody>\n </table>\n </Card>\n );\n};\n\nexport default PermissionTable;\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { MultipleChoiceFilterProps } from './types';
|
|
2
|
-
declare const MultipleChoiceFilter: ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped, isSearchable, onSearchChange, iconSrc, disabled, }: MultipleChoiceFilterProps) => import("react").JSX.Element;
|
|
2
|
+
declare const MultipleChoiceFilter: ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped, isSearchable, onSearchChange, iconSrc, disabled, size, }: MultipleChoiceFilterProps) => import("react").JSX.Element;
|
|
3
3
|
export default MultipleChoiceFilter;
|
|
@@ -4,7 +4,8 @@ import { useIntl } from '@openedx/frontend-base';
|
|
|
4
4
|
import { FilterList, Info, Search } from '@openedx/paragon/icons';
|
|
5
5
|
import { useState } from 'react';
|
|
6
6
|
import messages from '../messages';
|
|
7
|
-
|
|
7
|
+
import { validateSizeFormControl } from '../../utils';
|
|
8
|
+
const MultipleChoiceFilter = ({ filterButtonText, filterChoices, filterValue, setFilter, isGrouped = false, isSearchable = false, onSearchChange, iconSrc, disabled = false, size = 'sm', }) => {
|
|
8
9
|
const [searchValue, setSearchValue] = useState(undefined);
|
|
9
10
|
const { formatMessage } = useIntl();
|
|
10
11
|
const checkedBoxes = filterValue || [];
|
|
@@ -37,10 +38,10 @@ const MultipleChoiceFilter = ({ filterButtonText, filterChoices, filterValue, se
|
|
|
37
38
|
}, new Map());
|
|
38
39
|
return Array.from(groupedFilterChoices.values());
|
|
39
40
|
};
|
|
40
|
-
return (_jsxs(Dropdown, { className: "no-caret-dropdown filters", children: [_jsx(Dropdown.Toggle, { variant: checkedBoxes.length > 0 ? 'primary' : 'outline-primary', children: _jsxs(Stack, { direction: "horizontal", gap: 2, children: [iconSrc && _jsx(Icon, { color: "primary", src: iconSrc }), filterButtonText, checkedBoxes.length > 0 && ` (${checkedBoxes.length})`, _jsx(Icon, { color: "primary", src: FilterList })] }) }), _jsxs(Dropdown.Menu, { children: [isSearchable && (_jsx(Form.Control, { className: "m-1", type: "text", trailingElement: _jsx(Icon, { src: Search }), placeholder: formatMessage(messages['authz.table.controlbar.search']), onChange: (e) => {
|
|
41
|
+
return (_jsxs(Dropdown, { className: "no-caret-dropdown filters", children: [_jsx(Dropdown.Toggle, { variant: checkedBoxes.length > 0 ? 'primary' : 'outline-primary', size: size, children: _jsxs(Stack, { direction: "horizontal", gap: 2, children: [iconSrc && _jsx(Icon, { color: "primary", src: iconSrc }), filterButtonText, checkedBoxes.length > 0 && ` (${checkedBoxes.length})`, _jsx(Icon, { color: "primary", src: FilterList })] }) }), _jsxs(Dropdown.Menu, { children: [isSearchable && (_jsx(Form.Control, { className: "m-1", type: "text", trailingElement: _jsx(Icon, { src: Search }), placeholder: formatMessage(messages['authz.table.controlbar.search']), onChange: (e) => {
|
|
41
42
|
setSearchValue(e.target.value);
|
|
42
43
|
onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange(e.target.value);
|
|
43
|
-
}, value: searchValue })), _jsxs(Form.CheckboxSet, { className: "pgn__dropdown-filter-checkbox-group", name: filterButtonText, "aria-label": filterButtonText, value: checkedBoxes, children: [_jsx("span", { className: "small text-info-700 mt-2", children: formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length }) }), !isGrouped ? filterChoices.map(({ displayName, value, description, }) => (_jsx(Form.Checkbox, { className: "m-2 w-100", checked: checkedBoxes.includes(value), value: value, onChange: () => handleClickCheckbox(value, displayName), "aria-label": displayName, disabled: checkedBoxes.includes(value) ? false : disabled, children: _jsxs("div", { className: "d-flex flex-column", children: [_jsx("span", { className: "small", children: displayName }), description && _jsx("span", { className: "small text-muted d-block", children: description })] }) }, displayName)))
|
|
44
|
+
}, value: searchValue, size: validateSizeFormControl(size) })), _jsxs(Form.CheckboxSet, { className: "pgn__dropdown-filter-checkbox-group", name: filterButtonText, "aria-label": filterButtonText, value: checkedBoxes, children: [_jsx("span", { className: "small text-info-700 mt-2", children: formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length }) }), !isGrouped ? filterChoices.map(({ displayName, value, description, }) => (_jsx(Form.Checkbox, { className: "m-2 w-100", checked: checkedBoxes.includes(value), value: value, onChange: () => handleClickCheckbox(value, displayName), "aria-label": displayName, disabled: checkedBoxes.includes(value) ? false : disabled, children: _jsxs("div", { className: "d-flex flex-column", children: [_jsx("span", { className: "small", children: displayName }), description && _jsx("span", { className: "small text-muted d-block", children: description })] }) }, displayName)))
|
|
44
45
|
: getGroupedChoices().map(({ groupName, icon, options }) => (_jsxs("div", { children: [_jsxs("div", { className: "pgn__dropdown-filter-group-name text-info-700 d-flex align-items-center small m-2 ml-0", children: [icon && _jsx(Icon, { color: "primary", src: icon, className: "mr-2", size: "xs" }), _jsx("span", { children: groupName })] }), options.map(({ displayName, value, description }) => (_jsx(Form.Checkbox, { className: "m-2 w-100", value: value, onChange: () => handleClickCheckbox(value, displayName), disabled: checkedBoxes.includes(value) ? false : disabled, "aria-label": displayName, children: _jsxs("div", { className: "d-flex flex-column", children: [_jsx("span", { className: "small", children: displayName }), description && _jsx("span", { className: "small text-muted d-block", children: description })] }) }, displayName)))] }, groupName))), isSearchable && (_jsxs("div", { className: "d-flex align-items-center justify-content-between p-2", children: [_jsx("span", { className: "text-muted small", children: formatMessage(messages['authz.table.controlbar.filters.more.results']) }), _jsx(Icon, { className: "text-gray-300 ml-1", src: Info, size: "xs" })] }))] })] })] }));
|
|
45
46
|
};
|
|
46
47
|
export default MultipleChoiceFilter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultipleChoiceFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/MultipleChoiceFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Dropdown, Form, Icon, Stack,\n} from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { FilterList, Info, Search } from '@openedx/paragon/icons';\nimport { useState } from 'react';\nimport messages from '@src/authz-module/components/messages';\nimport { FilterChoice, MultipleChoiceFilterProps } from './types';\n\nconst MultipleChoiceFilter = ({\n filterButtonText,\n filterChoices,\n filterValue,\n setFilter,\n isGrouped = false,\n isSearchable = false,\n onSearchChange,\n iconSrc,\n disabled = false,\n}: MultipleChoiceFilterProps) => {\n const [searchValue, setSearchValue] = useState<string | undefined>(undefined);\n const { formatMessage } = useIntl();\n\n const checkedBoxes = filterValue || [];\n const handleClickCheckbox = (value, displayName) => {\n const newValue = {\n groupName: filterButtonText?.toLocaleLowerCase() || '',\n value,\n displayName,\n };\n if (checkedBoxes.includes(value)) {\n const newCheckedBoxes = checkedBoxes.filter((val) => val !== value);\n return setFilter(newCheckedBoxes, newValue);\n }\n const newCheckedBoxes = [...checkedBoxes, value];\n return setFilter(newCheckedBoxes, newValue);\n };\n\n const getGroupedChoices = () => {\n const groupedFilterChoices = filterChoices.reduce((groups, choice) => {\n const groupName = choice.groupName || 'Ungrouped';\n const icon = choice.groupIcon || undefined;\n if (!groups.has(groupName)) {\n groups.set(groupName, { groupName, options: [], icon });\n }\n groups.get(groupName)!.options.push({\n displayName: choice.displayName,\n value: choice.value,\n description: choice.description,\n });\n return groups;\n }, new Map<string, { groupName: string; options: FilterChoice[]; icon?: any }>());\n return Array.from(groupedFilterChoices.values());\n };\n\n return (\n <Dropdown className=\"no-caret-dropdown filters\">\n <Dropdown.Toggle variant={checkedBoxes.length > 0 ? 'primary' : 'outline-primary'}>\n <Stack direction=\"horizontal\" gap={2}>\n {iconSrc && <Icon color=\"primary\" src={iconSrc} />}\n {filterButtonText}\n {checkedBoxes.length > 0 && ` (${checkedBoxes.length})`}\n <Icon color=\"primary\" src={FilterList} />\n </Stack>\n </Dropdown.Toggle>\n\n <Dropdown.Menu>\n {isSearchable && (\n <Form.Control\n className=\"m-1\"\n type=\"text\"\n trailingElement={<Icon src={Search} />}\n placeholder={formatMessage(messages['authz.table.controlbar.search'])}\n onChange={(e) => {\n setSearchValue(e.target.value);\n onSearchChange?.(e.target.value);\n }}\n value={searchValue}\n />\n )}\n <Form.CheckboxSet\n className=\"pgn__dropdown-filter-checkbox-group\"\n name={filterButtonText}\n aria-label={filterButtonText}\n value={checkedBoxes}\n >\n <span className=\"small text-info-700 mt-2\">\n {formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length })}\n </span>\n {!isGrouped ? filterChoices.map(({\n displayName, value, description,\n }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n checked={checkedBoxes.includes(value)}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n aria-label={displayName}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))\n : getGroupedChoices().map(({ groupName, icon, options }) => (\n <div key={groupName}>\n <div className=\"pgn__dropdown-filter-group-name text-info-700 d-flex align-items-center small m-2 ml-0\">\n {icon && <Icon color=\"primary\" src={icon} className=\"mr-2\" size=\"xs\" />}\n <span>{groupName}</span>\n </div>\n {options.map(({ displayName, value, description }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n aria-label={displayName}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))}\n </div>\n ))}\n { isSearchable && (\n <div className=\"d-flex align-items-center justify-content-between p-2\">\n <span className=\"text-muted small\">{formatMessage(messages['authz.table.controlbar.filters.more.results'])}</span>\n <Icon className=\"text-gray-300 ml-1\" src={Info} size=\"xs\" />\n </div>\n )}\n </Form.CheckboxSet>\n </Dropdown.Menu>\n\n </Dropdown>\n );\n};\n\nexport default MultipleChoiceFilter;\n"]}
|
|
1
|
+
{"version":3,"file":"MultipleChoiceFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/MultipleChoiceFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Dropdown, Form, Icon, Stack,\n} from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { FilterList, Info, Search } from '@openedx/paragon/icons';\nimport { useState } from 'react';\nimport messages from '@src/authz-module/components/messages';\nimport { FilterChoice, MultipleChoiceFilterProps } from './types';\nimport { validateSizeFormControl } from '@src/authz-module/utils';\n\nconst MultipleChoiceFilter = ({\n filterButtonText,\n filterChoices,\n filterValue,\n setFilter,\n isGrouped = false,\n isSearchable = false,\n onSearchChange,\n iconSrc,\n disabled = false,\n size = 'sm',\n}: MultipleChoiceFilterProps) => {\n const [searchValue, setSearchValue] = useState<string | undefined>(undefined);\n const { formatMessage } = useIntl();\n\n const checkedBoxes = filterValue || [];\n const handleClickCheckbox = (value, displayName) => {\n const newValue = {\n groupName: filterButtonText?.toLocaleLowerCase() || '',\n value,\n displayName,\n };\n if (checkedBoxes.includes(value)) {\n const newCheckedBoxes = checkedBoxes.filter((val) => val !== value);\n return setFilter(newCheckedBoxes, newValue);\n }\n const newCheckedBoxes = [...checkedBoxes, value];\n return setFilter(newCheckedBoxes, newValue);\n };\n\n const getGroupedChoices = () => {\n const groupedFilterChoices = filterChoices.reduce((groups, choice) => {\n const groupName = choice.groupName || 'Ungrouped';\n const icon = choice.groupIcon || undefined;\n if (!groups.has(groupName)) {\n groups.set(groupName, { groupName, options: [], icon });\n }\n groups.get(groupName)!.options.push({\n displayName: choice.displayName,\n value: choice.value,\n description: choice.description,\n });\n return groups;\n }, new Map<string, { groupName: string; options: FilterChoice[]; icon?: any }>());\n return Array.from(groupedFilterChoices.values());\n };\n\n return (\n <Dropdown className=\"no-caret-dropdown filters\">\n <Dropdown.Toggle variant={checkedBoxes.length > 0 ? 'primary' : 'outline-primary'} size={size}>\n <Stack direction=\"horizontal\" gap={2}>\n {iconSrc && <Icon color=\"primary\" src={iconSrc} />}\n {filterButtonText}\n {checkedBoxes.length > 0 && ` (${checkedBoxes.length})`}\n <Icon color=\"primary\" src={FilterList} />\n </Stack>\n </Dropdown.Toggle>\n\n <Dropdown.Menu>\n {isSearchable && (\n <Form.Control\n className=\"m-1\"\n type=\"text\"\n trailingElement={<Icon src={Search} />}\n placeholder={formatMessage(messages['authz.table.controlbar.search'])}\n onChange={(e) => {\n setSearchValue(e.target.value);\n onSearchChange?.(e.target.value);\n }}\n value={searchValue}\n size={validateSizeFormControl(size)}\n />\n )}\n <Form.CheckboxSet\n className=\"pgn__dropdown-filter-checkbox-group\"\n name={filterButtonText}\n aria-label={filterButtonText}\n value={checkedBoxes}\n >\n <span className=\"small text-info-700 mt-2\">\n {formatMessage(messages['authz.table.controlbar.filters.items.showing'], { current: filterChoices.length, total: filterChoices.length })}\n </span>\n {!isGrouped ? filterChoices.map(({\n displayName, value, description,\n }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n checked={checkedBoxes.includes(value)}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n aria-label={displayName}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))\n : getGroupedChoices().map(({ groupName, icon, options }) => (\n <div key={groupName}>\n <div className=\"pgn__dropdown-filter-group-name text-info-700 d-flex align-items-center small m-2 ml-0\">\n {icon && <Icon color=\"primary\" src={icon} className=\"mr-2\" size=\"xs\" />}\n <span>{groupName}</span>\n </div>\n {options.map(({ displayName, value, description }) => (\n <Form.Checkbox\n className=\"m-2 w-100\"\n key={displayName}\n value={value}\n onChange={() => handleClickCheckbox(value, displayName)}\n disabled={checkedBoxes.includes(value) ? false : disabled}\n aria-label={displayName}\n >\n <div className=\"d-flex flex-column\">\n <span className=\"small\">{displayName}</span>\n { description && <span className=\"small text-muted d-block\">{description}</span> }\n </div>\n </Form.Checkbox>\n ))}\n </div>\n ))}\n { isSearchable && (\n <div className=\"d-flex align-items-center justify-content-between p-2\">\n <span className=\"text-muted small\">{formatMessage(messages['authz.table.controlbar.filters.more.results'])}</span>\n <Icon className=\"text-gray-300 ml-1\" src={Info} size=\"xs\" />\n </div>\n )}\n </Form.CheckboxSet>\n </Dropdown.Menu>\n\n </Dropdown>\n );\n};\n\nexport default MultipleChoiceFilter;\n"]}
|
|
@@ -2,6 +2,7 @@ interface SearchFilterProps {
|
|
|
2
2
|
filterValue: string;
|
|
3
3
|
setFilter: (value: string) => void;
|
|
4
4
|
placeholder: string;
|
|
5
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
6
|
}
|
|
6
|
-
declare const SearchFilter: ({ filterValue, setFilter, placeholder, }: SearchFilterProps) => import("react").JSX.Element;
|
|
7
|
+
declare const SearchFilter: ({ filterValue, setFilter, placeholder, size }: SearchFilterProps) => import("react").JSX.Element;
|
|
7
8
|
export default SearchFilter;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Form, Icon, } from '@openedx/paragon';
|
|
3
3
|
import { Search } from '@openedx/paragon/icons';
|
|
4
|
-
|
|
4
|
+
import { validateSizeFormControl } from '../../utils';
|
|
5
|
+
const SearchFilter = ({ filterValue, setFilter, placeholder, size = 'sm' }) => (_jsx(Form.Group, { className: "m-0", size: validateSizeFormControl(size), children: _jsx(Form.Control, { className: "mw-xs mr-0", trailingElement: _jsx(Icon, { src: Search }), value: filterValue || '', type: "text", onChange: e => {
|
|
5
6
|
setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
|
|
6
7
|
}, placeholder: placeholder }) }));
|
|
7
8
|
export default SearchFilter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/SearchFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,IAAI,EACJ,IAAI,GACL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"SearchFilter.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/SearchFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,IAAI,EACJ,IAAI,GACL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AASlE,MAAM,YAAY,GAAG,CAAC,EACpB,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,IAAI,EAC9B,EAAE,EAAE,CAAC,CACvB,KAAC,IAAI,CAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,IAAI,EAAE,uBAAuB,CAAC,IAAI,CAAC,YAC7D,KAAC,IAAI,CAAC,OAAO,IACX,SAAS,EAAC,YAAY,EACtB,eAAe,EAAE,KAAC,IAAI,IAAC,GAAG,EAAE,MAAM,GAAI,EACtC,KAAK,EAAE,WAAW,IAAI,EAAE,EACxB,IAAI,EAAC,MAAM,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE;YACZ,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,8CAA8C;QACxF,CAAC,EACD,WAAW,EAAE,WAAW,GACxB,GACS,CACd,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import {\n Form,\n Icon,\n} from '@openedx/paragon';\nimport { Search } from '@openedx/paragon/icons';\nimport { validateSizeFormControl } from '@src/authz-module/utils';\n\ninterface SearchFilterProps {\n filterValue: string;\n setFilter: (value: string) => void;\n placeholder: string;\n size?: 'sm' | 'md' | 'lg';\n}\n\nconst SearchFilter = ({\n filterValue, setFilter, placeholder, size = 'sm'\n}: SearchFilterProps) => (\n <Form.Group className=\"m-0\" size={validateSizeFormControl(size)}>\n <Form.Control\n className=\"mw-xs mr-0\"\n trailingElement={<Icon src={Search} />}\n value={filterValue || ''}\n type=\"text\"\n onChange={e => {\n setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely\n }}\n placeholder={placeholder}\n />\n </Form.Group>\n);\n\nexport default SearchFilter;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface FilterChoice {\n groupName?: string;\n groupIcon?: React.ComponentType;\n displayName: string;\n value: string;\n description?: string;\n}\n\nexport interface MultipleChoiceFilterProps {\n filterButtonText: string;\n filterChoices: FilterChoice[];\n filterValue: string[] | undefined;\n setFilter: (value: string[], newItem: FilterChoice) => void;\n isGrouped?: boolean;\n isSearchable?: boolean;\n onSearchChange?: (value: string) => void;\n iconSrc?: React.ComponentType | undefined;\n disabled?: boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/authz-module/components/TableControlBar/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface FilterChoice {\n groupName?: string;\n groupIcon?: React.ComponentType;\n displayName: string;\n value: string;\n description?: string;\n}\n\nexport interface MultipleChoiceFilterProps {\n filterButtonText: string;\n filterChoices: FilterChoice[];\n filterValue: string[] | undefined;\n setFilter: (value: string[], newItem: FilterChoice) => void;\n isGrouped?: boolean;\n isSearchable?: boolean;\n onSearchChange?: (value: string) => void;\n iconSrc?: React.ComponentType | undefined;\n disabled?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'inline';\n}\n"]}
|
|
@@ -3,8 +3,20 @@
|
|
|
3
3
|
.authz-module {
|
|
4
4
|
--height-action-divider: 30px;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
// Paragon scrolls the layout wrapper ≤1400px, which clips the table's box-shadow;
|
|
7
|
+
// the inner .pgn__data-table-container already handles horizontal scroll.
|
|
8
|
+
.pgn__data-table-layout-wrapper {
|
|
9
|
+
overflow-x: visible;
|
|
10
|
+
|
|
11
|
+
// A flex item won't shrink below its content by default, so without this the main
|
|
12
|
+
// column grows to the table's width and the inner container never gets to scroll.
|
|
13
|
+
.pgn__data-table-layout-main {
|
|
14
|
+
min-width: 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.title-border-bottom {
|
|
19
|
+
border-bottom: var(--pgn-size-nav-tabs-border-width) solid var(--pgn-color-nav-tabs-base-border-base);
|
|
8
20
|
}
|
|
9
21
|
|
|
10
22
|
.filters .dropdown-toggle::after {
|
|
@@ -57,9 +69,23 @@
|
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
.permission-table {
|
|
72
|
+
border-collapse: separate;
|
|
73
|
+
border-spacing: 0;
|
|
74
|
+
|
|
60
75
|
td {
|
|
61
76
|
line-height: 24px;
|
|
62
77
|
}
|
|
78
|
+
|
|
79
|
+
thead th::after {
|
|
80
|
+
content: '';
|
|
81
|
+
position: absolute;
|
|
82
|
+
top: 100%;
|
|
83
|
+
left: 0;
|
|
84
|
+
right: 0;
|
|
85
|
+
height: 6px;
|
|
86
|
+
background: linear-gradient(rgba(0, 0, 0, 0.15), transparent);
|
|
87
|
+
pointer-events: none;
|
|
88
|
+
}
|
|
63
89
|
}
|
|
64
90
|
|
|
65
91
|
// Paragon's `.overflow-auto` lives in the `paragon` cascade layer, where its `!important`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from 'react';
|
|
3
3
|
import { useIntl } from '@openedx/frontend-base';
|
|
4
|
-
import { Alert, Button, ButtonGroup,
|
|
4
|
+
import { Alert, Button, ButtonGroup, Card, Hyperlink, } from '@openedx/paragon';
|
|
5
5
|
import { coursePermissions, courseResourceTypes, courseRolesWithPermissions, } from './course/constants';
|
|
6
6
|
import { libraryRolesWithPermissions, libraryPermissions, libraryResourceTypes, } from './library/constants';
|
|
7
7
|
import AnchorButton from '../components/AnchorButton';
|
|
@@ -29,7 +29,7 @@ const RolesPermissions = () => {
|
|
|
29
29
|
});
|
|
30
30
|
return permissionsByResource;
|
|
31
31
|
}, [intl]);
|
|
32
|
-
return (_jsxs(_Fragment, { children: [
|
|
32
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Card, { className: "bg-light-200", children: [_jsx("div", { className: "px-3 py-4", children: _jsxs(ButtonGroup, { size: "md", children: [_jsx(Button, { onClick: () => setActive('courses'), variant: `${active === 'courses' ? 'primary' : 'outline-primary'}`, children: intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.tab']) }), _jsx(Button, { onClick: () => setActive('libraries'), variant: `${active === 'libraries' ? 'primary' : 'outline-primary'}`, children: intl.formatMessage(messages['authz.tabs.permissionsRoles.libraries.tab']) })] }) }), active === 'courses' && (_jsx("div", { className: "position-relative", children: _jsx(PermissionTable, { permissionsTable: coursePermissionsByResource, roles: courseRolesWithPermissions, title: intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.tab.title']) }) })), active === 'libraries' && (_jsx(PermissionTable, { permissionsTable: libraryPermissionsByResource, roles: libraryRolesWithPermissions, title: intl.formatMessage(messages['authz.tabs.permissionsRoles.libraries.tab.title']) }))] }), active === 'courses' && (_jsx(Alert, { variant: "info", className: "mt-5", children: _jsxs("div", { className: "row align-items-center", children: [_jsxs("div", { className: "col-12 col-md-7", children: [_jsx("p", { className: "text-primary font-weight-bold h4", children: intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.title']) }), _jsxs("span", { children: [_jsx("span", { className: "font-weight-bold", children: intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.note']) }), intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.description'])] })] }), _jsx("div", { className: "col-12 col-md-5 mt-3 mt-md-0", children: _jsx(Hyperlink, { className: "d-block text-right h5 font-weight-normal", destination: "https://docs.openedx.org/en/latest/educators/references/course_development/course_team_roles.html", target: "_blank", showLaunchIcon: false, isInline: true, children: intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.link']) }) })] }) })), _jsx(AnchorButton, {})] }));
|
|
33
33
|
};
|
|
34
34
|
export default RolesPermissions;
|
|
35
35
|
//# sourceMappingURL=RolesPermissions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RolesPermissions.js","sourceRoot":"","sources":["../../../src/authz-module/roles-permissions/RolesPermissions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,KAAK,EACL,MAAM,EACN,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"RolesPermissions.js","sourceRoot":"","sources":["../../../src/authz-module/roles-permissions/RolesPermissions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,KAAK,EACL,MAAM,EACN,WAAW,EACX,IAAI,EACJ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,YAAY,MAAM,2CAA2C,CAAC;AACrE,OAAO,eAAe,MAAM,8CAA8C,CAAC;AAE3E,OAAO,EAAE,+BAA+B,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEhD,MAAM,4BAA4B,GAAG,OAAO,CAAC,GAAG,EAAE;QAChD,MAAM,qBAAqB,GAAG,+BAA+B,CAAC;YAC5D,KAAK,EAAE,2BAA2B;YAClC,WAAW,EAAE,kBAAkB;YAC/B,SAAS,EAAE,oBAAoB;YAC/B,IAAI;SACL,CAAC,CAAC;QAEH,OAAO,qBAAqB,CAAC;IAC/B,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,MAAM,2BAA2B,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/C,MAAM,qBAAqB,GAAG,+BAA+B,CAAC;YAC5D,KAAK,EAAE,0BAA0B;YACjC,WAAW,EAAE,iBAAiB;YAC9B,SAAS,EAAE,mBAAmB;YAC9B,IAAI;SACL,CAAC,CAAC;QAEH,OAAO,qBAAqB,CAAC;IAC/B,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,CACL,8BACE,MAAC,IAAI,IAAC,SAAS,EAAC,cAAc,aAC5B,cAAK,SAAS,EAAC,WAAW,YACxB,MAAC,WAAW,IAAC,IAAI,EAAC,IAAI,aACpB,KAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,EACnC,OAAO,EAAE,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EAAE,YAEjE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC,GACjE,EACT,KAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,EACrC,OAAO,EAAE,GAAG,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EAAE,YAEnE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,2CAA2C,CAAC,CAAC,GACnE,IACG,GACV,EAEL,MAAM,KAAK,SAAS,IAAI,CACvB,cAAK,SAAS,EAAC,mBAAmB,YAChC,KAAC,eAAe,IACd,gBAAgB,EAAE,2BAA2B,EAC7C,KAAK,EAAE,0BAA0B,EACjC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,+CAA+C,CAAC,CAAC,GACpF,GACE,CACP,EAEA,MAAM,KAAK,WAAW,IAAI,CACzB,KAAC,eAAe,IACd,gBAAgB,EAAE,4BAA4B,EAC9C,KAAK,EAAE,2BAA2B,EAClC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iDAAiD,CAAC,CAAC,GACtF,CACH,IACI,EACN,MAAM,KAAK,SAAS,IAAI,CACvB,KAAC,KAAK,IACJ,OAAO,EAAC,MAAM,EACd,SAAS,EAAC,MAAM,YAEhB,eAAK,SAAS,EAAC,wBAAwB,aACrC,eAAK,SAAS,EAAC,iBAAiB,aAC9B,YAAG,SAAS,EAAC,kCAAkC,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iDAAiD,CAAC,CAAC,GAAK,EACrI,2BACE,eAAM,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,gDAAgD,CAAC,CAAC,GAAQ,EACzH,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,uDAAuD,CAAC,CAAC,IACjF,IACH,EACN,cAAK,SAAS,EAAC,8BAA8B,YAC3C,KAAC,SAAS,IAAC,SAAS,EAAC,0CAA0C,EAAC,WAAW,EAAC,mGAAmG,EAAC,MAAM,EAAC,QAAQ,EAAC,cAAc,EAAE,KAAK,EAAE,QAAQ,kBAC5N,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,gDAAgD,CAAC,CAAC,GACrE,GACR,IACF,GACA,CACT,EACD,KAAC,YAAY,KAAG,IACf,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { useMemo, useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport {\n Alert,\n Button,\n ButtonGroup,\n Card,\n Hyperlink,\n} from '@openedx/paragon';\n\nimport {\n coursePermissions,\n courseResourceTypes,\n courseRolesWithPermissions,\n} from './course/constants';\nimport {\n libraryRolesWithPermissions,\n libraryPermissions,\n libraryResourceTypes,\n} from './library/constants';\nimport AnchorButton from '@src/authz-module/components/AnchorButton';\nimport PermissionTable from '@src/authz-module/components/PermissionTable';\n\nimport { buildPermissionMatrixByResource } from './utils';\n\nimport messages from './messages';\n\nconst RolesPermissions = () => {\n const intl = useIntl();\n const [active, setActive] = useState('courses');\n\n const libraryPermissionsByResource = useMemo(() => {\n const permissionsByResource = buildPermissionMatrixByResource({\n roles: libraryRolesWithPermissions,\n permissions: libraryPermissions,\n resources: libraryResourceTypes,\n intl,\n });\n\n return permissionsByResource;\n }, [intl]);\n\n const coursePermissionsByResource = useMemo(() => {\n const permissionsByResource = buildPermissionMatrixByResource({\n roles: courseRolesWithPermissions,\n permissions: coursePermissions,\n resources: courseResourceTypes,\n intl,\n });\n\n return permissionsByResource;\n }, [intl]);\n\n return (\n <>\n <Card className=\"bg-light-200\">\n <div className=\"px-3 py-4\">\n <ButtonGroup size=\"md\">\n <Button\n onClick={() => setActive('courses')}\n variant={`${active === 'courses' ? 'primary' : 'outline-primary'}`}\n >\n {intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.tab'])}\n </Button>\n <Button\n onClick={() => setActive('libraries')}\n variant={`${active === 'libraries' ? 'primary' : 'outline-primary'}`}\n >\n {intl.formatMessage(messages['authz.tabs.permissionsRoles.libraries.tab'])}\n </Button>\n </ButtonGroup>\n </div>\n {/* Courses */}\n {active === 'courses' && (\n <div className=\"position-relative\">\n <PermissionTable\n permissionsTable={coursePermissionsByResource}\n roles={courseRolesWithPermissions}\n title={intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.tab.title'])}\n />\n </div>\n )}\n {/* Libraries */}\n {active === 'libraries' && (\n <PermissionTable\n permissionsTable={libraryPermissionsByResource}\n roles={libraryRolesWithPermissions}\n title={intl.formatMessage(messages['authz.tabs.permissionsRoles.libraries.tab.title'])}\n />\n )}\n </Card>\n {active === 'courses' && (\n <Alert\n variant=\"info\"\n className=\"mt-5\"\n >\n <div className=\"row align-items-center\">\n <div className=\"col-12 col-md-7\">\n <p className=\"text-primary font-weight-bold h4\">{intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.title'])}</p>\n <span>\n <span className=\"font-weight-bold\">{intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.note'])}</span>\n {intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.description'])}\n </span>\n </div>\n <div className=\"col-12 col-md-5 mt-3 mt-md-0\">\n <Hyperlink className=\"d-block text-right h5 font-weight-normal\" destination=\"https://docs.openedx.org/en/latest/educators/references/course_development/course_team_roles.html\" target=\"_blank\" showLaunchIcon={false} isInline>\n {intl.formatMessage(messages['authz.tabs.permissionsRoles.courses.alert.link'])}\n </Hyperlink>\n </div>\n </div>\n </Alert>\n )}\n <AnchorButton />\n </>\n );\n};\n\nexport default RolesPermissions;\n"]}
|
|
@@ -42,4 +42,6 @@ export const getScopeManageActionPermission = (scope) => {
|
|
|
42
42
|
scope,
|
|
43
43
|
};
|
|
44
44
|
};
|
|
45
|
+
// "md" is mapped to undefined because Paragon's Form.Control has no "md" size.
|
|
46
|
+
export const validateSizeFormControl = (size) => size === 'md' ? undefined : size;
|
|
45
47
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/authz-module/utils.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAE9F;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAE,WAAmB,EAAE,cAAwB,EAAE,EAAE;IAC/F,IAAI,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,CAC3B,gBAAM,SAAS,EAAC,oCAAoC,aAClD,KAAC,IAAI,IAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,MAAM,GAAG,EACnD,WAAW,IACP,CACR,CAAC;QACF,cAAc,CAAC,WAAW,GAAG,kBAAkB,QAAQ,EAAE,CAAC;QAC1D,cAAc,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,kBAAkB,QAAQ,EAAE,CAAC;QAC7D,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CACrD,mBAAmB,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CACtG,CAAC;AAEF,6FAA6F;AAC7F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CACrD,mBAAmB,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,OAAO;IAClD,CAAC,CAAC,2BAA2B,CAAC,mBAAmB;IACjD,CAAC,CAAC,0BAA0B,CAAC,kBAAkB,CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAa,EAAE,EAAE;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO;QACL,MAAM;QACN,KAAK;KACN,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { Icon } from '@openedx/paragon';\nimport { FilterList } from '@openedx/paragon/icons';\nimport { RESOURCE_ICONS } from './components/constants';\nimport { CONTEXT_TYPES, getScopeContextType } from './constants';\nimport { CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS } from './roles-permissions';\n\n/**\n * Returns a header value for a DataTable column that shows a filter icon\n * when the column has an active filter.\n *\n * When a filter is active, returns a **component function** with a custom\n * toString() override. This is necessary because Paragon's TableRow builds\n * cell keys via: `${cell.column.Header}${row.id}`\n *\n * - A JSX element stringifies to \"[object Object]\", causing duplicate keys.\n * - A function with a custom toString() produces a unique string per column.\n *\n * react-table's render('Header') calls the function as a component, so the\n * JSX is still rendered correctly in the table header.\n */\nexport const getCellHeader = (columnId: string, columnTitle: string, filtersApplied: string[]) => {\n if (filtersApplied.includes(columnId)) {\n const FilteredHeader = () => (\n <span className=\"d-flex flex-row align-items-center\">\n <Icon src={FilterList} size=\"sm\" className=\"mr-2\" />\n {columnTitle}\n </span>\n );\n FilteredHeader.displayName = `FilteredHeader_${columnId}`;\n FilteredHeader.toString = () => `FilteredHeader_${columnId}`;\n return FilteredHeader;\n }\n return columnTitle;\n};\n\n/**\n * Picks the course or library icon for a scope from the scope key itself.\n */\nexport const getScopeResourceIcon = (scope: string) => (\n getScopeContextType(scope) === CONTEXT_TYPES.LIBRARY ? RESOURCE_ICONS.LIBRARY : RESOURCE_ICONS.COURSE\n);\n\n/** Unrecognised scopes fall back to the course permission, as `getScopeContextType` does. */\nexport const getScopeManageAction = (scope: string) => (\n getScopeContextType(scope) === CONTEXT_TYPES.LIBRARY\n ? CONTENT_LIBRARY_PERMISSIONS.MANAGE_LIBRARY_TEAM\n : CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM\n);\n\nexport const getScopeManageActionPermission = (scope: string) => {\n const action = getScopeManageAction(scope);\n return {\n action,\n scope,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/authz-module/utils.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAE9F;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAE,WAAmB,EAAE,cAAwB,EAAE,EAAE;IAC/F,IAAI,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,CAC3B,gBAAM,SAAS,EAAC,oCAAoC,aAClD,KAAC,IAAI,IAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,MAAM,GAAG,EACnD,WAAW,IACP,CACR,CAAC;QACF,cAAc,CAAC,WAAW,GAAG,kBAAkB,QAAQ,EAAE,CAAC;QAC1D,cAAc,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,kBAAkB,QAAQ,EAAE,CAAC;QAC7D,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CACrD,mBAAmB,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CACtG,CAAC;AAEF,6FAA6F;AAC7F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CACrD,mBAAmB,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,OAAO;IAClD,CAAC,CAAC,2BAA2B,CAAC,mBAAmB;IACjD,CAAC,CAAC,0BAA0B,CAAC,kBAAkB,CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAa,EAAE,EAAE;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO;QACL,MAAM;QACN,KAAK;KACN,CAAC;AACJ,CAAC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE,EAAE,CAC9C,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC","sourcesContent":["import { Icon } from '@openedx/paragon';\nimport { FilterList } from '@openedx/paragon/icons';\nimport { RESOURCE_ICONS } from './components/constants';\nimport { CONTEXT_TYPES, getScopeContextType } from './constants';\nimport { CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS } from './roles-permissions';\n\n/**\n * Returns a header value for a DataTable column that shows a filter icon\n * when the column has an active filter.\n *\n * When a filter is active, returns a **component function** with a custom\n * toString() override. This is necessary because Paragon's TableRow builds\n * cell keys via: `${cell.column.Header}${row.id}`\n *\n * - A JSX element stringifies to \"[object Object]\", causing duplicate keys.\n * - A function with a custom toString() produces a unique string per column.\n *\n * react-table's render('Header') calls the function as a component, so the\n * JSX is still rendered correctly in the table header.\n */\nexport const getCellHeader = (columnId: string, columnTitle: string, filtersApplied: string[]) => {\n if (filtersApplied.includes(columnId)) {\n const FilteredHeader = () => (\n <span className=\"d-flex flex-row align-items-center\">\n <Icon src={FilterList} size=\"sm\" className=\"mr-2\" />\n {columnTitle}\n </span>\n );\n FilteredHeader.displayName = `FilteredHeader_${columnId}`;\n FilteredHeader.toString = () => `FilteredHeader_${columnId}`;\n return FilteredHeader;\n }\n return columnTitle;\n};\n\n/**\n * Picks the course or library icon for a scope from the scope key itself.\n */\nexport const getScopeResourceIcon = (scope: string) => (\n getScopeContextType(scope) === CONTEXT_TYPES.LIBRARY ? RESOURCE_ICONS.LIBRARY : RESOURCE_ICONS.COURSE\n);\n\n/** Unrecognised scopes fall back to the course permission, as `getScopeContextType` does. */\nexport const getScopeManageAction = (scope: string) => (\n getScopeContextType(scope) === CONTEXT_TYPES.LIBRARY\n ? CONTENT_LIBRARY_PERMISSIONS.MANAGE_LIBRARY_TEAM\n : CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM\n);\n\nexport const getScopeManageActionPermission = (scope: string) => {\n const action = getScopeManageAction(scope);\n return {\n action,\n scope,\n };\n};\n\n// \"md\" is mapped to undefined because Paragon's Form.Control has no \"md\" size.\nexport const validateSizeFormControl = (size) =>\n size === 'md' ? undefined : size;\n"]}
|