Skip to content

Task - implement grading permissions #320

Description

@MaferMazu
No description provided.

Activity

  1. bra-i-am commented on Jun 5, 2026

    @bra-i-am

    Refinement

    https://www.figma.com/design/onU2END2OXaF7RRLWEHsZI/AuthZ---v2?node-id=9145-5793&t=OrmroEXprX0NyD7D-4

    Permissions used:

    • courses.view_grading_settings
    • courses.edit_grading_settings

    Already in src/authz/constants.ts as COURSE_PERMISSIONS.VIEW_GRADING_SETTINGS / COURSE_PERMISSIONS.EDIT_GRADING_SETTINGS and in src/authz/permissionHelpers.ts as getGradingPermissions(courseId).

    Already resolved in grading-settings/GradingSettings.jsx via useCourseUserPermissions as canViewGradingSettings and canEditGradingSettings; isEditable is already derived and threaded to all child components.

    Role matrix:

    • Course Auditor (view ✅, edit ❌)
    • Course Editor (view ✅, edit ✅).

    All inputs in every subsection (GradingScale, DeadlineSection, CreditSection, AssignmentSection) are already disabled={!isEditable} — no change needed there. The three missing pieces are: the view-only banner, hiding the "Add new assignment type" button (currently disabled, must be hidden), and hiding the per-assignment "Delete" button (currently disabled, must be hidden). No new constants or helpers needed.


    UI location 1 — Grading page: view-only banner + hide "Add new assignment type" button for Course Auditor

    Files: grading-settings/messages.ts → grading-settings/GradingSettings.jsx

    grading-settings/messages.ts — add view-only alert message:

      viewOnlyAlert: {
        id: 'course-authoring.grading.alert.view-only',
        defaultMessage: 'You have view-only access to this page. Contact your organization admin to request editing permissions.',
        description: 'Alert shown to users who can view but cannot edit grading settings',
      },

    generic/sub-header/SubHeader.tsx — add banner prop (rendered after {title} inside the <h2>):

    interface SubHeaderProps {
      ...
      banner?: ReactElement | null;
      ...
    }
    
    const SubHeader = ({
      ...
      banner = null,
      ...
    }) => (
      ...
          <h2 className="sub-header-title">
            <small className="sub-header-title-subtitle">{subtitle}</small>
            {title}
            {titleActions && (
              ...
            )}
          </h2>
          {headerActions && ...}
        </header>
        {banner}
        {contentTitle && withSubHeaderContent && (

    grading-settings/GradingSettings.jsx — add Alert + Lock imports, pass banner via the new SubHeader prop, change Add button from disabled to conditionally rendered:

    // paragon imports — add Alert
    import {
      Alert,
      Button,
      Container,
      Layout,
      StatefulButton,
    } from '@openedx/paragon';
    
    // icons imports — add Lock
    import { Add as IconAdd, CheckCircle, Lock as LockIcon, Warning } from '@openedx/paragon/icons';
    
    ...
    
                      <SubHeader
                        title={intl.formatMessage(messages.headingTitle)}
                        subtitle={intl.formatMessage(messages.headingSubtitle)}
                        contentTitle={intl.formatMessage(messages.policy)}
                        description={intl.formatMessage(messages.policiesDescription)}
                        banner={!isEditable ? (
                          <Alert variant="info" icon={LockIcon}>
                            {intl.formatMessage(messages.viewOnlyAlert)}
                          </Alert>
                        ) : null}
                      />
                      <section>
                        <GradingScale ...
    
    ...
    
    // change Add button — from disabled to hidden:
                        {isEditable && (
                          <Button
                            variant="primary"
                            iconBefore={IconAdd}
                            onClick={handleAddAssignment}
                          >
                            {intl.formatMessage(messages.addNewAssignmentTypeBtn)}
                          </Button>
                        )}

    UI location 2 — Grading page: hide "Delete" button per assignment type for Course Auditor

    File: grading-settings/assignment-section/index.jsx

    grading-settings/assignment-section/index.jsx — change Delete button from disabled to conditionally rendered:

    // was:
                  <Button
                    className="course-grading-assignment-delete-btn"
                    variant="outline-primary"
                    size="sm"
                    onClick={() => handleRemoveAssignment(gradeField.id)}
                    disabled={!isEditable}
                  >
                    {intl.formatMessage(messages.assignmentDeleteButton)}
                  </Button>
    
    // change to:
                  {isEditable && (
                    <Button
                      className="course-grading-assignment-delete-btn"
                      variant="outline-primary"
                      size="sm"
                      onClick={() => handleRemoveAssignment(gradeField.id)}
                    >
                      {intl.formatMessage(messages.assignmentDeleteButton)}
                    </Button>
                  )}

    Testing implementation at https://github.com/eduNEXT/frontend-app-authoring/tree/bc/improve-grading-permissions

    Image
  2. moved this to Ready for Development in RBAC AuthZ Boardon Aug 4, 2026
  3. assigned and unassigned on Aug 10, 2026
  4. dcoa commented on Aug 10, 2026

    @dcoa
    Contributor

    Most of the implementation has been done previously. I am going to open a same PR for those that have the View Only Alert including this one.

  5. moved this from Ready for Development to In Progress in RBAC AuthZ Boardon Aug 10, 2026
  6. moved this from In Progress to Ready for Review in RBAC AuthZ Boardon Aug 10, 2026
  7. moved this from Ready for Review to Done in RBAC AuthZ Boardon Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions