Skip to content

Release/1.1.0 #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "etask-frontend",
"version": "1.0.0",
"version": "1.1.0",
"scripts": {
"ng": "ng",
"start": "ng serve --configuration development",
Expand All @@ -27,8 +27,8 @@
"@angular/platform-browser-dynamic": "~13.3.1",
"@angular/router": "~13.3.1",
"@covalent/markdown": "~4.1.0",
"@netgrif/components": "6.3.1",
"@netgrif/components-core": "6.3.1",
"@netgrif/components": "6.4.0",
"@netgrif/components-core": "6.4.0",
"@ngx-translate/core": "~13.0.0",
"@ngx-translate/http-loader": "~6.0.0",
"@schematics/angular": "~13.3.0",
Expand Down
74 changes: 35 additions & 39 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FlexLayoutModule, FlexModule} from '@angular/flex-layout';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexLayoutModule, FlexModule } from '@angular/flex-layout';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
AuthenticationComponentModule,
CaseViewComponentModule,
DashboardComponentModule,
DataFieldsComponentModule,
DialogComponentsModule,
HeaderComponentModule,
ImportNetComponent,
LoginFormComponentModule,
NavigationComponentModule,
NewCaseComponent,
PanelComponentModule,
QuickPanelComponentModule,
RoleAssignmentComponent,
SearchComponentModule,
SideMenuComponentModule,
SideMenuContentComponentModule,
Expand All @@ -34,36 +32,35 @@ import {
UriResourceService,
ViewService,
} from '@netgrif/components-core';
import {PieChartModule} from '@swimlane/ngx-charts';
import {ResizableModule} from 'angular-resizable-element';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {EtaskFrontendConfigurationService} from './etask-frontend-configuration.service';
import {EtaskFrontendViewService} from './etask-frontend-view.service';
import {DashboardComponent} from './views/dashboard/dashboard/dashboard.component';
import {EtaskUriResourceService} from './views/dashboard/service/etask-uri-resource.service';
import {LoginComponent} from './views/login/login.component';
import { PieChartModule } from '@swimlane/ngx-charts';
import { ResizableModule } from 'angular-resizable-element';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { EtaskFrontendConfigurationService } from './etask-frontend-configuration.service';
import { EtaskFrontendViewService } from './etask-frontend-view.service';
import { DashboardComponent } from './views/dashboard/dashboard/dashboard.component';
import { EtaskUriResourceService } from './views/dashboard/service/etask-uri-resource.service';
import { LoginComponent } from './views/login/login.component';
import {
EtaskTaskListPaginationComponent,
} from './views/panel/task-panel-list-pagination/etask-task-list-pagination.component';
import {EtaskTaskListComponent} from './views/panel/task-panel-list/etask-task-list.component';
import {EtaskTaskPanelComponent} from './views/panel/task-panel/etask-task-panel.component';
import {PublicResolverComponent} from './views/public/public-resolver/public-resolver.component';
import {PublicSingleTaskViewComponent} from './views/public/public-single-task-view/public-single-task-view.component';
import {PublicTaskViewComponent} from './views/public/public-task-view/public-task-view.component';
import {PublicWorkflowViewComponent} from './views/public/public-workflow-view/public-workflow-view.component';
import {ETaskTaskResourceService} from './views/public/service/e-task-task-resource.service';
import {SideNavCasesCaseViewComponent} from './views/side-nav/cases/side-nav-cases-case-view.component';
import {EmptyViewComponent} from './views/side-nav/emptyView/empty-view.component';
import {ETaskDoubleDrawerComponent} from './views/side-nav/etask-double-drawer/e-task-double-drawer.component';
import { EtaskTaskListComponent } from './views/panel/task-panel-list/etask-task-list.component';
import { EtaskTaskPanelComponent } from './views/panel/task-panel/etask-task-panel.component';
import { PublicResolverComponent } from './views/public/public-resolver/public-resolver.component';
import { PublicSingleTaskViewComponent } from './views/public/public-single-task-view/public-single-task-view.component';
import { PublicTaskViewComponent } from './views/public/public-task-view/public-task-view.component';
import { PublicWorkflowViewComponent } from './views/public/public-workflow-view/public-workflow-view.component';
import { ETaskTaskResourceService } from './views/public/service/e-task-task-resource.service';
import { SideNavCasesCaseViewComponent } from './views/side-nav/cases/side-nav-cases-case-view.component';
import { EmptyViewComponent } from './views/side-nav/emptyView/empty-view.component';
import { ETaskDoubleDrawerComponent } from './views/side-nav/etask-double-drawer/e-task-double-drawer.component';
import {
EtaskGroupNavigationComponentResolverService,
} from './views/side-nav/service/etask-group-navigation-component-resolver.service';
import {SidenavComponent} from './views/side-nav/sidenav.component';
import {EtaskTabViewComponent} from './views/side-nav/tab-view/etask-tab-view.component';
import {SideNavTasksTaskViewComponent} from './views/side-nav/tasks/side-nav-tasks-task-view.component';
import {WorkflowPanelComponent} from './views/workflow/workflow-panel/workflow-panel.component';
import {WorkflowViewComponent} from './views/workflow/workflow-view/workflow-view.component';
import { SidenavComponent } from './views/side-nav/sidenav.component';
import { SideNavTasksTaskViewComponent } from './views/side-nav/tasks/side-nav-tasks-task-view.component';
import { WorkflowPanelComponent } from './views/workflow/workflow-panel/workflow-panel.component';
import { WorkflowViewComponent } from './views/workflow/workflow-view/workflow-view.component';


@NgModule({
Expand All @@ -86,9 +83,7 @@ import {WorkflowViewComponent} from './views/workflow/workflow-view/workflow-vie
ETaskDoubleDrawerComponent,
WorkflowPanelComponent,
WorkflowViewComponent,
EtaskTabViewComponent,
],
entryComponents: [NewCaseComponent, LoginComponent, SidenavComponent, DashboardComponent, ImportNetComponent, RoleAssignmentComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
Expand Down Expand Up @@ -120,13 +115,14 @@ import {WorkflowViewComponent} from './views/workflow/workflow-view/workflow-vie
HeaderComponentModule,
PanelComponentModule,
DataFieldsComponentModule,
DialogComponentsModule
],
providers: [
{provide: ConfigurationService, useClass: EtaskFrontendConfigurationService},
{provide: ViewService, useClass: EtaskFrontendViewService},
{provide: TaskResourceService, useClass: ETaskTaskResourceService},
{provide: UriResourceService, useClass: EtaskUriResourceService},
{provide: GroupNavigationComponentResolverService, useClass: EtaskGroupNavigationComponentResolverService},
{ provide: ConfigurationService, useClass: EtaskFrontendConfigurationService },
{ provide: ViewService, useClass: EtaskFrontendViewService },
{ provide: TaskResourceService, useClass: ETaskTaskResourceService },
{ provide: UriResourceService, useClass: EtaskUriResourceService },
{ provide: GroupNavigationComponentResolverService, useClass: EtaskGroupNavigationComponentResolverService },
],
})
export class AppModule {
Expand Down
125 changes: 93 additions & 32 deletions src/app/views/dashboard/dashboard/dashboard.component.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import {
AccessService,
Case,
CaseResourceService,
CaseSearchRequestBody,
DynamicNavigationRouteProviderService,
FILTER_IDENTIFIERS,
FILTER_VIEW_TASK_TRANSITION_ID,
FilterExtractionService,
GroupNavigationConstants,
LoadingEmitter,
MENU_IDENTIFIERS,
NavigationItem,
Page,
PaginationParams,
PetriNetSearchRequest,
RoleAccess,
SETTINGS_TRANSITION_ID,
SimpleFilter,
TaskResourceService,
User,
UserService,
ViewNavigationItem,
UriService,
User, UserService,
} from '@netgrif/components-core';
import {Subscription} from 'rxjs';
import {map} from 'rxjs/operators';
import { Observable, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import custom_views from '../../../../assets/custom_views.json';
import icons from '../../../../assets/uriNodeIcons.json';
import {ETaskUriNodeResource} from '../service/etask-uri-resource.service';
import {EtaskUriService} from '../service/etask-uri.service';
import { ETaskUriNodeResource } from '../service/etask-uri-resource.service';
import { EtaskUriService } from '../service/etask-uri.service';
import { I18nFieldValue } from '@netgrif/components-core/lib/data-fields/i18n-field/models/i18n-field-value';
import { TranslateService } from '@ngx-translate/core';
import { HttpParams } from '@angular/common/http';


@Component({
Expand All @@ -30,12 +40,14 @@ import {EtaskUriService} from '../service/etask-uri.service';
export class DashboardComponent implements OnInit, OnDestroy {
public nodes: Array<ETaskUriNodeResource> = [];

public customViews: Array<ViewNavigationItem> = [];
public customViews: Array<NavigationItem> = [];
protected _counters: Map<string, number> = new Map<string, number>();

private _sub: Subscription;
private _loading: LoadingEmitter;

private filterIcon: string = 'filter_alt';

constructor(
private _user: UserService,
private _uri: EtaskUriService,
Expand All @@ -44,6 +56,8 @@ export class DashboardComponent implements OnInit, OnDestroy {
private _filterExtraction: FilterExtractionService,
private _dynamicRoutingService: DynamicNavigationRouteProviderService,
private _accessService: AccessService,
protected _translateService: TranslateService,
private _caseResourceService: CaseResourceService,
) {
this._loading = new LoadingEmitter();
}
Expand All @@ -59,15 +73,16 @@ export class DashboardComponent implements OnInit, OnDestroy {
this._loading.off();
});

this._uri.getCasesOfNode(this._uri.root, FILTER_IDENTIFIERS).pipe(
this._uri.getCasesOfNode(this._uri.root, MENU_IDENTIFIERS).pipe(
map(cases => {
const filteredViews = cases
.content.filter(it => custom_views.includes(it.immediateData.find(f => f.stringId === 'menu_item_identifier')?.value))
.sort((a, b) => this.getViewOrder(a) - this.getViewOrder(b));
return filteredViews.map(it => this.resolveFilterCaseToViewNavigationItem(it)).filter(it => !!it);
return filteredViews.map(it => this.resolveFilterCaseToNavigationItem(it)).filter(it => !!it);
}),
).subscribe(views => {
this.customViews = views;
// TODO not counting custom views
this.getCountForViews(this.customViews);
});
}
Expand All @@ -79,9 +94,40 @@ export class DashboardComponent implements OnInit, OnDestroy {
return this._uri.getCachedNodeCount(name);
}

/* from AbstractNavigationDoubleDrawerComponent */
protected extractChildCaseIds(item: Case): string[] {
return item.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_CHILD_ITEM_IDS)?.value
}

/* from AbstractNavigationDoubleDrawerComponent */
protected getItemCasesByIds(caseIds: string[], pageNumber: number, pageSize: string | number): Observable<Page<Case>> {
const searchBody: CaseSearchRequestBody = {
stringId: caseIds,
process: MENU_IDENTIFIERS.map(id => ({ identifier: id } as PetriNetSearchRequest))
};

let httpParams = new HttpParams()
.set(PaginationParams.PAGE_SIZE, pageSize)
.set(PaginationParams.PAGE_NUMBER, pageNumber);
return this._caseResourceService.searchCases(SimpleFilter.fromCaseQuery(searchBody), httpParams);
}

public openNode(node: ETaskUriNodeResource) {
this._uri.activeNode = node;
this._router.navigate(['portal']);
this._uri.getItemCaseByNodePath(node).subscribe(cases => {
let nodeItemCase = cases.content.pop();
let childCaseIds = this.extractChildCaseIds(nodeItemCase);
let childCases$ = this.getItemCasesByIds(childCaseIds, 0, childCaseIds.length).pipe(map(p => p.content));

childCases$.subscribe(result => {
result = (result as Case[])
result.map(folder => this.resolveFilterCaseToNavigationItem(folder)).filter(i => !!i);
let firstCase = result[0]
let taskDefault = firstCase.tasks.find(taskPair => taskPair.transition == SETTINGS_TRANSITION_ID).task;
this._router.navigate(['portal', 'filter', taskDefault]);
});
});

}

public getNodeIcon(node: ETaskUriNodeResource) {
Expand All @@ -92,24 +138,25 @@ export class DashboardComponent implements OnInit, OnDestroy {
}

/* custom views */
public countView(view: ViewNavigationItem) {
public countView(view: NavigationItem) {
return this.isCountLoaded(view) ? this._counters.get(view.id) : 0;
}

public isCountLoaded(view: ViewNavigationItem) {
public isCountLoaded(view: NavigationItem) {
return this._counters.has(view.id);
}

public areCountersLoaded(): boolean {
return !this._loading.getValue();
}

public getCountForViews(customViews: Array<ViewNavigationItem>) {
// TODO rozdrbane
public getCountForViews(customViews: Array<NavigationItem>) {
if (!customViews) {
return;
}
customViews.forEach(view => {
const taskId = view.resource.tasks.find(taskPair => taskPair.transition === FILTER_VIEW_TASK_TRANSITION_ID).task;
const taskId = view.resource.tasks.find(taskPair => taskPair.transition === SETTINGS_TRANSITION_ID).task;
this._taskResource.getData(taskId).subscribe(taskData => {
const filter = this._filterExtraction.extractCompleteFilterFromData(taskData);
this._taskResource.count(filter).subscribe(count => {
Expand All @@ -119,7 +166,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
});
}

public openView(view: ViewNavigationItem) {
public openView(view: NavigationItem) {
this._uri.activeNode = this._uri.root;
this._router.navigate([view.routing.path]);
}
Expand All @@ -145,32 +192,46 @@ export class DashboardComponent implements OnInit, OnDestroy {
}

/* from AbstractNavigationDoubleDrawerComponent */
protected resolveFilterCaseToViewNavigationItem(filter: Case): ViewNavigationItem | undefined {
const item: ViewNavigationItem = {
protected representsRootNode(item: Case): boolean {
return item.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_NODE_PATH).value === "/"
}

/* from AbstractNavigationDoubleDrawerComponent */
protected resolveFilterCaseToNavigationItem(itemCase: Case): NavigationItem | undefined {
if (this.representsRootNode(itemCase)) {
return
}
const item: NavigationItem = {
access: {},
navigation: {
icon: filter.immediateData.find(f => f.stringId === 'icon_name')?.value,
title: filter.immediateData.find(f => f.stringId === 'entry_name')?.value?.defaultValue || filter.title,
icon: itemCase.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_MENU_ICON)?.value || this.filterIcon,
title: this.getTranslation(itemCase.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_MENU_NAME)?.value) || itemCase.title,
},
routing: {
path: this.getFilterRoutingPath(filter),
path: this.getItemRoutingPath(itemCase),
},
id: filter.stringId,
resource: filter,
id: itemCase.stringId,
resource: itemCase,
};
const resolvedRoles = this.resolveAccessRoles(filter, 'allowed_roles');
const resolvedBannedRoles = this.resolveAccessRoles(filter, 'banned_roles');
const resolvedRoles = this.resolveAccessRoles(itemCase, GroupNavigationConstants.ITEM_FIELD_ID_ALLOWED_ROLES);
const resolvedBannedRoles = this.resolveAccessRoles(itemCase, GroupNavigationConstants.ITEM_FIELD_ID_BANNED_ROLES);
if (!!resolvedRoles) item.access['role'] = resolvedRoles;
if (!!resolvedBannedRoles) item.access['bannedRole'] = resolvedBannedRoles;
if (!this._accessService.canAccessView(item, item.routingPath)) return;
return item;
}

/* from AbstractNavigationDoubleDrawerComponent */
protected getFilterRoutingPath(filterCase: Case) {
const viewTaskId = filterCase.tasks.find(taskPair => taskPair.transition === FILTER_VIEW_TASK_TRANSITION_ID).task;
protected getTranslation(value: I18nFieldValue): string {
const locale = this._translateService.currentLang.split('-')[0];
return locale in value.translations ? value.translations[locale] : value.defaultValue;
}

/* from AbstractNavigationDoubleDrawerComponent */
protected getItemRoutingPath(itemCase: Case) {
const taskId = itemCase.tasks.find(taskPair => taskPair.transition === SETTINGS_TRANSITION_ID).task;
const url = this._dynamicRoutingService.route;
return `/${url}/${viewTaskId}`;
return `/${url}/${taskId}`;
}

/* from AbstractNavigationDoubleDrawerComponent */
Expand Down
14 changes: 7 additions & 7 deletions src/app/views/dashboard/service/etask-uri.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Injectable} from '@angular/core';
import { Injectable } from '@angular/core';
import {
ActiveGroupService,
CaseResourceService,
Expand All @@ -7,8 +7,8 @@ import {
UriService,
UserService,
} from '@netgrif/components-core';
import {Observable, Subject} from 'rxjs';
import {ETaskUriNodeResource, EtaskUriResourceService} from './etask-uri-resource.service';
import { Observable, Subject } from 'rxjs';
import { ETaskUriNodeResource, EtaskUriResourceService } from './etask-uri-resource.service';

@Injectable({
providedIn: 'root',
Expand All @@ -18,10 +18,10 @@ export class EtaskUriService extends UriService {
protected _counters: Map<string, number>;

constructor(protected userService: UserService,
_logger: LoggerService,
_resourceService: EtaskUriResourceService,
_caseResourceService: CaseResourceService,
_activeGroupService: ActiveGroupService) {
_logger: LoggerService,
_resourceService: EtaskUriResourceService,
_caseResourceService: CaseResourceService,
_activeGroupService: ActiveGroupService) {
// TODO load page size from injection token
super(_logger, _resourceService, _caseResourceService, _activeGroupService, 100);
this._counters = new Map<string, number>();
Expand Down
Loading