@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
406 lines (399 loc) • 35.3 kB
JavaScript
import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, DragDropModule } from '@angular/cdk/drag-drop';
import * as i0 from '@angular/core';
import { Injectable, HostListener, Input, Component, DOCUMENT, Inject, NgModule } from '@angular/core';
import * as i5 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import * as i1$2 from 'ngx-bootstrap/tooltip';
import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
import * as i1 from '@c8y/ngx-components';
import { IconDirective, C8yTranslateDirective, ListGroupComponent, ListItemComponent, ListItemDragHandleComponent, ListItemIconComponent, ChangeIconComponent, PopoverConfirmComponent, EmptyStateComponent, C8yTranslatePipe, CoreModule, CommonModule, ListGroupModule, FormsModule as FormsModule$1, ModalModule, hookDrawer } from '@c8y/ngx-components';
import { NgIf, NgFor, AsyncPipe } from '@angular/common';
import * as i2 from '@angular/router';
import { gettext } from '@c8y/ngx-components/gettext';
import { uniqBy, cloneDeep } from 'lodash-es';
import * as i1$1 from 'ngx-bootstrap/modal';
import * as i3 from '@ngx-translate/core';
import { firstValueFrom, map } from 'rxjs';
import * as i4 from '@c8y/ngx-components/icon-selector';
class BookmarkService {
static { this.DEFAULT_ICON = 'bookmark'; }
constructor(navigatorService, options, router, translateService, userPreferencesService) {
this.navigatorService = navigatorService;
this.options = options;
this.router = router;
this.translateService = translateService;
this.userPreferencesService = userPreferencesService;
this.USER_PREFERENCES_BOOKMARKS_KEY = 'bookmarks';
}
async updateBookmarksInStorage(newBookmarks) {
const existingBookmarks = await this.getBookmarks();
const mergedBookmarks = [...newBookmarks, ...existingBookmarks];
const cleanedBookmarks = uniqBy(mergedBookmarks, 'id').filter((bookmark) => !bookmark.markToRemove);
this.setUserPreferencesBookmarks(cleanedBookmarks);
}
async getActiveNodeIcon() {
const activeNode = await this.findActiveNode();
return activeNode?.icon || BookmarkService.DEFAULT_ICON;
}
extractIconName(input) {
const iconRegex = /\b(dlt-)?c8y-icon-(\w+(?:-\w+)*)\b/g;
const matches = [...input.matchAll(iconRegex)];
const match = matches?.pop();
if (!match) {
return null;
}
const [, prefix, name] = match;
return prefix ? name : `c8y-${name}`;
}
async getBookmarks() {
return await firstValueFrom(this.userPreferencesService
.get(this.USER_PREFERENCES_BOOKMARKS_KEY)
.pipe(map((bookmarks) => bookmarks ?? [])));
}
generateRandomID() {
const array = new Uint8Array(16);
crypto.getRandomValues(array);
return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
}
convertBookmarkLinkToObject(title, url, icon) {
const globalTitle = this.options.globalTitle ?? 'Cumulocity';
return {
id: this.generateRandomID(),
label: title.includes(globalTitle)
? title.replace(`${globalTitle} - `, '')
: this.translateService.instant(gettext('Bookmark')),
url,
icon
};
}
async findActiveNode() {
const nodes = await firstValueFrom(this.navigatorService.items$);
return this.findActiveInTree(nodes);
}
findActiveInTree(nodes) {
let result;
for (const node of nodes) {
if (node.path && this.isNodeActive(node)) {
result = node;
}
if (node.children?.length) {
const childMatch = this.findActiveInTree(node.children);
if (childMatch) {
result = childMatch;
}
}
}
return result;
}
isNodeActive(node) {
return this.router.isActive(node.path, {
paths: node.routerLinkExact ? 'exact' : 'subset',
queryParams: 'ignored',
fragment: 'ignored',
matrixParams: 'ignored'
});
}
setUserPreferencesBookmarks(bookmarks) {
this.userPreferencesService.set(this.USER_PREFERENCES_BOOKMARKS_KEY, bookmarks);
this.updatedBookmarks = bookmarks;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarkService, deps: [{ token: i1.NavigatorService }, { token: i1.OptionsService }, { token: i2.Router }, { token: i3.TranslateService }, { token: i1.UserPreferencesService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarkService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarkService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1.NavigatorService }, { type: i1.OptionsService }, { type: i2.Router }, { type: i3.TranslateService }, { type: i1.UserPreferencesService }] });
class EditBookmarksComponent {
constructor(bsModalRef, alertService, bookmarkService, iconSelector) {
this.bsModalRef = bsModalRef;
this.alertService = alertService;
this.bookmarkService = bookmarkService;
this.iconSelector = iconSelector;
this.confirmRemoveColumnButtons = [
{
label: gettext('Cancel'),
action: () => Promise.resolve(false)
},
{
label: gettext('Delete'),
status: 'danger',
action: () => Promise.resolve(true)
}
];
this.result = new Promise(resolve => {
this._close = resolve;
});
}
ngOnInit() {
this.bookmarksToUpdate = cloneDeep(this.bookmarks);
}
handleKeyboardEvent(event) {
if (event.key === 'Escape') {
this.close();
}
}
close() {
if (this.bookmarkService.updatedBookmarks) {
this._close(this.bookmarkService.updatedBookmarks);
}
this.bsModalRef.hide();
}
async drop(event) {
try {
moveItemInArray(this.bookmarks, event.previousIndex, event.currentIndex);
moveItemInArray(this.bookmarksToUpdate, event.previousIndex, event.currentIndex);
await this.bookmarkService.updateBookmarksInStorage(this.bookmarksToUpdate);
this.alertService.success(gettext('Bookmarks order updated.'));
}
catch {
this.alertService.success(gettext('Bookmarks order failed to update.'));
}
}
async updateBookmark(updatedBookmark, type) {
try {
this.bookmarksToUpdate = this.updateBookmarkProperty(updatedBookmark, type);
await this.bookmarkService.updateBookmarksInStorage(this.bookmarksToUpdate);
if (type !== 'markToRemove') {
this.alertService.success(gettext('Bookmark updated.'));
}
}
catch {
if (type !== 'markToRemove') {
this.alertService.warning(gettext('Bookmark update failed'));
}
}
}
updateBookmarkProperty(updatedBookmark, type) {
const update = {
icon: (bookmark) => ({ ...bookmark, icon: updatedBookmark.icon }),
label: (bookmark) => ({ ...bookmark, label: updatedBookmark.label }),
markToRemove: (bookmark) => ({ ...bookmark, markToRemove: true })
}[type];
return this.bookmarksToUpdate.map(bookmark => bookmark.id === updatedBookmark.id ? update(bookmark) : bookmark);
}
async changeBookmarkIcon(updatedBookmark) {
try {
const newIcon = await this.iconSelector.selectIcon();
updatedBookmark.icon = newIcon;
await this.updateBookmark(updatedBookmark, 'icon');
}
catch {
// nothing to do
}
}
async removeBookmark(poConfirm, bookmarkToDelete) {
poConfirm.message = gettext('This action is irreversible.');
try {
const remove = await poConfirm.show(this.confirmRemoveColumnButtons);
if (!remove) {
return;
}
await this.updateBookmark(bookmarkToDelete, 'markToRemove');
const bookmarkIndex = this.bookmarks.findIndex(bookmark => bookmark.id === bookmarkToDelete.id);
if (bookmarkIndex === -1) {
return;
}
this.bookmarks.splice(bookmarkIndex, 1);
this.alertService.success(gettext('Bookmark removed.'));
}
catch (err) {
/**
* Prevents an alert message from being displayed if the user clicks outside of a popover.
*/
if (err) {
this.alertService.warning(gettext('Bookmarks deletion failed.'));
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EditBookmarksComponent, deps: [{ token: i1$1.BsModalRef }, { token: i1.AlertService }, { token: BookmarkService }, { token: i4.IconSelectorService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EditBookmarksComponent, isStandalone: true, selector: "c8y-edit-bookmarks", inputs: { bookmarks: "bookmarks" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n *ngIf=\"bookmarks.length; else emptyList\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks?.length < 2\"\n >\n <c8y-li\n *ngFor=\"let bookmark of bookmarks\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n <c8y-li-icon\n style=\"{{ bookmarks?.length < 2 ? 'padding-left: 16px!important' : '' }}\"\n *ngIf=\"bookmark.icon\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n\n <div class=\"d-flex gap-8 a-i-center\">\n <form\n class=\"d-flex flex-grow\"\n name=\"bookmarksForm\"\n #bookmarksForm=\"ngForm\"\n >\n <div class=\"input-group input-group-editable\">\n <input\n class=\"form-control fit-w\"\n title=\"{{ bookmark.label }}\"\n id=\"label\"\n name=\"label\"\n type=\"text\"\n [(ngModel)]=\"bookmark.label\"\n #label=\"ngModel\"\n maxlength=\"50\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n (click)=\"updateBookmark(bookmark, 'label'); label.control.markAsPristine()\"\n [disabled]=\"label.invalid\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the "Add current page" button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n</ng-template>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: ChangeIconComponent, selector: "c8y-change-icon", inputs: ["currentIcon"], outputs: ["onButtonClick"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PopoverConfirmComponent, selector: "c8y-popover-confirm", inputs: ["buttons", "message", "title", "isOpen", "containerClass", "placement", "outsideClick", "adaptivePosition", "container"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EditBookmarksComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-edit-bookmarks', imports: [
IconDirective,
C8yTranslateDirective,
NgIf,
ListGroupComponent,
CdkDropList,
NgFor,
ListItemComponent,
CdkDrag,
ListItemDragHandleComponent,
CdkDragHandle,
ListItemIconComponent,
ChangeIconComponent,
FormsModule,
PopoverConfirmComponent,
EmptyStateComponent,
C8yTranslatePipe
], template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n *ngIf=\"bookmarks.length; else emptyList\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks?.length < 2\"\n >\n <c8y-li\n *ngFor=\"let bookmark of bookmarks\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n <c8y-li-icon\n style=\"{{ bookmarks?.length < 2 ? 'padding-left: 16px!important' : '' }}\"\n *ngIf=\"bookmark.icon\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n\n <div class=\"d-flex gap-8 a-i-center\">\n <form\n class=\"d-flex flex-grow\"\n name=\"bookmarksForm\"\n #bookmarksForm=\"ngForm\"\n >\n <div class=\"input-group input-group-editable\">\n <input\n class=\"form-control fit-w\"\n title=\"{{ bookmark.label }}\"\n id=\"label\"\n name=\"label\"\n type=\"text\"\n [(ngModel)]=\"bookmark.label\"\n #label=\"ngModel\"\n maxlength=\"50\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n (click)=\"updateBookmark(bookmark, 'label'); label.control.markAsPristine()\"\n [disabled]=\"label.invalid\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the "Add current page" button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i1.AlertService }, { type: BookmarkService }, { type: i4.IconSelectorService }], propDecorators: { bookmarks: [{
type: Input
}], handleKeyboardEvent: [{
type: HostListener,
args: ['document:keydown', ['$event']]
}] } });
class BookmarksComponent {
constructor(document, alertService, bookmarkService, bsModalService, router, headerService) {
this.document = document;
this.alertService = alertService;
this.bookmarkService = bookmarkService;
this.bsModalService = bsModalService;
this.router = router;
this.headerService = headerService;
this.bookmarks = [];
this.emptyMessageHeader = gettext('No bookmarks yet');
this.emptyMessageBody = gettext('Navigate to the desired page and click the "Add current page" button. Editing, deleting and reordering are possible by clicking on the cog wheel.');
this.addButtonText = gettext('Add current page');
this.drawerOpen$ = this.headerService.rightDrawerOpen$;
}
async ngOnInit() {
this.bookmarks = await this.bookmarkService.getBookmarks();
}
async addBookmark() {
const currentUrl = this.getRelativeUrl();
if (this.bookmarks.some(bookmark => this.toRelativeUrl(bookmark.url) === currentUrl)) {
this.alertService.warning(gettext('Bookmark with the same URL is already added.'));
return;
}
const icon = await this.bookmarkService.getActiveNodeIcon();
const linkObject = this.bookmarkService.convertBookmarkLinkToObject(this.document.title, currentUrl, icon);
this.bookmarks.push(linkObject);
await this.bookmarkService.updateBookmarksInStorage(this.bookmarks);
this.alertService.success(gettext('Bookmark added.'));
}
async editBookmarks() {
try {
const initialState = {
bookmarks: cloneDeep(this.bookmarks)
};
const modalRef = this.bsModalService.show(EditBookmarksComponent, {
class: 'modal-md',
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title',
initialState: initialState,
ignoreBackdropClick: true
}).content;
this.bookmarks = await modalRef.result;
}
catch (err) {
return;
}
}
openUrl(url) {
if (this.isRelativeUrl(url)) {
if (this.isSameApp(url)) {
const hash = url.includes('#') ? url.substring(url.indexOf('#') + 1) : '/';
this.router.navigateByUrl(hash);
}
else {
window.open(`${location.origin}${url}`, '_self');
}
return;
}
// Legacy support for absolute URLs stored before the relative URL migration
const parsedUrl = new URL(url);
const relativePath = `${parsedUrl.pathname}${parsedUrl.hash}`;
if (this.isSameApp(relativePath)) {
const hash = parsedUrl.hash ? parsedUrl.hash.substring(1) : '/';
this.router.navigateByUrl(hash);
}
else {
window.open(`${location.origin}${relativePath}`, '_self');
}
}
getRelativeUrl() {
const { pathname, hash } = this.document.location;
return `${pathname}${hash}`;
}
isRelativeUrl(url) {
return url.startsWith('/');
}
isSameApp(url) {
return url.startsWith(location.pathname);
}
toRelativeUrl(url) {
if (this.isRelativeUrl(url)) {
return url;
}
try {
const parsed = new URL(url);
return `${parsed.pathname}${parsed.hash}`;
}
catch {
return url;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarksComponent, deps: [{ token: DOCUMENT }, { token: i1.AlertService }, { token: BookmarkService }, { token: i1$1.BsModalService }, { token: i2.Router }, { token: i1.HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: BookmarksComponent, isStandalone: true, selector: "c8y-bookmarks", ngImport: i0, template: "<div class=\"separator-top p-t-8 m-t-auto c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Bookmarks' | translate }}</span>\n <button\n class=\"btn-dot m-l-auto\"\n [attr.aria-label]=\"'Edit bookmarks' | translate\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n tooltip=\"{{ 'Edit bookmarks' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n (click)=\"editBookmarks()\"\n >\n <i\n class=\"text-14 m-0\"\n c8yIcon=\"cog\"\n ></i>\n </button>\n</div>\n@if (bookmarks?.length) {\n <div class=\"c8y-right-drawer__item p-t-0 p-b-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n}\n@if (bookmarks?.length) {\n @for (bookmark of bookmarks; track bookmark.url) {\n <button\n class=\"c8y-right-drawer__link\"\n title=\"{{ bookmark.label }}\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"openUrl(bookmark.url)\"\n >\n @if (bookmark.icon) {\n <i [c8yIcon]=\"bookmark.icon\"></i>\n }\n <span class=\"text-truncate\">{{ bookmark.label }}</span>\n </button>\n }\n}\n\n<div class=\"p-t-8 p-b-8\">\n @if (!bookmarks?.length) {\n <span class=\"c8y-right-drawer__item text-muted text-bold text-14 p-b-0\">\n {{ emptyMessageHeader | translate }}\n </span>\n <span class=\"c8y-right-drawer__item text-12 p-t-0\">\n <span class=\"text-muted\">{{ emptyMessageBody | translate }}</span>\n </span>\n <div class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarksComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-bookmarks', imports: [IconDirective, TooltipDirective, C8yTranslatePipe, AsyncPipe], template: "<div class=\"separator-top p-t-8 m-t-auto c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Bookmarks' | translate }}</span>\n <button\n class=\"btn-dot m-l-auto\"\n [attr.aria-label]=\"'Edit bookmarks' | translate\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n tooltip=\"{{ 'Edit bookmarks' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n (click)=\"editBookmarks()\"\n >\n <i\n class=\"text-14 m-0\"\n c8yIcon=\"cog\"\n ></i>\n </button>\n</div>\n@if (bookmarks?.length) {\n <div class=\"c8y-right-drawer__item p-t-0 p-b-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n}\n@if (bookmarks?.length) {\n @for (bookmark of bookmarks; track bookmark.url) {\n <button\n class=\"c8y-right-drawer__link\"\n title=\"{{ bookmark.label }}\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"openUrl(bookmark.url)\"\n >\n @if (bookmark.icon) {\n <i [c8yIcon]=\"bookmark.icon\"></i>\n }\n <span class=\"text-truncate\">{{ bookmark.label }}</span>\n </button>\n }\n}\n\n<div class=\"p-t-8 p-b-8\">\n @if (!bookmarks?.length) {\n <span class=\"c8y-right-drawer__item text-muted text-bold text-14 p-b-0\">\n {{ emptyMessageHeader | translate }}\n </span>\n <span class=\"c8y-right-drawer__item text-12 p-t-0\">\n <span class=\"text-muted\">{{ emptyMessageBody | translate }}</span>\n </span>\n <div class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n }\n</div>\n" }]
}], ctorParameters: () => [{ type: DOCUMENT, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i1.AlertService }, { type: BookmarkService }, { type: i1$1.BsModalService }, { type: i2.Router }, { type: i1.HeaderService }] });
class BookmarksModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarksModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: BookmarksModule, imports: [CoreModule,
CommonModule,
ListGroupModule,
DragDropModule,
FormsModule,
FormsModule$1,
ModalModule, i1$2.TooltipModule, ChangeIconComponent,
BookmarksComponent,
EditBookmarksComponent], exports: [BookmarksComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarksModule, providers: [
hookDrawer({
component: BookmarksComponent,
position: 'right',
priority: 50,
id: 'bookmarks'
})
], imports: [CoreModule,
CommonModule,
ListGroupModule,
DragDropModule,
FormsModule,
FormsModule$1,
ModalModule,
TooltipModule.forRoot(),
ChangeIconComponent,
EditBookmarksComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BookmarksModule, decorators: [{
type: NgModule,
args: [{
imports: [
CoreModule,
CommonModule,
ListGroupModule,
DragDropModule,
FormsModule,
FormsModule$1,
ModalModule,
TooltipModule.forRoot(),
ChangeIconComponent,
BookmarksComponent,
EditBookmarksComponent
],
exports: [BookmarksComponent],
providers: [
hookDrawer({
component: BookmarksComponent,
position: 'right',
priority: 50,
id: 'bookmarks'
})
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { BookmarksComponent, BookmarksModule, EditBookmarksComponent };
//# sourceMappingURL=c8y-ngx-components-bookmarks.mjs.map