<cds-modal size="md" [open]="open" [hasScrollingContent]="false" (overlaySelected)="closeModal()">
<cds-modal-header (closeSelect)="closeModal()">
- <h4 cdsModalHeaderLabel class="cds--type-label-01">{{ accountName }}</h4>
- <h3 cdsModalHeaderHeading i18n>{{ mode }} role</h3>
+ @if (isEdit) {
+ <h4 cdsModalHeaderLabel class="cds--type-label-01" i18n>Role</h4>
+ <h3 cdsModalHeaderHeading i18n>Edit session duration</h3>
+ <p class="cds--modal-header__description cds--type-body-01 cds-mt-3" i18n>
+ Update the maximum session duration for this role.
+ </p>
+ } @else {
+ <h4 cdsModalHeaderLabel class="cds--type-label-01" i18n>User account</h4>
+ <h3 cdsModalHeaderHeading i18n>Create role</h3>
+ <p class="cds--modal-header__description cds--type-body-01 cds-mt-3" i18n>
+ Role grants temporary permissions to trusted users, applications, or services.
+ </p>
+ }
</cds-modal-header>
<form class="form" #formDir="ngForm" [formGroup]="form">
<div cdsModalContent>
+ @if (!isEdit) {
+ <!-- Account -->
+ <div class="form-item">
+ <label class="cds--label cds--type-label-01" i18n>Account</label>
+ <p class="cds--type-body-01">{{ accountName }}</p>
+ </div>
+
<!-- Role Name -->
<div class="form-item">
<cds-text-label
label="Role name"
for="role_name"
- cdRequiredField="Role name"
[invalid]="roleName.isInvalid"
[invalidText]="roleNameError"
+ helperText="Unique name used to identify this role within the account."
+ i18n-helperText
>Role name
<input
cdsText
id="role_name"
name="role_name"
formControlName="role_name"
- placeholder="Placeholder text"
+ placeholder="Enter a role name (e.g. BackupServiceRole)"
[invalid]="roleName.isInvalid"
[autofocus]="true"
modal-primary-focus
</ng-template>
</div>
+ <!-- Role (Edit only) -->
+ } @else {
+ <div class="form-item">
+ <label class="cds--label cds--type-label-01" i18n>Role</label>
+ <p class="cds--type-body-01">
+ <cds-tooltip-definition
+ align="right"
+ [description]="accountTooltip"
+ [openOnHover]="true"
+ [caret]="true"
+ [highContrast]="true"
+ [dropShadow]="true"
+ [autoAlign]="true"
+ >
+ {{ form.getValue('role_name') }}
+ </cds-tooltip-definition>
+ </p>
+ <ng-template #accountTooltip>
+ <div>
+ User account:<br />
+ <strong>{{ accountName }}</strong>
+ </div>
+ </ng-template>
+ </div>
+ }
+
<!-- Path & Assume Role Policy Document (Create only) -->
@if (!isEdit) {
<!-- Path -->
<div class="form-item">
<cds-text-label
- label="Path"
+ label="Role path"
for="role_path"
- cdRequiredField="Path"
[invalid]="rolePath.isInvalid"
[invalidText]="pathError"
- >Path
+ helperText='Specifies the hierarchy or namespace for the role. Use "/" for the root path.'
+ i18n-helperText
+ >Role path
<input
cdsText
cdValidate
id="role_path"
name="role_path"
formControlName="role_path"
- placeholder="Placeholder text"
+ placeholder="Enter path (/applications/)"
[invalid]="rolePath.isInvalid"
/>
</cds-text-label>
labelInputID="role_assume_policy_doc"
[invalid]="policyDoc.isInvalid"
[invalidText]="policyError"
- cdRequiredField="Trust Policy"
+ helperText="Defines which principals can assume this role. Enter a valid JSON policy document."
+ i18n-helperText
>Trust policy
<textarea
cdsTextArea
id="role_assume_policy_doc"
name="role_assume_policy_doc"
formControlName="role_assume_policy_doc"
- placeholder="Placeholder text"
+ placeholder="Enter a JSON trust policy document"
rows="8"
cols="200"
[invalid]="policyDoc.isInvalid"
</div>
}
- <!-- Max Session Duration (Edit only) -->
+ <!-- Maximum Session Duration (Edit only) -->
@if (isEdit) {
<div class="form-item">
<cds-number
- label="Max Session Duration (Hours)"
+ label="Maximum session duration (hours)"
cdValidate
#maxSessionDuration="cdValidate"
[invalid]="maxSessionDuration.isInvalid"
<cd-form-button-panel
(submitActionEvent)="onSubmit()"
[form]="form"
- [submitText]="mode"
+ [submitText]="isEdit ? 'Save' : 'Create'"
[modalForm]="true"
></cd-form-button-panel>
</form>
novalidate>
<div i18n="form title"
- class="form-header">{{ action | titlecase }} {{ resource | upperFirst }}
+ class="form-header cds--type-heading-04 cds-mb-5">{{ action | titlecase }} {{ resource | lowercase }}
</div>
+ <h4 class="cds--type-heading-03 cds-mb-4" i18n>Account details</h4>
+
<!-- Account Name -->
<div class="form-item">
- <cds-text-label label="Account Name"
+ <cds-text-label label="Account name"
for="acc_name"
- cdRequiredField="Account Name"
[invalid]="!accountForm.controls.name.valid && accountForm.controls.name.dirty"
[invalidText]="accountIdError"
- i18n>Account Name
+ helperText="Name must start and end in alphanumeric characters (3 to 63). Characters allowed: lowercase, numbers and nonconsecutive dots and hyphens."
+ i18n-helperText
+ i18n>Account name
<input cdsText
type="text"
- placeholder="Enter account name"
+ placeholder="for example, team-storage-01"
id="acc_name"
name="acc_name"
formControlName="name"/>
</div>
<!-- Tenant -->
<div class="form-item">
- <cds-text-label label="tenant"
+ <cds-text-label label="Tenant (optional)"
for="tenant"
- i18n>Tenant
+ helperText="Associates this account with an existing tenant namespace."
+ i18n-helperText
+ i18n>Tenant (optional)
<input cdsText
type="text"
- placeholder="Enter tenant"
+ placeholder="for example, finance-team"
id="tenant"
name="tenant"
formControlName="tenant"/>
<!-- Email -->
<div class="form-item">
- <cds-text-label label="email"
+ <cds-text-label label="Email address (optional)"
for="email"
[invalid]="!accountForm.controls.email.valid && accountForm.controls.email.dirty"
[invalidText]="emailError"
- i18n>Email
+ helperText="Contact for quota alerts and notifications."
+ i18n-helperText
+ i18n>Email address (optional)
<input cdsText
type="text"
- placeholder="Enter email"
+ placeholder="for example, admin@example.com"
id="email"
name="email"
formControlName="email"/>
</ng-template>
</div>
- <div class="form-item form-item-append"
- cdsRow>
- <div cdsCol>
- <!-- Max. bucket mode -->
- <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_buckets_mode' }"></ng-container>
- </div>
- <div cdsCol>
- <!-- Max buckets -->
- <span *ngIf="1 == accountForm.get('max_buckets_mode').value">
- <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_buckets' }"></ng-container>
- </span>
+ <div class="form-item cds-mt-5 cds-mb-3">
+ <h4 class="cds--type-heading-03" i18n>Advanced settings</h4>
+ <p class="cds--type-body-01" i18n>Configure resource limits and quota for this account</p>
+ <div class="cds-mt-3">
+ <button type="button" class="cds--btn cds--btn--ghost advanced-settings-btn" (click)="showAdvanced = !showAdvanced">
+ {{ showAdvanced ? 'Hide advanced settings' : 'Show advanced settings' }}
+ <svg cdsIcon="chevron--down" *ngIf="!showAdvanced" size="16" class="cds--btn__icon"></svg>
+ <svg cdsIcon="chevron--up" *ngIf="showAdvanced" size="16" class="cds--btn__icon"></svg>
+ </button>
</div>
</div>
- <div class="form-item form-item-append"
- cdsRow>
- <div cdsCol>
- <!-- Max. users mode -->
- <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_users_mode' }"></ng-container>
- </div>
- <div cdsCol>
- <!-- Max users -->
- <span *ngIf="1 == accountForm.get('max_users_mode').value">
- <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_users' }"></ng-container>
- </span>
- </div>
- </div>
+ <div *ngIf="showAdvanced">
+ <h5 class="cds--type-heading-02 cds-mb-2" i18n>Resource limits</h5>
+ <p class="cds--type-body-01 cds-mb-4" i18n>Set the mode and maximum allowed values for each resource type. Select Custom to specify a limit.</p>
- <div class="form-item form-item-append"
- cdsRow>
- <div cdsCol>
- <!-- Max. roles mode -->
- <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_roles_mode' }"></ng-container>
+ <div class="form-item form-item-append" cdsRow>
+ <div cdsCol>
+ <!-- Max. bucket mode -->
+ <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_buckets_mode' }"></ng-container>
+ </div>
+ <div cdsCol>
+ <!-- Max buckets -->
+ <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_buckets' }"></ng-container>
+ </div>
</div>
- <div cdsCol>
- <!-- Max roles -->
- <span *ngIf="1 == accountForm.get('max_roles_mode').value">
- <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_roles' }"></ng-container>
- </span>
- </div>
- </div>
- <div class="form-item form-item-append"
- cdsRow>
- <div cdsCol>
- <!-- Max. group mode -->
- <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_groups_mode' }"></ng-container>
+ <div class="form-item form-item-append" cdsRow>
+ <div cdsCol>
+ <!-- Max. users mode -->
+ <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_users_mode' }"></ng-container>
+ </div>
+ <div cdsCol>
+ <!-- Max users -->
+ <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_users' }"></ng-container>
+ </div>
</div>
- <div cdsCol>
- <!-- Max group -->
- <span *ngIf="1 == accountForm.get('max_groups_mode').value">
- <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_groups' }"></ng-container>
- </span>
+
+ <div class="form-item form-item-append" cdsRow>
+ <div cdsCol>
+ <!-- Max. roles mode -->
+ <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_roles_mode' }"></ng-container>
+ </div>
+ <div cdsCol>
+ <!-- Max roles -->
+ <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_roles' }"></ng-container>
+ </div>
</div>
- </div>
- <div class="form-item form-item-append"
- cdsRow>
- <div cdsCol>
- <!-- Max. acess keys mode -->
- <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_access_keys_mode' }"></ng-container>
+ <div class="form-item form-item-append" cdsRow>
+ <div cdsCol>
+ <!-- Max. group mode -->
+ <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_groups_mode' }"></ng-container>
+ </div>
+ <div cdsCol>
+ <!-- Max group -->
+ <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_groups' }"></ng-container>
+ </div>
</div>
- <div cdsCol>
- <!-- Max acess keys -->
- <span *ngIf="1 == accountForm.get('max_access_keys_mode').value">
- <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_access_keys' }"></ng-container>
- </span>
+
+ <div class="form-item form-item-append" cdsRow>
+ <div cdsCol>
+ <!-- Max. access keys mode -->
+ <ng-container *ngTemplateOutlet="selectModeTemplate;context: { formControl: 'max_access_keys_mode' }"></ng-container>
+ </div>
+ <div cdsCol>
+ <!-- Max access keys -->
+ <ng-container *ngTemplateOutlet="accountMaxValueTemplate;context: { formControl: 'max_access_keys' }"></ng-container>
+ </div>
</div>
- </div>
- <!-- Account Quota -->
- <div class="form-item">
- <ng-container *ngTemplateOutlet="quotaTemplate;context: { formControl: {
- enabled: 'account_quota_enabled',
- unlimitedSize: 'account_quota_max_size_unlimited',
- maxSize: 'account_quota_max_size',
- unlimitedObjects: 'account_quota_max_objects_unlimited',
- maxObjects: 'account_quota_max_objects'
- },
- quotaType: 'account'
- }">
- </ng-container>
- </div>
+ <h5 class="cds--type-heading-02 cds-mb-2 cds-mt-5" i18n>Quotas</h5>
+ <p class="cds--type-body-01 cds-mb-4" i18n>Define storage usage limits for the account and the buckets it owns. Quotas help control capacity consumption and enforce resource allocation policies.</p>
- <!-- Bucket Quota -->
- <div class="form-item">
- <ng-container *ngTemplateOutlet="quotaTemplate;
- context: {
- formControl: {
- enabled: 'bucket_quota_enabled',
- unlimitedSize: 'bucket_quota_max_size_unlimited',
- maxSize: 'bucket_quota_max_size',
- unlimitedObjects: 'bucket_quota_max_objects_unlimited',
- maxObjects: 'bucket_quota_max_objects'
- },
- quotaType: 'bucket'
- }">
- </ng-container>
+ <!-- Account Quota -->
+ <div class="form-item">
+ <ng-container *ngTemplateOutlet="quotaTemplate;context: { formControl: {
+ enabled: 'account_quota_enabled',
+ unlimitedSize: 'account_quota_max_size_unlimited',
+ maxSize: 'account_quota_max_size',
+ unlimitedObjects: 'account_quota_max_objects_unlimited',
+ maxObjects: 'account_quota_max_objects'
+ },
+ quotaType: 'account'
+ }">
+ </ng-container>
+ </div>
+
+ <!-- Bucket Quota -->
+ <div class="form-item">
+ <ng-container *ngTemplateOutlet="quotaTemplate;
+ context: {
+ formControl: {
+ enabled: 'bucket_quota_enabled',
+ unlimitedSize: 'bucket_quota_max_size_unlimited',
+ maxSize: 'bucket_quota_max_size',
+ unlimitedObjects: 'bucket_quota_max_objects_unlimited',
+ maxObjects: 'bucket_quota_max_objects'
+ },
+ quotaType: 'bucket'
+ }">
+ </ng-container>
+ </div>
</div>
<cd-form-button-panel (submitActionEvent)="submit()"
[form]="formDir"
- [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
+ [submitText]="(action | titlecase) + ' ' + (resource | lowercase)"
wrappingClass="text-right"></cd-form-button-panel>
</form>
<cds-select [formControlName]="formControl"
[name]="formControl"
[id]="formControl"
- label="{{formControl.split('_')[1] | upperFirst}} Mode"
+ label="{{formControl.split('_')[1] | upperFirst}} mode"
(change)="onModeChange($event.target.value, formControl)"
[helperText]="getHelperTextForMode(formControl)">
<option value="0">Unlimited</option>
<ng-template #accountMaxValueTemplate
let-formControl="formControl"
[formGroup]="accountForm">
-<cds-number [id]="formControl"
- [name]="formControl"
- formControlName="{{formControl}}"
- label="{{formControl.split('_')[0] | upperFirst}}. {{formControl.split('_').length > 2 ? formControl.split('_')[1]+' '+formControl.split('_')[2]: formControl.split('_')[1]}}"
- [min]="1"
- cdRequiredField="{{formControl.split('_')[0] | upperFirst}}. {{formControl.split('_').length > 2 ? formControl.split('_')[1]+' '+formControl.split('_')[2]: formControl.split('_')[1]}}"
- [invalid]="!accountForm.controls[formControl].valid && accountForm.controls[formControl].dirty"
- [invalidText]="maxValError"></cds-number>
+ <cds-number *ngIf="accountForm.get(formControl + '_mode').value == '1'"
+ [id]="formControl"
+ [name]="formControl"
+ formControlName="{{formControl}}"
+ label="Maximum {{formControl.replace('max_', '').replace('_', ' ')}}"
+ [min]="1"
+ [invalid]="!accountForm.controls[formControl].valid && accountForm.controls[formControl].dirty"
+ [invalidText]="maxValError"></cds-number>
+
+ <cds-text-label *ngIf="accountForm.get(formControl + '_mode').value != '1'"
+ label="Maximum {{formControl.replace('max_', '').replace('_', ' ')}}"
+ for="{{formControl}}_disabled">
+ Maximum {{formControl.replace('max_', '').replace('_', ' ')}}
+ <input cdsText
+ type="text"
+ [id]="formControl + '_disabled'"
+ name="{{formControl}}_disabled"
+ [ngModel]="'-'"
+ [ngModelOptions]="{standalone: true}"
+ [disabled]="true" />
+ </cds-text-label>
+
<ng-template #maxValError>
<span *ngIf="accountForm.showError(formControl, formDir, 'required')"
i18n>This field is required.</span>
let-quotaType="quotaType"
let-formControl="formControl"
[formGroup]="accountForm">
- <fieldset class="cds--fieldset">
- <legend class="cds--label">{{quotaType | upperFirst}} Quota</legend>
- <div *ngIf="quotaType == 'account';else bucket"
- class="quota-heading">Set quota on account owned by users.</div>
- <ng-template #bucket>
- <div class="quota-heading">
- Set quota on buckets owned by an account.
- </div>
- </ng-template>
+ <fieldset class="cds--fieldset cds-mb-4">
+ <legend class="cds--label">{{quotaType | upperFirst}} quota</legend>
<!-- Enabled -->
- <cds-checkbox [formControlName]="formControl.enabled"
- [id]="quotaType+'_checkbox'">
- Enabled
+ <cds-checkbox *ngIf="quotaType == 'account'" [formControlName]="formControl.enabled"
+ [id]="quotaType+'_checkbox'" class="cds-mb-3">
+ Enable account quota
+ </cds-checkbox >
+ <cds-checkbox *ngIf="quotaType == 'bucket'" [formControlName]="formControl.enabled"
+ [id]="quotaType+'_checkbox'" class="cds-mb-3">
+ Enable bucket quota
</cds-checkbox >
+ <p class="cds--type-body-01 cds-mb-4" *ngIf="quotaType == 'account'">Applies a storage quota to each user account.</p>
+ <p class="cds--type-body-01 cds-mb-4" *ngIf="quotaType == 'bucket'">Limits the total storage available across all buckets in an account.</p>
<div class="quota-sub-block"
*ngIf="accountForm.controls[formControl.enabled].value">
<!-- Unlimited size -->
*ngIf="accountForm.controls[formControl.enabled].value && !accountForm.getValue(formControl.unlimitedSize)">
<cds-text-label [label]="formControl.maxSize"
[for]="formControl.maxSize"
- cdRequiredField="Max. size"
[invalid]="!accountForm.controls[formControl.maxSize].valid && accountForm.controls[formControl.maxSize].dirty"
[invalidText]="quotaSizeError"
- i18n>Max. size
+ i18n>Maximum size
<input cdsText
type="text"
placeholder="Enter size"
*ngIf="accountForm.controls[formControl.enabled].value && !accountForm.getValue(formControl.unlimitedObjects)">
<cds-text-label [label]="formControl.maxObjects"
[for]="formControl.maxObjects"
- cdRequiredField="Max. objects"
[invalid]="!accountForm.controls[formControl.maxObjects].valid && accountForm.controls[formControl.maxObjects].dirty"
[invalidText]="quotaObjectError"
- i18n>Max. objects
+ i18n>Maximum objects
<input cdsText
type="number"
placeholder="Enter number of objects"