|
@ -28,7 +28,7 @@
|
|||
--a11y-min-target-size: 40px;
|
||||
}
|
||||
|
||||
ion-searchbar {
|
||||
ion-searchbar {
|
||||
padding: 0;
|
||||
--height: 40px;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<ion-row class="ion-justify-content-between ion-align-items-center ion-no-padding">
|
||||
<ion-col class="addon-block-timeline-activity-main ion-no-padding">
|
||||
<ion-row class="ion-justify-content-between ion-align-items-center ion-nowrap ion-no-padding">
|
||||
<ion-col class="addon-block-timeline-activity-time ion-no-padding">
|
||||
<ion-col class="addon-block-timeline-activity-time ion-no-padding ion-text-nowrap">
|
||||
<small>{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</small>
|
||||
<core-mod-icon *ngIf="event.iconUrl" [modicon]="event.iconUrl" [componentId]="event.instance"
|
||||
[modname]="event.modulename" [purpose]="event.purpose" />
|
||||
|
|
|
@ -14,7 +14,6 @@ Feature: Test messages navigation in the app
|
|||
| teacher | C1 | editingteacher |
|
||||
| student | C1 | student |
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Avoid recursive links to profile
|
||||
Given I entered the app as "teacher"
|
||||
When I press "Messages" in the app
|
||||
|
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -58,7 +58,6 @@ Feature: Test basic usage of assignment activity in app
|
|||
Then I should find "Online text submissions" in the app
|
||||
And I should find "Submission test edited" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading
|
||||
# Submit first attempt as a student
|
||||
Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app
|
||||
|
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
@ -26,7 +26,6 @@ Feature: Users can manage entries in database activities
|
|||
| data1 | text | URL | URL link |
|
||||
| data1 | text | Description | Link description |
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Create entry
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
Then I should find "No entries yet" in the app
|
||||
|
@ -38,7 +37,6 @@ Feature: Users can manage entries in database activities
|
|||
Then I should find "https://moodle.org/" in the app
|
||||
And I should find "Moodle community site" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Browse entry
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
|
||||
|
@ -72,7 +70,6 @@ Feature: Users can manage entries in database activities
|
|||
And I should find "Moodle community site" in the app
|
||||
And I should find "Moodle Cloud" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Students can not edit or delete other user's entries from list and single view in the app
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
And I press "Add entries" in the app
|
||||
|
@ -88,7 +85,6 @@ Feature: Users can manage entries in database activities
|
|||
And "Edit" "link" should not exist
|
||||
And "Delete" "link" should not exist
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Delete entry (student) & Update entry (student)
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
And I press "Add entries" in the app
|
||||
|
@ -148,7 +144,6 @@ Feature: Users can manage entries in database activities
|
|||
And I should not find "Moodle Cloud" in the app
|
||||
And I should find "No entries yet" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Delete entry (teacher) & Update entry (teacher)
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
And I press "Add entries" in the app
|
||||
|
@ -212,7 +207,6 @@ Feature: Users can manage entries in database activities
|
|||
And I press "Delete" in the app
|
||||
And I should not find "Moodle Cloud" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Handle number 0 correctly when creating entries
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber |
|
||||
|
|
|
@ -26,7 +26,6 @@ Feature: Users can store entries in database activities when offline and sync wh
|
|||
| data1 | text | URL | URL link |
|
||||
| data1 | text | Description | Link description |
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Create entry (offline)
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
And I switch network connection to offline
|
||||
|
@ -46,7 +45,6 @@ Feature: Users can store entries in database activities when offline and sync wh
|
|||
And I should find "Moodle community site" in the app
|
||||
And I should not find "This Database has offline data to be synchronised" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Update entry (offline) & Delete entry (offline)
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
And I should find "No entries yet" in the app
|
||||
|
@ -97,7 +95,6 @@ Feature: Users can store entries in database activities when offline and sync wh
|
|||
And I should not find "Moodle Cloud" in the app
|
||||
And I should not find "This Database has offline data to be synchronised" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Students can undo deleting entries to a database in the app while offline
|
||||
Given I entered the data activity "Web links" on course "Course 1" as "student1" in the app
|
||||
And I should find "No entries yet" in the app
|
||||
|
|
|
@ -50,7 +50,6 @@ Feature: Test basic usage of forum activity in app
|
|||
Then I should find "My happy subject" in the app
|
||||
And I should find "An awesome message" inside the split-view content in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Reply a post
|
||||
Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app
|
||||
When I replace "/.*/" within ".addon-mod-forum-discussion-author p" with "[Publication date]"
|
||||
|
@ -179,7 +178,6 @@ Feature: Test basic usage of forum activity in app
|
|||
And I press "Save changes" in the app
|
||||
Then I should find "Auto-test message edited" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Delete a forum post (only online)
|
||||
Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app
|
||||
When I press "Add discussion topic" in the app
|
||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -191,7 +191,6 @@ Feature: Attempt a quiz in app
|
|||
Then I should find "The correct answer is: Berlin" in the app
|
||||
And I should find "Mark 1.00 out of 1.00" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Submit a quiz & Review a quiz attempt
|
||||
Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
|
||||
When I press "Attempt quiz now" in the app
|
||||
|
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
@ -40,8 +40,7 @@ Feature: Notifications
|
|||
| Test 30 | student2 | student1 | 1649766629 | null |
|
||||
|
||||
Scenario: Mobile navigation
|
||||
Given I enter the app
|
||||
And I log in as "student1"
|
||||
Given I entered the app as "student1"
|
||||
And I press "Notifications" in the app
|
||||
Then I should find "Test 30" in the app
|
||||
But I should not find "Test 10" in the app
|
||||
|
@ -81,9 +80,8 @@ Feature: Notifications
|
|||
|
||||
@ionic7_failure
|
||||
Scenario: Tablet navigation
|
||||
Given I enter the app
|
||||
Given I entered the app as "student1"
|
||||
And I change viewport size to "1200x640" in the app
|
||||
And I log in as "student1"
|
||||
And I press "Notifications" in the app
|
||||
Then I should find "Test 30" in the app
|
||||
But I should not find "Test 10" in the app
|
||||
|
|
|
@ -10,20 +10,20 @@
|
|||
<ion-select id="{{row.id}}" [name]="row.name" [(ngModel)]="row.selected" interface="action-sheet" [disabled]="row.disabled"
|
||||
[cancelText]="'core.cancel' | translate"
|
||||
[ngClass]="{'addon-qtype-match-correct': row.isCorrect === 1,'addon-qtype-match-incorrect': row.isCorrect === 0}">
|
||||
<div slot="label">
|
||||
<div slot="label" class="flew-row">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="row.text" [contextLevel]="contextLevel"
|
||||
[contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
<label class="accesshide" for="{{row.id}}" *ngIf="row.accessibilityLabel">
|
||||
{{ row.accessibilityLabel }}
|
||||
</label>
|
||||
<ion-icon *ngIf="row.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success" slot="end"
|
||||
[attr.aria-label]="'core.question.correct' | translate" />
|
||||
<ion-icon *ngIf="row.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger" slot="end"
|
||||
[attr.aria-label]="'core.question.incorrect' | translate" />
|
||||
</div>
|
||||
<ion-select-option *ngFor="let option of row.options" [value]="option.value">
|
||||
{{option.label}}
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
<ion-icon *ngIf="row.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success" slot="end"
|
||||
[attr.aria-label]="'core.question.correct' | translate" />
|
||||
<ion-icon *ngIf="row.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger" slot="end"
|
||||
[attr.aria-label]="'core.question.incorrect' | translate" />
|
||||
</ion-item>
|
||||
</section>
|
||||
|
|
|
@ -10,4 +10,16 @@
|
|||
.addon-qtype-match-incorrect {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
ion-select::part(label) {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
div.flew-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,21 +18,22 @@
|
|||
<ion-item class="ion-text-wrap answer" *ngFor="let option of question.options">
|
||||
<ion-checkbox [attr.name]="option.name" [(ngModel)]="option.checked" [disabled]="option.disabled"
|
||||
[color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
|
||||
<div [class]="option.class">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="option.text" [contextLevel]="contextLevel"
|
||||
[contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
<div>
|
||||
<div [class]="option.class">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
|
||||
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
</div>
|
||||
<div *ngIf="option.feedback" class="specificfeedback">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
|
||||
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
</div>
|
||||
</div>
|
||||
<ion-icon *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
|
||||
[attr.aria-label]="'core.question.correct' | translate" />
|
||||
<ion-icon *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
|
||||
[attr.aria-label]="'core.question.incorrect' | translate" />
|
||||
</ion-checkbox>
|
||||
|
||||
<ion-icon slot="end" *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
|
||||
[attr.aria-label]="'core.question.correct' | translate" />
|
||||
<ion-icon slot="end" *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
|
||||
[attr.aria-label]="'core.question.incorrect' | translate" />
|
||||
|
||||
<!-- ion-checkbox doesn't use an input. Create a hidden input to hold the value. -->
|
||||
<input type="hidden" [ngModel]="option.checked" [attr.name]="option.name">
|
||||
</ion-item>
|
||||
|
@ -43,20 +44,21 @@
|
|||
<ion-item class="ion-text-wrap answer" *ngFor="let option of question.options">
|
||||
<ion-radio [value]="option.value" [disabled]="option.disabled"
|
||||
[color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
|
||||
<div [class]="option.class">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="option.text" [contextLevel]="contextLevel"
|
||||
[contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
<div>
|
||||
<div [class]="option.class">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
|
||||
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
</div>
|
||||
<div *ngIf="option.feedback" class="specificfeedback">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
|
||||
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
|
||||
</div>
|
||||
</div>
|
||||
<ion-icon *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
|
||||
[attr.aria-label]="'core.question.correct' | translate" />
|
||||
<ion-icon *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
|
||||
[attr.aria-label]="'core.question.incorrect' | translate" />
|
||||
</ion-radio>
|
||||
|
||||
<ion-icon slot="end" *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
|
||||
[attr.aria-label]="'core.question.correct' | translate" />
|
||||
<ion-icon slot="end" *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
|
||||
[attr.aria-label]="'core.question.incorrect' | translate" />
|
||||
</ion-item>
|
||||
<ion-button *ngIf="!question.disabled" class="ion-text-wrap ion-margin-top" expand="block" fill="outline"
|
||||
[disabled]="!question.singleChoiceModel" (click)="clear()" type="button">
|
||||
|
|
|
@ -6,15 +6,24 @@
|
|||
padding: 0 .7em;
|
||||
}
|
||||
|
||||
.answer {
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.d-flex {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.answer .answernumber {
|
||||
min-width: 1.5em;
|
||||
.answer {
|
||||
line-height: 2em;
|
||||
|
||||
.answernumber {
|
||||
min-width: 1.5em;
|
||||
}
|
||||
|
||||
ion-checkbox::part(label),
|
||||
ion-radio::part(label) {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
@use "theme/globals" as *;
|
||||
|
||||
:host {
|
||||
display: contents;
|
||||
|
||||
--textarea-background: var(--core-input-background);
|
||||
--textarea-color: var(--core-input-text);
|
||||
--textarea-border-width: var(--core-input-border-width);
|
||||
|
@ -6,7 +10,6 @@
|
|||
--textarea-radius: var(--radius-xl);
|
||||
|
||||
form {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
@ -27,10 +30,15 @@
|
|||
min-height: var(--a11y-min-target-size);
|
||||
line-height: 20px;
|
||||
padding: 10px;
|
||||
margin: 4px 8px;
|
||||
@include margin(4px, 0px, 4px, 8px);
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
ion-button {
|
||||
--padding-start: 16px;
|
||||
--padding-end: 16px;
|
||||
}
|
||||
|
||||
.core-send-message-input::placeholder {
|
||||
color: var(--ion-placeholder-color);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ Feature: Test basic usage of comments in app
|
|||
| database | type | name | description |
|
||||
| data1 | text | Test field name | Test field description |
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Add comments & Delete comments (database)
|
||||
# Create database entry and comment as a teacher
|
||||
Given I entered the data activity "Data" on course "Course 1" as "teacher1" in the app
|
||||
|
@ -65,7 +64,6 @@ Feature: Test basic usage of comments in app
|
|||
When I press the back button in the app
|
||||
Then I should find "Comments (1)" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Add comments offline & Delete comments offline & Sync comments (database)
|
||||
Given I entered the data activity "Data" on course "Course 1" as "teacher1" in the app
|
||||
And I press "Add entries" in the app
|
||||
|
@ -152,7 +150,6 @@ Feature: Test basic usage of comments in app
|
|||
When I press the back button in the app
|
||||
And I should find "Comments (1)" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Add comments offline & Delete comments offline & Sync comments (glossary)
|
||||
Given I entered the glossary activity "Test glossary" on course "Course 1" as "teacher1" in the app
|
||||
And I press "Add a new entry" in the app
|
||||
|
@ -231,7 +228,6 @@ Feature: Test basic usage of comments in app
|
|||
When I press the back button in the app
|
||||
Then I should find "Comments (0)" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Add comments offline & Delete comments offline & Sync comments (blogs)
|
||||
# Create blog as a teacher
|
||||
Given the following "core_blog > entries" exist:
|
||||
|
|
|
@ -114,42 +114,41 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck {
|
|||
* @inheritdoc
|
||||
*/
|
||||
async ngOnChanges(changes: Record<string, SimpleChange>): Promise<void> {
|
||||
if (!this.container) {
|
||||
// Only compile if text/javascript has changed or the forceCompile flag has been set to true.
|
||||
if (this.text === undefined ||
|
||||
!(changes.text || changes.javascript || (changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only compile if text/javascript has changed or the forceCompile flag has been set to true.
|
||||
if (this.text !== undefined && (changes.text || changes.javascript ||
|
||||
(changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) {
|
||||
// Create a new component and a new module.
|
||||
this.creatingComponent = true;
|
||||
this.compiling.emit(true);
|
||||
|
||||
// Create a new component and a new module.
|
||||
this.creatingComponent = true;
|
||||
this.compiling.emit(true);
|
||||
try {
|
||||
const componentClass = await this.getComponentClass();
|
||||
|
||||
try {
|
||||
const componentClass = await this.getComponentClass();
|
||||
// Destroy previous components.
|
||||
this.componentRef?.destroy();
|
||||
|
||||
// Destroy previous components.
|
||||
this.componentRef?.destroy();
|
||||
|
||||
// Create the component.
|
||||
// Create the component.
|
||||
if (this.container) {
|
||||
this.componentRef = await CoreCompile.createAndCompileComponent(
|
||||
this.text,
|
||||
componentClass,
|
||||
this.container,
|
||||
this.extraImports,
|
||||
);
|
||||
this.componentRef && this.created.emit(this.componentRef.instance);
|
||||
|
||||
this.loaded = true;
|
||||
} catch (error) {
|
||||
CoreDomUtils.showErrorModal(error);
|
||||
|
||||
this.loaded = true;
|
||||
} finally {
|
||||
this.creatingComponent = false;
|
||||
this.compiling.emit(false);
|
||||
}
|
||||
this.componentRef && this.created.emit(this.componentRef.instance);
|
||||
|
||||
this.loaded = true;
|
||||
} catch (error) {
|
||||
CoreDomUtils.showErrorModal(error);
|
||||
|
||||
this.loaded = true;
|
||||
} finally {
|
||||
this.creatingComponent = false;
|
||||
this.compiling.emit(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ Feature: Test basic usage of one course in app
|
|||
And I click on "Move right" "link" in the "assignment" activity
|
||||
And I log out
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: View course contents
|
||||
When I entered the course "Course 1" as "student1" in the app
|
||||
Then the header should be "Course 1" in the app
|
||||
|
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
@ -66,10 +66,6 @@
|
|||
}
|
||||
|
||||
.core-login-methods {
|
||||
form .item.item-input {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
form .item,
|
||||
form .item ion-label {
|
||||
--background: var(--core-login-input-background);
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
<div class="core-login-methods">
|
||||
<form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm *ngIf="!isBrowserSSO">
|
||||
<ion-item lines="inset">
|
||||
<ion-item class="ion-margin-bottom" lines="inset">
|
||||
<ion-input type="text" name="username" placeholder="{{ 'core.login.username' | translate }}"
|
||||
formControlName="username" autocapitalize="none" autocorrect="off" autocomplete="username" enterkeyhint="next"
|
||||
required="true" [attr.aria-label]="'core.login.username' | translate " />
|
||||
|
|
|
@ -25,7 +25,6 @@ Feature: Test basic usage of login in app
|
|||
Then I should not find "Skip" in the app
|
||||
And I should find "Connect to Moodle" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Add a new account in the app & Site name in displayed when adding a new account
|
||||
When I launch the app
|
||||
And I set the field "Your site" to "$WWWROOT" in the app
|
||||
|
@ -49,8 +48,7 @@ Feature: Test basic usage of login in app
|
|||
Then I should find "Can't connect to site" in the app
|
||||
|
||||
Scenario: Add a non existing account from accounts switcher
|
||||
When I enter the app
|
||||
And I log in as "student1"
|
||||
Given I entered the app as "student1"
|
||||
And I press the user menu button in the app
|
||||
And I press "Switch account" in the app
|
||||
And I press "Add" in the app
|
||||
|
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -119,8 +119,7 @@ Feature: Report builder
|
|||
| student1 | Lionel | Smith | lionel@example.com | Bilbao |
|
||||
|
||||
Scenario: Open report in mobile
|
||||
Given I enter the app
|
||||
And I log in as "student1"
|
||||
Given I entered the app as "student1"
|
||||
And I press the user menu button in the app
|
||||
When I press "Reports" in the app
|
||||
|
||||
|
@ -132,9 +131,8 @@ Feature: Report builder
|
|||
But I should not find "My report 02" in the app
|
||||
|
||||
Scenario: Open report in tablet
|
||||
Given I enter the app
|
||||
Given I entered the app as "student1"
|
||||
And I change viewport size to "1200x640" in the app
|
||||
And I log in as "student1"
|
||||
And I press the user menu button in the app
|
||||
When I press "Reports" in the app
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<form (ngSubmit)="submitForm($event)" role="search" #searchForm>
|
||||
<ion-item class="search-box">
|
||||
<ion-input [attr.aria-label]="placeholder" type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
|
||||
[autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox"
|
||||
(ionFocus)="focus($event)" />
|
||||
<ion-input [attr.aria-label]="placeholder" type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
|
||||
[autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox"
|
||||
(ionFocus)="focus($event)">
|
||||
<ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel"
|
||||
[disabled]="disabled || !searchText || (searchText.length < lengthCheck)">
|
||||
<ion-icon name="fas-magnifying-glass" slot="icon-only" aria-hidden="true" />
|
||||
|
@ -11,7 +10,7 @@
|
|||
[disabled]="searched === '' || disabled" (click)="clearForm()">
|
||||
<ion-icon name="fas-delete-left" slot="icon-only" aria-hidden="true" flip-rtl />
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</ion-input>
|
||||
<ion-list class="core-search-history" [hidden]="!historyShown">
|
||||
<ion-item button class="ion-text-wrap" *ngFor="let item of history" (click)="historyClicked($event, item.searchedtext)" tabindex="0"
|
||||
[detail]="true">
|
||||
|
|
|
@ -17,14 +17,21 @@
|
|||
background: var(--core-search-box-background);
|
||||
color: var(--core-search-box-border-color);
|
||||
|
||||
.search-box {
|
||||
--min-height: var(--search-height);
|
||||
border-radius: var(--core-search-box-border-radius);
|
||||
--min-height: var(--search-height);
|
||||
|
||||
ion-input {
|
||||
--padding-start: 16px;
|
||||
--padding-end: 16px;
|
||||
--border-radius: var(--core-search-box-border-radius);
|
||||
min-height: var(--search-height);
|
||||
}
|
||||
|
||||
ion-button.button {
|
||||
margin: 0;
|
||||
--a11y-min-target-size: var(--search-height);
|
||||
--padding-start: 0px;
|
||||
--padding-end: 0px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,23 +48,15 @@
|
|||
--background: var(--light);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
ion-label {
|
||||
margin: 0;
|
||||
}
|
||||
ion-item {
|
||||
--min-height: var(--a11y-min-target-size);
|
||||
--border-width: 0px;
|
||||
--background: var(--core-search-box-background);
|
||||
|
||||
ion-input {
|
||||
--padding-start: 0px;
|
||||
--padding-end: 0px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
|
||||
ion-item {
|
||||
--min-height: var(--a11y-min-target-size);
|
||||
--border-width: 0px;
|
||||
--background: var(--core-search-box-background);
|
||||
ion-label {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
</ion-refresher>
|
||||
<core-loading [hideUntil]="userLoaded">
|
||||
<ion-list *ngIf="user">
|
||||
<ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap" [lines]="user.description ? null : 'full'">
|
||||
<core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="!canChangeProfilePicture">
|
||||
<ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"
|
||||
[attr.aria-label]="'core.user.newpicture' | translate" fill="clear">
|
||||
<ion-icon slot="icon-only" name="fas-pen" aria-hidden="true" />
|
||||
</ion-button>
|
||||
</core-user-avatar>
|
||||
<ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap" [lines]="user.description ? 'none' : 'full'">
|
||||
<ion-label>
|
||||
<core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="!canChangeProfilePicture">
|
||||
<ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"
|
||||
[attr.aria-label]="'core.user.newpicture' | translate" fill="clear">
|
||||
<ion-icon slot="icon-only" name="fas-pen" aria-hidden="true" />
|
||||
</ion-button>
|
||||
</core-user-avatar>
|
||||
<h2>{{ user.fullname }}</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
:host {
|
||||
.core-user-profile-maininfo {
|
||||
padding-top: 16px;
|
||||
&::part(native) {
|
||||
ion-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 0px;
|
||||
|
||||
h2 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
core-user-avatar {
|
||||
|
|
|
@ -54,7 +54,6 @@ Feature: Test basic usage of user features
|
|||
When I press "Reconnect" in the app
|
||||
Then I should find "Acceptance test site" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: View profile
|
||||
Given the following "custom profile fields" exist:
|
||||
| datatype | shortname | name | required | param1 |
|
||||
|
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
@ -186,17 +186,20 @@ export class TestingBehatRuntimeService {
|
|||
closePopup(): string {
|
||||
this.log('Action - Close popup');
|
||||
|
||||
let backdrops = Array.from(document.querySelectorAll('ion-backdrop'));
|
||||
backdrops = backdrops.filter((backdrop) => !!backdrop.offsetParent);
|
||||
const backdrops = Array
|
||||
.from(document.querySelectorAll('ion-popover, ion-modal'))
|
||||
.map(popover => popover.shadowRoot?.querySelector('ion-backdrop'))
|
||||
.filter(backdrop => !!backdrop);
|
||||
|
||||
if (!backdrops.length) {
|
||||
return 'ERROR: Could not find backdrop';
|
||||
}
|
||||
|
||||
if (backdrops.length > 1) {
|
||||
return 'ERROR: Found too many backdrops ('+backdrops.length+')';
|
||||
}
|
||||
const backdrop = backdrops[0];
|
||||
backdrop.click();
|
||||
|
||||
backdrops[0]?.click();
|
||||
|
||||
// Mark busy until the click finishes processing.
|
||||
TestingBehatBlocking.delay();
|
||||
|
|
|
@ -18,7 +18,6 @@ Feature: It opens external links properly.
|
|||
| forum | user | name | message |
|
||||
| Test forum | student1 | Forum topic | See <a href="https://moodle.org/">moodle.org external link</a> |
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Click an external link
|
||||
Given I entered the forum activity "Test forum" on course "Course 1" as "student1" in the app
|
||||
When I press "Forum topic" in the app
|
||||
|
|
|
@ -72,7 +72,6 @@ Feature: It navigates properly in pages with a split-view component.
|
|||
And I should find "User account" in the app
|
||||
But I should not find "Back" in the app
|
||||
|
||||
@ionic7_failure
|
||||
Scenario: Navigate in grades tab on tablet
|
||||
|
||||
# Open user menu
|
||||
|
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
|
@ -253,6 +253,9 @@ ion-tabs.hide-header ion-header {
|
|||
|
||||
ion-footer {
|
||||
background-color: var(--contrast-background);
|
||||
> ion-toolbar:only-child {
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
// Ionic icon.
|
||||
|
@ -290,6 +293,11 @@ button,
|
|||
[role="button"] {
|
||||
min-height: var(--a11y-min-target-size);
|
||||
min-width: var(--a11y-min-target-size);
|
||||
|
||||
&.button-large {
|
||||
min-height: 2.8em;
|
||||
min-width: 2.8em
|
||||
}
|
||||
}
|
||||
|
||||
ion-fab-button {
|
||||
|
@ -1015,16 +1023,20 @@ ion-action-sheet.md {
|
|||
ion-radio,
|
||||
input[type=radio],
|
||||
.select-alert.ios .alert-radio-icon {
|
||||
--color: var(--text-color);
|
||||
--color-checked: var(--color);
|
||||
--border-radius: 50%;
|
||||
--border-width: 2px;
|
||||
--outer-border-width: 2px;
|
||||
--border-style: solid;
|
||||
--inner-border-radius: 50%;
|
||||
--size: 20px;
|
||||
|
||||
&:not(.ion-color) {
|
||||
--color: var(--text-color);
|
||||
--color-checked: var(--color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ios ion-radio,
|
||||
.ios input[type=radio],
|
||||
.select-alert.ios .alert-radio-icon {
|
||||
|
@ -1108,15 +1120,19 @@ input[type=radio],
|
|||
ion-checkbox,
|
||||
input[type=checkbox] {
|
||||
--border-radius: 2px;
|
||||
--border-color-checked: var(--text-color);
|
||||
--checkbox-background-checked: var(--text-color);
|
||||
--checkmark-color: var(--contrast-background);
|
||||
--border-width: 2px;
|
||||
--outer-border-width: 2px;
|
||||
--border-style: solid;
|
||||
--size: 20px;
|
||||
|
||||
&:not(.ion-color) {
|
||||
--border-color-checked: var(--text-color);
|
||||
--checkbox-background-checked: var(--text-color);
|
||||
--checkmark-color: var(--contrast-background);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ios input[type=checkbox] {
|
||||
--outer-border-width: 1px;
|
||||
}
|
||||
|
@ -1406,23 +1422,27 @@ audio.core-media-adapt-width {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
ion-item {
|
||||
// font-size: var(--text-size);
|
||||
ion-item.item-lines-default {
|
||||
--inner-border-width: 0px;
|
||||
}
|
||||
|
||||
ion-item.item-lines-full {
|
||||
--inner-border-width: 0px;
|
||||
--border-width: 0 0 1px 0;
|
||||
}
|
||||
|
||||
ion-item.item-lines-inset {
|
||||
--inner-border-width: 0 0 1px 0;
|
||||
--border-width: 0px;
|
||||
}
|
||||
|
||||
ion-item.item-input.ios {
|
||||
ion-item.ion-valid,
|
||||
ion-item.ion-invalid {
|
||||
--inner-border-width: 0 0 1px 0;
|
||||
|
||||
&.ion-touched {
|
||||
&.ion-invalid {
|
||||
--ion-item-border-color: var(--highlight-color-invalid);
|
||||
--highlight-background: var(--ion-item-border-color);
|
||||
--border-color: var(--ion-item-border-color);
|
||||
}
|
||||
&.ion-valid {
|
||||
--ion-item-border-color: var(--highlight-color-valid);
|
||||
--highlight-background: var(--ion-item-border-color);
|
||||
--border-color: var(--ion-item-border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fake item.
|
||||
|
|