http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/column-names.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/column-names.service.ts b/metron-interface/metron-alerts/src/app/service/column-names.service.ts new file mode 100644 index 0000000..e289ca2 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/column-names.service.ts @@ -0,0 +1,71 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs/Rx'; +import {Http} from '@angular/http'; + +import {ColumnNames} from '../model/column-names'; +import {DataSource} from './data-source'; + +@Injectable() +export class ColumnNamesService { + + static columnNameToDisplayValueMap = {}; + static columnDisplayValueToNameMap = {}; + + public static getColumnDisplayValue(key: string) { + if (!key) { + return ''; + } + + let displayValue = ColumnNamesService.columnNameToDisplayValueMap[key]; + + return displayValue ? displayValue : key; + } + + public static getColumnDisplayKey(key: string) { + if (!key) { + return key; + } + + let name = ColumnNamesService.columnDisplayValueToNameMap[key]; + + return (!name || name.length === 0) ? key : name; + } + + public static toMap(columnNames: ColumnNames[]) { + ColumnNamesService.columnNameToDisplayValueMap = {}; + ColumnNamesService.columnDisplayValueToNameMap = {}; + + columnNames.forEach(columnName => { + ColumnNamesService.columnNameToDisplayValueMap[columnName.key] = columnName.displayValue; + ColumnNamesService.columnDisplayValueToNameMap[columnName.displayValue] = columnName.key; + }); + } + + constructor(private http: Http, + private dataSource: DataSource) {} + + list(): Promise<ColumnNames[]> { + return this.dataSource.getAlertTableColumnNames().toPromise(); + } + + save(columns: ColumnNames[]): Observable<{}> { + return this.dataSource.saveAlertTableColumnNames(columns); + } +}
http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/configure-table.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/configure-table.service.ts b/metron-interface/metron-alerts/src/app/service/configure-table.service.ts new file mode 100644 index 0000000..5c8f49d --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/configure-table.service.ts @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs/Rx'; +import {Http} from '@angular/http'; +import {Subject} from 'rxjs/Subject'; +import {ColumnMetadata} from '../model/column-metadata'; +import {TableMetadata} from '../model/table-metadata'; +import {DataSource} from './data-source'; + +@Injectable() +export class ConfigureTableService { + + private tableChangedSource = new Subject<string>(); + tableChanged$ = this.tableChangedSource.asObservable(); + + constructor(private http: Http, + private dataSource: DataSource) {} + + fireTableChanged() { + this.tableChangedSource.next('table changed'); + } + + getTableMetadata(): Observable<TableMetadata> { + return this.dataSource.getAlertTableSettings(); + } + + saveColumnMetaData(columns: ColumnMetadata[]): Observable<{}> { + return this.dataSource.saveColumnMetaDataInAlertTableSettings(columns); + } + + saveTableMetaData(tableMetadata: TableMetadata): Observable<TableMetadata> { + return this.dataSource.saveAlertTableSettings(tableMetadata); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/data-source.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/data-source.ts b/metron-interface/metron-alerts/src/app/service/data-source.ts new file mode 100644 index 0000000..242fa3a --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/data-source.ts @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Observable} from 'rxjs/Rx'; +import {Injectable} from '@angular/core'; +import {Http} from '@angular/http'; + +import {Alert} from '../model/alert'; +import {ColumnMetadata} from '../model/column-metadata'; +import {ColumnNames} from '../model/column-names'; +import {TableMetadata} from '../model/table-metadata'; +import {SaveSearch} from '../model/save-search'; +import {AlertsSearchResponse} from '../model/alerts-search-response'; +import {SearchRequest} from '../model/search-request'; + +@Injectable() +export abstract class DataSource { + defaultHeaders: {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'}; + + constructor(protected http: Http) {} + + // Calls to fetch alerts + abstract getAlerts(searchRequest: SearchRequest): Observable<AlertsSearchResponse> + abstract getAlert(index: string, type: string, alertId: string): Observable<Alert> + abstract updateAlertState(request: any): Observable<{}> + + // Calls to fetch default alert table column names and all the field names across all indexes + abstract getDefaultAlertTableColumnNames(): Observable<ColumnMetadata[]> + abstract getAllFieldNames(): Observable<ColumnMetadata[]> + + // Calls to rename field names and to fetch the renamed field names + abstract getAlertTableColumnNames(): Observable<ColumnNames[]> + abstract saveAlertTableColumnNames(columns: ColumnNames[]): Observable<{}> + + // Calls to fetch and save alerts table settings like refresh interval, page size, default selected table column names + abstract getAlertTableSettings(): Observable<TableMetadata> + abstract saveColumnMetaDataInAlertTableSettings(columns: ColumnMetadata[]): Observable<{}> + abstract saveAlertTableSettings(tableMetadata): Observable<TableMetadata> + + // Calls to save search, last 10 searches, saved searches + abstract deleteRecentSearch(saveSearch: SaveSearch): Observable<{}> + abstract deleteSavedSearch(saveSearch: SaveSearch): Observable<{}> + abstract listRecentSearches(): Observable<SaveSearch[]> + abstract listSavedSearches(): Observable<SaveSearch[]> + abstract saveRecentSearch(saveSearch: SaveSearch): Observable<{}> + abstract saveSearch(saveSearch: SaveSearch): Observable<{}> + abstract updateSearch(saveSearch: SaveSearch): Observable<{}> +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts b/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts new file mode 100644 index 0000000..0cd2bce --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts @@ -0,0 +1,294 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Observable} from 'rxjs/Rx'; +import {Headers, RequestOptions} from '@angular/http'; + +import {HttpUtil} from '../utils/httpUtil'; +import {DataSource} from './data-source'; +import {Alert} from '../model/alert'; +import {ColumnMetadata} from '../model/column-metadata'; +import {ElasticsearchUtils} from '../utils/elasticsearch-utils'; +import { + ALERTS_COLUMN_NAMES, ALERTS_TABLE_METADATA, ALERTS_RECENT_SEARCH, + ALERTS_SAVED_SEARCH, NUM_SAVED_SEARCH +} from '../utils/constants'; +import {ColumnNames} from '../model/column-names'; +import {ColumnNamesService} from './column-names.service'; +import {TableMetadata} from '../model/table-metadata'; +import {SaveSearch} from '../model/save-search'; +import {AlertsSearchResponse} from '../model/alerts-search-response'; +import {SearchRequest} from '../model/search-request'; + +export class ElasticSearchLocalstorageImpl extends DataSource { + + private defaultColumnMetadata = [ + new ColumnMetadata('_id', 'string'), + new ColumnMetadata('timestamp', 'date'), + new ColumnMetadata('source:type', 'string'), + new ColumnMetadata('ip_src_addr', 'ip'), + new ColumnMetadata('enrichments:geo:ip_dst_addr:country', 'string'), + new ColumnMetadata('ip_dst_addr', 'ip'), + new ColumnMetadata('host', 'string'), + new ColumnMetadata('alert_status', 'string') + ]; + + getAlerts(searchRequest: SearchRequest): Observable<AlertsSearchResponse> { + let url = '/search/*' + ElasticsearchUtils.excludeIndexName + '/_search'; + let request: any = JSON.parse(JSON.stringify(searchRequest)); + request.query = { query_string: { query: searchRequest.query } }; + + return this.http.post(url, request, new RequestOptions({headers: new Headers(this.defaultHeaders)})) + .map(HttpUtil.extractData) + .map(ElasticsearchUtils.extractAlertsData) + .catch(HttpUtil.handleError) + .onErrorResumeNext(); + } + + getAlert(index: string, type: string, alertId: string): Observable<Alert> { + return this.http.get('/search/' + index + '/' + type + '/' + alertId, new RequestOptions({headers: new Headers(this.defaultHeaders)})) + .map(HttpUtil.extractData); + } + + updateAlertState(request: any) { + return this.http.post('/search/_bulk', request, new RequestOptions({headers: new Headers(this.defaultHeaders)})) + .map(HttpUtil.extractData) + .catch(HttpUtil.handleError); + } + + getDefaultAlertTableColumnNames(): Observable<ColumnMetadata[]> { + return Observable.create(observer => { + observer.next(JSON.parse(JSON.stringify(this.defaultColumnMetadata))); + observer.complete(); + }); + } + + getAllFieldNames(): Observable<ColumnMetadata[]> { + let url = '_cluster/state'; + return this.http.get(url, new RequestOptions({headers: new Headers(this.defaultHeaders)})) + .map(HttpUtil.extractData) + .map(ElasticsearchUtils.extractColumnNameData) + .catch(HttpUtil.handleError); + } + + getAlertTableColumnNames(): Observable<ColumnNames[]> { + return Observable.create(observer => { + let columnNames: ColumnNames[]; + try { + columnNames = JSON.parse(localStorage.getItem(ALERTS_COLUMN_NAMES)); + ColumnNamesService.toMap(columnNames); + } catch (e) {} + + columnNames = columnNames || []; + + observer.next(columnNames); + observer.complete(); + + }); + } + + saveAlertTableColumnNames(columns: ColumnNames[]): Observable<{}> { + return Observable.create(observer => { + try { + localStorage.setItem(ALERTS_COLUMN_NAMES, JSON.stringify(columns)); + } catch (e) {} + ColumnNamesService.toMap(columns); + observer.next({}); + observer.complete(); + + }); + } + + getAlertTableSettings(): Observable<TableMetadata> { + return Observable.create(observer => { + let tableMetadata: TableMetadata; + try { + tableMetadata = TableMetadata.fromJSON(JSON.parse(localStorage.getItem(ALERTS_TABLE_METADATA))); + } catch (e) {} + + observer.next(tableMetadata); + observer.complete(); + + }); + } + + saveColumnMetaDataInAlertTableSettings(columns: ColumnMetadata[]): Observable<{}> { + return Observable.create(observer => { + try { + let tableMetadata = TableMetadata.fromJSON(JSON.parse(localStorage.getItem(ALERTS_TABLE_METADATA))); + tableMetadata.tableColumns = columns; + localStorage.setItem(ALERTS_TABLE_METADATA, JSON.stringify(tableMetadata)); + } catch (e) {} + + observer.next({}); + observer.complete(); + + }); + } + + saveAlertTableSettings(tableMetadata): Observable<TableMetadata> { + return Observable.create(observer => { + try { + localStorage.setItem(ALERTS_TABLE_METADATA, JSON.stringify(tableMetadata)); + } catch (e) {} + + observer.next({}); + observer.complete(); + + }); + } + + deleteRecentSearch(saveSearch: SaveSearch): Observable<{}> { + return Observable.create(observer => { + let recentSearches: SaveSearch[] = []; + try { + recentSearches = JSON.parse(localStorage.getItem(ALERTS_RECENT_SEARCH)); + recentSearches = recentSearches.filter(search => search.name !== saveSearch.name); + } catch (e) {} + + localStorage.setItem(ALERTS_RECENT_SEARCH, JSON.stringify(recentSearches)); + + observer.next({}); + observer.complete(); + + }); + } + + deleteSavedSearch(saveSearch: SaveSearch): Observable<{}> { + return Observable.create(observer => { + let savedSearches: SaveSearch[] = []; + try { + savedSearches = JSON.parse(localStorage.getItem(ALERTS_SAVED_SEARCH)); + savedSearches = savedSearches.filter(search => search.name !== saveSearch.name); + } catch (e) {} + + localStorage.setItem(ALERTS_SAVED_SEARCH, JSON.stringify(savedSearches)); + + observer.next({}); + observer.complete(); + + }); + } + + listRecentSearches(): Observable<SaveSearch[]> { + return Observable.create(observer => { + let savedSearches: SaveSearch[] = []; + try { + savedSearches = JSON.parse(localStorage.getItem(ALERTS_RECENT_SEARCH)); + } catch (e) {} + + savedSearches = savedSearches || []; + savedSearches = savedSearches.map(tSaveSeacrh => SaveSearch.fromJSON(tSaveSeacrh)); + + observer.next(savedSearches); + observer.complete(); + + }); + } + + listSavedSearches(): Observable<SaveSearch[]> { + return Observable.create(observer => { + let savedSearches: SaveSearch[] = []; + try { + savedSearches = JSON.parse(localStorage.getItem(ALERTS_SAVED_SEARCH)); + } catch (e) {} + + savedSearches = savedSearches || []; + savedSearches = savedSearches.map(tSaveSeacrh => SaveSearch.fromJSON(tSaveSeacrh)); + + observer.next(savedSearches); + observer.complete(); + + }); + } + + saveRecentSearch(saveSearch: SaveSearch): Observable<{}> { + return Observable.create(observer => { + let savedSearches: SaveSearch[] = []; + saveSearch.lastAccessed = new Date().getTime(); + + try { + savedSearches = JSON.parse(localStorage.getItem(ALERTS_RECENT_SEARCH)); + } catch (e) {} + + savedSearches = savedSearches || []; + savedSearches = savedSearches.map(tSaveSeacrh => SaveSearch.fromJSON(tSaveSeacrh)); + + if (savedSearches.length === 0) { + savedSearches.push(saveSearch); + } else { + let found = false; + for ( let tSaveSearch of savedSearches) { + if (saveSearch.name === tSaveSearch.name) { + tSaveSearch.lastAccessed = new Date().getTime(); + found = true; + break; + } + } + if (!found ) { + if (savedSearches.length < NUM_SAVED_SEARCH) { + savedSearches.push(saveSearch); + } else { + savedSearches.sort((s1, s2) => s1.lastAccessed - s2.lastAccessed).shift(); + savedSearches.push(saveSearch); + } + } + } + + localStorage.setItem(ALERTS_RECENT_SEARCH, JSON.stringify(savedSearches)); + + observer.next({}); + observer.complete(); + + }); + } + + saveSearch(saveSearch: SaveSearch): Observable<{}> { + return Observable.create(observer => { + let savedSearches: SaveSearch[] = []; + try { + savedSearches = JSON.parse(localStorage.getItem(ALERTS_SAVED_SEARCH)); + } catch (e) {} + + savedSearches = savedSearches || []; + savedSearches.push(saveSearch); + localStorage.setItem(ALERTS_SAVED_SEARCH, JSON.stringify(savedSearches)); + + observer.next({}); + observer.complete(); + + }); + } + + updateSearch(saveSearch: SaveSearch): Observable<{}> { + return Observable.create(observer => { + let savedSearches: SaveSearch[] = []; + try { + savedSearches = JSON.parse(localStorage.getItem(ALERTS_SAVED_SEARCH)); + let savedItem = savedSearches.find(search => search.name === saveSearch.name); + savedItem.lastAccessed = saveSearch.lastAccessed; + savedItem.searchRequest = saveSearch.searchRequest; + } catch (e) {} + + localStorage.setItem(ALERTS_SAVED_SEARCH, JSON.stringify(savedSearches)); + + observer.next({}); + observer.complete(); + + }); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/save-search.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/save-search.service.ts b/metron-interface/metron-alerts/src/app/service/save-search.service.ts new file mode 100644 index 0000000..dba03c2 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/save-search.service.ts @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Injectable, } from '@angular/core'; +import {Observable} from 'rxjs/Rx'; +import {Http} from '@angular/http'; +import {Subject} from 'rxjs/Subject'; +import {QueryBuilder} from '../alerts/alerts-list/query-builder'; +import {SaveSearch} from '../model/save-search'; +import {ColumnMetadata} from '../model/column-metadata'; +import {DataSource} from './data-source'; + +@Injectable() +export class SaveSearchService { + + queryBuilder: QueryBuilder; + tableColumns: ColumnMetadata[]; + + private loadSavedSearch = new Subject<SaveSearch>(); + loadSavedSearch$ = this.loadSavedSearch.asObservable(); + + constructor(private http: Http, + private dataSource: DataSource) {} + + deleteRecentSearch(saveSearch: SaveSearch): Observable<{}> { + return this.dataSource.deleteRecentSearch(saveSearch); + } + + deleteSavedSearch(saveSearch: SaveSearch): Observable<{}> { + return this.dataSource.deleteSavedSearch(saveSearch); + } + + fireLoadSavedSearch(savedSearch: SaveSearch) { + this.loadSavedSearch.next(savedSearch); + } + + listRecentSearches(): Observable<SaveSearch[]> { + return this.dataSource.listRecentSearches(); + } + + listSavedSearches(): Observable<SaveSearch[]> { + return this.dataSource.listSavedSearches(); + } + + saveAsRecentSearches(saveSearch: SaveSearch): Observable<{}> { + return this.dataSource.saveRecentSearch(saveSearch); + } + + saveSearch(saveSearch: SaveSearch): Observable<{}> { + return this.dataSource.saveSearch(saveSearch); + } + + setCurrentQueryBuilderAndTableColumns(queryBuilder: QueryBuilder, tableColumns: ColumnMetadata[]) { + this.queryBuilder = queryBuilder; + this.tableColumns = tableColumns; + } + + updateSearch(saveSearch: SaveSearch): Observable<{}> { + return this.dataSource.updateSearch(saveSearch); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/service/workflow.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/workflow.service.ts b/metron-interface/metron-alerts/src/app/service/workflow.service.ts new file mode 100644 index 0000000..060769f --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/workflow.service.ts @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs/Rx'; +import {Alert} from '../model/alert'; +import {Http, Headers, RequestOptions} from '@angular/http'; +import {HttpUtil} from '../utils/httpUtil'; + +@Injectable() +export class WorkflowService { + + defaultHeaders = {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'}; + + constructor(private http: Http) { + } + + public start(alerts: Alert[]): Observable<string> { + return this.http.post('/api/v1/workflow', alerts, new RequestOptions({headers: new Headers(this.defaultHeaders)})) + .map(HttpUtil.extractString); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/collapse/collapse-component-data.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/collapse/collapse-component-data.ts b/metron-interface/metron-alerts/src/app/shared/collapse/collapse-component-data.ts new file mode 100644 index 0000000..cff81af --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/collapse/collapse-component-data.ts @@ -0,0 +1,32 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class CollapseComponentDataItems { + name: string; + count: number; + + constructor(name: string, count?: number) { + this.name = name; + this.count = count; + } +} + +export class CollapseComponentData { + groupName: string; + groupItems: CollapseComponentDataItems[] = []; +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.html b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.html new file mode 100644 index 0000000..aaca91a --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.html @@ -0,0 +1,31 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES + OR CONDITIONS OF ANY KIND, either express or implied. See the License for + the specific language governing permissions and limitations under the License. + --> +<a [attr.href]="'#' + uniqueId" data-toggle="collapse" aria-expanded="true" [attr.aria-controls]="uniqueId" class="pr-2" + [ngClass]="{'font-size-14' : fontSize === 14, 'font-size-15' : fontSize === 15, 'border-bottom' : titleSeperator=== true}"> + {{ data.groupName }} +</a> +<div class="collapse" [attr.id]="uniqueId" [ngClass]="{'show': show === true}"> + <div *ngIf="data.groupItems.length === 0" class="container-fluid no-data-text"> + <i> {{ 'No ' + data.groupName + ' yet'}} </i> + </div> + <ul *ngIf="data.groupItems.length > 0" class="list-group"> + <li *ngFor="let groupItem of data.groupItems" class="list-group-item justify-content-between anchor" + [ngClass]="{'font-size-14' : fontSize === 14, 'font-size-15' : fontSize === 15}" [attr.title]="groupItem.name" + (click)="onSelectClick(groupItem.name)"> + {{ groupItem.name | centerEllipses: strLength }} + <span *ngIf="data.doc_count" class="badge badge-default badge-pill"> {{ groupItem.count }} </span> + <span *ngIf="deleteOption" class="delete" (click)="onDeleteClick($event, groupItem.name)"> </span> + </li> + </ul> +</div> http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.scss b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.scss new file mode 100644 index 0000000..2208c37 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.scss @@ -0,0 +1,92 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@import "../../../variables.scss"; + +.font-size-14 { + font-size: 14px; +} + +.font-size-15 { + font-size: 15px; +} + +.border-bottom { + margin-bottom: 0px; + padding-bottom: 10px; + border-bottom: 1px solid $tundora; + color: $silver-chalice-2; +} + +a { + display: block; + margin: 5px 0px; + text-decoration: none; + color: $silver; + + &::after { + font-family: "FontAwesome"; + font-style: normal; + font-size: 14px; + content: '\f106'; + float: right; + color: $dove-grey; + } +} + +a.collapsed::after { + font-family: "FontAwesome"; + font-style: normal; + font-size: 14px; + content: '\f107'; + float: right; + color: $dove-grey; +} + +.list-group { + padding: 10px 0px; +} + +.list-group-item { + border: none; + background: none; + color: $curious-blue; +} + +.delete { + line-height: 0px; + opacity: 0; + transition: opacity .35s ease; + + &::before { + font-family: "FontAwesome"; + content: '\f014'; + color: $dove-grey; + } +} + +.list-group-item:hover { + background: $outer-space; + + .delete { + opacity: 1; + } +} + +.no-data-text { + font-size: 12px; +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.spec.ts b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.spec.ts new file mode 100644 index 0000000..f6f32d1 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.spec.ts @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CollapseComponent } from './collapse.component'; + +describe('CollapseComponent', () => { + let component: CollapseComponent; + let fixture: ComponentFixture<CollapseComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CollapseComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CollapseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + +}); http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.ts b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.ts new file mode 100644 index 0000000..98947d3 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.component.ts @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import 'bootstrap'; +import {CollapseComponentData} from './collapse-component-data'; + +@Component({ + selector: 'metron-collapse', + templateUrl: './collapse.component.html', + styleUrls: ['./collapse.component.scss'] +}) +export class CollapseComponent implements OnInit { + + static counter = 0; + uniqueId = ''; + + @Input() data = new CollapseComponentData(); + @Input() fontSize = 14; + @Input() titleSeperator = false; + @Input() deleteOption = false; + @Input() show = false; + @Input() strLength = 30; + + @Output() onSelect = new EventEmitter<{name: string, key: string}>(); + @Output() onDelete = new EventEmitter<{name: string, key: string}>(); + + constructor() { + this.uniqueId = 'CollapseComponent' + '_' + ++CollapseComponent.counter; + } + + ngOnInit() { + } + + onDeleteClick($event, key: string) { + this.onDelete.emit({name: this.data.groupName, key: key}); + $event.stopPropagation(); + return false; + } + + onSelectClick(key: string) { + this.onSelect.emit({name: this.data.groupName, key: key}); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/collapse/collapse.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/collapse/collapse.module.ts b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.module.ts new file mode 100644 index 0000000..79ac01d --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/collapse/collapse.module.ts @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {NgModule} from '@angular/core'; + +import {CollapseComponent} from './collapse.component'; +import {SharedModule} from '../shared.module'; + +@NgModule({ + imports: [SharedModule], + exports: [CollapseComponent], + declarations: [CollapseComponent], + providers: [], +}) +export class CollapseModule { +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.spec.ts b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.spec.ts new file mode 100644 index 0000000..f8debdb --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.spec.ts @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +describe('AlertSearchDirective', () => { + +}); http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts new file mode 100644 index 0000000..fc3d113 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts @@ -0,0 +1,208 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/// <reference path="../../../../node_modules/@types/ace/index.d.ts" /> +import {Directive, ElementRef, EventEmitter, AfterViewInit, Output, Input, OnChanges, SimpleChanges} from '@angular/core'; + +declare var ace: any; +let ACERange = ace.require('ace/range').Range; + +@Directive({ + selector: '[appAceEditor]' +}) + +export class AlertSearchDirective implements AfterViewInit, OnChanges { + editor: AceAjax.Editor; + closeButton: any; + mouseEventTimer: number; + target: any; + + @Input() text = ''; + @Output() textChanged = new EventEmitter(); + + constructor(private elementRef: ElementRef) { + const el = elementRef.nativeElement; + el.classList.add('editor'); + + ace.config.set('basePath', '/assets/ace'); + + this.editor = ace.edit(el); + this.editor.$blockScrolling = Infinity; + this.editor.renderer.setShowGutter(false); + this.editor.renderer.setShowPrintMargin(false); + this.editor.renderer.setPadding(10); + this.editor.setTheme('ace/theme/monokai'); + this.editor.container.style.lineHeight = '1.5'; + + this.editor.setOptions({ + minLines: 1, + highlightActiveLine: false, + maxLines: Infinity, + fontSize: '0.75em' + }); + + this.editor.getSession().setMode('ace/mode/lucene'); + + // This is a hack: setScrollMargin is not available in latest ace typings but is available in ace + let renderer: any = this.editor.renderer; + renderer.setScrollMargin(12, 12); + + this.closeButton = document.createElement('i'); + this.closeButton.classList.add('fa'); + this.closeButton.classList.add('fa-times'); + this.editor.on('click', (event) => { + if (event.domEvent.target.classList.contains('fa-times')) { + let pos = event.getDocumentPosition(); + let strToDelete = this.getTextTillOperator(event.domEvent.target.parentElement); + + let endIndex = pos.column; + let startIndex = pos.column - (strToDelete.length + 1); + if ( startIndex < 0) { + startIndex = 0; + endIndex = (strToDelete.length + 1); + } + + let range = new ACERange(0, startIndex , 0, endIndex); + this.editor.selection.addRange(range); + this.editor.removeWordLeft(); + this.editor.renderer.showCursor(); + this.textChanged.next(this.editor.getValue()); + } + }); + } + + private getTextTillOperator(valueElement) { + let str = valueElement ? valueElement.textContent : ''; + + let previousSibling = valueElement && valueElement.previousSibling; + if (previousSibling && previousSibling.classList && previousSibling.classList.contains('ace_keyword')) { + str = previousSibling.textContent + str; + } + + previousSibling = previousSibling && previousSibling.previousSibling; + if (previousSibling && previousSibling.nodeName === '#text') { + str = previousSibling.textContent + str; + } + + previousSibling = previousSibling && previousSibling.previousSibling; + if (previousSibling && previousSibling.classList && previousSibling.classList.contains('ace_operator')) { + str = previousSibling.textContent + str; + } else { + str = str + this.getTextTillNextOperator(valueElement); + } + + return str; + } + + getTextTillNextOperator(valueElement) { + let str = ''; + let nextSibling = valueElement.nextSibling; + + if (nextSibling && nextSibling.nodeName === '#text') { + str = str + nextSibling.textContent; + } + + nextSibling = nextSibling && nextSibling.nextSibling; + if (nextSibling && nextSibling.classList && nextSibling.classList.contains('ace_operator')) { + str = str + nextSibling.textContent; + } + + return str; + } + + getSeacrhText(): string { + return this.editor.getValue(); + } + + private handleMouseEvent (callback: Function) { + clearTimeout(this.mouseEventTimer); + this.mouseEventTimer = setTimeout(() => { callback(); }, 500); + } + + private mouseover($event) { + if ($event.target.classList.contains('ace_value') || + $event.target.classList.contains('ace_keyword') || + $event.target.classList.contains('fa-times')) { + this.handleMouseEvent(() => { + this.target = $event.target.classList.contains('fa-times') ? $event.target.parentElement : $event.target; + if (this.target.classList.contains('ace_value')) { + this.target.classList.add('active'); + if (this.target.previousSibling && this.target.previousSibling.classList) { + this.target.previousSibling.classList.add('active'); + } + this.target.appendChild(this.closeButton); + this.editor.renderer.hideCursor(); + } + if (this.target.classList.contains('ace_keyword') && !this.target.classList.contains('ace_operator')) { + this.target.classList.add('active'); + if (this.target.nextSibling && this.target.nextSibling.classList) { + this.target.nextSibling.classList.add('active'); + this.target.nextSibling.appendChild(this.closeButton); + } + this.editor.renderer.hideCursor(); + } + }); + } + } + + private mouseout($event) { + if (this.target) { + this.handleMouseEvent(() => { + if (this.target.classList.contains('ace_value')) { + this.target.classList.remove('active'); + if (this.target.previousSibling && this.target.previousSibling.classList) { + this.target.previousSibling.classList.remove('active'); + } + this.target.removeChild(this.closeButton); + this.editor.renderer.showCursor(); + } + if (this.target.classList.contains('ace_keyword') && !this.target.classList.contains('ace_operator')) { + this.target.classList.remove('active'); + if (this.target.nextSibling && this.target.nextSibling.classList) { + this.target.nextSibling.classList.remove('active'); + this.target.nextSibling.removeChild(this.closeButton); + } + this.editor.renderer.showCursor(); + } + this.target = null; + }); + } + } + + ngAfterViewInit() { + this.editor.getSession().setUseWrapMode(true); + this.editor.keyBinding.addKeyboardHandler( (data, hashId, keyString, keyCode, event) => { + if (keyCode === 13) { + event.preventDefault(); + event.stopPropagation(); + this.textChanged.next(this.editor.getValue()); + return false; + } + return true; + }, 0); + this.elementRef.nativeElement.querySelector('.ace_content').addEventListener('mouseover', this.mouseover.bind(this)); + this.elementRef.nativeElement.querySelector('.ace_content').addEventListener('mouseout', this.mouseout.bind(this)); + } + + ngOnChanges(changes: SimpleChanges) { + if (changes && changes['text']) { + this.editor.setValue(this.text); + this.editor.clearSelection(); + this.editor.focus(); + } + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/directives/alert-severity.directive.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/directives/alert-severity.directive.ts b/metron-interface/metron-alerts/src/app/shared/directives/alert-severity.directive.ts new file mode 100644 index 0000000..c978d62 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/directives/alert-severity.directive.ts @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Directive, ElementRef, OnChanges, SimpleChanges, Input, OnInit } from '@angular/core'; + +@Directive({ + selector: '[appAlertSeverity]' +}) +export class AlertSeverityDirective implements OnInit, OnChanges { + + @Input() severity: number; + + constructor(private el: ElementRef) { } + + ngOnInit() { + this.setBorder(this.severity); + } + + ngOnChanges(changes: SimpleChanges) { + if (changes['severity'] && changes['severity'].currentValue) { + this.setBorder(this.severity); + } + } + + private setBorder(severity: number) { + + if ( severity > 69 ) { + this.el.nativeElement.style.borderLeft = '4px solid #D60A15'; + this.el.nativeElement.style.paddingLeft = '10px'; + } else if ( severity > 39 ) { + this.el.nativeElement.style.borderLeft = '4px solid #D6711D'; + this.el.nativeElement.style.paddingLeft = '10px'; + } else { + this.el.nativeElement.style.borderLeft = '4px solid #AC9B5A'; + this.el.nativeElement.style.paddingLeft = '10px'; + } + } + +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.spec.ts b/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.spec.ts new file mode 100644 index 0000000..ec64f24 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.spec.ts @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { NavContentDirective } from './nav-content.directive'; + +describe('NavContentDirective', () => { + it('should create an instance', () => { + const directive = new NavContentDirective(); + expect(directive).toBeTruthy(); + }); +}); http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.ts b/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.ts new file mode 100644 index 0000000..8bf9ba2 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/directives/nav-content.directive.ts @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Directive, ElementRef, OnInit } from '@angular/core'; + +@Directive({ + selector: '[appNavContent]' +}) +export class NavContentDirective implements OnInit { + + constructor(private element: ElementRef) { + } + + ngOnInit() { + this.applyStyles(); + } + private applyStyles() { + this.element.nativeElement.classList = 'nav-content'; + } + +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/index.ts b/metron-interface/metron-alerts/src/app/shared/index.ts new file mode 100644 index 0000000..e69de29 http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.html b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.html new file mode 100644 index 0000000..948153c --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.html @@ -0,0 +1,19 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES + OR CONDITIONS OF ANY KIND, either express or implied. See the License for + the specific language governing permissions and limitations under the License. + --> +<ul class="list-group"> + <li *ngFor="let item of data; let i = index;" class="list-group-item anchor" [ngClass]="{'active': i === 0}"> + <i *ngIf="item.icon" [attr.class]="'fa ' + item.icon" aria-hidden="true"></i> + <span>{{ item.name }} </span> + </li> +</ul> http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.scss b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.scss new file mode 100644 index 0000000..2a7b65c --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.scss @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +ul { + margin: 10px 0px; +} +.list-group-item { + span { + padding-left: 25px; + } + + i+span { + padding-left: 10px; + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.spec.ts b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.spec.ts new file mode 100644 index 0000000..f9916e6 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.spec.ts @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ListGroupComponent } from './list-group.component'; + +describe('ListGroupComponent', () => { + let component: ListGroupComponent; + let fixture: ComponentFixture<ListGroupComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ListGroupComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ListGroupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.ts b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.ts new file mode 100644 index 0000000..f42f961 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/list-group/list-group.component.ts @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Component, OnInit, Input, HostListener, ElementRef } from '@angular/core'; + +export interface ListGroupComponentData { + name: string; + icon?: string; +} + +@Component({ + selector: 'metron-list-group', + templateUrl: './list-group.component.html', + styleUrls: ['./list-group.component.scss'] +}) +export class ListGroupComponent implements OnInit { + + @Input() data: ListGroupComponentData[] = []; + + constructor(private element: ElementRef) { } + + ngOnInit() { + } + + @HostListener('click', ['$event']) onClick($event) { + this.element.nativeElement.getElementsByClassName('active')[0].classList.remove('active'); + if ($event.target.nodeName === 'LI') { + $event.target.classList.add('active'); + } else { + $event.target.parentNode.classList.add('active'); + } + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/list-group/list-grup.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/list-group/list-grup.module.ts b/metron-interface/metron-alerts/src/app/shared/list-group/list-grup.module.ts new file mode 100644 index 0000000..b1ba2a9 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/list-group/list-grup.module.ts @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {NgModule} from '@angular/core'; + +import {ListGroupComponent} from './list-group.component'; +import {SharedModule} from '../shared.module'; + +@NgModule({ + imports: [SharedModule], + exports: [ListGroupComponent], + declarations: [ListGroupComponent], + providers: [], +}) +export class ListGroupModule { +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-dialog-box.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-dialog-box.ts b/metron-interface/metron-alerts/src/app/shared/metron-dialog-box.ts new file mode 100644 index 0000000..1b8e2bf --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-dialog-box.ts @@ -0,0 +1,91 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {EventEmitter} from '@angular/core'; + +declare var $; + +export enum DialogType { + Confirmation, Error +}; + +export class MetronDialogBox { + private static dialogType = DialogType; + + private getCancelButton(type: DialogType): string { + if (type === DialogType.Confirmation) { + return `<button type="button" class="btn btn-mine_shaft_2" data-dismiss="modal">Cancel</button>`; + } + + return ''; + } + + private createDialogBox(message: string, type: DialogType) { + let cancelButtonHTML = this.getCancelButton(type); + let html = `<div class="metron-dialog modal fade" data-backdrop="static" > + <div class="modal-dialog modal-sm" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + <span class="modal-title"><b>` + MetronDialogBox.dialogType[type] + `</b></span> + </div> + <div class="modal-body"> + <p>` + message + `</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-all_ports">OK</button>` + + cancelButtonHTML + + `</div> + </div> + </div> + </div>`; + + let element = document.createElement('div'); + element.innerHTML = html; + + document.body.appendChild(element); + + return element; + } + + public showConfirmationMessage(message: string, dialogType = DialogType.Confirmation): EventEmitter<boolean> { + message = message.replace(/\n/g, '<br>'); + let eventEmitter = new EventEmitter<boolean>(); + let element = this.createDialogBox(message, dialogType); + + $(element).find('.metron-dialog').modal('show'); + + $(element).find('.btn-all_ports').on('click', function (e) { + $(element).find('.metron-dialog').modal('hide'); + eventEmitter.emit(true); + }); + + $(element).find('.btn-mine_shaft_2').on('click', function (e) { + $(element).find('.metron-dialog').modal('hide'); + eventEmitter.emit(false); + }); + + $(element).find('.metron-dialog').on('hidden.bs.modal', function (e) { + $(element).remove(); + }); + + return eventEmitter; + + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/index.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/index.ts new file mode 100644 index 0000000..dcfa7b0 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/index.ts @@ -0,0 +1,18 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './metron-sorter.component'; http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html new file mode 100644 index 0000000..988bec1 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html @@ -0,0 +1,21 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES + OR CONDITIONS OF ANY KIND, either express or implied. See the License for + the specific language governing permissions and limitations under the License. + --> +<a style="cursor: pointer" class="text-nowrap" (click)="sort()"> + <ng-content></ng-content> + <i class="fa fa-sort" aria-hidden="true" *ngIf="!sortAsc && !sortDesc"></i> + <i class="fa fa-sort-asc" aria-hidden="true" *ngIf="sortAsc"></i> + <i class="fa fa-sort-desc" aria-hidden="true" *ngIf="sortDesc"></i> +</a> http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss new file mode 100644 index 0000000..5d5f1e3 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss @@ -0,0 +1,17 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts new file mode 100644 index 0000000..bec9378 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts @@ -0,0 +1,92 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* tslint:disable:no-unused-variable */ +// directiveSelectorNameRule + +import {MetronSorterComponent} from './metron-sorter.component'; +import {MetronTableDirective} from '../metron-table.directive'; + +describe('Component: MetronSorter', () => { + + it('should create an instance', () => { + let metronTable = new MetronTableDirective(); + let component = new MetronSorterComponent(metronTable); + expect(component).toBeTruthy(); + }); + + it('should set the variables according to sorter', () => { + let metronTable = new MetronTableDirective(); + let sorter1 = new MetronSorterComponent(metronTable); + let sorter2 = new MetronSorterComponent(metronTable); + let sorter3 = new MetronSorterComponent(metronTable); + + sorter1.sortBy = 'col1'; + sorter2.sortBy = 'col2'; + sorter3.sortBy = 'col3'; + + sorter1.sort(); + expect(sorter1.sortAsc).toEqual(true); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter1.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(true); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter2.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(true); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter2.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(true); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter3.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(true); + expect(sorter3.sortDesc).toEqual(false); + + sorter3.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(true); + + }); + +}); http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts new file mode 100644 index 0000000..4808156 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Component, Input } from '@angular/core'; +import {MetronTableDirective, SortEvent} from '../metron-table.directive'; +import {Sort} from '../../../utils/enums'; + +@Component({ + selector: 'metron-config-sorter', + templateUrl: './metron-sorter.component.html', + styleUrls: ['./metron-sorter.component.scss'] +}) +export class MetronSorterComponent { + + @Input() sortBy: string; + @Input() type = 'string'; + + sortAsc = false; + sortDesc = false; + + constructor(private metronTable: MetronTableDirective ) { + this.metronTable.onSortColumnChange.subscribe((event: SortEvent) => { + this.sortAsc = (event.sortBy === this.sortBy && event.sortOrder === Sort.ASC); + this.sortDesc = (event.sortBy === this.sortBy && event.sortOrder === Sort.DSC); + }); + } + + sort() { + let order = this.sortAsc ? Sort.DSC : Sort.ASC; + this.metronTable.setSort({sortBy: this.sortBy, sortOrder: order, type: this.type}); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.module.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.module.ts new file mode 100644 index 0000000..088d120 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-sorter/metron-sorter.module.ts @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {NgModule} from '@angular/core'; + +import {MetronSorterComponent} from './metron-sorter.component'; +import {SharedModule} from '../../shared.module'; + +@NgModule({ + imports: [SharedModule], + exports: [MetronSorterComponent], + declarations: [MetronSorterComponent], + providers: [], +}) +export class MetronSorterModule { +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.html b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.html new file mode 100644 index 0000000..63609a5 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.html @@ -0,0 +1,20 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES + OR CONDITIONS OF ANY KIND, either express or implied. See the License for + the specific language governing permissions and limitations under the License. + --> +<div *ngIf="pagination.total > 0"> + <i *ngIf="pagination.from > 0" class="fa fa-chevron-left" aria-hidden="true" (click)="onPrevious()"></i> + <i *ngIf="pagination.from === 0" class="fa fa-chevron-left disabled" aria-hidden="true"></i> + <span> {{pagination.from + 1}} - {{pagination.total > (pagination.from + pagination.size) ? (pagination.from + pagination.size) : pagination.total}} of {{ pagination.total }} </span> + <i *ngIf="pagination.total - (pagination.from + pagination.size) > 0" class="fa fa-chevron-right" aria-hidden="true" (click)="onNext()"></i> + <i *ngIf="pagination.total - (pagination.from + pagination.size) <= 0" class="fa fa-chevron-right disabled" aria-hidden="true"></i> +</div> http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.scss b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.scss new file mode 100644 index 0000000..bad1e52 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.scss @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +i { + cursor: pointer; + margin: 0px 10px; +} + +.disabled { + opacity: 0.3; + cursor: default; +} + +span { + font-size: 14px; +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.spec.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.spec.ts new file mode 100644 index 0000000..3a519b6 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.spec.ts @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MetronTablePaginationComponent } from './metron-table-pagination.component'; + +describe('MetronTablePaginationComponent', () => { + let component: MetronTablePaginationComponent; + let fixture: ComponentFixture<MetronTablePaginationComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MetronTablePaginationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MetronTablePaginationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.ts new file mode 100644 index 0000000..0aaa217 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.component.ts @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import {Pagination} from '../../../model/pagination'; + +@Component({ + selector: 'metron-table-pagination', + templateUrl: './metron-table-pagination.component.html', + styleUrls: ['./metron-table-pagination.component.scss'] +}) +export class MetronTablePaginationComponent { + + @Output() pageChange = new EventEmitter(); + pagination = new Pagination(); + + @Input() + get pagingData() { + return this.pagination; + } + + set pagingData(val) { + this.pagination = val; + } + + onPrevious() { + this.pagination.from -= this.pagination.size; + this.pageChange.emit(); + } + + onNext() { + this.pagination.from += this.pagination.size; + this.pageChange.emit(); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/7d554444/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.module.ts b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.module.ts new file mode 100644 index 0000000..27b98dc --- /dev/null +++ b/metron-interface/metron-alerts/src/app/shared/metron-table/metron-table-pagination/metron-table-pagination.module.ts @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {NgModule} from '@angular/core'; + +import {MetronTablePaginationComponent} from './metron-table-pagination.component'; +import {SharedModule} from '../../shared.module'; + +@NgModule({ + imports: [SharedModule], + exports: [MetronTablePaginationComponent], + declarations: [MetronTablePaginationComponent], + providers: [], +}) +export class MetronTablePaginationModule { +}