Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ export const RowActionMenuLabel = {
REMOVE_ACCESSGROUP_AGENT: 'Remove Agent',
REMOVE_ACCESSGROUP_USER: 'Remove User',
ARCHIVE_PRETASK: 'Archive PreTask',
UNARCHIVE_PRETASK: 'Unarchive PreTask'
UNARCHIVE_PRETASK: 'Unarchive PreTask',
SHOW_SUBTASK: 'Show Subtasks'
};

export const RowActionMenuAction = {
Expand All @@ -72,6 +73,7 @@ export const RowActionMenuAction = {
COPY_TO_PRETASK: 'copy-to-pretask',
EDIT_TASKS: 'edit-tasks',
EDIT_SUBTASKS: 'edit-subtasks',
SHOW_SUBTASKS: 'show-subtasks',
NEW: 'new',
IMPORT: 'import',
EXPORT: 'export',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { UIConfig, uiConfigDefault } from '@models/config-ui.model';
import { JHashlist } from '@models/hashlist.model';
import { JNotification } from '@models/notification.model';
import { JSuperTask } from '@models/supertask.model';
import { JTask, JTaskWrapper, TaskType } from '@models/task.model';
import { JUser } from '@models/user.model';

import { ContextMenuService } from '@services/context-menu/base/context-menu.service';
Expand Down Expand Up @@ -111,7 +112,7 @@ export class BaseTableComponent {
* @param chunk - chunk object to render router link for
* @return observable object containing a router link array
*/
renderCrackedLink(chunk: JChunk): Observable<HTTableRouterLink[]> {
renderCrackedLinkFromChunk(chunk: JChunk): Observable<HTTableRouterLink[]> {
const links: HTTableRouterLink[] = [];
if (chunk) {
links.push({
Expand All @@ -122,6 +123,44 @@ export class BaseTableComponent {
return of(links);
}

/**
* Render cracked link from task object to be displayed in HTML code
* @return observable object containing a router link array
* @param task
*/
renderCrackedLinkFromTask(task: JTask): Observable<HTTableRouterLink[]> {
const links: HTTableRouterLink[] = [];
if (task.chunkData.cracked) {
links.push({
routerLink: ['/hashlists', 'hashes', 'tasks', task.id],
label: task.chunkData.cracked.toLocaleString()
});
}
return of(links);
}

/**
* Render router link to show cracked hashes for a task if any.
* For supertasks only the cracked number as text is shown
* @param wrapper - the task wrapper object to render the link for
* @return observable containing an array of router links to be rendered in HTML
*/
protected renderCrackedLinkFromWrapper(wrapper: JTaskWrapper): Observable<HTTableRouterLink[]> {
if (wrapper.cracked === 0) {
return of([{ label: null, routerLink: null }]);
}

const isSupertask = wrapper.taskType === TaskType.SUPERTASK;

const link: HTTableRouterLink = {
label: wrapper.cracked.toLocaleString(),
routerLink: isSupertask ? null : ['/hashlists', 'hashes', 'tasks', wrapper.tasks[0].id],
tooltip: isSupertask ? 'Please access the cracked hashes via the row\'s context menu "show subtasks"' : undefined
};

return of([link]);
}

/**
* Render hashlist link to be displayed in HTML code
* @param hashlist - hashlist object to render router link for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export class ChunksTableComponent extends BaseTableComponent implements OnInit {
{
id: ChunksTableCol.CRACKED,
dataKey: 'cracked',
routerLink: (chunk: JChunk) => this.renderCrackedLink(chunk),
routerLink: (chunk: JChunk) => this.renderCrackedLinkFromChunk(chunk),
isSortable: true
}
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@
}
</span>
<ng-container *ngIf="!tableColumn.truncate">
<app-ht-table-link [tableColumn]="tableColumn" [element]="element"></app-ht-table-link>
<app-ht-table-link (linkClicked)="onLinkClicked();" [tableColumn]="tableColumn" [element]="element"></app-ht-table-link>
<ht-table-default [tableColumn]="tableColumn" [element]="element"></ht-table-default>
<ht-table-editable
[tableColumn]="tableColumn"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ export class HTTableComponent implements OnInit, AfterViewInit, OnDestroy {
@Output() selectedFilterColumnChanged: EventEmitter<string> = new EventEmitter();
@Output() emitCopyRowData: EventEmitter<BaseModel> = new EventEmitter();
@Output() emitFullHashModal: EventEmitter<JHash> = new EventEmitter();
@Output() linkClicked = new EventEmitter();

/** Fetches user customizations */
private uiSettings: UISettingsUtilityClass;

Expand Down Expand Up @@ -280,6 +282,11 @@ export class HTTableComponent implements OnInit, AfterViewInit, OnDestroy {
this.loadingTimeoutSubscription.unsubscribe();
}
}

onLinkClicked() {
this.linkClicked.emit();
}

copyRowDataEmit(event: JHash) {
this.emitCopyRowData.emit(event);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<ng-container *ngIf="tableColumn.routerLink">
<ng-container *ngFor="let link of tableColumn.routerLink(element) | async">
<ng-container *ngFor="let link of tableColumn.routerLink(element) | async trackBy: trackByFn">
<ng-container *ngIf="link.label || link.routerLink">

<!-- If routerLink is set, render as link <a> -->
<ng-container *ngIf="link.routerLink; else plainText">
<a [routerLink]="link.routerLink" [title]="link.tooltip ?? ''" class="link">
<a (click)="onLinkClicked();" [routerLink]="link.routerLink" [title]="link.tooltip ?? ''" class="link">
<ng-container *ngIf="link.label; else fallbackLabel">
{{ link.label }}
</ng-container>
Expand All @@ -19,18 +19,23 @@

<!-- If no routerLink, render as plain text <span> -->
<ng-template #plainText>
<span>
<ng-container *ngIf="link.label; else fallbackPlain">
{{ link.label }}
</ng-container>
<ng-template #fallbackPlain>
{{ element[tableColumn.dataKey] }}
</ng-template>
<ng-container *ngIf="link.icon?.faIcon">
<fa-icon [icon]="link.icon.faIcon" [title]="link.icon.tooltip ?? ''"></fa-icon>
</ng-container>
</span>
<div [matTooltip]="link.tooltip ?? ''">
<span>
<ng-container *ngIf="link.label; else fallbackPlain">
{{ link.label }}
</ng-container>
<ng-template #fallbackPlain>
{{ element[tableColumn.dataKey] }}
</ng-template>
<ng-container *ngIf="link.icon?.faIcon">
<fa-icon [icon]="link.icon.faIcon" [title]="link.icon.tooltip ?? ''"></fa-icon>
</ng-container>
</span>
</div>
</ng-template>

</ng-container>
</ng-container>
</ng-container>


Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';

import { BaseModel } from '@models/base.model';

import { HTTableColumn } from '@components/tables/ht-table/ht-table.models';
import { HTTableColumn, HTTableRouterLink } from '@components/tables/ht-table/ht-table.models';

@Component({
selector: 'app-ht-table-link',
Expand All @@ -13,4 +13,34 @@ import { HTTableColumn } from '@components/tables/ht-table/ht-table.models';
export class HTTableTypeLinkComponent {
@Input() element: BaseModel;
@Input() tableColumn: HTTableColumn;

@Output() linkClicked = new EventEmitter();

onLinkClicked() {
this.linkClicked.emit();
}

/**
* TrackBy function for HTTableRouterLink items in an ngFor loop.
*
* This function helps Angular identify each item uniquely to optimize DOM updates
* by avoiding re-rendering of unchanged items.
*
* Since HTTableRouterLink does not have a unique `id`, this function uses the
* joined `routerLink` array as a unique key. If `routerLink` is empty, it falls back
* to the `label`. If neither is available, it returns the index as a last resort.
*
* @param index - The index of the item in the iterable.
* @param item - The HTTableRouterLink item.
* @returns A unique identifier for the item (string, number, or index).
*/
trackByFn(index: number, item: HTTableRouterLink): string | number {
if (item.routerLink && item.routerLink.length) {
return item.routerLink.join('-');
}
if (item.label) {
return item.label;
}
return index;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class TasksChunksTableComponent extends BaseTableComponent implements OnI
{
id: TasksChunksTableCol.CRACKED,
dataKey: 'cracked',
routerLink: (chunk: JChunk) => this.renderCrackedLink(chunk),
routerLink: (chunk: JChunk) => this.renderCrackedLinkFromChunk(chunk),
isSortable: true
}
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
[dataSource]="dataSource"
[tableColumns]="tableColumns"
[isSelectable]="true"
[contextMenuService]="contextMenuService"
[isFilterable]="true"
[filterFn]="filter"
[isPageable]="true"
(editableSaved)="editableSaved($event)"
(bulkActionClicked)="bulkActionClicked($event)"
(rowActionClicked)="rowActionClicked($event)"
(exportActionClicked)="exportActionClicked($event)"
(linkClicked)="onLinkClick()"
/>

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { catchError, forkJoin } from 'rxjs';

import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { SafeHtml } from '@angular/platform-browser';

import { ChunkData } from '@models/chunk.model';
Expand Down Expand Up @@ -33,6 +33,7 @@ import { convertToLocale } from '@src/app/shared/utils/util';
})
export class TasksSupertasksTableComponent extends BaseTableComponent implements OnInit, OnDestroy {
@Input() supertaskId = 0;
@Output() linkClicked = new EventEmitter<void>();

tableColumns: HTTableColumn[] = [];
dataSource: TasksSupertasksDataSource;
Expand All @@ -55,6 +56,10 @@ export class TasksSupertasksTableComponent extends BaseTableComponent implements
}
}

onLinkClick(): void {
this.linkClicked.emit();
}

filter(item: JTask, filterValue: string): boolean {
return item.taskName.toLowerCase().includes(filterValue);
}
Expand Down Expand Up @@ -83,7 +88,7 @@ export class TasksSupertasksTableComponent extends BaseTableComponent implements
{
id: TasksSupertasksDataSourceTableCol.CRACKED,
dataKey: 'cracked',
//routerLink: (wrapper: JTask) => this.renderCrackedLink(wrapper),
routerLink: (task: JTask) => this.renderCrackedLinkFromTask(task),
isSortable: true
},
{
Expand Down Expand Up @@ -325,7 +330,7 @@ export class TasksSupertasksTableComponent extends BaseTableComponent implements
let val = 0;
try {
val = parseInt(priority);
} catch (error) {
} catch {
// Do nothing
}

Expand Down Expand Up @@ -357,7 +362,7 @@ export class TasksSupertasksTableComponent extends BaseTableComponent implements
let val = 0;
try {
val = parseInt(max);
} catch (error) {
} catch {
// Do nothing
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export class TasksTableComponent extends BaseTableComponent implements OnInit, O
case RowActionMenuAction.EDIT_TASKS:
this.rowActionEdit(event.data);
break;
case RowActionMenuAction.EDIT_SUBTASKS:
case RowActionMenuAction.SHOW_SUBTASKS:
// eslint-disable-next-line no-case-declarations
this.rowActionEditSubtasks(event.data);
break;
Expand Down Expand Up @@ -737,24 +737,6 @@ export class TasksTableComponent extends BaseTableComponent implements OnInit, O
);
}

/**
* Render router link to show cracked hashes for a task if any.
* For supertasks only the cracked number as text is shown
* @param wrapper - the task wrapper object to render the link for
* @return observable containing an array of router links to be rendered in HTML
* @private
*/
private renderCrackedLinkFromWrapper(wrapper: JTaskWrapper): Observable<HTTableRouterLink[]> {
if (wrapper.cracked === 0) {
return of([{ label: null, routerLink: null }]);
}
const link: HTTableRouterLink = {
label: wrapper.cracked.toLocaleString(),
routerLink: wrapper.taskType === TaskType.TASK ? ['/hashlists', 'hashes', 'tasks', wrapper.tasks[0].id] : null
};
return of([link]);
}

/**
* Render router links for any type of tasks for a task wrapper object
* @param wrapper - the task wrapper object to render the link for
Expand Down
22 changes: 12 additions & 10 deletions src/app/core/_datasources/hashes.datasource.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { catchError, finalize, of } from 'rxjs';

import { BaseDataSource } from '@datasources/base.datasource';
import { FilterType } from '@models/request-params.model';
import { JHash } from '@models/hash.model';
import { JsonAPISerializer } from '@services/api/serializer-service';
import { RequestParamBuilder } from '@services/params/builder-implementation.service';
import { FilterType } from '@models/request-params.model';
import { ResponseWrapper } from '@models/response.model';
import { JTask } from '@models/task.model';

import { JsonAPISerializer } from '@services/api/serializer-service';
import { SERV } from '@services/main.config';
import { JTaskWrapper } from '@models/task.model';
import { RequestParamBuilder } from '@services/params/builder-implementation.service';

import { BaseDataSource } from '@datasources/base.datasource';

export class HashesDataSource extends BaseDataSource<JHash> {
private _id = 0;
Expand All @@ -25,23 +27,23 @@ export class HashesDataSource extends BaseDataSource<JHash> {
this.loading = true;

if (this._dataType === 'tasks') {
const paramsTaskwrapper = new RequestParamBuilder().addInitial(this).addInclude('tasks');
const paramsTasks = new RequestParamBuilder().addInitial(this).addInclude('hashlist');

const taskwrapperService = this.service.get(SERV.TASKS_WRAPPER, this._id, paramsTaskwrapper.create());
const taskService = this.service.get(SERV.TASKS, this._id, paramsTasks.create());

this.subscriptions.push(
taskwrapperService
taskService
.pipe(
catchError(() => of([])),
finalize(() => (this.loading = false))
)
.subscribe((response: ResponseWrapper) => {
const taskwrapper = new JsonAPISerializer().deserialize<JTaskWrapper>({
const task = new JsonAPISerializer().deserialize<JTask>({
data: response.data,
included: response.included
});

const hashlistId = taskwrapper.hashlistId;
const hashlistId = task.hashlist.id;

const paramsHashlist = new RequestParamBuilder()
.addInitial(this)
Expand Down
8 changes: 1 addition & 7 deletions src/app/core/_datasources/tasks-supertasks.datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,7 @@ export class TasksSupertasksDataSource extends BaseDataSource<JTask> {
});
const length = response.meta.page.total_elements;

this.setPaginationConfig(
this.pageSize,
length,
this.pageAfter,
this.pageBefore,
this.index
);
this.setPaginationConfig(this.pageSize, length, this.pageAfter, this.pageBefore, this.index);
const subtasks = taskWrappers[0].tasks;

const chunkParams = new RequestParamBuilder().addFilter({
Expand Down
Loading