forked from CIT/Vmeda.Online
		
	
						commit
						598f710678
					
				@ -9,6 +9,12 @@
 | 
			
		||||
            color: white;
 | 
			
		||||
            border-radius: 50%;
 | 
			
		||||
            padding: 0.7rem;
 | 
			
		||||
            --margin-vertical: 12px;
 | 
			
		||||
            --margin-end: 12px;
 | 
			
		||||
            margin-top: var(--margin-vertical);
 | 
			
		||||
            margin-bottom: var(--margin-vertical);
 | 
			
		||||
            @include margin-horizontal(null, var(--margin-end));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @each $category, $value in $calendar-event-category-colors {
 | 
			
		||||
 | 
			
		||||
@ -496,7 +496,6 @@ class AddonCalendarMonthSlidesItemsManagerSource extends CoreSwipeSlidesDynamicI
 | 
			
		||||
        const weeks = result.weeks as AddonCalendarWeek[];
 | 
			
		||||
        const currentDay = new Date().getDate();
 | 
			
		||||
        const currentTime = CoreTimeUtils.timestamp();
 | 
			
		||||
        let isPast = true;
 | 
			
		||||
 | 
			
		||||
        const preloadedMonth: PreloadedMonth = {
 | 
			
		||||
            ...month,
 | 
			
		||||
@ -523,8 +522,7 @@ class AddonCalendarMonthSlidesItemsManagerSource extends CoreSwipeSlidesDynamicI
 | 
			
		||||
 | 
			
		||||
                if (preloadedMonth.isCurrentMonth) {
 | 
			
		||||
                    day.istoday = day.mday == currentDay;
 | 
			
		||||
                    day.ispast = isPast && !day.istoday;
 | 
			
		||||
                    isPast = day.ispast;
 | 
			
		||||
                    day.ispast = preloadedMonth.isPastMonth || day.mday < currentDay;
 | 
			
		||||
 | 
			
		||||
                    if (day.istoday) {
 | 
			
		||||
                        day.eventsFormated?.forEach((event) => {
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@
 | 
			
		||||
                </ion-label>
 | 
			
		||||
                <ion-radio slot="end" value="custom"></ion-radio>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
            <ion-item class="ion-text-wrap">
 | 
			
		||||
            <ion-item class="ion-text-wrap" (click)="customInputClicked($event)">
 | 
			
		||||
                <ion-label></ion-label>
 | 
			
		||||
 | 
			
		||||
                <div class="flex-row">
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,6 @@
 | 
			
		||||
import { AddonCalendar, AddonCalendarReminderUnits, AddonCalendarValueAndUnit } from '@addons/calendar/services/calendar';
 | 
			
		||||
import { Component, Input, OnInit } from '@angular/core';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreUtils } from '@services/utils/utils';
 | 
			
		||||
import { ModalController } from '@singletons';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -166,11 +165,9 @@ export class AddonCalendarReminderTimeModalComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
        this.radioValue = 'custom';
 | 
			
		||||
 | 
			
		||||
        await CoreUtils.nextTick();
 | 
			
		||||
 | 
			
		||||
        const target = <HTMLInputElement | Element | null> ev.target;
 | 
			
		||||
        if (target && 'focus' in target) {
 | 
			
		||||
            target.focus();
 | 
			
		||||
        const target = <HTMLInputElement | HTMLElement | null> ev.target;
 | 
			
		||||
        if (target) {
 | 
			
		||||
            CoreDomUtils.focusElement(target);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -49,19 +49,7 @@ export class CoreAutoFocusDirective implements AfterViewInit {
 | 
			
		||||
 | 
			
		||||
        await CoreDom.waitToBeInDOM(this.element);
 | 
			
		||||
 | 
			
		||||
        let focusElement = this.element;
 | 
			
		||||
 | 
			
		||||
        if ('getInputElement' in focusElement) {
 | 
			
		||||
            // If it's an Ionic element get the right input to use.
 | 
			
		||||
            focusElement.componentOnReady && await focusElement.componentOnReady();
 | 
			
		||||
            focusElement = await focusElement.getInputElement();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!focusElement) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CoreDomUtils.focusElement(focusElement);
 | 
			
		||||
        CoreDomUtils.focusElement(this.element);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -50,11 +50,10 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
 | 
			
		||||
    protected contentScrollListener?: EventListener;
 | 
			
		||||
    protected endContentScrollListener?: EventListener;
 | 
			
		||||
    protected resizeListener?: CoreEventObserver;
 | 
			
		||||
    protected domPromise?: CoreCancellablePromise<void>;
 | 
			
		||||
    protected slotPromise?: CoreCancellablePromise<void>;
 | 
			
		||||
 | 
			
		||||
    constructor(el: ElementRef, protected ionContent: IonContent) {
 | 
			
		||||
        this.element = el.nativeElement;
 | 
			
		||||
        this.element.setAttribute('slot', 'fixed'); // Just in case somebody forgets to add it.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -63,9 +62,9 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
 | 
			
		||||
    async ngOnInit(): Promise<void> {
 | 
			
		||||
        // Only if not present or explicitly falsy it will be false.
 | 
			
		||||
        this.appearOnBottom = !CoreUtils.isFalseOrZero(this.appearOnBottom);
 | 
			
		||||
        this.domPromise = CoreDom.waitToBeInDOM(this.element);
 | 
			
		||||
        this.slotPromise = CoreDom.slotOnContent(this.element);
 | 
			
		||||
 | 
			
		||||
        await this.domPromise;
 | 
			
		||||
        await this.slotPromise;
 | 
			
		||||
        await this.waitLoadingsDone();
 | 
			
		||||
        await this.waitFormatTextsRendered();
 | 
			
		||||
 | 
			
		||||
@ -229,7 +228,7 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.resizeListener?.off();
 | 
			
		||||
        this.domPromise?.cancel();
 | 
			
		||||
        this.slotPromise?.cancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,19 +31,18 @@ export class CoreFabDirective implements OnInit, OnDestroy {
 | 
			
		||||
    protected element: HTMLElement;
 | 
			
		||||
    protected content?: HTMLIonContentElement | null;
 | 
			
		||||
    protected initialPaddingBottom = 0;
 | 
			
		||||
    protected domPromise?: CoreCancellablePromise<void>;
 | 
			
		||||
    protected slotPromise?: CoreCancellablePromise<void>;
 | 
			
		||||
 | 
			
		||||
    constructor(el: ElementRef) {
 | 
			
		||||
        this.element = el.nativeElement;
 | 
			
		||||
        this.element.setAttribute('slot', 'fixed');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async ngOnInit(): Promise<void> {
 | 
			
		||||
        this.domPromise = CoreDom.waitToBeInDOM(this.element);
 | 
			
		||||
        await this.domPromise;
 | 
			
		||||
        this.slotPromise = CoreDom.slotOnContent(this.element);
 | 
			
		||||
        await this.slotPromise;
 | 
			
		||||
 | 
			
		||||
        this.content = this.element.closest('ion-content');
 | 
			
		||||
 | 
			
		||||
@ -70,12 +69,6 @@ export class CoreFabDirective implements OnInit, OnDestroy {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const initialHeight = this.element.getBoundingClientRect().height || 56;
 | 
			
		||||
 | 
			
		||||
        // Move element to the nearest ion-content if it's not the parent
 | 
			
		||||
        if (this.element.parentElement?.nodeName != 'ION-CONTENT') {
 | 
			
		||||
            this.content.appendChild(this.element);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.content.style.setProperty('--padding-bottom', this.initialPaddingBottom + initialHeight + 'px');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -86,7 +79,7 @@ export class CoreFabDirective implements OnInit, OnDestroy {
 | 
			
		||||
        if (this.content) {
 | 
			
		||||
            this.content.style.setProperty('--padding-bottom', this.initialPaddingBottom + 'px');
 | 
			
		||||
        }
 | 
			
		||||
        this.domPromise?.cancel();
 | 
			
		||||
        this.slotPromise?.cancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,11 @@
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { Component, ElementRef, Input, ViewChild } from '@angular/core';
 | 
			
		||||
import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
 | 
			
		||||
import { CoreCancellablePromise } from '@classes/cancellable-promise';
 | 
			
		||||
import { CoreUserTours, CoreUserToursAlignment, CoreUserToursSide } from '@features/usertours/services/user-tours';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreDom } from '@singletons/dom';
 | 
			
		||||
import { CoreBlockSideBlocksTourComponent } from '../side-blocks-tour/side-blocks-tour';
 | 
			
		||||
import { CoreBlockSideBlocksComponent } from '../side-blocks/side-blocks';
 | 
			
		||||
 | 
			
		||||
@ -26,11 +28,25 @@ import { CoreBlockSideBlocksComponent } from '../side-blocks/side-blocks';
 | 
			
		||||
    templateUrl: 'side-blocks-button.html',
 | 
			
		||||
    styleUrls: ['side-blocks-button.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class CoreBlockSideBlocksButtonComponent {
 | 
			
		||||
export class CoreBlockSideBlocksButtonComponent implements OnInit, OnDestroy {
 | 
			
		||||
 | 
			
		||||
    @Input() courseId!: number;
 | 
			
		||||
    @ViewChild('button', { read: ElementRef }) button?: ElementRef<HTMLElement>;
 | 
			
		||||
 | 
			
		||||
    protected element: HTMLElement;
 | 
			
		||||
    protected slotPromise?: CoreCancellablePromise<void>;
 | 
			
		||||
 | 
			
		||||
    constructor(el: ElementRef) {
 | 
			
		||||
        this.element = el.nativeElement;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async ngOnInit(): Promise<void> {
 | 
			
		||||
        this.slotPromise = CoreDom.slotOnContent(this.element);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Open side blocks.
 | 
			
		||||
     */
 | 
			
		||||
@ -62,4 +78,11 @@ export class CoreBlockSideBlocksButtonComponent {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    ngOnDestroy(): void {
 | 
			
		||||
        this.slotPromise?.cancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<core-dynamic-component [component]="componentClass" [data]="data"></core-dynamic-component>
 | 
			
		||||
 | 
			
		||||
<core-block-side-blocks-button *ngIf="course && hasBlocks" [courseId]="course.id">
 | 
			
		||||
<core-block-side-blocks-button slot="fixed" *ngIf="course && hasBlocks" [courseId]="course.id">
 | 
			
		||||
</core-block-side-blocks-button>
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
            </ng-container>
 | 
			
		||||
        </ion-list>
 | 
			
		||||
 | 
			
		||||
        <core-block-side-blocks-button *ngIf="hasSideBlocks"></core-block-side-blocks-button>
 | 
			
		||||
        <core-block-side-blocks-button slot="fixed" *ngIf="hasSideBlocks"></core-block-side-blocks-button>
 | 
			
		||||
 | 
			
		||||
        <core-empty-box *ngIf="blocks.length == 0" icon="fas-cubes" [message]="'core.course.nocontentavailable' | translate">
 | 
			
		||||
        </core-empty-box>
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@
 | 
			
		||||
                </core-show-password>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
            <ion-button expand="block" type="submit" [disabled]="siteChecked && !isBrowserSSO && !credForm.valid"
 | 
			
		||||
                class="ion-margin core-login-login-button">
 | 
			
		||||
                class="ion-margin core-login-login-button ion-text-wrap">
 | 
			
		||||
                {{ 'core.login.loginbutton' | translate }}
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <!-- Remove this once Ionic fixes this bug: https://github.com/ionic-team/ionic-framework/issues/19368 -->
 | 
			
		||||
 | 
			
		||||
@ -51,20 +51,15 @@
 | 
			
		||||
                    </ion-input>
 | 
			
		||||
                </core-show-password>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
            <ion-grid class="ion-padding">
 | 
			
		||||
                <ion-row>
 | 
			
		||||
                    <ion-col>
 | 
			
		||||
                        <ion-button expand="block" fill="outline" (click)="cancel($event)">
 | 
			
		||||
                            {{ 'core.login.cancel' | translate }}
 | 
			
		||||
                        </ion-button>
 | 
			
		||||
                    </ion-col>
 | 
			
		||||
                    <ion-col>
 | 
			
		||||
                        <ion-button type="submit" expand="block" [disabled]="!credForm.valid">
 | 
			
		||||
                            {{ 'core.login.loginbutton' | translate }}
 | 
			
		||||
                        </ion-button>
 | 
			
		||||
                    </ion-col>
 | 
			
		||||
                </ion-row>
 | 
			
		||||
            </ion-grid>
 | 
			
		||||
            <div class="adaptable-buttons-row">
 | 
			
		||||
                <ion-button expand="block" fill="outline" (click)="cancel($event)" class="ion-margin ion-text-wrap">
 | 
			
		||||
                    {{ 'core.login.cancel' | translate }}
 | 
			
		||||
                </ion-button>
 | 
			
		||||
                <ion-button type="submit" expand="block" [disabled]="!credForm.valid"
 | 
			
		||||
                    class="ion-margin core-login-login-button ion-text-wrap">
 | 
			
		||||
                    {{ 'core.login.loginbutton' | translate }}
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <ng-container *ngIf="showScanQR">
 | 
			
		||||
                <div class="ion-text-center ion-padding">{{ 'core.login.or' | translate }}</div>
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@
 | 
			
		||||
                </ng-container>
 | 
			
		||||
            </ng-container>
 | 
			
		||||
        </ion-list>
 | 
			
		||||
        <core-block-side-blocks-button *ngIf="hasBlocks" [courseId]="siteHomeId">
 | 
			
		||||
        <core-block-side-blocks-button slot="fixed" *ngIf="hasBlocks" [courseId]="siteHomeId">
 | 
			
		||||
        </core-block-side-blocks-button>
 | 
			
		||||
 | 
			
		||||
        <core-empty-box *ngIf="!hasContent" icon="fas-box-open" [message]="'core.course.nocontentavailable' | translate">
 | 
			
		||||
 | 
			
		||||
@ -336,12 +336,22 @@ export class CoreDomUtilsProvider {
 | 
			
		||||
    /**
 | 
			
		||||
     * Focus an element and open keyboard.
 | 
			
		||||
     *
 | 
			
		||||
     * @param focusElement HTML element to focus.
 | 
			
		||||
     * @param element HTML element to focus.
 | 
			
		||||
     */
 | 
			
		||||
    async focusElement(focusElement: HTMLElement): Promise<void> {
 | 
			
		||||
    async focusElement(
 | 
			
		||||
        element: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement | HTMLElement,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        let retries = 10;
 | 
			
		||||
 | 
			
		||||
        if (!focusElement.focus) {
 | 
			
		||||
        let focusElement = element;
 | 
			
		||||
 | 
			
		||||
        if ('getInputElement' in focusElement) {
 | 
			
		||||
            // If it's an Ionic element get the right input to use.
 | 
			
		||||
            focusElement.componentOnReady && await focusElement.componentOnReady();
 | 
			
		||||
            focusElement = await focusElement.getInputElement();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!focusElement || !focusElement.focus) {
 | 
			
		||||
            throw new CoreError('Element to focus cannot be focused');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -205,6 +205,38 @@ export class CoreDom {
 | 
			
		||||
        return CoreDom.scrollToElement(container, '.core-input-error');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Move element to content so it can be slotted.
 | 
			
		||||
     *
 | 
			
		||||
     * @param element HTML Element.
 | 
			
		||||
     * @param slot Slot name.
 | 
			
		||||
     * @return Promise resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    static slotOnContent(element: HTMLElement, slot = 'fixed'): CoreCancellablePromise<void> {
 | 
			
		||||
        element.setAttribute('slot', slot);
 | 
			
		||||
        if (element.parentElement?.nodeName === 'ION-CONTENT') {
 | 
			
		||||
            return CoreCancellablePromise.resolve();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const domPromise = CoreDom.waitToBeInDOM(element);
 | 
			
		||||
 | 
			
		||||
        return new CoreCancellablePromise<void>(
 | 
			
		||||
            async (resolve) => {
 | 
			
		||||
                await domPromise;
 | 
			
		||||
 | 
			
		||||
                // Move element to the nearest ion-content if it's not the parent
 | 
			
		||||
                if (element.parentElement?.nodeName !== 'ION-CONTENT') {
 | 
			
		||||
                    element.closest('ion-content')?.appendChild(element);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                resolve();
 | 
			
		||||
            },
 | 
			
		||||
            () => {
 | 
			
		||||
                domPromise.cancel();
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wait an element to be added to the root DOM.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user