Added some components & styles
This commit is contained in:
parent
25d66040d0
commit
53f8f0af29
14
src/assets/icons/logout.svg
Executable file
14
src/assets/icons/logout.svg
Executable file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="14px" version="1.1" viewBox="0 0 17 14" width="17px" xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
|
||||
<defs></defs>
|
||||
<g fill="none" fill-rule="evenodd" id="Artboard" stroke="none" stroke-width="1"
|
||||
transform="translate(-488.000000, -4752.000000)">
|
||||
<g fill="currentColor" id="User-Menu" transform="translate(456.000000, 4454.000000)">
|
||||
<path
|
||||
d="M48.7966936,304.522526 C49.0677688,304.796017 49.0677688,305.203983 48.7966936,305.477474 L46.4800677,307.794882 C46.2071762,308.068373 45.7989742,308.068373 45.5260828,307.794882 L45.0488633,307.317862 L46.6839417,305.681457 L38.6810935,305.681457 C38.3069461,305.681457 38,305.374347 38,305 C38,304.625653 38.3069461,304.318543 38.6810935,304.318543 L46.6839417,304.318543 L45.0488633,302.682138 L45.5260828,302.205118 C45.7989742,301.931627 46.2071762,301.931627 46.4800677,302.205118 L48.7966936,304.522526 Z M35.5184445,312 C33.6163541,312 32.0629803,310.462957 32,308.500218 L32,301.499782 C32.0629803,299.537043 33.6163541,298 35.5184445,298 L39.6083615,298 C41.4791731,298 42.9682985,299.571064 43,301.499782 C43,301.891457 42.7142638,302.186304 42.3342684,302.186304 C41.9546957,302.186304 41.6689594,301.891457 41.6689594,301.499782 C41.6689594,300.322138 40.7491931,299.373481 39.6083615,299.373481 L35.5184445,299.373481 C34.377613,299.373481 33.395289,300.289862 33.3310406,301.499782 L33.3310406,308.500218 C33.3935982,309.677862 34.3446434,310.626519 35.5184445,310.626519 L39.6083615,310.626519 C40.7491931,310.626519 41.6689594,309.677862 41.6689594,308.500218 C41.6689594,308.108543 41.9546957,307.813696 42.3342684,307.813696 C42.7142638,307.813696 43,308.108543 43,308.500218 C43,310.430681 41.4774823,312 39.6083615,312 L35.5184445,312 Z"
|
||||
id="logout_icon"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
8
src/assets/icons/menu.svg
Normal file
8
src/assets/icons/menu.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg height="384pt" viewBox="0 -53 384 384" width="384pt" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="m368 154.667969h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/>
|
||||
<path
|
||||
d="m368 32h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/>
|
||||
<path
|
||||
d="m368 277.332031h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 525 B |
90
src/assets/styles/common-components.scss
Normal file
90
src/assets/styles/common-components.scss
Normal file
@ -0,0 +1,90 @@
|
||||
.oval,
|
||||
.square {
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.large {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
&.gray-dark {
|
||||
background-color: var(--iqser-grey-6);
|
||||
}
|
||||
|
||||
&.gray-primary {
|
||||
background-color: var(--iqser-grey-6);
|
||||
color: var(--iqser-primary);
|
||||
}
|
||||
|
||||
&.lightgray-dark {
|
||||
background-color: var(--iqser-grey-4);
|
||||
}
|
||||
|
||||
&.lightgray-primary {
|
||||
background-color: var(--iqser-grey-4);
|
||||
color: var(--iqser-primary);
|
||||
}
|
||||
|
||||
&.darkgray-white {
|
||||
background-color: var(--iqser-accent);
|
||||
color: var(--iqser-white);
|
||||
}
|
||||
|
||||
&.lightgray-white {
|
||||
background-color: var(--iqser-grey-5);
|
||||
color: var(--iqser-white);
|
||||
}
|
||||
|
||||
&.primary--white {
|
||||
background-color: var(--iqser-primary);
|
||||
color: var(--iqser-white);
|
||||
}
|
||||
|
||||
&.white-dark {
|
||||
border: 1px solid var(--iqser-grey-4);
|
||||
}
|
||||
|
||||
&.inactive {
|
||||
background-color: var(--iqser-grey-6);
|
||||
color: var(--iqser-grey-7);
|
||||
}
|
||||
}
|
||||
|
||||
.oval {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.stats-subtitle {
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
|
||||
mat-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
line-height: 13px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,3 +5,4 @@
|
||||
@use 'common-full-pages';
|
||||
@use 'common-layout';
|
||||
@use 'common-dialogs';
|
||||
@use 'common-components';
|
||||
|
||||
@ -6,7 +6,7 @@ import { DomSanitizer } from '@angular/platform-browser';
|
||||
@NgModule({
|
||||
imports: [CommonModule, MatIconModule],
|
||||
declarations: [],
|
||||
exports: [MatIconModule]
|
||||
exports: [MatIconModule],
|
||||
})
|
||||
export class IqserIconsModule {
|
||||
constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) {
|
||||
@ -20,14 +20,20 @@ export class IqserIconsModule {
|
||||
'help-outline',
|
||||
'lanes',
|
||||
'list',
|
||||
'logout',
|
||||
'menu',
|
||||
'offline',
|
||||
'refresh',
|
||||
'search',
|
||||
'sort-asc',
|
||||
'sort-desc'
|
||||
'sort-desc',
|
||||
]);
|
||||
icons.forEach(icon => {
|
||||
_iconRegistry.addSvgIconInNamespace('iqser', icon, _sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`));
|
||||
_iconRegistry.addSvgIconInNamespace(
|
||||
'iqser',
|
||||
icon,
|
||||
_sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
40
src/lib/services/composite-route.guard.ts
Normal file
40
src/lib/services/composite-route.guard.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
|
||||
import { Injectable, InjectionToken, Injector } from '@angular/core';
|
||||
import { from, of } from 'rxjs';
|
||||
import { LoadingService } from '../loading';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CompositeRouteGuard implements CanActivate {
|
||||
constructor(protected readonly _injector: Injector, private readonly _loadingService: LoadingService) {}
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
|
||||
this._loadingService.start();
|
||||
|
||||
const routeGuards = <InjectionToken<CanActivate>[]>route.data.routeGuards;
|
||||
|
||||
if (routeGuards) {
|
||||
for (let i = 0; i < routeGuards.length; i++) {
|
||||
const routeGuard = this._injector.get<CanActivate>(routeGuards[i]);
|
||||
let canActivateResult = routeGuard.canActivate(route, state);
|
||||
if (canActivateResult instanceof Promise) {
|
||||
canActivateResult = from(canActivateResult);
|
||||
}
|
||||
if (typeof canActivateResult === 'boolean' || canActivateResult instanceof UrlTree) {
|
||||
canActivateResult = of(canActivateResult);
|
||||
}
|
||||
|
||||
const result = await canActivateResult.toPromise();
|
||||
if (!result) {
|
||||
this._loadingService.stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._loadingService.stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
56
src/lib/services/dialog.service.ts
Normal file
56
src/lib/services/dialog.service.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ComponentType } from '@angular/cdk/portal';
|
||||
|
||||
export const largeDialogConfig: MatDialogConfig = {
|
||||
width: '90vw',
|
||||
maxWidth: '90vw',
|
||||
maxHeight: '90vh',
|
||||
autoFocus: false,
|
||||
} as const;
|
||||
|
||||
export const defaultDialogConfig: MatDialogConfig = {
|
||||
width: '662px',
|
||||
maxWidth: '90vw',
|
||||
autoFocus: false,
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export abstract class DialogService<T extends string> {
|
||||
protected readonly _config: {
|
||||
[key in T]: {
|
||||
component: ComponentType<unknown>;
|
||||
dialogConfig?: MatDialogConfig;
|
||||
};
|
||||
};
|
||||
|
||||
protected constructor(protected readonly _dialog: MatDialog) {}
|
||||
|
||||
openDialog(
|
||||
type: T,
|
||||
$event: MouseEvent,
|
||||
data: unknown,
|
||||
cb?: (...params) => unknown,
|
||||
finallyCb?: (...params) => unknown | Promise<unknown>,
|
||||
): MatDialogRef<unknown> {
|
||||
const config = this._config[type];
|
||||
|
||||
$event?.stopPropagation();
|
||||
const ref = this._dialog.open(config.component, {
|
||||
...defaultDialogConfig,
|
||||
...(config.dialogConfig || {}),
|
||||
data,
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
ref.afterClosed().subscribe(async result => {
|
||||
if (result && cb) {
|
||||
await cb(result);
|
||||
}
|
||||
|
||||
if (finallyCb) {
|
||||
await finallyCb(result);
|
||||
}
|
||||
});
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
export * from './dialog.service';
|
||||
export * from './toaster.service';
|
||||
export * from './error-message.service';
|
||||
export * from './generic.service';
|
||||
export * from './composite-route.guard';
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import {tap} from 'rxjs/operators';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
export function capitalize(value: string): string {
|
||||
if (!value) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
return value.charAt(0).toUpperCase() + value.slice(1);
|
||||
}
|
||||
|
||||
export function humanize(value: string, lowercase = true): string {
|
||||
if (!value) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
|
||||
const words = (lowercase ? value.toLowerCase() : value).split(/[ \-_]+/);
|
||||
@ -17,3 +17,11 @@ export function humanize(value: string, lowercase = true): string {
|
||||
}
|
||||
|
||||
export const log = tap(console.log);
|
||||
|
||||
export const toNumber = (str: string) => {
|
||||
try {
|
||||
return parseInt(`${str}`.replace(/\D/g, ''), 10);
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -12,3 +12,4 @@ export * from './decorators/debounce.decorator';
|
||||
export * from './decorators/on-change.decorator';
|
||||
export * from './http-encoder';
|
||||
export * from './types/iqser-types';
|
||||
export * from './pruning-translation-loader';
|
||||
|
||||
29
src/lib/utils/pruning-translation-loader.ts
Normal file
29
src/lib/utils/pruning-translation-loader.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { TranslateLoader } from '@ngx-translate/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export class PruningTranslationLoader implements TranslateLoader {
|
||||
constructor(private _http: HttpClient, private _prefix: string, private _suffix: string) {}
|
||||
|
||||
getTranslation(lang: string): Observable<Record<string, unknown>> {
|
||||
return this._http
|
||||
.get(`${this._prefix}${lang}${this._suffix}`)
|
||||
.pipe(map((result: Record<string, unknown>) => this._process(result)));
|
||||
}
|
||||
|
||||
private _process(object: unknown): Record<string, unknown> {
|
||||
return (
|
||||
Object.keys(object)
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
.filter(key => object.hasOwnProperty(key) && object[key] !== '')
|
||||
.reduce(
|
||||
(result: Record<string, unknown>, key) => (
|
||||
(result[key] = typeof object[key] === 'object' ? this._process(object[key]) : object[key]),
|
||||
result
|
||||
),
|
||||
{},
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user