angular-busy2
Version:
306 lines (297 loc) • 20 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, Injector, isSignal, effect, Input, ViewEncapsulation, Component, InjectionToken, Inject, Injectable, Directive, NgModule } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { Observable, Subscription, finalize } from 'rxjs';
class CgBusyService {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
promises;
subscriptions;
delayPromise;
durationPromise;
minDuration;
detectChanges;
injector = inject(Injector);
constructor() {
this.promises = [];
this.subscriptions = [];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static isPromise(promiseThing) {
return promiseThing && (promiseThing instanceof Promise || promiseThing instanceof Observable || promiseThing instanceof Subscription || isSignal(promiseThing));
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callThen(promiseThing, callback) {
if (promiseThing.finally) {
promiseThing.finally(callback);
}
else if (promiseThing.then) {
promiseThing.then(callback, callback);
}
else if (promiseThing instanceof Observable) {
promiseThing.pipe(finalize(callback));
}
else if (promiseThing instanceof Subscription) {
promiseThing.add(callback);
}
else if (isSignal(promiseThing)) {
let init = true;
const effectRef = effect(() => {
const v = promiseThing();
// ignore initial value if is undefined;
if (init && v === undefined) {
init = false;
}
else {
callback();
effectRef.destroy();
}
}, ...(ngDevMode ? [{ debugName: "effectRef", injector: this.injector }] : [{ injector: this.injector }]));
}
else {
throw new Error('cgBusy expects a Promise ,an Observable, a Subscription, a number or a boolean');
}
}
reset(options) {
this.minDuration = options.minDuration;
this.promises = [];
options.promises.forEach((p) => {
if (!p || p.$cgBusyFulfilled) {
return;
}
this.addPromiseLikeThing(p);
});
if (this.promises.length === 0) {
// if we have no promises then don't do the delay or duration stuff
return;
}
if (options.delay) {
this.delayPromise = window.setTimeout(() => {
this.delayPromise = null;
if (this.detectChanges) {
this.detectChanges();
}
this.createMinDuration(options);
}, options.delay);
}
else {
this.createMinDuration(options);
}
}
createMinDuration(options) {
if (options.minDuration) {
this.durationPromise = window.setTimeout(() => {
this.durationPromise = null;
if (this.detectChanges) {
this.detectChanges();
}
}, options.minDuration);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
addPromiseLikeThing(promise) {
if (!CgBusyService.isPromise(promise)) {
throw new Error('cgBusy expects a Promise ,an Observable, a Subscription, a Signal, a number or a boolean');
}
if (this.promises.indexOf(promise) !== -1) {
return;
}
this.promises.push(promise);
this.callThen(promise, () => {
promise.$cgBusyFulfilled = true;
if (this.promises.indexOf(promise) === -1) {
return;
}
this.promises.splice(this.promises.indexOf(promise), 1);
if (this.delayPromise && this.promises.length === 0) {
clearTimeout(this.delayPromise);
this.delayPromise = null;
}
if (this.detectChanges) {
this.detectChanges();
}
});
}
active() {
return !this.delayPromise && (!!this.durationPromise || this.promises.length > 0);
}
destroy() {
if (this.delayPromise) {
clearTimeout(this.delayPromise);
this.delayPromise = null;
}
if (this.durationPromise) {
clearTimeout(this.durationPromise);
this.durationPromise = null;
}
this.promises = [];
this.detectChanges = null;
}
}
class CgBusyComponent {
options;
tracker;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.2", type: CgBusyComponent, isStandalone: true, selector: "cg-busy", inputs: { options: "options", tracker: "tracker" }, ngImport: i0, template: "<div class=\"cg-busy cg-busy-animation {{options.wrapperClass}}\" [hidden]=\"!tracker.active()\">\n <div class=\"cg-busy-backdrop cg-busy-backdrop-animation\" [hidden]=\"!options.backdrop\"></div>\n <ng-container class=\"cg-busy-template\"\n [ngTemplateOutlet]=\"options.templateRef ? options.templateRef : defaultTemplate\"\n [ngTemplateOutletContext]=\"{options: options}\"></ng-container>\n</div>\n<ng-template #defaultTemplate>\n <div class=\"cg-busy-default-sign\">\n <div class=\"cg-busy-default-spinner\">\n <div class=\"bar1\"></div>\n <div class=\"bar2\"></div>\n <div class=\"bar3\"></div>\n <div class=\"bar4\"></div>\n <div class=\"bar5\"></div>\n <div class=\"bar6\"></div>\n <div class=\"bar7\"></div>\n <div class=\"bar8\"></div>\n <div class=\"bar9\"></div>\n <div class=\"bar10\"></div>\n <div class=\"bar11\"></div>\n <div class=\"bar12\"></div>\n </div>\n <div class=\"cg-busy-default-text\" [innerHtml]=\"options.message\"></div>\n </div>\n</ng-template>\n", styles: [".cg-busy,.cg-busy .cg-busy-template,.cg-busy .cg-busy-backdrop{position:absolute;inset:0;width:100%;height:100%}.cg-busy{z-index:1001;text-align:center}.cg-busy-animation.ng-hide-add,.cg-busy-animation.ng-hide-remove{transition:all .3s ease;display:block!important}.cg-busy-animation.ng-hide-remove{opacity:0;transform:translateY(-40px)}.cg-busy-animation.ng-hide-remove.ng-hide-remove-active,.cg-busy-animation.ng-hide-add{opacity:1;transform:translate(0)}.cg-busy-animation.ng-hide-add.ng-hide-add-active{opacity:0;transform:translateY(-40px)}.cg-busy-backdrop{background-color:#fff;opacity:.7}.cg-busy-backdrop-animation.ng-hide-add,.cg-busy-backdrop-animation.ng-hide-remove{transition:opacity .3s ease;display:block!important}.cg-busy-backdrop-animation.ng-hide{opacity:0}.cg-busy-default-sign{display:inline-block;position:relative;z-index:1002;padding-bottom:6px;color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);background-color:#e9eeee;border:1px solid #dddddd;border-top-width:0;border-radius:0 0 7px 7px;box-shadow:inset 0 1px #fff3,0 1px 2px #0000000d}.cg-busy-default-text{margin:13px 12px 6px 49px;font-size:16px;color:#555;text-align:left;max-width:400px}.cg-busy-default-spinner{position:absolute;width:25px;height:25px;display:inline-block;top:12px;left:14px}.cg-busy-default-spinner div{width:12%;height:26%;background:#000;position:absolute;left:44.5%;top:37%;opacity:0;animation:cg-busy-spinner-anim 1s linear infinite;border-radius:50px;box-shadow:0 0 3px #0003}.cg-busy-default-spinner div.bar1{transform:rotate(0) translateY(-142%);animation-delay:0s}.cg-busy-default-spinner div.bar2{transform:rotate(30deg) translateY(-142%);animation-delay:-.9167s}.cg-busy-default-spinner div.bar3{transform:rotate(60deg) translateY(-142%);animation-delay:-.833s}.cg-busy-default-spinner div.bar4{transform:rotate(90deg) translateY(-142%);animation-delay:-.75s}.cg-busy-default-spinner div.bar5{transform:rotate(120deg) translateY(-142%);animation-delay:-.667s}.cg-busy-default-spinner div.bar6{transform:rotate(150deg) translateY(-142%);animation-delay:-.5833s}.cg-busy-default-spinner div.bar7{transform:rotate(180deg) translateY(-142%);animation-delay:-.5s}.cg-busy-default-spinner div.bar8{transform:rotate(210deg) translateY(-142%);animation-delay:-.41667s}.cg-busy-default-spinner div.bar9{transform:rotate(240deg) translateY(-142%);animation-delay:-.333s}.cg-busy-default-spinner div.bar10{transform:rotate(270deg) translateY(-142%);animation-delay:-.25s}.cg-busy-default-spinner div.bar11{transform:rotate(300deg) translateY(-142%);animation-delay:-.1667s}.cg-busy-default-spinner div.bar12{transform:rotate(330deg) translateY(-142%);animation-delay:-.0833s}@keyframes cg-busy-spinner-anim{0%{opacity:1}to{opacity:.25}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyComponent, decorators: [{
type: Component,
args: [{ selector: 'cg-busy', encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet], template: "<div class=\"cg-busy cg-busy-animation {{options.wrapperClass}}\" [hidden]=\"!tracker.active()\">\n <div class=\"cg-busy-backdrop cg-busy-backdrop-animation\" [hidden]=\"!options.backdrop\"></div>\n <ng-container class=\"cg-busy-template\"\n [ngTemplateOutlet]=\"options.templateRef ? options.templateRef : defaultTemplate\"\n [ngTemplateOutletContext]=\"{options: options}\"></ng-container>\n</div>\n<ng-template #defaultTemplate>\n <div class=\"cg-busy-default-sign\">\n <div class=\"cg-busy-default-spinner\">\n <div class=\"bar1\"></div>\n <div class=\"bar2\"></div>\n <div class=\"bar3\"></div>\n <div class=\"bar4\"></div>\n <div class=\"bar5\"></div>\n <div class=\"bar6\"></div>\n <div class=\"bar7\"></div>\n <div class=\"bar8\"></div>\n <div class=\"bar9\"></div>\n <div class=\"bar10\"></div>\n <div class=\"bar11\"></div>\n <div class=\"bar12\"></div>\n </div>\n <div class=\"cg-busy-default-text\" [innerHtml]=\"options.message\"></div>\n </div>\n</ng-template>\n", styles: [".cg-busy,.cg-busy .cg-busy-template,.cg-busy .cg-busy-backdrop{position:absolute;inset:0;width:100%;height:100%}.cg-busy{z-index:1001;text-align:center}.cg-busy-animation.ng-hide-add,.cg-busy-animation.ng-hide-remove{transition:all .3s ease;display:block!important}.cg-busy-animation.ng-hide-remove{opacity:0;transform:translateY(-40px)}.cg-busy-animation.ng-hide-remove.ng-hide-remove-active,.cg-busy-animation.ng-hide-add{opacity:1;transform:translate(0)}.cg-busy-animation.ng-hide-add.ng-hide-add-active{opacity:0;transform:translateY(-40px)}.cg-busy-backdrop{background-color:#fff;opacity:.7}.cg-busy-backdrop-animation.ng-hide-add,.cg-busy-backdrop-animation.ng-hide-remove{transition:opacity .3s ease;display:block!important}.cg-busy-backdrop-animation.ng-hide{opacity:0}.cg-busy-default-sign{display:inline-block;position:relative;z-index:1002;padding-bottom:6px;color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);background-color:#e9eeee;border:1px solid #dddddd;border-top-width:0;border-radius:0 0 7px 7px;box-shadow:inset 0 1px #fff3,0 1px 2px #0000000d}.cg-busy-default-text{margin:13px 12px 6px 49px;font-size:16px;color:#555;text-align:left;max-width:400px}.cg-busy-default-spinner{position:absolute;width:25px;height:25px;display:inline-block;top:12px;left:14px}.cg-busy-default-spinner div{width:12%;height:26%;background:#000;position:absolute;left:44.5%;top:37%;opacity:0;animation:cg-busy-spinner-anim 1s linear infinite;border-radius:50px;box-shadow:0 0 3px #0003}.cg-busy-default-spinner div.bar1{transform:rotate(0) translateY(-142%);animation-delay:0s}.cg-busy-default-spinner div.bar2{transform:rotate(30deg) translateY(-142%);animation-delay:-.9167s}.cg-busy-default-spinner div.bar3{transform:rotate(60deg) translateY(-142%);animation-delay:-.833s}.cg-busy-default-spinner div.bar4{transform:rotate(90deg) translateY(-142%);animation-delay:-.75s}.cg-busy-default-spinner div.bar5{transform:rotate(120deg) translateY(-142%);animation-delay:-.667s}.cg-busy-default-spinner div.bar6{transform:rotate(150deg) translateY(-142%);animation-delay:-.5833s}.cg-busy-default-spinner div.bar7{transform:rotate(180deg) translateY(-142%);animation-delay:-.5s}.cg-busy-default-spinner div.bar8{transform:rotate(210deg) translateY(-142%);animation-delay:-.41667s}.cg-busy-default-spinner div.bar9{transform:rotate(240deg) translateY(-142%);animation-delay:-.333s}.cg-busy-default-spinner div.bar10{transform:rotate(270deg) translateY(-142%);animation-delay:-.25s}.cg-busy-default-spinner div.bar11{transform:rotate(300deg) translateY(-142%);animation-delay:-.1667s}.cg-busy-default-spinner div.bar12{transform:rotate(330deg) translateY(-142%);animation-delay:-.0833s}@keyframes cg-busy-spinner-anim{0%{opacity:1}to{opacity:.25}}\n"] }]
}], propDecorators: { options: [{
type: Input
}], tracker: [{
type: Input
}] } });
const BUSY_OPTIONS = new InjectionToken('BUSY_OPTIONS');
class CgBusyDefaults {
delay;
minDuration;
backdrop;
message;
wrapperClass;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
templateRef;
constructor(busyOptions) {
if (!busyOptions) {
busyOptions = {};
}
this.delay = busyOptions.delay || 0;
this.minDuration = busyOptions.minDuration || 0;
this.backdrop = busyOptions.backdrop !== undefined ? busyOptions.backdrop : true;
this.message = busyOptions.message || 'Please Wait...';
this.wrapperClass = busyOptions.wrapperClass || '';
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyDefaults, deps: [{ token: BUSY_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyDefaults });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyDefaults, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [BUSY_OPTIONS]
}] }] });
class CgBusyDirective {
viewContainer;
defaultOptions;
renderer;
el;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cgBusy;
cgBusyConfig;
tracker;
fakePromise;
fakePromiseResolve;
$options;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
$promise;
componentRef;
constructor(viewContainer, defaultOptions, renderer, el) {
this.viewContainer = viewContainer;
this.defaultOptions = defaultOptions;
this.renderer = renderer;
this.el = el;
this.$options = { ...this.defaultOptions };
this.$promise = [];
this.renderer.setStyle(this.el.nativeElement.parentNode, 'position', 'relative');
this.componentRef = this.viewContainer.createComponent(CgBusyComponent);
this.tracker = new CgBusyService();
this.tracker.detectChanges = () => this.componentRef.changeDetectorRef.detectChanges();
this.componentRef.instance.tracker = this.tracker;
this.componentRef.instance.options = this.$options;
}
ngOnChanges(changes) {
if (changes.cgBusyConfig) {
this.$options = {
...this.defaultOptions,
...this.$options,
...this.cgBusyConfig
};
this.componentRef.instance.options = this.$options;
}
if (changes.cgBusy) {
if (this.fakePromise) {
this.fakePromiseResolve();
this.fakePromise = undefined;
this.fakePromiseResolve = undefined;
}
if (Number.isFinite(this.cgBusy) || this.cgBusy === true || this.cgBusy === false) {
this.fakePromise = new Promise((resolve) => {
this.fakePromiseResolve = resolve;
if (!this.cgBusy) {
resolve();
}
});
this.$promise = [this.fakePromise];
}
else if (Array.isArray(this.cgBusy)) {
this.$promise = this.cgBusy;
}
else {
// @ts-ignore
this.$promise = [this.cgBusy];
}
}
this.tracker.reset({
promises: this.$promise,
delay: this.$options.delay || 0,
minDuration: this.$options.minDuration || 0
});
}
ngOnDestroy() {
this.tracker.destroy();
delete this.tracker;
this.componentRef.destroy();
delete this.componentRef;
this.$promise = [];
this.fakePromise = undefined;
this.fakePromiseResolve = undefined;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyDirective, deps: [{ token: i0.ViewContainerRef }, { token: CgBusyDefaults }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.2", type: CgBusyDirective, isStandalone: true, selector: "[cgBusy]", inputs: { cgBusy: "cgBusy", cgBusyConfig: "cgBusyConfig" }, exportAs: ["cgBusy"], usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyDirective, decorators: [{
type: Directive,
args: [{ selector: '[cgBusy]', standalone: true, exportAs: 'cgBusy' }]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: CgBusyDefaults }, { type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { cgBusy: [{
type: Input
}], cgBusyConfig: [{
type: Input
}] } });
function cgBusyDefaultsFactory(busyOptions) {
return new CgBusyDefaults(busyOptions);
}
class CgBusyModule {
static forRoot(busyOptions) {
return {
ngModule: CgBusyModule,
providers: [
{
provide: CgBusyDefaults,
useFactory: cgBusyDefaultsFactory,
deps: [BUSY_OPTIONS]
},
{
provide: BUSY_OPTIONS,
useValue: busyOptions
}
]
};
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.2", ngImport: i0, type: CgBusyModule, imports: [CgBusyDirective], exports: [CgBusyDirective] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: CgBusyModule, decorators: [{
type: NgModule,
args: [{
imports: [CgBusyDirective],
exports: [CgBusyDirective]
}]
}] });
/*
* Public API Surface of angular-busy2
*/
/**
* Generated bundle index. Do not edit.
*/
export { CgBusyDefaults, CgBusyDirective, CgBusyModule };
//# sourceMappingURL=angular-busy2.mjs.map