<commit_before>import { HttpResponse } from '@angular/common/http';
import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/core';
import { Notification, QueryFilters } from 'app/api/models';
import { NotificationsService } from 'app/api/services';
import { HeadingAction } from 'app/shared/action';
import { ApiHelper } from 'app/shared/api-helper';
import { BaseSearchPageComponent } from 'app/shared/base-search-page.component';
import { Menu } from 'app/shared/menu';
import { forkJoin, Observable } from 'rxjs';
import { first } from 'rxjs/operators';

type NotificationSearchParams = QueryFilters & { onlyUnread: boolean };

/**
 * Displays a search for notifications
 */
@Component({
  selector: 'search-notifications',
  templateUrl: 'search-notifications.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SearchNotificationsComponent
  extends BaseSearchPageComponent<any, NotificationSearchParams, Notification>
  implements OnInit {

  constructor(
    injector: Injector,
    private notificationsService: NotificationsService,
  ) {
    super(injector);
  }

  ngOnInit() {
    super.ngOnInit();

    // Whenever a new notification arrives, update the list
    this.addSub(this.notification.notificationsStatus$.subscribe(() => this.update()));

    // Update the data with any non-null value, so the search page is properly initialized
    this.data = {};

    // Send a background request indicating the last time notifications were viewed
    this.addSub(this.notificationsService.markAsViewed().pipe(first()).subscribe(() => {
      // And then immediately update the current notifications status
      const status$ = this.notification.notificationsStatus$;
      const status = { ...status$.value };
      status.lastViewDate = this.dataForUiHolder.now().toISOString();
      status.newNotifications = 0;
      status$.next(status);
    }));

    // Update the heading actions with the mark all as read if there's any unread notifications
    this.addSub(this.results$.subscribe(results => {
      const headingActions = [];
      const notifications = ((results ? results.results : null) || []);
      const unread = notifications.filter(n => !n.read);
      if (unread.length > 0) {
        headingActions.push(new HeadingAction('done_all', this.i18n.notification.actions.markAllRead, () => this.markAllRead()));
      }
      if (notifications.length > 0) {
        headingActions.push(new HeadingAction('clear', this.i18n.notification.actions.removeAll, () => this.removeAll()));
      }
      this.headingActions = headingActions;
    }));
  }

  rowClick(notification: Notification) {
    // Mark as read
    this.addSub(this.notificationsService.markNotificationsAsRead({ ids: [notification.id] }).subscribe());

    // If a known path, navigate
    const path = this.path(notification);
    if (path) {
      this.router.navigateByUrl(path);
    }
  }

  remove(notification: Notification) {<commit_msg>Fixes #339<commit_after>import { HttpResponse } from '@angular/common/http';
import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/core';
import { Notification, QueryFilters } from 'app/api/models';
import { NotificationsService } from 'app/api/services';
import { HeadingAction } from 'app/shared/action';
import { ApiHelper } from 'app/shared/api-helper';
import { BaseSearchPageComponent } from 'app/shared/base-search-page.component';
import { Menu } from 'app/shared/menu';
import { forkJoin, Observable } from 'rxjs';
import { first, skip } from 'rxjs/operators';

type NotificationSearchParams = QueryFilters & { onlyUnread: boolean };

/**
 * Displays a search for notifications
 */
@Component({
  selector: 'search-notifications',
  templateUrl: 'search-notifications.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SearchNotificationsComponent
  extends BaseSearchPageComponent<any, NotificationSearchParams, Notification>
  implements OnInit {

  constructor(
    injector: Injector,
    private notificationsService: NotificationsService,
  ) {
    super(injector);
  }

  ngOnInit() {
    super.ngOnInit();

    // Update the data with any non-null value, so the search page is properly initialized
    this.data = {};

    // Send a background request indicating the last time notifications were viewed
    this.addSub(this.notificationsService.markAsViewed().pipe(first()).subscribe(() => {
      // And then immediately update the current notifications status
      const status$ = this.notification.notificationsStatus$;
      const status = { ...status$.value };
      status.lastViewDate = this.dataForUiHolder.now().toISOString();
      status.newNotifications = 0;
      status$.next(status);
      // Whenever a new notification arrives, update the list
      // Skip first subscription invocation to avoid duplicate initial search
      this.addSub(this.notification.notificationsStatus$.pipe(skip(1)).subscribe(() => this.update()));
    }));

    // Update the heading actions with the mark all as read if there's any unread notifications
    this.addSub(this.results$.subscribe(results => {
      const headingActions = [];
      const notifications = ((results ? results.results : null) || []);
      const unread = notifications.filter(n => !n.read);
      if (unread.length > 0) {
        headingActions.push(new HeadingAction('done_all', this.i18n.notification.actions.markAllRead, () => this.markAllRead()));
      }
      if (notifications.length > 0) {
        headingActions.push(new HeadingAction('clear', this.i18n.notification.actions.removeAll, () => this.removeAll()));
      }
      this.headingActions = headingActions;
    }));
  }

  rowClick(notification: Notification) {
    // Mark as read
    this.addSub(this.notificationsService.markNotificationsAsRead({ ids: [notification.id] }).subscribe());

    // If a known path, navigate
    const path = this.path(notification);
    if (path) {
      this.router.navigateByUrl(path);
    }
  }

  remove(notification: Notification) {
{'fraction_non_alphanumeric': 0.12269433465085638, 'fraction_numerical': 0.0029644268774703555, 'mean_word_length': 3.941415785191212, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4043918', 'n_tokens_mistral': 1678, 'n_tokens_neox': 1631, 'n_words': 413}